0
# Import System
1
2
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.
3
4
## Capabilities
5
6
### Installation and Management
7
8
Functions to install and manage the import hooks for automatic Cython compilation.
9
10
```python { .api }
11
def install(pyximport=True, pyimport=False, build_dir=None,
12
build_in_temp=True, setup_args=None, reload_support=False,
13
load_py_module_on_import_failure=False, inplace=False,
14
language_level=None):
15
"""Install import hooks for .pyx files.
16
17
Args:
18
pyximport: Enable .pyx file import hooks
19
pyimport: Enable .py file compilation (experimental)
20
build_dir: Directory for compiled modules (default: ~/.pyxbld)
21
build_in_temp: Build in temporary directory vs locally
22
setup_args: Additional arguments for distutils setup
23
reload_support: Enable dynamic reload() support
24
load_py_module_on_import_failure: Fallback to .py on compilation failure
25
inplace: Install compiled modules next to source files
26
language_level: Source language level (2 or 3)
27
28
Returns:
29
Tuple of (py_importer, pyx_importer) instances
30
"""
31
32
def uninstall(py_importer, pyx_importer):
33
"""Uninstall previously installed import hooks.
34
35
Args:
36
py_importer: Python file importer to remove
37
pyx_importer: Pyrex/Cython file importer to remove
38
"""
39
```
40
41
### Module Building
42
43
Functions for manually building individual Cython modules.
44
45
```python { .api }
46
def build_module(name, pyxfilename, pyxbuild_dir=None, inplace=False,
47
language_level=None):
48
"""Build a single Cython module from source.
49
50
Args:
51
name: Module name
52
pyxfilename: Path to .pyx source file
53
pyxbuild_dir: Build directory for compilation
54
inplace: Build module in same directory as source
55
language_level: Python language level (2 or 3)
56
57
Returns:
58
Path to compiled shared library (.so/.pyd file)
59
"""
60
```
61
62
### Internal Classes
63
64
Meta path finders and loaders that implement the import hook functionality.
65
66
```python { .api }
67
class PyxImportMetaFinder:
68
"""Meta path finder for .pyx files."""
69
70
def __init__(self, extension=".pyx", pyxbuild_dir=None,
71
inplace=False, language_level=None):
72
"""Initialize .pyx file finder.
73
74
Args:
75
extension: File extension to handle (default: ".pyx")
76
pyxbuild_dir: Build directory for compilation
77
inplace: Build modules in-place
78
language_level: Python language level
79
"""
80
81
def find_spec(self, fullname, path, target=None):
82
"""Find module spec for .pyx files.
83
84
Args:
85
fullname: Fully qualified module name
86
path: Module search path
87
target: Target module (optional)
88
89
Returns:
90
ModuleSpec for .pyx file or None if not found
91
"""
92
93
class PyImportMetaFinder:
94
"""Meta path finder for .py files (experimental)."""
95
96
def __init__(self, extension=".py", pyxbuild_dir=None,
97
inplace=False, language_level=None):
98
"""Initialize .py file finder for Cython compilation.
99
100
Args:
101
extension: File extension to handle (default: ".py")
102
pyxbuild_dir: Build directory for compilation
103
inplace: Build modules in-place
104
language_level: Python language level
105
"""
106
107
def find_spec(self, fullname, path, target=None):
108
"""Find module spec for .py files to compile with Cython.
109
110
Args:
111
fullname: Fully qualified module name
112
path: Module search path
113
target: Target module (optional)
114
115
Returns:
116
ModuleSpec for .py file or None if not found
117
"""
118
119
class PyxImportLoader:
120
"""Loader for .pyx and .py files."""
121
122
def __init__(self, filename, pyxbuild_dir, inplace, language_level):
123
"""Initialize loader for Cython files.
124
125
Args:
126
filename: Path to source file
127
pyxbuild_dir: Build directory
128
inplace: Build in-place flag
129
language_level: Python language level
130
"""
131
132
def create_module(self, spec):
133
"""Create module from compiled extension.
134
135
Args:
136
spec: Module spec
137
138
Returns:
139
Loaded module object
140
"""
141
142
def exec_module(self, module):
143
"""Execute the loaded module.
144
145
Args:
146
module: Module to execute
147
"""
148
```
149
150
## Usage Examples
151
152
### Basic Import Hook Installation
153
154
```python
155
import pyximport
156
pyximport.install()
157
158
# Now you can import .pyx files directly
159
import my_cython_module
160
result = my_cython_module.fast_function(42)
161
```
162
163
### Advanced Installation with Options
164
165
```python
166
import pyximport
167
168
# Install with specific configuration
169
py_importer, pyx_importer = pyximport.install(
170
build_dir="./build/cython", # Custom build directory
171
build_in_temp=False, # Build locally for debugging
172
language_level=3, # Use Python 3 syntax
173
inplace=True, # Build .so files next to .pyx files
174
reload_support=True, # Enable module reloading
175
)
176
177
# Import and use Cython modules
178
import my_module
179
print(my_module.compute_something())
180
181
# Clean up when done
182
pyximport.uninstall(py_importer, pyx_importer)
183
```
184
185
### Experimental Python File Compilation
186
187
```python
188
import pyximport
189
190
# Enable compilation of .py files (experimental)
191
pyximport.install(
192
pyimport=True, # Enable .py file compilation
193
load_py_module_on_import_failure=True, # Fallback to Python on failure
194
language_level=3,
195
)
196
197
# Regular Python files may now be compiled with Cython
198
import my_python_module # This .py file might get compiled
199
```
200
201
### Development Setup with Debugging
202
203
```python
204
import pyximport
205
import os
206
207
# Development configuration
208
debug_mode = os.environ.get('DEBUG', '0') == '1'
209
210
pyximport.install(
211
build_in_temp=not debug_mode, # Build locally when debugging
212
setup_args={
213
'script_args': ['--force'] if debug_mode else [],
214
'options': {
215
'build_ext': {
216
'define': [('CYTHON_TRACE', '1')] if debug_mode else []
217
}
218
}
219
},
220
language_level=3,
221
)
222
223
# Now imports will use debug configuration
224
import my_debug_module
225
```
226
227
### Manual Module Building
228
229
```python
230
import pyximport
231
232
# Build a specific module manually
233
so_path = pyximport.build_module(
234
name="my_module",
235
pyxfilename="./src/my_module.pyx",
236
pyxbuild_dir="./build",
237
inplace=False,
238
language_level=3
239
)
240
241
print(f"Module compiled to: {so_path}")
242
243
# Load the compiled module
244
import importlib.util
245
spec = importlib.util.spec_from_file_location("my_module", so_path)
246
my_module = importlib.util.module_from_spec(spec)
247
spec.loader.exec_module(my_module)
248
```
249
250
### Context Manager Usage
251
252
```python
253
import pyximport
254
import contextlib
255
256
@contextlib.contextmanager
257
def cython_imports(**kwargs):
258
"""Context manager for temporary Cython import hooks."""
259
importers = pyximport.install(**kwargs)
260
try:
261
yield
262
finally:
263
pyximport.uninstall(*importers)
264
265
# Use within a specific context
266
with cython_imports(language_level=3, build_in_temp=True):
267
import my_cython_module
268
result = my_cython_module.process_data([1, 2, 3, 4, 5])
269
print(result)
270
```
271
272
### Package Structure with Import Hooks
273
274
```python
275
# In your package's __init__.py
276
import pyximport
277
pyximport.install(language_level=3)
278
279
# Directory structure:
280
# my_package/
281
# __init__.py (contains pyximport.install())
282
# algorithms.pyx (Cython implementation)
283
# utils.pyx (Cython utilities)
284
# interface.py (Pure Python interface)
285
286
# Users can now import your package normally:
287
# import my_package.algorithms
288
# import my_package.utils
289
```
290
291
### Build Configuration Files
292
293
You can create `.pyxbld` files for custom build configuration:
294
295
```python
296
# my_module.pyxbld - build configuration for my_module.pyx
297
def make_ext(modname, pyxfilename):
298
from distutils.extension import Extension
299
return Extension(
300
name=modname,
301
sources=[pyxfilename, 'helper.c'],
302
include_dirs=['/usr/local/include'],
303
libraries=['custom_lib'],
304
define_macros=[('MY_DEFINE', '1')]
305
)
306
307
def make_setup_args():
308
return dict(script_args=["--compiler=mingw32"])
309
```
310
311
```python
312
# my_module.pyxdep - dependency tracking for my_module.pyx
313
header1.h
314
header2.h
315
../common/shared.pxi
316
```