diff options
Diffstat (limited to 'debian/pyrex/pyrex-0.9.9/Doc/Manual/extension_types.html')
-rw-r--r-- | debian/pyrex/pyrex-0.9.9/Doc/Manual/extension_types.html | 1079 |
1 files changed, 1079 insertions, 0 deletions
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/Manual/extension_types.html b/debian/pyrex/pyrex-0.9.9/Doc/Manual/extension_types.html new file mode 100644 index 00000000..3cd3dc42 --- /dev/null +++ b/debian/pyrex/pyrex-0.9.9/Doc/Manual/extension_types.html @@ -0,0 +1,1079 @@ +<!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>Extension Types</title></head> +<body> + + + +<h1> +<hr width="100%">Extension Types +<hr width="100%"></h1> + + + +<h2> Contents</h2> + + + +<ul> + + + <li> <a href="#Introduction">Introduction</a></li> + + + <li> <a href="#ExtTypeAttrs">Attributes</a></li> + <li><a href="#TypeDeclarations">Type declarations</a></li> + + + <li> <a href="#NotNone">Extension types and None</a></li> + + + <li> <a href="special_methods.html">Special methods</a></li> + + + <li> <a href="#Properties">Properties</a></li> + + + <li><a href="#SubclassingExtTypes">Subclassing</a></li> + + + <li> <a href="#CMethods">C Methods</a></li><li><a href="#ForwardDeclaringExtTypes">Forward-declaring extension types</a></li> + + <li><a href="#WeakRefs">Making extension types weak-referenceable</a><span style="color: rgb(255, 0, 0);"></span><br> + + + </li> + + + + <li> <a href="#PublicAndExtern">Public and external extension types</a><font color="#2f8b20"><br> + + + </font></li> + + + + + <ul> + + + <li> <a href="#ExternalExtTypes">External extension types</a></li> + + + <li> <a href="#ImplicitImport">Implicit importing</a><font color="#2f8b20"><br> + + + </font></li> + + + <li> <a href="#TypeVsConstructor">Type names vs. constructor names</a></li> + + + <li> <a href="#PublicExtensionTypes">Public extension types</a></li> + + + <li> <a href="#NameSpecClause">Name specification clause</a></li> + + + + + </ul> + + + +</ul> + + + +<h2> <a name="Introduction"></a>Introduction</h2> + + + As well as creating normal user-defined classes with the Python <b>class</b> +statement, Pyrex also lets you create new built-in Python types, known as +<i>extension types</i>. <br><br><table style="text-align: left; background-color: rgb(255, 255, 0); width: 554px; margin-left: 40px;" border="0" cellpadding="5" cellspacing="0"><tbody><tr><td style="vertical-align: top; text-align: left;">WARNING: There are substantial differences in the way many of the +special methods work in extension types compared to Python classes. +Before attempting to define any __xxx__ methods, read the section on <a href="special_methods.html">Special Methods of Extension Types.</a></td></tr></tbody></table><br>You define an extension type using the <b>cdef class</b> statement. Here's an example: +<blockquote><tt>cdef class Shrubbery:</tt> + + <p><tt> cdef int width, height</tt> </p> + + + + + <p><tt> def __init__(self, w, h):</tt> <br> + + + <tt> self.width = w</tt> <br> + + + <tt> self.height = h</tt> </p> + + + + + <p><tt> def describe(self):</tt> <br> + + + <tt> print "This shrubbery is", +self.width, \</tt> <br> + + + <tt> +"by", self.height, "cubits."</tt></p> + + + </blockquote> + + + As you can see, a Pyrex extension type definition looks a lot like a Python + class definition. Within it, you use the <b>def</b> statement to define +methods that can be called from Python code. You can even define many of +the special methods such as <tt>__init__</tt> as you would in Python. +<p>The main difference is that you can use the <b>cdef</b> statement to define +attributes. The attributes may be Python objects (either generic or of a particular +extension type), or they may be of any C data type. So you can use extension +types to wrap arbitrary C data structures and provide a Python-like interface +to them. </p> + + + +<h2> <a name="ExtTypeAttrs"></a>Attributes</h2> + + + Attributes of an extension type are stored directly in the object's C struct. + The set of attributes is fixed at compile time; you can't add attributes +to an extension type instance at run time simply by assigning to them, as +you could with a Python class instance. (You can subclass the extension type +in Python and add attributes to instances of the subclass, however.) +<p>There are two ways that attributes of an extension type can be accessed: + by Python attribute lookup, or by direct access to the C struct from Pyrex + code. Python code is only able to access attributes of an extension type +by the first method, but Pyrex code can use either method. </p> + + + +<p>By default, extension type attributes are only accessible by direct access, +not Python access, which means that they are not accessible from Python code. +To make them accessible from Python code, you need to declare them as <tt>public</tt> or <tt>readonly</tt>. For example, </p> + + + +<blockquote><tt>cdef class Shrubbery:</tt> <br> + + + <tt> cdef public int width, height</tt> <br> + + + <tt> cdef readonly float depth</tt></blockquote> + + + makes the <tt>width</tt> and <tt>height</tt> attributes readable and writable + from Python code, and the <tt>depth</tt> attribute readable but not writable. + +<p>Note that you can only expose simple C types, such as ints, floats and + strings, for Python access. You can also expose Python-valued attributes, + although read-write exposure is only possible for generic Python attributes + (of type <tt>object</tt>). If the attribute is declared to be of an extension + type, it must be exposed <tt>readonly</tt>. </p> + + + +<p>Note also that the <tt>public</tt> and <tt>readonly</tt> options apply + only to <i>Python</i> access, not direct access. All the attributes of an +extension type are always readable and writable by direct access.</p> + +<h2><a name="TypeDeclarations"></a>Type declarations </h2> + + + +<p>Before you can directly access the attributes of an extension type, the Pyrex compiler must know +that you have an instance of that type, and not just a generic Python object. +It knows this already in the case of the "self" parameter of the methods of +that type, but in other cases you will have to use a type declaration.</p> + +<p>For example, in the following function,</p> + +<blockquote><tt>cdef widen_shrubbery(sh, extra_width): # </tt><span style="font-family: monospace;"><span style="color: rgb(255, 0, 0);">BAD</span></span><br> + + + <tt> sh.width = sh.width + extra_width</tt></blockquote> + +<p> because the <span style="font-family: monospace;">sh</span> parameter hasn't been given a type, the <span style="font-family: monospace;">width</span> +attribute will be accessed by a Python attribute lookup. If the +attribute has been declared <span style="font-style: italic;">public</span> or <span style="font-style: italic;">readonly</span> then this will work, but +it will be very inefficient. If the attribute is private, it will not work at all -- the +code will compile, but an attribute error will be raised at run time.</p> + +<p>The solution is to declare sh as being of type <span style="font-family: monospace;">Shrubbery</span>, as follows:</p> + + + +<blockquote><tt>cdef widen_shrubbery(Shrubbery sh, extra_width):</tt> <br> + + + <tt> sh.width = sh.width + extra_width</tt></blockquote> + +Now the Pyrex compiler knows that <span style="font-family: monospace;">sh</span> has a C attribute called <span style="font-family: monospace;">width</span> and will generate code to access it directly and efficiently. The same consideration applies to local variables, for example,<br> + +<br> + +<div style="margin-left: 40px;"><code>cdef Shrubbery another_shrubbery(Shrubbery sh1):<br> + + cdef Shrubbery sh2<br> + + sh2 = Shrubbery()<br> + + sh2.width = sh1.width<br> + + sh2.height = sh1.height<br> + + return sh2</code></div> + + +<h2> <a name="NotNone"></a>Extension types and None</h2> + + + When you declare a parameter or C variable as being of an extension type, + Pyrex will allow it to take on the value None as well as values of its declared +type. This is analogous to the way a C pointer can take on the value NULL, +and you need to exercise the same caution because of it. There is no problem +as long as you are performing Python operations on it, because full dynamic +type checking will be applied. However, when you access C attributes of an +extension type (as in the <tt>widen_shrubbery</tt> function above), it's up +to you to make sure the reference you're using is not None -- in the interests +of efficiency, Pyrex does <i>not</i> check this. +<p>You need to be particularly careful when exposing Python functions which + take extension types as arguments. If we wanted to make <tt>widen_shrubbery</tt> +a Python function, for example, if we simply wrote </p> + + + +<blockquote><tt>def widen_shrubbery(Shrubbery sh, extra_width): # <font color="#ed181e">This is</font></tt> <br> + + + <tt> sh.width = sh.width + extra_width +# <font color="#ed181e">dangerous!</font></tt></blockquote> + + + then users of our module could crash it by passing None for the <tt>sh</tt> +parameter. +<p>One way to fix this would be </p> + + + +<blockquote><tt>def widen_shrubbery(Shrubbery sh, extra_width):</tt> <br> + + + <tt> if sh is None:</tt> <br> + + + <tt> raise TypeError</tt> <br> + + + <tt> sh.width = sh.width + extra_width</tt></blockquote> + + + but since this is anticipated to be such a frequent requirement, Pyrex +provides a more convenient way. Parameters of a Python function declared +as an extension type can have a <b><tt>not</tt></b> <b><tt>None</tt></b> clause: +<blockquote><tt>def widen_shrubbery(Shrubbery sh not None, extra_width):</tt> + <br> + + + <tt> sh.width = sh.width + extra_width</tt></blockquote> + + + Now the function will automatically check that <tt>sh</tt> is not None +along with checking that it has the right type. +<p>Note, however that the <tt>not</tt> <tt>None</tt> clause can <i>only</i> be used + in Python functions (defined with <tt>def</tt>) and not C functions (defined + with <tt>cdef</tt>). If you need to check whether a parameter to a C function + is None, you will need to do it yourself. </p> + + + +<p>Some more things to note: </p> + + + +<ul> + + + <li> The <b>self</b> parameter of a method of an extension type is guaranteed + never to be None.</li> + + + +</ul> + + + +<ul> + + + <li> When comparing a value with None, keep in mind that, if <tt>x</tt> is a Python object, <tt>x</tt> <tt>is</tt> <tt>None</tt> and <tt>x is</tt> <tt>not</tt> <tt>None</tt> are very +efficient because they translate directly to C pointer comparisons, whereas + <tt>x == None</tt> and <tt>x != None</tt>, or simply using <tt>x</tt> as a boolean value (as in <tt>if x: ...</tt>) will invoke Python operations +and therefore be much slower.</li> + + + +</ul> + + + +<h2> <a name="ExtTypeSpecialMethods"></a>Special methods</h2> + + + Although the principles are similar, there are substantial differences +between many of the <span style="font-family: monospace;">__xxx__</span> special methods of extension types and their +Python counterparts. There is a <a href="special_methods.html">separate page</a> devoted to this subject, and you should read it carefully before attempting +to use any special methods in your extension types. +<h2> <a name="Properties"></a>Properties</h2> + + + There is a special syntax for defining <b>properties</b> in an extension + class: +<blockquote><tt>cdef class Spam:</tt> + + <p><tt> property cheese:</tt> </p> + + + + + <p><tt> "A doc string can go +here."</tt> </p> + + + + + <p><tt> def __get__(self):</tt> + <br> + + + <tt> +# This is called when the property is read.</tt> <br> + + + <tt> +...</tt> </p> + + + + + <p><tt> def __set__(self, value):</tt> + <br> + + + <tt> +# This is called when the property is written.</tt> <br> + + + <tt> +...</tt> </p> + + + + + <p><tt> def __del__(self):</tt> + <br> + + + <tt> +# This is called when the property is deleted.</tt> <br> + + + </p> + + + </blockquote> + + + The <tt>__get__</tt>, <tt>__set__</tt> and <tt>__del__</tt> methods are +all optional; if they are omitted, an exception will be raised when the corresponding +operation is attempted. +<p>Here's a complete example. It defines a property which adds to a list +each time it is written to, returns the list when it is read, and empties +the list when it is deleted. <br> + + + </p> + + + +<center> +<table align="center" cellpadding="5"> + + + <tbody> + + + <tr> + + + <td bgcolor="#ffaf18"><b><tt>cheesy.pyx</tt></b></td> + + + <td bgcolor="#5dbaca"><b>Test input</b></td> + + + </tr> + + + <tr> + + + <td rowspan="3" bgcolor="#ffaf18" valign="top"><tt>cdef class CheeseShop:</tt> + + + <p><tt> cdef object cheeses</tt> </p> + + + + + <p><tt> def __cinit__(self):</tt> <br> + + + <tt> self.cheeses = []</tt> </p> + + + + + <p><tt> property cheese:</tt> </p> + + + + + <p><tt> def __get__(self):</tt> <br> + + + <tt> return "We don't have: %s" % self.cheeses</tt> + </p> + + + + + <p><tt> def __set__(self, value):</tt> <br> + + + <tt> self.cheeses.append(value)</tt> + </p> + + + + + <p><tt> def __del__(self):</tt> <br> + + + <tt> del self.cheeses[:]</tt></p> + + + </td> + + + <td bgcolor="#5dbaca" valign="top"><tt>from cheesy import CheeseShop</tt> + + + <p><tt>shop = CheeseShop()</tt> <br> + + + <tt>print shop.cheese</tt> </p> + + + + + <p><tt>shop.cheese = "camembert"</tt> <br> + + + <tt>print shop.cheese</tt> </p> + + + + + <p><tt>shop.cheese = "cheddar"</tt> <br> + + + <tt>print shop.cheese</tt> </p> + + + + + <p><tt>del shop.cheese</tt> <br> + + + <tt>print shop.cheese</tt></p> + + + </td> + + + </tr> + + + <tr> + + + <td bgcolor="#8cbc1c"><b>Test output</b></td> + + + </tr> + + + <tr> + + + <td bgcolor="#8cbc1c"><tt>We don't have: []</tt> <br> + + + <tt>We don't have: ['camembert']</tt> <br> + + + <tt>We don't have: ['camembert', 'cheddar']</tt> <br> + + + <tt>We don't have: []</tt></td> + + + </tr> + + + + + </tbody> +</table> + + + </center> + + + +<h2> <a name="SubclassingExtTypes"></a>Subclassing</h2> + + + An extension type may inherit from a built-in type or another extension +type: +<blockquote><tt>cdef class Parrot:</tt> <br> + + + <tt> ...</tt><tt></tt> + + <p><tt>cdef class Norwegian(Parrot):</tt> <br> + + + <tt> ...</tt></p> + + + </blockquote> + + + +<p><br> + + + A complete definition of the base type must be available to Pyrex, so if +the base type is a built-in type, it must have been previously declared as +an <b>extern</b> extension type. If the base type is defined in another Pyrex +module, it must either be declared as an extern extension type or imported +using the <b><a href="sharing.html">cimport</a></b> statement. </p> + + + +<p>An extension type can only have one base class (no multiple inheritance). + </p> + + + +<p>Pyrex extension types can also be subclassed in Python. A Python class + can inherit from multiple extension types provided that the usual Python +rules for multiple inheritance are followed (i.e. the C layouts of all the +base classes must be compatible).<br> + + + </p> + + + +<h2><a name="CMethods"></a>C methods</h2> + + + Extension types can have C methods as well as Python methods. Like C functions, +C methods are declared using <tt>cdef</tt> instead of <tt>def</tt>. C methods +are "virtual", and may be overridden in derived extension types.<br> + + + <br> + + + +<table align="center" cellpadding="5"> + + + <tbody> + + + <tr> + + + <td bgcolor="#ffaf18" valign="top" width="50%"><b><tt>pets.pyx</tt></b><br> + + + </td> + + + <td bgcolor="#8cbc1c" valign="top" width="30%"><b>Output</b><br> + + + </td> + + + </tr> + + + <tr> + + + <td bgcolor="#ffaf18" valign="top" width="50%"><tt>cdef class Parrot:<br> + + + <br> + + + cdef void describe(self):<br> + + + print "This parrot is resting."<br> + + + <br> + + + cdef class Norwegian(Parrot):<br> + + + <br> + + + cdef void describe(self):<br> + + + Parrot.describe(self)<br> + + + print "Lovely plumage!"<br> + + + <br> + + + <br> + + + cdef Parrot p1, p2<br> + + + p1 = Parrot()<br> + + + p2 = Norwegian()<br> + + +print "p1:"<br> + + + p1.describe()<br> + + +print "p2:"<br> + + + p2.describe()</tt> <br> + + + </td> + + + <td bgcolor="#8cbc1c" valign="top" width="30%"><tt>p1:<br> + + +This parrot is resting.<br> + + +p2:<br> + + + </tt><tt>This parrot is resting.<br> + + + </tt><tt> Lovely plumage!</tt><br> + + + </td> + + + </tr> + + + + + </tbody> +</table> + + + <br> + + + The above example also illustrates that a C method can call an inherited +C method using the usual Python technique, i.e.<br> + + +<blockquote><tt>Parrot.describe(self)</tt><br> + + +</blockquote> + + + +<h2><a name="ForwardDeclaringExtTypes"></a>Forward-declaring extension types</h2> + + + Extension types can be forward-declared, like struct and union types. This + will be necessary if you have two extension types that need to refer to +each other, e.g. +<blockquote><tt>cdef class Shrubbery # forward declaration</tt> + + <p><tt>cdef class Shrubber:</tt> <br> + + + <tt> cdef Shrubbery work_in_progress</tt> </p> + + + + + <p><tt>cdef class Shrubbery:</tt> <br> + + + <tt> cdef Shrubber creator</tt></p> + + + </blockquote><h2><a name="WeakRefs"></a>Making extension types weak-referenceable</h2> + +By +default, extension types do not support having weak references made to +them. You can enable weak referencing by declaring a C attribute of +type <span style="font-family: monospace;">object</span> called <span style="font-family: monospace; font-weight: bold;">__weakref__</span>. For example,<br> + + +<br> + + +<div style="margin-left: 40px;"><span style="font-family: monospace;">cdef class ExplodingAnimal:<br><br style="font-family: monospace;"></span> + + +<span style="font-family: monospace;"> """This animal will self-destruct when it is</span><br> + + +<span style="font-family: monospace;"> no longer strongly referenced."""</span><br> + + +<span style="font-family: monospace;"> </span><br style="font-family: monospace;"> + + +<span style="font-family: monospace;"></span><span style="font-family: monospace;"> cdef object __weakref__</span><br> + + +</div> + + +<h2>Garbage Collection</h2>Normally, any extension type which has +Python-valued attributes automatically participates in cyclic garbage +collection. You can prevent this as follows:<br><pre style="margin-left: 40px;">cdef class Hovercraft [nogc]:<br><br> """This object will not participate in cyclic gc<br> even though it has a Python attribute."""<br><br> cdef object eels<br></pre>However, +if there is a base type with Python attributes that participates in GC, +any subclasses of it will also participate in GC regardless of their <span style="font-family: monospace;">nogc</span> options. + + +<h2><a name="PublicAndExtern"></a>Public and external extension types</h2> + + + + Extension types can be declared <b>extern</b> or <b>public</b>. An <a href="#ExternalExtTypes"><b>extern</b> extension type declaration</a> makes +an extension type defined in external C code available to a Pyrex module. +A <a href="#PublicExtensionTypes"><b>public</b> extension type declaration</a> makes an extension type defined in a Pyrex module available to external C +code. +<h3> <a name="ExternalExtTypes"></a>External extension types</h3> + + + An <b>extern</b> extension type allows you to gain access to the internals + of Python objects defined in the Python core or in a non-Pyrex extension +module. +<blockquote><b>NOTE:</b> In Pyrex versions before 0.8, <b>extern</b> extension + types were also used to reference extension types defined in another Pyrex + module. While you can still do that, Pyrex 0.8 and later provides a better + mechanism for this. See <a href="sharing.html">Sharing C Declarations Between + Pyrex Modules</a>.</blockquote> + + + Here is an example which will let you get at the C-level members of the +built-in <i>complex</i> object. +<blockquote><tt>cdef extern from "complexobject.h":</tt> + + <p><tt> struct Py_complex:</tt> <br> + + + <tt> double real</tt> <br> + + + <tt> double imag</tt> </p> + + + + + <p><tt> ctypedef class __builtin__.complex [object PyComplexObject]:</tt> + <br> + + + <tt> cdef Py_complex cval</tt> + </p> + + + + + <p><tt># A function which uses the above type</tt> <br> + + + <tt>def spam(complex c):</tt> <br> + + + <tt> print "Real:", c.cval.real</tt> <br> + + + <tt> print "Imag:", c.cval.imag</tt></p> + + + </blockquote> + + + Some important things to note are: +<ol> + + + <li> In this example, <b>ctypedef class</b> has been used. This is because, + in the Python header files, the <tt>PyComplexObject</tt> struct is declared + with<br> + + + <br> + + + + + <div style="margin-left: 40px;"><tt>ctypedef struct {</tt> <br> + + + <tt> ...</tt> <br> + + + <tt>} PyComplexObject;<br> + + + <br> + + + </tt></div> + + + </li> + + <li>As well as the name of the extension type, the <i>module</i> in which +its type object can be found is also specified. See the <a href="#ImplicitImport">implicit importing</a> section below. <br> + + + <br> + + + </li> + + + <li> When declaring an external extension type, you don't declare +any methods. Declaration of methods is not required in order to call them, +because the calls are Python method calls. Also, as with structs and unions, +if your extension class declaration is inside a <i>cdef extern from</i> block, + you only need to declare those C members which you wish to access.</li> + + + +</ol> + + + +<h3> <a name="ImplicitImport"></a>Implicit importing</h3> + + + +<blockquote><font color="#ef1f1d">Backwards Incompatibility Note</font>: +You will have to update any pre-0.8 Pyrex modules you have which use <b>extern</b> +extension types. I apologise for this, but for complicated reasons it proved + to be too difficult to continue supporting the old way of doing these while + introducing the new features that I wanted.</blockquote> + + + Pyrex 0.8 and later requires you to include a module name in an extern +extension class declaration, for example, +<blockquote><tt>cdef extern class MyModule.Spam:</tt> <br> + + + <tt> ...</tt></blockquote> + + + The type object will be implicitly imported from the specified module and + bound to the corresponding name in this module. In other words, in this +example an implicit +<ol> + + + + + <pre>from <tt>MyModule</tt> import Spam</pre> + + + +</ol> + + + statement will be executed at module load time. +<p>The module name can be a dotted name to refer to a module inside a package + hierarchy, for example, </p> + + + +<blockquote><tt>cdef extern class My.Nested.Package.Spam:</tt> <br> + + + <tt> ...</tt></blockquote> + + + You can also specify an alternative name under which to import the type +using an <b>as</b> clause, for example, +<ol> + + + <tt>cdef extern class My.Nested.Package.Spam as Yummy:</tt> <br> + + + <tt> ...</tt> +</ol> + + + which corresponds to the implicit import statement +<ol> + + + + + <pre>from <tt>My.Nested.Package</tt> import <tt>Spam</tt> as <tt>Yummy</tt></pre> + + + +</ol> + + + +<h3> <a name="TypeVsConstructor"></a>Type names vs. constructor names</h3> + + + Inside a Pyrex module, the name of an extension type serves two distinct + purposes. When used in an expression, it refers to a module-level global +variable holding the type's constructor (i.e. its type-object). However, +it can also be used as a C type name to declare variables, arguments and +return values of that type. +<p>When you declare </p> + + + +<blockquote><tt>cdef extern class MyModule.Spam:</tt> <br> + + + <tt> ...</tt></blockquote> + + + the name <tt>Spam</tt> serves both these roles. There may be other names + by which you can refer to the constructor, but only <tt>Spam</tt> can be +used as a type name. For example, if you were to explicity <tt>import MyModule</tt>, + you could use<tt> MyModule.Spam()</tt> to create a Spam instance, but you + wouldn't be able to use <tt>MyModule.Spam</tt> as a type name. +<p>When an <b>as</b> clause is used, the name specified in the <b>as</b> +clause also takes over both roles. So if you declare </p> + + + +<blockquote><tt>cdef extern class MyModule.Spam as Yummy:</tt> <br> + + + <tt> ...</tt></blockquote> + + + then <tt>Yummy</tt> becomes both the type name and a name for the constructor. + Again, there are other ways that you could get hold of the constructor, +but only <tt>Yummy</tt> is usable as a type name. +<h3> <a name="PublicExtensionTypes"></a>Public extension types</h3> + + + An extension type can be declared <b>public</b>, in which case a <b>.h</b> +file is generated containing declarations for its object struct and type +object. By including the <b>.h</b> file in external C code that you write, +that code can access the attributes of the extension type. +<h3> <a name="NameSpecClause"></a>Name specification clause</h3> + + + The part of the class declaration in square brackets is a special feature + only available for <b>extern</b> or <b>public</b> extension types. The full +form of this clause is +<blockquote><tt>[object </tt><i>object_struct_name</i><tt>, type </tt><i>type_object_name</i><span style="font-family: monospace;"> ]</span></blockquote> + + + where <i>object_struct_name</i> is the name to assume for the type's C +struct, and <i>type_object_name</i> is the name to assume for the type's +statically declared type object. (The object and type clauses can be written +in either order.) +<p>If the extension type declaration is inside a <b>cdef extern from</b> +block, the <b>object</b> clause is required, because Pyrex must be able to +generate code that is compatible with the declarations in the header file. +Otherwise, for <b>extern</b> extension types, the <b>object</b> clause is +optional. </p> + + + +<p>For <b>public</b> extension types, the <b>object</b> and <b>type</b> clauses +are both required, because Pyrex must be able to generate code that is compatible +with external C code. </p> + + + +<p> </p> + + + +<hr width="100%"> <br> + + + Back to the <a href="overview.html">Language Overview</a> <br> + + + <br> + + + <br> + + +</body></html>
\ No newline at end of file |