diff options
| author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2022-01-05 13:12:21 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-01-05 13:12:21 (GMT) |
| commit | da8be157f4e275c4c32b9199f1466ed7e52f62cf (patch) | |
| tree | 366ed1099d264eef151ae62b2d08c57c3b52ca1a | |
| parent | 7e951f356ec76a5a5fdb851d71df5d120014bf3f (diff) | |
| download | cpython-da8be157f4e275c4c32b9199f1466ed7e52f62cf.zip cpython-da8be157f4e275c4c32b9199f1466ed7e52f62cf.tar.gz cpython-da8be157f4e275c4c32b9199f1466ed7e52f62cf.tar.bz2 | |
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@gmail.com>
| -rw-r--r-- | Misc/NEWS.d/next/C API/2022-01-05-10-16-16.bpo-46236.pcmVQw.rst | 1 | ||||
| -rw-r--r-- | Objects/funcobject.c | 55 |
2 files changed, 34 insertions, 22 deletions
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 0000000..6190658 --- /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 da648b7..801478a 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 |
