Commit f7fa62ef authored by Xtreak's avatar Xtreak Committed by Chris Withers

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
parent 5344501a
...@@ -103,6 +103,7 @@ def _check_signature(func, mock, skipfirst, instance=False): ...@@ -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): ...@@ -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): ...@@ -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
......
import inspect
import time import time
import types import types
import unittest import unittest
...@@ -901,6 +902,35 @@ class SpecSignatureTest(unittest.TestCase): ...@@ -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):
......
Set ``__signature__`` on mock for :mod:`inspect` to get signature.
Patch by Karthikeyan Singaravelan.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment