From 0d5505decbc703149bbfbbba8d1fa9f62025e0a9 Mon Sep 17 00:00:00 2001 From: harjoth Date: Wed, 15 Jul 2026 22:15:13 -0700 Subject: [PATCH] gh-141276: Avoid compiling zipimport source in get_filename --- Lib/test/test_zipimport.py | 18 ++++++++++++++++++ Lib/zipimport.py | 11 +++++++---- ...6-07-15-21-45-33.gh-issue-141276.xH7qP2.rst | 2 ++ 3 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-07-15-21-45-33.gh-issue-141276.xH7qP2.rst diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index 76cd85709a63af8..4ed86cf48263bf1 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -9,6 +9,7 @@ import time import unittest import unittest.mock +import warnings from test import support from test.support import import_helper @@ -229,6 +230,23 @@ def testPy(self): files = {TESTMOD + ".py": test_src} self.doTest(".py", files, TESTMOD) + def test_syntax_warning(self): + files = {TESTMOD + ".py": "x = 1 is 1\n"} + self.makeZip(files) + zi = zipimport.zipimporter(TEMP_ZIP) + + with warnings.catch_warnings(record=True) as caught: + warnings.simplefilter("always", SyntaxWarning) + spec = zi.find_spec(TESTMOD) + self.assertIsNotNone(spec) + self.assertEqual(caught, []) + + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + + self.assertEqual(len(caught), 1) + self.assertIsInstance(caught[0].message, SyntaxWarning) + def testPyc(self): files = {TESTMOD + pyc_ext: test_pyc} self.doTest(pyc_ext, files, TESTMOD) diff --git a/Lib/zipimport.py b/Lib/zipimport.py index 19279d1c2bea368..f7b6ada3981beaa 100644 --- a/Lib/zipimport.py +++ b/Lib/zipimport.py @@ -163,7 +163,8 @@ def get_filename(self, fullname): """ # Deciding the filename requires working out where the code # would come from if the module was actually loaded - code, ispackage, modpath = _get_module_code(self, fullname) + _, _, modpath = _get_module_code( + self, fullname, compile_source=False) return modpath @@ -793,9 +794,9 @@ def _get_pyc_source(self, path): return _get_data(self.archive, toc_entry) -# Get the code object associated with the module specified by -# 'fullname'. -def _get_module_code(self, fullname): +# Get the code object associated with the module specified by 'fullname'. +# If compile_source is false, return None for source code without compiling it. +def _get_module_code(self, fullname, *, compile_source=True): path = _get_module_path(self, fullname) import_error = None for suffix, isbytecode, ispackage in _zip_searchorder: @@ -815,6 +816,8 @@ def _get_module_code(self, fullname): except ImportError as exc: import_error = exc else: + if not compile_source: + return None, ispackage, modpath code = _compile_source(modpath, data, fullname) if code is None: # bad magic number or non-matching mtime diff --git a/Misc/NEWS.d/next/Library/2026-07-15-21-45-33.gh-issue-141276.xH7qP2.rst b/Misc/NEWS.d/next/Library/2026-07-15-21-45-33.gh-issue-141276.xH7qP2.rst new file mode 100644 index 000000000000000..6bbb7ce6d8a6cc8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-15-21-45-33.gh-issue-141276.xH7qP2.rst @@ -0,0 +1,2 @@ +Fix duplicate :exc:`SyntaxWarning` messages when importing source modules +from ZIP archives.