Close #20839: pkgutil.find_loader now uses importlib.util.find_spec

This commit is contained in:
Nick Coghlan 2014-03-04 20:39:42 +10:00
parent 01cc2d5fb8
commit 62b4b9eecb
4 changed files with 41 additions and 21 deletions

View file

@ -470,29 +470,22 @@ def get_loader(module_or_name):
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):