Skip to content

Commit 93fee76

Browse files
committed
Document problems with multi-threading
- also fix some minor documentation issues - see #1102
1 parent 5ca69f1 commit 93fee76

File tree

3 files changed

+44
-28
lines changed

3 files changed

+44
-28
lines changed

docs/intro.rst

+29-24
Original file line numberDiff line numberDiff line change
@@ -6,75 +6,76 @@ system that mocks the Python file system modules.
66
Using pyfakefs, your tests operate on a fake file system in memory without touching the real disk.
77
The software under test requires no modification to work with pyfakefs.
88

9-
pyfakefs works with CPython 3.7 and above, on Linux, Windows and macOS,
9+
``pyfakefs`` works with CPython 3.7 and above, on Linux, Windows and macOS,
1010
and with PyPy3.
1111

12-
pyfakefs works with `pytest <doc.pytest.org>`__ version 3.0.0 or above by
12+
``pyfakefs`` works with `pytest <doc.pytest.org>`__ version 6.2.5 or above by
1313
providing the `fs` fixture that enables the fake filesystem.
1414

1515
Installation
1616
------------
17-
pyfakefs is available on `PyPI <https://pypi.python.org/pypi/pyfakefs/>`__.
17+
``pyfakefs`` is available on `PyPI <https://pypi.python.org/pypi/pyfakefs/>`__.
1818
The latest released version can be installed from PyPI:
1919

2020
.. code:: bash
2121
2222
pip install pyfakefs
2323
24-
The latest main can be installed from the GitHub sources:
24+
The latest development version (main branch) can be installed from the GitHub sources:
2525

2626
.. code:: bash
2727
2828
pip install git+https://github.com/pytest-dev/pyfakefs
2929
3030
Features
3131
--------
32-
- Code executed under pyfakefs works transparently on a memory-based file
32+
- Code executed under ``pyfakefs`` works transparently on a memory-based file
3333
system without the need of special commands. The same code that works on
3434
the real filesystem will work on the fake filesystem if running under
35-
pyfakefs.
35+
``pyfakefs``.
3636

37-
- pyfakefs provides direct support for `pytest` (via the `fs` fixture)
37+
- ``pyfakefs`` provides direct support for `pytest` (via the `fs` fixture)
3838
and `unittest` (via a `TestCase` base class), but can also be used with
3939
other test frameworks.
4040

41-
- Each pyfakefs test starts with an empty file system, but it is possible to
42-
map files and directories from the real file system into the fake
41+
- Each ``pyfakefs`` test starts with an empty (except for the :ref:`os_temporary_directories`) file system,
42+
but it is possible to map files and directories from the real file system into the fake
4343
filesystem if needed.
4444

4545
- No files in the real file system are changed during the tests, even in the
4646
case of writing to mapped real files.
4747

48-
- pyfakefs keeps track of the filesystem size if configured. The file system
49-
size can be configured arbitrarily.
48+
- ``pyfakefs`` keeps track of the filesystem size if configured. The file system
49+
size can be configured arbitrarily. It is also possible to create files with a defined
50+
size without setting contents.
5051

51-
- it is possible to pause and resume using the fake filesystem, if the
52-
real file system has to be used in a test step
52+
- It is possible to pause and resume using the fake filesystem, if the
53+
real file system has to be used in a test step.
5354

54-
- pyfakefs defaults to the OS it is running on, but can also be configured
55+
- ``pyfakefs`` defaults to the OS it is running on, but can also be configured
5556
to test code running under another OS (Linux, macOS or Windows).
5657

57-
- pyfakefs can be configured to behave as if running as a root or as a
58+
- ``pyfakefs`` can be configured to behave as if running as a root or as a
5859
non-root user, independently from the actual user.
5960

6061
.. _limitations:
6162

6263
Limitations
6364
-----------
64-
- pyfakefs will not work with Python libraries (other than `os` and `io`) that
65+
- ``pyfakefs`` will not work with Python libraries (other than `os` and `io`) that
6566
use C libraries to access the file system, because it cannot patch the
6667
underlying C libraries' file access functions
6768

68-
- pyfakefs patches most kinds of importing file system modules automatically,
69+
- ``pyfakefs`` patches most kinds of importing file system modules automatically,
6970
but there are still some cases where this will not work.
7071
See :ref:`customizing_patcher` for more information and ways to work around
7172
this.
7273

73-
- pyfakefs does not retain the MRO for file objects, so you cannot rely on
74+
- ``pyfakefs`` does not retain the MRO for file objects, so you cannot rely on
7475
checks using `isinstance` for these objects (for example, to differentiate
7576
between binary and textual file objects).
7677

77-
- pyfakefs is only tested with CPython and the newest PyPy versions, other
78+
- ``pyfakefs`` is only tested with CPython and the newest PyPy versions, other
7879
Python implementations will probably not work
7980

8081
- Differences in the behavior in different Linux distributions or different
@@ -84,26 +85,30 @@ Limitations
8485
considered as reference systems. Additionally, the tests are run in Docker
8586
containers with the latest CentOS, Debian, Fedora and Ubuntu images.
8687

87-
- pyfakefs may not work correctly if file system functions are patched by
88+
- ``pyfakefs`` may not work correctly if file system functions are patched by
8889
other means (e.g. using `unittest.mock.patch`) - see
8990
:ref:`usage_with_mock_open` for more information
9091

91-
- pyfakefs will not work correctly with
92+
- ``pyfakefs`` will not work correctly with
9293
`behave <https://github.com/behave/behave>`__ due to the way it loads
9394
the steps, if any filesystem modules are imported globally in the steps or
9495
environment files; as a workaround, you may load them locally inside the
9596
test steps (see `this issue <https://github.com/pytest-dev/pyfakefs/issues/703>`__)
9697

98+
- ``pyfakefs`` is not guaranteed to work correctly in multi-threading environments.
99+
Specifically, it does not ensure concurrent write access to a file from different
100+
threads, which is possible under Posix.
101+
97102
History
98103
-------
99-
pyfakefs was initially developed at Google by
104+
``pyfakefs`` was initially developed at Google by
100105
`Mike Bland <https://mike-bland.com/about.html>`__ as a modest
101106
fake implementation of core Python modules. It was introduced to all of
102107
Google in September 2006. Since then, it has been enhanced to extend its
103-
functionality and usefulness. At last count, pyfakefs was used in over
108+
functionality and usefulness. At last count, ``pyfakefs`` was used in over
104109
20,000 Python tests at Google.
105110

106-
Google released pyfakefs to the public in 2011 as Google Code project
111+
Google released ``pyfakefs`` to the public in 2011 as Google Code project
107112
`pyfakefs <http://code.google.com/p/pyfakefs/>`__:
108113

109114
* Fork `jmcgeheeiv-pyfakefs <http://code.google.com/p/jmcgeheeiv-pyfakefs/>`__

docs/troubleshooting.rst

+14-2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,16 @@ function correctly. Examples that have shown this problem include `GitPython`_
6969
and `plumbum`_. Calling ``find_library`` also uses ``subprocess`` and does not work in
7070
the fake filesystem.
7171

72+
Modules using multi-threading
73+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
74+
This includes for example the standard library module ``threading`` and the standard library
75+
class ``concurrent.futures.ThreadPoolExecutor``.
76+
Multi-threading is not specifically handled in ``pyfakefs`` and may lead to problems
77+
in some cases. Specifically, writing to the same file from different threads (using
78+
different file handles) may fail, while in the real filesystem this is possible in
79+
Posix systems. There may be similar problems that we have not encountered yet, so
80+
use ``pyfakefs`` in multi-threaded environments with care.
81+
7282
`sqlite3`_ (built-in)
7383
~~~~~~~~~~~~~~~~~~~~~~~~
7484
This is a database adapter written in C, which uses the database C API to access files.
@@ -132,7 +142,7 @@ the filesystem functions that ``pyfakefs`` patches, but in some cases it may
132142
access other files in the packages. An example is the ``pytz`` module, which is loading timezone information
133143
from configuration files. In these cases, you have to map the respective files
134144
or directories from the real into the fake filesystem as described in
135-
:ref:`real_fs_access`. For the timezone example, this could look like the following::
145+
:ref:`real_fs_access`. For the timezone example, this could look like the following:
136146

137147
.. code:: python
138148
@@ -172,6 +182,8 @@ Here's an example of how to add these using pytest:
172182
)
173183
return fs
174184
185+
.. _os_temporary_directories:
186+
175187
OS temporary directories
176188
------------------------
177189
Tests relying on a completely empty file system on test start will fail.
@@ -256,7 +268,7 @@ passed before the ``mocker`` fixture to ensure this:
256268
257269
Pathlib.Path objects created outside of tests
258270
---------------------------------------------
259-
An pattern which is more often seen with the increased usage of ``pathlib`` is the
271+
A pattern which is seen more often with the increased usage of ``pathlib`` is the
260272
creation of global ``pathlib.Path`` objects (instead of string paths) that are imported
261273
into the tests. As these objects are created in the real filesystem,
262274
they do not have the same attributes as fake ``pathlib.Path`` objects,

docs/usage.rst

+1-2
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,7 @@ method ``setUpClassPyfakefs`` instead:
115115
self.assertTrue(os.path.exists(file_path))
116116
117117
.. note:: This feature cannot be used with a Python version before Python 3.8 due to
118-
a missing feature in ``unittest``. If you use ``pytest`` for running tests using this feature,
119-
you need to have at least ``pytest`` version 6.2 due to an issue in earlier versions.
118+
a missing feature in ``unittest``.
120119

121120
.. caution:: If this is used, any changes made in the fake filesystem inside a test
122121
will remain there for all following tests in the test class, if they are not reverted

0 commit comments

Comments
 (0)