https://github.com/python/cpython/commit/464a7a91d0c75241a2f1913e78dbfbc29d4193b4
commit: 464a7a91d0c75241a2f1913e78dbfbc29d4193b4
branch: main
author: Bénédikt Tran <10796600+picn...@users.noreply.github.com>
committer: hugovk <1324225+hug...@users.noreply.github.com>
date: 2024-11-01T18:35:22+02:00
summary:

gh-97850: remove ``find_loader`` and ``get_loader`` from ``pkgutil`` (#119656)

Co-authored-by: Hugo van Kemenade <1324225+hug...@users.noreply.github.com>
Co-authored-by: Brett Cannon <br...@python.org>

files:
A Misc/NEWS.d/next/Library/2024-05-28-14-35-23.gh-issue-97850.dCtjel.rst
M Doc/deprecations/pending-removal-in-3.14.rst
M Doc/library/pkgutil.rst
M Doc/whatsnew/3.12.rst
M Doc/whatsnew/3.14.rst
M Lib/pkgutil.py
M Lib/test/test_doctest/test_doctest.py
M Lib/test/test_pkgutil.py
M Misc/NEWS.d/3.12.0b1.rst

diff --git a/Doc/deprecations/pending-removal-in-3.14.rst 
b/Doc/deprecations/pending-removal-in-3.14.rst
index b8791b8d6c387e..23c9bde5c01ba7 100644
--- a/Doc/deprecations/pending-removal-in-3.14.rst
+++ b/Doc/deprecations/pending-removal-in-3.14.rst
@@ -85,7 +85,7 @@ Pending removal in Python 3.14
   :meth:`~pathlib.PurePath.relative_to`: passing additional arguments is
   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`;
   use :func:`importlib.util.find_spec` instead.
   (Contributed by Nikita Sobolev in :gh:`97850`.)
diff --git a/Doc/library/pkgutil.rst b/Doc/library/pkgutil.rst
index 4a39d53a5f1440..20b8f6bcf19117 100644
--- a/Doc/library/pkgutil.rst
+++ b/Doc/library/pkgutil.rst
@@ -49,25 +49,6 @@ support.
    this function to raise an exception (in line with :func:`os.path.isdir`
    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)
 
@@ -84,27 +65,6 @@ support.
       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='')
 
    Yield :term:`finder` objects for the given module name.
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index 1354355894e375..3640095acbaa2b 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -1229,7 +1229,7 @@ Deprecated
   your code *requires* ``'fork'``.  See :ref:`contexts and 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;
   use :func:`importlib.util.find_spec` instead.
   (Contributed by Nikita Sobolev in :gh:`97850`.)
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index 48314f9c98c036..db32be89cf88ff 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -621,6 +621,13 @@ pathlib
   :meth:`~pathlib.PurePath.is_relative_to`. In previous versions, any such
   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
 ---
 
diff --git a/Lib/pkgutil.py b/Lib/pkgutil.py
index dccbec52aa731e..b84d72f2395d45 100644
--- a/Lib/pkgutil.py
+++ b/Lib/pkgutil.py
@@ -12,7 +12,7 @@
 import warnings
 
 __all__ = [
-    'get_importer', 'iter_importers', 'get_loader', 'find_loader',
+    'get_importer', 'iter_importers',
     'walk_packages', 'iter_modules', 'get_data',
     'read_code', 'extend_path',
     'ModuleInfo',
@@ -263,59 +263,6 @@ def iter_importers(fullname=""):
         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):
     """Extend a package's path.
 
diff --git a/Lib/test/test_doctest/test_doctest.py 
b/Lib/test/test_doctest/test_doctest.py
index 171412cb7cb08c..b1e165fe16b54f 100644
--- a/Lib/test/test_doctest/test_doctest.py
+++ b/Lib/test/test_doctest/test_doctest.py
@@ -2410,25 +2410,6 @@ def test_DocFileSuite():
          >>> suite.run(unittest.TestResult())
          <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
        to a native separator at run time:
 
diff --git a/Lib/test/test_pkgutil.py b/Lib/test/test_pkgutil.py
index ca6927554b053c..736b83711def03 100644
--- a/Lib/test/test_pkgutil.py
+++ b/Lib/test/test_pkgutil.py
@@ -607,73 +607,6 @@ class ImportlibMigrationTests(unittest.TestCase):
     # PEP 302 emulation in this module is in the process of being
     # 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):
         # We use an illegal path so *none* of the path hooks should fire
         with check_warnings() as w:
diff --git a/Misc/NEWS.d/3.12.0b1.rst b/Misc/NEWS.d/3.12.0b1.rst
index 7126e08a20c7fd..3a3870ac9fe621 100644
--- a/Misc/NEWS.d/3.12.0b1.rst
+++ b/Misc/NEWS.d/3.12.0b1.rst
@@ -1750,7 +1750,7 @@ Remove the long-deprecated ``imp`` module.
 .. nonce: N46coo
 .. 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`.
 
 ..
diff --git 
a/Misc/NEWS.d/next/Library/2024-05-28-14-35-23.gh-issue-97850.dCtjel.rst 
b/Misc/NEWS.d/next/Library/2024-05-28-14-35-23.gh-issue-97850.dCtjel.rst
new file mode 100644
index 00000000000000..bb94f7d8ad124d
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-05-28-14-35-23.gh-issue-97850.dCtjel.rst
@@ -0,0 +1 @@
+Remove deprecated :func:`!pkgutil.get_loader` and :func:`!pkgutil.find_loader`.

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to