From 7a33c7a8d8b30a1125538a328a234a5e1faaad0b Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Thu, 8 May 2025 20:53:07 +0800 Subject: [PATCH 1/7] Remove deprecated `zipimport.zipimporter.load_module` --- Doc/deprecations/pending-removal-in-3.15.rst | 6 --- Doc/library/zipimport.rst | 11 ----- Doc/whatsnew/3.15.rst | 9 ++-- Lib/test/test_zipimport.py | 19 -------- Lib/zipimport.py | 46 ------------------- Misc/NEWS.d/3.14.0a6.rst | 2 +- ...-05-08-20-45-35.gh-issue-133656.cxZODA.rst | 2 + 7 files changed, 9 insertions(+), 86 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-05-08-20-45-35.gh-issue-133656.cxZODA.rst diff --git a/Doc/deprecations/pending-removal-in-3.15.rst b/Doc/deprecations/pending-removal-in-3.15.rst index 7b32275ad86760..edea692eadcfe9 100644 --- a/Doc/deprecations/pending-removal-in-3.15.rst +++ b/Doc/deprecations/pending-removal-in-3.15.rst @@ -96,9 +96,3 @@ Pending removal in Python 3.15 and :meth:`~wave.Wave_read.getmarkers` methods of the :class:`~wave.Wave_read` and :class:`~wave.Wave_write` classes have been deprecated since Python 3.13. - -* :mod:`zipimport`: - - * :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`.) 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 5e9922069aa42c..2885790fea3fc1 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -115,10 +115,13 @@ Deprecated Removed ======= -module_name ------------ +zipimport +--------- -* TODO +* Remove deprecated :meth:`!zipimport.zipimporter.load_module`. + They had previously raised a :exc:`DeprecationWarning` since Python 3.10. + 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 1f288c8b45d589..52e8d5db94bc0d 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -556,13 +556,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) @@ -675,11 +668,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) @@ -1069,9 +1057,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 +1067,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 bafd8845de6973..3ecca693cb894e 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. From 02919a6e127d9deba5b912c2605f5e7179a42560 Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Sat, 10 May 2025 09:01:35 +0800 Subject: [PATCH 2/7] Fix test failure --- Doc/whatsnew/3.15.rst | 1 - Lib/test/test_zipimport.py | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 2885790fea3fc1..59d9a4694680c8 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -119,7 +119,6 @@ zipimport --------- * Remove deprecated :meth:`!zipimport.zipimporter.load_module`. - They had previously raised a :exc:`DeprecationWarning` since Python 3.10. Use :meth:`zipimport.zipimporter.exec_module` instead. (Contributed by Jiahao Li in :gh:`133656`.) diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index 52e8d5db94bc0d..19de450a7246be 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -552,6 +552,8 @@ def testZipImporterMethods(self): "spam" + pyc_ext: test_pyc} self.makeZip(files, file_comment=b"spam") + sys.path.insert(0, TEMP_ZIP) + zi = zipimport.zipimporter(TEMP_ZIP) self.assertEqual(zi.archive, TEMP_ZIP) self.assertTrue(zi.is_package(TESTPACK)) @@ -664,6 +666,8 @@ def testZipImporterMethodsInSubDirectory(self): packdir2 + TESTMOD + pyc_ext: test_pyc} self.makeZip(files, file_comment=b"eggs") + sys.path.insert(0, TEMP_ZIP + os.sep + TESTPACK) + zi = zipimport.zipimporter(TEMP_ZIP + os.sep + packdir) self.assertEqual(zi.archive, TEMP_ZIP) self.assertEqual(zi.prefix, packdir) From ead7345683428fa87532e39787e002b885a7723f Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Sun, 11 May 2025 20:21:49 +0800 Subject: [PATCH 3/7] Update pending-removal-in-3.15.rst --- Doc/deprecations/pending-removal-in-3.15.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Doc/deprecations/pending-removal-in-3.15.rst b/Doc/deprecations/pending-removal-in-3.15.rst index 26e139aedc3049..1db00d5916fd0c 100644 --- a/Doc/deprecations/pending-removal-in-3.15.rst +++ b/Doc/deprecations/pending-removal-in-3.15.rst @@ -103,3 +103,10 @@ Pending removal in Python 3.15 and :meth:`~wave.Wave_read.getmarkers` methods of the :class:`~wave.Wave_read` and :class:`~wave.Wave_write` classes have been deprecated since Python 3.13. + +* :mod:`zipimport` + + * :meth:`!zipimport.zipimporter.load_module` has been deprecated since + Python 3.10. Use :meth:`~zipimport.zipimporter.exec_module` instead. + (:gh:`125746`.) + From 963343d36ef05a107faf37802df149fbe896e520 Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Sun, 11 May 2025 20:22:47 +0800 Subject: [PATCH 4/7] Update pending-removal-in-3.15.rst --- Doc/deprecations/pending-removal-in-3.15.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Doc/deprecations/pending-removal-in-3.15.rst b/Doc/deprecations/pending-removal-in-3.15.rst index 1db00d5916fd0c..54e7d305929847 100644 --- a/Doc/deprecations/pending-removal-in-3.15.rst +++ b/Doc/deprecations/pending-removal-in-3.15.rst @@ -104,9 +104,8 @@ Pending removal in Python 3.15 the :class:`~wave.Wave_read` and :class:`~wave.Wave_write` classes have been deprecated since Python 3.13. -* :mod:`zipimport` +* :mod:`zipimport`: * :meth:`!zipimport.zipimporter.load_module` has been deprecated since Python 3.10. Use :meth:`~zipimport.zipimporter.exec_module` instead. (:gh:`125746`.) - From 0edaa29ae1c3db2e3acb3d923cbfe4460b61cfef Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Sun, 6 Jul 2025 15:15:15 +0800 Subject: [PATCH 5/7] Update 3.15.rst --- Doc/whatsnew/3.15.rst | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index c289e8955ed8f3..8667bf071f707c 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -290,7 +290,25 @@ typing or ``TD = TypedDict("TD", {})`` instead. (Contributed by Bénédikt Tran in :gh:`133823`.) - + +unittest +-------- + +* Lets users specify formatter in TestCase.assertLogs. + :func:`unittest.TestCase.assertLogs` will now accept a formatter + to control how messages are formatted. + (Contributed by Garry Cairns in :gh:`134567`.) + + +wave +---- + +* Removed the ``getmark()``, ``setmark()`` and ``getmarkers()`` methods + of the :class:`~wave.Wave_read` and :class:`~wave.Wave_write` classes, + which were deprecated since Python 3.13. + (Contributed by Bénédikt Tran in :gh:`133873`.) + + zipimport --------- From 5616e27403799b481f44f96c3a21336fd03941c9 Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Sun, 6 Jul 2025 15:19:30 +0800 Subject: [PATCH 6/7] Resolved conflict --- Lib/test/test_zipimport.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index a7be367b9f7995..b368b771572fec 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 From 6207b716f49b50db4945d59b3008654b096efd57 Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Mon, 11 Aug 2025 21:16:47 +0800 Subject: [PATCH 7/7] move to before the first full import request --- Lib/test/test_zipimport.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index b368b771572fec..d359f0b0fbb577 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -551,8 +551,6 @@ def testZipImporterMethods(self): "spam" + pyc_ext: test_pyc} self.makeZip(files, file_comment=b"spam") - sys.path.insert(0, TEMP_ZIP) - zi = zipimport.zipimporter(TEMP_ZIP) self.assertEqual(zi.archive, TEMP_ZIP) self.assertTrue(zi.is_package(TESTPACK)) @@ -571,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) @@ -665,8 +665,6 @@ def testZipImporterMethodsInSubDirectory(self): packdir2 + TESTMOD + pyc_ext: test_pyc} self.makeZip(files, file_comment=b"eggs") - sys.path.insert(0, TEMP_ZIP + os.sep + TESTPACK) - zi = zipimport.zipimporter(TEMP_ZIP + os.sep + packdir) self.assertEqual(zi.archive, TEMP_ZIP) self.assertEqual(zi.prefix, packdir) @@ -693,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))