Python compiler that transforms Python code into C/C++ extensions for high-performance computing.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The pyximport module provides import hooks that allow importing .pyx files directly as Python modules without explicit compilation. This system automatically compiles and caches Cython modules at import time, making development and testing more convenient.
Functions to install and manage the import hooks for automatic Cython compilation.
def install(pyximport=True, pyimport=False, build_dir=None,
build_in_temp=True, setup_args=None, reload_support=False,
load_py_module_on_import_failure=False, inplace=False,
language_level=None):
"""Install import hooks for .pyx files.
Args:
pyximport: Enable .pyx file import hooks
pyimport: Enable .py file compilation (experimental)
build_dir: Directory for compiled modules (default: ~/.pyxbld)
build_in_temp: Build in temporary directory vs locally
setup_args: Additional arguments for distutils setup
reload_support: Enable dynamic reload() support
load_py_module_on_import_failure: Fallback to .py on compilation failure
inplace: Install compiled modules next to source files
language_level: Source language level (2 or 3)
Returns:
Tuple of (py_importer, pyx_importer) instances
"""
def uninstall(py_importer, pyx_importer):
"""Uninstall previously installed import hooks.
Args:
py_importer: Python file importer to remove
pyx_importer: Pyrex/Cython file importer to remove
"""Functions for manually building individual Cython modules.
def build_module(name, pyxfilename, pyxbuild_dir=None, inplace=False,
language_level=None):
"""Build a single Cython module from source.
Args:
name: Module name
pyxfilename: Path to .pyx source file
pyxbuild_dir: Build directory for compilation
inplace: Build module in same directory as source
language_level: Python language level (2 or 3)
Returns:
Path to compiled shared library (.so/.pyd file)
"""Meta path finders and loaders that implement the import hook functionality.
class PyxImportMetaFinder:
"""Meta path finder for .pyx files."""
def __init__(self, extension=".pyx", pyxbuild_dir=None,
inplace=False, language_level=None):
"""Initialize .pyx file finder.
Args:
extension: File extension to handle (default: ".pyx")
pyxbuild_dir: Build directory for compilation
inplace: Build modules in-place
language_level: Python language level
"""
def find_spec(self, fullname, path, target=None):
"""Find module spec for .pyx files.
Args:
fullname: Fully qualified module name
path: Module search path
target: Target module (optional)
Returns:
ModuleSpec for .pyx file or None if not found
"""
class PyImportMetaFinder:
"""Meta path finder for .py files (experimental)."""
def __init__(self, extension=".py", pyxbuild_dir=None,
inplace=False, language_level=None):
"""Initialize .py file finder for Cython compilation.
Args:
extension: File extension to handle (default: ".py")
pyxbuild_dir: Build directory for compilation
inplace: Build modules in-place
language_level: Python language level
"""
def find_spec(self, fullname, path, target=None):
"""Find module spec for .py files to compile with Cython.
Args:
fullname: Fully qualified module name
path: Module search path
target: Target module (optional)
Returns:
ModuleSpec for .py file or None if not found
"""
class PyxImportLoader:
"""Loader for .pyx and .py files."""
def __init__(self, filename, pyxbuild_dir, inplace, language_level):
"""Initialize loader for Cython files.
Args:
filename: Path to source file
pyxbuild_dir: Build directory
inplace: Build in-place flag
language_level: Python language level
"""
def create_module(self, spec):
"""Create module from compiled extension.
Args:
spec: Module spec
Returns:
Loaded module object
"""
def exec_module(self, module):
"""Execute the loaded module.
Args:
module: Module to execute
"""import pyximport
pyximport.install()
# Now you can import .pyx files directly
import my_cython_module
result = my_cython_module.fast_function(42)import pyximport
# Install with specific configuration
py_importer, pyx_importer = pyximport.install(
build_dir="./build/cython", # Custom build directory
build_in_temp=False, # Build locally for debugging
language_level=3, # Use Python 3 syntax
inplace=True, # Build .so files next to .pyx files
reload_support=True, # Enable module reloading
)
# Import and use Cython modules
import my_module
print(my_module.compute_something())
# Clean up when done
pyximport.uninstall(py_importer, pyx_importer)import pyximport
# Enable compilation of .py files (experimental)
pyximport.install(
pyimport=True, # Enable .py file compilation
load_py_module_on_import_failure=True, # Fallback to Python on failure
language_level=3,
)
# Regular Python files may now be compiled with Cython
import my_python_module # This .py file might get compiledimport pyximport
import os
# Development configuration
debug_mode = os.environ.get('DEBUG', '0') == '1'
pyximport.install(
build_in_temp=not debug_mode, # Build locally when debugging
setup_args={
'script_args': ['--force'] if debug_mode else [],
'options': {
'build_ext': {
'define': [('CYTHON_TRACE', '1')] if debug_mode else []
}
}
},
language_level=3,
)
# Now imports will use debug configuration
import my_debug_moduleimport pyximport
# Build a specific module manually
so_path = pyximport.build_module(
name="my_module",
pyxfilename="./src/my_module.pyx",
pyxbuild_dir="./build",
inplace=False,
language_level=3
)
print(f"Module compiled to: {so_path}")
# Load the compiled module
import importlib.util
spec = importlib.util.spec_from_file_location("my_module", so_path)
my_module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(my_module)import pyximport
import contextlib
@contextlib.contextmanager
def cython_imports(**kwargs):
"""Context manager for temporary Cython import hooks."""
importers = pyximport.install(**kwargs)
try:
yield
finally:
pyximport.uninstall(*importers)
# Use within a specific context
with cython_imports(language_level=3, build_in_temp=True):
import my_cython_module
result = my_cython_module.process_data([1, 2, 3, 4, 5])
print(result)# In your package's __init__.py
import pyximport
pyximport.install(language_level=3)
# Directory structure:
# my_package/
# __init__.py (contains pyximport.install())
# algorithms.pyx (Cython implementation)
# utils.pyx (Cython utilities)
# interface.py (Pure Python interface)
# Users can now import your package normally:
# import my_package.algorithms
# import my_package.utilsYou can create .pyxbld files for custom build configuration:
# my_module.pyxbld - build configuration for my_module.pyx
def make_ext(modname, pyxfilename):
from distutils.extension import Extension
return Extension(
name=modname,
sources=[pyxfilename, 'helper.c'],
include_dirs=['/usr/local/include'],
libraries=['custom_lib'],
define_macros=[('MY_DEFINE', '1')]
)
def make_setup_args():
return dict(script_args=["--compiler=mingw32"])# my_module.pyxdep - dependency tracking for my_module.pyx
header1.h
header2.h
../common/shared.pxiInstall with Tessl CLI
npx tessl i tessl/pypi-cython