Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
68811fa9
Commit
68811fa9
authored
Aug 01, 2012
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
support in-place building for pyximport
parent
a4e6c41f
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
42 additions
and
21 deletions
+42
-21
pyximport/pyxbuild.py
pyximport/pyxbuild.py
+10
-3
pyximport/pyximport.py
pyximport/pyximport.py
+32
-18
No files found.
pyximport/pyxbuild.py
View file @
68811fa9
...
@@ -21,7 +21,8 @@ DEBUG = 0
...
@@ -21,7 +21,8 @@ DEBUG = 0
_reloads
=
{}
_reloads
=
{}
def
pyx_to_dll
(
filename
,
ext
=
None
,
force_rebuild
=
0
,
def
pyx_to_dll
(
filename
,
ext
=
None
,
force_rebuild
=
0
,
build_in_temp
=
False
,
pyxbuild_dir
=
None
,
setup_args
=
{},
reload_support
=
False
):
build_in_temp
=
False
,
pyxbuild_dir
=
None
,
setup_args
=
{},
reload_support
=
False
,
inplace
=
False
):
"""Compile a PYX file to a DLL and return the name of the generated .so
"""Compile a PYX file to a DLL and return the name of the generated .so
or .dll ."""
or .dll ."""
assert
os
.
path
.
exists
(
filename
),
"Could not find %s"
%
os
.
path
.
abspath
(
filename
)
assert
os
.
path
.
exists
(
filename
),
"Could not find %s"
%
os
.
path
.
abspath
(
filename
)
...
@@ -82,10 +83,16 @@ def pyx_to_dll(filename, ext = None, force_rebuild = 0,
...
@@ -82,10 +83,16 @@ def pyx_to_dll(filename, ext = None, force_rebuild = 0,
try
:
try
:
dist
.
run_commands
()
obj_build_ext
=
dist
.
get_command_obj
(
"build_ext"
)
obj_build_ext
=
dist
.
get_command_obj
(
"build_ext"
)
orig_inplace
=
obj_build_ext
.
inplace
if
inplace
:
obj_build_ext
.
inplace
=
True
try
:
dist
.
run_commands
()
finally
:
obj_build_ext
.
inplace
=
orig_inplace
so_path
=
obj_build_ext
.
get_outputs
()[
0
]
so_path
=
obj_build_ext
.
get_outputs
()[
0
]
if
o
bj_build_ext
.
inplace
:
if
o
rig_inplace
or
inplace
:
# Python distutils get_outputs()[ returns a wrong so_path
# Python distutils get_outputs()[ returns a wrong so_path
# when --inplace ; see http://bugs.python.org/issue5977
# when --inplace ; see http://bugs.python.org/issue5977
# workaround:
# workaround:
...
...
pyximport/pyximport.py
View file @
68811fa9
...
@@ -160,7 +160,7 @@ def handle_dependencies(pyxfilename):
...
@@ -160,7 +160,7 @@ def handle_dependencies(pyxfilename):
if
testing
:
if
testing
:
_test_files
.
append
(
file
)
_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
),
(
assert
os
.
path
.
exists
(
pyxfilename
),
(
"Path does not exist: %s"
%
pyxfilename
)
"Path does not exist: %s"
%
pyxfilename
)
handle_dependencies
(
pyxfilename
)
handle_dependencies
(
pyxfilename
)
...
@@ -176,6 +176,7 @@ def build_module(name, pyxfilename, pyxbuild_dir=None):
...
@@ -176,6 +176,7 @@ def build_module(name, pyxfilename, pyxbuild_dir=None):
build_in_temp
=
build_in_temp
,
build_in_temp
=
build_in_temp
,
pyxbuild_dir
=
pyxbuild_dir
,
pyxbuild_dir
=
pyxbuild_dir
,
setup_args
=
sargs
,
setup_args
=
sargs
,
inplace
=
inplace
,
reload_support
=
pyxargs
.
reload_support
)
reload_support
=
pyxargs
.
reload_support
)
assert
os
.
path
.
exists
(
so_path
),
"Cannot find: %s"
%
so_path
assert
os
.
path
.
exists
(
so_path
),
"Cannot find: %s"
%
so_path
...
@@ -190,13 +191,13 @@ def build_module(name, pyxfilename, pyxbuild_dir=None):
...
@@ -190,13 +191,13 @@ def build_module(name, pyxfilename, pyxbuild_dir=None):
return
so_path
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
:
try
:
if
is_package
:
if
is_package
:
module_name
=
name
+
'.__init__'
module_name
=
name
+
'.__init__'
else
:
else
:
module_name
=
name
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
)
mod
=
imp
.
load_dynamic
(
name
,
so_path
)
assert
mod
.
__file__
==
so_path
,
(
mod
.
__file__
,
so_path
)
assert
mod
.
__file__
==
so_path
,
(
mod
.
__file__
,
so_path
)
except
Exception
:
except
Exception
:
...
@@ -217,9 +218,10 @@ def load_module(name, pyxfilename, pyxbuild_dir=None, is_package=False):
...
@@ -217,9 +218,10 @@ def load_module(name, pyxfilename, pyxbuild_dir=None, is_package=False):
class
PyxImporter
(
object
):
class
PyxImporter
(
object
):
"""A meta-path importer for .pyx files.
"""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
.
extension
=
extension
self
.
pyxbuild_dir
=
pyxbuild_dir
self
.
pyxbuild_dir
=
pyxbuild_dir
self
.
inplace
=
inplace
def
find_module
(
self
,
fullname
,
package_path
=
None
):
def
find_module
(
self
,
fullname
,
package_path
=
None
):
if
fullname
in
sys
.
modules
and
not
pyxargs
.
reload_support
:
if
fullname
in
sys
.
modules
and
not
pyxargs
.
reload_support
:
...
@@ -232,10 +234,12 @@ class PyxImporter(object):
...
@@ -232,10 +234,12 @@ class PyxImporter(object):
if
os
.
path
.
isfile
(
pkg_file
):
if
os
.
path
.
isfile
(
pkg_file
):
return
PyxLoader
(
fullname
,
pathname
,
return
PyxLoader
(
fullname
,
pathname
,
init_path
=
pkg_file
,
init_path
=
pkg_file
,
pyxbuild_dir
=
self
.
pyxbuild_dir
)
pyxbuild_dir
=
self
.
pyxbuild_dir
,
inplace
=
self
.
inplace
)
if
pathname
and
pathname
.
endswith
(
self
.
extension
):
if
pathname
and
pathname
.
endswith
(
self
.
extension
):
return
PyxLoader
(
fullname
,
pathname
,
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!
if
ty
!=
imp
.
C_EXTENSION
:
# only when an extension, check if we have a .pyx next!
return
None
return
None
...
@@ -243,7 +247,8 @@ class PyxImporter(object):
...
@@ -243,7 +247,8 @@ class PyxImporter(object):
pyxpath
=
os
.
path
.
splitext
(
pathname
)[
0
]
+
self
.
extension
pyxpath
=
os
.
path
.
splitext
(
pathname
)[
0
]
+
self
.
extension
if
os
.
path
.
isfile
(
pyxpath
):
if
os
.
path
.
isfile
(
pyxpath
):
return
PyxLoader
(
fullname
,
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
# .so/.pyd's on PATH should not be remote from .pyx's
# think no need to implement PyxArgs.importer_search_remote here?
# think no need to implement PyxArgs.importer_search_remote here?
...
@@ -277,7 +282,8 @@ class PyxImporter(object):
...
@@ -277,7 +282,8 @@ class PyxImporter(object):
path
=
os
.
getcwd
()
path
=
os
.
getcwd
()
if
is_file
(
path
+
sep
+
pyx_module_name
):
if
is_file
(
path
+
sep
+
pyx_module_name
):
return
PyxLoader
(
fullname
,
join_path
(
path
,
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
# not found, normal package, not a .pyx file, none of our business
_debug
(
"%s not found"
%
fullname
)
_debug
(
"%s not found"
%
fullname
)
...
@@ -286,9 +292,9 @@ class PyxImporter(object):
...
@@ -286,9 +292,9 @@ class PyxImporter(object):
class
PyImporter
(
PyxImporter
):
class
PyImporter
(
PyxImporter
):
"""A meta-path importer for normal .py files.
"""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
=
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
.
uncompilable_modules
=
{}
self
.
blocked_modules
=
[
'Cython'
,
'distutils.extension'
,
self
.
blocked_modules
=
[
'Cython'
,
'distutils.extension'
,
'distutils.sysconfig'
]
'distutils.sysconfig'
]
...
@@ -326,7 +332,8 @@ class PyImporter(PyxImporter):
...
@@ -326,7 +332,8 @@ class PyImporter(PyxImporter):
real_name
=
fullname
real_name
=
fullname
_debug
(
"importer found path %s for module %s"
,
path
,
real_name
)
_debug
(
"importer found path %s for module %s"
,
path
,
real_name
)
build_module
(
real_name
,
path
,
build_module
(
real_name
,
path
,
pyxbuild_dir
=
self
.
pyxbuild_dir
)
pyxbuild_dir
=
self
.
pyxbuild_dir
,
inplace
=
self
.
inplace
)
except
Exception
,
e
:
except
Exception
,
e
:
if
DEBUG_IMPORT
:
if
DEBUG_IMPORT
:
import
traceback
import
traceback
...
@@ -343,11 +350,12 @@ class PyImporter(PyxImporter):
...
@@ -343,11 +350,12 @@ class PyImporter(PyxImporter):
return
importer
return
importer
class
PyxLoader
(
object
):
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
)
_debug
(
"PyxLoader created for loading %s from %s (init path: %s)"
,
fullname
,
path
,
init_path
)
self
.
fullname
=
fullname
self
.
fullname
=
fullname
self
.
path
,
self
.
init_path
=
path
,
init_path
self
.
path
,
self
.
init_path
=
path
,
init_path
self
.
pyxbuild_dir
=
pyxbuild_dir
self
.
pyxbuild_dir
=
pyxbuild_dir
self
.
inplace
=
inplace
def
load_module
(
self
,
fullname
):
def
load_module
(
self
,
fullname
):
assert
self
.
fullname
==
fullname
,
(
assert
self
.
fullname
==
fullname
,
(
...
@@ -357,12 +365,14 @@ class PyxLoader(object):
...
@@ -357,12 +365,14 @@ class PyxLoader(object):
# package
# package
#print "PACKAGE", fullname
#print "PACKAGE", fullname
module
=
load_module
(
fullname
,
self
.
init_path
,
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
]
module
.
__path__
=
[
self
.
path
]
else
:
else
:
#print "MODULE", fullname
#print "MODULE", fullname
module
=
load_module
(
fullname
,
self
.
path
,
module
=
load_module
(
fullname
,
self
.
path
,
self
.
pyxbuild_dir
)
self
.
pyxbuild_dir
,
build_inplace
=
self
.
inplace
)
return
module
return
module
...
@@ -388,7 +398,7 @@ def _have_importers():
...
@@ -388,7 +398,7 @@ def _have_importers():
def
install
(
pyximport
=
True
,
pyimport
=
False
,
build_dir
=
None
,
build_in_temp
=
True
,
def
install
(
pyximport
=
True
,
pyimport
=
False
,
build_dir
=
None
,
build_in_temp
=
True
,
setup_args
=
{},
reload_support
=
False
,
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
"""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
your meta-path for a single Python process. If you want it to be
installed whenever you use Python, add it to your sitecustomize
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,
...
@@ -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 second import will rerun these modifications in whatever state
the system was left after the import of the compiled module
the system was left after the import of the compiled module
failed.
failed.
``inplace``: Install the compiled module next to the source file.
"""
"""
if
not
build_dir
:
if
not
build_dir
:
build_dir
=
os
.
path
.
expanduser
(
'~/.pyxbld'
)
build_dir
=
os
.
path
.
expanduser
(
'~/.pyxbld'
)
...
@@ -442,11 +454,13 @@ def install(pyximport=True, pyimport=False, build_dir=None, build_in_temp=True,
...
@@ -442,11 +454,13 @@ def install(pyximport=True, pyimport=False, build_dir=None, build_in_temp=True,
py_importer
,
pyx_importer
=
None
,
None
py_importer
,
pyx_importer
=
None
,
None
if
pyimport
and
not
has_py_importer
:
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
)
sys
.
meta_path
.
insert
(
0
,
py_importer
)
if
pyximport
and
not
has_pyx_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
)
sys
.
meta_path
.
append
(
pyx_importer
)
return
py_importer
,
pyx_importer
return
py_importer
,
pyx_importer
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment