[Python-checkins] cpython (3.4): Close #20839: pkgutil.find_loader now uses importlib.util.find_spec
larry.hastings
python-checkins at python.org
Mon Mar 17 07:33:21 CET 2014
http://hg.python.org/cpython/rev/a8b30fd6ee4f
changeset: 89787:a8b30fd6ee4f
branch: 3.4
user: Nick Coghlan <ncoghlan at gmail.com>
date: Tue Mar 04 20:39:42 2014 +1000
summary:
Close #20839: pkgutil.find_loader now uses importlib.util.find_spec
files:
Doc/library/pkgutil.rst | 17 +++++++++--------
Lib/pkgutil.py | 17 +++++------------
Lib/test/test_pkgutil.py | 19 +++++++++++++++++++
Misc/NEWS | 9 ++++++++-
4 files changed, 41 insertions(+), 21 deletions(-)
diff --git a/Doc/library/pkgutil.rst b/Doc/library/pkgutil.rst
--- a/Doc/library/pkgutil.rst
+++ b/Doc/library/pkgutil.rst
@@ -74,15 +74,17 @@
Retrieve a :pep:`302` module loader for the given *fullname*.
- This is a convenience wrapper around :func:`importlib.find_loader` that
- sets the *path* argument correctly when searching for submodules, and
- also ensures parent packages (if any) are imported before searching for
- submodules.
+ This is a backwards compatibility wrapper around
+ :func:`importlib.util.find_spec` that converts most failures to
+ :exc:`ImportError` and only returns the loader rather than the full
+ :class:`ModuleSpec`.
.. versionchanged:: 3.3
Updated to be based directly on :mod:`importlib` rather than relying
on the package internal PEP 302 import emulation.
+ .. versionchanged:: 3.4
+ Updated to be based on :pep:`451`
.. function:: get_importer(path_item)
@@ -109,14 +111,13 @@
not already imported, its containing package (if any) is imported, in order
to establish the package ``__path__``.
- This function uses :func:`iter_importers`, and is thus subject to the same
- limitations regarding platform-specific special import locations such as the
- Windows registry.
-
.. versionchanged:: 3.3
Updated to be based directly on :mod:`importlib` rather than relying
on the package internal PEP 302 import emulation.
+ .. versionchanged:: 3.4
+ Updated to be based on :pep:`451`
+
.. function:: iter_importers(fullname='')
diff --git a/Lib/pkgutil.py b/Lib/pkgutil.py
--- a/Lib/pkgutil.py
+++ b/Lib/pkgutil.py
@@ -470,29 +470,22 @@
def find_loader(fullname):
"""Find a PEP 302 "loader" object for fullname
- This is s convenience wrapper around :func:`importlib.find_loader` that
- sets the *path* argument correctly when searching for submodules, and
- also ensures parent packages (if any) are imported before searching for
- submodules.
+ This is a backwards compatibility wrapper around
+ importlib.util.find_spec that converts most failures to ImportError
+ and only returns the loader rather than the full spec
"""
if fullname.startswith('.'):
msg = "Relative module name {!r} not supported".format(fullname)
raise ImportError(msg)
- path = None
- pkg_name = fullname.rpartition(".")[0]
- if pkg_name:
- pkg = importlib.import_module(pkg_name)
- path = getattr(pkg, "__path__", None)
- if path is None:
- return None
try:
- return importlib.find_loader(fullname, path)
+ spec = importlib.util.find_spec(fullname)
except (ImportError, AttributeError, TypeError, ValueError) as ex:
# This hack fixes an impedance mismatch between pkgutil and
# importlib, where the latter raises other errors for cases where
# pkgutil previously raised ImportError
msg = "Error while finding loader for {!r} ({}: {})"
raise ImportError(msg.format(fullname, type(ex), ex)) from ex
+ return spec.loader
def extend_path(path, name):
diff --git a/Lib/test/test_pkgutil.py b/Lib/test/test_pkgutil.py
--- a/Lib/test/test_pkgutil.py
+++ b/Lib/test/test_pkgutil.py
@@ -334,6 +334,25 @@
self.assertIsNotNone(pkgutil.get_loader("test.support"))
self.assertEqual(len(w.warnings), 0)
+ def test_get_loader_handles_missing_loader_attribute(self):
+ global __loader__
+ this_loader = __loader__
+ del __loader__
+ try:
+ with check_warnings() as w:
+ self.assertIsNotNone(pkgutil.get_loader(__name__))
+ self.assertEqual(len(w.warnings), 0)
+ finally:
+ __loader__ = this_loader
+
+
+ def test_find_loader_avoids_emulation(self):
+ with check_warnings() as w:
+ self.assertIsNotNone(pkgutil.find_loader("sys"))
+ self.assertIsNotNone(pkgutil.find_loader("os"))
+ self.assertIsNotNone(pkgutil.find_loader("test.support"))
+ self.assertEqual(len(w.warnings), 0)
+
def test_get_importer_avoids_emulation(self):
# We use an illegal path so *none* of the path hooks should fire
with check_warnings() as w:
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,13 @@
- Issue #20786: Fix signatures for dict.__delitem__ and
property.__delete__ builtins.
+Library
+-------
+
+- Issue #20839: Don't trigger a DeprecationWarning in the still supported
+ pkgutil.get_loader() API when __loader__ isn't set on a module (nor
+ when pkgutil.find_loader() is called directly).
+
Build
-----
@@ -27,7 +34,7 @@
uninstalling pip (rather than failing) if the user has updated pip to a
different version from the one bundled with ensurepip.
-- Issue #20465: Update OS X and Windows installer builds to use
+- Issue #20465: Update OS X and Windows installer builds to use
SQLite 3.8.3.1.
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list