Skip to content

Commit eaf9ef4

Browse files
picnixzhugovkbrettcannon
authored andcommitted
pythongh-97850: remove find_loader and get_loader from pkgutil (python#119656)
Co-authored-by: Hugo van Kemenade <[email protected]> Co-authored-by: Brett Cannon <[email protected]>
1 parent 436d742 commit eaf9ef4

File tree

9 files changed

+12
-183
lines changed

9 files changed

+12
-183
lines changed

Doc/deprecations/pending-removal-in-3.14.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ Pending removal in Python 3.14
8585
:meth:`~pathlib.PurePath.relative_to`: passing additional arguments is
8686
deprecated.
8787

88-
* :mod:`pkgutil`: :func:`~pkgutil.find_loader` and :func:`~pkgutil.get_loader`
88+
* :mod:`pkgutil`: :func:`!pkgutil.find_loader` and :func:!pkgutil.get_loader`
8989
now raise :exc:`DeprecationWarning`;
9090
use :func:`importlib.util.find_spec` instead.
9191
(Contributed by Nikita Sobolev in :gh:`97850`.)

Doc/library/pkgutil.rst

-40
Original file line numberDiff line numberDiff line change
@@ -49,25 +49,6 @@ support.
4949
this function to raise an exception (in line with :func:`os.path.isdir`
5050
behavior).
5151

52-
.. function:: find_loader(fullname)
53-
54-
Retrieve a module :term:`loader` for the given *fullname*.
55-
56-
This is a backwards compatibility wrapper around
57-
:func:`importlib.util.find_spec` that converts most failures to
58-
:exc:`ImportError` and only returns the loader rather than the full
59-
:class:`importlib.machinery.ModuleSpec`.
60-
61-
.. versionchanged:: 3.3
62-
Updated to be based directly on :mod:`importlib` rather than relying
63-
on the package internal :pep:`302` import emulation.
64-
65-
.. versionchanged:: 3.4
66-
Updated to be based on :pep:`451`
67-
68-
.. deprecated-removed:: 3.12 3.14
69-
Use :func:`importlib.util.find_spec` instead.
70-
7152

7253
.. function:: get_importer(path_item)
7354

@@ -84,27 +65,6 @@ support.
8465
on the package internal :pep:`302` import emulation.
8566

8667

87-
.. function:: get_loader(module_or_name)
88-
89-
Get a :term:`loader` object for *module_or_name*.
90-
91-
If the module or package is accessible via the normal import mechanism, a
92-
wrapper around the relevant part of that machinery is returned. Returns
93-
``None`` if the module cannot be found or imported. If the named module is
94-
not already imported, its containing package (if any) is imported, in order
95-
to establish the package ``__path__``.
96-
97-
.. versionchanged:: 3.3
98-
Updated to be based directly on :mod:`importlib` rather than relying
99-
on the package internal :pep:`302` import emulation.
100-
101-
.. versionchanged:: 3.4
102-
Updated to be based on :pep:`451`
103-
104-
.. deprecated-removed:: 3.12 3.14
105-
Use :func:`importlib.util.find_spec` instead.
106-
107-
10868
.. function:: iter_importers(fullname='')
10969

11070
Yield :term:`finder` objects for the given module name.

Doc/whatsnew/3.12.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -1229,7 +1229,7 @@ Deprecated
12291229
your code *requires* ``'fork'``. See :ref:`contexts and start methods
12301230
<multiprocessing-start-methods>`.
12311231

1232-
* :mod:`pkgutil`: :func:`pkgutil.find_loader` and :func:`pkgutil.get_loader`
1232+
* :mod:`pkgutil`: :func:`!pkgutil.find_loader` and :func:`!pkgutil.get_loader`
12331233
are deprecated and will be removed in Python 3.14;
12341234
use :func:`importlib.util.find_spec` instead.
12351235
(Contributed by Nikita Sobolev in :gh:`97850`.)

Doc/whatsnew/3.14.rst

+7
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,13 @@ pathlib
621621
:meth:`~pathlib.PurePath.is_relative_to`. In previous versions, any such
622622
arguments are joined onto *other*.
623623

624+
pkgutil
625+
-------
626+
627+
* Remove deprecated :func:`!pkgutil.get_loader` and :func:`!pkgutil.find_loader`.
628+
These had previously raised a :exc:`DeprecationWarning` since Python 3.12.
629+
(Contributed by Bénédikt Tran in :gh:`97850`.)
630+
624631
pty
625632
---
626633

Lib/pkgutil.py

+1-54
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import warnings
1313

1414
__all__ = [
15-
'get_importer', 'iter_importers', 'get_loader', 'find_loader',
15+
'get_importer', 'iter_importers',
1616
'walk_packages', 'iter_modules', 'get_data',
1717
'read_code', 'extend_path',
1818
'ModuleInfo',
@@ -263,59 +263,6 @@ def iter_importers(fullname=""):
263263
yield get_importer(item)
264264

265265

266-
def get_loader(module_or_name):
267-
"""Get a "loader" object for module_or_name
268-
269-
Returns None if the module cannot be found or imported.
270-
If the named module is not already imported, its containing package
271-
(if any) is imported, in order to establish the package __path__.
272-
"""
273-
warnings._deprecated("pkgutil.get_loader",
274-
f"{warnings._DEPRECATED_MSG}; "
275-
"use importlib.util.find_spec() instead",
276-
remove=(3, 14))
277-
if module_or_name in sys.modules:
278-
module_or_name = sys.modules[module_or_name]
279-
if module_or_name is None:
280-
return None
281-
if isinstance(module_or_name, ModuleType):
282-
module = module_or_name
283-
loader = getattr(module, '__loader__', None)
284-
if loader is not None:
285-
return loader
286-
if getattr(module, '__spec__', None) is None:
287-
return None
288-
fullname = module.__name__
289-
else:
290-
fullname = module_or_name
291-
return find_loader(fullname)
292-
293-
294-
def find_loader(fullname):
295-
"""Find a "loader" object for fullname
296-
297-
This is a backwards compatibility wrapper around
298-
importlib.util.find_spec that converts most failures to ImportError
299-
and only returns the loader rather than the full spec
300-
"""
301-
warnings._deprecated("pkgutil.find_loader",
302-
f"{warnings._DEPRECATED_MSG}; "
303-
"use importlib.util.find_spec() instead",
304-
remove=(3, 14))
305-
if fullname.startswith('.'):
306-
msg = "Relative module name {!r} not supported".format(fullname)
307-
raise ImportError(msg)
308-
try:
309-
spec = importlib.util.find_spec(fullname)
310-
except (ImportError, AttributeError, TypeError, ValueError) as ex:
311-
# This hack fixes an impedance mismatch between pkgutil and
312-
# importlib, where the latter raises other errors for cases where
313-
# pkgutil previously raised ImportError
314-
msg = "Error while finding loader for {!r} ({}: {})"
315-
raise ImportError(msg.format(fullname, type(ex), ex)) from ex
316-
return spec.loader if spec is not None else None
317-
318-
319266
def extend_path(path, name):
320267
"""Extend a package's path.
321268

Lib/test/test_doctest/test_doctest.py

-19
Original file line numberDiff line numberDiff line change
@@ -2410,25 +2410,6 @@ def test_DocFileSuite():
24102410
>>> suite.run(unittest.TestResult())
24112411
<unittest.result.TestResult run=3 errors=0 failures=2>
24122412
2413-
Support for using a package's __loader__.get_data() is also
2414-
provided.
2415-
2416-
>>> import unittest, pkgutil, test
2417-
>>> added_loader = False
2418-
>>> if not hasattr(test, '__loader__'):
2419-
... test.__loader__ = pkgutil.get_loader(test)
2420-
... added_loader = True
2421-
>>> try:
2422-
... suite = doctest.DocFileSuite('test_doctest.txt',
2423-
... 'test_doctest2.txt',
2424-
... 'test_doctest4.txt',
2425-
... package='test.test_doctest')
2426-
... suite.run(unittest.TestResult())
2427-
... finally:
2428-
... if added_loader:
2429-
... del test.__loader__
2430-
<unittest.result.TestResult run=3 errors=0 failures=2>
2431-
24322413
'/' should be used as a path separator. It will be converted
24332414
to a native separator at run time:
24342415

Lib/test/test_pkgutil.py

-67
Original file line numberDiff line numberDiff line change
@@ -607,73 +607,6 @@ class ImportlibMigrationTests(unittest.TestCase):
607607
# PEP 302 emulation in this module is in the process of being
608608
# deprecated in favour of importlib proper
609609

610-
@unittest.skipIf(__name__ == '__main__', 'not compatible with __main__')
611-
@ignore_warnings(category=DeprecationWarning)
612-
def test_get_loader_handles_missing_loader_attribute(self):
613-
global __loader__
614-
this_loader = __loader__
615-
del __loader__
616-
try:
617-
self.assertIsNotNone(pkgutil.get_loader(__name__))
618-
finally:
619-
__loader__ = this_loader
620-
621-
@ignore_warnings(category=DeprecationWarning)
622-
def test_get_loader_handles_missing_spec_attribute(self):
623-
name = 'spam'
624-
mod = type(sys)(name)
625-
del mod.__spec__
626-
with CleanImport(name):
627-
try:
628-
sys.modules[name] = mod
629-
loader = pkgutil.get_loader(name)
630-
finally:
631-
sys.modules.pop(name, None)
632-
self.assertIsNone(loader)
633-
634-
@ignore_warnings(category=DeprecationWarning)
635-
def test_get_loader_handles_spec_attribute_none(self):
636-
name = 'spam'
637-
mod = type(sys)(name)
638-
mod.__spec__ = None
639-
with CleanImport(name):
640-
try:
641-
sys.modules[name] = mod
642-
loader = pkgutil.get_loader(name)
643-
finally:
644-
sys.modules.pop(name, None)
645-
self.assertIsNone(loader)
646-
647-
@ignore_warnings(category=DeprecationWarning)
648-
def test_get_loader_None_in_sys_modules(self):
649-
name = 'totally bogus'
650-
sys.modules[name] = None
651-
try:
652-
loader = pkgutil.get_loader(name)
653-
finally:
654-
del sys.modules[name]
655-
self.assertIsNone(loader)
656-
657-
def test_get_loader_is_deprecated(self):
658-
with check_warnings(
659-
(r".*\bpkgutil.get_loader\b.*", DeprecationWarning),
660-
):
661-
res = pkgutil.get_loader("sys")
662-
self.assertIsNotNone(res)
663-
664-
def test_find_loader_is_deprecated(self):
665-
with check_warnings(
666-
(r".*\bpkgutil.find_loader\b.*", DeprecationWarning),
667-
):
668-
res = pkgutil.find_loader("sys")
669-
self.assertIsNotNone(res)
670-
671-
@ignore_warnings(category=DeprecationWarning)
672-
def test_find_loader_missing_module(self):
673-
name = 'totally bogus'
674-
loader = pkgutil.find_loader(name)
675-
self.assertIsNone(loader)
676-
677610
def test_get_importer_avoids_emulation(self):
678611
# We use an illegal path so *none* of the path hooks should fire
679612
with check_warnings() as w:

Misc/NEWS.d/3.12.0b1.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -1750,7 +1750,7 @@ Remove the long-deprecated ``imp`` module.
17501750
.. nonce: N46coo
17511751
.. section: Library
17521752
1753-
Deprecate :func:`pkgutil.find_loader` and :func:`pkgutil.get_loader` in
1753+
Deprecate :func:`!pkgutil.find_loader` and :func:`!pkgutil.get_loader` in
17541754
favor of :func:`importlib.util.find_spec`.
17551755

17561756
..
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Remove deprecated :func:`!pkgutil.get_loader` and :func:`!pkgutil.find_loader`.

0 commit comments

Comments
 (0)