This section describes how to make C declarations, functions and extension types in one Cython module available for use in another Cython module. These facilities are closely modeled on the Python import mechanism, and can be thought of as a compile-time version of it.
A Cython module can be split into two parts: a definition file with a
suffix, containing C declarations that are to be available to other Cython
modules, and an implementation file with a
.pyx suffix, containing
everything else. When a module wants to use something declared in another
module’s definition file, it imports it using the
.pxd file that consists solely of extern declarations does not need
to correspond to an actual
.pyx file or Python module. This can make it a
convenient place to put common declarations, for example declarations of
functions from an external library that one
wants to use in several modules.
A definition file can contain:
It cannot contain the implementations of any C or Python functions, or any
Python class definitions, or any executable statements. It is needed when one
wants to access
cdef attributes and methods, or to inherit from
cdef classes defined in this module.
You don’t need to (and shouldn’t) declare anything in a declaration file public in order to make it available to other Cython modules; its mere presence in a definition file does that. You only need a public declaration if you want to make something available to external C code.
An implementation file can contain any kind of Cython statement, although there
are some restrictions on the implementation part of an extension type if the
corresponding definition file also defines that type (see below).
If one doesn’t need to
cimport anything from this module, then this
is the only file one needs.
cimport statement is used in a definition or
implementation file to gain access to names declared in another definition
file. Its syntax exactly parallels that of the normal Python import
cimport module [, module...] from module cimport name [as name] [, name [as name] ...]
Here is an example.
dishes.pxd is a definition file which exports a
C data type.
restaurant.pyx is an implementation file which imports and
cdef enum otherstuff: sausage, eggs, lettuce cdef struct spamdish: int oz_of_spam otherstuff filler
cimport dishes from dishes cimport spamdish cdef void prepare(spamdish *d): d.oz_of_spam = 42 d.filler = dishes.sausage def serve(): cdef spamdish d prepare(&d) print "%d oz spam, filler no. %d" % (d.oz_of_spam, d.filler)
It is important to understand that the
cimport statement can only
be used to import C data types, C functions and variables, and extension
types. It cannot be used to import any Python objects, and (with one
exception) it doesn’t imply any Python import at run time. If you want to
refer to any Python names from a module that you have cimported, you will have
to include a regular import statement for it as well.
The exception is that when you use
cimport to import an extension type, its
type object is imported at run time and made available by the name under which
you imported it. Using
cimport to import extension types is covered in more
.pxd file changes, any modules that
cimport from it may need to be
Cython.Build.cythonize utility can take care of this for you.
cimport a module called
modulename, the Cython
compiler searches for a file called
It searches for this file along the path for include files
(as specified by
-I command line options or the
cythonize()), as well as
package_data to install
.pxd files in your
allows other packages to cimport items from your module as a dependency.
Also, whenever you compile a file
modulename.pyx, the corresponding
modulename.pxd is first searched for along the
include path (but not
sys.path), and if found, it is processed before
cimport mechanism provides a clean and simple way to solve the
problem of wrapping external C functions with Python functions of the same
name. All you need to do is put the extern C declarations into a
for an imaginary module, and
cimport that module. You can then
refer to the C functions by qualifying them with the name of the module.
Here’s an example:
cdef extern from "lunch.h": void eject_tomato(float)
cimport c_lunch def eject_tomato(float speed): c_lunch.eject_tomato(speed)
You don’t need any
c_lunch.pyx file, because the only things defined
c_lunch.pxd are extern C entities. There won’t be any actual
c_lunch module at run time, but that doesn’t matter; the
c_lunch.pxd file has done its job of providing an additional namespace
at compile time.