]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-93021: Fix __text_signature__ for __get__ (GH-93023)
authorJelle Zijlstra <jelle.zijlstra@gmail.com>
Tue, 21 Jun 2022 19:45:38 +0000 (12:45 -0700)
committerGitHub <noreply@github.com>
Tue, 21 Jun 2022 19:45:38 +0000 (21:45 +0200)
Because of the way wrap_descr_get is written, the second argument
to __get__ methods implemented through the wrapper is always
optional.

Lib/test/test_types.py
Misc/NEWS.d/next/Core and Builtins/2022-05-20-09-25-34.gh-issue-93021.k3Aji2.rst [new file with mode: 0644]
Objects/typeobject.c

index cde9dadc5e97fa982bccb8b9b93e92c635096dce..8556ca35ca06c125957ab3e8aa9e14f43846bece 100644 (file)
@@ -597,6 +597,12 @@ class TypesTests(unittest.TestCase):
         self.assertIsInstance(object.__lt__, types.WrapperDescriptorType)
         self.assertIsInstance(int.__lt__, types.WrapperDescriptorType)
 
+    def test_dunder_get_signature(self):
+        sig = inspect.signature(object.__init__.__get__)
+        self.assertEqual(list(sig.parameters), ["instance", "owner"])
+        # gh-93021: Second parameter is optional
+        self.assertIs(sig.parameters["owner"].default, None)
+
     def test_method_wrapper_types(self):
         self.assertIsInstance(object().__init__, types.MethodWrapperType)
         self.assertIsInstance(object().__str__, types.MethodWrapperType)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-20-09-25-34.gh-issue-93021.k3Aji2.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-20-09-25-34.gh-issue-93021.k3Aji2.rst
new file mode 100644 (file)
index 0000000..8fdd8df
--- /dev/null
@@ -0,0 +1,2 @@
+Fix the :attr:`__text_signature__` for :meth:`__get__` methods implemented
+in C. Patch by Jelle Zijlstra.
index 40df69e8b8315c2c2eb37619b5dce3edca325c80..5ebff6084f4a9726fd460886f6bcc329dc1c48b6 100644 (file)
@@ -7184,7 +7184,7 @@ wrap_descr_get(PyObject *self, PyObject *args, void *wrapped)
         obj = NULL;
     if (type == Py_None)
         type = NULL;
-    if (type == NULL &&obj == NULL) {
+    if (type == NULL && obj == NULL) {
         PyErr_SetString(PyExc_TypeError,
                         "__get__(None, None) is invalid");
         return NULL;
@@ -8209,7 +8209,7 @@ static slotdef slotdefs[] = {
     TPSLOT("__next__", tp_iternext, slot_tp_iternext, wrap_next,
            "__next__($self, /)\n--\n\nImplement next(self)."),
     TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get,
-           "__get__($self, instance, owner, /)\n--\n\nReturn an attribute of instance, which is of type owner."),
+           "__get__($self, instance, owner=None, /)\n--\n\nReturn an attribute of instance, which is of type owner."),
     TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set,
            "__set__($self, instance, value, /)\n--\n\nSet an attribute of instance to value."),
     TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set,