[Python-checkins] cpython (merge 3.5 -> default): merge from 3.5

senthil.kumaran python-checkins at python.org
Sat Jan 9 02:44:18 EST 2016


https://hg.python.org/cpython/rev/9b21dfd71561
changeset:   99815:9b21dfd71561
parent:      99813:d733b6275e17
parent:      99814:b67ed559a7d3
user:        Senthil Kumaran <senthil at uthcode.com>
date:        Fri Jan 08 23:44:10 2016 -0800
summary:
  merge from 3.5

Issue #22138: Fix mock.patch behavior when patching descriptors. Restore
original values after patching.

Patch contributed by Sean McCully.

files:
  Lib/unittest/mock.py                    |   5 ++-
  Lib/unittest/test/testmock/testpatch.py |  26 +++++++++++++
  Misc/NEWS                               |   3 +
  3 files changed, 33 insertions(+), 1 deletions(-)


diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -1332,7 +1332,10 @@
             setattr(self.target, self.attribute, self.temp_original)
         else:
             delattr(self.target, self.attribute)
-            if not self.create and not hasattr(self.target, self.attribute):
+            if not self.create and (not hasattr(self.target, self.attribute) or
+                        self.attribute in ('__doc__', '__module__',
+                                           '__defaults__', '__annotations__',
+                                           '__kwdefaults__')):
                 # needed for proxy objects like django settings
                 setattr(self.target, self.attribute, self.temp_original)
 
diff --git a/Lib/unittest/test/testmock/testpatch.py b/Lib/unittest/test/testmock/testpatch.py
--- a/Lib/unittest/test/testmock/testpatch.py
+++ b/Lib/unittest/test/testmock/testpatch.py
@@ -1817,5 +1817,31 @@
         self.assertEqual(stopped, ["three", "two", "one"])
 
 
+    def test_special_attrs(self):
+        def foo(x=0):
+            """TEST"""
+            return x
+        with patch.object(foo, '__defaults__', (1, )):
+            self.assertEqual(foo(), 1)
+        self.assertEqual(foo(), 0)
+
+        with patch.object(foo, '__doc__', "FUN"):
+            self.assertEqual(foo.__doc__, "FUN")
+        self.assertEqual(foo.__doc__, "TEST")
+
+        with patch.object(foo, '__module__', "testpatch2"):
+            self.assertEqual(foo.__module__, "testpatch2")
+        self.assertEqual(foo.__module__, 'unittest.test.testmock.testpatch')
+
+        with patch.object(foo, '__annotations__', dict([('s', 1, )])):
+            self.assertEqual(foo.__annotations__, dict([('s', 1, )]))
+        self.assertEqual(foo.__annotations__, dict())
+
+        def foo(*a, x=0):
+            return x
+        with patch.object(foo, '__kwdefaults__', dict([('x', 1, )])):
+            self.assertEqual(foo(), 1)
+        self.assertEqual(foo(), 0)
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -128,6 +128,9 @@
 Library
 -------
 
+- Issue #22138: Fix mock.patch behavior when patching descriptors. Restore
+  original values after patching. Patch contributed by Sean McCully.
+
 - Issue #25672: In the ssl module, enable the SSL_MODE_RELEASE_BUFFERS mode
   option if it is safe to do so.
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list