mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
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
This commit is contained in:
parent
5344501ad1
commit
f7fa62ef44
3 changed files with 36 additions and 2 deletions
|
@ -103,6 +103,7 @@ def _check_signature(func, mock, skipfirst, instance=False):
|
||||||
sig.bind(*args, **kwargs)
|
sig.bind(*args, **kwargs)
|
||||||
_copy_func_details(func, checksig)
|
_copy_func_details(func, checksig)
|
||||||
type(mock)._mock_check_sig = checksig
|
type(mock)._mock_check_sig = checksig
|
||||||
|
type(mock).__signature__ = sig
|
||||||
|
|
||||||
|
|
||||||
def _copy_func_details(func, funcopy):
|
def _copy_func_details(func, funcopy):
|
||||||
|
@ -172,11 +173,11 @@ def _set_signature(mock, original, instance=False):
|
||||||
return mock(*args, **kwargs)""" % name
|
return mock(*args, **kwargs)""" % name
|
||||||
exec (src, context)
|
exec (src, context)
|
||||||
funcopy = context[name]
|
funcopy = context[name]
|
||||||
_setup_func(funcopy, mock)
|
_setup_func(funcopy, mock, sig)
|
||||||
return funcopy
|
return funcopy
|
||||||
|
|
||||||
|
|
||||||
def _setup_func(funcopy, mock):
|
def _setup_func(funcopy, mock, sig):
|
||||||
funcopy.mock = mock
|
funcopy.mock = mock
|
||||||
|
|
||||||
# can't use isinstance with mocks
|
# can't use isinstance with mocks
|
||||||
|
@ -224,6 +225,7 @@ def _setup_func(funcopy, mock):
|
||||||
funcopy.assert_called = assert_called
|
funcopy.assert_called = assert_called
|
||||||
funcopy.assert_not_called = assert_not_called
|
funcopy.assert_not_called = assert_not_called
|
||||||
funcopy.assert_called_once = assert_called_once
|
funcopy.assert_called_once = assert_called_once
|
||||||
|
funcopy.__signature__ = sig
|
||||||
|
|
||||||
mock._mock_delegate = funcopy
|
mock._mock_delegate = funcopy
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import inspect
|
||||||
import time
|
import time
|
||||||
import types
|
import types
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -901,6 +902,35 @@ class SpecSignatureTest(unittest.TestCase):
|
||||||
self.assertFalse(hasattr(autospec, '__name__'))
|
self.assertFalse(hasattr(autospec, '__name__'))
|
||||||
|
|
||||||
|
|
||||||
|
def test_spec_inspect_signature(self):
|
||||||
|
|
||||||
|
def myfunc(x, y):
|
||||||
|
pass
|
||||||
|
|
||||||
|
mock = create_autospec(myfunc)
|
||||||
|
mock(1, 2)
|
||||||
|
mock(x=1, y=2)
|
||||||
|
|
||||||
|
self.assertEqual(inspect.getfullargspec(mock), inspect.getfullargspec(myfunc))
|
||||||
|
self.assertEqual(mock.mock_calls, [call(1, 2), call(x=1, y=2)])
|
||||||
|
self.assertRaises(TypeError, mock, 1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_spec_inspect_signature_annotations(self):
|
||||||
|
|
||||||
|
def foo(a: int, b: int=10, *, c:int) -> int:
|
||||||
|
return a + b + c
|
||||||
|
|
||||||
|
mock = create_autospec(foo)
|
||||||
|
mock(1, 2, c=3)
|
||||||
|
mock(1, c=3)
|
||||||
|
|
||||||
|
self.assertEqual(inspect.getfullargspec(mock), inspect.getfullargspec(foo))
|
||||||
|
self.assertEqual(mock.mock_calls, [call(1, 2, c=3), call(1, c=3)])
|
||||||
|
self.assertRaises(TypeError, mock, 1)
|
||||||
|
self.assertRaises(TypeError, mock, 1, 2, 3, c=4)
|
||||||
|
|
||||||
|
|
||||||
class TestCallList(unittest.TestCase):
|
class TestCallList(unittest.TestCase):
|
||||||
|
|
||||||
def test_args_list_contains_call_list(self):
|
def test_args_list_contains_call_list(self):
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Set ``__signature__`` on mock for :mod:`inspect` to get signature.
|
||||||
|
Patch by Karthikeyan Singaravelan.
|
Loading…
Add table
Add a link
Reference in a new issue