|
Packit |
562c7a |
Pyximport
|
|
Packit |
562c7a |
=========
|
|
Packit |
562c7a |
|
|
Packit |
562c7a |
Cython is a compiler. Therefore it is natural that people tend to go
|
|
Packit |
562c7a |
through an edit/compile/test cycle with Cython modules. But my personal
|
|
Packit |
562c7a |
opinion is that one of the deep insights in Python's implementation is
|
|
Packit |
562c7a |
that a language can be compiled (Python modules are compiled to .pyc)
|
|
Packit |
562c7a |
files and hide that compilation process from the end-user so that they
|
|
Packit |
562c7a |
do not have to worry about it. Pyximport does this for Cython modules.
|
|
Packit |
562c7a |
For instance if you write a Cython module called ``foo.pyx``, with
|
|
Packit |
562c7a |
Pyximport you can import it in a regular Python module like this::
|
|
Packit |
562c7a |
|
|
Packit |
562c7a |
import pyximport; pyximport.install()
|
|
Packit |
562c7a |
import foo
|
|
Packit |
562c7a |
|
|
Packit |
562c7a |
Doing so will result in the compilation of ``foo.pyx`` (with appropriate
|
|
Packit |
562c7a |
exceptions if it has an error in it).
|
|
Packit |
562c7a |
|
|
Packit |
562c7a |
If you would always like to import Cython files without building them
|
|
Packit |
562c7a |
specially, you can also add the first line above to your sitecustomize.py.
|
|
Packit |
562c7a |
That will install the hook every time you run Python. Then you can use
|
|
Packit |
562c7a |
Cython modules just with simple import statements. I like to test my
|
|
Packit |
562c7a |
Cython modules like this::
|
|
Packit |
562c7a |
|
|
Packit |
562c7a |
python -c "import foo"
|
|
Packit |
562c7a |
|
|
Packit |
562c7a |
See help(pyximport.install) to learn its options for controlling the
|
|
Packit |
562c7a |
default behavior of ``import`` and ``reload``.
|
|
Packit |
562c7a |
|
|
Packit |
562c7a |
Dependency Handling
|
|
Packit |
562c7a |
-------------------
|
|
Packit |
562c7a |
|
|
Packit |
562c7a |
In Pyximport 1.1 it is possible to declare that your module depends on
|
|
Packit |
562c7a |
multiple files, (likely ``.h`` and ``.pxd`` files). If your Cython module is
|
|
Packit |
562c7a |
named ``foo`` and thus has the filename ``foo.pyx`` then you should make
|
|
Packit |
562c7a |
another file in the same directory called ``foo.pyxdep``. The
|
|
Packit |
562c7a |
``modname.pyxdep`` file can be a list of filenames or ``globs`` (like
|
|
Packit |
562c7a |
``*.pxd`` or ``include/*.h``). Each filename or glob must be on a separate
|
|
Packit |
562c7a |
line. Pyximport will check the file date for each of those files before
|
|
Packit |
562c7a |
deciding whether to rebuild the module. In order to keep track of the
|
|
Packit |
562c7a |
fact that the dependency has been handled, Pyximport updates the
|
|
Packit |
562c7a |
modification time of your ``.pyx`` source file. Future versions may do
|
|
Packit |
562c7a |
something more sophisticated like informing distutils of the
|
|
Packit |
562c7a |
dependencies directly.
|
|
Packit |
562c7a |
|
|
Packit |
562c7a |
Limitations
|
|
Packit |
562c7a |
-----------
|
|
Packit |
562c7a |
Pyximport does not give you any control over how your Cython file is
|
|
Packit |
562c7a |
compiled. Usually the defaults are fine. You might run into problems if
|
|
Packit |
562c7a |
you wanted to write your program in half-C, half-Cython and build them
|
|
Packit |
562c7a |
into a single library. Pyximport 1.2 will probably do this.
|
|
Packit |
562c7a |
|
|
Packit |
562c7a |
Pyximport does not hide the Distutils/GCC warnings and errors generated
|
|
Packit |
562c7a |
by the import process. Arguably this will give you better feedback if
|
|
Packit |
562c7a |
something went wrong and why. And if nothing went wrong it will give you
|
|
Packit |
562c7a |
the warm fuzzy that pyximport really did rebuild your module as it was
|
|
Packit |
562c7a |
supposed to.
|
|
Packit |
562c7a |
|
|
Packit |
562c7a |
For further thought and discussion
|
|
Packit |
562c7a |
----------------------------------
|
|
Packit |
562c7a |
|
|
Packit |
562c7a |
``setup.py install`` does not modify ``sitecustomize.py`` for you. Should it?
|
|
Packit |
562c7a |
Modifying Python's "standard interpreter" behaviour may be more than
|
|
Packit |
562c7a |
most people expect of a package they install..
|
|
Packit |
562c7a |
|
|
Packit |
562c7a |
Pyximport puts your ``.c`` file beside your ``.pyx`` file (analogous to
|
|
Packit |
562c7a |
``.pyc`` beside ``.py``). But it puts the platform-specific binary in a
|
|
Packit |
562c7a |
build directory as per normal for Distutils. If I could wave a magic
|
|
Packit |
562c7a |
wand and get Cython or distutils or whoever to put the build directory I
|
|
Packit |
562c7a |
might do it but not necessarily: having it at the top level is VERY
|
|
Packit |
562c7a |
HELPFUL for debugging Cython problems.
|