Skip to content

Commit f7fa62e

Browse files
tirkarthicjw296
authored andcommitted
bpo-17185: Add __signature__ to mock that can be used by inspect for signature (GH11048)
* Fix partial and partial method signatures in mock * Add more calls * Add NEWS entry * Use assertEquals and fix markup in NEWS * Refactor branching and add markup reference for functools * Revert partial object related changes and fix pr comments
1 parent 5344501 commit f7fa62e

3 files changed

Lines changed: 36 additions & 2 deletions

File tree

Lib/unittest/mock.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ def checksig(_mock_self, *args, **kwargs):
103103
sig.bind(*args, **kwargs)
104104
_copy_func_details(func, checksig)
105105
type(mock)._mock_check_sig = checksig
106+
type(mock).__signature__ = sig
106107

107108

108109
def _copy_func_details(func, funcopy):
@@ -172,11 +173,11 @@ def checksig(*args, **kwargs):
172173
return mock(*args, **kwargs)""" % name
173174
exec (src, context)
174175
funcopy = context[name]
175-
_setup_func(funcopy, mock)
176+
_setup_func(funcopy, mock, sig)
176177
return funcopy
177178

178179

179-
def _setup_func(funcopy, mock):
180+
def _setup_func(funcopy, mock, sig):
180181
funcopy.mock = mock
181182

182183
# can't use isinstance with mocks
@@ -224,6 +225,7 @@ def reset_mock():
224225
funcopy.assert_called = assert_called
225226
funcopy.assert_not_called = assert_not_called
226227
funcopy.assert_called_once = assert_called_once
228+
funcopy.__signature__ = sig
227229

228230
mock._mock_delegate = funcopy
229231

Lib/unittest/test/testmock/testhelpers.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import inspect
12
import time
23
import types
34
import unittest
@@ -901,6 +902,35 @@ def __getattr__(self, attribute):
901902
self.assertFalse(hasattr(autospec, '__name__'))
902903

903904

905+
def test_spec_inspect_signature(self):
906+
907+
def myfunc(x, y):
908+
pass
909+
910+
mock = create_autospec(myfunc)
911+
mock(1, 2)
912+
mock(x=1, y=2)
913+
914+
self.assertEqual(inspect.getfullargspec(mock), inspect.getfullargspec(myfunc))
915+
self.assertEqual(mock.mock_calls, [call(1, 2), call(x=1, y=2)])
916+
self.assertRaises(TypeError, mock, 1)
917+
918+
919+
def test_spec_inspect_signature_annotations(self):
920+
921+
def foo(a: int, b: int=10, *, c:int) -> int:
922+
return a + b + c
923+
924+
mock = create_autospec(foo)
925+
mock(1, 2, c=3)
926+
mock(1, c=3)
927+
928+
self.assertEqual(inspect.getfullargspec(mock), inspect.getfullargspec(foo))
929+
self.assertEqual(mock.mock_calls, [call(1, 2, c=3), call(1, c=3)])
930+
self.assertRaises(TypeError, mock, 1)
931+
self.assertRaises(TypeError, mock, 1, 2, 3, c=4)
932+
933+
904934
class TestCallList(unittest.TestCase):
905935

906936
def test_args_list_contains_call_list(self):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Set ``__signature__`` on mock for :mod:`inspect` to get signature.
2+
Patch by Karthikeyan Singaravelan.

0 commit comments

Comments
 (0)