summaryrefslogtreecommitdiffstats
path: root/Lib/unittest
diff options
context:
space:
mode:
authorMichael Foord <michael@voidspace.org.uk>2014-04-15 21:22:22 (GMT)
committerMichael Foord <michael@voidspace.org.uk>2014-04-15 21:22:22 (GMT)
commit15f2d1775e64b3ae0742f0faae108bc3d6e3d5e4 (patch)
tree67a93e8c6553d0d8d3153fdf657cb72194d4305d /Lib/unittest
parent27adf4469023597883d9240ad40a7a52d81b6f66 (diff)
parentebc1a30d55f07d590d62504c3f097cb8a15ee7d3 (diff)
downloadcpython-15f2d1775e64b3ae0742f0faae108bc3d6e3d5e4.zip
cpython-15f2d1775e64b3ae0742f0faae108bc3d6e3d5e4.tar.gz
cpython-15f2d1775e64b3ae0742f0faae108bc3d6e3d5e4.tar.bz2
Merge
Diffstat (limited to 'Lib/unittest')
-rw-r--r--Lib/unittest/mock.py15
-rw-r--r--Lib/unittest/test/testmock/testpatch.py19
2 files changed, 28 insertions, 6 deletions
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index e8dbc22..42cf23a 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -1054,7 +1054,7 @@ def _is_started(patcher):
class _patch(object):
attribute_name = None
- _active_patches = set()
+ _active_patches = []
def __init__(
self, getter, attribute, new, spec, create,
@@ -1330,13 +1330,18 @@ class _patch(object):
def start(self):
"""Activate a patch, returning any created mock."""
result = self.__enter__()
- self._active_patches.add(self)
+ self._active_patches.append(self)
return result
def stop(self):
"""Stop an active patch."""
- self._active_patches.discard(self)
+ try:
+ self._active_patches.remove(self)
+ except ValueError:
+ # If the patch hasn't been started this will fail
+ pass
+
return self.__exit__()
@@ -1629,8 +1634,8 @@ def _clear_dict(in_dict):
def _patch_stopall():
- """Stop all active patches."""
- for patch in list(_patch._active_patches):
+ """Stop all active patches. LIFO to unroll nested patches."""
+ for patch in reversed(_patch._active_patches):
patch.stop()
diff --git a/Lib/unittest/test/testmock/testpatch.py b/Lib/unittest/test/testmock/testpatch.py
index d941d8a..28fe86b 100644
--- a/Lib/unittest/test/testmock/testpatch.py
+++ b/Lib/unittest/test/testmock/testpatch.py
@@ -12,7 +12,7 @@ from unittest.test.testmock.support import SomeClass, is_instance
from unittest.mock import (
NonCallableMock, CallableMixin, patch, sentinel,
MagicMock, Mock, NonCallableMagicMock, patch, _patch,
- DEFAULT, call, _get_target
+ DEFAULT, call, _get_target, _patch
)
@@ -1799,6 +1799,23 @@ class PatchTest(unittest.TestCase):
patched()
self.assertIs(os.path, path)
+ def test_stopall_lifo(self):
+ stopped = []
+ class thing(object):
+ one = two = three = None
+
+ def get_patch(attribute):
+ class mypatch(_patch):
+ def stop(self):
+ stopped.append(attribute)
+ return super(mypatch, self).stop()
+ return mypatch(lambda: thing, attribute, None, None,
+ False, None, None, None, {})
+ [get_patch(val).start() for val in ("one", "two", "three")]
+ patch.stopall()
+
+ self.assertEqual(stopped, ["three", "two", "one"])
+
if __name__ == '__main__':
unittest.main()