From 6a12931c9cb5d472fe6370dbcd2bde72f34dddb4 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 12 Dec 2018 00:58:36 -0800 Subject: [PATCH] bpo-17185: Add __signature__ to mock that can be used by inspect for signature (GH11125) * 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 (cherry picked from commit f7fa62ef4422c9deee050a794fd8504640d9f8f4) Co-authored-by: Xtreak --- Lib/unittest/mock.py | 6 ++-- Lib/unittest/test/testmock/testhelpers.py | 30 +++++++++++++++++++ .../2018-12-09-17-04-15.bpo-17185.SfSCJF.rst | 2 ++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-12-09-17-04-15.bpo-17185.SfSCJF.rst diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index f641e38dc54b..5907e5c240f5 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -102,6 +102,7 @@ def _check_signature(func, mock, skipfirst, instance=False): sig.bind(*args, **kwargs) _copy_func_details(func, checksig) type(mock)._mock_check_sig = checksig + type(mock).__signature__ = sig def _copy_func_details(func, funcopy): @@ -171,11 +172,11 @@ def _set_signature(mock, original, instance=False): return mock(*args, **kwargs)""" % name exec (src, context) funcopy = context[name] - _setup_func(funcopy, mock) + _setup_func(funcopy, mock, sig) return funcopy -def _setup_func(funcopy, mock): +def _setup_func(funcopy, mock, sig): funcopy.mock = mock # can't use isinstance with mocks @@ -223,6 +224,7 @@ def _setup_func(funcopy, mock): funcopy.assert_called = assert_called funcopy.assert_not_called = assert_not_called funcopy.assert_called_once = assert_called_once + funcopy.__signature__ = sig mock._mock_delegate = funcopy diff --git a/Lib/unittest/test/testmock/testhelpers.py b/Lib/unittest/test/testmock/testhelpers.py index 9388311e3e25..745580ef79db 100644 --- a/Lib/unittest/test/testmock/testhelpers.py +++ b/Lib/unittest/test/testmock/testhelpers.py @@ -1,3 +1,4 @@ +import inspect import time import types import unittest @@ -901,6 +902,35 @@ class SpecSignatureTest(unittest.TestCase): 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): def test_args_list_contains_call_list(self): diff --git a/Misc/NEWS.d/next/Library/2018-12-09-17-04-15.bpo-17185.SfSCJF.rst b/Misc/NEWS.d/next/Library/2018-12-09-17-04-15.bpo-17185.SfSCJF.rst new file mode 100644 index 000000000000..311c6d2b0e4e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-12-09-17-04-15.bpo-17185.SfSCJF.rst @@ -0,0 +1,2 @@ +Set ``__signature__`` on mock for :mod:`inspect` to get signature. +Patch by Karthikeyan Singaravelan. -- 2.47.3