* Are considered by Python to be "built-in" types.
* Can be used to wrap arbitrary C data structures, and provide a Python-like interface to them from Python.
* Attributes and methods can be called from Python or Cython code
- * Are defined by the ``cdef`` class statement::
+ * Are defined by the ``cdef class`` statement.
+
+::
cdef class Shrubbery:
* Below, is a full example that defines a property which can..
- * Add to a list each time it is written to.
- * Return the list when it is read.
- * Empty the list when it is deleted.
+ * Add to a list each time it is written to (``"__set__"``).
+ * Return the list when it is read (``"__get__"``).
+ * Empty the list when it is deleted (``"__del__"``).
::
Special Methods
===============
-.. provide link to the table of special methods
+.. note:: Attention
+
+ The semantics of special methods are similar in principle to Python, but there are substantial differences in some behavior.
+
+* See :doc:`special_methods_table` for available methods.
+* Cython provides many "special method" method types.
+* Be aware that some Cython special methods have no Python counter-part.
+
+Declaration
+===========
+
+* Must be declared with ``def`` and cannot be declared with ``cdef``.
+* Performance is not affected by the ``def`` declaration because of special calling conventions
+
+Docstrings
+==========
+
+* Docstrings are not supported yet for some special method types.
+* They can be included in the source, but may not appear in the corresponding ``__doc__`` attribute at run-time.
+
+ * This a Python library limitation because the ``PyTypeObject`` data structure is limited
+
+Initialization: ``__cinit__()`` and ``__init__()``
+==================================================
+
+* Any arguments passed to the extension type's constructor, will be passed to both initialization methods.
+* ``__cinit__()`` is where you should perform C-level initialization of the object
+
+ * This includes any allocation of C data structures.
+ * **Caution** is warranted as to what you do in this method.
+
+ * The object may not be fully valid Python object when it is called.
+ * Calling Python objects, including the extensions own methods, may be hazardous.
+
+ * By the time ``__cinit__()`` is called...
+
+ * Memory has been allocated for the object.
+ * All C-level attributes have been initialized to 0 or null.
+ * Python have been initialized to ``None``, but you can not rely on that for each occasion.
+ * This initialization method is guaranteed to be called exactly once.
+
+ * For Extensions types that inherit a base type:
+
+ * The ``__cinit__()`` method of the base type is automatically called before this one.
+ * The inherited ``__cinit__()`` method can not be called explicitly.
+ * Passing modified argument lists to the base type must be done through ``__init__()``.
+ * It may be wise to give the ``__cinit__()`` method both ``"*"`` and ``"**"`` arguments.
+
+ * Allows the method to accept or ignore additional arguments.
+ * Eliminates the need for a Python level sub-class, that changes the ``__init__()`` method's signature, to have to override both the ``__new__()`` and ``__init__()`` methods.
+
+ * If ``__cinit__()`` is declared to take no arguments except ``self``, it will ignore any extra arguments passed to the constructor without complaining about a signature mis-match
+
+
+* ``__init__()`` is for higher-level initialization and is safer for Python access.
+
+ * By the time this method is called, the extension type is a fully valid Python object.
+ * All operations are safe.
+ * This method may sometimes be called more than once, or possibly not at all.
+
+ * Take this into consideration to make sure the design of your other methods are robust of this fact.
+
+Finalization: ``__dealloc__()``
+===============================
+
+* This method is the counter-part to ``__cinit__()``.
+* Any C-data that was explicitly allocated in the ``__cinit__()`` method should be freed here.
+* Use caution in this method:
+
+ * The Python object to which this method belongs may not be completely intact at this point.
+ * Avoid invoking any Python operations that may touch the object.
+ * Don't call any of this object's methods.
+ * It's best to just deallocate C-data structures here.
+
+* All Python attributes of your extension type object are deallocated by Cython after the ``__dealloc__()`` method returns.
+
+Arithmetic Methods
+==================
+
+.. note:: Most of these methods behave differently than in Python
+
+* There are not "reversed" versions of these methods... there is no __radd__() for instance.
+* If the first operand cannot perform the operation, the same method of the second operand is called, with the operands in the same order.
+* Do not rely on the first parameter of these methods, being ``"self"`` or the right type.
+* The types of both operands should be tested before deciding what to do.
+* Return ``NotImplemented`` for unhandled, mis-matched operand types.
+* The previously mentioned points..
+
+ * Also apply to 'in-place' method ``__ipow__()``.
+ * Do not apply to other 'in-place' methods like ``__iadd__()``, in that these always take ``self`` as the first argument.
+
+
+Rich Comparisons
+================
+
+.. note:: There are no separate methods for individual rich comparison operations.
+
+* A single special method called ``__richcmp__()`` replaces all the individual rich compare, special method types.
+* ``__richcmp__()`` takes an integer argument, indicating which operation is to be performed as shown in the table below.
+
+ +-----+-----+
+ | < | 0 |
+ +-----+-----+
+ | == | 2 |
+ +-----+-----+
+ | > | 4 |
+ +-----+-----+
+ | <= | 1 |
+ +-----+-----+
+ | != | 3 |
+ +-----+-----+
+ | >= | 5 |
+ +-----+-----+
+
+
+
+
+The ``__next__()`` Method
+=========================
+
+* Extension types used to expose an iterator interface should define a ``__next__()`` method.
+* **Do not** explicitly supply a ``next()`` method, because Python does that for you automatically.
+
===========
Subclassing
===========
+* An extension type may inherit from a built-in type or another extension type::
+
+ cdef class Parrot:
+ ...
+
+ cdef class Norwegian(Parrot):
+ ...
+
+* A complete definition of the base type must be available to Cython
+
+ * If the base type is a built-in type, it must have been previously declared as an ``extern`` extension type.
+ * ``cimport`` can be used to import the base type, if the extern declared base type is in a ``.pxd`` definition file.
+
+ * In Cython, multiple inheritance is not permitted.. singlular inheritance only
+
+* Cython extenstion types can also be sub-classed in Python.
+
+ * Here multiple inhertance is permissible as is normal for Python.
+ * Even multiple extension types may be inherited, but C-layout of all the base classes must be compatible.
+
+
====================
Forward Declarations
====================
+* Extension types can be "forward-declared".
+* This is necessary when two extension types refer to each other::
+
+ cdef class Shrubbery # forward declaration
+
+ cdef class Shrubber:
+ cdef Shrubbery work_in_progress
+
+ cdef class Shrubbery:
+ cdef Shrubber creator
+
+* An extension type that has a base-class, requires that both forward-declarations be specified::
+
+ cdef class A(B)
+
+ ...
+
+ cdef class A(B):
+ # attributes and methods
+
+
========================
Extension Types and None
========================
Weak Referencing
================
+* By default, weak references are not supported.
+* It can be enabled by declaring a C attribute of the ``object`` type called ``__weakref__()``::
+
+ cdef class ExplodingAnimal:
+ """This animal will self-destruct when it is
+ no longer strongly referenced."""
+
+ cdef object __weakref__
+
+
======
Public
======
--- /dev/null
+Special Methods Table
+---------------------
+
+This table lists all of the special methods together with their parameter and
+return types. In the table below, a parameter name of self is used to indicate
+that the parameter has the type that the method belongs to. Other parameters
+with no type specified in the table are generic Python objects.
+
+You don't have to declare your method as taking these parameter types. If you
+declare different types, conversions will be performed as necessary.
+
+General
+^^^^^^^
+
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| Name | Parameters | Return type | Description |
++=======================+=======================================+=============+=====================================================+
+| __cinit__ |self, ... | | Basic initialisation (no direct Python equivalent) |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __init__ |self, ... | | Further initialisation |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __dealloc__ |self | | Basic deallocation (no direct Python equivalent) |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __cmp__ |x, y | int | 3-way comparison |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __richcmp__ |x, y, int op | object | Rich comparison (no direct Python equivalent) |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __str__ |self | object | str(self) |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __repr__ |self | object | repr(self) |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __hash__ |self | int | Hash function |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __call__ |self, ... | object | self(...) |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __iter__ |self | object | Return iterator for sequence |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __getattr__ |self, name | object | Get attribute |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __setattr__ |self, name, val | | Set attribute |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __delattr__ |self, name | | Delete attribute |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+
+Arithmetic operators
+^^^^^^^^^^^^^^^^^^^^
+
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| Name | Parameters | Return type | Description |
++=======================+=======================================+=============+=====================================================+
+| __add__ | x, y | object | binary `+` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __sub__ | x, y | object | binary `-` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __mul__ | x, y | object | `*` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __div__ | x, y | object | `/` operator for old-style division |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __floordiv__ | x, y | object | `//` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __truediv__ | x, y | object | `/` operator for new-style division |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __mod__ | x, y | object | `%` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __divmod__ | x, y | object | combined div and mod |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __pow__ | x, y, z | object | `**` operator or pow(x, y, z) |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __neg__ | self | object | unary `-` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __pos__ | self | object | unary `+` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __abs__ | self | object | absolute value |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __nonzero__ | self | int | convert to boolean |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __invert__ | self | object | `~` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __lshift__ | x, y | object | `<<` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __rshift__ | x, y | object | `>>` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __and__ | x, y | object | `&` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __or__ | x, y | object | `|` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __xor__ | x, y | object | `^` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+
+Numeric conversions
+^^^^^^^^^^^^^^^^^^^
+
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| Name | Parameters | Return type | Description |
++=======================+=======================================+=============+=====================================================+
+| __int__ | self | object | Convert to integer |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __long__ | self | object | Convert to long integer |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __float__ | self | object | Convert to float |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __oct__ | self | object | Convert to octal |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __hex__ | self | object | Convert to hexadecimal |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __index__ (2.5+ only) | self | object | Convert to sequence index |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+
+In-place arithmetic operators
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| Name | Parameters | Return type | Description |
++=======================+=======================================+=============+=====================================================+
+| __iadd__ | self, x | object | `+=` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __isub__ | self, x | object | `-=` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __imul__ | self, x | object | `*=` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __idiv__ | self, x | object | `/=` operator for old-style division |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __ifloordiv__ | self, x | object | `//=` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __itruediv__ | self, x | object | `/=` operator for new-style division |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __imod__ | self, x | object | `%=` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __ipow__ | x, y, z | object | `**=` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __ilshift__ | self, x | object | `<<=` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __irshift__ | self, x | object | `>>=` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __iand__ | self, x | object | `&=` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __ior__ | self, x | object | `|=` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __ixor__ | self, x | object | `^=` operator |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+
+Sequences and mappings
+^^^^^^^^^^^^^^^^^^^^^^
+
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| Name | Parameters | Return type | Description |
++=======================+=======================================+=============+=====================================================+
+| __len__ | self int | | len(self) |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __getitem__ | self, x | object | self[x] |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __setitem__ | self, x, y | | self[x] = y |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __delitem__ | self, x | | del self[x] |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __getslice__ | self, Py_ssize_t i, Py_ssize_t j | object | self[i:j] |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __setslice__ | self, Py_ssize_t i, Py_ssize_t j, x | | self[i:j] = x |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __delslice__ | self, Py_ssize_t i, Py_ssize_t j | | del self[i:j] |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __contains__ | self, x | int | x in self |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+
+Iterators
+^^^^^^^^^
+
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| Name | Parameters | Return type | Description |
++=======================+=======================================+=============+=====================================================+
+| __next__ | self | object | Get next item (called next in Python) |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+
+Buffer interface
+^^^^^^^^^^^^^^^^
+
+.. note::
+ The buffer interface is intended for use by C code and is not directly
+ accessible from Python. It is described in the Python/C API Reference Manual
+ under sections 6.6 and 10.6.
+
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| Name | Parameters | Return type | Description |
++=======================+=======================================+=============+=====================================================+
+| __getreadbuffer__ | self, int i, void `**p` | | |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __getwritebuffer__ | self, int i, void `**p` | | |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __getsegcount__ | self, int `*p` | | |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __getcharbuffer__ | self, int i, char `**p` | | |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+
+Descriptor objects
+^^^^^^^^^^^^^^^^^^
+
+.. note::
+ Descriptor objects are part of the support mechanism for new-style
+ Python classes. See the discussion of descriptors in the Python documentation.
+ See also PEP 252, "Making Types Look More Like Classes", and PEP 253,
+ "Subtyping Built-In Types".
+
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| Name | Parameters | Return type | Description |
++=======================+=======================================+=============+=====================================================+
+| __get__ | self, instance, class | object | Get value of attribute |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __set__ | self, instance, value | | Set value of attribute |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __delete__ | self, instance | | Delete attribute |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+
+
+
+
+