2525
2626
2727import asyncio
28+ from collections import namedtuple
2829import contextlib
2930import io
3031import inspect
@@ -1320,12 +1321,7 @@ def _check_spec_arg_typos(kwargs_to_check):
13201321 )
13211322
13221323
1323- class _PatchStartedContext (object ):
1324- def __init__ (self , exit_stack , is_local , target , temp_original ):
1325- self .exit_stack = exit_stack
1326- self .is_local = is_local
1327- self .target = target
1328- self .temp_original = temp_original
1324+ _PatchContext = namedtuple ("_PatchContext" , "exit_stack is_local original target" )
13291325
13301326
13311327class _patch (object ):
@@ -1368,7 +1364,7 @@ def __init__(
13681364 self .autospec = autospec
13691365 self .kwargs = kwargs
13701366 self .additional_patchers = []
1371- self ._started_context = None
1367+ self ._context = None
13721368
13731369
13741370 def copy (self ):
@@ -1480,19 +1476,23 @@ def get_original(self):
14801476
14811477 @property
14821478 def is_started (self ):
1483- return self ._started_context is not None
1479+ return self ._context is not None
14841480
14851481 @property
14861482 def is_local (self ):
1487- return self ._started_context .is_local
1483+ return self ._context .is_local
1484+
1485+ @property
1486+ def original (self ):
1487+ return self ._context .original
14881488
14891489 @property
14901490 def target (self ):
1491- return self ._started_context .target
1491+ return self ._context .target
14921492
14931493 @property
1494- def temp_original (self ):
1495- return self ._started_context . temp_original
1494+ def temp_original (self ): # backwards compatibility
1495+ return self .original
14961496
14971497 def __enter__ (self ):
14981498 """Perform the patch."""
@@ -1627,11 +1627,12 @@ def __enter__(self):
16271627
16281628 new_attr = new
16291629
1630- self ._started_context = _PatchStartedContext (
1631- exit_stack = contextlib .ExitStack (),
1630+ exit_stack = contextlib .ExitStack ()
1631+ self ._context = _PatchContext (
1632+ exit_stack = exit_stack ,
16321633 is_local = is_local ,
1634+ original = original ,
16331635 target = self .getter (),
1634- temp_original = original ,
16351636 )
16361637 try :
16371638 setattr (self .target , self .attribute , new_attr )
@@ -1640,7 +1641,7 @@ def __enter__(self):
16401641 if self .new is DEFAULT :
16411642 extra_args [self .attribute_name ] = new
16421643 for patching in self .additional_patchers :
1643- arg = self . _started_context . exit_stack .enter_context (patching )
1644+ arg = exit_stack .enter_context (patching )
16441645 if patching .new is DEFAULT :
16451646 extra_args .update (arg )
16461647 return extra_args
@@ -1655,19 +1656,19 @@ def __exit__(self, *exc_info):
16551656 if not self .is_started :
16561657 return
16571658
1658- if self .is_local and self .temp_original is not DEFAULT :
1659- setattr (self .target , self .attribute , self .temp_original )
1659+ if self .is_local and self .original is not DEFAULT :
1660+ setattr (self .target , self .attribute , self .original )
16601661 else :
16611662 delattr (self .target , self .attribute )
16621663 if not self .create and (not hasattr (self .target , self .attribute ) or
16631664 self .attribute in ('__doc__' , '__module__' ,
16641665 '__defaults__' , '__annotations__' ,
16651666 '__kwdefaults__' )):
16661667 # needed for proxy objects like django settings
1667- setattr (self .target , self .attribute , self .temp_original )
1668+ setattr (self .target , self .attribute , self .original )
16681669
1669- exit_stack = self ._started_context .exit_stack
1670- self ._started_context = None
1670+ exit_stack = self ._context .exit_stack
1671+ self ._context = None
16711672 return exit_stack .__exit__ (* exc_info )
16721673
16731674
0 commit comments