Skip to content

Commit a820900

Browse files
committed
Add chapter about nested fake filesystems to troubleshouting guide
1 parent be19d4a commit a820900

File tree

3 files changed

+67
-21
lines changed

3 files changed

+67
-21
lines changed

CHANGES.md

+19-19
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,38 @@ The released versions correspond to PyPI releases.
44
## Unreleased
55

66
### Changes
7-
* The handling of file permissions under Posix is should now mostly match the behavior
7+
* the handling of file permissions under Posix is should now mostly match the behavior
88
of the real filesystem, which may change the behavior of some tests
99

1010
### Fixes
11-
* Fixed a specific problem on reloading a pandas-related module (see [#947](../../issues/947)),
11+
* fixed a specific problem on reloading a pandas-related module (see [#947](../../issues/947)),
1212
added possibility for unload hooks for specific modules
13-
* Use this also to reload django views (see [#932](../../issues/932))
14-
* Fixed `EncodingWarning` for Python >= 3.11 (see [#957](../../issues/957))
15-
* Consider directory ownership while adding or removing directory entries
13+
* use this also to reload django views (see [#932](../../issues/932))
14+
* fixed `EncodingWarning` for Python >= 3.11 (see [#957](../../issues/957))
15+
* consider directory ownership while adding or removing directory entries
1616
(see [#959](../../issues/959))
17-
* Fixed handling of directory enumeration and search permissions under Posix systems
17+
* fixed handling of directory enumeration and search permissions under Posix systems
1818
(see [#960](../../issues/960))
1919

2020
## [Version 5.3.5](https://pypi.python.org/pypi/pyfakefs/5.3.5) (2024-01-30)
2121
Fixes a regression.
2222

2323
### Fixes
24-
* Fixes a regression due to the changed behavior of the dynamic patcher cleanup (see [#939](../../issues/939)).
24+
* Fixed a regression due to the changed behavior of the dynamic patcher cleanup (see [#939](../../issues/939)).
2525
The change is now by default only made if the `django` module is loaded, and the behavior can
2626
be changed using the new argument `module_cleanup_mode`.
2727

2828
### Packaging
29-
* include `tox.ini` and a few more files into the source distribution (see [#937](../../issues/937))
29+
* included `tox.ini` and a few more files into the source distribution (see [#937](../../issues/937))
3030

3131
## [Version 5.3.4](https://pypi.python.org/pypi/pyfakefs/5.3.4) (2024-01-19)
3232
Bugfix release.
3333

3434
### Fixes
35-
* fixes handling of unhashable modules which cannot be cached (see [#923](../../issues/923))
35+
* fixed handling of unhashable modules which cannot be cached (see [#923](../../issues/923))
3636
* reload modules loaded by the dynamic patcher instead of removing them - sometimes they may
3737
not be reloaded automatically (see [#932](../../issues/932))
38-
* add back argument `use_dynamic_patch` as a fallback for similar problems
38+
* added back argument `use_dynamic_patch` as a fallback for similar problems
3939

4040

4141
## [Version 5.3.2](https://pypi.python.org/pypi/pyfakefs/5.3.2) (2023-11-30)
@@ -58,23 +58,23 @@ Mostly a bugfix release.
5858
to an existing directory in the fake filesystem (see [#901](../../issues/901))
5959

6060
### Fixes
61-
* fixes the problem that filesystem patching was still active in the pytest
61+
* fixed the problem that filesystem patching was still active in the pytest
6262
logreport phase (see [#904](../../issues/904))
63-
* Restores compatibility with PyTorch 2.0 and above, as well as with other
64-
classes that have custom __setattr__ methods (see [#905](../../pull/905)).
63+
* restored compatibility with PyTorch 2.0 and above, as well as with other
64+
classes that have custom __setattr__ methods (see [#905](../../pull/905))
6565

6666
## [Version 5.3.0](https://pypi.python.org/pypi/pyfakefs/5.3.0) (2023-10-11)
6767
Adds official support for Python 3.12.
6868

6969
### Changes
70-
* add official support for Python 3.12
70+
* added official support for Python 3.12
7171

7272
### Fixes
7373
* removed a leftover debug print statement (see [#869](../../issues/869))
7474
* make sure tests work without HOME environment set (see [#870](../../issues/870))
7575
* automount drive or UNC path under Windows if needed for `pathlib.Path.mkdir()`
7676
(see [#890](../../issues/890))
77-
* adapt patching `io.open` and `io.open_code` to work with Python 3.12
77+
* adapted patching `io.open` and `io.open_code` to work with Python 3.12
7878
(see [#836](../../issues/836) and [#892](../../issues/892))
7979

8080
## [Version 5.2.4](https://pypi.python.org/pypi/pyfakefs/5.2.4) (2023-08-18)
@@ -91,12 +91,12 @@ Adds compatibility with PyPy 3.10 and Python 3.12.
9191
### Fixes
9292
* Re-create temp directory if it had been created before on resetting file system
9393
(see [#814](../../issues/814)).
94-
* Exclude pytest `pathlib` modules from patching to avoid mixup of patched/unpatched
94+
* Excluded pytest `pathlib` modules from patching to avoid mixup of patched/unpatched
9595
code (see [#814](../../issues/814)).
96-
* Adapt to changes in Python 3.12 beta1 (only working partially,
96+
* Adapted to changes in Python 3.12 beta1 (only working partially,
9797
see [#830](../../issues/830) and [#831](../../issues/831)).
98-
* Adapt to changes in `shutil` in Python 3.12 beta2 (see [#814](../../issues/814)).
99-
* Fix support for newer PyPi versions (see [#859](../../issues/859)).
98+
* Adapted to changes in `shutil` in Python 3.12 beta2 (see [#814](../../issues/814)).
99+
* Fixed support for newer PyPi versions (see [#859](../../issues/859)).
100100

101101
### Documentation
102102
* Added a note regarding the incompatibility of the built-in `sqlite3` module with

docs/troubleshooting.rst

+47-1
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ from configuration files. In these cases, you have to map the respective files
134134
or directories from the real into the fake filesystem as described in
135135
:ref:`real_fs_access`. For the timezone example, this could look like the following::
136136

137+
.. code:: python
138+
137139
from pathlib import Path
138140
import pytz
139141
from pyfakefs.fake_filesystem_unittest import TestCase
@@ -150,13 +152,15 @@ or directories from the real into the fake filesystem as described in
150152
If you are using Django, various dependencies may expect both the project
151153
directory and the ``site-packages`` installation to exist in the fake filesystem.
152154

153-
Here's an example of how to add these using pytest::
155+
Here's an example of how to add these using pytest:
154156

157+
.. code:: python
155158
156159
import os
157160
import django
158161
import pytest
159162
163+
160164
@pytest.fixture
161165
def fake_fs(fs):
162166
PROJECT_BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -279,6 +283,48 @@ is problematic and better avoided.
279283
`pathlib` has been restructured so that a pathlib path no longer contains a reference
280284
to the original filesystem accessor, and it can safely be used in the fake filesystem.
281285

286+
.. _nested_patcher_invocation:
287+
288+
Nested file system fixtures and Patcher invocations
289+
---------------------------------------------------
290+
``pyfakefs`` does not support nested faked file systems. Instead, it uses reference counting
291+
on the single fake filesystem instance. That means, if you are trying to create a fake filesystem
292+
inside a fake filesystem, only the reference count will increase, and any arguments you may pass
293+
to the patcher or fixture are ignored. Likewise, if you leave a nested fake filesystem,
294+
only the reference count is decreased and nothing is reverted.
295+
296+
There are some situations where that may happen, probably without you noticing:
297+
298+
* If you use the module- or session based variants of the ``fs`` fixture (e.g. ``fs_module`` or
299+
``fs_session``), you may still use the ``fs`` fixture in single tests. This will practically
300+
reference the module- or session based fake filesystem, instead of creating a new one.
301+
302+
.. code:: python
303+
304+
@pytest.fixture(scope="module", autouse=True)
305+
def use_fs(fs_module):
306+
# do some setup...
307+
yield fs_module
308+
309+
310+
def test_something(fs):
311+
do_more_fs_setup()
312+
test_something()
313+
# the fs setup done in this test is not reverted!
314+
315+
* If you invoke a ``Patcher`` instance inside a test with the ``fs`` fixture (or with an active
316+
``fs_module`` or ``fs_session`` fixture), this will be ignored. For example:
317+
318+
.. code:: python
319+
320+
def test_something(fs):
321+
with Patcher(allow_root_user=False):
322+
# root user is still allowed
323+
do_stuff()
324+
325+
* The same is true, if you use ``setUpPyfakefs`` or ``setUpClassPyfakefs`` in a unittest context, or if you use
326+
the ``patchfs`` decorator. ``Patcher`` instances created in the tests will be ignored likewise.
327+
282328

283329
.. _`multiprocessing`: https://docs.python.org/3/library/multiprocessing.html
284330
.. _`subprocess`: https://docs.python.org/3/library/subprocess.html

docs/usage.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ respectively.
5151
not setup / tear down the fake filesystem in the current scope; instead, it
5252
will just serve as a reference to the active fake filesystem. That means that changes
5353
done in the fake filesystem inside a test will remain there until the respective scope
54-
ends.
54+
ends (see also :ref:`nested_patcher_invocation`).
5555

5656
Patch using fake_filesystem_unittest
5757
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

0 commit comments

Comments
 (0)