summaryrefslogtreecommitdiff
path: root/pyximport/pyximport.py
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2012-08-01 14:06:38 +0200
committerStefan Behnel <stefan_ml@behnel.de>2012-08-01 14:06:38 +0200
commit68811fa9946e4253ad405ba3011512a32807bc7b (patch)
tree090a0b4bdf0fb24e69ec98b9051aeb8d95203e56 /pyximport/pyximport.py
parenta4e6c41fc0dff70df19117df466a18b7133ae3b1 (diff)
downloadcython-68811fa9946e4253ad405ba3011512a32807bc7b.tar.gz
support in-place building for pyximport
Diffstat (limited to 'pyximport/pyximport.py')
-rw-r--r--pyximport/pyximport.py50
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