Commit 6a32131a authored by Lisandro Dalcin's avatar Lisandro Dalcin

zipimport support for cimporting pxd's from Cython/Includes

parent 3a667aa9
...@@ -78,8 +78,8 @@ class Context(object): ...@@ -78,8 +78,8 @@ class Context(object):
self.pxds = {} # full name -> node tree self.pxds = {} # full name -> node tree
standard_include_path = os.path.abspath( standard_include_path = os.path.abspath(os.path.normpath(
os.path.join(os.path.dirname(__file__), '..', 'Includes')) os.path.join(os.path.dirname(__file__), os.path.pardir, 'Includes')))
self.include_directories = include_directories + [standard_include_path] self.include_directories = include_directories + [standard_include_path]
def create_pipeline(self, pxd, py=False): def create_pipeline(self, pxd, py=False):
...@@ -356,17 +356,17 @@ class Context(object): ...@@ -356,17 +356,17 @@ class Context(object):
for dir in dirs: for dir in dirs:
path = os.path.join(dir, dotted_filename) path = os.path.join(dir, dotted_filename)
if os.path.exists(path): if Utils.path_exists(path):
return path return path
if not include: if not include:
package_dir = self.check_package_dir(dir, package_names) package_dir = self.check_package_dir(dir, package_names)
if package_dir is not None: if package_dir is not None:
path = os.path.join(package_dir, module_filename) path = os.path.join(package_dir, module_filename)
if os.path.exists(path): if Utils.path_exists(path):
return path return path
path = os.path.join(dir, package_dir, module_name, path = os.path.join(dir, package_dir, module_name,
package_filename) package_filename)
if os.path.exists(path): if Utils.path_exists(path):
return path return path
return None return None
...@@ -380,14 +380,11 @@ class Context(object): ...@@ -380,14 +380,11 @@ class Context(object):
return dir return dir
def check_package_dir(self, dir, package_names): def check_package_dir(self, dir, package_names):
package_dir = os.path.join(dir, *package_names)
if not os.path.exists(package_dir):
return None
for dirname in package_names: for dirname in package_names:
dir = os.path.join(dir, dirname) dir = os.path.join(dir, dirname)
if not self.is_package_dir(dir): if not self.is_package_dir(dir):
return None return None
return package_dir return dir
def c_file_out_of_date(self, source_path): def c_file_out_of_date(self, source_path):
c_path = Utils.replace_suffix(source_path, ".c") c_path = Utils.replace_suffix(source_path, ".c")
...@@ -421,7 +418,7 @@ class Context(object): ...@@ -421,7 +418,7 @@ class Context(object):
"__init__.pyx", "__init__.pyx",
"__init__.pxd"): "__init__.pxd"):
path = os.path.join(dir_path, filename) path = os.path.join(dir_path, filename)
if os.path.exists(path): if Utils.path_exists(path):
return 1 return 1
def read_dependency_file(self, source_path): def read_dependency_file(self, source_path):
......
...@@ -45,6 +45,27 @@ def file_newer_than(path, time): ...@@ -45,6 +45,27 @@ def file_newer_than(path, time):
ftime = modification_time(path) ftime = modification_time(path)
return ftime > time return ftime > time
def path_exists(path):
# try on the filesystem first
if os.path.exists(path):
return True
# figure out if a PEP 302 loader is around
try:
loader = __loader__
# XXX the code below assumes as 'zipimport.zipimporter' instance
# XXX should be easy to generalize, but too lazy right now to write it
if path.startswith(loader.archive):
nrmpath = os.path.normpath(path)
arcname = nrmpath[len(loader.archive)+1:]
try:
loader.get_data(arcname)
return True
except IOError:
return False
except NameError:
pass
return False
# support for source file encoding detection # support for source file encoding detection
def encode_filename(filename): def encode_filename(filename):
...@@ -110,17 +131,28 @@ class NormalisedNewlineStream(object): ...@@ -110,17 +131,28 @@ class NormalisedNewlineStream(object):
return u''.join(content).split(u'\n') return u''.join(content).split(u'\n')
try: try:
from io import open as io_open import io
except ImportError: except ImportError:
io_open = None io = None
def open_source_file(source_filename, mode="r", def open_source_file(source_filename, mode="r",
encoding=None, error_handling=None, encoding=None, error_handling=None,
require_normalised_newlines=True): require_normalised_newlines=True):
if encoding is None: if encoding is None:
encoding = detect_file_encoding(source_filename) encoding = detect_file_encoding(source_filename)
if io_open is not None: #
return io_open(source_filename, mode=mode, try:
loader = __loader__
if source_filename.startswith(loader.archive):
return open_source_from_loader(
loader, source_filename,
encoding, error_handling,
require_normalised_newlines)
except (NameError, AttributeError):
pass
#
if io is not None:
return io.open(source_filename, mode=mode,
encoding=encoding, errors=error_handling) encoding=encoding, errors=error_handling)
else: else:
# codecs module doesn't have universal newline support # codecs module doesn't have universal newline support
...@@ -130,6 +162,28 @@ def open_source_file(source_filename, mode="r", ...@@ -130,6 +162,28 @@ def open_source_file(source_filename, mode="r",
stream = NormalisedNewlineStream(stream) stream = NormalisedNewlineStream(stream)
return stream return stream
def open_source_from_loader(loader,
source_filename,
encoding=None, error_handling=None,
require_normalised_newlines=True):
nrmpath = os.path.normpath(source_filename)
arcname = nrmpath[len(loader.archive)+1:]
data = loader.get_data(arcname)
if io is not None:
return io.TextIOWrapper(io.BytesIO(data),
encoding=encoding,
errors=error_handling)
else:
try:
import cStringIO as StringIO
except ImportError:
import StringIO
reader = codecs.getreader(encoding)
stream = reader(StringIO.StringIO(data))
if require_normalised_newlines:
stream = NormalisedNewlineStream(stream)
return stream
def long_literal(value): def long_literal(value):
if isinstance(value, basestring): if isinstance(value, basestring):
if len(value) < 2: if len(value) < 2:
......
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