diff options
author | Xtreak <tir.karthi@gmail.com> | 2019-02-24 18:54:49 (GMT) |
---|---|---|
committer | Chris Withers <chris@withers.org> | 2019-02-24 18:54:49 (GMT) |
commit | a875ea58b29fbf510f9790ae1653eeaa47dc0de8 (patch) | |
tree | 076c625afd240521c200df9b98485846f32687a4 | |
parent | aeca373b339e0ea9739536ce6b43bd90f3b89873 (diff) | |
download | cpython-a875ea58b29fbf510f9790ae1653eeaa47dc0de8.zip cpython-a875ea58b29fbf510f9790ae1653eeaa47dc0de8.tar.gz cpython-a875ea58b29fbf510f9790ae1653eeaa47dc0de8.tar.bz2 |
bpo-35512: Resolve string target to patch.dict decorator during function call GH#12000
* Resolve string target to patch.dict during function call
* Add NEWS entry
* Remove unneeded call
* Restore original value for support.target and refactor assertions
* Add extra assertion to verify unpatched dict
-rw-r--r-- | Lib/unittest/mock.py | 4 | ||||
-rw-r--r-- | Lib/unittest/test/testmock/support.py | 3 | ||||
-rw-r--r-- | Lib/unittest/test/testmock/testpatch.py | 17 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2019-02-24-00-04-10.bpo-35512.eWDjCJ.rst | 3 |
4 files changed, 25 insertions, 2 deletions
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 8f46050..ccbcd35 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -1620,8 +1620,6 @@ class _patch_dict(object): """ def __init__(self, in_dict, values=(), clear=False, **kwargs): - if isinstance(in_dict, str): - in_dict = _importer(in_dict) self.in_dict = in_dict # support any argument supported by dict(...) constructor self.values = dict(values) @@ -1662,6 +1660,8 @@ class _patch_dict(object): def _patch_dict(self): values = self.values + if isinstance(self.in_dict, str): + self.in_dict = _importer(self.in_dict) in_dict = self.in_dict clear = self.clear diff --git a/Lib/unittest/test/testmock/support.py b/Lib/unittest/test/testmock/support.py index c7ad20b..f146be2 100644 --- a/Lib/unittest/test/testmock/support.py +++ b/Lib/unittest/test/testmock/support.py @@ -1,3 +1,6 @@ +target = {'foo': 'FOO'} + + def is_instance(obj, klass): """Version of is_instance that doesn't access __class__""" return issubclass(type(obj), klass) diff --git a/Lib/unittest/test/testmock/testpatch.py b/Lib/unittest/test/testmock/testpatch.py index f052257..c484adb 100644 --- a/Lib/unittest/test/testmock/testpatch.py +++ b/Lib/unittest/test/testmock/testpatch.py @@ -664,6 +664,23 @@ class PatchTest(unittest.TestCase): test() + def test_patch_dict_decorator_resolution(self): + # bpo-35512: Ensure that patch with a string target resolves to + # the new dictionary during function call + original = support.target.copy() + + @patch.dict('unittest.test.testmock.support.target', {'bar': 'BAR'}) + def test(): + self.assertEqual(support.target, {'foo': 'BAZ', 'bar': 'BAR'}) + + try: + support.target = {'foo': 'BAZ'} + test() + self.assertEqual(support.target, {'foo': 'BAZ'}) + finally: + support.target = original + + def test_patch_descriptor(self): # would be some effort to fix this - we could special case the # builtin descriptors: classmethod, property, staticmethod diff --git a/Misc/NEWS.d/next/Library/2019-02-24-00-04-10.bpo-35512.eWDjCJ.rst b/Misc/NEWS.d/next/Library/2019-02-24-00-04-10.bpo-35512.eWDjCJ.rst new file mode 100644 index 0000000..8281b1b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-02-24-00-04-10.bpo-35512.eWDjCJ.rst @@ -0,0 +1,3 @@ +:func:`unittest.mock.patch.dict` used as a decorator with string target +resolves the target during function call instead of during decorator +construction. Patch by Karthikeyan Singaravelan. |