From 01d94ca1533e0af74792a199e50783f69e7bad64 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Sat, 7 Jan 2023 13:49:15 +0300 Subject: [PATCH] gh-96127: Fix `inspect.signature` call on mocks (#96335) (cherry picked from commit 9e7d7266ecdcccc02385fe4ccb094f3444102e26) --- Lib/test/test_inspect.py | 19 +++++++++++++++++++ Lib/unittest/mock.py | 10 +++++++++- ...2-08-27-10-35-50.gh-issue-96127.8RdLre.rst | 2 ++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2022-08-27-10-35-50.gh-issue-96127.8RdLre.rst diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 9ea49854cbc636..c50486003a4dab 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -3238,6 +3238,25 @@ def test_signature_on_lambdas(self): ((('a', 10, ..., "positional_or_keyword"),), ...)) + def test_signature_on_mocks(self): + # https://github.com/python/cpython/issues/96127 + for mock in ( + unittest.mock.Mock(), + unittest.mock.AsyncMock(), + unittest.mock.MagicMock(), + ): + with self.subTest(mock=mock): + self.assertEqual(str(inspect.signature(mock)), '(*args, **kwargs)') + + def test_signature_on_noncallable_mocks(self): + for mock in ( + unittest.mock.NonCallableMock(), + unittest.mock.NonCallableMagicMock(), + ): + with self.subTest(mock=mock): + with self.assertRaises(TypeError): + inspect.signature(mock) + def test_signature_equality(self): def foo(a, *, b:int) -> float: pass self.assertFalse(inspect.signature(foo) == 42) diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index fa0bd9131a21e7..54bd3ecdd76f14 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -2201,7 +2201,15 @@ def __init__(self, /, *args, **kwargs): self.__dict__['_mock_await_args'] = None self.__dict__['_mock_await_args_list'] = _CallList() code_mock = NonCallableMock(spec_set=CodeType) - code_mock.co_flags = inspect.CO_COROUTINE + code_mock.co_flags = ( + inspect.CO_COROUTINE + + inspect.CO_VARARGS + + inspect.CO_VARKEYWORDS + ) + code_mock.co_argcount = 0 + code_mock.co_varnames = ('args', 'kwargs') + code_mock.co_posonlyargcount = 0 + code_mock.co_kwonlyargcount = 0 self.__dict__['__code__'] = code_mock self.__dict__['__name__'] = 'AsyncMock' self.__dict__['__defaults__'] = tuple() diff --git a/Misc/NEWS.d/next/Library/2022-08-27-10-35-50.gh-issue-96127.8RdLre.rst b/Misc/NEWS.d/next/Library/2022-08-27-10-35-50.gh-issue-96127.8RdLre.rst new file mode 100644 index 00000000000000..79edd8fd5d8f40 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-27-10-35-50.gh-issue-96127.8RdLre.rst @@ -0,0 +1,2 @@ +``inspect.signature`` was raising ``TypeError`` on call with mock objects. +Now it correctly returns ``(*args, **kwargs)`` as infered signature.