mirror of https://github.com/python/cpython
gh-123085: Fix issue in inferred caller when resources package has no source (#123102)
gh-123085: Fix issue in inferred caller when resources package has no source. From importlib_resources 6.4.3 (python/importlib_resources#314).
This commit is contained in:
parent
8145ebea58
commit
a53812df12
|
@ -93,12 +93,13 @@ def _infer_caller():
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def is_this_file(frame_info):
|
def is_this_file(frame_info):
|
||||||
return frame_info.filename == __file__
|
return frame_info.filename == stack[0].filename
|
||||||
|
|
||||||
def is_wrapper(frame_info):
|
def is_wrapper(frame_info):
|
||||||
return frame_info.function == 'wrapper'
|
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
|
# also exclude 'wrapper' due to singledispatch in the call stack
|
||||||
callers = itertools.filterfalse(is_wrapper, not_this_file)
|
callers = itertools.filterfalse(is_wrapper, not_this_file)
|
||||||
return next(callers).frame
|
return next(callers).frame
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
import os
|
||||||
|
import pathlib
|
||||||
|
import py_compile
|
||||||
|
import shutil
|
||||||
import textwrap
|
import textwrap
|
||||||
import unittest
|
import unittest
|
||||||
import warnings
|
import warnings
|
||||||
|
@ -7,6 +11,7 @@ import contextlib
|
||||||
from importlib import resources
|
from importlib import resources
|
||||||
from importlib.resources.abc import Traversable
|
from importlib.resources.abc import Traversable
|
||||||
from . import util
|
from . import util
|
||||||
|
from test.support import os_helper, import_helper
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
|
@ -97,8 +102,8 @@ class ModuleFilesZipTests(DirectSpec, util.ZipSetup, ModulesFiles, unittest.Test
|
||||||
|
|
||||||
class ImplicitContextFiles:
|
class ImplicitContextFiles:
|
||||||
set_val = textwrap.dedent(
|
set_val = textwrap.dedent(
|
||||||
"""
|
f"""
|
||||||
import importlib.resources as res
|
import {resources.__name__} as res
|
||||||
val = res.files().joinpath('res.txt').read_text(encoding='utf-8')
|
val = res.files().joinpath('res.txt').read_text(encoding='utf-8')
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
@ -108,6 +113,10 @@ class ImplicitContextFiles:
|
||||||
'submod.py': set_val,
|
'submod.py': set_val,
|
||||||
'res.txt': 'resources are the best',
|
'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):
|
def test_implicit_files_package(self):
|
||||||
|
@ -122,6 +131,32 @@ class ImplicitContextFiles:
|
||||||
"""
|
"""
|
||||||
assert importlib.import_module('somepkg.submod').val == 'resources are the best'
|
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(
|
class ImplicitContextFilesDiskTests(
|
||||||
DirectSpec, util.DiskSetup, ImplicitContextFiles, unittest.TestCase
|
DirectSpec, util.DiskSetup, ImplicitContextFiles, unittest.TestCase
|
||||||
|
|
|
@ -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).
|
Loading…
Reference in New Issue