Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ The released versions correspond to PyPI releases.

## Unreleased

### Fixes
* fixed an interaction problem of `fs` with other pytest fixtures (see [#1200](../../issues/1200))

### Infrastructure
* fixed some warnings in tests (see [#1190](../../issues/1190))

Expand Down
6 changes: 6 additions & 0 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ you can define a longer name in your ``conftest.py`` and use that in your tests:
"""
yield fs

.. note:: Filesystem patching is paused in the pytest logreport phases to ensure that
logs are correctly written to the real filesystem.

Class-, module- and session-scoped fixtures
...........................................
For convenience, class-, module- and session-scoped fixtures with the same
Expand All @@ -55,6 +58,9 @@ respectively.
done in the fake filesystem inside a test will remain there until the respective scope
ends (see also :ref:`nested_patcher_invocation`).

.. note:: To avoid unwanted side-effects, the patching is paused between the tests,
even if the fixture is still active.

.. _unittest_usage:

Patch using fake_filesystem_unittest
Expand Down
6 changes: 3 additions & 3 deletions pyfakefs/fake_filesystem_unittest.py
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ def fake_path_module(fs: FakeFilesystem):
"io": fake_io.FakeIoModule,
"pathlib": fake_pathlib_module,
}
if sys.version_info >= (3, 13):
if sys.version_info[:2] == (3, 13):
# for Python 3.13, we need both pathlib (path with __init__.py) and
# pathlib._local (has the actual implementation);
# depending on how pathlib is imported, either may be used
Expand All @@ -806,10 +806,10 @@ def fake_path_module(fs: FakeFilesystem):
# be contained in - this allows for alternative modules like
# `pathlib` and `pathlib2`
self._class_modules["Path"] = ["pathlib"]
if sys.version_info >= (3, 13):
if sys.version_info[:2] == (3, 13):
self._class_modules["Path"].append("pathlib._local")
self._unfaked_module_classes["pathlib"] = fake_pathlib.RealPathlibModule
if sys.version_info >= (3, 13):
if sys.version_info[:2] == (3, 13):
self._unfaked_module_classes["pathlib._local"] = (
fake_pathlib.RealPathlibModule
)
Expand Down
26 changes: 12 additions & 14 deletions pyfakefs/pytest_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ def my_fakefs_test(fs):
assert os.path.exists('/var/data/xx1.txt')
"""

import contextlib

import py
import pytest
from _pytest import capture

from pyfakefs.fake_filesystem_unittest import Patcher
from pyfakefs.fake_filesystem_unittest import Patcher, Pause

try:
from _pytest import pathlib
Expand Down Expand Up @@ -85,22 +87,18 @@ def pytest_sessionfinish(session, exitstatus):
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_logreport(report):
"""Make sure that patching is not active during reporting."""
pause = Patcher.PATCHER is not None and report.when == "call"
if pause:
pause = Patcher.PATCHER is not None and Patcher.PATCHER.is_patching
context_mgr = Pause(Patcher.PATCHER) if pause else contextlib.nullcontext()
with context_mgr:
yield
if pause and report.when == "teardown":
# if we get here, we are not in a function scope fixture
# in this case, we still want to pause patching between the tests
Patcher.PATCHER.pause()
yield


@pytest.hookimpl(hookwrapper=True, trylast=True)
@pytest.hookimpl(tryfirst=True)
def pytest_runtest_setup(item):
# resume patcher if not in a function scope
if Patcher.PATCHER is not None:
Patcher.PATCHER.resume()
yield


@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_teardown(item, nextitem):
"""Make sure that patching is not active during reporting."""
if Patcher.PATCHER is not None:
Patcher.PATCHER.pause()
yield
12 changes: 12 additions & 0 deletions pyfakefs/pytest_tests/test_fs_with_monkeypatch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from pyfakefs.fake_filesystem import FakeFileOpen


def test_monkeypatch_with_fs(fs, monkeypatch):
"""Regression test for issue 1200"""
fake_open = FakeFileOpen(fs)
monkeypatch.setattr("builtins.open", fake_open, raising=False)


def test_open():
"""Tests if open is poisoned by the above test"""
assert "built-in" in str(open)
Loading