|
@@ -2221,6 +2221,10 @@ class Freezer:
|
|
|
|
|
|
|
|
return True
|
|
return True
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+_PKG_NAMESPACE_DIRECTORY = object()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
class PandaModuleFinder(modulefinder.ModuleFinder):
|
|
class PandaModuleFinder(modulefinder.ModuleFinder):
|
|
|
|
|
|
|
|
def __init__(self, *args, **kw):
|
|
def __init__(self, *args, **kw):
|
|
@@ -2279,6 +2283,44 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
|
|
|
|
|
|
|
|
return None
|
|
return None
|
|
|
|
|
|
|
|
|
|
+ def _dir_exists(self, path):
|
|
|
|
|
+ """Returns True if the given directory exists, either on disk or inside
|
|
|
|
|
+ a wheel."""
|
|
|
|
|
+
|
|
|
|
|
+ if os.path.isdir(path):
|
|
|
|
|
+ return True
|
|
|
|
|
+
|
|
|
|
|
+ # Is there a zip file along the path?
|
|
|
|
|
+ dir, dirname = os.path.split(path.rstrip(os.path.sep + '/'))
|
|
|
|
|
+ fn = dirname
|
|
|
|
|
+ while dirname:
|
|
|
|
|
+ if os.path.isfile(dir):
|
|
|
|
|
+ # Okay, this is actually a file. Is it a zip file?
|
|
|
|
|
+ if dir in self._zip_files:
|
|
|
|
|
+ # Yes, and we've previously opened this.
|
|
|
|
|
+ zip = self._zip_files[dir]
|
|
|
|
|
+ elif zipfile.is_zipfile(dir):
|
|
|
|
|
+ zip = zipfile.ZipFile(dir)
|
|
|
|
|
+ self._zip_files[dir] = zip
|
|
|
|
|
+ else:
|
|
|
|
|
+ # It's a different kind of file. Stop looking.
|
|
|
|
|
+ return None
|
|
|
|
|
+
|
|
|
|
|
+ # (Most) zip files do not store directories; check instead for a
|
|
|
|
|
+ # file whose path starts with this directory name.
|
|
|
|
|
+ prefix = fn.replace(os.path.sep, '/') + '/'
|
|
|
|
|
+ for name in zip.namelist():
|
|
|
|
|
+ if name.startswith(prefix):
|
|
|
|
|
+ return True
|
|
|
|
|
+
|
|
|
|
|
+ return False
|
|
|
|
|
+
|
|
|
|
|
+ # Look at the parent directory.
|
|
|
|
|
+ dir, dirname = os.path.split(dir)
|
|
|
|
|
+ fn = os.path.join(dirname, fn)
|
|
|
|
|
+
|
|
|
|
|
+ return False
|
|
|
|
|
+
|
|
|
def load_module(self, fqname, fp, pathname, file_info):
|
|
def load_module(self, fqname, fp, pathname, file_info):
|
|
|
"""Copied from ModuleFinder.load_module with fixes to handle sending bytes
|
|
"""Copied from ModuleFinder.load_module with fixes to handle sending bytes
|
|
|
to compile() for PY_SOURCE types. Sending bytes to compile allows it to
|
|
to compile() for PY_SOURCE types. Sending bytes to compile allows it to
|
|
@@ -2291,6 +2333,12 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
|
|
|
self.msgout(2, "load_module ->", m)
|
|
self.msgout(2, "load_module ->", m)
|
|
|
return m
|
|
return m
|
|
|
|
|
|
|
|
|
|
+ if type is _PKG_NAMESPACE_DIRECTORY:
|
|
|
|
|
+ m = self.add_module(fqname)
|
|
|
|
|
+ m.__code__ = compile('', '', 'exec')
|
|
|
|
|
+ m.__path__ = pathname
|
|
|
|
|
+ return m
|
|
|
|
|
+
|
|
|
if type == imp.PY_SOURCE:
|
|
if type == imp.PY_SOURCE:
|
|
|
if fqname in overrideModules:
|
|
if fqname in overrideModules:
|
|
|
# This module has a custom override.
|
|
# This module has a custom override.
|
|
@@ -2384,6 +2432,8 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
|
|
|
pass
|
|
pass
|
|
|
|
|
|
|
|
# Look for the module on the search path.
|
|
# Look for the module on the search path.
|
|
|
|
|
+ ns_dirs = []
|
|
|
|
|
+
|
|
|
for dir_path in path:
|
|
for dir_path in path:
|
|
|
basename = os.path.join(dir_path, name.split('.')[-1])
|
|
basename = os.path.join(dir_path, name.split('.')[-1])
|
|
|
|
|
|
|
@@ -2400,6 +2450,10 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
|
|
|
if self._open_file(init, mode):
|
|
if self._open_file(init, mode):
|
|
|
return (None, basename, ('', '', imp.PKG_DIRECTORY))
|
|
return (None, basename, ('', '', imp.PKG_DIRECTORY))
|
|
|
|
|
|
|
|
|
|
+ # This may be a namespace package.
|
|
|
|
|
+ if self._dir_exists(basename):
|
|
|
|
|
+ ns_dirs.append(basename)
|
|
|
|
|
+
|
|
|
# It wasn't found through the normal channels. Maybe it's one of
|
|
# It wasn't found through the normal channels. Maybe it's one of
|
|
|
# ours, or maybe it's frozen?
|
|
# ours, or maybe it's frozen?
|
|
|
if not path:
|
|
if not path:
|
|
@@ -2408,6 +2462,11 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
|
|
|
# It's a frozen module.
|
|
# It's a frozen module.
|
|
|
return (None, name, ('', '', imp.PY_FROZEN))
|
|
return (None, name, ('', '', imp.PY_FROZEN))
|
|
|
|
|
|
|
|
|
|
+ # If we found folders on the path with this module name without an
|
|
|
|
|
+ # __init__.py file, we should consider this a namespace package.
|
|
|
|
|
+ if ns_dirs and sys.version_info >= (3, 3):
|
|
|
|
|
+ return (None, ns_dirs, ('', '', _PKG_NAMESPACE_DIRECTORY))
|
|
|
|
|
+
|
|
|
raise ImportError(name)
|
|
raise ImportError(name)
|
|
|
|
|
|
|
|
def find_all_submodules(self, m):
|
|
def find_all_submodules(self, m):
|