From 6bc3162256acc9364a096ba1d58883c9cb599ce5 Mon Sep 17 00:00:00 2001 From: mrbean-bremen Date: Mon, 11 Jul 2022 18:31:30 +0200 Subject: [PATCH] Overwrite instance check for PathLibPathModule (#685) - fixes #666 without the need to skip _pytest.pathlib patching - add module and session scoped fs fixtures - fixes #684 --- CHANGES.md | 8 ++++++ docs/usage.rst | 4 +++ pyfakefs/fake_pathlib.py | 5 ++++ pyfakefs/pytest_plugin.py | 27 ++++++++++++++++--- .../tests/fake_filesystem_unittest_test.py | 12 +++++++++ 5 files changed, 53 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index a07e2b44..89a49e68 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -18,6 +18,14 @@ The released versions correspond to PyPi releases. ### New Features * added some support for the upcoming Python version 3.11 (see [#677](../../issues/677)) +* added convenience fixtures for module- and session based `fs` fixtures + (`fs_module` and `fs_session`) + +### Fixes +* fixed an incompatibility of `tmpdir` (and probably other fixtures) with the + module-scoped version of `fs`; had been introduced in + pyfakefs 4.5.5 by the fix for [#666](../../issues/666) + (see [#684](../../issues/684)) ## [Version 4.5.6](https://pypi.python.org/pypi/pyfakefs/4.5.6) (2022-03-17) Fixes a regression which broke tests with older pytest versions (< 3.9). diff --git a/docs/usage.rst b/docs/usage.rst index b2ec2fa1..2a2631ec 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -64,6 +64,10 @@ tests: """ yield fs +For convenience, module- and session-scoped fixtures with the same +functionality are provided, named ``fs_module`` and ``fs_session``, +respectively. + Patch using fake_filesystem_unittest.Patcher ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/pyfakefs/fake_pathlib.py b/pyfakefs/fake_pathlib.py index e1179a28..efa07067 100644 --- a/pyfakefs/fake_pathlib.py +++ b/pyfakefs/fake_pathlib.py @@ -792,6 +792,11 @@ def __call__(self, *args, **kwargs): def __getattr__(self, name): return getattr(self.fake_pathlib.Path, name) + @classmethod + def __instancecheck__(cls, instance): + # fake the inheritance to pass isinstance checks - see #666 + return isinstance(instance, PurePath) + class RealPath(pathlib.Path): """Replacement for `pathlib.Path` if it shall not be faked. diff --git a/pyfakefs/pytest_plugin.py b/pyfakefs/pytest_plugin.py index 3d3306cd..7a3103f6 100644 --- a/pyfakefs/pytest_plugin.py +++ b/pyfakefs/pytest_plugin.py @@ -8,7 +8,6 @@ def my_fakefs_test(fs): fs.create_file('/var/data/xx1.txt') assert os.path.exists('/var/data/xx1.txt') """ -import _pytest import py import pytest @@ -16,8 +15,6 @@ def my_fakefs_test(fs): Patcher.SKIPMODULES.add(py) Patcher.SKIPMODULES.add(pytest) -if hasattr(_pytest, "pathlib"): - Patcher.SKIPMODULES.add(_pytest.pathlib) @pytest.fixture @@ -31,3 +28,27 @@ def fs(request): patcher.setUp() yield patcher.fs patcher.tearDown() + + +@pytest.fixture(scope="module") +def fs_module(request): + """ Module-scoped fake filesystem fixture. """ + if hasattr(request, 'param'): + patcher = Patcher(*request.param) + else: + patcher = Patcher() + patcher.setUp() + yield patcher.fs + patcher.tearDown() + + +@pytest.fixture(scope="session") +def fs_session(request): + """ Session-scoped fake filesystem fixture. """ + if hasattr(request, 'param'): + patcher = Patcher(*request.param) + else: + patcher = Patcher() + patcher.setUp() + yield patcher.fs + patcher.tearDown() diff --git a/pyfakefs/tests/fake_filesystem_unittest_test.py b/pyfakefs/tests/fake_filesystem_unittest_test.py index 97b5f7b6..4627b098 100644 --- a/pyfakefs/tests/fake_filesystem_unittest_test.py +++ b/pyfakefs/tests/fake_filesystem_unittest_test.py @@ -32,6 +32,8 @@ from pathlib import Path from unittest import TestCase, mock +import pytest + import pyfakefs.tests.import_as_example import pyfakefs.tests.logsio from pyfakefs import fake_filesystem_unittest, fake_filesystem @@ -879,5 +881,15 @@ def test_is_absolute(self, fs): self.assertTrue(pathlib.Path(".").absolute().is_absolute()) +class TestModuleScopedFsWithTmpdir: + @pytest.fixture(autouse=True) + def test_internal(self, tmpdir): + yield + + def test_fail(self, fs_module): + # Regression test for #684 + assert True + + if __name__ == "__main__": unittest.main()