diff --git a/Doc/deprecations/pending-removal-in-3.15.rst b/Doc/deprecations/pending-removal-in-3.15.rst index c5ca599bb04a6f..c48b9f8f1b0307 100644 --- a/Doc/deprecations/pending-removal-in-3.15.rst +++ b/Doc/deprecations/pending-removal-in-3.15.rst @@ -107,6 +107,6 @@ Pending removal in Python 3.15 * :mod:`zipimport`: - * :meth:`~zipimport.zipimporter.load_module` has been deprecated since + * :meth:`!zipimport.zipimporter.load_module` has been deprecated since Python 3.10. Use :meth:`~zipimport.zipimporter.exec_module` instead. - (Contributed by Jiahao Li in :gh:`125746`.) + (:gh:`125746`.) diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst index cd76f29a556939..19ae12bd4050cf 100644 --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -142,17 +142,6 @@ zipimporter Objects :exc:`ZipImportError` if the module couldn't be found. - .. method:: load_module(fullname) - - Load the module specified by *fullname*. *fullname* must be the fully - qualified (dotted) module name. Returns the imported module on success, - raises :exc:`ZipImportError` on failure. - - .. deprecated-removed:: 3.10 3.15 - - Use :meth:`exec_module` instead. - - .. method:: invalidate_caches() Clear out the internal cache of information about files found within diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 706a816f888b30..8667bf071f707c 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -309,6 +309,14 @@ wave (Contributed by Bénédikt Tran in :gh:`133873`.) +zipimport +--------- + +* Remove deprecated :meth:`!zipimport.zipimporter.load_module`. + Use :meth:`zipimport.zipimporter.exec_module` instead. + (Contributed by Jiahao Li in :gh:`133656`.) + + Porting to Python 3.15 ====================== diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index b5b4acf5f850be..d359f0b0fbb577 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -9,7 +9,6 @@ import time import unittest import unittest.mock -import warnings from test import support from test.support import import_helper @@ -556,13 +555,6 @@ def testZipImporterMethods(self): self.assertEqual(zi.archive, TEMP_ZIP) self.assertTrue(zi.is_package(TESTPACK)) - # PEP 302 - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - - mod = zi.load_module(TESTPACK) - self.assertEqual(zi.get_filename(TESTPACK), mod.__file__) - # PEP 451 spec = zi.find_spec('spam') self.assertIsNotNone(spec) @@ -577,6 +569,8 @@ def testZipImporterMethods(self): spec.loader.exec_module(mod) self.assertEqual(zi.get_filename(TESTPACK), mod.__file__) + sys.path.insert(0, TEMP_ZIP) + existing_pack_path = importlib.import_module(TESTPACK).__path__[0] expected_path_path = os.path.join(TEMP_ZIP, TESTPACK) self.assertEqual(existing_pack_path, expected_path_path) @@ -675,11 +669,6 @@ def testZipImporterMethodsInSubDirectory(self): self.assertEqual(zi.archive, TEMP_ZIP) self.assertEqual(zi.prefix, packdir) self.assertTrue(zi.is_package(TESTPACK2)) - # PEP 302 - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - mod = zi.load_module(TESTPACK2) - self.assertEqual(zi.get_filename(TESTPACK2), mod.__file__) # PEP 451 spec = zi.find_spec(TESTPACK2) mod = importlib.util.module_from_spec(spec) @@ -702,9 +691,12 @@ def testZipImporterMethodsInSubDirectory(self): self.assertEqual( spec.loader.get_filename(TESTMOD), load_mod.__file__) + sys.path.insert(0, TEMP_ZIP + os.sep + TESTPACK) + mod_path = TESTPACK2 + os.sep + TESTMOD mod_name = module_path_to_dotted_name(mod_path) mod = importlib.import_module(mod_name) + self.assertTrue(mod_name in sys.modules) self.assertIsNone(zi.get_source(TESTPACK2)) self.assertIsNone(zi.get_source(mod_path)) @@ -1069,9 +1061,6 @@ def _testBogusZipFile(self): z = zipimport.zipimporter(TESTMOD) try: - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - self.assertRaises(TypeError, z.load_module, None) self.assertRaises(TypeError, z.find_module, None) self.assertRaises(TypeError, z.find_spec, None) self.assertRaises(TypeError, z.exec_module, None) @@ -1082,10 +1071,6 @@ def _testBogusZipFile(self): error = zipimport.ZipImportError self.assertIsNone(z.find_spec('abc')) - - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - self.assertRaises(error, z.load_module, 'abc') self.assertRaises(error, z.get_code, 'abc') self.assertRaises(OSError, z.get_data, 'abc') self.assertRaises(error, z.get_source, 'abc') diff --git a/Lib/zipimport.py b/Lib/zipimport.py index 444c9dd11d8672..35820844b2561e 100644 --- a/Lib/zipimport.py +++ b/Lib/zipimport.py @@ -210,52 +210,6 @@ def is_package(self, fullname): return mi - # Load and return the module named by 'fullname'. - def load_module(self, fullname): - """load_module(fullname) -> module. - - Load the module specified by 'fullname'. 'fullname' must be the - fully qualified (dotted) module name. It returns the imported - module, or raises ZipImportError if it could not be imported. - - Deprecated since Python 3.10. Use exec_module() instead. - """ - import warnings - warnings._deprecated("zipimport.zipimporter.load_module", - f"{warnings._DEPRECATED_MSG}; " - "use zipimport.zipimporter.exec_module() instead", - remove=(3, 15)) - code, ispackage, modpath = _get_module_code(self, fullname) - mod = sys.modules.get(fullname) - if mod is None or not isinstance(mod, _module_type): - mod = _module_type(fullname) - sys.modules[fullname] = mod - mod.__loader__ = self - - try: - if ispackage: - # add __path__ to the module *before* the code gets - # executed - path = _get_module_path(self, fullname) - fullpath = _bootstrap_external._path_join(self.archive, path) - mod.__path__ = [fullpath] - - if not hasattr(mod, '__builtins__'): - mod.__builtins__ = __builtins__ - _bootstrap_external._fix_up_module(mod.__dict__, fullname, modpath) - exec(code, mod.__dict__) - except: - del sys.modules[fullname] - raise - - try: - mod = sys.modules[fullname] - except KeyError: - raise ImportError(f'Loaded module {fullname!r} not found in sys.modules') - _bootstrap._verbose_message('import {} # loaded from Zip {}', fullname, modpath) - return mod - - def get_resource_reader(self, fullname): """Return the ResourceReader for a module in a zip file.""" from importlib.readers import ZipReader diff --git a/Misc/NEWS.d/3.14.0a6.rst b/Misc/NEWS.d/3.14.0a6.rst index d8840b6f283e76..9064402bcf71f6 100644 --- a/Misc/NEWS.d/3.14.0a6.rst +++ b/Misc/NEWS.d/3.14.0a6.rst @@ -758,7 +758,7 @@ Patch by Semyon Moroz. .. nonce: wDLTay .. section: Library -Delay deprecated :meth:`zipimport.zipimporter.load_module` removal time to +Delay deprecated :meth:`!zipimport.zipimporter.load_module` removal time to 3.15. Use :meth:`zipimport.zipimporter.exec_module` instead. .. diff --git a/Misc/NEWS.d/next/Library/2025-05-08-20-45-35.gh-issue-133656.cxZODA.rst b/Misc/NEWS.d/next/Library/2025-05-08-20-45-35.gh-issue-133656.cxZODA.rst new file mode 100644 index 00000000000000..720370d21c10fd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-05-08-20-45-35.gh-issue-133656.cxZODA.rst @@ -0,0 +1,2 @@ +Remove deprecated :meth:`!zipimport.zipimporter.load_module`. Use +:meth:`zipimport.zipimporter.exec_module` instead.