Commit 17bef673 authored by Sergei Lebedev's avatar Sergei Lebedev

Allowed importing pyx files from ZIP archives

parent 0d27e211
...@@ -47,10 +47,11 @@ the documentation. ...@@ -47,10 +47,11 @@ the documentation.
This code is based on the Py2.3+ import protocol as described in PEP 302. This code is based on the Py2.3+ import protocol as described in PEP 302.
""" """
import sys
import os
import glob import glob
import imp import imp
import os
import sys
from zipimport import zipimporter, ZipImportError
mod_name = "pyximport" mod_name = "pyximport"
...@@ -300,19 +301,31 @@ class PyxImporter(object): ...@@ -300,19 +301,31 @@ class PyxImporter(object):
paths = package_path paths = package_path
else: else:
paths = sys.path 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: for path in paths:
if not path: if not path:
path = os.getcwd() path = os.getcwd()
elif not is_abs(path): elif not os.path.isabs(path):
path = abspath(path) path = os.path.abspath(path)
if is_file(path+sep+pyx_module_name):
return PyxLoader(fullname, join_path(path, pyx_module_name), 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, pyxbuild_dir=self.pyxbuild_dir,
inplace=self.inplace, inplace=self.inplace,
language_level=self.language_level) language_level=self.language_level)
......
from __future__ import absolute_import, print_function 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 os
import time, shutil import shutil
import sys
import tempfile import tempfile
import time
from zipfile import ZipFile
try:
from __builtin__ import reload
except ImportError:
from importlib import reload
def make_tempdir(): def make_tempdir():
...@@ -27,7 +36,7 @@ def on_remove_file_error(func, path, excinfo): ...@@ -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.") print("You may want to delete this yourself when you get a chance.")
def test(): def test_with_reload():
pyximport._test_files = [] pyximport._test_files = []
tempdir = make_tempdir() tempdir = make_tempdir()
sys.path.append(tempdir) sys.path.append(tempdir)
...@@ -68,5 +77,27 @@ def make_ext(name, filename): ...@@ -68,5 +77,27 @@ def make_ext(name, filename):
remove_tempdir(tempdir) remove_tempdir(tempdir)
if __name__=="__main__": def test_zip():
test() 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()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment