You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1485 lines
50 KiB
1485 lines
50 KiB
<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
|
|
<html><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"><meta name="GENERATOR" content="Mozilla/4.61 (Macintosh; I; PPC) [Netscape]"><title>Pyrex Language Overview</title></head>
|
|
<body>
|
|
|
|
|
|
<h1>
|
|
<hr width="100%">Overview of the Pyrex Language
|
|
<hr width="100%"></h1>
|
|
|
|
|
|
This document informally describes the extensions to the Python language
|
|
made by Pyrex. Some day there will be a reference manual covering everything
|
|
in more detail. <h2> Contents</h2>
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
<li><a href="#SourceFiles">Source Files and Compilation</a> <span style="color: rgb(0, 153, 0);">(Section added in 0.9.5)</span><br>
|
|
</li><li><a href="#Basics">Basics</a></li>
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
<li> <a href="#PyFuncsVsCFuncs">Python functions vs. C functions</a></li>
|
|
|
|
<li> <a href="#PyObjParams">Python objects as parameters</a></li>
|
|
|
|
<li> <a href="#CVarAndTypeDecls">C variable and type definitions</a></li>
|
|
<li><a href="#AutomaticTypeConversions">Automatic type conversions</a></li>
|
|
|
|
|
|
<ul>
|
|
|
|
<li><a href="#PyToCStringCaveats">Caveats when using a Python string in a C context</a></li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
<li> <a href="#ScopeRules">Scope rules</a></li>
|
|
|
|
<li> <a href="#StatsAndExprs">Statements and expressions</a></li>
|
|
|
|
|
|
<ul>
|
|
|
|
<li> <a href="#ExprSyntaxDifferences">Differences between C and Pyrex
|
|
expressions<br>
|
|
|
|
</a></li>
|
|
|
|
<li> <a href="#ForFromLoop">Integer for-loops</a></li>
|
|
|
|
|
|
</ul>
|
|
|
|
<li> <a href="#ExceptionValues">Error return values</a></li>
|
|
|
|
|
|
<ul>
|
|
|
|
<li> <a href="#CheckingReturnValues">Checking return values of non-Pyrex
|
|
functions</a></li>
|
|
|
|
|
|
</ul>
|
|
|
|
<li> <a href="#IncludeStatement">The <tt>include</tt> statement</a></li><li><a href="#KeywordOnlyArguments">Keyword-only arguments</a><span style="color: rgb(255, 0, 0);"> (New in 0.9.6)</span></li>
|
|
|
|
|
|
</ul>
|
|
|
|
<li> <a href="#InterfacingWithExternal">Interfacing with External C Code</a></li>
|
|
|
|
|
|
<ul>
|
|
|
|
<li> <a href="#ExternDecls">External declarations</a></li>
|
|
|
|
|
|
<ul>
|
|
|
|
<li> <a href="#ReferencingHeaders">Referencing C header files</a></li>
|
|
|
|
<li> <a href="#StructDeclStyles">Styles of struct/union/enum declaration</a></li>
|
|
|
|
<li> <a href="#AccessingAPI">Accessing Python/C API routines</a></li><li><a href="#SpecialTypes">Special Types</a><span style="color: rgb(255, 0, 0);"> (New in 0.9.6)</span></li><li><a href="#CallingConventions">Windows Calling Conventions</a><span style="color: rgb(255, 0, 0);"> (New in 0.9.6)</span></li>
|
|
|
|
<li> <a href="#CNameSpecs">Resolving naming conflicts - C name specifications</a></li>
|
|
|
|
|
|
</ul><li><a href="#Using_Pyrex_Declarations_from_C">Using Pyrex declarations from C</a></li>
|
|
|
|
<ul><li> <a href="#PublicDecls">Public declarations</a></li></ul><ul><li><a href="#C_API_Declarations">C API declarations</a><span style="color: rgb(255, 0, 0);"> (New in 0.9.6)</span></li></ul>
|
|
|
|
|
|
</ul>
|
|
|
|
<li> <a href="extension_types.html">Extension Types</a></li>
|
|
|
|
<li> <a href="sharing.html">Sharing Declarations Between Pyrex Modules</a></li>
|
|
|
|
<li> <a href="#Limitations">Limitations</a></li>
|
|
|
|
|
|
<ul>
|
|
|
|
<li> <a href="#Unsupported">Unsupported Python features</a></li>
|
|
|
|
<li> <a href="#SemanticDifferences">Semantic differences between Python
|
|
and Pyrex</a></li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<h2>
|
|
<hr width="100%"></h2>
|
|
<h2><a name="SourceFiles"></a>Source Files and Compilation<br>
|
|
</h2>
|
|
<hr style="width: 100%; height: 2px;"><br>
|
|
Pyrex source file names consist of the name of the module followed by a <span style="font-family: monospace;">.pyx</span> extension, for example a module called <span style="font-family: monospace;">primes</span> would have a source file named <span style="font-family: monospace;">primes.pyx</span>.<br>
|
|
|
|
<br>
|
|
|
|
If your module is destined to live in a package, the source file name should include the <span style="font-style: italic;">full dotted name</span> that the module will eventually have. For example, a module called <span style="font-family: monospace;">primes</span> that will be installed in a package called <span style="font-family: monospace;">numbers</span> should have a source file called <span style="font-family: monospace;">numbers.primes.pyx</span>.
|
|
This will ensure that the __name__ properties of the module and any
|
|
classes defined in it are set correctly. If you don't do this, you may
|
|
find that pickling doesn't work, among other problems. It also ensures
|
|
that the Pyrex compiler has the right idea about the layout of the
|
|
module namespace, which can be important when accessing extension types
|
|
defined in other modules.<br>
|
|
<br>
|
|
Once you have written your .pyx file, there are a couple of ways of
|
|
turning it into an extension module. One way is to compile it manually
|
|
with the Pyrex compiler, e.g.<br>
|
|
<br>
|
|
<div style="margin-left: 40px;"><span style="font-family: monospace;">pyrexc primes.pyx</span><br>
|
|
</div>
|
|
<br>
|
|
This will produce a file called <span style="font-family: monospace;">primes.c</span>,
|
|
which then needs to be compiled with the C compiler using whatever
|
|
options are appropriate on your platform for generating an extension
|
|
module. There's a Makefile in the Demos directory (called <span style="font-family: monospace;">Makefile.nodistutils</span>) that shows how to do this for Linux.<br>
|
|
<br>
|
|
The other, and probably better, way is to use the distutils extension provided with Pyrex. See the <span style="font-family: monospace;">Setup.py</span>
|
|
file in the Demos directory for an example of how to use it. This
|
|
method has the advantage of being cross-platform -- the same setup file
|
|
should work on any platform where distutils can compile an extension
|
|
module.<br>
|
|
<br>
|
|
<hr style="width: 100%; height: 2px;">
|
|
<h2><a name="Basics"></a>Language Basics
|
|
<hr width="100%"></h2>
|
|
This section describes the basic features of the Pyrex language. The facilities
|
|
covered in this section allow you to create Python-callable functions that
|
|
manipulate C data structures and convert between Python and C data types.
|
|
Later sections will cover facilities for <a href="#InterfacingWithExternal">wrapping external C code</a>, <a href="extension_types.html">creating new Python types</a> and <a href="sharing.html">cooperation between Pyrex modules</a>.<br>
|
|
|
|
<h3> <a name="PyFuncsVsCFuncs"></a>Python functions vs. C functions</h3>
|
|
|
|
|
|
There are two kinds of function definition in Pyrex:
|
|
<p><b>Python functions</b> are defined using the <b>def</b> statement, as
|
|
in Python. They take Python objects as parameters and return Python objects.
|
|
</p>
|
|
|
|
|
|
|
|
<p><b>C functions</b> are defined using the new <b>cdef</b> statement. They
|
|
take either Python objects or C values as parameters, and can return either
|
|
Python objects or C values. </p>
|
|
|
|
|
|
|
|
<p>Within a Pyrex module, Python functions and C functions can call each other
|
|
freely, but only Python functions can be called from outside the module by
|
|
interpreted Python code. So, any functions that you want to "export" from
|
|
your Pyrex module must be declared as Python functions using <span style="font-weight: bold;">def</span>. </p>
|
|
|
|
|
|
|
|
<p>Parameters of either type of function can be declared to have C data types,
|
|
using normal C declaration syntax. For example, </p>
|
|
|
|
|
|
|
|
<blockquote>
|
|
<pre>def spam(int i, char *s):<br> ...</pre>
|
|
|
|
|
|
<pre>cdef int eggs(unsigned long l, float f):<br> ...</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
When a parameter of a Python function is declared to have a C data type,
|
|
it is passed in as a Python object and automatically converted to a C value,
|
|
if possible. Automatic conversion is currently only possible for numeric
|
|
types and string types; attempting to use any other type for the parameter
|
|
of a Python function will result in a compile-time error.
|
|
<p>C functions, on the other hand, can have parameters of any type, since
|
|
they're passed in directly using a normal C function call. </p>
|
|
|
|
|
|
|
|
<h3> <a name="PyObjParams"></a>Python objects as parameters and return values</h3>
|
|
|
|
|
|
If no type is specified for a parameter or return value, <i>it is assumed
|
|
to be a Python object.</i> (Note that this is different from the C convention,
|
|
where it would default to <tt>int</tt>.) For example, the following defines
|
|
a C function that takes two Python objects as parameters and returns a Python
|
|
object:
|
|
<blockquote>
|
|
<pre>cdef spamobjs(x, y):<br> ...</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
Reference counting for these objects is performed automatically according
|
|
to the standard Python/C API rules (i.e. borrowed references are taken as
|
|
parameters and a new reference is returned).
|
|
<p>The name <b>object</b> can also be used to explicitly declare something
|
|
as a Python object. This can be useful if the name being declared would otherwise
|
|
be taken as the name of a type, for example, </p>
|
|
|
|
|
|
|
|
<blockquote>
|
|
<pre>cdef ftang(object int):<br> ...</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
declares a parameter called <tt>int</tt> which is a Python object. You
|
|
can also use <b>object </b>as the explicit return type of a function, e.g.
|
|
|
|
<blockquote>
|
|
<pre>cdef object ftang(object int):<br> ...</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
In the interests of clarity, it is probably a good idea to always be explicit
|
|
about <b>object </b>parameters in C functions.
|
|
<h3> <a name="CVarAndTypeDecls"></a>C variable and type definitions</h3>
|
|
|
|
|
|
The <b>cdef</b> statement is also used to declare C variables, either
|
|
local or module-level:
|
|
<blockquote>
|
|
<pre>cdef int i, j, k<br>cdef float f, g[42], *h</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
and C struct, union or enum types:
|
|
<blockquote>
|
|
<pre>cdef struct Grail:<br> int age<br> float volume</pre>
|
|
|
|
|
|
<pre>cdef union Food:<br> char *spam<br> float *eggs</pre>
|
|
|
|
|
|
<pre>cdef enum CheeseType:<br> cheddar, edam, <br> camembert</pre>
|
|
|
|
|
|
<pre>cdef enum CheeseState:<br> hard = 1<br> soft = 2<br> runny = 3</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
There is currently no special syntax for defining a constant, but you
|
|
can use an anonymous enum declaration for this purpose, for example,
|
|
<blockquote><tt>cdef enum:</tt> <br>
|
|
|
|
<tt> tons_of_spam = 3</tt></blockquote>
|
|
|
|
|
|
Note that the words <span style="font-family: monospace;">struct</span>, <span style="font-family: monospace;">union</span> and <span style="font-family: monospace;">enum</span> are used only when <i>defining</i> a type, not when referring to it. For example, to declare a variable pointing
|
|
to a Grail you would write
|
|
<blockquote>
|
|
<pre>cdef Grail *gp</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
and <i>not</i>
|
|
<blockquote>
|
|
<pre>cdef struct Grail *gp <font color="#ed181e"># WRONG</font></pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
There is also a <b>ctypedef</b> statement for giving names to types, e.g.
|
|
|
|
<blockquote>
|
|
<pre>ctypedef unsigned long ULong</pre>
|
|
|
|
|
|
<pre>ctypedef int *IntPtr<br></pre>
|
|
</blockquote>
|
|
|
|
|
|
<h3><a name="AutomaticTypeConversions"></a>Automatic type conversions</h3>
|
|
|
|
|
|
In most situations, automatic conversions will be performed for the
|
|
basic numeric and string types when a Python object is used in a
|
|
context requiring a C value, or vice versa. The following table
|
|
summarises the conversion possibilities.<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
<table style="margin-left: auto; margin-right: auto; width: 10%; text-align: left;" border="1" cellpadding="4" cellspacing="0">
|
|
|
|
|
|
<tbody>
|
|
|
|
<tr>
|
|
|
|
<th style="vertical-align: top; width: 40%; white-space: nowrap;">C types<br>
|
|
|
|
</th>
|
|
|
|
<th style="vertical-align: top; width: 150px; white-space: nowrap;">From Python types<br>
|
|
|
|
</th>
|
|
|
|
<th style="vertical-align: top; width: 150px; white-space: nowrap;">To Python types<br>
|
|
|
|
</th>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td colspan="1" rowspan="1" style="vertical-align: top; width: 40%; white-space: nowrap;">[unsigned] char<br>
|
|
|
|
[unsigned] short<br>
|
|
|
|
int, long</td>
|
|
|
|
<td colspan="1" rowspan="1" style="vertical-align: top; width: 150px; white-space: nowrap;">int, long<br>
|
|
|
|
</td>
|
|
|
|
<td colspan="1" rowspan="1" style="vertical-align: top; width: 150px; white-space: nowrap;">int<br>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
</tr>
|
|
|
|
|
|
<tr>
|
|
|
|
<td colspan="1" rowspan="1" style="vertical-align: top; width: 40%; white-space: nowrap;">unsigned int<br>
|
|
|
|
unsigned long<br>
|
|
|
|
[unsigned] long long<br>
|
|
|
|
|
|
</td>
|
|
|
|
<td colspan="1" rowspan="1" style="vertical-align: top; white-space: nowrap;">int, long<br>
|
|
|
|
<br>
|
|
|
|
|
|
</td>
|
|
|
|
<td colspan="1" rowspan="1" style="vertical-align: top; white-space: nowrap;">long<br>
|
|
|
|
<br>
|
|
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
|
|
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td style="vertical-align: top; width: 40%; white-space: nowrap;">float, double, long double<br>
|
|
|
|
</td>
|
|
|
|
<td style="vertical-align: top; width: 150px; white-space: nowrap;">int, long, float<br>
|
|
|
|
</td>
|
|
|
|
<td style="vertical-align: top; width: 150px; white-space: nowrap;">float<br>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td style="vertical-align: top; width: 40%; white-space: nowrap;">char *<br>
|
|
|
|
</td>
|
|
|
|
<td style="vertical-align: top; width: 150px; white-space: nowrap;">str<span style="font-style: italic;"></span><br>
|
|
|
|
</td>
|
|
|
|
<td style="vertical-align: top; width: 150px; white-space: nowrap;">str<br>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
<h4><a name="PyToCStringCaveats"></a>Caveats when using a Python string in a C context</h4>
|
|
|
|
|
|
You need to be careful when using a Python string in a context expecting a <span style="font-family: monospace;">char *</span>.
|
|
In this situation, a pointer to the contents of the Python string is
|
|
used, which is only valid as long as the Python string exists. So you
|
|
need to make sure that a reference to the original Python string is
|
|
held for as long as the C string is needed. If you can't guarantee that
|
|
the Python string will live long enough, you will need to copy the C
|
|
string.<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
Pyrex detects and prevents <span style="font-style: italic;">some</span> mistakes of this kind. For instance, if you attempt something like<br>
|
|
|
|
|
|
<pre style="margin-left: 40px;">cdef char *s<br>s = pystring1 + pystring2</pre>
|
|
|
|
|
|
then Pyrex will produce the error message "<span style="font-weight: bold;">Obtaining char * from temporary Python value</span>".
|
|
The reason is that concatenating the two Python strings produces a new
|
|
Python string object that is referenced only by a temporary internal
|
|
variable that Pyrex generates. As soon as the statement has finished,
|
|
the temporary variable will be decrefed and the Python string
|
|
deallocated, leaving <span style="font-family: monospace;">s</span> dangling. Since this code could not possibly work, Pyrex refuses to compile it.<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
The solution is to assign the result of the concatenation to a Python variable, and then obtain the char * from that, i.e.<br>
|
|
|
|
|
|
<pre style="margin-left: 40px;">cdef char *s<br>p = pystring1 + pystring2<br>s = p<br></pre>
|
|
|
|
|
|
It is then your responsibility to hold the reference <span style="font-family: monospace;">p</span> for as long as necessary.<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
Keep in mind that the rules used to detect such errors are only
|
|
heuristics. Sometimes Pyrex will complain unnecessarily, and sometimes
|
|
it will fail to detect a problem that exists. Ultimately, you need to
|
|
understand the issue and be careful what you do.
|
|
|
|
|
|
|
|
|
|
<h3> <a name="ScopeRules"></a>Scope rules</h3>
|
|
|
|
|
|
Pyrex determines whether a variable belongs to a local scope, the module
|
|
scope, or the built-in scope <i>completely statically.</i> As with Python,
|
|
assigning to a variable which is not otherwise declared implicitly declares
|
|
it to be a Python variable residing in the scope where it is assigned. Unlike
|
|
Python, however, a name which is referred to but not declared or assigned
|
|
is assumed to reside in the <i>builtin scope, </i>not the module scope.
|
|
Names added to the module dictionary at run time will not shadow such names.
|
|
|
|
<p>You can use a <b>global</b> statement at the module level to explicitly
|
|
declare a name to be a module-level name when there would otherwise not be
|
|
any indication of this, for example, </p>
|
|
|
|
|
|
|
|
<blockquote><tt>global __name__</tt> <br>
|
|
|
|
<tt>print __name__</tt></blockquote>
|
|
|
|
|
|
Without the <b>global</b> statement, the above would print the name of
|
|
the builtins module.<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
Note: A consequence of these rules is that the module-level scope behaves
|
|
the same way as a Python local scope if you refer to a variable before assigning
|
|
to it. In particular, tricks such as the following will <i>not</i> work
|
|
in Pyrex:<br>
|
|
|
|
|
|
|
|
<blockquote>
|
|
<pre>try:<br> x = True<br>except NameError:<br> True = 1<br></pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
because, due to the assignment, the True will always be looked up in the
|
|
module-level scope. You would have to do something like this instead:<br>
|
|
|
|
|
|
|
|
<blockquote>
|
|
<pre>import __builtin__<br>try:<br> True = __builtin__.True<br>except AttributeError:<br> True = 1<br></pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
|
|
<hr width="100%">
|
|
<h3> <a name="StatsAndExprs"></a>Statements and expressions</h3>
|
|
|
|
|
|
Control structures and expressions follow Python syntax for the most part.
|
|
When applied to Python objects, they have the same semantics as in Python
|
|
(unless otherwise noted). Most of the Python operators can also be applied
|
|
to C values, with the obvious semantics.
|
|
<p>If Python objects and C values are mixed in an expression, conversions
|
|
are performed automatically between Python objects and C numeric or string
|
|
types. </p>
|
|
|
|
|
|
|
|
<p>Reference counts are maintained automatically for all Python objects, and
|
|
all Python operations are automatically checked for errors, with appropriate
|
|
action taken. </p>
|
|
|
|
|
|
|
|
<h4> <a name="ExprSyntaxDifferences"></a>Differences between C and Pyrex
|
|
expressions</h4>
|
|
|
|
There
|
|
are some differences in syntax and semantics between C expressions and
|
|
Pyrex expressions, particularly in the area of C constructs which have
|
|
no direct equivalent in Python.<br>
|
|
|
|
|
|
<ul>
|
|
|
|
<li>An integer literal without an <span style="font-family: monospace; font-weight: bold;">L</span> suffix is treated as a C constant, and will be truncated to whatever size your C compiler thinks appropriate. With an <span style="font-family: monospace; font-weight: bold;">L</span> suffix, it will be converted to Python long integer (even if it would be small enough to fit into a C int).<br>
|
|
|
|
<br>
|
|
|
|
</li>
|
|
|
|
<li> There is no <b><tt>-></tt></b> operator in Pyrex. Instead of <tt>p->x</tt>,
|
|
use <tt>p.x</tt></li>
|
|
|
|
|
|
<li> There is no <b><tt>*</tt></b> operator in Pyrex. Instead of
|
|
<tt>*p</tt>, use <tt>p[0]</tt></li>
|
|
|
|
|
|
<li> There is an <b><tt>&</tt></b> operator, with the same semantics
|
|
as in C.</li>
|
|
|
|
|
|
<li> The null C pointer is called <b><tt>NULL</tt></b>, not 0 (and
|
|
<tt>NULL</tt> is a reserved word).</li>
|
|
|
|
|
|
<li> Character literals are written with a <b>c</b> prefix, for
|
|
example:</li>
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
<pre>c'X'</pre>
|
|
|
|
|
|
</ul>
|
|
|
|
<li> Type casts are written <b><tt><type>value</tt></b> , for example:</li>
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
<pre>cdef char *p, float *q<br>p = <char*>q</pre>
|
|
|
|
|
|
</ul>
|
|
|
|
<i><b>Warning</b>: Don't attempt to use a typecast to convert between
|
|
Python and C data types -- it won't do the right thing. Leave Pyrex to perform
|
|
the conversion automatically.</i>
|
|
</ul>
|
|
|
|
|
|
|
|
<h4> <a name="ForFromLoop"></a>Integer for-loops</h4>
|
|
|
|
|
|
You should be aware that a for-loop such as
|
|
<blockquote><tt>for i in range(n):</tt> <br>
|
|
|
|
<tt> ...</tt></blockquote>
|
|
|
|
|
|
won't be very fast, even if <tt>i</tt> and <tt>n</tt> are declared as
|
|
C integers, because <tt>range</tt> is a Python function. For iterating over
|
|
ranges of integers, Pyrex has another form of for-loop:
|
|
<blockquote><tt>for i from 0 <= i < n:</tt> <br>
|
|
|
|
<tt> ...</tt></blockquote>
|
|
|
|
|
|
If the loop variable and the lower and upper bounds are all C integers,
|
|
this form of loop will be much faster, because Pyrex will translate it into
|
|
pure C code.
|
|
<p>Some things to note about the <tt>for-from</tt> loop: </p>
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
<li> The target expression must be a variable name.</li>
|
|
|
|
<li> The name between the lower and upper bounds must be the same as
|
|
the target name.</li>
|
|
|
|
<li> The direction of iteration is determined by the relations. If they
|
|
are both from the set {<tt><</tt>, <tt><=</tt>} then it is upwards;
|
|
if they are both from the set {<tt>></tt>, <tt>>=</tt>} then it is
|
|
downwards. (Any other combination is disallowed.)</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
Like other Python looping statements, <tt>break</tt> and <tt>continue</tt> may be used in the body, and the loop may have an <tt>else</tt> clause.
|
|
|
|
<h2>
|
|
<hr width="100%"></h2>
|
|
|
|
|
|
|
|
<h3> <a name="ExceptionValues"></a>Error return values</h3>
|
|
|
|
|
|
If you don't do anything special, a function declared with <b>cdef</b> that does not return a Python object has no way of reporting Python exceptions
|
|
to its caller. If an exception is detected in such a function, a warning
|
|
message is printed and the exception is ignored.
|
|
<p>If you want a C function that does not return a Python object to be able
|
|
to propagate exceptions to its caller, you need to declare an <b>exception
|
|
value</b> for it. Here is an example: </p>
|
|
|
|
|
|
|
|
<blockquote><tt>cdef int spam() except -1:</tt> <br>
|
|
|
|
<tt> ...</tt></blockquote>
|
|
|
|
|
|
With this declaration, whenever an exception occurs inside <tt>spam</tt>,
|
|
it will immediately return with the value <tt>-1</tt>. Furthermore, whenever
|
|
a call to <tt>spam</tt> returns <tt>-1</tt>, an exception will be assumed
|
|
to have occurred and will be propagated.
|
|
<p>When you declare an exception value for a function, you should never explicitly
|
|
return that value. If all possible return values are legal and you can't
|
|
reserve one entirely for signalling errors, you can use an alternative form
|
|
of exception value declaration: </p>
|
|
|
|
|
|
|
|
<blockquote><tt>cdef int spam() except? -1:</tt> <br>
|
|
|
|
<tt> ...</tt></blockquote>
|
|
|
|
|
|
The "?" indicates that the value <tt>-1</tt> only indicates a <i>possible</i> error. In this case, Pyrex generates a call to <tt>PyErr_Occurred</tt> if the
|
|
exception value is returned, to make sure it really is an error.
|
|
<p>There is also a third form of exception value declaration: </p>
|
|
|
|
|
|
|
|
<blockquote><tt>cdef int spam() except *:</tt> <br>
|
|
|
|
<tt> ...</tt></blockquote>
|
|
|
|
|
|
This form causes Pyrex to generate a call to <tt>PyErr_Occurred</tt> after
|
|
<i>every</i> call to <code>spam</code>, regardless of what value it returns. If you have
|
|
a function returning <tt>void</tt> that needs to propagate errors, you will
|
|
have to use this form, since there isn't any return value to test.
|
|
<p>Some things to note: </p>
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
<li>Exception values can only declared for functions returning
|
|
an integer, enum, float or pointer type, and the value must be a constant expression. The only possible pointer
|
|
exception value is <tt>NULL</tt>. Void functions can only use the <tt>except
|
|
*</tt> form.</li>
|
|
|
|
|
|
<li> The exception value specification is part of the signature
|
|
of the function. If you're passing a pointer to a function as a parameter
|
|
or assigning it to a variable, the declared type of the parameter or variable
|
|
must have the same exception value specification (or lack thereof). Here
|
|
is an example of a pointer-to-function declaration with an exception value:</li>
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
<pre><tt>int (*grail)(int, char *) except -1</tt></pre>
|
|
|
|
|
|
</ul>
|
|
|
|
<li> You don't need to (and shouldn't) declare exception values for functions
|
|
which return Python objects. Remember that a function with no declared return
|
|
type implicitly returns a Python object.</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<h4> <a name="CheckingReturnValues"></a>Checking return values of non-Pyrex
|
|
functions</h4>
|
|
|
|
|
|
It's important to understand that the <tt>except</tt> clause does <i>not</i> cause an error to be <i>raised</i> when the specified value is returned. For
|
|
example, you can't write something like
|
|
<blockquote>
|
|
<pre>cdef extern FILE *fopen(char *filename, char *mode) except NULL <font color="#ed181e"># WRONG!</font></pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
and expect an exception to be automatically raised if a call to fopen
|
|
returns NULL. The except clause doesn't work that way; its only purpose
|
|
is for <i>propagating</i> exceptions that have already been raised, either
|
|
by a Pyrex function or a C function that calls Python/C API routines. To
|
|
get an exception from a non-Python-aware function such as fopen, you will
|
|
have to check the return value and raise it yourself, for example,
|
|
<blockquote>
|
|
<pre>cdef FILE *p<br>p = fopen("spam.txt", "r")<br>if p == NULL:<br> raise SpamError("Couldn't open the spam file")</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
|
|
<h4>
|
|
<hr width="100%"></h4>
|
|
|
|
|
|
|
|
<h3> <a name="IncludeStatement"></a>The <tt>include</tt> statement</h3>
|
|
|
|
|
|
For convenience, a large Pyrex module can be split up into a number of
|
|
files which are put together using the <b>include</b> statement, for example
|
|
|
|
<blockquote>
|
|
<pre>include "spamstuff.pxi"</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
The contents of the named file are textually included at that point. The
|
|
included file can contain any complete top-level Pyrex statements, including
|
|
other <b>include</b> statements. The <b>include</b> statement itself can
|
|
only appear at the top level of a file.
|
|
<p>The <b>include</b> statement can also be used in conjunction with <a href="#PublicDecls"><b>public</b> declarations</a> to make C functions and
|
|
variables defined in one Pyrex module accessible to another. However, note
|
|
that some of these uses have been superseded by the facilities described
|
|
in <a href="sharing.html">Sharing Declarations Between Pyrex Modules</a>,
|
|
and it is expected that use of the <b>include</b> statement for this purpose
|
|
will be phased out altogether in future versions.</p><hr style="width: 100%; height: 2px;"><h3><a name="KeywordOnlyArguments"></a>Keyword-only arguments</h3><p>Python functions can have keyword-only arguments listed after the * parameter and before the ** paramter if any, e.g.</p><pre style="margin-left: 40px;">def f(a, b, *args, c, d = 42, e, **kwds):<br> ...<br></pre>Here
|
|
c, d and e cannot be passed as position arguments and must be passed as
|
|
keyword arguments. Furthermore, c and e are required keyword arguments,
|
|
since they do not have a default value.<br><br>If the parameter name after the * is omitted, the function will not accept any extra positional arguments, e.g.<br><br><pre style="margin-left: 40px;">def g(a, b, *, c, d):<br> ...<br></pre>takes exactly two positional parameters and has two required keyword parameters.
|
|
|
|
|
|
|
|
<h2>
|
|
<hr width="100%"><a name="InterfacingWithExternal"></a>Interfacing with External
|
|
C Code
|
|
<hr width="100%"></h2>
|
|
|
|
|
|
One of the main uses of Pyrex is wrapping existing libraries of C code.
|
|
This is achieved by using <a href="#ExternDecls">external declarations</a> to declare the C functions and variables from the library that you want to
|
|
use.
|
|
<p>You can also use <a href="#PublicDecls">public declarations</a> to make
|
|
C functions and variables defined in a Pyrex module available to external
|
|
C code. The need for this is expected to be less frequent, but you might
|
|
want to do it, for example, if you are embedding Python in another application
|
|
as a scripting language. Just as a Pyrex module can be used as a bridge to
|
|
allow Python code to call C code, it can also be used to allow C code to
|
|
call Python code. </p>
|
|
|
|
|
|
|
|
<h3> <a name="ExternDecls"></a>External declarations</h3>
|
|
|
|
|
|
By default, C functions and variables declared at the module level are
|
|
local to the module (i.e. they have the C <b>static</b> storage class). They
|
|
can also be declared <b>extern</b> to specify that they are defined elsewhere,
|
|
for example:
|
|
<blockquote>
|
|
<pre>cdef extern int spam_counter</pre>
|
|
|
|
|
|
<pre>cdef extern void order_spam(int tons)</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
|
|
<blockquote> </blockquote>
|
|
|
|
|
|
|
|
<h4> <a name="ReferencingHeaders"></a>Referencing C header files</h4>
|
|
|
|
|
|
When you use an extern definition on its own as in the examples above,
|
|
Pyrex includes a declaration for it in the generated C file. This can cause
|
|
problems if the declaration doesn't exactly match the declaration that will
|
|
be seen by other C code. If you're wrapping an existing C library, for example,
|
|
it's important that the generated C code is compiled with exactly the same
|
|
declarations as the rest of the library.
|
|
<p>To achieve this, you can tell Pyrex that the declarations are to be found
|
|
in a C header file, like this: </p>
|
|
|
|
|
|
|
|
<blockquote>
|
|
<pre>cdef extern from "spam.h":</pre>
|
|
|
|
|
|
<pre> int spam_counter</pre>
|
|
|
|
|
|
<pre> void order_spam(int tons)</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
The <b>cdef extern from</b> clause does three things:
|
|
<ol>
|
|
|
|
|
|
<li> It directs Pyrex to place a <b>#include</b> statement for the named
|
|
header file in the generated C code.<br>
|
|
|
|
</li>
|
|
|
|
<li> It prevents Pyrex from generating any C code for the declarations
|
|
found in the associated block.<br>
|
|
|
|
</li>
|
|
|
|
<li> It treats all declarations within the block as though they
|
|
started with <b>cdef extern</b>.</li>
|
|
|
|
|
|
</ol>
|
|
|
|
|
|
It's important to understand that Pyrex does <i>not</i> itself read the
|
|
C header file, so you still need to provide Pyrex versions of any declarations
|
|
from it that you use. However, the Pyrex declarations don't always have to
|
|
exactly match the C ones, and in some cases they shouldn't or can't. In particular:
|
|
|
|
<ol>
|
|
|
|
|
|
<li> Don't use <b>const</b>. Pyrex doesn't know anything about const,
|
|
so just leave it out. Most of the time this shouldn't cause any problem,
|
|
although on rare occasions you might have to use a cast.<sup><a href="#Footnote1"> 1</a></sup><br>
|
|
|
|
</li>
|
|
|
|
<li> Leave out any platform-specific extensions to C declarations
|
|
such as <b>__declspec()</b>.<br>
|
|
|
|
</li>
|
|
|
|
<li> If the header file declares a big struct and you only want
|
|
to use a few members, you only need to declare the members you're interested
|
|
in. Leaving the rest out doesn't do any harm, because the C compiler will
|
|
use the full definition from the header file.<br>
|
|
|
|
<br>
|
|
|
|
In some cases, you might not need <i>any</i> of the struct's members, in
|
|
which case you can just put <tt>pass</tt> in the body of the struct declaration,
|
|
e.g.<br>
|
|
|
|
<br>
|
|
|
|
<tt> cdef extern from "foo.h":<br>
|
|
|
|
struct spam:<br>
|
|
|
|
pass</tt><br>
|
|
|
|
<br>
|
|
|
|
Note that you can only do this inside a <b>cdef extern from</b> block; struct
|
|
declarations anywhere else must be non-empty.<br>
|
|
|
|
<br>
|
|
|
|
</li>
|
|
|
|
<li> If the header file uses typedef names such as <b>size_t </b>to refer
|
|
to platform-dependent flavours of numeric types, you will need a corresponding
|
|
<b>ctypedef</b> statement, but you don't need to match the type exactly,
|
|
just use something of the right general kind (int, float, etc). For example,</li>
|
|
|
|
|
|
<ol>
|
|
|
|
|
|
<pre>ctypedef int size_t</pre>
|
|
|
|
|
|
</ol>
|
|
|
|
will work okay whatever the actual size of a size_t is (provided the header
|
|
file defines it correctly). <br>
|
|
|
|
<li> If the header file uses macros to define constants, translate
|
|
them into a dummy <b>enum</b> declaration.<br>
|
|
|
|
</li>
|
|
|
|
<li> If the header file defines a function using a macro, declare
|
|
it as though it were an ordinary function, with appropriate argument and
|
|
result types.</li>
|
|
|
|
|
|
</ol>
|
|
|
|
|
|
A few more tricks and tips:
|
|
<ul>
|
|
|
|
|
|
<li> If you want to include a C header because it's needed by another
|
|
header, but don't want to use any declarations from it, put <tt><font size="+1">pass</font></tt> in the extern-from block:</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
<tt>cdef extern from "spam.h":</tt> <br>
|
|
|
|
<tt> pass</tt>
|
|
</ul>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
<li> If you want to include some external declarations, but don't want
|
|
to specify a header file (because it's included by some other header that
|
|
you've already included) you can put <tt>*</tt> in place of the header file
|
|
name:</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<blockquote>
|
|
<blockquote><tt>cdef extern from *:</tt> <br>
|
|
|
|
<tt> ...</tt></blockquote>
|
|
|
|
</blockquote>
|
|
|
|
|
|
|
|
<h4> <a name="StructDeclStyles"></a>Styles of struct, union and enum declaration</h4>
|
|
|
|
|
|
There are two main ways that structs, unions and enums can be declared
|
|
in C header files: using a tag name, or using a typedef. There are also some
|
|
variations based on various combinations of these.
|
|
<p>It's important to make the Pyrex declarations match the style used in the
|
|
header file, so that Pyrex can emit the right sort of references to the type
|
|
in the code it generates. To make this possible, Pyrex provides two different
|
|
syntaxes for declaring a struct, union or enum type. The style introduced
|
|
above corresponds to the use of a tag name. To get the other style, you prefix
|
|
the declaration with <b>ctypedef</b>, as illustrated below. </p>
|
|
|
|
|
|
|
|
<p>The following table shows the various possible styles that can be found
|
|
in a header file, and the corresponding Pyrex declaration that you should
|
|
put in the <b>cdef exern from </b>block. Struct declarations are used as
|
|
an example; the same applies equally to union and enum declarations. </p>
|
|
|
|
|
|
|
|
<p>Note that in all the cases below, you refer to the type in Pyrex code simply
|
|
as <tt><font size="+1">Foo</font></tt>, not <tt><font size="+1">struct Foo</font></tt>.
|
|
<br>
|
|
|
|
|
|
<table cellpadding="5">
|
|
|
|
<tbody>
|
|
|
|
<tr bgcolor="#8cbc1c" valign="top">
|
|
|
|
<td bgcolor="#8cbc1c"> </td>
|
|
|
|
<td bgcolor="#ff9933" nowrap="nowrap"><b>C code</b></td>
|
|
|
|
<td bgcolor="#66cccc" valign="top"><b>Possibilities for corresponding
|
|
Pyrex code</b></td>
|
|
|
|
<td bgcolor="#99cc33" valign="top"><b>Comments</b></td>
|
|
|
|
</tr>
|
|
|
|
<tr bgcolor="#8cbc1c" valign="top">
|
|
|
|
<td>1</td>
|
|
|
|
<td bgcolor="#ff9900"><tt>struct Foo {</tt> <br>
|
|
|
|
<tt> ...</tt> <br>
|
|
|
|
<tt>};</tt></td>
|
|
|
|
<td bgcolor="#66cccc"><tt>cdef struct Foo:</tt> <br>
|
|
|
|
<tt> ...</tt></td>
|
|
|
|
<td>Pyrex will refer to the type as <tt>struct Foo </tt>in the generated
|
|
C code<tt>.</tt></td>
|
|
|
|
</tr>
|
|
|
|
<tr bgcolor="#8cbc1c" valign="top">
|
|
|
|
<td valign="top">2</td>
|
|
|
|
<td bgcolor="#ff9900" nowrap="nowrap"><tt>typedef struct {</tt> <br>
|
|
|
|
<tt> ...</tt> <br>
|
|
|
|
<tt>} Foo;</tt></td>
|
|
|
|
<td bgcolor="#66cccc" valign="top"><tt>ctypedef struct Foo:</tt> <br>
|
|
|
|
<tt> ...</tt></td>
|
|
|
|
<td valign="top">Pyrex will refer to the type simply as <tt>Foo</tt>
|
|
in the generated C code.</td>
|
|
|
|
</tr>
|
|
|
|
<tr bgcolor="#8cbc1c" valign="top">
|
|
|
|
<td rowspan="2">3</td>
|
|
|
|
<td rowspan="2" bgcolor="#ff9900" nowrap="nowrap"><tt>typedef struct
|
|
foo {</tt> <br>
|
|
|
|
<tt> ...</tt> <br>
|
|
|
|
<tt>} Foo;</tt></td>
|
|
|
|
<td bgcolor="#66cccc" nowrap="nowrap" valign="top"><tt>cdef struct foo:</tt> <br>
|
|
|
|
<tt> ...</tt> <br>
|
|
|
|
<tt>ctypedef foo Foo #optional</tt></td>
|
|
|
|
<td rowspan="2" valign="top">If the C header uses both a tag and a typedef
|
|
with <i>different</i> names, you can use either form of declaration in Pyrex
|
|
(although if you need to forward reference the type, you'll have to use
|
|
the first form).</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td bgcolor="#66cccc"><tt>ctypedef struct Foo:</tt> <br>
|
|
|
|
<tt> ...</tt></td>
|
|
|
|
</tr>
|
|
|
|
<tr bgcolor="#8cbc1c" valign="top">
|
|
|
|
<td>4</td>
|
|
|
|
<td bgcolor="#ff9900" nowrap="nowrap"><tt>typedef struct Foo {</tt> <br>
|
|
|
|
<tt> ...</tt> <br>
|
|
|
|
<tt>} Foo;</tt></td>
|
|
|
|
<td bgcolor="#66cccc" valign="top"><tt>cdef struct Foo:</tt> <br>
|
|
|
|
<tt> ...</tt></td>
|
|
|
|
<td>If the header uses the <i>same</i> name for the tag and the typedef,
|
|
you won't be able to include a <b>ctypedef</b> for it -- but then, it's not
|
|
necessary.</td>
|
|
|
|
</tr>
|
|
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<h4> <a name="AccessingAPI"></a>Accessing Python/C API routines</h4>
|
|
|
|
|
|
One particular use of the <b>cdef extern from</b> statement is for gaining
|
|
access to routines in the Python/C API. For example,
|
|
<blockquote>
|
|
<pre>cdef extern from "Python.h":</pre>
|
|
|
|
|
|
<pre> object PyString_FromStringAndSize(char *s, Py_ssize_t len)</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
will allow you to create Python strings containing null bytes.
|
|
<h4> <a name="SpecialTypes"></a>Special Types</h4><p>Pyrex predefines the name <span style="font-family: monospace;">Py_ssize_t</span>
|
|
for use with Python/C API routines. To make your extensions compatible
|
|
with 64-bit systems, you should always use this type where it is
|
|
specified in the documentation of Python/C API routines.</p><h4><a name="CallingConventions"></a>Windows Calling Conventions</h4><p>The <span style="font-family: monospace;">__stdcall</span> and <span style="font-family: monospace;">__cdecl</span> calling convention specifiers can be used in Pyrex, with the same syntax as used by C compilers on Windows, for example,</p><pre style="margin-left: 40px;">cdef extern int __stdcall FrobnicateWindow(long handle)<br><br>cdef void (__stdcall *callback)(void *)<br></pre>If __stdcall is used, the function is only considered compatible with other __stdcall functions of the same signature.<br>
|
|
|
|
|
|
|
|
<hr width="100%">
|
|
<h3> <a name="CNameSpecs"></a>Resolving naming conflicts - C name specifications</h3>
|
|
|
|
|
|
Each Pyrex module has a single module-level namespace for both Python
|
|
and C names. This can be inconvenient if you want to wrap some external
|
|
C functions and provide the Python user with Python functions of the same
|
|
names.
|
|
<p>Pyrex 0.8 provides a couple of different ways of solving this problem.
|
|
The best way, especially if you have many C functions to wrap, is probably
|
|
to put the extern C function declarations into a different namespace using
|
|
the facilities described in the section on <a href="sharing.html">sharing
|
|
declarations between Pyrex modules</a>. </p>
|
|
|
|
|
|
|
|
<p>The other way is to use a <b>c name specification</b> to give different
|
|
Pyrex and C names to the C function. Suppose, for example, that you want
|
|
to wrap an external function called <tt>eject_tomato</tt>. If you declare
|
|
it as </p>
|
|
|
|
|
|
|
|
<blockquote>
|
|
<pre>cdef extern void c_eject_tomato "eject_tomato" (float speed)</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
then its name inside the Pyrex module will be <tt>c_eject_tomato</tt>,
|
|
whereas its name in C will be <tt>eject_tomato</tt>. You can then wrap it
|
|
with
|
|
<blockquote>
|
|
<pre>def eject_tomato(speed):<br> c_eject_tomato(speed)</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
so that users of your module can refer to it as <tt>eject_tomato</tt>.
|
|
|
|
<p>Another use for this feature is referring to external names that happen
|
|
to be Pyrex keywords. For example, if you want to call an external function
|
|
called <tt>print</tt>, you can rename it to something else in your Pyrex
|
|
module. </p>
|
|
|
|
|
|
|
|
<p>As well as functions, C names can be specified for variables, structs,
|
|
unions, enums, struct and union members, and enum values. For example, </p>
|
|
|
|
|
|
|
|
<blockquote>
|
|
<pre>cdef extern int one "ein", two "zwei"<br>cdef extern float three "drei"<br><br>cdef struct spam "SPAM":<br> int i "eye"</pre>
|
|
|
|
<tt>cdef enum surprise "inquisition":</tt> <br>
|
|
|
|
<tt> first "alpha"</tt> <br>
|
|
|
|
<tt> second "beta" = 3</tt></blockquote>
|
|
|
|
|
|
|
|
<hr width="100%">
|
|
<h3><a name="Using_Pyrex_Declarations_from_C"></a>Using Pyrex Declarations from C</h3>Pyrex
|
|
provides two methods for making C declarations from a Pyrex module
|
|
available for use by external C code – public declarations and C API
|
|
declarations.<br><br><div style="margin-left: 40px;"><span style="font-weight: bold;">NOTE:</span> You do <span style="font-style: italic;">not</span> need to use either of these to make declarations from one Pyrex module available to another Pyrex module – you should use the <span style="font-weight: bold;">cimport</span> statement for that. <a href="sharing.html">Sharing Declarations Between
|
|
Pyrex Modules</a>.</div><h4><a name="PublicDecls"></a>Public Declarations</h4>
|
|
|
|
|
|
You can make C types, variables and functions defined in a Pyrex module accessible
|
|
to C code that is linked with the module, by declaring them with the <b><tt>public</tt></b> keyword:
|
|
<blockquote><tt>cdef public struct Bunny: # public type declaration<br> int vorpalness<br><br>cdef public int spam # public variable declaration</tt>
|
|
<p><tt>cdef public void grail(Bunny *): # public function declaration</tt> <br>
|
|
|
|
<tt> ...</tt></p>
|
|
|
|
</blockquote>
|
|
|
|
|
|
If there are any <tt>public</tt> declarations in a Pyrex module, a header file called <b><span style="font-style: italic;">modulename</span>.h</b> file is generated containing equivalent C declarations for inclusion in other
|
|
C code.<br><br>Any
|
|
C code wanting to make use of these declarations will need to be
|
|
linked, either statically or dynamically, with the extension module.<br><br>If
|
|
the Pyrex module resides within a package, then the name of the .h file
|
|
consists of the full dotted name of the module, e.g. a module called <span style="font-weight: bold;">foo.spam</span> would have a header file called <span style="font-weight: bold;">foo.spam.h</span>.
|
|
<h4><a name="C_API_Declarations"></a>C API Declarations</h4><p>The other way of making functions available to C code is by declaring them with the <span style="font-family: monospace; font-weight: bold;">api</span> keyword. A header file called "<span style="font-weight: bold;"><span style="font-style: italic;">modulename</span>_api.h</span>" is produced containing declarations of the functions, and a function called <span style="font-weight: bold;">import_<span style="font-style: italic;">modulename</span>()</span>.</p><p>C code wanting to use the functions needs to include the header and call the import_<span style="font-style: italic;">modulename</span>() function. The other functions can then be called as usual.</p><p>Any <span style="font-family: monospace;">public</span> type declarations in the Pyrex module are also made available when you include <span style="font-style: italic;">modulename</span>_api.h.</p><table style="text-align: left; width: 100%;" border="0" cellpadding="5" cellspacing="2"><tbody><tr><td style="background-color: rgb(102, 204, 204);"><pre>delorean.pyx</pre></td><td style="background-color: rgb(255, 153, 0);"><pre>marty.c</pre></td></tr><tr><td style="vertical-align: top; background-color: rgb(102, 204, 204);"><pre>cdef public struct Vehicle:<br> int speed<br> float power<br><br>cdef api void activate(Vehicle *v):<br> if v.speed >= 88 \<br> and v.power >= 1.21:<br> print "Time travel achieved"</pre></td><td style="background-color: rgb(255, 153, 0);"><pre>#include "delorean_api.h"<br><br>Vehicle car;<br><br>int main(int argc, char *argv[]) {<br> import_delorean();<br> car.speed = atoi(argv[1]);<br> car.power = atof(argv[2]); <br> activate(&car);<br>}</pre></td></tr></tbody></table><br>This
|
|
method does not require the C code using the functions to be linked
|
|
with the extension module in any way, as the Python import machinery is
|
|
used to make the connection dynamically. However, only functions can be
|
|
accessed this way, not variables.You can use both <span style="font-family: monospace;">public</span> and <span style="font-family: monospace;">api</span> on the same function to make it available by both methods, e.g.<br><pre style="margin-left: 40px;">cdef public api void belt_and_braces():<br> ...<br></pre>However, note that you should include <span style="font-weight: bold;">either</span> <span style="font-style: italic;">modulename</span>.h <span style="font-weight: bold;">or</span> <span style="font-style: italic;">modulename</span>_api.h in a given C file, <span style="font-style: italic;">not</span> both, otherwise you may get conflicting dual definitions.<br><br>If the Pyrex module resides within a package, then:<br><ul><li>The name of the header file contains of the full dotted name of the module.</li><li>The name of the importing function contains the full name with dots replaced by double underscores.</li></ul>E.g. a module called <span style="font-weight: bold;">foo.spam</span> would have an API header file called <span style="font-weight: bold;">foo.spam_api.h</span> and an importing function called <span style="font-weight: bold;">import_foo__spam()</span>.<h2>
|
|
<hr width="100%">Extension Types
|
|
<hr width="100%"></h2>
|
|
|
|
|
|
One of the most powerful features of Pyrex is the ability to easily create
|
|
new built-in Python types, called <b>extension types</b>. This is a major
|
|
topic in itself, so there is a <a href="extension_types.html">separate
|
|
page</a> devoted to it.
|
|
<h2>
|
|
<hr width="100%">Sharing Declarations Between Pyrex Modules
|
|
<hr width="100%"></h2>
|
|
|
|
|
|
Pyrex 0.8 introduces a substantial new set of facilities allowing a Pyrex
|
|
module to easily import and use C declarations and extension types from another
|
|
Pyrex module. You can now create a set of co-operating Pyrex modules just
|
|
as easily as you can create a set of co-operating Python modules. There is
|
|
a <a href="sharing.html">separate page</a> devoted to this topic.
|
|
<h2>
|
|
<hr width="100%"><a name="Limitations"></a>Limitations
|
|
<hr width="100%"></h2>
|
|
|
|
|
|
|
|
<h3> <a name="Unsupported"></a>Unsupported Python features</h3>
|
|
|
|
|
|
Pyrex is not quite a full superset of Python. The following restrictions
|
|
apply:
|
|
<blockquote> <li> Function definitions (whether using <b>def</b> or <b>cdef</b>)
|
|
cannot be nested within other function definitions.<br>
|
|
|
|
</li>
|
|
|
|
<li> Class definitions can only appear at the top level of a module,
|
|
not inside a function.<br>
|
|
|
|
</li>
|
|
|
|
<li> The<tt> import *</tt> form of import is not allowed anywhere
|
|
(other forms of the import statement are fine, though).<br>
|
|
|
|
</li>
|
|
|
|
<li> Generators cannot be defined in Pyrex.<br>
|
|
|
|
<br>
|
|
|
|
</li>
|
|
|
|
<li> The <tt>globals()</tt> and <tt>locals()</tt> functions cannot be
|
|
used.</li>
|
|
|
|
</blockquote>
|
|
|
|
|
|
The above restrictions will most likely remain, since removing them would
|
|
be difficult and they're not really needed for Pyrex's intended applications.
|
|
|
|
<p>There are also some temporary limitations, which may eventually be lifted, including:
|
|
</p>
|
|
|
|
|
|
|
|
<blockquote> <li> Class and function definitions cannot be placed inside
|
|
control structures.<br>
|
|
|
|
</li>
|
|
|
|
<li> In-place arithmetic operators (+=, etc) are not yet supported.<br>
|
|
|
|
</li>
|
|
|
|
<li> List comprehensions are not yet supported.<br>
|
|
|
|
</li>
|
|
|
|
<li> There is no support for Unicode.<br>
|
|
|
|
</li>
|
|
|
|
<li> Special methods of extension types cannot have functioning
|
|
docstrings.<br>
|
|
|
|
<br>
|
|
|
|
</li>
|
|
|
|
<li> The use of string literals as comments is not recommended at present,
|
|
because Pyrex doesn't optimize them away, and won't even accept them in
|
|
places where executable statements are not allowed.</li>
|
|
|
|
</blockquote>
|
|
|
|
|
|
<h3> <a name="SemanticDifferences"></a>Semantic differences between Python
|
|
and Pyrex</h3>
|
|
|
|
|
|
|
|
<h4> Behaviour of class scopes</h4>
|
|
|
|
|
|
In Python, referring to a method of a class inside the class definition,
|
|
i.e. while the class is being defined, yields a plain function object, but
|
|
in Pyrex it yields an unbound method<sup><font size="-2"><a href="#Footnote2">2</a></font></sup>. A consequence of this is that the
|
|
usual idiom for using the classmethod and staticmethod functions, e.g.
|
|
<blockquote>
|
|
<pre>class Spam:</pre>
|
|
|
|
|
|
<pre> def method(cls):<br> ...</pre>
|
|
|
|
|
|
<pre> method = classmethod(method)</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
will not work in Pyrex. This can be worked around by defining the function
|
|
<i>outside</i> the class, and then assigning the result of classmethod or
|
|
staticmethod inside the class, i.e.
|
|
<blockquote>
|
|
<pre>def Spam_method(cls):<br> ...</pre>
|
|
|
|
|
|
<pre>class Spam:</pre>
|
|
|
|
|
|
<pre> method = classmethod(Spam_method)</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
|
|
<h1>
|
|
<hr width="100%"><font size="+0">Footnotes</font>
|
|
<hr width="100%"></h1>
|
|
|
|
|
|
<a name="Footnote1"></a>1. A problem with const could arise if you have
|
|
something like
|
|
<blockquote>
|
|
<pre>cdef extern from "grail.h":<br> char *nun</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
where grail.h actually contains
|
|
<blockquote>
|
|
<pre>extern const char *nun;</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
and you do
|
|
<blockquote>
|
|
<pre>cdef void languissement(char *s):<br> #something that doesn't change s</pre>
|
|
|
|
|
|
<pre>...</pre>
|
|
|
|
|
|
<pre>languissement(nun)</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
which will cause the C compiler to complain. You can work around it by
|
|
casting away the constness:
|
|
<blockquote>
|
|
<pre>languissement(<char *>nun)</pre>
|
|
|
|
</blockquote>
|
|
|
|
|
|
|
|
<hr width="100%"><a name="Footnote2"></a>2. The reason for the different behaviour
|
|
of class scopes is that Pyrex-defined Python functions are PyCFunction objects,
|
|
not PyFunction objects, and are not recognised by the machinery that creates
|
|
a bound or unbound method when a function is extracted from a class. To get
|
|
around this, Pyrex wraps each method in an unbound method object itself before
|
|
storing it in the class's dictionary. <br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
|
|
</body></html> |