Support the importlib.resources files API in rewritten files (#9173)
This commit is contained in:
parent
e84ba80301
commit
3407fe63e2
|
@ -0,0 +1 @@
|
||||||
|
Support for the ``files`` API from ``importlib.resources`` within rewritten files.
|
|
@ -64,7 +64,7 @@ class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.fnpats = ["test_*.py", "*_test.py"]
|
self.fnpats = ["test_*.py", "*_test.py"]
|
||||||
self.session: Optional[Session] = None
|
self.session: Optional[Session] = None
|
||||||
self._rewritten_names: Set[str] = set()
|
self._rewritten_names: Dict[str, Path] = {}
|
||||||
self._must_rewrite: Set[str] = set()
|
self._must_rewrite: Set[str] = set()
|
||||||
# flag to guard against trying to rewrite a pyc file while we are already writing another pyc file,
|
# flag to guard against trying to rewrite a pyc file while we are already writing another pyc file,
|
||||||
# which might result in infinite recursion (#3506)
|
# which might result in infinite recursion (#3506)
|
||||||
|
@ -134,7 +134,7 @@ class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader)
|
||||||
fn = Path(module.__spec__.origin)
|
fn = Path(module.__spec__.origin)
|
||||||
state = self.config.stash[assertstate_key]
|
state = self.config.stash[assertstate_key]
|
||||||
|
|
||||||
self._rewritten_names.add(module.__name__)
|
self._rewritten_names[module.__name__] = fn
|
||||||
|
|
||||||
# The requested module looks like a test file, so rewrite it. This is
|
# The requested module looks like a test file, so rewrite it. This is
|
||||||
# the most magical part of the process: load the source, rewrite the
|
# the most magical part of the process: load the source, rewrite the
|
||||||
|
@ -276,6 +276,14 @@ class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader)
|
||||||
with open(pathname, "rb") as f:
|
with open(pathname, "rb") as f:
|
||||||
return f.read()
|
return f.read()
|
||||||
|
|
||||||
|
if sys.version_info >= (3, 9):
|
||||||
|
|
||||||
|
def get_resource_reader(self, name: str) -> importlib.abc.TraversableResources: # type: ignore
|
||||||
|
from types import SimpleNamespace
|
||||||
|
from importlib.readers import FileReader
|
||||||
|
|
||||||
|
return FileReader(SimpleNamespace(path=self._rewritten_names[name]))
|
||||||
|
|
||||||
|
|
||||||
def _write_pyc_fp(
|
def _write_pyc_fp(
|
||||||
fp: IO[bytes], source_stat: os.stat_result, co: types.CodeType
|
fp: IO[bytes], source_stat: os.stat_result, co: types.CodeType
|
||||||
|
|
|
@ -795,6 +795,35 @@ class TestRewriteOnImport:
|
||||||
)
|
)
|
||||||
assert pytester.runpytest().ret == ExitCode.NO_TESTS_COLLECTED
|
assert pytester.runpytest().ret == ExitCode.NO_TESTS_COLLECTED
|
||||||
|
|
||||||
|
@pytest.mark.skipif(
|
||||||
|
sys.version_info < (3, 9),
|
||||||
|
reason="importlib.resources.files was introduced in 3.9",
|
||||||
|
)
|
||||||
|
def test_load_resource_via_files_with_rewrite(self, pytester: Pytester) -> None:
|
||||||
|
example = pytester.path.joinpath("demo") / "example"
|
||||||
|
init = pytester.path.joinpath("demo") / "__init__.py"
|
||||||
|
pytester.makepyfile(
|
||||||
|
**{
|
||||||
|
"demo/__init__.py": """
|
||||||
|
from importlib.resources import files
|
||||||
|
|
||||||
|
def load():
|
||||||
|
return files(__name__)
|
||||||
|
""",
|
||||||
|
"test_load": f"""
|
||||||
|
pytest_plugins = ["demo"]
|
||||||
|
|
||||||
|
def test_load():
|
||||||
|
from demo import load
|
||||||
|
found = {{str(i) for i in load().iterdir() if i.name != "__pycache__"}}
|
||||||
|
assert found == {{{str(example)!r}, {str(init)!r}}}
|
||||||
|
""",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
example.mkdir()
|
||||||
|
|
||||||
|
assert pytester.runpytest("-vv").ret == ExitCode.OK
|
||||||
|
|
||||||
def test_readonly(self, pytester: Pytester) -> None:
|
def test_readonly(self, pytester: Pytester) -> None:
|
||||||
sub = pytester.mkdir("testing")
|
sub = pytester.mkdir("testing")
|
||||||
sub.joinpath("test_readonly.py").write_bytes(
|
sub.joinpath("test_readonly.py").write_bytes(
|
||||||
|
|
Loading…
Reference in New Issue