summaryrefslogtreecommitdiffstats
path: root/debian/pyrex/pyrex-0.9.9/Doc/Manual/basics.html
diff options
context:
space:
mode:
Diffstat (limited to 'debian/pyrex/pyrex-0.9.9/Doc/Manual/basics.html')
-rw-r--r--debian/pyrex/pyrex-0.9.9/Doc/Manual/basics.html1118
1 files changed, 1118 insertions, 0 deletions
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/Manual/basics.html b/debian/pyrex/pyrex-0.9.9/Doc/Manual/basics.html
new file mode 100644
index 00000000..132c2899
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Doc/Manual/basics.html
@@ -0,0 +1,1118 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html><head>
+<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>Language Basics</title>
+
+</head>
+<body>
+<h1>
+<hr style="width: 100%; height: 2px;">Language
+Basics
+<hr width="100%"></h1>
+<ul id="mozToc">
+<!--mozToc h2 1 h3 2--><li><a href="#mozTocId641350">Python
+functions vs. C functions</a></li>
+<li><a href="#mozTocId972536">Python objects as
+parameters
+and return values</a></li>
+<li><a href="#mozTocId155104">C
+variable and type definitions</a>
+<ul>
+<li><a href="#mozTocId890190">Forward
+Declarations</a></li>
+<li><a href="#mozTocId522210">Grouping
+multiple C declarations</a></li>
+</ul>
+</li>
+<li><a href="#mozTocId763321">Automatic
+type conversions</a>
+<ul>
+<li><a href="#mozTocId440941">Caveats
+when using a Python string in a C context</a></li>
+</ul>
+</li>
+<li><a href="#mozTocId834148">Scope rules</a></li>
+<li><a href="#mozTocId954330">Statements and
+expressions</a>
+<ul>
+<li><a href="#mozTocId401576">Differences
+between C
+and Pyrex
+expressions</a></li>
+<li><a href="#mozTocId899067">Integer for-loops</a></li>
+<li><a href="#mozTocId457396">Catching
+exceptions and tracebacks</a></li>
+</ul>
+</li>
+<li><a href="#mozTocId482761">Error return values</a>
+<ul>
+<li><a href="#mozTocId622828">Checking
+return values of non-Pyrex functions</a></li>
+</ul>
+</li>
+<li><a href="#mozTocId494354">The include
+statement</a></li>
+<li><a href="#mozTocId849661">Keyword-only
+arguments</a></li>
+<li><a href="#mozTocId829237">Built-in Names</a>
+<ul>
+<li><a href="#mozTocId813519">Built-in
+Constants</a></li>
+<li><a href="#mozTocId593628">Built-in
+Functions</a></li>
+<li><a href="#mozTocId452377">Built-in Types</a></li>
+</ul>
+</li>
+<li><a href="#mozTocId42018">Conditional
+Compilation</a>
+<ul>
+<li><a href="#mozTocId379306">Compile-Time
+Definitions</a></li>
+<li><a href="#mozTocId997015">Conditional
+Statements</a></li>
+</ul>
+</li>
+</ul>
+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="external.html">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>
+<h2><a class="mozTocH2" name="mozTocId641350"></a>
+<a name="PyFuncsVsCFuncs"></a>Python
+functions vs. C functions</h2>
+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>&nbsp;&nbsp;&nbsp; ...</pre>
+<pre>cdef int eggs(unsigned long l, float f):<br>&nbsp;&nbsp;&nbsp; ...</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>
+<h2><a class="mozTocH2" name="mozTocId972536"></a>
+<a name="PyObjParams"></a>Python objects as
+parameters
+and return values</h2>
+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>&nbsp;&nbsp;&nbsp; ...</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>&nbsp;&nbsp;&nbsp; ...</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>&nbsp;&nbsp;&nbsp; ...</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.
+<h2><a class="mozTocH2" name="mozTocId155104"></a><a name="CVarAndTypeDecls"></a>C
+variable and type definitions</h2>
+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>&nbsp;&nbsp;&nbsp; int age<br>&nbsp;&nbsp;&nbsp; float volume</pre>
+<pre>cdef union Food:<br>&nbsp;&nbsp;&nbsp; char *spam<br>&nbsp;&nbsp;&nbsp; float *eggs</pre>
+<pre>cdef enum CheeseType:<br>&nbsp;&nbsp;&nbsp; cheddar, edam,&nbsp;<br>&nbsp;&nbsp;&nbsp; camembert</pre>
+<pre>cdef enum CheeseState:<br>&nbsp;&nbsp;&nbsp; hard = 1<br>&nbsp;&nbsp;&nbsp; soft = 2<br>&nbsp;&nbsp;&nbsp; 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>&nbsp;&nbsp;&nbsp;
+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 class="mozTocH2" name="mozTocId890190"></a>Forward
+Declarations</h3>
+If
+you have two struct or union types containing pointers that refer to
+each other, you will need to use a forward declaration for at least one
+of them. This is simply the header of a struct or union without the
+colon or body, for example,<br>
+<br>
+<div style="margin-left: 40px;"><span style="font-family: monospace;">cdef struct Sandwich</span><br style="font-family: monospace;">
+<br style="font-family: monospace;">
+<span style="font-family: monospace;">cdef struct Lunchbox:</span><br style="font-family: monospace;">
+<div style="margin-left: 40px;"><span style="font-family: monospace;">Sandwich *lunch</span><br style="font-family: monospace;">
+</div>
+<br style="font-family: monospace;">
+<span style="font-family: monospace;">cdef struct Sandwich:</span><br style="font-family: monospace;">
+<div style="margin-left: 40px;"><span style="font-family: monospace;">Lunchbox *container</span><br>
+</div>
+</div>
+<br>
+You
+can also forward-declare C functions, but there should be little need
+to do this. Pyrex processes all declarations in a module before
+analysing any executable statements, so calling a function defined
+further down in the source file is usually not a problem.
+<h3><a class="mozTocH2" name="mozTocId522210"></a><a name="Grouping_multiple_C_declarations"></a>Grouping
+multiple C declarations</h3>
+If you have a series of declarations that all begin with <span style="font-family: monospace;">cdef</span>, you can
+group them into a cdef block like this:<br>
+<pre style="margin-left: 40px;">cdef:<br><br> struct Spam:<br> int tons<br><br> int i<br> float f<br> Spam *p<br><br> void f(Spam *s):<br> print s.tons, "Tons of spam"<br> </pre>
+<h2><a class="mozTocH2" name="mozTocId763321"></a><a name="AutomaticTypeConversions"></a>Automatic
+type conversions</h2>
+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="text-align: left; background-color: rgb(204, 255, 255); width: 10%; margin-left: 40px;" border="1" cellpadding="4" cellspacing="0">
+<tbody>
+<tr>
+<th style="vertical-align: top; width: 40%; white-space: nowrap; background-color: rgb(255, 204, 51);">C
+types<br>
+</th>
+<th style="vertical-align: top; width: 150px; white-space: nowrap; background-color: rgb(255, 204, 51);">From
+Python types<br>
+</th>
+<th style="vertical-align: top; width: 150px; white-space: nowrap; background-color: rgb(255, 204, 51);">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>
+<h3><a class="mozTocH3" name="mozTocId440941"></a><a name="PyToCStringCaveats"></a>Caveats
+when using a Python string in a C context</h3>
+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.
+<h2><a class="mozTocH2" name="mozTocId834148"></a><a name="ScopeRules"></a>Scope rules</h2>
+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.<br>
+<br>
+This can result in some odd things happening under rare circumstances,
+for example<br>
+<br>
+<div style="margin-left: 40px;"><tt>print __name__</tt></div>
+<p>In
+Pyrex, instead of printing the name of the current module, this prints
+the name of the builtins module. The reason is that because Pyrex
+hasn't seen a declaration of anything called <span style="font-family: monospace;">__name__</span> in the
+module, it's assumed to reside in the builtins. The solution is to use
+a <span style="font-weight: bold;">global</span>
+statement to declare <span style="font-family: monospace;">__name__</span>
+as a module-level name:</p>
+<p style="margin-left: 40px;"><tt>global
+__name__</tt><tt><br>
+print __name__</tt></p>
+Another
+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>&nbsp; x = True<br>except NameError:<br>&nbsp; True = 1<br></pre>
+</blockquote>
+because, due to the assignment in the last line, <span style="font-family: monospace;">True</span> 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%">
+<h2><a class="mozTocH2" name="mozTocId954330"></a><a name="StatsAndExprs"></a>Statements and
+expressions</h2>
+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>
+<h3><a class="mozTocH3" name="mozTocId401576"></a>
+<a name="ExprSyntaxDifferences"></a>Differences
+between C
+and Pyrex
+expressions</h3>
+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>-&gt;</tt></b>
+operator
+in Pyrex. Instead of <tt>p-&gt;x</tt>, use <tt>p.x</tt></li>
+&nbsp; <li> There is no <b><tt>*</tt></b>
+operator in Pyrex. Instead of <tt>*p</tt>, use <tt>p[0]</tt></li>
+&nbsp; <li> There is an <b><tt>&amp;</tt></b>
+operator, with the same semantics as in C.</li>
+&nbsp; <li>
+The null C pointer is called <b><tt>NULL</tt></b>,
+not 0 (and <tt>NULL</tt> is a reserved word).</li>
+&nbsp; <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>&lt;type&gt;value</tt></b>
+, for example:</li>
+<ul>
+<pre>cdef char *p, float *q<br>p = &lt;char*&gt;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>Operator Precedence</h4>
+Keep in mind that there are
+some differences
+in operator precedence between Python and C, and that Pyrex uses the
+Python precedences, not the C ones.
+<h3><a class="mozTocH3" name="mozTocId899067"></a>Integer
+for-loops</h3>
+You should be aware that a for-loop such as
+<blockquote><tt>for
+i in range(n):</tt> <br>
+<tt>&nbsp;&nbsp;&nbsp;
+...</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 0 &lt;= i
+&lt; n:</tt> <br>
+<tt>&nbsp;&nbsp;&nbsp;
+...</tt></blockquote>
+Provided 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 integer for-loop: </p>
+<ul>
+<li> The target expression (the middle one) must be a variable
+name.</li>
+<li>The direction of iteration is
+determined by the relations. If they are both from the set {<tt>&lt;</tt>,
+<tt>&lt;=</tt>} then it is upwards; if they are
+both
+from the set {<tt>&gt;</tt>, <tt>&gt;=</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.
+<h3><a class="mozTocH3" name="mozTocId457396"></a>Catching
+exceptions and tracebacks</h3>
+For
+reasons of efficiency, there are some differences between Pyrex and
+Python concerning the way exceptions caught by a try-except statement
+are handled.<br>
+<ul>
+<li>Exceptions caught by an <span style="font-family: monospace;">except</span> clause <span style="font-style: italic;">cannot</span> be retrieved
+using <span style="font-family: monospace;">sys.exc_info()</span>.
+To access the caught exception, you must bind it to a name in the
+except clause.<br><br>Pyrex also allows an additional name to be provided for
+catching the traceback. For example,</li>
+</ul>
+<pre style="margin-left: 80px;">try:<br>&nbsp;&nbsp;&nbsp; start_engine()<br>except HovercraftError, e, tb:<br>&nbsp;&nbsp;&nbsp; print "Got an error:", e<br>&nbsp;&nbsp;&nbsp; traceback.print_tb(tb)</pre>
+<ul>
+<li>A <span style="font-family: monospace;">raise</span>
+statement with no arguments (to re-raise the last exception caught)
+must be lexically enclosed in the <span style="font-family: monospace;">except</span> clause
+which caught the exception. A raise statement in a Python function
+called from the except clause will <span style="font-style: italic;">not</span>
+work.</li>
+</ul>
+<pre style="margin-left: 80px;">try:<br> start_engine()<br>except HovercraftError, e:<br> print "Unable to start:", e<br> raise # the exception caught by the enclosing except clause</pre>
+<h2><a class="mozTocH2" name="mozTocId329136"></a>
+<hr width="100%"></h2>
+<h2><a class="mozTocH2" name="mozTocId482761"></a><a name="ExceptionValues"></a>Error return values</h2>
+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>&nbsp;&nbsp;&nbsp;
+...</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>&nbsp;&nbsp;&nbsp;
+...</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>&nbsp;&nbsp;&nbsp;
+...</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>
+&nbsp; <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>
+<h3><a class="mozTocH3" name="mozTocId622828"></a>
+<a name="CheckingReturnValues"></a>Checking
+return values of non-Pyrex functions</h3>
+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>&nbsp;&nbsp;&nbsp; raise SpamError("Couldn't open the spam file")</pre>
+</blockquote>
+<h4>
+<hr width="100%"></h4>
+<h2><a class="mozTocH2" name="mozTocId494354"></a>
+<a name="IncludeStatement"></a>The <tt>include</tt>
+statement</h2>
+A&nbsp;Pyrex source file can include material from other files
+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
+statements or declarations that are valid in the context where the
+include statement appears, including other <b>include</b>
+statements. The contents of the included file should begin at an
+indentation level of zero, and will be treated as though they were
+indented to the level of the include statement that is including the
+file.<br>
+<br>
+Note
+that there are other mechanisms available for splitting Pyrex code into
+separate parts that may be more appropriate in many cases. See<a href="sharing.html"> Sharing Declarations Between
+Pyrex Modules</a>.<br>
+<hr style="width: 100%; height: 2px;">
+<h2><a class="mozTocH2" name="mozTocId849661"></a><a name="KeywordOnlyArguments"></a>Keyword-only arguments</h2>
+<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.<br>
+<br>
+<hr style="width: 100%; height: 2px;">
+<h2><a class="mozTocH2" name="mozTocId829237"></a><a name="Built-in_Names"></a>Built-in Names</h2>
+Pyrex
+knows about many of the names in the builtin namespace, and treats them
+specially in the interests of generating efficient code.<br>
+<h3><a class="mozTocH3" name="mozTocId813519"></a><a name="Built-in_Constants"></a>Built-in Constants</h3>
+Pyrex
+knows the following built-in constant and type names, and references
+their values directly instead of using a dictionary lookup.<br>
+<br>
+<table style="background-color: rgb(204, 255, 255); width: 10px; margin-left: 40px;" border="1" cellpadding="5" cellspacing="0">
+<tbody>
+<tr>
+<td style="vertical-align: top; white-space: nowrap; text-align: left; background-color: rgb(255, 204, 0);">Type
+objects (type <span style="font-family: monospace;">type</span>)</td>
+<td colspan="2" rowspan="1" style="vertical-align: top; white-space: nowrap; text-align: left; background-color: rgb(255, 204, 0);">Exceptions
+(type <span style="font-family: monospace;">type</span>)</td>
+</tr>
+<tr>
+<td style="vertical-align: top; white-space: nowrap; text-align: left; height: 10px;">buffer<br>
+enumerate<br>
+file<br>
+float<br>
+int<br>
+long<br>
+open<br>
+property<br>
+str<br>
+tuple<br>
+xrange</td>
+<td colspan="1" rowspan="3" align="left" nowrap="nowrap" valign="top">Exception<br>
+StopIteration<br>
+StandardError<br>
+ArithmeticError<br>
+LookupError<br>
+AsssertionError<br>
+EOFError<br>
+FloatingPointError<br>
+EnvironmentError<br>
+IOError<br>
+OSError<br>
+ImportError<br>
+IndexError<br>
+KeyError<br>
+KeyboardInterrupt<br>
+MemoryError<br>
+NameError<br>
+OverflowError<br>
+RuntimeError<br>
+NotImplementedError<br>
+SyntaxError</td>
+<td colspan="1" rowspan="3" style="vertical-align: top; white-space: nowrap; text-align: left;">IndentationError<br>
+TabError<br>
+ReferenceError<br>
+SystemError<br>
+SystemExit<br>
+TypeError<br>
+UnboundLocalError<br>
+UnicodeError<br>
+UnicodeEncodeError<br>
+UnicodeDecodeError<br>
+UnicodeTranslateError<br>
+ValueError<br>
+ZeroDivisionError<br>
+Warning<br>
+UserWarning<br>
+DeprecationWarning<br>
+PendingDeprecationWarning<br>
+SyntaxWarning<br>
+OverflowWarning<br>
+RuntimeWarning<br>
+FutureWarning</td>
+</tr>
+<tr>
+<td style="vertical-align: top; white-space: nowrap; text-align: left; height: 10px; background-color: rgb(255, 204, 0);">Constants
+(type <span style="font-family: monospace;">object</span>)</td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">True<br>
+False<br>
+Ellipsis</td>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+</tbody>
+</table>
+<br>
+Note that although some of the above names refer to type objects, they
+are not Pyrex type names and therefore can't be used to declare the
+type of a variable. Only the names listed under Built-in Types below
+can be used as type names in declarations.<br>
+<h3><a class="mozTocH3" name="mozTocId593628"></a><a name="Built-in_Functions"></a>Built-in Functions</h3>
+Pyrex
+compiles calls to the following built-in functions into direct calls to
+the corresponding Python/C API routines, making them particularly fast.<br>
+<br>
+<table style="text-align: left; background-color: rgb(204, 255, 255); margin-left: 40px;" border="1" cellpadding="4" cellspacing="0">
+<tbody>
+<tr>
+<td style="font-weight: bold; background-color: rgb(255, 204, 51);">Function
+and arguments</td>
+<td style="font-weight: bold; background-color: rgb(255, 204, 51);">Return
+type</td>
+<td style="font-weight: bold; white-space: nowrap; background-color: rgb(255, 204, 51);">Python/C
+API Equivalent</td>
+</tr>
+<tr>
+<td>abs(obj)</td>
+<td>object</td>
+<td>PyNumber_Absolute</td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">bool(obj)
+&nbsp; <span style="font-style: italic;">(Note 3)</span></td>
+<td align="left" nowrap="nowrap" valign="top">int</td>
+<td align="left" nowrap="nowrap" valign="top">PyObject_IsTrue</td>
+</tr>
+<tr>
+<td>delattr(obj,&nbsp;name)</td>
+<td>int</td>
+<td>PyObject_DelAttr</td>
+</tr>
+<tr>
+<td>dir(obj)</td>
+<td>object</td>
+<td>PyObject_Dir</td>
+</tr>
+<tr>
+<td>divmod(x, y)</td>
+<td>object</td>
+<td>PyNumber_Divmod</td>
+</tr>
+<tr>
+<td style="white-space: nowrap;">getattr(obj,&nbsp;name)
+<span style="font-style: italic;">&nbsp; (Note 1</span>)<br>
+getattr3(obj, name, default)</td>
+<td>object</td>
+<td>PyObject_GetAttr</td>
+</tr>
+<tr>
+<td>hasattr(obj, name)</td>
+<td>int</td>
+<td>PyObject_HasAttr</td>
+</tr>
+<tr>
+<td>hash(obj)</td>
+<td>int</td>
+<td>PyObject_Hash</td>
+</tr>
+<tr>
+<td>cintern(char *)<span style="font-style: italic;">
+&nbsp; (Note 5)</span></td>
+<td>object</td>
+<td>PyString_InternFromString</td>
+</tr>
+<tr>
+<td>isinstance(obj, type)</td>
+<td>int</td>
+<td>PyObject_IsInstance</td>
+</tr>
+<tr>
+<td>issubclass(obj, type)</td>
+<td>int</td>
+<td>PyObject_IsSubclass</td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">issubtype(type,
+type) &nbsp; <span style="font-style: italic;">(Note 4</span>)</td>
+<td align="left" nowrap="nowrap" valign="top">int</td>
+<td align="left" nowrap="nowrap" valign="top">PyType_IsSubType</td>
+</tr>
+<tr>
+<td>iter(obj)</td>
+<td>object</td>
+<td>PyObject_GetIter</td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">iter2(obj,
+obj)</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top">PyCallIter_New</td>
+</tr>
+<tr>
+<td>len(obj)</td>
+<td>Py_ssize_t</td>
+<td>PyObject_Length</td>
+</tr>
+<tr>
+<td style="width: 1px;">pow(x, y, z) <span style="font-style: italic;">&nbsp; (Note 2)</span></td>
+<td style="width: 1px;">object</td>
+<td style="width: 1px;">PyNumber_Power</td>
+</tr>
+<tr>
+<td>reload(obj)</td>
+<td>object</td>
+<td>PyImport_ReloadModule</td>
+</tr>
+<tr>
+<td>repr(obj)</td>
+<td>object</td>
+<td>PyObject_Repr</td>
+</tr>
+<tr>
+<td style="width: 200px;">setattr(obj,&nbsp;name)</td>
+<td style="width: 100px;">void</td>
+<td style="width: 150px;">PyObject_SetAttr</td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">typecheck(obj,
+type) &nbsp; <span style="font-style: italic;">(Note
+4)</span></td>
+<td align="left" nowrap="nowrap" valign="top">int</td>
+<td align="left" nowrap="nowrap" valign="top">PyObject_TypeCheck</td>
+</tr>
+</tbody>
+</table>
+<br>
+<div style="margin-left: 40px;"><span style="font-style: italic;">Note 1:</span> There are
+two different functions corresponding to the Python <span style="font-family: monospace;">getattr</span>
+depending on whether a third argument is used. In a non-call context,
+they both evaluate to the Python <span style="font-family: monospace;">getattr</span>
+function.<br>
+<br>
+<span style="font-style: italic;">Note 2:</span>
+Only the three-argument form of <span style="font-family: monospace;">pow()</span> is
+supported. Use the <span style="font-family: monospace;">**</span>
+operator otherwise.<br>
+<br>
+<span style="font-style: italic;">Note 3:</span> In
+a non-call context, the name <span style="font-family: monospace;">bool</span>
+refers to the Python built-in bool type.<br>
+<br>
+<span style="font-style: italic;">Note 4:</span> The
+functions <span style="font-family: monospace;">typecheck</span>
+and <span style="font-family: monospace;">issubtype</span>
+have no exact Python equivalent. They are included for fast, safe type
+checking of extension types. They are safer than using <span style="font-family: monospace;">isinstance</span> and <span style="font-family: monospace;">issubclass</span>
+for this purpose, because the behaviour of the latter functions can be
+overridden, so they don't necessarily reflect the true C types of the
+objects involved.<br>
+<br>
+<span style="font-style: italic;">Note 5:</span>
+This function is named <span style="font-family: monospace;">cintern</span>
+instead of <span style="font-family: monospace;">intern</span>
+because it takes a null-terminated C string rather than a Python
+string, and therefore cannot handle strings containing null bytes.<br>
+</div>
+<br>
+Only
+direct function calls using these names are optimised. If you do
+something else with one of these names that assumes it's a Python
+object, such as assign it to a Python variable, and later call it, the
+call will be made as a Python function call.
+<h3><a class="mozTocH3" name="mozTocId452377"></a><a name="BuiltinTypes"></a>Built-in Types</h3>
+Pyrex
+knows about the following builtin
+types:<br>
+<br>
+<div style="margin-left: 40px;"><span style="font-family: monospace;">dict</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">list</span><br>
+<span style="font-family: monospace;">object</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">slice</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">type</span><br>
+</div>
+<br>
+If you declare a variable as being of one of these types, then
+calls to the methods in the table below will be compiled to direct
+Python/C API calls,
+avoiding the overhead of a Python attribute lookup and function call.
+In the case of attributes, they will be accessed directly from the
+object's C struct.<br>
+<br>
+Referring to the types themselves is also
+slightly more efficient, because the relevant type object is accessed
+directly rather than via a global variable lookup.<br>
+<br>
+<table style="text-align: left; background-color: rgb(204, 255, 255); width: 665px; height: 330px;" border="1" cellpadding="4" cellspacing="0">
+<tbody>
+<tr>
+<td style="font-weight: bold; background-color: rgb(255, 204, 51);">Method
+or Attribute</td>
+<td style="font-weight: bold; background-color: rgb(255, 204, 51);">Return
+type</td>
+<td colspan="1" rowspan="1" style="font-weight: bold; white-space: nowrap; background-color: rgb(255, 204, 51);">Python/C
+API Equivalent</td>
+<td style="background-color: rgb(255, 204, 51); font-weight: bold;" align="left" nowrap="nowrap">Notes</td>
+</tr>
+<tr>
+<td colspan="4" rowspan="1" style="vertical-align: top; white-space: nowrap; text-align: left; background-color: rgb(51, 153, 153);"><span style="font-weight: bold;">Type </span><span style="font-family: monospace; font-weight: bold;">dict</span></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">clear()</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyDict_Clear</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">copy()</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyDict_Copy</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">items()</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top">PyDict_Items</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">keys()</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top">PyDict_Keys</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">values()</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top">PyDict_Values</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">merge(obj,
+override)</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyDict_Merge</td>
+<td align="left" nowrap="nowrap" valign="top">Merge
+items from a mapping</td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">update(obj)</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyDict_Update</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">merge_pairs(obj,&nbsp;override)</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyDict_MergeFromSeq2</td>
+<td align="left" nowrap="nowrap" valign="top">Merge
+(key, value) pairs from a sequence</td>
+</tr>
+<tr>
+<td colspan="4" rowspan="1" style="vertical-align: top; white-space: nowrap; text-align: left; background-color: rgb(51, 153, 153);"><span style="font-weight: bold;">Type </span><span style="font-family: monospace; font-weight: bold;">list</span></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">insert(int,
+obj)</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyList_Insert</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">append(obj)</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyList_Append</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">sort()</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyList_Sort</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">reverse()</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyList_Reverse</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">as_tuple()</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top">PyList_AsTuple</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td colspan="4" rowspan="1" style="vertical-align: top; white-space: nowrap; text-align: left; background-color: rgb(51, 153, 153);"><span style="font-weight: bold;">Type <span style="font-family: monospace;">slice</span></span></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">indices()</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top">PySlice_Indices</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">start</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">stop</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">step</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+</tbody>
+</table>
+<br>
+Some
+of the above methods have no direct Python equivalent, but are there to
+provide access to routines that exist in the Python/C API.<br>
+<br>
+As an example, the following compiles into code containing no Python
+attribute lookups or function calls.<br>
+<br>
+<div style="margin-left: 40px;"><span style="font-family: monospace;">cdef list cheeses</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">cheeses = []</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">cheeses.append("camembert")</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">cheeses.append("cheddar")</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">cheeses.insert(1,
+"something runny")</span><br style="font-family: monospace;">
+</div>
+<br>
+<hr style="width: 100%; height: 2px;">
+<h2><a class="mozTocH2" name="mozTocId42018"></a><a name="Conditional_Compilation"></a>Conditional
+Compilation</h2>
+Some features are available for conditional compilation and
+compile-time constants within a Pyrex source file.<br>
+<h3><a class="mozTocH3" name="mozTocId379306"></a><a name="Compile-Time_Definitions"></a>Compile-Time
+Definitions</h3>
+A compile-time constant can be defined using the <span style="font-family: monospace; font-weight: bold;">DEF</span>
+statement:<br>
+<pre style="margin-left: 40px;">DEF FavouriteFood = "spam"<br>DEF ArraySize = 42<br>DEF OtherArraySize = 2 * ArraySize + 17</pre>
+The
+right-hand side of the DEF must be a valid compile-time expression.
+Such expressions are made up of literal values and names defined using
+DEF statements, combined using any of the Python expression syntax.<br>
+<br>
+The following compile-time names are predefined, corresponding to the
+values returned by <span style="font-weight: bold;">os.uname()</span>.<br>
+<pre style="margin-left: 40px;">UNAME_SYSNAME, UNAME_NODENAME, UNAME_RELEASE,<br>UNAME_VERSION, UNAME_MACHINE</pre>
+The following selection of builtin constants and functions are also
+available:<br>
+<pre style="margin-left: 40px;">None, True, False,<br>abs, bool, chr, cmp, complex, dict, divmod, enumerate,<br>float, hash, hex, int, len, list, long, map, max, min,<br>oct, ord, pow, range, reduce, repr, round, slice, str,<br>sum, tuple, xrange, zip</pre>
+A
+name defined using DEF can be used anywhere an identifier can appear,
+and it is replaced with its compile-time value as though it were
+written into the source at that point as a literal. For this to work,
+the compile-time expression must evaluate to a Python value of type <span style="font-weight: bold;">int</span>, <span style="font-weight: bold;">long</span>, <span style="font-weight: bold;">float </span>or <span style="font-weight: bold;">str</span>.<br>
+<pre style="margin-left: 40px;">cdef int a1[ArraySize]<br>cdef int a2[OtherArraySize]<br>print "I like", FavouriteFood</pre>
+<h3><a class="mozTocH3" name="mozTocId997015"></a><a name="Conditional_Statements"></a>Conditional
+Statements</h3>
+The <span style="font-family: monospace; font-weight: bold;">IF</span>
+statement can be used to conditionally include or exclude sections of
+code at compile time. It works in a similar way to the <span style="font-weight: bold;">#if</span> preprocessor
+directive in C.<br>
+<pre style="margin-left: 40px;">IF UNAME_SYSNAME == "Windows":<br> include "icky_definitions.pxi"<br>ELIF UNAME_SYSNAME == "Darwin":<br> include "nice_definitions.pxi"<br>ELIF UNAME_SYSNAME == "Linux":<br> include "penguin_definitions.pxi"<br>ELSE:<br> include "other_definitions.pxi"</pre>
+The
+ELIF and ELSE clauses are optional. An IF statement can appear anywhere
+that a normal statement or declaration can appear, and it can contain
+any statements or declarations that would be valid in that context,
+including DEF statements and other IF statements.<br>
+<br>
+The
+expressions in the IF and ELIF clauses must be valid compile-time
+expressions as for the DEF statement, although they can evaluate to any
+Python value, and the truth of the result is determined in the usual
+Python way.<br>
+<br>
+---
+</body></html> \ No newline at end of file