bpo-35512: Resolve string target to patch.dict decorator during funct… · python/cpython@ea199b9 (original) (raw)

4 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -1595,8 +1595,6 @@ class _patch_dict(object):
1595 1595 """
1596 1596
1597 1597 def __init__(self, in_dict, values=(), clear=False, **kwargs):
1598 -if isinstance(in_dict, str):
1599 -in_dict = _importer(in_dict)
1600 1598 self.in_dict = in_dict
1601 1599 # support any argument supported by dict(...) constructor
1602 1600 self.values = dict(values)
@@ -1637,6 +1635,8 @@ def __enter__(self):
1637 1635
1638 1636 def _patch_dict(self):
1639 1637 values = self.values
1638 +if isinstance(self.in_dict, str):
1639 +self.in_dict = _importer(self.in_dict)
1640 1640 in_dict = self.in_dict
1641 1641 clear = self.clear
1642 1642
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
1 +target = {'foo': 'FOO'}
2 +
3 +
1 4 def is_instance(obj, klass):
2 5 """Version of is_instance that doesn't access __class__"""
3 6 return issubclass(type(obj), klass)
Original file line number Diff line number Diff line change
@@ -664,6 +664,23 @@ def test():
664 664 test()
665 665
666 666
667 +def test_patch_dict_decorator_resolution(self):
668 +# bpo-35512: Ensure that patch with a string target resolves to
669 +# the new dictionary during function call
670 +original = support.target.copy()
671 +
672 +@patch.dict('unittest.test.testmock.support.target', {'bar': 'BAR'})
673 +def test():
674 +self.assertEqual(support.target, {'foo': 'BAZ', 'bar': 'BAR'})
675 +
676 +try:
677 +support.target = {'foo': 'BAZ'}
678 +test()
679 +self.assertEqual(support.target, {'foo': 'BAZ'})
680 +finally:
681 +support.target = original
682 +
683 +
667 684 def test_patch_descriptor(self):
668 685 # would be some effort to fix this - we could special case the
669 686 # builtin descriptors: classmethod, property, staticmethod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
1 +:func:`unittest.mock.patch.dict` used as a decorator with string target
2 +resolves the target during function call instead of during decorator
3 +construction. Patch by Karthikeyan Singaravelan.