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
Kirill Smelkov
cython
Commits
17bef673
Commit
17bef673
authored
Oct 12, 2016
by
Sergei Lebedev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allowed importing pyx files from ZIP archives
parent
0d27e211
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
77 additions
and
33 deletions
+77
-33
pyximport/pyximport.py
pyximport/pyximport.py
+39
-26
pyximport/test/test_pyximport.py
pyximport/test/test_pyximport.py
+38
-7
No files found.
pyximport/pyximport.py
View file @
17bef673
"""
Import hooks; when installed with the install() function, these hooks
Import hooks; when installed with the install() function, these hooks
allow importing .pyx files as if they were Python modules.
If you want the hook installed every time you run Python
you can add it to your Python version by adding these lines to
sitecustomize.py (which you can create from scratch in site-packages
sitecustomize.py (which you can create from scratch in site-packages
if it doesn't exist there or somewhere else on your python path)::
import pyximport
...
...
@@ -47,10 +47,11 @@ the documentation.
This code is based on the Py2.3+ import protocol as described in PEP 302.
"""
import
sys
import
os
import
glob
import
imp
import
os
import
sys
from
zipimport
import
zipimporter
,
ZipImportError
mod_name
=
"pyximport"
...
...
@@ -79,8 +80,8 @@ def _info(message, *args):
# Performance problem: for every PYX file that is imported, we will
# invoke the whole distutils infrastructure even if the module is
# already built. It might be more efficient to only do it when the
# invoke the whole distutils infrastructure even if the module is
# already built. It might be more efficient to only do it when the
# mod time of the .pyx is newer than the mod time of the .so but
# the question is how to get distutils to tell me the name of the .so
# before it builds it. Maybe it is easy...but maybe the peformance
...
...
@@ -94,7 +95,7 @@ def get_distutils_extension(modname, pyxfilename, language_level=None):
# import hashlib
# except ImportError:
# import md5 as hashlib
# extra = "_" + hashlib.md5(open(pyxfilename).read()).hexdigest()
# extra = "_" + hashlib.md5(open(pyxfilename).read()).hexdigest()
# modname = modname + extra
extension_mod
,
setup_args
=
handle_special_build
(
modname
,
pyxfilename
)
if
not
extension_mod
:
...
...
@@ -113,7 +114,7 @@ def handle_special_build(modname, pyxfilename):
special_build
=
os
.
path
.
splitext
(
pyxfilename
)[
0
]
+
PYXBLD_EXT
ext
=
None
setup_args
=
{}
if
os
.
path
.
exists
(
special_build
):
if
os
.
path
.
exists
(
special_build
):
# globls = {}
# locs = {}
# execfile(special_build, globls, locs)
...
...
@@ -126,11 +127,11 @@ def handle_special_build(modname, pyxfilename):
make_setup_args
=
getattr
(
mod
,
'make_setup_args'
,
None
)
if
make_setup_args
:
setup_args
=
make_setup_args
()
assert
isinstance
(
setup_args
,
dict
),
(
"make_setup_args in %s did not return a dict"
assert
isinstance
(
setup_args
,
dict
),
(
"make_setup_args in %s did not return a dict"
%
special_build
)
assert
set
or
setup_args
,
(
"neither make_ext nor make_setup_args %s"
assert
set
or
setup_args
,
(
"neither make_ext nor make_setup_args %s"
%
special_build
)
ext
.
sources
=
[
os
.
path
.
join
(
os
.
path
.
dirname
(
special_build
),
source
)
ext
.
sources
=
[
os
.
path
.
join
(
os
.
path
.
dirname
(
special_build
),
source
)
for
source
in
ext
.
sources
]
return
ext
,
setup_args
...
...
@@ -142,7 +143,7 @@ def handle_dependencies(pyxfilename):
# by default let distutils decide whether to rebuild on its own
# (it has a better idea of what the output file will be)
# but we know more about dependencies so force a rebuild if
# but we know more about dependencies so force a rebuild if
# some of the dependencies are newer than the pyxfile.
if
os
.
path
.
exists
(
dependfile
):
depends
=
open
(
dependfile
).
readlines
()
...
...
@@ -153,7 +154,7 @@ def handle_dependencies(pyxfilename):
files
=
[
dependfile
]
for
depend
in
depends
:
fullpath
=
os
.
path
.
join
(
os
.
path
.
dirname
(
dependfile
),
depend
)
depend
)
files
.
extend
(
glob
.
glob
(
fullpath
))
# only for unit testing to see we did the right thing
...
...
@@ -191,7 +192,7 @@ def build_module(name, pyxfilename, pyxbuild_dir=None, inplace=False, language_l
inplace
=
inplace
,
reload_support
=
pyxargs
.
reload_support
)
assert
os
.
path
.
exists
(
so_path
),
"Cannot find: %s"
%
so_path
junkpath
=
os
.
path
.
join
(
os
.
path
.
dirname
(
so_path
),
name
+
"_*"
)
#very dangerous with --inplace ? yes, indeed, trying to eat my files ;)
junkstuff
=
glob
.
glob
(
junkpath
)
for
path
in
junkstuff
:
...
...
@@ -249,7 +250,7 @@ class PyxImporter(object):
def
find_module
(
self
,
fullname
,
package_path
=
None
):
if
fullname
in
sys
.
modules
and
not
pyxargs
.
reload_support
:
return
None
# only here when reload()
return
None
# only here when reload()
try
:
fp
,
pathname
,
(
ext
,
mode
,
ty
)
=
imp
.
find_module
(
fullname
,
package_path
)
if
fp
:
fp
.
close
()
# Python should offer a Default-Loader to avoid this double find/open!
...
...
@@ -300,19 +301,31 @@ class PyxImporter(object):
paths
=
package_path
else
:
paths
=
sys
.
path
join_path
=
os
.
path
.
join
is_file
=
os
.
path
.
isfile
is_abs
=
os
.
path
.
isabs
abspath
=
os
.
path
.
abspath
#is_dir = os.path.isdir
sep
=
os
.
path
.
sep
for
path
in
paths
:
if
not
path
:
path
=
os
.
getcwd
()
elif
not
is_abs
(
path
):
path
=
abspath
(
path
)
if
is_file
(
path
+
sep
+
pyx_module_name
):
return
PyxLoader
(
fullname
,
join_path
(
path
,
pyx_module_name
),
elif
not
os
.
path
.
isabs
(
path
):
path
=
os
.
path
.
abspath
(
path
)
try
:
zi
=
zipimporter
(
path
)
data
=
zi
.
get_data
(
pyx_module_name
)
except
(
ZipImportError
,
IOError
):
pyx_module_path
=
os
.
path
.
join
(
path
,
pyx_module_name
)
else
:
# XXX unzip the imported file into the build dir. A bit
# hacky, but it works!
if
not
os
.
path
.
exists
(
self
.
pyxbuild_dir
):
os
.
makedirs
(
self
.
pyxbuild_dir
)
pyx_module_path
=
os
.
path
.
join
(
self
.
pyxbuild_dir
,
pyx_module_name
)
with
open
(
pyx_module_path
,
"wb"
)
as
handle
:
handle
.
write
(
data
)
if
os
.
path
.
isfile
(
pyx_module_path
):
return
PyxLoader
(
fullname
,
pyx_module_path
,
pyxbuild_dir
=
self
.
pyxbuild_dir
,
inplace
=
self
.
inplace
,
language_level
=
self
.
language_level
)
...
...
@@ -520,7 +533,7 @@ def install(pyximport=True, pyimport=False, build_dir=None, build_in_temp=True,
setup_args
=
{}
if
not
build_dir
:
build_dir
=
os
.
path
.
join
(
os
.
path
.
expanduser
(
'~'
),
'.pyxbld'
)
global
pyxargs
pyxargs
=
PyxArgs
()
#$pycheck_no
pyxargs
.
build_dir
=
build_dir
...
...
pyximport/test/test_pyximport.py
View file @
17bef673
from
__future__
import
absolute_import
,
print_function
from
pyximport
import
pyximport
;
pyximport
.
install
(
reload_support
=
True
)
from
pyximport
import
pyximport
pyximport
.
install
(
reload_support
=
True
)
import
os
,
sys
import
time
,
shutil
import
os
import
shutil
import
sys
import
tempfile
import
time
from
zipfile
import
ZipFile
try
:
from
__builtin__
import
reload
except
ImportError
:
from
importlib
import
reload
def
make_tempdir
():
...
...
@@ -27,7 +36,7 @@ def on_remove_file_error(func, path, excinfo):
print
(
"You may want to delete this yourself when you get a chance."
)
def
test
():
def
test
_with_reload
():
pyximport
.
_test_files
=
[]
tempdir
=
make_tempdir
()
sys
.
path
.
append
(
tempdir
)
...
...
@@ -46,7 +55,7 @@ def test():
build_file
.
write
(
"""
from distutils.extension import Extension
def make_ext(name, filename):
return Extension(name=name, sources=[filename])
return Extension(name=name, sources=[filename])
"""
)
build_file
.
close
()
...
...
@@ -68,5 +77,27 @@ def make_ext(name, filename):
remove_tempdir
(
tempdir
)
if
__name__
==
"__main__"
:
test
()
def
test_zip
():
try
:
import
test_zip_module
except
ImportError
:
pass
else
:
assert
False
,
"test_zip_module already exists"
fd
,
zip_path
=
tempfile
.
mkstemp
(
suffix
=
".zip"
)
os
.
close
(
fd
)
try
:
with
ZipFile
(
zip_path
,
"w"
)
as
zf
:
zf
.
writestr
(
"test_zip_module.pyx"
,
b"x = 42"
)
sys
.
path
.
insert
(
0
,
zip_path
)
import
test_zip_module
assert
test_zip_module
.
x
==
42
finally
:
os
.
remove
(
zip_path
)
if
__name__
==
"__main__"
:
test_with_reload
()
test_zip
()
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