Added special methods info from pyrex, begun documenting the pxd packages
authorggellner@giton <none@none>
Thu, 23 Oct 2008 03:54:45 +0000 (23:54 -0400)
committerggellner@giton <none@none>
Thu, 23 Oct 2008 03:54:45 +0000 (23:54 -0400)
docs/pxd_package.rst [new file with mode: 0644]
docs/pyrex_differences.rst
docs/special_methods.rst [new file with mode: 0644]
index.rst
sphinxext/cython_highlighting.pyc
sphinxext/ipython_console_highlighting.pyc

diff --git a/docs/pxd_package.rst b/docs/pxd_package.rst
new file mode 100644 (file)
index 0000000..7f424b6
--- /dev/null
@@ -0,0 +1,49 @@
+I think this is a result of a recent change to Pyrex that
+has been merged into Cython.
+
+If a directory contains an :file:`__init__.py` or :file:`__init__.pyx` file,
+it's now assumed to be a package directory. So, for example,
+if you have a directory structure::
+
+   foo/
+     __init__.py
+     shrubbing.pxd
+     shrubbing.pyx
+
+then the shrubbing module is assumed to belong to a package
+called 'foo', and its fully qualified module name is
+'foo.shrubbing'.
+
+So when Pyrex wants to find out whether there is a `.pxd` file for shrubbing,
+it looks for one corresponding to a module called :module:`foo.shrubbing`. It
+does this by searching the include path for a top-level package directory
+called 'foo' containing a file called 'shrubbing.pxd'.
+
+However, if foo is the current directory you're running
+the compiler from, and you haven't added foo to the
+include path using a -I option, then it won't be on
+the include path, and the `.pxd` won't be found.
+
+What to do about this depends on whether you really
+intend the module to reside in a package.
+
+If you intend shrubbing to be a top-level module, you
+will have to move it somewhere else where there is
+no :file:`__init__.*` file.
+
+If you do intend it to reside in a package, then there
+are two alternatives:
+
+1. cd to the directory containing foo and compile
+   from there::
+
+      cd ..; cython foo/shrubbing.pyx
+
+2. arrange for the directory containing foo to be
+   passed as a -I option, e.g.::
+
+      cython -I .. shrubbing.pyx
+
+Arguably this behaviour is not very desirable, and I'll
+see if I can do something about it.
+
index e07052a3f1161bc7676ccdd830cf04f1cecdb8c3..415e8164f1136c5b17b72d769c3a776844938e53 100644 (file)
@@ -6,11 +6,6 @@
 Differences between Cython and Pyrex
 **************************************
 
-Package names and cross-directory imports
-==========================================
-
-Just like in python. 
-
 List Comprehensions
 ====================
 
diff --git a/docs/special_methods.rst b/docs/special_methods.rst
new file mode 100644 (file)
index 0000000..c4df482
--- /dev/null
@@ -0,0 +1,314 @@
+Special Methods of Extension Types
+===================================
+
+This page describes the special methods currently supported by Pyrex extension
+types. A complete list of all the special methods appears in the table at the
+bottom. Some of these methods behave differently from their Python
+counterparts or have no direct Python counterparts, and require special
+mention.
+
+.. Note: Everything said on this page applies only to extension types, defined
+    with the :keyword:`cdef class` statement. It doesn't apply to classes defined with the
+    Python :keyword:`class` statement, where the normal Python rules apply.  
+    
+Declaration
+------------
+Special methods of extension types must be declared with :keyword:`def`, not
+:keyword:`cdef`.
+
+Docstrings
+-----------
+
+Currently, docstrings are not fully supported in special methods of extension
+types. You can place a docstring in the source to serve as a comment, but it
+won't show up in the corresponding :attr:`__doc__` attribute at run time. (This is a
+Python limitation -- there's nowhere in the `PyTypeObject` data structure to put
+such docstrings.) 
+
+Initialisation methods: :meth:`__cinit__` and :meth:`__init__`
+---------------------------------------------------------------
+There are two methods concerned with initialising the object.
+
+The :meth:`__cinit__` method is where you should perform basic C-level
+initialisation of the object, including allocation of any C data structures
+that your object will own. You need to be careful what you do in the
+:meth:`__cinit__` method, because the object may not yet be a valid Python
+object when it is called. Therefore, you must not invoke any Python operations
+which might touch the object; in particular, do not try to call any of its
+methods.
+
+By the time your :meth:`__cinit__` method is called, memory has been allocated for the
+object and any C attributes it has have been initialised to 0 or null. (Any
+Python attributes have also been initialised to None, but you probably
+shouldn't rely on that.) Your :meth:`__cinit__` method is guaranteed to be called
+exactly once.
+
+If your extension type has a base type, the :meth:`__cinit__` method of the base type
+is automatically called before your :meth:`__cinit__` method is called; you cannot
+explicitly call the inherited :meth:`__cinit__` method. If you need to pass a modified
+argument list to the base type, you will have to do the relevant part of the
+initialisation in the :meth:`__init__` method instead (where the normal rules for
+calling inherited methods apply).
+
+Any initialisation which cannot safely be done in the :meth:`__cinit__` method should
+be done in the :meth:`__init__` method. By the time :meth:`__init__` is called, the object is
+a fully valid Python object and all operations are safe. Under some
+circumstances it is possible for :meth:`__init__` to be called more than once or not
+to be called at all, so your other methods should be designed to be robust in
+such situations.
+
+Any arguments passed to the constructor will be passed to both the
+:meth:`__cinit__` method and the :meth:`__init__` method. If you anticipate
+subclassing your extension type in Python, you may find it useful to give the
+:meth:`__cinit__` method `*` and `**` arguments so that it can accept and
+ignore extra arguments. Otherwise, any Python subclass which has an
+:meth:`__init__` with a different signature will have to override
+:meth:`__new__` as well as :meth:`__init__`, which the writer of a Python
+class wouldn't expect to have to do.  Finalization method: :meth:`__dealloc__`
+The counterpart to the :meth:`__cinit__` method is the :meth:`__dealloc__`
+method, which should perform the inverse of the :meth:`__cinit__` method. Any
+C data structures that you allocated in your :meth:`__cinit__` method should
+be freed in your :meth:`__dealloc__` method.
+
+You need to be careful what you do in a :meth:`__dealloc__` method. By the time your
+:meth:`__dealloc__` method is called, the object may already have been partially
+destroyed and may not be in a valid state as far as Python is concerned, so
+you should avoid invoking any Python operations which might touch the object.
+In particular, don't call any other methods of the object or do anything which
+might cause the object to be resurrected. It's best if you stick to just
+deallocating C data.
+
+You don't need to worry about deallocating Python attributes of your object,
+because that will be done for you by Pyrex after your :meth:`__dealloc__` method
+returns.
+
+.. Note: There is no :meth:`__del__` method for extension types.
+
+Arithmetic methods
+-------------------
+
+Arithmetic operator methods, such as :meth:`__add__`, behave differently from their
+Python counterparts. There are no separate "reversed" versions of these
+methods (:meth:`__radd__`, etc.) Instead, if the first operand cannot perform the
+operation, the same method of the second operand is called, with the operands
+in the same order.
+
+This means that you can't rely on the first parameter of these methods being
+"self", and you should test the types of both operands before deciding what to
+do. If you can't handle the combination of types you've been given, you should
+return `NotImplemented`.
+
+This also applies to the in-place arithmetic method :meth:`__ipow__`. It doesn't apply
+to any of the other in-place methods (:meth:`__iadd__`, etc.) which always
+take `self` as the first argument.
+
+Rich comparisons
+-----------------
+
+There are no separate methods for the individual rich comparison operations
+(:meth:`__eq__`, :meth:`__le__`, etc.) Instead there is a single method
+:meth:`__richcmp__` which takes an integer indicating which operation is to be
+performed, as follows:
+             
++-----+-----+
+|  <  |  0  |  
++-----+-----+
+| ==  |  2  |
++-----+-----+
+|  >  |  4  |
++-----+-----+
+| <=  |  1  |  
++-----+-----+
+| !=  |  3  |  
++-----+-----+
+| >=  |  5  |
++-----+-----+
+
+The :meth:`__next__` method
+----------------------------
+
+Extension types wishing to implement the iterator interface should define a
+method called :meth:`__next__`, not next. The Python system will automatically
+supply a next method which calls your :meth:`__next__`. Do *NOT* explicitly
+give your type a next method, or bad things could happen.
+
+Type Testing in Special Methods 
+--------------------------------
+
+.. TODO document the Cython way using the overridden isinstance
+
+
+Special Method 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.
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| Name                         | Parameters                            | Return type |         Description                                 |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| General                                                                                                                           |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __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                                                                                                              |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __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                                                                                                               |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __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                                                                                                     |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __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                                                                                                            |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __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                                                                                                                         |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __next__             | self                                  | object      | Get next item (called next in Python)               |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| Buffer interface  (no Python equivalents - see note 1)                                                                            |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __getreadbuffer__    | self, int i, void `**p`               |             |                                                     | 
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __getwritebuffer__   | self, int i, void `**p`               |             |                                                     |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __getsegcount__      | self, int `*p`                        |             |                                                     |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __getcharbuffer__    | self, int i, char `**p`               |             |                                                     |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| Descriptor objects  (see note 2)                                                                                                  |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __get__              | self, instance, class                 | object      |         Get value of attribute                      |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __set__              | self, instance, value                 |             |     Set value of attribute                          |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+| __delete__           | self, instance                        |             |     Delete attribute                                |
++-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
+
+.. note:: (1) 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.
+
+.. note:: (2) 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".
+
index 4c14c1cd7628955401639e6bebe1540db1c0b995..e513f1e2c459b4dafd5c3f4c2d3861e0c2d4a529 100644 (file)
--- a/index.rst
+++ b/index.rst
@@ -12,6 +12,7 @@ Contents:
    docs/numpy_tutorial
    docs/language_basics
    docs/extension_types
+   docs/special_methods
    docs/sharing_declarations
    docs/external_C_code
    docs/source_files_and_compilation
index 9ae12f8161d8517e9115f7a96ef9e4fa500ad40f..e026e9ebd69510c615e074cfa3dfaa5d95d81034 100644 (file)
Binary files a/sphinxext/cython_highlighting.pyc and b/sphinxext/cython_highlighting.pyc differ
index efcf6e02f66c9a177d79a6d11527780de35f8fb9..4c0dea0f8b1090adde91b3328241530fb0816e11 100644 (file)
Binary files a/sphinxext/ipython_console_highlighting.pyc and b/sphinxext/ipython_console_highlighting.pyc differ