Skip to content

Fix cleanup handler documentation #1111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 14, 2025
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
11 changes: 6 additions & 5 deletions .github/workflows/testsuite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,18 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
python-version: [3.7, 3.8, 3.9, "3.10", "3.11", "3.12", "3.13"]
python-version: [3.8, 3.9, "3.10", "3.11", "3.12", "3.13"]
include:
- python-version: "pypy-3.7"
os: ubuntu-latest
os: ubuntu-22.04
- python-version: "pypy-3.9"
os: ubuntu-latest
- python-version: "pypy-3.10"
os: ubuntu-latest
exclude:
- python-version: 3.7
os: macOS-latest
- python-version: "3.7"
os: ubuntu-22.04
- python-version: "3.7"
os: windows-latest

steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ The released versions correspond to PyPI releases.
* fixed a problem with module and session scoped fixtures in Python 3.13
(see [#1101](../../issues/1101))
* fixed handling of `cwd` if set to a `pathlib.Path` (see [#1108](../../issues/1108))
* fixed documentation for cleanup handlers, added convenience handler `reload_cleanup_handler`
(see [#1105](../../issues/1105))

## [Version 5.7.3](https://pypi.python.org/pypi/pyfakefs/5.7.3) (2024-12-15)
Fixes a regression in version 5.7.3.
Expand Down
22 changes: 19 additions & 3 deletions docs/troubleshooting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -374,9 +374,25 @@ be added to the patcher:

@pytest.fixture
def my_fs():
with Patcher():
patcher["modulename"] = handler_no_cleanup
yield
with Patcher() as patcher:
patcher.cleanup_handlers["modulename"] = handler_no_cleanup
yield patcher.fs


A specific problem are modules that use filesystem functions and are imported by other modules locally
(e.g. inside a function). These kinds of modules are not correctly reset and need to be reloaded manually.
For this case, the cleanup handler `reload_cleanup_handler` in `pyfakefs.helpers` can be used:

.. code:: python

from pyfakefs.helpers import reload_cleanup_handler


@pytest.fixture
def my_fs():
with Patcher() as patcher:
patcher.cleanup_handlers["modulename"] = reload_cleanup_handler
yield patcher.fs

As this may not be trivial, we recommend to write an issue in ``pyfakefs`` with a reproducible example.
We will analyze the problem, and if we find a solution we will either get this fixed in ``pyfakefs``
Expand Down
10 changes: 10 additions & 0 deletions pyfakefs/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"""Helper classes use for fake file system implementation."""

import ctypes
import importlib
import io
import locale
import os
Expand Down Expand Up @@ -539,3 +540,12 @@ def starts_with(path, string):
):
return True
return False


def reload_cleanup_handler(name):
"""Cleanup handler that reloads the module with the given name.
Maybe needed in cases where a module is imported locally.
"""
if name in sys.modules:
importlib.reload(sys.modules[name])
return True
5 changes: 5 additions & 0 deletions pyfakefs/pytest_tests/lib_using_pathlib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import pathlib


def use_pathlib(path: str):
return pathlib.Path(path)
4 changes: 4 additions & 0 deletions pyfakefs/pytest_tests/local_import.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
def load(path: str) -> str:
from pyfakefs.pytest_tests import lib_using_pathlib

return lib_using_pathlib.use_pathlib(path)
26 changes: 26 additions & 0 deletions pyfakefs/pytest_tests/test_reload_local_import.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import pytest

from pyfakefs.fake_filesystem_unittest import Patcher
from pyfakefs.fake_pathlib import FakePathlibModule
from pyfakefs.helpers import reload_cleanup_handler
from pyfakefs.pytest_tests import local_import


@pytest.fixture
def test_fs():
with Patcher() as patcher:
patcher.cleanup_handlers["pyfakefs.pytest_tests.lib_using_pathlib"] = (
reload_cleanup_handler
)
yield patcher.fs


class TestReloadCleanupHandler:
def test1(self, test_fs):
path = local_import.load("some_path")
assert isinstance(path, FakePathlibModule.Path)

def test2(self):
path = local_import.load("some_path")
# will fail without reload handler
assert not isinstance(path, FakePathlibModule.Path)
Loading