From cd3dc82c7f950f7276e78377577471fd4b89b7cc Mon Sep 17 00:00:00 2001 From: mrbean-bremen Date: Tue, 28 Nov 2023 20:30:37 +0100 Subject: [PATCH] Use hookwrapper to pause patching during logreport - shall fix #904 more reliably --- CHANGES.md | 2 + pyfakefs/pytest_plugin.py | 12 +++--- pyfakefs/pytest_tests/hook_test/conftest.py | 25 ++++++++++++ .../hook_test/pytest_hook_test.py | 38 +++++++++++++++++++ .../pytest_module_fixture_test.py | 7 ---- 5 files changed, 70 insertions(+), 14 deletions(-) create mode 100644 pyfakefs/pytest_tests/hook_test/conftest.py create mode 100644 pyfakefs/pytest_tests/hook_test/pytest_hook_test.py diff --git a/CHANGES.md b/CHANGES.md index 8e0c2385..4d3e7406 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,8 @@ The released versions correspond to PyPI releases. (see [#912](../../issues/912)) * fixed result of `os.walk` with a path-like top directory (see [#915](../../issues/915)) +* properly fixed the problem that filesystem patching was still active in the pytest + logreport phase (see [#904](../../issues/904)), the previous fix was incomplete ## [Version 5.3.1](https://pypi.python.org/pypi/pyfakefs/5.3.0) (2023-11-15) Mostly a bugfix release. diff --git a/pyfakefs/pytest_plugin.py b/pyfakefs/pytest_plugin.py index 26bbd583..223ef2d4 100644 --- a/pyfakefs/pytest_plugin.py +++ b/pyfakefs/pytest_plugin.py @@ -82,14 +82,12 @@ def pytest_sessionfinish(session, exitstatus): Patcher.clear_fs_cache() -@pytest.hookimpl(tryfirst=True) +@pytest.hookimpl(hookwrapper=True, tryfirst=True) def pytest_runtest_logreport(report): """Make sure that patching is not active during reporting.""" - if report.when == "call" and Patcher.PATCHER is not None: + pause = Patcher.PATCHER is not None and report.when == "call" + if pause: Patcher.PATCHER.pause() - - -def pytest_runtest_call(item): - """Resume paused patching before test start.""" - if Patcher.PATCHER is not None: + yield + if pause: Patcher.PATCHER.resume() diff --git a/pyfakefs/pytest_tests/hook_test/conftest.py b/pyfakefs/pytest_tests/hook_test/conftest.py new file mode 100644 index 00000000..615d1d2b --- /dev/null +++ b/pyfakefs/pytest_tests/hook_test/conftest.py @@ -0,0 +1,25 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from pathlib import Path + +import pytest + + +# Used for testing paused patching during reporting. + + +@pytest.hookimpl +def pytest_runtest_logreport(report): + if report.when == "call": + report_path = Path(__file__).parent / "report.txt" + with open(report_path, "w") as f: + f.write("Test") diff --git a/pyfakefs/pytest_tests/hook_test/pytest_hook_test.py b/pyfakefs/pytest_tests/hook_test/pytest_hook_test.py new file mode 100644 index 00000000..c3388279 --- /dev/null +++ b/pyfakefs/pytest_tests/hook_test/pytest_hook_test.py @@ -0,0 +1,38 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from pathlib import Path + +import pytest + + +@pytest.fixture +def report_path(): + yield Path(__file__).parent / "report.txt" + + +def test_1(fs): + pass + + +def test_2_report_in_real_fs(report_path): + print("test_2_report_in_real_fs") + assert report_path.exists() + report_path.unlink() + + +def test_3(fs): + pass + + +def test_4_report_in_real_fs(report_path): + assert report_path.exists() + report_path.unlink() diff --git a/pyfakefs/pytest_tests/pytest_module_fixture_test.py b/pyfakefs/pytest_tests/pytest_module_fixture_test.py index d4eeda66..3aa9bcb5 100644 --- a/pyfakefs/pytest_tests/pytest_module_fixture_test.py +++ b/pyfakefs/pytest_tests/pytest_module_fixture_test.py @@ -20,13 +20,6 @@ def use_fs(fs_module): yield fs_module -@pytest.fixture(autouse=True) -def check_patching_stopped(fs): - # patching shall be paused at test end, even in module scope (see #904) - yield - assert not fs.patcher.is_patching - - @pytest.mark.usefixtures("fs") def test_fs_uses_fs_module1(): # check that `fs` uses the same filesystem as `fs_module`