[Python-checkins] bpo-46236: Fix PyFunction_GetAnnotations() returned tuple. (GH-30409)

miss-islington webhook-mailer at python.org
Wed Jan 5 08:12:27 EST 2022


https://github.com/python/cpython/commit/da8be157f4e275c4c32b9199f1466ed7e52f62cf
commit: da8be157f4e275c4c32b9199f1466ed7e52f62cf
branch: 3.10
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2022-01-05T05:12:21-08:00
summary:

bpo-46236: Fix PyFunction_GetAnnotations() returned tuple. (GH-30409)


Automerge-Triggered-By: GH:pablogsal
(cherry picked from commit 46e4c257e7c26c813620232135781e6c53fe8d4d)

Co-authored-by: Inada Naoki <songofacandy at gmail.com>

files:
A Misc/NEWS.d/next/C API/2022-01-05-10-16-16.bpo-46236.pcmVQw.rst
M Objects/funcobject.c

diff --git a/Misc/NEWS.d/next/C API/2022-01-05-10-16-16.bpo-46236.pcmVQw.rst b/Misc/NEWS.d/next/C API/2022-01-05-10-16-16.bpo-46236.pcmVQw.rst
new file mode 100644
index 0000000000000..61906584a16a3
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2022-01-05-10-16-16.bpo-46236.pcmVQw.rst	
@@ -0,0 +1 @@
+Fix a bug in :c:func:`PyFunction_GetAnnotations` that caused it to return a ``tuple`` instead of a ``dict``.
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index da648b7a0ebad..801478ade22f6 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -221,6 +221,37 @@ PyFunction_SetClosure(PyObject *op, PyObject *closure)
     return 0;
 }
 
+static PyObject *
+func_get_annotation_dict(PyFunctionObject *op)
+{
+    if (op->func_annotations == NULL) {
+        return NULL;
+    }
+    if (PyTuple_CheckExact(op->func_annotations)) {
+        PyObject *ann_tuple = op->func_annotations;
+        PyObject *ann_dict = PyDict_New();
+        if (ann_dict == NULL) {
+            return NULL;
+        }
+
+        assert(PyTuple_GET_SIZE(ann_tuple) % 2 == 0);
+
+        for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(ann_tuple); i += 2) {
+            int err = PyDict_SetItem(ann_dict,
+                                     PyTuple_GET_ITEM(ann_tuple, i),
+                                     PyTuple_GET_ITEM(ann_tuple, i + 1));
+
+            if (err < 0) {
+                return NULL;
+            }
+        }
+        Py_SETREF(op->func_annotations, ann_dict);
+    }
+    Py_INCREF(op->func_annotations);
+    assert(PyDict_Check(op->func_annotations));
+    return op->func_annotations;
+}
+
 PyObject *
 PyFunction_GetAnnotations(PyObject *op)
 {
@@ -228,7 +259,7 @@ PyFunction_GetAnnotations(PyObject *op)
         PyErr_BadInternalCall();
         return NULL;
     }
-    return ((PyFunctionObject *) op) -> func_annotations;
+    return func_get_annotation_dict((PyFunctionObject *)op);
 }
 
 int
@@ -443,27 +474,7 @@ func_get_annotations(PyFunctionObject *op, void *Py_UNUSED(ignored))
         if (op->func_annotations == NULL)
             return NULL;
     }
-    if (PyTuple_CheckExact(op->func_annotations)) {
-        PyObject *ann_tuple = op->func_annotations;
-        PyObject *ann_dict = PyDict_New();
-        if (ann_dict == NULL) {
-            return NULL;
-        }
-
-        assert(PyTuple_GET_SIZE(ann_tuple) % 2 == 0);
-
-        for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(ann_tuple); i += 2) {
-            int err = PyDict_SetItem(ann_dict,
-                                     PyTuple_GET_ITEM(ann_tuple, i),
-                                     PyTuple_GET_ITEM(ann_tuple, i + 1));
-
-            if (err < 0)
-                return NULL;
-        }
-        Py_SETREF(op->func_annotations, ann_dict);
-    }
-    Py_INCREF(op->func_annotations);
-    return op->func_annotations;
+    return func_get_annotation_dict(op);
 }
 
 static int



More information about the Python-checkins mailing list