Skip to content

Commit d712ece

Browse files
authored
[3.12] gh-123085: Fix issue in inferred caller when resources package has no source (GH-123102) (#124021)
gh-123085: Fix issue in inferred caller when resources package has no source. From importlib_resources 6.4.3 (python/importlib_resourcesGH-314). (cherry picked from commit a53812d)
1 parent 09f7d88 commit d712ece

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

Lib/importlib/resources/_common.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,13 @@ def _infer_caller():
9393
"""
9494

9595
def is_this_file(frame_info):
96-
return frame_info.filename == __file__
96+
return frame_info.filename == stack[0].filename
9797

9898
def is_wrapper(frame_info):
9999
return frame_info.function == 'wrapper'
100100

101-
not_this_file = itertools.filterfalse(is_this_file, inspect.stack())
101+
stack = inspect.stack()
102+
not_this_file = itertools.filterfalse(is_this_file, stack)
102103
# also exclude 'wrapper' due to singledispatch in the call stack
103104
callers = itertools.filterfalse(is_wrapper, not_this_file)
104105
return next(callers).frame

Lib/test/test_importlib/resources/test_files.py

+44-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
import typing
2+
import os
3+
import pathlib
4+
import py_compile
5+
import shutil
26
import textwrap
37
import unittest
48
import warnings
@@ -10,8 +14,7 @@
1014
from . import data01
1115
from . import util
1216
from . import _path
13-
from test.support import os_helper
14-
from test.support import import_helper
17+
from test.support import os_helper, import_helper
1518

1619

1720
@contextlib.contextmanager
@@ -144,6 +147,45 @@ def create_zip_from_directory(source_dir, zip_filename):
144147
self.fixtures.enter_context(import_helper.DirsOnSysPath(zip_file))
145148
assert importlib.import_module('somepkg.submod').val == 'resources are the best'
146149

150+
def _compile_importlib(self):
151+
"""
152+
Make a compiled-only copy of the importlib resources package.
153+
"""
154+
bin_site = self.fixtures.enter_context(os_helper.temp_dir())
155+
c_resources = pathlib.Path(bin_site, 'c_resources')
156+
sources = pathlib.Path(resources.__file__).parent
157+
shutil.copytree(sources, c_resources, ignore=lambda *_: ['__pycache__'])
158+
159+
for dirpath, _, filenames in os.walk(c_resources):
160+
for filename in filenames:
161+
source_path = pathlib.Path(dirpath) / filename
162+
cfile = source_path.with_suffix('.pyc')
163+
py_compile.compile(source_path, cfile)
164+
pathlib.Path.unlink(source_path)
165+
self.fixtures.enter_context(import_helper.DirsOnSysPath(bin_site))
166+
167+
def test_implicit_files_with_compiled_importlib(self):
168+
"""
169+
Caller detection works for compiled-only resources module.
170+
171+
python/cpython#123085
172+
"""
173+
set_val = textwrap.dedent(
174+
f"""
175+
import {resources.__name__} as res
176+
val = res.files().joinpath('res.txt').read_text(encoding='utf-8')
177+
"""
178+
)
179+
spec = {
180+
'frozenpkg': {
181+
'__init__.py': set_val.replace(resources.__name__, 'c_resources'),
182+
'res.txt': 'resources are the best',
183+
},
184+
}
185+
_path.build(spec, self.site_dir)
186+
self._compile_importlib()
187+
assert importlib.import_module('frozenpkg').val == 'resources are the best'
188+
147189

148190
if __name__ == '__main__':
149191
unittest.main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
In a bare call to :func:`importlib.resources.files`, ensure the caller's
2+
frame is properly detected when ``importlib.resources`` is itself available
3+
as a compiled module only (no source).

0 commit comments

Comments
 (0)