mirror of https://github.com/python/cpython
gh-97850: remove ``find_loader`` and ``get_loader`` from ``pkgutil`` (#119656)
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Brett Cannon <brett@python.org>
This commit is contained in:
parent
38a604fd90
commit
464a7a91d0
|
@ -85,7 +85,7 @@ Pending removal in Python 3.14
|
||||||
:meth:`~pathlib.PurePath.relative_to`: passing additional arguments is
|
:meth:`~pathlib.PurePath.relative_to`: passing additional arguments is
|
||||||
deprecated.
|
deprecated.
|
||||||
|
|
||||||
* :mod:`pkgutil`: :func:`~pkgutil.find_loader` and :func:`~pkgutil.get_loader`
|
* :mod:`pkgutil`: :func:`!pkgutil.find_loader` and :func:!pkgutil.get_loader`
|
||||||
now raise :exc:`DeprecationWarning`;
|
now raise :exc:`DeprecationWarning`;
|
||||||
use :func:`importlib.util.find_spec` instead.
|
use :func:`importlib.util.find_spec` instead.
|
||||||
(Contributed by Nikita Sobolev in :gh:`97850`.)
|
(Contributed by Nikita Sobolev in :gh:`97850`.)
|
||||||
|
|
|
@ -49,25 +49,6 @@ support.
|
||||||
this function to raise an exception (in line with :func:`os.path.isdir`
|
this function to raise an exception (in line with :func:`os.path.isdir`
|
||||||
behavior).
|
behavior).
|
||||||
|
|
||||||
.. function:: find_loader(fullname)
|
|
||||||
|
|
||||||
Retrieve a module :term:`loader` for the given *fullname*.
|
|
||||||
|
|
||||||
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:`importlib.machinery.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`
|
|
||||||
|
|
||||||
.. deprecated-removed:: 3.12 3.14
|
|
||||||
Use :func:`importlib.util.find_spec` instead.
|
|
||||||
|
|
||||||
|
|
||||||
.. function:: get_importer(path_item)
|
.. function:: get_importer(path_item)
|
||||||
|
|
||||||
|
@ -84,27 +65,6 @@ support.
|
||||||
on the package internal :pep:`302` import emulation.
|
on the package internal :pep:`302` import emulation.
|
||||||
|
|
||||||
|
|
||||||
.. function:: get_loader(module_or_name)
|
|
||||||
|
|
||||||
Get a :term:`loader` object for *module_or_name*.
|
|
||||||
|
|
||||||
If the module or package is accessible via the normal import mechanism, a
|
|
||||||
wrapper around the relevant part of that machinery is returned. Returns
|
|
||||||
``None`` if the module cannot be found or imported. If the named module is
|
|
||||||
not already imported, its containing package (if any) is imported, in order
|
|
||||||
to establish the package ``__path__``.
|
|
||||||
|
|
||||||
.. 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`
|
|
||||||
|
|
||||||
.. deprecated-removed:: 3.12 3.14
|
|
||||||
Use :func:`importlib.util.find_spec` instead.
|
|
||||||
|
|
||||||
|
|
||||||
.. function:: iter_importers(fullname='')
|
.. function:: iter_importers(fullname='')
|
||||||
|
|
||||||
Yield :term:`finder` objects for the given module name.
|
Yield :term:`finder` objects for the given module name.
|
||||||
|
|
|
@ -1229,7 +1229,7 @@ Deprecated
|
||||||
your code *requires* ``'fork'``. See :ref:`contexts and start methods
|
your code *requires* ``'fork'``. See :ref:`contexts and start methods
|
||||||
<multiprocessing-start-methods>`.
|
<multiprocessing-start-methods>`.
|
||||||
|
|
||||||
* :mod:`pkgutil`: :func:`pkgutil.find_loader` and :func:`pkgutil.get_loader`
|
* :mod:`pkgutil`: :func:`!pkgutil.find_loader` and :func:`!pkgutil.get_loader`
|
||||||
are deprecated and will be removed in Python 3.14;
|
are deprecated and will be removed in Python 3.14;
|
||||||
use :func:`importlib.util.find_spec` instead.
|
use :func:`importlib.util.find_spec` instead.
|
||||||
(Contributed by Nikita Sobolev in :gh:`97850`.)
|
(Contributed by Nikita Sobolev in :gh:`97850`.)
|
||||||
|
|
|
@ -621,6 +621,13 @@ pathlib
|
||||||
:meth:`~pathlib.PurePath.is_relative_to`. In previous versions, any such
|
:meth:`~pathlib.PurePath.is_relative_to`. In previous versions, any such
|
||||||
arguments are joined onto *other*.
|
arguments are joined onto *other*.
|
||||||
|
|
||||||
|
pkgutil
|
||||||
|
-------
|
||||||
|
|
||||||
|
* Remove deprecated :func:`!pkgutil.get_loader` and :func:`!pkgutil.find_loader`.
|
||||||
|
These had previously raised a :exc:`DeprecationWarning` since Python 3.12.
|
||||||
|
(Contributed by Bénédikt Tran in :gh:`97850`.)
|
||||||
|
|
||||||
pty
|
pty
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ from types import ModuleType
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'get_importer', 'iter_importers', 'get_loader', 'find_loader',
|
'get_importer', 'iter_importers',
|
||||||
'walk_packages', 'iter_modules', 'get_data',
|
'walk_packages', 'iter_modules', 'get_data',
|
||||||
'read_code', 'extend_path',
|
'read_code', 'extend_path',
|
||||||
'ModuleInfo',
|
'ModuleInfo',
|
||||||
|
@ -263,59 +263,6 @@ def iter_importers(fullname=""):
|
||||||
yield get_importer(item)
|
yield get_importer(item)
|
||||||
|
|
||||||
|
|
||||||
def get_loader(module_or_name):
|
|
||||||
"""Get a "loader" object for module_or_name
|
|
||||||
|
|
||||||
Returns None if the module cannot be found or imported.
|
|
||||||
If the named module is not already imported, its containing package
|
|
||||||
(if any) is imported, in order to establish the package __path__.
|
|
||||||
"""
|
|
||||||
warnings._deprecated("pkgutil.get_loader",
|
|
||||||
f"{warnings._DEPRECATED_MSG}; "
|
|
||||||
"use importlib.util.find_spec() instead",
|
|
||||||
remove=(3, 14))
|
|
||||||
if module_or_name in sys.modules:
|
|
||||||
module_or_name = sys.modules[module_or_name]
|
|
||||||
if module_or_name is None:
|
|
||||||
return None
|
|
||||||
if isinstance(module_or_name, ModuleType):
|
|
||||||
module = module_or_name
|
|
||||||
loader = getattr(module, '__loader__', None)
|
|
||||||
if loader is not None:
|
|
||||||
return loader
|
|
||||||
if getattr(module, '__spec__', None) is None:
|
|
||||||
return None
|
|
||||||
fullname = module.__name__
|
|
||||||
else:
|
|
||||||
fullname = module_or_name
|
|
||||||
return find_loader(fullname)
|
|
||||||
|
|
||||||
|
|
||||||
def find_loader(fullname):
|
|
||||||
"""Find a "loader" object for fullname
|
|
||||||
|
|
||||||
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
|
|
||||||
"""
|
|
||||||
warnings._deprecated("pkgutil.find_loader",
|
|
||||||
f"{warnings._DEPRECATED_MSG}; "
|
|
||||||
"use importlib.util.find_spec() instead",
|
|
||||||
remove=(3, 14))
|
|
||||||
if fullname.startswith('.'):
|
|
||||||
msg = "Relative module name {!r} not supported".format(fullname)
|
|
||||||
raise ImportError(msg)
|
|
||||||
try:
|
|
||||||
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 if spec is not None else None
|
|
||||||
|
|
||||||
|
|
||||||
def extend_path(path, name):
|
def extend_path(path, name):
|
||||||
"""Extend a package's path.
|
"""Extend a package's path.
|
||||||
|
|
||||||
|
|
|
@ -2410,25 +2410,6 @@ def test_DocFileSuite():
|
||||||
>>> suite.run(unittest.TestResult())
|
>>> suite.run(unittest.TestResult())
|
||||||
<unittest.result.TestResult run=3 errors=0 failures=2>
|
<unittest.result.TestResult run=3 errors=0 failures=2>
|
||||||
|
|
||||||
Support for using a package's __loader__.get_data() is also
|
|
||||||
provided.
|
|
||||||
|
|
||||||
>>> import unittest, pkgutil, test
|
|
||||||
>>> added_loader = False
|
|
||||||
>>> if not hasattr(test, '__loader__'):
|
|
||||||
... test.__loader__ = pkgutil.get_loader(test)
|
|
||||||
... added_loader = True
|
|
||||||
>>> try:
|
|
||||||
... suite = doctest.DocFileSuite('test_doctest.txt',
|
|
||||||
... 'test_doctest2.txt',
|
|
||||||
... 'test_doctest4.txt',
|
|
||||||
... package='test.test_doctest')
|
|
||||||
... suite.run(unittest.TestResult())
|
|
||||||
... finally:
|
|
||||||
... if added_loader:
|
|
||||||
... del test.__loader__
|
|
||||||
<unittest.result.TestResult run=3 errors=0 failures=2>
|
|
||||||
|
|
||||||
'/' should be used as a path separator. It will be converted
|
'/' should be used as a path separator. It will be converted
|
||||||
to a native separator at run time:
|
to a native separator at run time:
|
||||||
|
|
||||||
|
|
|
@ -607,73 +607,6 @@ class ImportlibMigrationTests(unittest.TestCase):
|
||||||
# PEP 302 emulation in this module is in the process of being
|
# PEP 302 emulation in this module is in the process of being
|
||||||
# deprecated in favour of importlib proper
|
# deprecated in favour of importlib proper
|
||||||
|
|
||||||
@unittest.skipIf(__name__ == '__main__', 'not compatible with __main__')
|
|
||||||
@ignore_warnings(category=DeprecationWarning)
|
|
||||||
def test_get_loader_handles_missing_loader_attribute(self):
|
|
||||||
global __loader__
|
|
||||||
this_loader = __loader__
|
|
||||||
del __loader__
|
|
||||||
try:
|
|
||||||
self.assertIsNotNone(pkgutil.get_loader(__name__))
|
|
||||||
finally:
|
|
||||||
__loader__ = this_loader
|
|
||||||
|
|
||||||
@ignore_warnings(category=DeprecationWarning)
|
|
||||||
def test_get_loader_handles_missing_spec_attribute(self):
|
|
||||||
name = 'spam'
|
|
||||||
mod = type(sys)(name)
|
|
||||||
del mod.__spec__
|
|
||||||
with CleanImport(name):
|
|
||||||
try:
|
|
||||||
sys.modules[name] = mod
|
|
||||||
loader = pkgutil.get_loader(name)
|
|
||||||
finally:
|
|
||||||
sys.modules.pop(name, None)
|
|
||||||
self.assertIsNone(loader)
|
|
||||||
|
|
||||||
@ignore_warnings(category=DeprecationWarning)
|
|
||||||
def test_get_loader_handles_spec_attribute_none(self):
|
|
||||||
name = 'spam'
|
|
||||||
mod = type(sys)(name)
|
|
||||||
mod.__spec__ = None
|
|
||||||
with CleanImport(name):
|
|
||||||
try:
|
|
||||||
sys.modules[name] = mod
|
|
||||||
loader = pkgutil.get_loader(name)
|
|
||||||
finally:
|
|
||||||
sys.modules.pop(name, None)
|
|
||||||
self.assertIsNone(loader)
|
|
||||||
|
|
||||||
@ignore_warnings(category=DeprecationWarning)
|
|
||||||
def test_get_loader_None_in_sys_modules(self):
|
|
||||||
name = 'totally bogus'
|
|
||||||
sys.modules[name] = None
|
|
||||||
try:
|
|
||||||
loader = pkgutil.get_loader(name)
|
|
||||||
finally:
|
|
||||||
del sys.modules[name]
|
|
||||||
self.assertIsNone(loader)
|
|
||||||
|
|
||||||
def test_get_loader_is_deprecated(self):
|
|
||||||
with check_warnings(
|
|
||||||
(r".*\bpkgutil.get_loader\b.*", DeprecationWarning),
|
|
||||||
):
|
|
||||||
res = pkgutil.get_loader("sys")
|
|
||||||
self.assertIsNotNone(res)
|
|
||||||
|
|
||||||
def test_find_loader_is_deprecated(self):
|
|
||||||
with check_warnings(
|
|
||||||
(r".*\bpkgutil.find_loader\b.*", DeprecationWarning),
|
|
||||||
):
|
|
||||||
res = pkgutil.find_loader("sys")
|
|
||||||
self.assertIsNotNone(res)
|
|
||||||
|
|
||||||
@ignore_warnings(category=DeprecationWarning)
|
|
||||||
def test_find_loader_missing_module(self):
|
|
||||||
name = 'totally bogus'
|
|
||||||
loader = pkgutil.find_loader(name)
|
|
||||||
self.assertIsNone(loader)
|
|
||||||
|
|
||||||
def test_get_importer_avoids_emulation(self):
|
def test_get_importer_avoids_emulation(self):
|
||||||
# We use an illegal path so *none* of the path hooks should fire
|
# We use an illegal path so *none* of the path hooks should fire
|
||||||
with check_warnings() as w:
|
with check_warnings() as w:
|
||||||
|
|
|
@ -1750,7 +1750,7 @@ Remove the long-deprecated ``imp`` module.
|
||||||
.. nonce: N46coo
|
.. nonce: N46coo
|
||||||
.. section: Library
|
.. section: Library
|
||||||
|
|
||||||
Deprecate :func:`pkgutil.find_loader` and :func:`pkgutil.get_loader` in
|
Deprecate :func:`!pkgutil.find_loader` and :func:`!pkgutil.get_loader` in
|
||||||
favor of :func:`importlib.util.find_spec`.
|
favor of :func:`importlib.util.find_spec`.
|
||||||
|
|
||||||
..
|
..
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Remove deprecated :func:`!pkgutil.get_loader` and :func:`!pkgutil.find_loader`.
|
Loading…
Reference in New Issue