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.
This commit is contained in:
Mario Corchero 2020-01-24 08:38:33 +00:00 committed by Chris Withers
parent 1d0c5e16ea
commit e131c9720d
3 changed files with 69 additions and 2 deletions

View File

@ -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):

View File

@ -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):

View File

@ -0,0 +1,2 @@
Fix :func:`mock.patch.stopall` to stop active patches that were created with
:func:`mock.patch.dict`.