Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue in inferred caller when resourcse package has no source. #314

Merged
merged 7 commits into from
Aug 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions importlib_resources/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 37 additions & 2 deletions importlib_resources/tests/test_files.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import os
import pathlib
import py_compile
import shutil
import textwrap
import unittest
import warnings
Expand All @@ -7,6 +11,7 @@
import importlib_resources as resources
from ..abc import Traversable
from . import util
from .compat.py39 import os_helper, import_helper


@contextlib.contextmanager
Expand Down Expand Up @@ -97,8 +102,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')
"""
)
Expand All @@ -108,6 +113,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):
Expand All @@ -122,6 +131,32 @@ def test_implicit_files_submodule(self):
"""
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
Expand Down
1 change: 1 addition & 0 deletions newsfragments/+0f77c990.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
When inferring the caller in ``files()`` correctly detect one's own module even when the resources package source is not present. (python/cpython#123085)
Loading