From 2ee83a335fac2e9f185f84ee52cf5d6139bac89d Mon Sep 17 00:00:00 2001 From: mrbean-bremen Date: Thu, 10 Feb 2022 21:44:23 +0100 Subject: [PATCH] Use RealPathlibModule for all skipped modules - avoids the use of FakePathLibPath in pathlib - add _pytest.pathlib to skipped modules, fake isinstance check for RealPathlibPathModule - prevents issue with _pytest.pathlib in pytest 7.0.0, which would cause all tests with fs fixture to fail - see #666 --- CHANGES.md | 2 ++ pyfakefs/fake_filesystem_unittest.py | 36 +++++++++++++------------- pyfakefs/fake_pathlib.py | 6 +++++ pyfakefs/pytest_plugin.py | 3 ++- pyfakefs/tests/fake_filesystem_test.py | 6 +++++ 5 files changed, 34 insertions(+), 19 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e59b9c0f..848d58a0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,8 @@ The released versions correspond to PyPi releases. (see [#661](../../issues/661)) * disallow `encoding` argument on binary `open()` (see [#664](../../issues/664)) +* fixed compatibility issue with pytest 7.0.0 + (see [#666](../../issues/666)) ## [Version 4.5.4](https://pypi.python.org/pypi/pyfakefs/4.5.4) (2022-01-12) Minor bugfix release. diff --git a/pyfakefs/fake_filesystem_unittest.py b/pyfakefs/fake_filesystem_unittest.py index c2ec11e7..6633cb54 100644 --- a/pyfakefs/fake_filesystem_unittest.py +++ b/pyfakefs/fake_filesystem_unittest.py @@ -681,7 +681,6 @@ def _find_modules(self) -> None: for name, module in list(sys.modules.items()): try: if (self.use_cache and module in self.CACHED_MODULES or - module in self.SKIPMODULES or not inspect.ismodule(module)): continue except Exception: @@ -692,7 +691,8 @@ def _find_modules(self) -> None: if self.use_cache: self.__class__.CACHED_MODULES.add(module) continue - skipped = (any([sn.startswith(module.__name__) + skipped = (module in self.SKIPMODULES or + any([sn.startswith(module.__name__) for sn in self._skip_names])) module_items = module.__dict__.copy().items() @@ -703,22 +703,22 @@ def _find_modules(self) -> None: for name, mod in modules.items(): self.__class__.SKIPPED_FS_MODULES.setdefault( name, set()).add((module, mod.__name__)) - continue - - for name, mod in modules.items(): - self.__class__.FS_MODULES.setdefault(name, set()).add( - (module, mod.__name__)) - functions = {name: fct for name, fct in - module_items - if self._is_fs_function(fct)} - - for name, fct in functions.items(): - self.__class__.FS_FUNCTIONS.setdefault( - (name, fct.__name__, fct.__module__), set()).add(module) - - # find default arguments that are file system functions - if self.patch_default_args: - self._find_def_values(module_items) + else: + for name, mod in modules.items(): + self.__class__.FS_MODULES.setdefault(name, set()).add( + (module, mod.__name__)) + functions = {name: fct for name, fct in + module_items + if self._is_fs_function(fct)} + + for name, fct in functions.items(): + self.__class__.FS_FUNCTIONS.setdefault( + (name, fct.__name__, fct.__module__), + set()).add(module) + + # find default arguments that are file system functions + if self.patch_default_args: + self._find_def_values(module_items) if self.use_cache: self.__class__.CACHED_MODULES.add(module) diff --git a/pyfakefs/fake_pathlib.py b/pyfakefs/fake_pathlib.py index 2b305e8c..88685581 100644 --- a/pyfakefs/fake_pathlib.py +++ b/pyfakefs/fake_pathlib.py @@ -845,6 +845,12 @@ class RealPathlibPathModule: """Patches `pathlib.Path` by passing all calls to RealPathlibModule.""" real_pathlib = None + @classmethod + def __instancecheck__(cls, instance): + # as we cannot derive from pathlib.Path, we fake + # the inheritance to pass isinstance checks - see #666 + return isinstance(instance, PurePath) + def __init__(self): if self.real_pathlib is None: self.__class__.real_pathlib = RealPathlibModule() diff --git a/pyfakefs/pytest_plugin.py b/pyfakefs/pytest_plugin.py index e8b95f38..43890f98 100644 --- a/pyfakefs/pytest_plugin.py +++ b/pyfakefs/pytest_plugin.py @@ -8,7 +8,7 @@ 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,6 +16,7 @@ def my_fakefs_test(fs): Patcher.SKIPMODULES.add(py) Patcher.SKIPMODULES.add(pytest) +Patcher.SKIPMODULES.add(_pytest.pathlib) @pytest.fixture diff --git a/pyfakefs/tests/fake_filesystem_test.py b/pyfakefs/tests/fake_filesystem_test.py index b95db8fd..f131d2fc 100644 --- a/pyfakefs/tests/fake_filesystem_test.py +++ b/pyfakefs/tests/fake_filesystem_test.py @@ -1814,6 +1814,8 @@ def test_disk_full_after_reopened(self): f.write('b' * 110) with self.raises_os_error(errno.ENOSPC): f.flush() + with self.open('bar.txt') as f: + self.assertEqual('', f.read()) def test_disk_full_append(self): file_path = 'bar.txt' @@ -1826,6 +1828,8 @@ def test_disk_full_append(self): f.write('b' * 41) with self.raises_os_error(errno.ENOSPC): f.flush() + with self.open('bar.txt') as f: + self.assertEqual(f.read(), 'a' * 60) def test_disk_full_after_reopened_rplus_seek(self): with self.open('bar.txt', 'w') as f: @@ -1838,6 +1842,8 @@ def test_disk_full_after_reopened_rplus_seek(self): f.write('b' * 60) with self.raises_os_error(errno.ENOSPC): f.flush() + with self.open('bar.txt') as f: + self.assertEqual(f.read(), 'a' * 60) class MountPointTest(TestCase):