diff options
author | Mario Corchero <mariocj89@gmail.com> | 2020-01-24 08:38:33 (GMT) |
---|---|---|
committer | Chris Withers <chris@withers.org> | 2020-01-24 08:38:32 (GMT) |
commit | e131c9720d087c0c4988bd2a5c62020feb9d1d77 (patch) | |
tree | 209230859dbb25990ed04ce139bf06abac490e04 | |
parent | 1d0c5e16eab29d55773cc4196bb90d2bf12e09dd (diff) | |
download | cpython-e131c9720d087c0c4988bd2a5c62020feb9d1d77.zip cpython-e131c9720d087c0c4988bd2a5c62020feb9d1d77.tar.gz cpython-e131c9720d087c0c4988bd2a5c62020feb9d1d77.tar.bz2 |
Fix `mock.patch.dict` to be stopped with `mock.patch.stopall` (#17606)
As the function was not registering in the active patches, the mocks
started by `mock.patch.dict` were not being stopped when
`mock.patch.stopall` was being called.
-rw-r--r-- | Lib/unittest/mock.py | 19 | ||||
-rw-r--r-- | Lib/unittest/test/testmock/testpatch.py | 50 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2019-12-14-14-38-40.bpo-21600.kC4Cgh.rst | 2 |
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`. |