From 10d3600ea6988c81eaca44a0dc489a9b6c3c0436 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 29 Apr 2024 21:51:33 +0300 Subject: [PATCH] gh-118402: Fix inspect.signature() for functools.cmp_to_key() result --- Lib/test/test_functools.py | 12 +++++++++--- .../2024-04-29-21-51-28.gh-issue-118402.Z_06Th.rst | 2 ++ Modules/_functoolsmodule.c | 12 ++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-04-29-21-51-28.gh-issue-118402.Z_06Th.rst diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index bb4c7cc8701fb4..4a9a7313712f60 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -947,8 +947,13 @@ def mycmp(x, y): @unittest.skipIf(support.MISSING_C_DOCSTRINGS, "Signature information for builtins requires docstrings") def test_cmp_to_signature(self): - self.assertEqual(str(Signature.from_callable(self.cmp_to_key)), - '(mycmp)') + sig = Signature.from_callable(self.cmp_to_key) + self.assertEqual(str(sig), '(mycmp)') + def mycmp(x, y): + return y - x + sig = Signature.from_callable(self.cmp_to_key(mycmp)) + self.assertEqual(str(sig), '(obj)') + @unittest.skipUnless(c_functools, 'requires the C _functools module') @@ -1864,9 +1869,10 @@ def test_staticmethod(x): self.assertIsNone(ref()) def test_common_signatures(self): - def orig(): ... + def orig(a, /, b, c=True): ... lru = self.module.lru_cache(1)(orig) + self.assertEqual(str(Signature.from_callable(lru)), '(a, /, b, c=True)') self.assertEqual(str(Signature.from_callable(lru.cache_info)), '()') self.assertEqual(str(Signature.from_callable(lru.cache_clear)), '()') diff --git a/Misc/NEWS.d/next/Library/2024-04-29-21-51-28.gh-issue-118402.Z_06Th.rst b/Misc/NEWS.d/next/Library/2024-04-29-21-51-28.gh-issue-118402.Z_06Th.rst new file mode 100644 index 00000000000000..25d7b45b8726c9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-04-29-21-51-28.gh-issue-118402.Z_06Th.rst @@ -0,0 +1,2 @@ +Fix :func:`inspect.signature` for the result of the +:func:`functools.cmp_to_key` call. diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 406fcf0da2f7e4..e37473a582b55f 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -571,6 +571,17 @@ static PyMemberDef keyobject_members[] = { {NULL} }; +static PyObject * +keyobject_text_signature(PyObject *self, void *Py_UNUSED(ignored)) +{ + return PyUnicode_FromString("(obj)"); +} + +static PyGetSetDef keyobject_getset[] = { + {"__text_signature__", keyobject_text_signature, (setter)NULL}, + {NULL} +}; + static PyObject * keyobject_call(keyobject *ko, PyObject *args, PyObject *kwds); @@ -585,6 +596,7 @@ static PyType_Slot keyobject_type_slots[] = { {Py_tp_clear, keyobject_clear}, {Py_tp_richcompare, keyobject_richcompare}, {Py_tp_members, keyobject_members}, + {Py_tp_getset, keyobject_getset}, {0, 0} };