Skip to content

Commit 2c68684

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

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
@@ -1226,6 +1227,40 @@ def unbound_f(self, n):
12261227
)
12271228

12281229

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

0 commit comments

Comments
 (0)