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. In other words, the definition of ``spam`` above is equivalent to
writing::
writing
.. tabs::
.. group-tab:: Pure Python
.. code-block:: python
def spam(python_i, python_s):
i: cython.int = python_i
s: cython.p_char = python_s
...
.. group-tab:: Cython
.. code-block:: cython
def spam(python_i, python_s):
cdef int i = python_i
cdef char* s = python_s
...
def spam(python_i, python_s):
cdef int i = python_i
cdef char* s = python_s
...
Automatic conversion is currently only possible for numeric types,
string types and structs (composed recursively of any of these types);
...
...
@@ -243,7 +411,8 @@ with string attributes if they are to be used after the function returns.
C functions, on the other hand, can have parameters of any type, since they're
passed in directly using a normal C function call.
Functions declared using :keyword:`cdef` with Python object return type, like Python functions, will return a :keyword:`None`
C Functions declared using :keyword:`cdef` or the ``@cfunc`` decorator with a
Python object return type, like Python functions, will return a :keyword:`None`
value when execution leaves the function body without an explicit return value. This is in
contrast to C/C++, which leaves the return value undefined.
In the case of non-Python object return types, the equivalent of zero is returned, for example, 0 for ``int``, :keyword:`False` for ``bint`` and :keyword:`NULL` for pointer types.
...
...
@@ -257,10 +426,24 @@ Python objects as parameters and return values
If no type is specified for a parameter or return value, it is assumed to be a
Python object. (Note that this is different from the C convention, where it
would default to int.) For example, the following defines a C function that
takes two Python objects as parameters and returns a Python object::
takes two Python objects as parameters and returns a Python object
cdef spamobjs(x, y):
...
.. tabs::
.. group-tab:: Pure Python
.. code-block:: python
@cython.cfunc
def spamobjs(x, y):
...
.. group-tab:: Cython
.. code-block:: cython
cdef spamobjs(x, y):
...
Reference counting for these objects is performed automatically according to
the standard Python/C API rules (i.e. borrowed references are taken as
...
...
@@ -274,17 +457,34 @@ parameters and a new reference is returned).
The name object 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,::
as the name of a type, for example,
cdef ftang(object int):
...
.. tabs::
.. group-tab:: Pure Python
.. code-block:: python
@cython.cfunc
def ftang(int: object):
...
.. group-tab:: Cython
.. code-block:: cython
declares a parameter called int which is a Python object. You can also use
cdef ftang(object int):
...
declares a parameter called ``int`` which is a Python object. You can also use
object as the explicit return type of a function, e.g.::
cdef object ftang(object int):
...
.. note:: Currently, Cython contains a bug not allowing ``object`` as return annotation in
pure Python from a C function. (GitHub issue :issue:`2529`)
In the interests of clarity, it is probably a good idea to always be explicit
about object parameters in C functions.
...
...
@@ -292,7 +492,15 @@ about object parameters in C functions.
To create a borrowed reference, specify the parameter type as ``PyObject*``.
Cython won't perform automatic ``Py_INCREF``, or ``Py_DECREF``, e.g.: