C or Cython Extensions¶
Warning
This page has not been fully adapted from astropy
Scikit-beam supports using C extensions for wrapping C libraries and Cython for
speeding up computationally-intensive calculations. Both Cython and C extension
building can be customized using the get_extensions
function of the
setup_package.py
file. If defined, this function must return a list of
distutils.core.Extension
objects. The creation process is left to the
subpackage designer, and can be customized however is relevant for the
extensions in the subpackage.
While C extensions must always be defined through the get_extensions
mechanism, Cython files (ending in .pyx
) are automatically located and
loaded in separate extensions if they are not in get_extensions
. For
Cython extensions located in this way, headers for numpy C functions are
included in the build, but no other external headers are included. .pyx
files present in the extensions returned by get_extensions
are not
included in the list of extensions automatically generated extensions. Note
that this allows disabling a Cython file by providing an extension that
includes the Cython file, but giving it the special name
‘cython_skip’. Any
extension with this package name will not be built by setup.py
.
Note
If an Extension
object is provided for Cython
source files using the get_extensions
mechanism, it is very
important that the .pyx
files be given as the source
, rather than the
.c
files generated by Cython.
Installing C header files¶
If your C extension needs to be linked from other third-party C code, you probably want to install its header files along side the Python module.
Create an
include
directory inside of your package for all of the header files.Use the
get_package_data
hook insetup_package.py
to install those header files. For example, thescikit-beam.wcs
package has this:def get_package_data(): return {'scikit-beam.wcs': ['include/*.h']}
Preventing importing at build time¶
In rare cases, some packages may need to be imported at build time.
Unfortunately, anything that requires a C or Cython extension will fail to
import until the build phase has completed. In this cases, the
_ASTROPY_SETUP_
variable can be used to determine if the package is being
imported as part of the build and choose to not import problematic modules.
_ASTROPY_SETUP_
is inserted into the builtins, and is True when inside
of scikit-beam’s setup.py
script, and False otherwise.
For example, suppose there is a subpackage foo
that needs to
import a module called version.py
at build time in order to set
some version information, and also has a C extension, process
,
that will not be available in the source tree. In this case,
scikit-beam/foo/__init__.py
would probably want to check the value of
_ASTROPY_SETUP_
before importing the C extension:
try:
from . import process
except ImportError:
if not _ASTROPY_SETUP_:
raise
from . import version