diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2012-08-01 14:06:38 +0200 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2012-08-01 14:06:38 +0200 |
commit | 68811fa9946e4253ad405ba3011512a32807bc7b (patch) | |
tree | 090a0b4bdf0fb24e69ec98b9051aeb8d95203e56 /pyximport/pyximport.py | |
parent | a4e6c41fc0dff70df19117df466a18b7133ae3b1 (diff) | |
download | cython-68811fa9946e4253ad405ba3011512a32807bc7b.tar.gz |
support in-place building for pyximport
Diffstat (limited to 'pyximport/pyximport.py')
-rw-r--r-- | pyximport/pyximport.py | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/pyximport/pyximport.py b/pyximport/pyximport.py index 772b16e8f..b46e15ef0 100644 --- a/pyximport/pyximport.py +++ b/pyximport/pyximport.py @@ -160,7 +160,7 @@ def handle_dependencies(pyxfilename): if testing: _test_files.append(file) -def build_module(name, pyxfilename, pyxbuild_dir=None): +def build_module(name, pyxfilename, pyxbuild_dir=None, inplace=False): assert os.path.exists(pyxfilename), ( "Path does not exist: %s" % pyxfilename) handle_dependencies(pyxfilename) @@ -176,6 +176,7 @@ def build_module(name, pyxfilename, pyxbuild_dir=None): build_in_temp=build_in_temp, pyxbuild_dir=pyxbuild_dir, setup_args=sargs, + inplace=inplace, reload_support=pyxargs.reload_support) assert os.path.exists(so_path), "Cannot find: %s" % so_path @@ -190,13 +191,13 @@ def build_module(name, pyxfilename, pyxbuild_dir=None): return so_path -def load_module(name, pyxfilename, pyxbuild_dir=None, is_package=False): +def load_module(name, pyxfilename, pyxbuild_dir=None, is_package=False, build_inplace=False): try: if is_package: module_name = name + '.__init__' else: module_name = name - so_path = build_module(module_name, pyxfilename, pyxbuild_dir) + so_path = build_module(module_name, pyxfilename, pyxbuild_dir, inplace=build_inplace) mod = imp.load_dynamic(name, so_path) assert mod.__file__ == so_path, (mod.__file__, so_path) except Exception: @@ -217,9 +218,10 @@ def load_module(name, pyxfilename, pyxbuild_dir=None, is_package=False): class PyxImporter(object): """A meta-path importer for .pyx files. """ - def __init__(self, extension=PYX_EXT, pyxbuild_dir=None): + def __init__(self, extension=PYX_EXT, pyxbuild_dir=None, inplace=False): self.extension = extension self.pyxbuild_dir = pyxbuild_dir + self.inplace = inplace def find_module(self, fullname, package_path=None): if fullname in sys.modules and not pyxargs.reload_support: @@ -232,10 +234,12 @@ class PyxImporter(object): if os.path.isfile(pkg_file): return PyxLoader(fullname, pathname, init_path=pkg_file, - pyxbuild_dir=self.pyxbuild_dir) + pyxbuild_dir=self.pyxbuild_dir, + inplace=self.inplace) if pathname and pathname.endswith(self.extension): return PyxLoader(fullname, pathname, - pyxbuild_dir=self.pyxbuild_dir) + pyxbuild_dir=self.pyxbuild_dir, + inplace=self.inplace) if ty != imp.C_EXTENSION: # only when an extension, check if we have a .pyx next! return None @@ -243,8 +247,9 @@ class PyxImporter(object): pyxpath = os.path.splitext(pathname)[0]+self.extension if os.path.isfile(pyxpath): return PyxLoader(fullname, pyxpath, - pyxbuild_dir=self.pyxbuild_dir) - + pyxbuild_dir=self.pyxbuild_dir, + inplace=self.inplace) + # .so/.pyd's on PATH should not be remote from .pyx's # think no need to implement PyxArgs.importer_search_remote here? @@ -277,7 +282,8 @@ class PyxImporter(object): path = os.getcwd() if is_file(path+sep+pyx_module_name): return PyxLoader(fullname, join_path(path, pyx_module_name), - pyxbuild_dir=self.pyxbuild_dir) + pyxbuild_dir=self.pyxbuild_dir, + inplace=self.inplace) # not found, normal package, not a .pyx file, none of our business _debug("%s not found" % fullname) @@ -286,9 +292,9 @@ class PyxImporter(object): class PyImporter(PyxImporter): """A meta-path importer for normal .py files. """ - def __init__(self, pyxbuild_dir=None): + def __init__(self, pyxbuild_dir=None, inplace=False): self.super = super(PyImporter, self) - self.super.__init__(extension='.py', pyxbuild_dir=pyxbuild_dir) + self.super.__init__(extension='.py', pyxbuild_dir=pyxbuild_dir, inplace=inplace) self.uncompilable_modules = {} self.blocked_modules = ['Cython', 'distutils.extension', 'distutils.sysconfig'] @@ -326,7 +332,8 @@ class PyImporter(PyxImporter): real_name = fullname _debug("importer found path %s for module %s", path, real_name) build_module(real_name, path, - pyxbuild_dir=self.pyxbuild_dir) + pyxbuild_dir=self.pyxbuild_dir, + inplace=self.inplace) except Exception, e: if DEBUG_IMPORT: import traceback @@ -343,11 +350,12 @@ class PyImporter(PyxImporter): return importer class PyxLoader(object): - def __init__(self, fullname, path, init_path=None, pyxbuild_dir=None): + def __init__(self, fullname, path, init_path=None, pyxbuild_dir=None, inplace=False): _debug("PyxLoader created for loading %s from %s (init path: %s)", fullname, path, init_path) self.fullname = fullname self.path, self.init_path = path, init_path self.pyxbuild_dir = pyxbuild_dir + self.inplace=inplace def load_module(self, fullname): assert self.fullname == fullname, ( @@ -357,12 +365,14 @@ class PyxLoader(object): # package #print "PACKAGE", fullname module = load_module(fullname, self.init_path, - self.pyxbuild_dir, is_package=True) + self.pyxbuild_dir, is_package=True, + build_inplace=self.inplace) module.__path__ = [self.path] else: #print "MODULE", fullname module = load_module(fullname, self.path, - self.pyxbuild_dir) + self.pyxbuild_dir, + build_inplace=self.inplace) return module @@ -388,7 +398,7 @@ def _have_importers(): def install(pyximport=True, pyimport=False, build_dir=None, build_in_temp=True, setup_args={}, reload_support=False, - load_py_module_on_import_failure=False): + load_py_module_on_import_failure=False, inplace=False): """Main entry point. Call this to install the .pyx import hook in your meta-path for a single Python process. If you want it to be installed whenever you use Python, add it to your sitecustomize @@ -426,6 +436,8 @@ def install(pyximport=True, pyimport=False, build_dir=None, build_in_temp=True, the second import will rerun these modifications in whatever state the system was left after the import of the compiled module failed. + + ``inplace``: Install the compiled module next to the source file. """ if not build_dir: build_dir = os.path.expanduser('~/.pyxbld') @@ -442,11 +454,13 @@ def install(pyximport=True, pyimport=False, build_dir=None, build_in_temp=True, py_importer, pyx_importer = None, None if pyimport and not has_py_importer: - py_importer = PyImporter(pyxbuild_dir=build_dir) + py_importer = PyImporter(pyxbuild_dir=build_dir, inplace=inplace) + # make sure we import Cython before we install the import hook + import pyxbuild, Cython.Compiler.Main, Cython.Compiler.Pipeline, Cython.Compiler.Optimize sys.meta_path.insert(0, py_importer) if pyximport and not has_pyx_importer: - pyx_importer = PyxImporter(pyxbuild_dir=build_dir) + pyx_importer = PyxImporter(pyxbuild_dir=build_dir, inplace=inplace) sys.meta_path.append(pyx_importer) return py_importer, pyx_importer |