summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2019-10-29 09:32:45 -0400
committerGitHub <noreply@github.com>2019-10-29 09:32:45 -0400
commit0ced2c09cc96ccb3ab757a9ca8d36327d7f025da (patch)
tree81d681bf5b9d126766add8aa0c4b71a638ce5306
parent7748921de342160ca2dc9c9539562bb9c924e14c (diff)
parentcfa9245a7dea8a35f11580c0bfd27472a3182c7e (diff)
downloadpython-setuptools-git-0ced2c09cc96ccb3ab757a9ca8d36327d7f025da.tar.gz
Merge pull request #1855 from isidentical/issue-479
Upgrade setuptools.depends to importlib from depracated imp
-rw-r--r--changelog.d/479.bugfix.rst1
-rw-r--r--conftest.py1
-rw-r--r--setuptools/_imp.py73
-rw-r--r--setuptools/depends.py48
-rw-r--r--setuptools/py27compat.py32
-rw-r--r--setuptools/py34compat.py13
6 files changed, 139 insertions, 29 deletions
diff --git a/changelog.d/479.bugfix.rst b/changelog.d/479.bugfix.rst
new file mode 100644
index 00000000..3c33964e
--- /dev/null
+++ b/changelog.d/479.bugfix.rst
@@ -0,0 +1 @@
+Replace usage of deprecated ``imp`` module with local re-implementation in ``setuptools._imp``.
diff --git a/conftest.py b/conftest.py
index 0d7b274c..1746bfb5 100644
--- a/conftest.py
+++ b/conftest.py
@@ -19,6 +19,7 @@ collect_ignore = [
if sys.version_info < (3,):
collect_ignore.append('setuptools/lib2to3_ex.py')
+ collect_ignore.append('setuptools/_imp.py')
if sys.version_info < (3, 6):
diff --git a/setuptools/_imp.py b/setuptools/_imp.py
new file mode 100644
index 00000000..a3cce9b2
--- /dev/null
+++ b/setuptools/_imp.py
@@ -0,0 +1,73 @@
+"""
+Re-implementation of find_module and get_frozen_object
+from the deprecated imp module.
+"""
+
+import os
+import importlib.util
+import importlib.machinery
+
+from .py34compat import module_from_spec
+
+
+PY_SOURCE = 1
+PY_COMPILED = 2
+C_EXTENSION = 3
+C_BUILTIN = 6
+PY_FROZEN = 7
+
+
+def find_module(module, paths=None):
+ """Just like 'imp.find_module()', but with package support"""
+ spec = importlib.util.find_spec(module, paths)
+ if spec is None:
+ raise ImportError("Can't find %s" % module)
+ if not spec.has_location and hasattr(spec, 'submodule_search_locations'):
+ spec = importlib.util.spec_from_loader('__init__.py', spec.loader)
+
+ kind = -1
+ file = None
+ static = isinstance(spec.loader, type)
+ if spec.origin == 'frozen' or static and issubclass(
+ spec.loader, importlib.machinery.FrozenImporter):
+ kind = PY_FROZEN
+ path = None # imp compabilty
+ suffix = mode = '' # imp compability
+ elif spec.origin == 'built-in' or static and issubclass(
+ spec.loader, importlib.machinery.BuiltinImporter):
+ kind = C_BUILTIN
+ path = None # imp compabilty
+ suffix = mode = '' # imp compability
+ elif spec.has_location:
+ path = spec.origin
+ suffix = os.path.splitext(path)[1]
+ mode = 'r' if suffix in importlib.machinery.SOURCE_SUFFIXES else 'rb'
+
+ if suffix in importlib.machinery.SOURCE_SUFFIXES:
+ kind = PY_SOURCE
+ elif suffix in importlib.machinery.BYTECODE_SUFFIXES:
+ kind = PY_COMPILED
+ elif suffix in importlib.machinery.EXTENSION_SUFFIXES:
+ kind = C_EXTENSION
+
+ if kind in {PY_SOURCE, PY_COMPILED}:
+ file = open(path, mode)
+ else:
+ path = None
+ suffix = mode = ''
+
+ return file, path, (suffix, mode, kind)
+
+
+def get_frozen_object(module, paths=None):
+ spec = importlib.util.find_spec(module, paths)
+ if not spec:
+ raise ImportError("Can't find %s" % module)
+ return spec.loader.get_code(module)
+
+
+def get_module(module, paths, info):
+ spec = importlib.util.find_spec(module, paths)
+ if not spec:
+ raise ImportError("Can't find %s" % module)
+ return module_from_spec(spec)
diff --git a/setuptools/depends.py b/setuptools/depends.py
index 45e7052d..a37675cb 100644
--- a/setuptools/depends.py
+++ b/setuptools/depends.py
@@ -1,11 +1,13 @@
import sys
-import imp
import marshal
+import contextlib
from distutils.version import StrictVersion
-from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN
from .py33compat import Bytecode
+from .py27compat import find_module, PY_COMPILED, PY_FROZEN, PY_SOURCE
+from . import py27compat
+
__all__ = [
'Require', 'find_module', 'get_module_constant', 'extract_constant'
@@ -15,7 +17,8 @@ __all__ = [
class Require:
"""A prerequisite to building or installing a distribution"""
- def __init__(self, name, requested_version, module, homepage='',
+ def __init__(
+ self, name, requested_version, module, homepage='',
attribute=None, format=None):
if format is None and requested_version is not None:
@@ -79,23 +82,15 @@ class Require:
return self.version_ok(version)
-def find_module(module, paths=None):
- """Just like 'imp.find_module()', but with package support"""
-
- parts = module.split('.')
-
- while parts:
- part = parts.pop(0)
- f, path, (suffix, mode, kind) = info = imp.find_module(part, paths)
-
- if kind == PKG_DIRECTORY:
- parts = parts or ['__init__']
- paths = [path]
-
- elif parts:
- raise ImportError("Can't find %r in %s" % (parts, module))
+def maybe_close(f):
+ @contextlib.contextmanager
+ def empty():
+ yield
+ return
+ if not f:
+ return empty()
- return info
+ return contextlib.closing(f)
def get_module_constant(module, symbol, default=-1, paths=None):
@@ -106,28 +101,23 @@ def get_module_constant(module, symbol, default=-1, paths=None):
constant. Otherwise, return 'default'."""
try:
- f, path, (suffix, mode, kind) = find_module(module, paths)
+ f, path, (suffix, mode, kind) = info = find_module(module, paths)
except ImportError:
# Module doesn't exist
return None
- try:
+ with maybe_close(f):
if kind == PY_COMPILED:
f.read(8) # skip magic & date
code = marshal.load(f)
elif kind == PY_FROZEN:
- code = imp.get_frozen_object(module)
+ code = py27compat.get_frozen_object(module, paths)
elif kind == PY_SOURCE:
code = compile(f.read(), path, 'exec')
else:
# Not something we can parse; we'll have to import it. :(
- if module not in sys.modules:
- imp.load_module(module, f, path, (suffix, mode, kind))
- return getattr(sys.modules[module], symbol, None)
-
- finally:
- if f:
- f.close()
+ imported = py27compat.get_module(module, paths, info)
+ return getattr(imported, symbol, None)
return extract_constant(code, symbol, default)
diff --git a/setuptools/py27compat.py b/setuptools/py27compat.py
index 2985011b..1d57360f 100644
--- a/setuptools/py27compat.py
+++ b/setuptools/py27compat.py
@@ -2,6 +2,7 @@
Compatibility Support for Python 2.7 and earlier
"""
+import sys
import platform
from setuptools.extern import six
@@ -26,3 +27,34 @@ linux_py2_ascii = (
rmtree_safe = str if linux_py2_ascii else lambda x: x
"""Workaround for http://bugs.python.org/issue24672"""
+
+
+try:
+ from ._imp import find_module, PY_COMPILED, PY_FROZEN, PY_SOURCE
+ from ._imp import get_frozen_object, get_module
+except ImportError:
+ import imp
+ from imp import PY_COMPILED, PY_FROZEN, PY_SOURCE # noqa
+
+ def find_module(module, paths=None):
+ """Just like 'imp.find_module()', but with package support"""
+ parts = module.split('.')
+ while parts:
+ part = parts.pop(0)
+ f, path, (suffix, mode, kind) = info = imp.find_module(part, paths)
+
+ if kind == imp.PKG_DIRECTORY:
+ parts = parts or ['__init__']
+ paths = [path]
+
+ elif parts:
+ raise ImportError("Can't find %r in %s" % (parts, module))
+
+ return info
+
+ def get_frozen_object(module, paths):
+ return imp.get_frozen_object(module)
+
+ def get_module(module, paths, info):
+ imp.load_module(module, *info)
+ return sys.modules[module]
diff --git a/setuptools/py34compat.py b/setuptools/py34compat.py
new file mode 100644
index 00000000..3ad91722
--- /dev/null
+++ b/setuptools/py34compat.py
@@ -0,0 +1,13 @@
+import importlib
+
+try:
+ import importlib.util
+except ImportError:
+ pass
+
+
+try:
+ module_from_spec = importlib.util.module_from_spec
+except AttributeError:
+ def module_from_spec(spec):
+ return spec.loader.load_module(spec.name)