|
@@ -1,3 +1,6 @@
|
|
|
+import importlib
|
|
|
+import importlib.abc
|
|
|
+import importlib.machinery
|
|
|
import os
|
|
|
import shutil
|
|
|
import sys
|
|
@@ -85,127 +88,60 @@ def copytree_ignore_callback(excludes, pkgdir, modname, directory, files):
|
|
|
|
|
|
return ignored
|
|
|
|
|
|
-if not PY2:
|
|
|
- import importlib
|
|
|
- import importlib.abc
|
|
|
- import importlib.machinery
|
|
|
|
|
|
- class ModuleCopier:
|
|
|
- """Finds and copies importable Python modules and packages.
|
|
|
+class ModuleCopier:
|
|
|
+ """Finds and copies importable Python modules and packages.
|
|
|
|
|
|
- This is the Python >3.3 version and uses the `importlib` package to
|
|
|
- locate modules.
|
|
|
- """
|
|
|
- def __init__(self, py_version, path=None):
|
|
|
- self.py_version = py_version
|
|
|
- self.path = path if (path is not None) else ([''] + sys.path)
|
|
|
-
|
|
|
- def copy(self, modname, target, exclude):
|
|
|
- """Copy the importable module 'modname' to the directory 'target'.
|
|
|
-
|
|
|
- modname should be a top-level import, i.e. without any dots.
|
|
|
- Packages are always copied whole.
|
|
|
-
|
|
|
- This can currently copy regular filesystem files and directories,
|
|
|
- and extract modules and packages from appropriately structured zip
|
|
|
- files.
|
|
|
- """
|
|
|
- loader = importlib.find_loader(modname, self.path)
|
|
|
- if loader is None:
|
|
|
- raise ImportError('Could not find %s' % modname)
|
|
|
- pkg = loader.is_package(modname)
|
|
|
-
|
|
|
- if isinstance(loader, importlib.machinery.ExtensionFileLoader):
|
|
|
- check_ext_mod(loader.path, self.py_version)
|
|
|
- shutil.copy2(loader.path, target)
|
|
|
-
|
|
|
- elif isinstance(loader, importlib.abc.FileLoader):
|
|
|
- file = loader.get_filename(modname)
|
|
|
- if pkg:
|
|
|
- pkgdir, basename = os.path.split(file)
|
|
|
- assert basename.startswith('__init__')
|
|
|
- check_package_for_ext_mods(pkgdir, self.py_version)
|
|
|
- dest = os.path.join(target, modname)
|
|
|
- if exclude:
|
|
|
- shutil.copytree(
|
|
|
- pkgdir, dest,
|
|
|
- ignore=partial(copytree_ignore_callback, exclude, pkgdir, modname)
|
|
|
- )
|
|
|
- else:
|
|
|
- # Don't use our exclude callback if we don't need to,
|
|
|
- # as it slows things down.
|
|
|
- shutil.copytree(
|
|
|
- pkgdir, dest,
|
|
|
- ignore=shutil.ignore_patterns('*.pyc')
|
|
|
- )
|
|
|
- else:
|
|
|
- shutil.copy2(file, target)
|
|
|
+ This is the Python >3.3 version and uses the `importlib` package to
|
|
|
+ locate modules.
|
|
|
+ """
|
|
|
+ def __init__(self, py_version, path=None):
|
|
|
+ self.py_version = py_version
|
|
|
+ self.path = path if (path is not None) else ([''] + sys.path)
|
|
|
|
|
|
- elif isinstance(loader, zipimport.zipimporter):
|
|
|
- copy_zipmodule(loader, modname, target)
|
|
|
-else:
|
|
|
- import imp
|
|
|
+ def copy(self, modname, target, exclude):
|
|
|
+ """Copy the importable module 'modname' to the directory 'target'.
|
|
|
|
|
|
- class ModuleCopier:
|
|
|
- """Finds and copies importable Python modules and packages.
|
|
|
+ modname should be a top-level import, i.e. without any dots.
|
|
|
+ Packages are always copied whole.
|
|
|
|
|
|
- This is the Python 2.7 version and uses the `imp` package to locate
|
|
|
- modules.
|
|
|
+ This can currently copy regular filesystem files and directories,
|
|
|
+ and extract modules and packages from appropriately structured zip
|
|
|
+ files.
|
|
|
"""
|
|
|
- def __init__(self, py_version, path=None):
|
|
|
- self.py_version = py_version
|
|
|
- self.path = path if (path is not None) else ([''] + sys.path)
|
|
|
- self.zip_paths = [p for p in self.path if zipfile.is_zipfile(p)]
|
|
|
-
|
|
|
- def copy(self, modname, target, exclude):
|
|
|
- """Copy the importable module 'modname' to the directory 'target'.
|
|
|
-
|
|
|
- modname should be a top-level import, i.e. without any dots.
|
|
|
- Packages are always copied whole.
|
|
|
-
|
|
|
- This can currently copy regular filesystem files and directories,
|
|
|
- and extract modules and packages from appropriately structured zip
|
|
|
- files.
|
|
|
- """
|
|
|
- try:
|
|
|
- info = imp.find_module(modname, self.path)
|
|
|
- except ImportError:
|
|
|
- # Search all ZIP files in self.path for the module name
|
|
|
- # NOTE: `imp.find_module(...)` will *not* find modules in ZIP
|
|
|
- # files, so we have to check each file for ourselves
|
|
|
- for zpath in self.zip_paths:
|
|
|
- loader = zipimport.zipimporter(zpath)
|
|
|
- if loader.find_module(modname) is None:
|
|
|
- continue
|
|
|
- copy_zipmodule(loader, modname, target)
|
|
|
- return
|
|
|
- # Not found in zip files either - re-raise exception
|
|
|
- raise
|
|
|
-
|
|
|
- path = info[1]
|
|
|
- modtype = info[2][2]
|
|
|
-
|
|
|
- if modtype == imp.C_EXTENSION:
|
|
|
- check_ext_mod(path, self.py_version)
|
|
|
-
|
|
|
- if modtype in (imp.PY_SOURCE, imp.C_EXTENSION):
|
|
|
- shutil.copy2(path, target)
|
|
|
-
|
|
|
- elif modtype == imp.PKG_DIRECTORY:
|
|
|
- check_package_for_ext_mods(path, self.py_version)
|
|
|
+ loader = importlib.find_loader(modname, self.path)
|
|
|
+ if loader is None:
|
|
|
+ raise ImportError('Could not find %s' % modname)
|
|
|
+ pkg = loader.is_package(modname)
|
|
|
+
|
|
|
+ if isinstance(loader, importlib.machinery.ExtensionFileLoader):
|
|
|
+ check_ext_mod(loader.path, self.py_version)
|
|
|
+ shutil.copy2(loader.path, target)
|
|
|
+
|
|
|
+ elif isinstance(loader, importlib.abc.FileLoader):
|
|
|
+ file = loader.get_filename(modname)
|
|
|
+ if pkg:
|
|
|
+ pkgdir, basename = os.path.split(file)
|
|
|
+ assert basename.startswith('__init__')
|
|
|
+ check_package_for_ext_mods(pkgdir, self.py_version)
|
|
|
dest = os.path.join(target, modname)
|
|
|
if exclude:
|
|
|
shutil.copytree(
|
|
|
- path, dest,
|
|
|
- ignore=partial(copytree_ignore_callback, exclude, path, modname)
|
|
|
+ pkgdir, dest,
|
|
|
+ ignore=partial(copytree_ignore_callback, exclude, pkgdir, modname)
|
|
|
)
|
|
|
else:
|
|
|
# Don't use our exclude callback if we don't need to,
|
|
|
# as it slows things down.
|
|
|
shutil.copytree(
|
|
|
- path, dest,
|
|
|
+ pkgdir, dest,
|
|
|
ignore=shutil.ignore_patterns('*.pyc')
|
|
|
)
|
|
|
+ else:
|
|
|
+ shutil.copy2(file, target)
|
|
|
+
|
|
|
+ elif isinstance(loader, zipimport.zipimporter):
|
|
|
+ copy_zipmodule(loader, modname, target)
|
|
|
|
|
|
|
|
|
def copy_modules(modnames, target, py_version, path=None, exclude=None):
|