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.

  1. Create an include directory inside of your package for all of the header files.

  2. Use the get_package_data hook in setup_package.py to install those header files. For example, the scikit-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