[Python-checkins] bpo-35512: Resolve string target to patch.dict decorator during function call GHGH-12000 (#12021)

Chris Withers webhook-mailer at python.org
Mon Feb 25 16:17:21 EST 2019


https://github.com/python/cpython/commit/ea199b90bb61866cd3c2f154341d1eb0d5c4a710
commit: ea199b90bb61866cd3c2f154341d1eb0d5c4a710
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Chris Withers <chris at withers.org>
date: 2019-02-25T21:17:16Z
summary:

bpo-35512: Resolve string target to patch.dict decorator during function call GHGH-12000 (#12021)

* 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
(cherry picked from commit a875ea58b29fbf510f9790ae1653eeaa47dc0de8)

Co-authored-by: Xtreak <tir.karthi at gmail.com>

files:
A Misc/NEWS.d/next/Library/2019-02-24-00-04-10.bpo-35512.eWDjCJ.rst
M Lib/unittest/mock.py
M Lib/unittest/test/testmock/support.py
M Lib/unittest/test/testmock/testpatch.py

diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 42fbc22e748c..c97ea7984a6e 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -1595,8 +1595,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)
@@ -1637,6 +1635,8 @@ def __enter__(self):
 
     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 205431adcacc..73e406f0a86f 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 f05225730daf..c484adb60508 100644
--- a/Lib/unittest/test/testmock/testpatch.py
+++ b/Lib/unittest/test/testmock/testpatch.py
@@ -664,6 +664,23 @@ def test():
         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 000000000000..8281b1b2c49a
--- /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.



More information about the Python-checkins mailing list