diff -r de287a94b486 Lib/unittest/mock.py --- a/Lib/unittest/mock.py Tue Aug 05 14:01:10 2014 -0500 +++ b/Lib/unittest/mock.py Wed Aug 06 03:46:24 2014 -0500 @@ -1308,7 +1308,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 -r de287a94b486 Lib/unittest/test/testmock/testpatch.py --- a/Lib/unittest/test/testmock/testpatch.py Tue Aug 05 14:01:10 2014 -0500 +++ b/Lib/unittest/test/testmock/testpatch.py Wed Aug 06 03:46:24 2014 -0500 @@ -1797,5 +1797,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()