Skip to content

Commit 46e4c25

Browse files
authored
bpo-46236: Fix PyFunction_GetAnnotations() returned tuple. (GH-30409)
Automerge-Triggered-By: GH:pablogsal
1 parent dd50316 commit 46e4c25

File tree

2 files changed

+34
-22
lines changed

2 files changed

+34
-22
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a bug in :c:func:`PyFunction_GetAnnotations` that caused it to return a ``tuple`` instead of a ``dict``.

Objects/funcobject.c

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -274,14 +274,45 @@ PyFunction_SetClosure(PyObject *op, PyObject *closure)
274274
return 0;
275275
}
276276

277+
static PyObject *
278+
func_get_annotation_dict(PyFunctionObject *op)
279+
{
280+
if (op->func_annotations == NULL) {
281+
return NULL;
282+
}
283+
if (PyTuple_CheckExact(op->func_annotations)) {
284+
PyObject *ann_tuple = op->func_annotations;
285+
PyObject *ann_dict = PyDict_New();
286+
if (ann_dict == NULL) {
287+
return NULL;
288+
}
289+
290+
assert(PyTuple_GET_SIZE(ann_tuple) % 2 == 0);
291+
292+
for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(ann_tuple); i += 2) {
293+
int err = PyDict_SetItem(ann_dict,
294+
PyTuple_GET_ITEM(ann_tuple, i),
295+
PyTuple_GET_ITEM(ann_tuple, i + 1));
296+
297+
if (err < 0) {
298+
return NULL;
299+
}
300+
}
301+
Py_SETREF(op->func_annotations, ann_dict);
302+
}
303+
Py_INCREF(op->func_annotations);
304+
assert(PyDict_Check(op->func_annotations));
305+
return op->func_annotations;
306+
}
307+
277308
PyObject *
278309
PyFunction_GetAnnotations(PyObject *op)
279310
{
280311
if (!PyFunction_Check(op)) {
281312
PyErr_BadInternalCall();
282313
return NULL;
283314
}
284-
return ((PyFunctionObject *) op) -> func_annotations;
315+
return func_get_annotation_dict((PyFunctionObject *)op);
285316
}
286317

287318
int
@@ -501,27 +532,7 @@ func_get_annotations(PyFunctionObject *op, void *Py_UNUSED(ignored))
501532
if (op->func_annotations == NULL)
502533
return NULL;
503534
}
504-
if (PyTuple_CheckExact(op->func_annotations)) {
505-
PyObject *ann_tuple = op->func_annotations;
506-
PyObject *ann_dict = PyDict_New();
507-
if (ann_dict == NULL) {
508-
return NULL;
509-
}
510-
511-
assert(PyTuple_GET_SIZE(ann_tuple) % 2 == 0);
512-
513-
for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(ann_tuple); i += 2) {
514-
int err = PyDict_SetItem(ann_dict,
515-
PyTuple_GET_ITEM(ann_tuple, i),
516-
PyTuple_GET_ITEM(ann_tuple, i + 1));
517-
518-
if (err < 0)
519-
return NULL;
520-
}
521-
Py_SETREF(op->func_annotations, ann_dict);
522-
}
523-
Py_INCREF(op->func_annotations);
524-
return op->func_annotations;
535+
return func_get_annotation_dict(op);
525536
}
526537

527538
static int

0 commit comments

Comments
 (0)