https://github.com/python/cpython/commit/880a7905ca53d3c5c22958934f170f33fe44f0f5
commit: 880a7905ca53d3c5c22958934f170f33fe44f0f5
branch: main
author: Brett Cannon <[email protected]>
committer: brettcannon <[email protected]>
date: 2025-12-10T15:35:51-08:00
summary:
GH-97850: Remove all uses and definitions of `load_module()` from importlib
(#142205)
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2025-12-02-15-39-16.gh-issue-97850.H6QKwl.rst
M Doc/library/importlib.rst
M Doc/reference/import.rst
M Doc/whatsnew/3.10.rst
M Doc/whatsnew/3.4.rst
M Doc/whatsnew/3.6.rst
M Lib/importlib/_abc.py
M Lib/importlib/_bootstrap.py
M Lib/importlib/_bootstrap_external.py
M Lib/importlib/abc.py
M Lib/test/test_import/__init__.py
M Lib/test/test_importlib/abc.py
M Lib/test/test_importlib/builtin/test_loader.py
M Lib/test/test_importlib/extension/test_loader.py
M Lib/test/test_importlib/import_/test_api.py
M Lib/test/test_importlib/source/test_file_loader.py
M Lib/test/test_importlib/source/test_finder.py
M Lib/test/test_importlib/source/test_source_encoding.py
M Lib/test/test_importlib/test_abc.py
M Lib/test/test_importlib/test_spec.py
M Misc/NEWS.d/3.14.0a6.rst
diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
index 3f0a54ac535cd6..34130f9be67e7e 100644
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -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)
diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst
index d772d1f5345fcd..f50d02a0ef03b9 100644
--- a/Doc/reference/import.rst
+++ b/Doc/reference/import.rst
@@ -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.
diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst
index d8251185fa7f4b..4b092b13959530 100644
--- a/Doc/whatsnew/3.10.rst
+++ b/Doc/whatsnew/3.10.rst
@@ -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`.)
diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst
index 9f4068116e3726..a390211ddb5021 100644
--- a/Doc/whatsnew/3.4.rst
+++ b/Doc/whatsnew/3.4.rst
@@ -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`,
diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst
index b1e3269239d629..9eafc09dbee5f4 100644
--- a/Doc/whatsnew/3.6.rst
+++ b/Doc/whatsnew/3.6.rst
@@ -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`.
diff --git a/Lib/importlib/_abc.py b/Lib/importlib/_abc.py
index 693b466112638f..2598036dac4918 100644
--- a/Lib/importlib/_abc.py
+++ b/Lib/importlib/_abc.py
@@ -19,21 +19,3 @@ def create_module(self, spec):
# 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)
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
index 43c66765dd9779..8cee9fda935050 100644
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -521,24 +521,6 @@ def _requires_frozen_wrapper(self, fullname):
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 @@ def is_package(cls, fullname):
"""Return False as built-in modules are never packages."""
return False
- load_module = classmethod(_load_module_shim)
-
class FrozenImporter:
@@ -1178,25 +1105,6 @@ def exec_module(module):
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):
diff --git a/Lib/importlib/_bootstrap_external.py
b/Lib/importlib/_bootstrap_external.py
index 2f9307cba4f086..332dc1c5a4fc8f 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -757,11 +757,6 @@ def exec_module(self, module):
'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 @@ def __eq__(self, other):
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 @@ def create_module(self, spec):
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)
diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py
index 5c13432b5bda8c..87922f32d1111b 100644
--- a/Lib/importlib/abc.py
+++ b/Lib/importlib/abc.py
@@ -128,7 +128,6 @@ def source_to_code(data, path='<string>', fullname=None):
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)
diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py
index fa4f5e013d4b17..bc61ddc4f03675 100644
--- a/Lib/test/test_import/__init__.py
+++ b/Lib/test/test_import/__init__.py
@@ -2053,10 +2053,6 @@ def test_import_bug(self):
# 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 @@ def exec_module(*args):
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 @@ def _load_dynamic(self, name, path):
# 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)
diff --git a/Lib/test/test_importlib/abc.py b/Lib/test/test_importlib/abc.py
index 5d4b958767633e..0da98e0c99e39e 100644
--- a/Lib/test/test_importlib/abc.py
+++ b/Lib/test/test_importlib/abc.py
@@ -40,22 +40,6 @@ def test_failure(self):
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.
diff --git a/Lib/test/test_importlib/builtin/test_loader.py
b/Lib/test/test_importlib/builtin/test_loader.py
index 7e9d1b1960fdd7..2a5c2a8f39ee13 100644
--- a/Lib/test/test_importlib/builtin/test_loader.py
+++ b/Lib/test/test_importlib/builtin/test_loader.py
@@ -7,70 +7,6 @@
import unittest
import warnings
[email protected](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:
diff --git a/Lib/test/test_importlib/extension/test_loader.py
b/Lib/test/test_importlib/extension/test_loader.py
index 0dd21e079eba22..15d5a7d4752cc8 100644
--- a/Lib/test/test_importlib/extension/test_loader.py
+++ b/Lib/test/test_importlib/extension/test_loader.py
@@ -35,11 +35,6 @@ def setUp(self):
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 @@ def test_inequality(self):
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 @@ def test_module(self):
# 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 @@ def setUp(self):
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 @@ def load_module_by_name(self, fullname):
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 @@ def setUp(self):
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 @@ def load_module_by_name(self, fullname):
# 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)
diff --git a/Lib/test/test_importlib/import_/test_api.py
b/Lib/test/test_importlib/import_/test_api.py
index d6ad590b3d46a0..ea1e29a4e5f278 100644
--- a/Lib/test/test_importlib/import_/test_api.py
+++ b/Lib/test/test_importlib/import_/test_api.py
@@ -27,13 +27,6 @@ def exec_module(module):
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 @@ def test_blocked_fromlist(self):
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
diff --git a/Lib/test/test_importlib/source/test_file_loader.py
b/Lib/test/test_importlib/source/test_file_loader.py
index f35adec1a8e800..5d5d4722171a8e 100644
--- a/Lib/test/test_importlib/source/test_file_loader.py
+++ b/Lib/test/test_importlib/source/test_file_loader.py
@@ -22,7 +22,7 @@
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 @@ def setUp(self):
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 @@ def test_inequality(self):
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 @@ def import_(self, file, module_name):
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()
diff --git a/Lib/test/test_importlib/source/test_finder.py
b/Lib/test/test_importlib/source/test_finder.py
index 4de736a6bf3b2d..c33e90232b36e6 100644
--- a/Lib/test/test_importlib/source/test_finder.py
+++ b/Lib/test/test_importlib/source/test_finder.py
@@ -73,7 +73,7 @@ def run_test(self, test, create=None, *, compile_=None,
unlink=None):
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 @@ def test_module_in_package(self):
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 @@ def test_package_in_package(self):
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 @@ def test_empty_string_for_dir(self):
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')
diff --git a/Lib/test/test_importlib/source/test_source_encoding.py
b/Lib/test/test_importlib/source/test_source_encoding.py
index c09c9aa12b862e..fada07877fc125 100644
--- a/Lib/test/test_importlib/source/test_source_encoding.py
+++ b/Lib/test/test_importlib/source/test_source_encoding.py
@@ -102,19 +102,6 @@ def load(self, loader):
) = 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 @@ def load(self, loader, module_name):
) = 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()
diff --git a/Lib/test/test_importlib/test_abc.py
b/Lib/test/test_importlib/test_abc.py
index bd1540ce403ce2..8132a69d8f4e89 100644
--- a/Lib/test/test_importlib/test_abc.py
+++ b/Lib/test/test_importlib/test_abc.py
@@ -194,10 +194,6 @@ def test_create_module(self):
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 @@ def is_package(self, fullname):
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 @@ def test_get_code_source_not_found(self):
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 @@ def test_source_to_code(self):
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.
diff --git a/Lib/test/test_importlib/test_spec.py
b/Lib/test/test_importlib/test_spec.py
index aebeabaf83f75d..fef0fda101e46d 100644
--- a/Lib/test/test_importlib/test_spec.py
+++ b/Lib/test/test_importlib/test_spec.py
@@ -287,20 +287,6 @@ def exec_module(self, module):
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):
diff --git a/Misc/NEWS.d/3.14.0a6.rst b/Misc/NEWS.d/3.14.0a6.rst
index 9064402bcf71f6..cf250df5526091 100644
--- a/Misc/NEWS.d/3.14.0a6.rst
+++ b/Misc/NEWS.d/3.14.0a6.rst
@@ -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
index 00000000000000..f26d79d0c03bc8
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-02-15-39-16.gh-issue-97850.H6QKwl.rst
@@ -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.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]