Skip to content

Commit 399bb66

Browse files
committed
Refactor patch context
1 parent 1b9c6d4 commit 399bb66

File tree

1 file changed

+22
-21
lines changed

1 file changed

+22
-21
lines changed

Lib/unittest/mock.py

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626

2727
import asyncio
28+
from collections import namedtuple
2829
import contextlib
2930
import io
3031
import 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

13311327
class _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

Comments
 (0)