Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-97850: Deprecate find_loader and get_loader in pkgutil #98520

Merged
merged 14 commits into from
May 3, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Doc/library/pkgutil.rst
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ support.
.. versionchanged:: 3.4
Updated to be based on :pep:`451`

.. deprecated:: 3.12
sobolevn marked this conversation as resolved.
Show resolved Hide resolved
Use :func:`importlib.util.find_spec` instead.


.. function:: get_importer(path_item)

Retrieve a :term:`finder` for the given *path_item*.
Expand Down Expand Up @@ -123,6 +127,9 @@ support.
.. versionchanged:: 3.4
Updated to be based on :pep:`451`

.. deprecated:: 3.12
sobolevn marked this conversation as resolved.
Show resolved Hide resolved
Use :func:`importlib.util.find_spec` instead.


.. function:: iter_importers(fullname='')

Expand Down
6 changes: 6 additions & 0 deletions Doc/whatsnew/3.12.rst
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,11 @@ Deprecated
:exc:`ImportWarning`).
(Contributed by Brett Cannon in :gh:`65961`.)

* :func:`pkgutil.find_loader` and :func:`pkgutil.get_loader`
now raise :exc:`DeprecationWarning`;
use :func:`importlib.util.find_spec` instead.
sobolevn marked this conversation as resolved.
Show resolved Hide resolved
(Contributed by Nikita Sobolev in :gh:`97850`.)
sobolevn marked this conversation as resolved.
Show resolved Hide resolved

* The :meth:`~asyncio.get_event_loop` method of the
default event loop policy now emits a :exc:`DeprecationWarning` if there
is no current event loop set and it decides to create one.
Expand Down Expand Up @@ -601,6 +606,7 @@ Deprecated
in Python 3.14. Use *onexc* instead. (Contributed by Irit Katriel in :gh:`102828`.)



Pending Removal in Python 3.13
------------------------------

Expand Down
8 changes: 8 additions & 0 deletions Lib/pkgutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,10 @@ def get_loader(module_or_name):
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",
brettcannon marked this conversation as resolved.
Show resolved Hide resolved
remove=(3, 14))
if module_or_name in sys.modules:
module_or_name = sys.modules[module_or_name]
if module_or_name is None:
Expand All @@ -489,6 +493,10 @@ def find_loader(fullname):
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",
brettcannon marked this conversation as resolved.
Show resolved Hide resolved
remove=(3, 14))
if fullname.startswith('.'):
msg = "Relative module name {!r} not supported".format(fullname)
raise ImportError(msg)
Expand Down
39 changes: 21 additions & 18 deletions Lib/test/test_pkgutil.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from pathlib import Path
from test.support.import_helper import unload, CleanImport
from test.support.warnings_helper import check_warnings
from test.support.warnings_helper import check_warnings, ignore_warnings
import unittest
import sys
import importlib
Expand Down Expand Up @@ -549,25 +549,18 @@ def test_loader_deprecated(self):
with self.check_deprecated():
pkgutil.ImpLoader("", "", "", "")

def test_get_loader_avoids_emulation(self):
with check_warnings() as w:
self.assertIsNotNone(pkgutil.get_loader("sys"))
self.assertIsNotNone(pkgutil.get_loader("os"))
self.assertIsNotNone(pkgutil.get_loader("test.support"))
self.assertEqual(len(w.warnings), 0)

@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:
with check_warnings() as w:
self.assertIsNotNone(pkgutil.get_loader(__name__))
self.assertEqual(len(w.warnings), 0)
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)
Expand All @@ -577,6 +570,7 @@ def test_get_loader_handles_missing_spec_attribute(self):
loader = pkgutil.get_loader(name)
self.assertIsNone(loader)

@ignore_warnings(category=DeprecationWarning)
def test_get_loader_handles_spec_attribute_none(self):
name = 'spam'
mod = type(sys)(name)
Expand All @@ -586,6 +580,7 @@ def test_get_loader_handles_spec_attribute_none(self):
loader = pkgutil.get_loader(name)
self.assertIsNone(loader)

@ignore_warnings(category=DeprecationWarning)
def test_get_loader_None_in_sys_modules(self):
name = 'totally bogus'
sys.modules[name] = None
Expand All @@ -595,18 +590,26 @@ def test_get_loader_None_in_sys_modules(self):
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_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:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Deprecate :func:`pkgutil.find_loader` and :func:`pkgutil.get_loader`
in favor of :func:`importlib.util.find_spec`.