Try statement in Cython for cimport (for use with mpi4py)
cython, mpi4py, preprocessor-directive, try-catch
Solution
Using a try-catch block in this way is something you won't be able to do. The extension module you are making must be statically compiled and linked against the things it uses `cimport` to load at the C-level. A try-catch block is something that will be executed when the module is imported, not when it is compiled.
On the other hand, in theory, you should be able to get the effect you're looking for using Cython's support for conditional compilation. In your `setup.py` file you can check to see if the needed modules are defined and then define environment variables to be passed to the Cython compiler that, in turn, depend on whether or not the needed modules are present.
There's an example of how to do this in one of Cython's tests. There they pass a dictionary containing the desired environment variables to the constructor for Cython's `Extension` class as the keyword argument `pyrex_compile_time_env`, which has been renamed to `cython_compile_time_env`, and for `Cython.Build.Dependencies.cythonize` is called `compile_time_env`).
Problem
Is there a way to have the equivalent of the Python try statement in Cython for the cimport? Something like that: ``` try: cimport something except ImportError: pass ``` I would need this to write a Cython extension that can be compiled with or without mpi4py. This is very standard in compiled languages where the mpi commands can be put between #ifdef and #endif preprocessor directives. How can we obtain the same result in Cython? I tried this but it does not work: ``` try: from mpi4py import MPI from mpi4py cimport MPI from mpi4py.mpi_c cimport * except ImportError: rank = 0 nb_proc = 1 # solve a incompatibility between openmpi and mpi4py versions cdef extern from 'mpi-compat.h': pass does_it_work = 'Not yet' ``` Actually it works well if mpi4py is correctly installed but if `import mpi4py` raises an ImportError, the Cython file does not compile and I get the error: ``` Error compiling Cython file: ------------------------------------------------------------ ... try: from mpi4py import MPI from mpi4py cimport MPI ^ ------------------------------------------------------------ mod.pyx:4:4: 'mpi4py.pxd' not found ``` The file `setup.py`: ``` from setuptools import setup, Extension from Cython.Distutils import build_ext import os here = os.path.abspath(os.path.dirname(__file__)) include_dirs = [here] try: import mpi4py except ImportError: pass else: INCLUDE_MPI = '/usr/lib/openmpi/include' include_dirs.extend([ INCLUDE_MPI, mpi4py.get_include()]) name = 'mod' ext = Extension( name, include_dirs=include_dirs, sources=['mod.pyx']) setup(name=name, cmdclass={"build_ext": build_ext}, ext_modules=[ext]) ```