Writing extension modules for pypy¶
This document tries to explain how to interface the PyPy python interpreter with any external library.
Right now, there are the following possibilities of providing third-party modules for the PyPy python interpreter (in order, from most directly useful to most messy to use with PyPy):
- Write them in pure Python and use CFFI.
- Write them in pure Python and use ctypes.
- Write them in C++ and bind them through cppyy using Cling.
- Write them as RPython mixed modules.
CFFI is the recommended way. It is a way to write pure Python code
that accesses C libraries. The idea is to support either ABI- or
API-level access to C — so that you can sanely access C libraries
without depending on details like the exact field order in the C
structures or the numerical value of all the constants. It works on
both CPython (as a separate
pip install cffi) and on PyPy, where it
is included by default.
PyPy’s JIT does a quite reasonable job on the Python code that call C functions or manipulate C pointers with CFFI. (As of PyPy 2.2.1, it could still be improved, but is already good.)
See the documentation here.
The goal of the ctypes module of PyPy is to be as compatible as possible with the CPython ctypes version. It works for large examples, such as pyglet. PyPy’s implementation is not strictly 100% compatible with CPython, but close enough for most cases.
We also used to provide
ctypes-configure for some API-level access.
This is now viewed as a precursor of CFFI, which you should use instead.
More (but older) information is available here.
Also, ctypes’ performance is not as good as CFFI’s.
PyPy implements ctypes as pure Python code around two built-in modules
_rawffi, which give a very low-level binding to
the C library libffi. Nowadays it is not recommended to use directly
these two modules.
For C++, _cppyy_ is an automated bindings generator available for both
PyPy and CPython.
_cppyy_ relies on declarations from C++ header files to dynamically
construct Python equivalent classes, functions, variables, etc.
It is designed for use by large scale programs and supports modern C++.
With PyPy, it leverages the built-in
_cppyy module, allowing the JIT to
remove most of the cross-language overhead.
To install, run
pip install cppyy.
Further details are available in the full documentation.
RPython Mixed Modules¶
This is the internal way to write built-in extension modules in PyPy. It cannot be used by any 3rd-party module: the extension modules are built-in, not independently loadable DLLs.
This is reserved for special cases: it gives direct access to e.g. the details of the JIT, allowing us to tweak its interaction with user code. This is how the numpy module is being developed.