Skip to content

Commit 62369f7

Browse files
committed
Add back argument use_dynamic_patch
- can be used for cases where dynamic patching causes problems
1 parent fb97b62 commit 62369f7

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

CHANGES.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ The released versions correspond to PyPI releases.
77
* fixes handling of unhashable modules which cannot be cached (see [#923](../../issues/923))
88
* reload modules loaded by the dynamic patcher instead of removing them - sometimes they may
99
not be reloaded automatically (see [#932](../../issues/932))
10+
* add back argument `use_dynamic_patch` as a fallback for similar problems
11+
1012

1113
## [Version 5.3.2](https://pypi.python.org/pypi/pyfakefs/5.3.2) (2023-11-30)
1214
Bugfix release.

docs/usage.rst

+7
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,13 @@ If you want to clear the cache just for a specific test instead, you can call
657657
fs.clear_cache()
658658
...
659659
660+
use_dynamic_patch
661+
~~~~~~~~~~~~~~~~~
662+
If ``True`` (the default), dynamic patching after setup is used (for example
663+
for modules loaded locally inside of functions).
664+
Can be switched off if it causes unwanted side effects, which happened at least in
665+
once instance while testing a django project.
666+
660667

661668
.. _convenience_methods:
662669

pyfakefs/fake_filesystem_unittest.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ def patchfs(
105105
patch_open_code: PatchMode = PatchMode.OFF,
106106
patch_default_args: bool = False,
107107
use_cache: bool = True,
108+
use_dynamic_patch: bool = True,
108109
) -> Callable:
109110
"""Convenience decorator to use patcher with additional parameters in a
110111
test function.
@@ -132,6 +133,7 @@ def wrapped(*args, **kwargs):
132133
patch_open_code=patch_open_code,
133134
patch_default_args=patch_default_args,
134135
use_cache=use_cache,
136+
use_dynamic_patch=use_dynamic_patch,
135137
) as p:
136138
args = list(args)
137139
args.append(p.fs)
@@ -167,6 +169,7 @@ def load_doctests(
167169
use_known_patches: bool = True,
168170
patch_open_code: PatchMode = PatchMode.OFF,
169171
patch_default_args: bool = False,
172+
use_dynamic_patch: bool = True,
170173
) -> TestSuite: # pylint:disable=unused-argument
171174
"""Load the doctest tests for the specified module into unittest.
172175
Args:
@@ -186,6 +189,7 @@ def load_doctests(
186189
use_known_patches=use_known_patches,
187190
patch_open_code=patch_open_code,
188191
patch_default_args=patch_default_args,
192+
use_dynamic_patch=use_dynamic_patch,
189193
is_doc_test=True,
190194
)
191195
assert Patcher.DOC_PATCHER is not None
@@ -312,6 +316,7 @@ def setUpClassPyfakefs(
312316
patch_open_code: PatchMode = PatchMode.OFF,
313317
patch_default_args: bool = False,
314318
use_cache: bool = True,
319+
use_dynamic_patch: bool = True,
315320
) -> None:
316321
"""Similar to :py:func:`setUpPyfakefs`, but as a class method that
317322
can be used in `setUpClass` instead of in `setUp`.
@@ -349,6 +354,7 @@ def setUpClassPyfakefs(
349354
patch_open_code=patch_open_code,
350355
patch_default_args=patch_default_args,
351356
use_cache=use_cache,
357+
use_dynamic_patch=use_dynamic_patch,
352358
)
353359

354360
Patcher.PATCHER.setUp()
@@ -513,6 +519,7 @@ def __init__(
513519
patch_open_code: PatchMode = PatchMode.OFF,
514520
patch_default_args: bool = False,
515521
use_cache: bool = True,
522+
use_dynamic_patch: bool = True,
516523
is_doc_test: bool = False,
517524
) -> None:
518525
"""
@@ -545,6 +552,9 @@ def __init__(
545552
cached between tests for performance reasons. As this is a new
546553
feature, this argument allows to turn it off in case it
547554
causes any problems.
555+
use_dynamic_patch: If `True`, dynamic patching after setup is used
556+
(for example for modules loaded locally inside of functions).
557+
Can be switched off if it causes unwanted side effects.
548558
"""
549559
self.is_doc_test = is_doc_test
550560
if is_doc_test:
@@ -582,6 +592,7 @@ def __init__(
582592
self.modules_to_reload.extend(modules_to_reload)
583593
self.patch_default_args = patch_default_args
584594
self.use_cache = use_cache
595+
self.use_dynamic_patch = use_dynamic_patch
585596

586597
if use_known_patches:
587598
from pyfakefs.patched_packages import (
@@ -914,6 +925,9 @@ def start_patching(self) -> None:
914925
for module in self.modules_to_reload:
915926
if sys.modules.get(module.__name__) is module:
916927
reload(module)
928+
if not self.use_dynamic_patch:
929+
self._dyn_patcher.cleanup()
930+
sys.meta_path.pop(0)
917931

918932
def patch_functions(self) -> None:
919933
assert self._stubs is not None
@@ -989,7 +1003,7 @@ def stop_patching(self, temporary=False) -> None:
9891003
if self._stubs:
9901004
self._stubs.smart_unset_all()
9911005
self.unset_defaults()
992-
if self._dyn_patcher:
1006+
if self.use_dynamic_patch and self._dyn_patcher:
9931007
self._dyn_patcher.cleanup()
9941008
sys.meta_path.pop(0)
9951009

0 commit comments

Comments
 (0)