Skip to content

Commit 73fb5d2

Browse files
committed
Make sure that pyfakefs is not active during pytest reporting
- pause the patching in pytest_runtest_logreport - fixes #904
1 parent 26ed458 commit 73fb5d2

File tree

5 files changed

+41
-20
lines changed

5 files changed

+41
-20
lines changed

CHANGES.md

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ The released versions correspond to PyPI releases.
33

44
## Unreleased
55

6+
### Fixes
7+
* fixes the problem that filesystem patching was still active in the pytest
8+
logreport phase (see [#904](../../issues/904))
9+
610
## [Version 5.3.0](https://pypi.python.org/pypi/pyfakefs/5.3.0) (2023-10-11)
711
Adds official support for Python 3.12.
812

pyfakefs/fake_filesystem_unittest.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@ def __init__(
628628
self._isStale = True
629629
self._dyn_patcher: Optional[DynamicPatcher] = None
630630
self._patching = False
631+
self._paused = False
631632

632633
@classmethod
633634
def clear_fs_cache(cls) -> None:
@@ -898,6 +899,7 @@ def setUp(self, doctester: Any = None) -> None:
898899
def start_patching(self) -> None:
899900
if not self._patching:
900901
self._patching = True
902+
self._paused = False
901903

902904
self.patch_modules()
903905
self.patch_functions()
@@ -975,17 +977,22 @@ def tearDown(self, doctester: Any = None):
975977
else:
976978
self.__class__.PATCHER = None
977979

978-
def stop_patching(self) -> None:
980+
def stop_patching(self, temporary=False) -> None:
979981
if self._patching:
980982
self._isStale = True
981983
self._patching = False
984+
self._paused = temporary
982985
if self._stubs:
983986
self._stubs.smart_unset_all()
984987
self.unset_defaults()
985988
if self._dyn_patcher:
986989
self._dyn_patcher.cleanup()
987990
sys.meta_path.pop(0)
988991

992+
@property
993+
def is_patching(self):
994+
return self._patching
995+
989996
def unset_defaults(self) -> None:
990997
for fct, idx, ft in self.FS_DEFARGS:
991998
new_defaults = []
@@ -1003,15 +1010,16 @@ def pause(self) -> None:
10031010
Calling pause() twice is silently ignored.
10041011
10051012
"""
1006-
self.stop_patching()
1013+
self.stop_patching(temporary=True)
10071014

10081015
def resume(self) -> None:
10091016
"""Resume the patching of the file system modules if `pause` has
10101017
been called before. After that call, all file system calls are
10111018
executed in the fake file system.
10121019
Does nothing if patching is not paused.
10131020
"""
1014-
self.start_patching()
1021+
if self._paused:
1022+
self.start_patching()
10151023

10161024

10171025
class Pause:

pyfakefs/pytest_plugin.py

+13
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,16 @@ def fs_session(request):
8080
def pytest_sessionfinish(session, exitstatus):
8181
"""Make sure that the cache is cleared before the final test shutdown."""
8282
Patcher.clear_fs_cache()
83+
84+
85+
@pytest.hookimpl(tryfirst=True)
86+
def pytest_runtest_logreport(report):
87+
"""Make sure that patching is not active during reporting."""
88+
if report.when == "call" and Patcher.PATCHER is not None:
89+
Patcher.PATCHER.pause()
90+
91+
92+
def pytest_runtest_call(item):
93+
"""Resume paused patching before test start."""
94+
if Patcher.PATCHER is not None:
95+
Patcher.PATCHER.resume()

pyfakefs/pytest_tests/pytest_module_fixture_test.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,19 @@ def use_fs(fs_module):
2020
yield fs_module
2121

2222

23+
@pytest.fixture(autouse=True)
24+
def check_patching_stopped(fs):
25+
# patching shall be paused at test end, even in module scope (see #904)
26+
yield
27+
assert not fs.patcher.is_patching
28+
29+
2330
@pytest.mark.usefixtures("fs")
24-
def test_fs_uses_fs_module():
31+
def test_fs_uses_fs_module1():
2532
# check that `fs` uses the same filesystem as `fs_module`
2633
assert os.path.exists(os.path.join("foo", "bar"))
34+
35+
36+
def test_fs_uses_fs_module2(fs):
37+
# check that testing was not stopped by the first test
38+
assert os.path.exists(os.path.join("foo", "bar"))

pyfakefs/pytest_tests/segfault_test.py

-16
This file was deleted.

0 commit comments

Comments
 (0)