]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-123085: Fix issue in inferred caller when resource package has no source...
authorJason R. Coombs <jaraco@jaraco.com>
Fri, 15 Aug 2025 14:21:16 +0000 (07:21 -0700)
committerGitHub <noreply@github.com>
Fri, 15 Aug 2025 14:21:16 +0000 (14:21 +0000)
Lib/importlib/resources/_common.py
Lib/test/test_importlib/resources/test_files.py
Misc/NEWS.d/next/Library/2024-08-17-08-17-20.gh-issue-123085.7Io2yH.rst [new file with mode: 0644]

index 171a7f29249943849ab987278adf921dc1ec0a0d..cae4699f410b3a7e477e34101447db6a8077e275 100644 (file)
@@ -93,12 +93,13 @@ def _infer_caller():
     """
 
     def is_this_file(frame_info):
-        return frame_info.filename == __file__
+        return frame_info.filename == stack[0].filename
 
     def is_wrapper(frame_info):
         return frame_info.function == 'wrapper'
 
-    not_this_file = itertools.filterfalse(is_this_file, inspect.stack())
+    stack = inspect.stack()
+    not_this_file = itertools.filterfalse(is_this_file, stack)
     # also exclude 'wrapper' due to singledispatch in the call stack
     callers = itertools.filterfalse(is_wrapper, not_this_file)
     return next(callers).frame
index ef7b57959974ee3b648a44b6f6a764c8c5e3a4f2..f903d3bba85ebc9eafcb64a9052f7c4ca2d4256c 100644 (file)
@@ -1,3 +1,7 @@
+import os
+import pathlib
+import py_compile
+import shutil
 import textwrap
 import unittest
 import warnings
@@ -7,6 +11,7 @@ import contextlib
 from importlib import resources
 from importlib.resources.abc import Traversable
 from . import util
+from test.support import os_helper, import_helper
 
 
 @contextlib.contextmanager
@@ -117,8 +122,8 @@ class ModuleFilesZipTests(DirectSpec, util.ZipSetup, ModulesFiles, unittest.Test
 
 class ImplicitContextFiles:
     set_val = textwrap.dedent(
-        """
-        import importlib.resources as res
+        f"""
+        import {resources.__name__} as res
         val = res.files().joinpath('res.txt').read_text(encoding='utf-8')
         """
     )
@@ -128,6 +133,10 @@ class ImplicitContextFiles:
             'submod.py': set_val,
             'res.txt': 'resources are the best',
         },
+        'frozenpkg': {
+            '__init__.py': set_val.replace(resources.__name__, 'c_resources'),
+            'res.txt': 'resources are the best',
+        },
     }
 
     def test_implicit_files_package(self):
@@ -142,6 +151,32 @@ class ImplicitContextFiles:
         """
         assert importlib.import_module('somepkg.submod').val == 'resources are the best'
 
+    def _compile_importlib(self):
+        """
+        Make a compiled-only copy of the importlib resources package.
+        """
+        bin_site = self.fixtures.enter_context(os_helper.temp_dir())
+        c_resources = pathlib.Path(bin_site, 'c_resources')
+        sources = pathlib.Path(resources.__file__).parent
+        shutil.copytree(sources, c_resources, ignore=lambda *_: ['__pycache__'])
+
+        for dirpath, _, filenames in os.walk(c_resources):
+            for filename in filenames:
+                source_path = pathlib.Path(dirpath) / filename
+                cfile = source_path.with_suffix('.pyc')
+                py_compile.compile(source_path, cfile)
+                pathlib.Path.unlink(source_path)
+        self.fixtures.enter_context(import_helper.DirsOnSysPath(bin_site))
+
+    def test_implicit_files_with_compiled_importlib(self):
+        """
+        Caller detection works for compiled-only resources module.
+
+        python/cpython#123085
+        """
+        self._compile_importlib()
+        assert importlib.import_module('frozenpkg').val == 'resources are the best'
+
 
 class ImplicitContextFilesDiskTests(
     DirectSpec, util.DiskSetup, ImplicitContextFiles, unittest.TestCase
diff --git a/Misc/NEWS.d/next/Library/2024-08-17-08-17-20.gh-issue-123085.7Io2yH.rst b/Misc/NEWS.d/next/Library/2024-08-17-08-17-20.gh-issue-123085.7Io2yH.rst
new file mode 100644 (file)
index 0000000..2e09401
--- /dev/null
@@ -0,0 +1,3 @@
+In a bare call to :func:`importlib.resources.files`, ensure the caller's
+frame is properly detected when ``importlib.resources`` is itself available
+as a compiled module only (no source).