Skip to content

Commit

Permalink
Add back argument use_dynamic_patch
Browse files Browse the repository at this point in the history
- can be used for cases where dynamic patching causes problems
  • Loading branch information
mrbean-bremen committed Jan 19, 2024
1 parent fb97b62 commit ac4af93
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ The released versions correspond to PyPI releases.
* fixes handling of unhashable modules which cannot be cached (see [#923](../../issues/923))
* reload modules loaded by the dynamic patcher instead of removing them - sometimes they may
not be reloaded automatically (see [#932](../../issues/932))
* add back argument `use_dynamic_patch` as a fallback for similar problems


## [Version 5.3.2](https://pypi.python.org/pypi/pyfakefs/5.3.2) (2023-11-30)
Bugfix release.
Expand Down
7 changes: 7 additions & 0 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,13 @@ If you want to clear the cache just for a specific test instead, you can call
fs.clear_cache()
...
use_dynamic_patch
~~~~~~~~~~~~~~~~~
If ``True`` (the default), dynamic patching after setup is used (for example
for modules loaded locally inside of functions).
Can be switched off if it causes unwanted side effects, which happened at least in
once instance while testing a django project.


.. _convenience_methods:

Expand Down
16 changes: 15 additions & 1 deletion pyfakefs/fake_filesystem_unittest.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ def patchfs(
patch_open_code: PatchMode = PatchMode.OFF,
patch_default_args: bool = False,
use_cache: bool = True,
use_dynamic_patch: bool = True,
) -> Callable:
"""Convenience decorator to use patcher with additional parameters in a
test function.
Expand Down Expand Up @@ -132,6 +133,7 @@ def wrapped(*args, **kwargs):
patch_open_code=patch_open_code,
patch_default_args=patch_default_args,
use_cache=use_cache,
use_dynamic_patch=use_dynamic_patch,
) as p:
args = list(args)
args.append(p.fs)
Expand Down Expand Up @@ -167,6 +169,7 @@ def load_doctests(
use_known_patches: bool = True,
patch_open_code: PatchMode = PatchMode.OFF,
patch_default_args: bool = False,
use_dynamic_patch: bool = True,
) -> TestSuite: # pylint:disable=unused-argument
"""Load the doctest tests for the specified module into unittest.
Args:
Expand All @@ -186,6 +189,7 @@ def load_doctests(
use_known_patches=use_known_patches,
patch_open_code=patch_open_code,
patch_default_args=patch_default_args,
use_dynamic_patch=use_dynamic_patch,
is_doc_test=True,
)
assert Patcher.DOC_PATCHER is not None
Expand Down Expand Up @@ -312,6 +316,7 @@ def setUpClassPyfakefs(
patch_open_code: PatchMode = PatchMode.OFF,
patch_default_args: bool = False,
use_cache: bool = True,
use_dynamic_patch: bool = True,
) -> None:
"""Similar to :py:func:`setUpPyfakefs`, but as a class method that
can be used in `setUpClass` instead of in `setUp`.
Expand Down Expand Up @@ -349,6 +354,7 @@ def setUpClassPyfakefs(
patch_open_code=patch_open_code,
patch_default_args=patch_default_args,
use_cache=use_cache,
use_dynamic_patch=use_dynamic_patch,
)

Patcher.PATCHER.setUp()
Expand Down Expand Up @@ -513,6 +519,7 @@ def __init__(
patch_open_code: PatchMode = PatchMode.OFF,
patch_default_args: bool = False,
use_cache: bool = True,
use_dynamic_patch: bool = True,
is_doc_test: bool = False,
) -> None:
"""
Expand Down Expand Up @@ -545,6 +552,9 @@ def __init__(
cached between tests for performance reasons. As this is a new
feature, this argument allows to turn it off in case it
causes any problems.
use_dynamic_patch: If `True`, dynamic patching after setup is used
(for example for modules loaded locally inside of functions).
Can be switched off if it causes unwanted side effects.
"""
self.is_doc_test = is_doc_test
if is_doc_test:
Expand Down Expand Up @@ -582,6 +592,7 @@ def __init__(
self.modules_to_reload.extend(modules_to_reload)
self.patch_default_args = patch_default_args
self.use_cache = use_cache
self.use_dynamic_patch = True

if use_known_patches:
from pyfakefs.patched_packages import (
Expand Down Expand Up @@ -914,6 +925,9 @@ def start_patching(self) -> None:
for module in self.modules_to_reload:
if sys.modules.get(module.__name__) is module:
reload(module)
if not self.use_dynamic_patch:
self._dyn_patcher.cleanup()
sys.meta_path.pop(0)

def patch_functions(self) -> None:
assert self._stubs is not None
Expand Down Expand Up @@ -989,7 +1003,7 @@ def stop_patching(self, temporary=False) -> None:
if self._stubs:
self._stubs.smart_unset_all()
self.unset_defaults()
if self._dyn_patcher:
if self.use_dynamic_patch and self._dyn_patcher:
self._dyn_patcher.cleanup()
sys.meta_path.pop(0)

Expand Down

0 comments on commit ac4af93

Please sign in to comment.