@@ -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