Skip to content

Commit 566cf95

Browse files
committed
bpo-32092: Adds a mock autospec test for stacked decorators
Signed-off-by: Claudiu Belu <cbelu@cloudbasesolutions.com>
1 parent f31b883 commit 566cf95

1 file changed

Lines changed: 35 additions & 0 deletions

File tree

‎Lib/test/test_unittest/testmock/testpatch.py‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# E-mail: fuzzyman AT voidspace DOT org DOT uk
33
# http://www.voidspace.org.uk/python/mock/
44

5+
import functools
56
import os
67
import sys
78
from collections import OrderedDict
@@ -1227,6 +1228,40 @@ def unbound_f(self, n):
12271228
)
12281229

12291230

1231+
def test_autospec_stacked_functools_wraps_decorators(self):
1232+
# a method wrapped by 2+ layers of functools.wraps decorators will have
1233+
# a chain of __wrapped__ attributes. autospec must still see the
1234+
# original method's (self, ...) signature through that chain and
1235+
# strip `self`, rather than falling back to (*args, **kwargs) and
1236+
# miscounting positional arguments.
1237+
def bar(f):
1238+
@functools.wraps(f)
1239+
def wrapper(*args, **kwargs):
1240+
return f(*args, **kwargs)
1241+
return wrapper
1242+
1243+
def tender(f):
1244+
@functools.wraps(f)
1245+
def wrapper(*args, **kwargs):
1246+
return f(*args, **kwargs)
1247+
return wrapper
1248+
1249+
class Foo:
1250+
@bar
1251+
@tender
1252+
def f(self, a, b):
1253+
return ('real', a, b)
1254+
1255+
with patch.object(Foo, 'f', autospec=True, wraps=Foo.f) as method:
1256+
foo = Foo()
1257+
self.assertEqual(foo.f(1, 2), ('real', 1, 2))
1258+
method.assert_called_once_with(1, 2)
1259+
1260+
self.assertRaises(TypeError, foo.f)
1261+
self.assertRaises(TypeError, foo.f, 1)
1262+
self.assertRaises(TypeError, foo.f, 1, 2, 3)
1263+
1264+
12301265
def test_autospec_with_new(self):
12311266
patcher = patch('%s.function' % __name__, new=3, autospec=True)
12321267
self.assertRaises(TypeError, patcher.start)

0 commit comments

Comments
 (0)