Browse Source

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

Automerge-Triggered-By: GH:pablogsal
pull/30421/head
Inada Naoki 4 years ago
committed by GitHub
parent
commit
46e4c257e7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      Misc/NEWS.d/next/C API/2022-01-05-10-16-16.bpo-46236.pcmVQw.rst
  2. 55
      Objects/funcobject.c

1
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``.

55
Objects/funcobject.c

@ -274,6 +274,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)
{
@ -281,7 +312,7 @@ PyFunction_GetAnnotations(PyObject *op)
PyErr_BadInternalCall();
return NULL;
}
return ((PyFunctionObject *) op) -> func_annotations;
return func_get_annotation_dict((PyFunctionObject *)op);
}
int
@ -501,27 +532,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

Loading…
Cancel
Save