]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-97850: Remove all uses and definitions of `load_module()` from importlib (#142205)
authorBrett Cannon <brett@python.org>
Wed, 10 Dec 2025 23:35:51 +0000 (15:35 -0800)
committerGitHub <noreply@github.com>
Wed, 10 Dec 2025 23:35:51 +0000 (15:35 -0800)
21 files changed:
Doc/library/importlib.rst
Doc/reference/import.rst
Doc/whatsnew/3.10.rst
Doc/whatsnew/3.4.rst
Doc/whatsnew/3.6.rst
Lib/importlib/_abc.py
Lib/importlib/_bootstrap.py
Lib/importlib/_bootstrap_external.py
Lib/importlib/abc.py
Lib/test/test_import/__init__.py
Lib/test/test_importlib/abc.py
Lib/test/test_importlib/builtin/test_loader.py
Lib/test/test_importlib/extension/test_loader.py
Lib/test/test_importlib/import_/test_api.py
Lib/test/test_importlib/source/test_file_loader.py
Lib/test/test_importlib/source/test_finder.py
Lib/test/test_importlib/source/test_source_encoding.py
Lib/test/test_importlib/test_abc.py
Lib/test/test_importlib/test_spec.py
Misc/NEWS.d/3.14.0a6.rst
Misc/NEWS.d/next/Core_and_Builtins/2025-12-02-15-39-16.gh-issue-97850.H6QKwl.rst [new file with mode: 0644]

index 3f0a54ac535cd621ad19da7745debeb6f5d3f2b3..34130f9be67e7eb0e3dce59e41324f9a68557fe1 100644 (file)
@@ -320,6 +320,9 @@ ABC hierarchy::
     .. versionchanged:: 3.7
        Introduced the optional :meth:`get_resource_reader` method.
 
+   .. versionchanged:: 3.15
+      Removed the ``load_module()`` method.
+
     .. method:: create_module(spec)
 
        A method that returns the module object to use when
@@ -344,47 +347,6 @@ ABC hierarchy::
        .. versionchanged:: 3.6
           :meth:`create_module` must also be defined.
 
-    .. method:: load_module(fullname)
-
-        A legacy method for loading a module.  If the module cannot be
-        loaded, :exc:`ImportError` is raised, otherwise the loaded module is
-        returned.
-
-        If the requested module already exists in :data:`sys.modules`, that
-        module should be used and reloaded.
-        Otherwise the loader should create a new module and insert it into
-        :data:`sys.modules` before any loading begins, to prevent recursion
-        from the import.  If the loader inserted a module and the load fails, it
-        must be removed by the loader from :data:`sys.modules`; modules already
-        in :data:`sys.modules` before the loader began execution should be left
-        alone.
-
-        The loader should set several attributes on the module
-        (note that some of these attributes can change when a module is
-        reloaded):
-
-        - :attr:`module.__name__`
-        - :attr:`module.__file__`
-        - :attr:`module.__cached__` *(deprecated)*
-        - :attr:`module.__path__`
-        - :attr:`module.__package__` *(deprecated)*
-        - :attr:`module.__loader__` *(deprecated)*
-
-        When :meth:`exec_module` is available then backwards-compatible
-        functionality is provided.
-
-        .. versionchanged:: 3.4
-           Raise :exc:`ImportError` when called instead of
-           :exc:`NotImplementedError`.  Functionality provided when
-           :meth:`exec_module` is available.
-
-        .. deprecated-removed:: 3.4 3.15
-           The recommended API for loading a module is :meth:`exec_module`
-           (and :meth:`create_module`).  Loaders should implement it instead of
-           :meth:`load_module`.  The import machinery takes care of all the
-           other responsibilities of :meth:`load_module` when
-           :meth:`exec_module` is implemented.
-
 
 .. class:: ResourceLoader
 
@@ -490,13 +452,6 @@ ABC hierarchy::
 
        .. versionadded:: 3.4
 
-    .. method:: load_module(fullname)
-
-       Implementation of :meth:`Loader.load_module`.
-
-       .. deprecated-removed:: 3.4 3.15
-          use :meth:`exec_module` instead.
-
 
 .. class:: ExecutionLoader
 
@@ -530,6 +485,9 @@ ABC hierarchy::
 
    .. versionadded:: 3.3
 
+   .. versionchanged:: 3.15
+      Removed the ``load_module()`` method.
+
    .. attribute:: name
 
       The name of the module the loader can handle.
@@ -538,13 +496,6 @@ ABC hierarchy::
 
       Path to the file of the module.
 
-   .. method:: load_module(fullname)
-
-      Calls super's ``load_module()``.
-
-      .. deprecated-removed:: 3.4 3.15
-         Use :meth:`Loader.exec_module` instead.
-
    .. method:: get_filename(fullname)
       :abstractmethod:
 
@@ -576,6 +527,9 @@ ABC hierarchy::
     optimization to speed up loading by removing the parsing step of Python's
     compiler, and so no bytecode-specific API is exposed.
 
+    .. versionchanged:: 3.15
+       Removed the ``load_module()`` method.
+
     .. method:: path_stats(path)
 
         Optional abstract method which returns a :class:`dict` containing
@@ -629,13 +583,6 @@ ABC hierarchy::
 
        .. versionadded:: 3.4
 
-    .. method:: load_module(fullname)
-
-       Concrete implementation of :meth:`Loader.load_module`.
-
-       .. deprecated-removed:: 3.4 3.15
-          Use :meth:`exec_module` instead.
-
     .. method:: get_source(fullname)
 
         Concrete implementation of :meth:`InspectLoader.get_source`.
@@ -1059,6 +1006,9 @@ find and load modules.
 
    .. versionadded:: 3.3
 
+   .. versionchanged:: 3.15
+      Removed the ``load_module()`` method.
+
    .. attribute:: name
 
       The name of the module that this loader will handle.
@@ -1079,15 +1029,6 @@ find and load modules.
 
       Concrete implementation of :meth:`importlib.abc.SourceLoader.set_data`.
 
-   .. method:: load_module(name=None)
-
-      Concrete implementation of :meth:`importlib.abc.Loader.load_module` where
-      specifying the name of the module to load is optional.
-
-      .. deprecated-removed:: 3.6 3.15
-
-         Use :meth:`importlib.abc.Loader.exec_module` instead.
-
 
 .. class:: SourcelessFileLoader(fullname, path)
 
@@ -1101,6 +1042,9 @@ find and load modules.
 
    .. versionadded:: 3.3
 
+   .. versionchanged:: 3.15
+      Removed the ``load_module()`` method.
+
    .. attribute:: name
 
       The name of the module the loader will handle.
@@ -1122,15 +1066,6 @@ find and load modules.
       Returns ``None`` as bytecode files have no source when this loader is
       used.
 
-   .. method:: load_module(name=None)
-
-   Concrete implementation of :meth:`importlib.abc.Loader.load_module` where
-   specifying the name of the module to load is optional.
-
-   .. deprecated-removed:: 3.6 3.15
-
-      Use :meth:`importlib.abc.Loader.exec_module` instead.
-
 
 .. class:: ExtensionFileLoader(fullname, path)
 
index d772d1f5345fcdd6c97099504927fc4844bab007..f50d02a0ef03b9c41b0261d06b91b5c8447b6cb6 100644 (file)
@@ -359,21 +359,16 @@ of what happens during the loading portion of import::
     if spec.loader is None:
         # unsupported
         raise ImportError
-    if spec.origin is None and spec.submodule_search_locations is not None:
-        # namespace package
-        sys.modules[spec.name] = module
-    elif not hasattr(spec.loader, 'exec_module'):
-        module = spec.loader.load_module(spec.name)
-    else:
-        sys.modules[spec.name] = module
+
+    sys.modules[spec.name] = module
+    try:
+        spec.loader.exec_module(module)
+    except BaseException:
         try:
-            spec.loader.exec_module(module)
-        except BaseException:
-            try:
-                del sys.modules[spec.name]
-            except KeyError:
-                pass
-            raise
+            del sys.modules[spec.name]
+        except KeyError:
+            pass
+        raise
     return sys.modules[spec.name]
 
 Note the following details:
@@ -408,7 +403,10 @@ Note the following details:
 .. versionchanged:: 3.4
    The import system has taken over the boilerplate responsibilities of
    loaders.  These were previously performed by the
-   :meth:`importlib.abc.Loader.load_module` method.
+   ``importlib.abc.Loader.load_module`` method.
+
+.. versionchanged:: 3.15
+    The ``load_module`` method is no longer used.
 
 Loaders
 -------
@@ -443,7 +441,7 @@ import machinery will create the new module itself.
    The :meth:`~importlib.abc.Loader.create_module` method of loaders.
 
 .. versionchanged:: 3.4
-   The :meth:`~importlib.abc.Loader.load_module` method was replaced by
+   The ``importlib.abc.Loader.load_module`` method was replaced by
    :meth:`~importlib.abc.Loader.exec_module` and the import
    machinery assumed all the boilerplate responsibilities of loading.
 
index d8251185fa7f4b6cef153c016d0c3dba4ea5f55b..4b092b1395953040276ef888ef6a7fdc5d797566 100644 (file)
@@ -1622,7 +1622,7 @@ Deprecated
   compatibility. Specifically,
   :meth:`!find_loader`/:meth:`!find_module`
   (superseded by :meth:`~importlib.abc.MetaPathFinder.find_spec`),
-  :meth:`~importlib.abc.Loader.load_module`
+  ``importlib.abc.Loader.load_module``
   (superseded by :meth:`~importlib.abc.Loader.exec_module`),
   :meth:`!module_repr` (which the import system
   takes care of for you), the ``__package__`` attribute
@@ -1652,7 +1652,7 @@ Deprecated
   preference for :meth:`~zipimport.zipimporter.exec_module`.
   (Contributed by Brett Cannon in :issue:`26131`.)
 
-* The use of :meth:`~importlib.abc.Loader.load_module` by the import
+* The use of ``importlib.abc.Loader.load_module`` by the import
   system now triggers an :exc:`ImportWarning` as
   :meth:`~importlib.abc.Loader.exec_module` is preferred.
   (Contributed by Brett Cannon in :issue:`26131`.)
index 9f4068116e3726ff0c7610a0800997fef8d8e187..a390211ddb502158ce4ceb7d191557b9e739be8a 100644 (file)
@@ -2086,10 +2086,10 @@ Deprecations in the Python API
   :meth:`!importlib.abc.PathEntryFinder.find_loader` and
   :meth:`!find_module` are replaced by
   :meth:`importlib.abc.PathEntryFinder.find_spec`; all of the :samp:`{xxx}Loader` ABC
-  ``load_module`` methods (:meth:`!importlib.abc.Loader.load_module`,
-  :meth:`!importlib.abc.InspectLoader.load_module`,
-  :meth:`!importlib.abc.FileLoader.load_module`,
-  :meth:`!importlib.abc.SourceLoader.load_module`) should no longer be
+  ``load_module`` methods (``importlib.abc.Loader.load_module``,
+  ``importlib.abc.InspectLoader.load_module``,
+  ``importlib.abc.FileLoader.load_module``,
+  ``importlib.abc.SourceLoader.load_module``) should no longer be
   implemented, instead loaders should implement an
   ``exec_module`` method
   (:meth:`importlib.abc.Loader.exec_module`,
index b1e3269239d62973ce92d2139bf830576618f7a0..9eafc09dbee5f43cb621e79ba1fa5ef9c715280e 100644 (file)
@@ -2006,10 +2006,10 @@ deprecated.
 importlib
 ~~~~~~~~~
 
-The :meth:`importlib.machinery.SourceFileLoader.load_module` and
-:meth:`importlib.machinery.SourcelessFileLoader.load_module` methods
+The ``importlib.machinery.SourceFileLoader.load_module`` and
+``importlib.machinery.SourcelessFileLoader.load_module`` methods
 are now deprecated. They were the only remaining implementations of
-:meth:`importlib.abc.Loader.load_module` in :mod:`importlib` that had not
+``importlib.abc.Loader.load_module`` in :mod:`importlib` that had not
 been deprecated in previous versions of Python in favour of
 :meth:`importlib.abc.Loader.exec_module`.
 
index 693b466112638f52c8b8822daf1973dd288209c2..2598036dac49181de0467a02f3ffa166e2268b55 100644 (file)
@@ -19,21 +19,3 @@ class Loader(metaclass=abc.ABCMeta):
 
     # We don't define exec_module() here since that would break
     # hasattr checks we do to support backward compatibility.
-
-    def load_module(self, fullname):
-        """Return the loaded module.
-
-        The module must be added to sys.modules and have import-related
-        attributes set properly.  The fullname is a str.
-
-        ImportError is raised on failure.
-
-        This method is deprecated in favor of loader.exec_module(). If
-        exec_module() exists then it is used to provide a backwards-compatible
-        functionality for this method.
-
-        """
-        if not hasattr(self, 'exec_module'):
-            raise ImportError
-        # Warning implemented in _load_module_shim().
-        return _bootstrap._load_module_shim(self, fullname)
index 43c66765dd97792cf9afcf62028a0e01255285ea..8cee9fda935050809a26e4d3d0f7d4599bdebc82 100644 (file)
@@ -521,24 +521,6 @@ def _requires_frozen(fxn):
     return _requires_frozen_wrapper
 
 
-# Typically used by loader classes as a method replacement.
-def _load_module_shim(self, fullname):
-    """Load the specified module into sys.modules and return it.
-
-    This method is deprecated.  Use loader.exec_module() instead.
-
-    """
-    msg = ("the load_module() method is deprecated and slated for removal in "
-           "Python 3.15; use exec_module() instead")
-    _warnings.warn(msg, DeprecationWarning)
-    spec = spec_from_loader(fullname, self)
-    if fullname in sys.modules:
-        module = sys.modules[fullname]
-        _exec(spec, module)
-        return sys.modules[fullname]
-    else:
-        return _load(spec)
-
 # Module specifications #######################################################
 
 def _module_repr(module):
@@ -763,8 +745,7 @@ def _init_module_attrs(spec, module, *, override=False):
                 # should also be None for consistency.  While a bit of a hack,
                 # this is the best place to ensure this consistency.
                 #
-                # See # https://docs.python.org/3/library/importlib.html#importlib.abc.Loader.load_module
-                # and bpo-32305
+                # See bpo-32305
                 module.__file__ = None
         try:
             module.__loader__ = loader
@@ -844,7 +825,7 @@ def _module_repr_from_spec(spec):
             return f'<module {spec.name!r} ({spec.origin})>'
 
 
-# Used by importlib.reload() and _load_module_shim().
+# Used by importlib.reload().
 def _exec(spec, module):
     """Execute the spec's specified module in an existing module's namespace."""
     name = spec.name
@@ -860,13 +841,7 @@ def _exec(spec, module):
                 _init_module_attrs(spec, module, override=True)
             else:
                 _init_module_attrs(spec, module, override=True)
-                if not hasattr(spec.loader, 'exec_module'):
-                    msg = (f"{_object_name(spec.loader)}.exec_module() not found; "
-                           "falling back to load_module()")
-                    _warnings.warn(msg, ImportWarning)
-                    spec.loader.load_module(name)
-                else:
-                    spec.loader.exec_module(module)
+                spec.loader.exec_module(module)
         finally:
             # Update the order of insertion into sys.modules for module
             # clean-up at shutdown.
@@ -874,53 +849,8 @@ def _exec(spec, module):
             sys.modules[spec.name] = module
     return module
 
-
-def _load_backward_compatible(spec):
-    # It is assumed that all callers have been warned about using load_module()
-    # appropriately before calling this function.
-    try:
-        spec.loader.load_module(spec.name)
-    except:
-        if spec.name in sys.modules:
-            module = sys.modules.pop(spec.name)
-            sys.modules[spec.name] = module
-        raise
-    # The module must be in sys.modules at this point!
-    # Move it to the end of sys.modules.
-    module = sys.modules.pop(spec.name)
-    sys.modules[spec.name] = module
-    if getattr(module, '__loader__', None) is None:
-        try:
-            module.__loader__ = spec.loader
-        except AttributeError:
-            pass
-    if getattr(module, '__package__', None) is None:
-        try:
-            # Since module.__path__ may not line up with
-            # spec.submodule_search_paths, we can't necessarily rely
-            # on spec.parent here.
-            module.__package__ = module.__name__
-            if not hasattr(module, '__path__'):
-                module.__package__ = spec.name.rpartition('.')[0]
-        except AttributeError:
-            pass
-    if getattr(module, '__spec__', None) is None:
-        try:
-            module.__spec__ = spec
-        except AttributeError:
-            pass
-    return module
-
 def _load_unlocked(spec):
     # A helper for direct use by the import system.
-    if spec.loader is not None:
-        # Not a namespace package.
-        if not hasattr(spec.loader, 'exec_module'):
-            msg = (f"{_object_name(spec.loader)}.exec_module() not found; "
-                    "falling back to load_module()")
-            _warnings.warn(msg, ImportWarning)
-            return _load_backward_compatible(spec)
-
     module = module_from_spec(spec)
 
     # This must be done before putting the module in sys.modules
@@ -954,8 +884,7 @@ def _load_unlocked(spec):
 
     return module
 
-# A method used during testing of _load_unlocked() and by
-# _load_module_shim().
+# A method used during testing of _load_unlocked().
 def _load(spec):
     """Return a new module object, loaded by the spec's loader.
 
@@ -1020,8 +949,6 @@ class BuiltinImporter:
         """Return False as built-in modules are never packages."""
         return False
 
-    load_module = classmethod(_load_module_shim)
-
 
 class FrozenImporter:
 
@@ -1178,25 +1105,6 @@ class FrozenImporter:
         code = _call_with_frames_removed(_imp.get_frozen_object, name)
         exec(code, module.__dict__)
 
-    @classmethod
-    def load_module(cls, fullname):
-        """Load a frozen module.
-
-        This method is deprecated.  Use exec_module() instead.
-
-        """
-        # Warning about deprecation implemented in _load_module_shim().
-        module = _load_module_shim(cls, fullname)
-        info = _imp.find_frozen(fullname)
-        assert info is not None
-        _, ispkg, origname = info
-        module.__origname__ = origname
-        vars(module).pop('__file__', None)
-        if ispkg:
-            module.__path__ = []
-        cls._fix_up_module(module)
-        return module
-
     @classmethod
     @_requires_frozen
     def get_code(cls, fullname):
index 2f9307cba4f086e10bdc6938a2f162083bb8b713..332dc1c5a4fc8f2e0b5b81497371a6d98c0498c8 100644 (file)
@@ -757,11 +757,6 @@ class _LoaderBasics:
                               'get_code() returns None')
         _bootstrap._call_with_frames_removed(exec, code, module.__dict__)
 
-    def load_module(self, fullname):
-        """This method is deprecated."""
-        # Warning implemented in _load_module_shim().
-        return _bootstrap._load_module_shim(self, fullname)
-
 
 class SourceLoader(_LoaderBasics):
 
@@ -927,18 +922,6 @@ class FileLoader:
     def __hash__(self):
         return hash(self.name) ^ hash(self.path)
 
-    @_check_name
-    def load_module(self, fullname):
-        """Load a module from a file.
-
-        This method is deprecated.  Use exec_module() instead.
-
-        """
-        # The only reason for this method is for the name check.
-        # Issue #14857: Avoid the zero-argument form of super so the implementation
-        # of that form can be updated without breaking the frozen module.
-        return super(FileLoader, self).load_module(fullname)
-
     @_check_name
     def get_filename(self, fullname):
         """Return the path to the source file as found by the finder."""
@@ -1190,18 +1173,6 @@ class NamespaceLoader:
     def exec_module(self, module):
         pass
 
-    def load_module(self, fullname):
-        """Load a namespace module.
-
-        This method is deprecated.  Use exec_module() instead.
-
-        """
-        # The import system never calls this method.
-        _bootstrap._verbose_message('namespace module loaded with path {!r}',
-                                    self._path)
-        # Warning implemented in _load_module_shim().
-        return _bootstrap._load_module_shim(self, fullname)
-
     def get_resource_reader(self, module):
         from importlib.readers import NamespaceReader
         return NamespaceReader(self._path)
index 5c13432b5bda8c27421514ab2547f40f4fdb188e..87922f32d1111b86e5597ecc1d54a7416c38b204 100644 (file)
@@ -128,7 +128,6 @@ class InspectLoader(Loader):
         return compile(data, path, 'exec', dont_inherit=True, module=fullname)
 
     exec_module = _bootstrap_external._LoaderBasics.exec_module
-    load_module = _bootstrap_external._LoaderBasics.load_module
 
 _register(InspectLoader, machinery.BuiltinImporter, machinery.FrozenImporter, machinery.NamespaceLoader)
 
index fa4f5e013d4b1721c280072f06f599c50af48d00..bc61ddc4f03675aaf6805d9f1b7e03cd3d43e60f 100644 (file)
@@ -2053,10 +2053,6 @@ class ImportTracebackTests(unittest.TestCase):
         # away from the traceback.
         self.create_module("foo", "")
         importlib = sys.modules['_frozen_importlib_external']
-        if 'load_module' in vars(importlib.SourceLoader):
-            old_exec_module = importlib.SourceLoader.exec_module
-        else:
-            old_exec_module = None
         try:
             def exec_module(*args):
                 1/0
@@ -2069,10 +2065,7 @@ class ImportTracebackTests(unittest.TestCase):
                 self.fail("ZeroDivisionError should have been raised")
             self.assert_traceback(tb, [__file__, '<frozen importlib', __file__])
         finally:
-            if old_exec_module is None:
-                del importlib.SourceLoader.exec_module
-            else:
-                importlib.SourceLoader.exec_module = old_exec_module
+            del importlib.SourceLoader.exec_module
 
     @unittest.skipUnless(TESTFN_UNENCODABLE, 'need TESTFN_UNENCODABLE')
     def test_unencodable_filename(self):
@@ -2792,9 +2785,6 @@ class SinglephaseInitTests(unittest.TestCase):
         # This is essentially copied from the old imp module.
         from importlib._bootstrap import _load
         loader = self.LOADER(name, path)
-
-        # Issue bpo-24748: Skip the sys.modules check in _load_module_shim;
-        # always load new extension.
         spec = importlib.util.spec_from_file_location(name, path,
                                                       loader=loader)
         return _load(spec)
index 5d4b958767633e302801c70c57b32bdd80e17599..0da98e0c99e39e4f903f1044ae8adaf0d95a6f58 100644 (file)
@@ -40,22 +40,6 @@ class FinderTests(metaclass=abc.ABCMeta):
 
 class LoaderTests(metaclass=abc.ABCMeta):
 
-    @abc.abstractmethod
-    def test_module(self):
-        """A module should load without issue.
-
-        After the loader returns the module should be in sys.modules.
-
-        Attributes to verify:
-
-            * __file__
-            * __loader__
-            * __name__
-            * No __path__
-
-        """
-        pass
-
     @abc.abstractmethod
     def test_package(self):
         """Loading a package should work.
index 7e9d1b1960fdd77a3af8108311c9f71e81d0e1ba..2a5c2a8f39ee13187777b0af9fd85fabe8fbfa39 100644 (file)
@@ -7,70 +7,6 @@ import types
 import unittest
 import warnings
 
-@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module')
-class LoaderTests(abc.LoaderTests):
-
-    """Test load_module() for built-in modules."""
-
-    def setUp(self):
-        self.verification = {'__name__': 'errno', '__package__': '',
-                             '__loader__': self.machinery.BuiltinImporter}
-
-    def verify(self, module):
-        """Verify that the module matches against what it should have."""
-        self.assertIsInstance(module, types.ModuleType)
-        for attr, value in self.verification.items():
-            self.assertEqual(getattr(module, attr), value)
-        self.assertIn(module.__name__, sys.modules)
-
-    def load_module(self, name):
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", DeprecationWarning)
-            return self.machinery.BuiltinImporter.load_module(name)
-
-    def test_module(self):
-        # Common case.
-        with util.uncache(util.BUILTINS.good_name):
-            module = self.load_module(util.BUILTINS.good_name)
-            self.verify(module)
-
-    # Built-in modules cannot be a package.
-    test_package = test_lacking_parent = None
-
-    # No way to force an import failure.
-    test_state_after_failure = None
-
-    def test_module_reuse(self):
-        # Test that the same module is used in a reload.
-        with util.uncache(util.BUILTINS.good_name):
-            module1 = self.load_module(util.BUILTINS.good_name)
-            module2 = self.load_module(util.BUILTINS.good_name)
-            self.assertIs(module1, module2)
-
-    def test_unloadable(self):
-        name = 'dssdsdfff'
-        assert name not in sys.builtin_module_names
-        with self.assertRaises(ImportError) as cm:
-            self.load_module(name)
-        self.assertEqual(cm.exception.name, name)
-
-    def test_already_imported(self):
-        # Using the name of a module already imported but not a built-in should
-        # still fail.
-        module_name = 'builtin_reload_test'
-        assert module_name not in sys.builtin_module_names
-        with util.uncache(module_name):
-            module = types.ModuleType(module_name)
-            sys.modules[module_name] = module
-        with self.assertRaises(ImportError) as cm:
-            self.load_module(module_name)
-        self.assertEqual(cm.exception.name, module_name)
-
-
-(Frozen_LoaderTests,
- Source_LoaderTests
- ) = util.test_both(LoaderTests, machinery=machinery)
-
 
 @unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module')
 class InspectLoaderTests:
index 0dd21e079eba224758a13c2427b1d5adb67ef75c..15d5a7d4752cc89c5e287eed4f7a81bd9e237751 100644 (file)
@@ -35,11 +35,6 @@ class LoaderTests:
 
         self.loader = self.LoaderClass(util.EXTENSIONS.name, util.EXTENSIONS.file_path)
 
-    def load_module(self, fullname):
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", DeprecationWarning)
-            return self.loader.load_module(fullname)
-
     def test_equality(self):
         other = self.LoaderClass(util.EXTENSIONS.name, util.EXTENSIONS.file_path)
         self.assertEqual(self.loader, other)
@@ -48,25 +43,6 @@ class LoaderTests:
         other = self.LoaderClass('_' + util.EXTENSIONS.name, util.EXTENSIONS.file_path)
         self.assertNotEqual(self.loader, other)
 
-    def test_load_module_API(self):
-        # Test the default argument for load_module().
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", DeprecationWarning)
-            self.loader.load_module()
-            self.loader.load_module(None)
-            with self.assertRaises(ImportError):
-                self.load_module('XXX')
-
-    def test_module(self):
-        with util.uncache(util.EXTENSIONS.name):
-            module = self.load_module(util.EXTENSIONS.name)
-            for attr, value in [('__name__', util.EXTENSIONS.name),
-                                ('__file__', util.EXTENSIONS.file_path),
-                                ('__package__', '')]:
-                self.assertEqual(getattr(module, attr), value)
-            self.assertIn(util.EXTENSIONS.name, sys.modules)
-            self.assertIsInstance(module.__loader__, self.LoaderClass)
-
     # No extension module as __init__ available for testing.
     test_package = None
 
@@ -76,18 +52,6 @@ class LoaderTests:
     # No easy way to trigger a failure after a successful import.
     test_state_after_failure = None
 
-    def test_unloadable(self):
-        name = 'asdfjkl;'
-        with self.assertRaises(ImportError) as cm:
-            self.load_module(name)
-        self.assertEqual(cm.exception.name, name)
-
-    def test_module_reuse(self):
-        with util.uncache(util.EXTENSIONS.name):
-            module1 = self.load_module(util.EXTENSIONS.name)
-            module2 = self.load_module(util.EXTENSIONS.name)
-            self.assertIs(module1, module2)
-
     def test_is_package(self):
         self.assertFalse(self.loader.is_package(util.EXTENSIONS.name))
         for suffix in self.machinery.EXTENSION_SUFFIXES:
@@ -126,11 +90,6 @@ class SinglePhaseExtensionModuleTests(abc.LoaderTests):
 
         self.loader = self.LoaderClass(self.name, self.spec.origin)
 
-    def load_module(self):
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", DeprecationWarning)
-            return self.loader.load_module(self.name)
-
     def load_module_by_name(self, fullname):
         # Load a module from the test extension by name.
         origin = self.spec.origin
@@ -140,19 +99,6 @@ class SinglePhaseExtensionModuleTests(abc.LoaderTests):
         loader.exec_module(module)
         return module
 
-    def test_module(self):
-        # Test loading an extension module.
-        with util.uncache(self.name):
-            module = self.load_module()
-            for attr, value in [('__name__', self.name),
-                                ('__file__', self.spec.origin),
-                                ('__package__', '')]:
-                self.assertEqual(getattr(module, attr), value)
-            with self.assertRaises(AttributeError):
-                module.__path__
-            self.assertIs(module, sys.modules[self.name])
-            self.assertIsInstance(module.__loader__, self.LoaderClass)
-
     # No extension module as __init__ available for testing.
     test_package = None
 
@@ -213,12 +159,6 @@ class MultiPhaseExtensionModuleTests(abc.LoaderTests):
         assert self.spec
         self.loader = self.LoaderClass(self.name, self.spec.origin)
 
-    def load_module(self):
-        # Load the module from the test extension.
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", DeprecationWarning)
-            return self.loader.load_module(self.name)
-
     def load_module_by_name(self, fullname):
         # Load a module from the test extension by name.
         origin = self.spec.origin
@@ -237,60 +177,6 @@ class MultiPhaseExtensionModuleTests(abc.LoaderTests):
     # Handling failure on reload is the up to the module.
     test_state_after_failure = None
 
-    def test_module(self):
-        # Test loading an extension module.
-        with util.uncache(self.name):
-            module = self.load_module()
-            for attr, value in [('__name__', self.name),
-                                ('__file__', self.spec.origin),
-                                ('__package__', '')]:
-                self.assertEqual(getattr(module, attr), value)
-            with self.assertRaises(AttributeError):
-                module.__path__
-            self.assertIs(module, sys.modules[self.name])
-            self.assertIsInstance(module.__loader__, self.LoaderClass)
-
-    def test_functionality(self):
-        # Test basic functionality of stuff defined in an extension module.
-        with util.uncache(self.name):
-            module = self.load_module()
-            self.assertIsInstance(module, types.ModuleType)
-            ex = module.Example()
-            self.assertEqual(ex.demo('abcd'), 'abcd')
-            self.assertEqual(ex.demo(), None)
-            with self.assertRaises(AttributeError):
-                ex.abc
-            ex.abc = 0
-            self.assertEqual(ex.abc, 0)
-            self.assertEqual(module.foo(9, 9), 18)
-            self.assertIsInstance(module.Str(), str)
-            self.assertEqual(module.Str(1) + '23', '123')
-            with self.assertRaises(module.error):
-                raise module.error()
-            self.assertEqual(module.int_const, 1969)
-            self.assertEqual(module.str_const, 'something different')
-
-    def test_reload(self):
-        # Test that reload didn't re-set the module's attributes.
-        with util.uncache(self.name):
-            module = self.load_module()
-            ex_class = module.Example
-            importlib.reload(module)
-            self.assertIs(ex_class, module.Example)
-
-    def test_try_registration(self):
-        # Assert that the PyState_{Find,Add,Remove}Module C API doesn't work.
-        with util.uncache(self.name):
-            module = self.load_module()
-            with self.subTest('PyState_FindModule'):
-                self.assertEqual(module.call_state_registration_func(0), None)
-            with self.subTest('PyState_AddModule'):
-                with self.assertRaises(SystemError):
-                    module.call_state_registration_func(1)
-            with self.subTest('PyState_RemoveModule'):
-                with self.assertRaises(SystemError):
-                    module.call_state_registration_func(2)
-
     def test_load_submodule(self):
         # Test loading a simulated submodule.
         module = self.load_module_by_name('pkg.' + self.name)
index d6ad590b3d46a00c80833e426fd482a6d0bc30fa..ea1e29a4e5f278353aac69139368cc28e3aa29e9 100644 (file)
@@ -27,13 +27,6 @@ class BadSpecFinderLoader:
             raise ImportError('I cannot be loaded!')
 
 
-class BadLoaderFinder:
-    @classmethod
-    def load_module(cls, fullname):
-        if fullname == SUBMOD_NAME:
-            raise ImportError('I cannot be loaded!')
-
-
 class APITest:
 
     """Test API-specific details for __import__ (e.g. raising the right
@@ -93,45 +86,6 @@ class APITest:
                 self.assertEqual(cm.exception.name, SUBMOD_NAME)
 
 
-class OldAPITests(APITest):
-    bad_finder_loader = BadLoaderFinder
-
-    def test_raises_ModuleNotFoundError(self):
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", ImportWarning)
-            super().test_raises_ModuleNotFoundError()
-
-    def test_name_requires_rparition(self):
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", ImportWarning)
-            super().test_name_requires_rparition()
-
-    def test_negative_level(self):
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", ImportWarning)
-            super().test_negative_level()
-
-    def test_nonexistent_fromlist_entry(self):
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", ImportWarning)
-            super().test_nonexistent_fromlist_entry()
-
-    def test_fromlist_load_error_propagates(self):
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", ImportWarning)
-            super().test_fromlist_load_error_propagates
-
-    def test_blocked_fromlist(self):
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", ImportWarning)
-            super().test_blocked_fromlist()
-
-
-(Frozen_OldAPITests,
- Source_OldAPITests
- ) = util.test_both(OldAPITests, __import__=util.__import__)
-
-
 class SpecAPITests(APITest):
     bad_finder_loader = BadSpecFinderLoader
 
index f35adec1a8e800b1935b35a088821fe977449b2c..5d5d4722171a8eaaf0665332918c54e7bbabeadd 100644 (file)
@@ -22,7 +22,7 @@ from test.test_py_compile import without_source_date_epoch
 from test.test_py_compile import SourceDateEpochTestMeta
 
 
-class SimpleTest(abc.LoaderTests):
+class SimpleTest:
 
     """Should have no issue importing a source module [basic]. And if there is
     a syntax error, it should raise a SyntaxError [syntax error].
@@ -34,17 +34,6 @@ class SimpleTest(abc.LoaderTests):
         self.filepath = os.path.join('ham', self.name + '.py')
         self.loader = self.machinery.SourceFileLoader(self.name, self.filepath)
 
-    def test_load_module_API(self):
-        class Tester(self.abc.FileLoader):
-            def get_source(self, _): return 'attr = 42'
-            def is_package(self, _): return False
-
-        loader = Tester('blah', 'blah.py')
-        self.addCleanup(unload, 'blah')
-        with warnings.catch_warnings():
-            warnings.simplefilter('ignore', DeprecationWarning)
-            module = loader.load_module()  # Should not raise an exception.
-
     def test_get_filename_API(self):
         # If fullname is not set then assume self.path is desired.
         class Tester(self.abc.FileLoader):
@@ -69,173 +58,11 @@ class SimpleTest(abc.LoaderTests):
         other = self.machinery.SourceFileLoader('_' + self.name, self.filepath)
         self.assertNotEqual(self.loader, other)
 
-    # [basic]
-    def test_module(self):
-        with util.create_modules('_temp') as mapping:
-            loader = self.machinery.SourceFileLoader('_temp', mapping['_temp'])
-            with warnings.catch_warnings():
-                warnings.simplefilter('ignore', DeprecationWarning)
-                module = loader.load_module('_temp')
-            self.assertIn('_temp', sys.modules)
-            check = {'__name__': '_temp', '__file__': mapping['_temp'],
-                     '__package__': ''}
-            for attr, value in check.items():
-                self.assertEqual(getattr(module, attr), value)
-
-    def test_package(self):
-        with util.create_modules('_pkg.__init__') as mapping:
-            loader = self.machinery.SourceFileLoader('_pkg',
-                                                 mapping['_pkg.__init__'])
-            with warnings.catch_warnings():
-                warnings.simplefilter('ignore', DeprecationWarning)
-                module = loader.load_module('_pkg')
-            self.assertIn('_pkg', sys.modules)
-            check = {'__name__': '_pkg', '__file__': mapping['_pkg.__init__'],
-                     '__path__': [os.path.dirname(mapping['_pkg.__init__'])],
-                     '__package__': '_pkg'}
-            for attr, value in check.items():
-                self.assertEqual(getattr(module, attr), value)
-
-
-    def test_lacking_parent(self):
-        with util.create_modules('_pkg.__init__', '_pkg.mod')as mapping:
-            loader = self.machinery.SourceFileLoader('_pkg.mod',
-                                                    mapping['_pkg.mod'])
-            with warnings.catch_warnings():
-                warnings.simplefilter('ignore', DeprecationWarning)
-                module = loader.load_module('_pkg.mod')
-            self.assertIn('_pkg.mod', sys.modules)
-            check = {'__name__': '_pkg.mod', '__file__': mapping['_pkg.mod'],
-                     '__package__': '_pkg'}
-            for attr, value in check.items():
-                self.assertEqual(getattr(module, attr), value)
 
     def fake_mtime(self, fxn):
         """Fake mtime to always be higher than expected."""
         return lambda name: fxn(name) + 1
 
-    def test_module_reuse(self):
-        with util.create_modules('_temp') as mapping:
-            loader = self.machinery.SourceFileLoader('_temp', mapping['_temp'])
-            with warnings.catch_warnings():
-                warnings.simplefilter('ignore', DeprecationWarning)
-                module = loader.load_module('_temp')
-            module_id = id(module)
-            module_dict_id = id(module.__dict__)
-            with open(mapping['_temp'], 'w', encoding='utf-8') as file:
-                file.write("testing_var = 42\n")
-            with warnings.catch_warnings():
-                warnings.simplefilter('ignore', DeprecationWarning)
-                module = loader.load_module('_temp')
-            self.assertIn('testing_var', module.__dict__,
-                         "'testing_var' not in "
-                            "{0}".format(list(module.__dict__.keys())))
-            self.assertEqual(module, sys.modules['_temp'])
-            self.assertEqual(id(module), module_id)
-            self.assertEqual(id(module.__dict__), module_dict_id)
-
-    def test_state_after_failure(self):
-        # A failed reload should leave the original module intact.
-        attributes = ('__file__', '__path__', '__package__')
-        value = '<test>'
-        name = '_temp'
-        with util.create_modules(name) as mapping:
-            orig_module = types.ModuleType(name)
-            for attr in attributes:
-                setattr(orig_module, attr, value)
-            with open(mapping[name], 'w', encoding='utf-8') as file:
-                file.write('+++ bad syntax +++')
-            loader = self.machinery.SourceFileLoader('_temp', mapping['_temp'])
-            with self.assertRaises(SyntaxError):
-                loader.exec_module(orig_module)
-            for attr in attributes:
-                self.assertEqual(getattr(orig_module, attr), value)
-            with self.assertRaises(SyntaxError):
-                with warnings.catch_warnings():
-                    warnings.simplefilter('ignore', DeprecationWarning)
-                    loader.load_module(name)
-            for attr in attributes:
-                self.assertEqual(getattr(orig_module, attr), value)
-
-    # [syntax error]
-    def test_bad_syntax(self):
-        with util.create_modules('_temp') as mapping:
-            with open(mapping['_temp'], 'w', encoding='utf-8') as file:
-                file.write('=')
-            loader = self.machinery.SourceFileLoader('_temp', mapping['_temp'])
-            with self.assertRaises(SyntaxError):
-                with warnings.catch_warnings():
-                    warnings.simplefilter('ignore', DeprecationWarning)
-                    loader.load_module('_temp')
-            self.assertNotIn('_temp', sys.modules)
-
-    def test_file_from_empty_string_dir(self):
-        # Loading a module found from an empty string entry on sys.path should
-        # not only work, but keep all attributes relative.
-        file_path = '_temp.py'
-        with open(file_path, 'w', encoding='utf-8') as file:
-            file.write("# test file for importlib")
-        try:
-            with util.uncache('_temp'):
-                loader = self.machinery.SourceFileLoader('_temp', file_path)
-                with warnings.catch_warnings():
-                    warnings.simplefilter('ignore', DeprecationWarning)
-                    mod = loader.load_module('_temp')
-                self.assertEqual(file_path, mod.__file__)
-                self.assertEqual(self.util.cache_from_source(file_path),
-                                 mod.__cached__)
-        finally:
-            os.unlink(file_path)
-            pycache = os.path.dirname(self.util.cache_from_source(file_path))
-            if os.path.exists(pycache):
-                shutil.rmtree(pycache)
-
-    @util.writes_bytecode_files
-    def test_timestamp_overflow(self):
-        # When a modification timestamp is larger than 2**32, it should be
-        # truncated rather than raise an OverflowError.
-        with util.create_modules('_temp') as mapping:
-            source = mapping['_temp']
-            compiled = self.util.cache_from_source(source)
-            with open(source, 'w', encoding='utf-8') as f:
-                f.write("x = 5")
-            try:
-                os.utime(source, (2 ** 33 - 5, 2 ** 33 - 5))
-            except OverflowError:
-                self.skipTest("cannot set modification time to large integer")
-            except OSError as e:
-                if e.errno != getattr(errno, 'EOVERFLOW', None):
-                    raise
-                self.skipTest("cannot set modification time to large integer ({})".format(e))
-            loader = self.machinery.SourceFileLoader('_temp', mapping['_temp'])
-            # PEP 451
-            module = types.ModuleType('_temp')
-            module.__spec__ = self.util.spec_from_loader('_temp', loader)
-            loader.exec_module(module)
-            self.assertEqual(module.x, 5)
-            self.assertTrue(os.path.exists(compiled))
-            os.unlink(compiled)
-            # PEP 302
-            with warnings.catch_warnings():
-                warnings.simplefilter('ignore', DeprecationWarning)
-                mod = loader.load_module('_temp')
-            # Sanity checks.
-            self.assertEqual(mod.__cached__, compiled)
-            self.assertEqual(mod.x, 5)
-            # The pyc file was created.
-            self.assertTrue(os.path.exists(compiled))
-
-    def test_unloadable(self):
-        loader = self.machinery.SourceFileLoader('good name', {})
-        module = types.ModuleType('bad name')
-        module.__spec__ = self.machinery.ModuleSpec('bad name', loader)
-        with self.assertRaises(ImportError):
-            loader.exec_module(module)
-        with self.assertRaises(ImportError):
-            with warnings.catch_warnings():
-                warnings.simplefilter('ignore', DeprecationWarning)
-                loader.load_module('bad name')
-
     @util.writes_bytecode_files
     def test_checked_hash_based_pyc(self):
         with util.create_modules('_temp') as mapping:
@@ -511,16 +338,6 @@ class BadBytecodeTestPEP451(BadBytecodeTest):
         loader.exec_module(module)
 
 
-class BadBytecodeTestPEP302(BadBytecodeTest):
-
-    def import_(self, file, module_name):
-        loader = self.loader(module_name, file)
-        with warnings.catch_warnings():
-            warnings.simplefilter('ignore', DeprecationWarning)
-            module = loader.load_module(module_name)
-        self.assertIn(module_name, sys.modules)
-
-
 class SourceLoaderBadBytecodeTest:
 
     @classmethod
@@ -681,18 +498,6 @@ class SourceLoaderBadBytecodeTestPEP451(
                     util=importlib_util)
 
 
-class SourceLoaderBadBytecodeTestPEP302(
-        SourceLoaderBadBytecodeTest, BadBytecodeTestPEP302):
-    pass
-
-
-(Frozen_SourceBadBytecodePEP302,
- Source_SourceBadBytecodePEP302
- ) = util.test_both(SourceLoaderBadBytecodeTestPEP302, importlib=importlib,
-                    machinery=machinery, abc=importlib_abc,
-                    util=importlib_util)
-
-
 class SourcelessLoaderBadBytecodeTest:
 
     @classmethod
@@ -779,17 +584,5 @@ class SourcelessLoaderBadBytecodeTestPEP451(SourcelessLoaderBadBytecodeTest,
                     util=importlib_util)
 
 
-class SourcelessLoaderBadBytecodeTestPEP302(SourcelessLoaderBadBytecodeTest,
-        BadBytecodeTestPEP302):
-    pass
-
-
-(Frozen_SourcelessBadBytecodePEP302,
- Source_SourcelessBadBytecodePEP302
- ) = util.test_both(SourcelessLoaderBadBytecodeTestPEP302, importlib=importlib,
-                    machinery=machinery, abc=importlib_abc,
-                    util=importlib_util)
-
-
 if __name__ == '__main__':
     unittest.main()
index 4de736a6bf3b2d329084a278385f2c1581807370..c33e90232b36e653771cbacb39f44bd28a2d5fa2 100644 (file)
@@ -73,7 +73,7 @@ class FinderTests(abc.FinderTests):
                         if error.errno != errno.ENOENT:
                             raise
             loader = self.import_(mapping['.root'], test)
-            self.assertHasAttr(loader, 'load_module')
+            self.assertHasAttr(loader, 'exec_module')
             return loader
 
     def test_module(self):
@@ -100,7 +100,7 @@ class FinderTests(abc.FinderTests):
         with util.create_modules('pkg.__init__', 'pkg.sub') as mapping:
             pkg_dir = os.path.dirname(mapping['pkg.__init__'])
             loader = self.import_(pkg_dir, 'pkg.sub')
-            self.assertHasAttr(loader, 'load_module')
+            self.assertHasAttr(loader, 'exec_module')
 
     # [sub package]
     def test_package_in_package(self):
@@ -108,7 +108,7 @@ class FinderTests(abc.FinderTests):
         with context as mapping:
             pkg_dir = os.path.dirname(mapping['pkg.__init__'])
             loader = self.import_(pkg_dir, 'pkg.sub')
-            self.assertHasAttr(loader, 'load_module')
+            self.assertHasAttr(loader, 'exec_module')
 
     # [package over modules]
     def test_package_over_module(self):
@@ -129,7 +129,7 @@ class FinderTests(abc.FinderTests):
             file.write("# test file for importlib")
         try:
             loader = self._find(finder, 'mod', loader_only=True)
-            self.assertHasAttr(loader, 'load_module')
+            self.assertHasAttr(loader, 'exec_module')
         finally:
             os.unlink('mod.py')
 
index c09c9aa12b862e1cfcf6d88290a01746dcddedbe..fada07877fc1258344768b2d8625cdff18bc5364 100644 (file)
@@ -102,19 +102,6 @@ class EncodingTestPEP451(EncodingTest):
  ) = util.test_both(EncodingTestPEP451, machinery=machinery)
 
 
-class EncodingTestPEP302(EncodingTest):
-
-    def load(self, loader):
-        with warnings.catch_warnings():
-            warnings.simplefilter('ignore', DeprecationWarning)
-            return loader.load_module(self.module_name)
-
-
-(Frozen_EncodingTestPEP302,
- Source_EncodingTestPEP302
- ) = util.test_both(EncodingTestPEP302, machinery=machinery)
-
-
 class LineEndingTest:
 
     r"""Source written with the three types of line endings (\n, \r\n, \r)
@@ -158,18 +145,5 @@ class LineEndingTestPEP451(LineEndingTest):
  ) = util.test_both(LineEndingTestPEP451, machinery=machinery)
 
 
-class LineEndingTestPEP302(LineEndingTest):
-
-    def load(self, loader, module_name):
-        with warnings.catch_warnings():
-            warnings.simplefilter('ignore', DeprecationWarning)
-            return loader.load_module(module_name)
-
-
-(Frozen_LineEndingTestPEP302,
- Source_LineEndingTestPEP302
- ) = util.test_both(LineEndingTestPEP302, machinery=machinery)
-
-
 if __name__ == '__main__':
     unittest.main()
index bd1540ce403ce29eb7fa7a1b91f9c5e5df4ef9ac..8132a69d8f4e8922eb7aa92304d5321d82e554b3 100644 (file)
@@ -194,10 +194,6 @@ class LoaderDefaultsTests(ABCTestHarness):
         spec = 'a spec'
         self.assertIsNone(self.ins.create_module(spec))
 
-    def test_load_module(self):
-        with self.assertRaises(ImportError):
-            self.ins.load_module('something')
-
     def test_module_repr(self):
         mod = types.ModuleType('blah')
         with warnings.catch_warnings():
@@ -358,38 +354,6 @@ class LoaderLoadModuleTests:
 
         return SpecLoader()
 
-    def test_fresh(self):
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", DeprecationWarning)
-            loader = self.loader()
-            name = 'blah'
-            with test_util.uncache(name):
-                loader.load_module(name)
-                module = loader.found
-                self.assertIs(sys.modules[name], module)
-            self.assertEqual(loader, module.__loader__)
-            self.assertEqual(loader, module.__spec__.loader)
-            self.assertEqual(name, module.__name__)
-            self.assertEqual(name, module.__spec__.name)
-            self.assertIsNotNone(module.__path__)
-            self.assertIsNotNone(module.__path__,
-                                module.__spec__.submodule_search_locations)
-
-    def test_reload(self):
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", DeprecationWarning)
-            name = 'blah'
-            loader = self.loader()
-            module = types.ModuleType(name)
-            module.__spec__ = self.util.spec_from_loader(name, loader)
-            module.__loader__ = loader
-            with test_util.uncache(name):
-                sys.modules[name] = module
-                loader.load_module(name)
-                found = loader.found
-                self.assertIs(found, sys.modules[name])
-                self.assertIs(module, sys.modules[name])
-
 
 (Frozen_LoaderLoadModuleTests,
  Source_LoaderLoadModuleTests
@@ -478,59 +442,6 @@ class InspectLoaderGetCodeTests:
                          InspectLoaderSubclass=SPLIT_IL)
 
 
-class InspectLoaderLoadModuleTests:
-
-    """Test InspectLoader.load_module()."""
-
-    module_name = 'blah'
-
-    def setUp(self):
-        import_helper.unload(self.module_name)
-        self.addCleanup(import_helper.unload, self.module_name)
-
-    def load(self, loader):
-        spec = self.util.spec_from_loader(self.module_name, loader)
-        with warnings.catch_warnings():
-            warnings.simplefilter('ignore', DeprecationWarning)
-            return self.init._bootstrap._load_unlocked(spec)
-
-    def mock_get_code(self):
-        return mock.patch.object(self.InspectLoaderSubclass, 'get_code')
-
-    def test_get_code_ImportError(self):
-        # If get_code() raises ImportError, it should propagate.
-        with self.mock_get_code() as mocked_get_code:
-            mocked_get_code.side_effect = ImportError
-            with self.assertRaises(ImportError):
-                loader = self.InspectLoaderSubclass()
-                self.load(loader)
-
-    def test_get_code_None(self):
-        # If get_code() returns None, raise ImportError.
-        with self.mock_get_code() as mocked_get_code:
-            mocked_get_code.return_value = None
-            with self.assertRaises(ImportError):
-                loader = self.InspectLoaderSubclass()
-                self.load(loader)
-
-    def test_module_returned(self):
-        # The loaded module should be returned.
-        code = compile('attr = 42', '<string>', 'exec')
-        with self.mock_get_code() as mocked_get_code:
-            mocked_get_code.return_value = code
-            loader = self.InspectLoaderSubclass()
-            module = self.load(loader)
-            self.assertEqual(module, sys.modules[self.module_name])
-
-
-(Frozen_ILLoadModuleTests,
- Source_ILLoadModuleTests
- ) = test_util.test_both(InspectLoaderLoadModuleTests,
-                         InspectLoaderSubclass=SPLIT_IL,
-                         init=init,
-                         util=util)
-
-
 ##### ExecutionLoader concrete methods #########################################
 class ExecutionLoaderGetCodeTests:
 
@@ -729,34 +640,6 @@ class SourceOnlyLoaderTests(SourceLoaderTestHarness):
         code = self.loader.source_to_code(self.loader.source, self.path)
         self.verify_code(code)
 
-    def test_load_module(self):
-        # Loading a module should set __name__, __loader__, __package__,
-        # __path__ (for packages), __file__, and __cached__.
-        # The module should also be put into sys.modules.
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", ImportWarning)
-            with test_util.uncache(self.name):
-                with warnings.catch_warnings():
-                    warnings.simplefilter('ignore', DeprecationWarning)
-                    module = self.loader.load_module(self.name)
-                self.verify_module(module)
-                self.assertEqual(module.__path__, [os.path.dirname(self.path)])
-                self.assertIn(self.name, sys.modules)
-
-    def test_package_settings(self):
-        # __package__ needs to be set, while __path__ is set on if the module
-        # is a package.
-        # Testing the values for a package are covered by test_load_module.
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", ImportWarning)
-            self.setUp(is_package=False)
-            with test_util.uncache(self.name):
-                with warnings.catch_warnings():
-                    warnings.simplefilter('ignore', DeprecationWarning)
-                    module = self.loader.load_module(self.name)
-                self.verify_module(module)
-                self.assertNotHasAttr(module, '__path__')
-
     def test_get_source_encoding(self):
         # Source is considered encoded in UTF-8 by default unless otherwise
         # specified by an encoding line.
index aebeabaf83f75daf6d3173e9aa09e09d7c22443c..fef0fda101e46d9e38945bd99afff0270ed4b261 100644 (file)
@@ -287,20 +287,6 @@ class ModuleSpecMethodsTests:
                 loaded = self.bootstrap._load(self.spec)
             self.assertNotIn(self.spec.name, sys.modules)
 
-    def test_load_legacy_attributes_immutable(self):
-        module = object()
-        with warnings.catch_warnings():
-            warnings.simplefilter("ignore", ImportWarning)
-            class ImmutableLoader(TestLoader):
-                def load_module(self, name):
-                    sys.modules[name] = module
-                    return module
-            self.spec.loader = ImmutableLoader()
-            with CleanImport(self.spec.name):
-                loaded = self.bootstrap._load(self.spec)
-
-                self.assertIs(sys.modules[self.spec.name], module)
-
     # reload()
 
     def test_reload(self):
index 9064402bcf71f6e15f23c639462d1ce77e9c7ce3..cf250df552609178c4510101578767d94d3e9425 100644 (file)
@@ -621,7 +621,7 @@ Andrew Svetlov.
 .. nonce: jQ0CvW
 .. section: Library
 
-Update the deprecation warning of :meth:`importlib.abc.Loader.load_module`.
+Update the deprecation warning of ``importlib.abc.Loader.load_module``.
 
 ..
 
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-02-15-39-16.gh-issue-97850.H6QKwl.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-02-15-39-16.gh-issue-97850.H6QKwl.rst
new file mode 100644 (file)
index 0000000..f26d79d
--- /dev/null
@@ -0,0 +1,3 @@
+Remove all ``*.load_module()`` usage and definitions from the import system
+and importlib. The method has been deprecated in favor of
+``importlib.abc.Loader.exec_module()`` since Python 3.4.