summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/unittest/mock.py19
-rw-r--r--Lib/unittest/test/testmock/testpatch.py50
-rw-r--r--Misc/NEWS.d/next/Library/2019-12-14-14-38-40.bpo-21600.kC4Cgh.rst2
3 files changed, 69 insertions, 2 deletions
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 5622917..3fafe59 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -1851,8 +1851,23 @@ class _patch_dict(object):
self._unpatch_dict()
return False
- start = __enter__
- stop = __exit__
+
+ def start(self):
+ """Activate a patch, returning any created mock."""
+ result = self.__enter__()
+ _patch._active_patches.append(self)
+ return result
+
+
+ def stop(self):
+ """Stop an active patch."""
+ try:
+ _patch._active_patches.remove(self)
+ except ValueError:
+ # If the patch hasn't been started this will fail
+ pass
+
+ return self.__exit__()
def _clear_dict(in_dict):
diff --git a/Lib/unittest/test/testmock/testpatch.py b/Lib/unittest/test/testmock/testpatch.py
index dc4ccdb..438dfd8 100644
--- a/Lib/unittest/test/testmock/testpatch.py
+++ b/Lib/unittest/test/testmock/testpatch.py
@@ -1808,6 +1808,56 @@ class PatchTest(unittest.TestCase):
self.assertEqual(stopped, ["three", "two", "one"])
+ def test_patch_dict_stopall(self):
+ dic1 = {}
+ dic2 = {1: 'a'}
+ dic3 = {1: 'A', 2: 'B'}
+ origdic1 = dic1.copy()
+ origdic2 = dic2.copy()
+ origdic3 = dic3.copy()
+ patch.dict(dic1, {1: 'I', 2: 'II'}).start()
+ patch.dict(dic2, {2: 'b'}).start()
+
+ @patch.dict(dic3)
+ def patched():
+ del dic3[1]
+
+ patched()
+ self.assertNotEqual(dic1, origdic1)
+ self.assertNotEqual(dic2, origdic2)
+ self.assertEqual(dic3, origdic3)
+
+ patch.stopall()
+
+ self.assertEqual(dic1, origdic1)
+ self.assertEqual(dic2, origdic2)
+ self.assertEqual(dic3, origdic3)
+
+
+ def test_patch_and_patch_dict_stopall(self):
+ original_unlink = os.unlink
+ original_chdir = os.chdir
+ dic1 = {}
+ dic2 = {1: 'A', 2: 'B'}
+ origdic1 = dic1.copy()
+ origdic2 = dic2.copy()
+
+ patch('os.unlink', something).start()
+ patch('os.chdir', something_else).start()
+ patch.dict(dic1, {1: 'I', 2: 'II'}).start()
+ patch.dict(dic2).start()
+ del dic2[1]
+
+ self.assertIsNot(os.unlink, original_unlink)
+ self.assertIsNot(os.chdir, original_chdir)
+ self.assertNotEqual(dic1, origdic1)
+ self.assertNotEqual(dic2, origdic2)
+ patch.stopall()
+ self.assertIs(os.unlink, original_unlink)
+ self.assertIs(os.chdir, original_chdir)
+ self.assertEqual(dic1, origdic1)
+ self.assertEqual(dic2, origdic2)
+
def test_special_attrs(self):
def foo(x=0):
diff --git a/Misc/NEWS.d/next/Library/2019-12-14-14-38-40.bpo-21600.kC4Cgh.rst b/Misc/NEWS.d/next/Library/2019-12-14-14-38-40.bpo-21600.kC4Cgh.rst
new file mode 100644
index 0000000..0f72639
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-12-14-14-38-40.bpo-21600.kC4Cgh.rst
@@ -0,0 +1,2 @@
+Fix :func:`mock.patch.stopall` to stop active patches that were created with
+:func:`mock.patch.dict`.