mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
[3.12] gh-106719: Fix __annotations__ getter and setter in the type and module types (GH-106720) (GH-106848)
gh-106719: Fix __annotations__ getter and setter in the type and module types (GH-106720)
No longer suppress arbitrary errors. Simplify the code.
(cherry picked from commit e1c295e3da
)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
e903c16a6c
commit
d671c6567a
3 changed files with 35 additions and 47 deletions
|
@ -0,0 +1,2 @@
|
||||||
|
No longer suppress arbitrary errors in the ``__annotations__`` getter and
|
||||||
|
setter in the type and module types.
|
|
@ -935,26 +935,20 @@ static PyObject *
|
||||||
module_get_annotations(PyModuleObject *m, void *Py_UNUSED(ignored))
|
module_get_annotations(PyModuleObject *m, void *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
PyObject *dict = PyObject_GetAttr((PyObject *)m, &_Py_ID(__dict__));
|
PyObject *dict = PyObject_GetAttr((PyObject *)m, &_Py_ID(__dict__));
|
||||||
|
if (dict == NULL) {
|
||||||
if ((dict == NULL) || !PyDict_Check(dict)) {
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!PyDict_Check(dict)) {
|
||||||
PyErr_Format(PyExc_TypeError, "<module>.__dict__ is not a dictionary");
|
PyErr_Format(PyExc_TypeError, "<module>.__dict__ is not a dictionary");
|
||||||
Py_XDECREF(dict);
|
Py_DECREF(dict);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *annotations;
|
PyObject *annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__));
|
||||||
/* there's no _PyDict_GetItemId without WithError, so let's LBYL. */
|
|
||||||
if (PyDict_Contains(dict, &_Py_ID(__annotations__))) {
|
|
||||||
annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__));
|
|
||||||
/*
|
|
||||||
** _PyDict_GetItemIdWithError could still fail,
|
|
||||||
** for instance with a well-timed Ctrl-C or a MemoryError.
|
|
||||||
** so let's be totally safe.
|
|
||||||
*/
|
|
||||||
if (annotations) {
|
if (annotations) {
|
||||||
Py_INCREF(annotations);
|
Py_INCREF(annotations);
|
||||||
}
|
}
|
||||||
} else {
|
else if (!PyErr_Occurred()) {
|
||||||
annotations = PyDict_New();
|
annotations = PyDict_New();
|
||||||
if (annotations) {
|
if (annotations) {
|
||||||
int result = PyDict_SetItem(
|
int result = PyDict_SetItem(
|
||||||
|
@ -973,8 +967,10 @@ module_set_annotations(PyModuleObject *m, PyObject *value, void *Py_UNUSED(ignor
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
PyObject *dict = PyObject_GetAttr((PyObject *)m, &_Py_ID(__dict__));
|
PyObject *dict = PyObject_GetAttr((PyObject *)m, &_Py_ID(__dict__));
|
||||||
|
if (dict == NULL) {
|
||||||
if ((dict == NULL) || !PyDict_Check(dict)) {
|
return -1;
|
||||||
|
}
|
||||||
|
if (!PyDict_Check(dict)) {
|
||||||
PyErr_Format(PyExc_TypeError, "<module>.__dict__ is not a dictionary");
|
PyErr_Format(PyExc_TypeError, "<module>.__dict__ is not a dictionary");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
@ -982,19 +978,17 @@ module_set_annotations(PyModuleObject *m, PyObject *value, void *Py_UNUSED(ignor
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
/* set */
|
/* set */
|
||||||
ret = PyDict_SetItem(dict, &_Py_ID(__annotations__), value);
|
ret = PyDict_SetItem(dict, &_Py_ID(__annotations__), value);
|
||||||
goto exit;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
/* delete */
|
/* delete */
|
||||||
if (!PyDict_Contains(dict, &_Py_ID(__annotations__))) {
|
|
||||||
PyErr_Format(PyExc_AttributeError, "__annotations__");
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = PyDict_DelItem(dict, &_Py_ID(__annotations__));
|
ret = PyDict_DelItem(dict, &_Py_ID(__annotations__));
|
||||||
|
if (ret < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) {
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "__annotations__");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(dict);
|
Py_DECREF(dict);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1449,15 +1449,8 @@ type_get_annotations(PyTypeObject *type, void *context)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *annotations;
|
PyObject *annotations;
|
||||||
/* there's no _PyDict_GetItemId without WithError, so let's LBYL. */
|
|
||||||
PyObject *dict = lookup_tp_dict(type);
|
PyObject *dict = lookup_tp_dict(type);
|
||||||
if (PyDict_Contains(dict, &_Py_ID(__annotations__))) {
|
|
||||||
annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__));
|
annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__));
|
||||||
/*
|
|
||||||
** PyDict_GetItemWithError could still fail,
|
|
||||||
** for instance with a well-timed Ctrl-C or a MemoryError.
|
|
||||||
** so let's be totally safe.
|
|
||||||
*/
|
|
||||||
if (annotations) {
|
if (annotations) {
|
||||||
if (Py_TYPE(annotations)->tp_descr_get) {
|
if (Py_TYPE(annotations)->tp_descr_get) {
|
||||||
annotations = Py_TYPE(annotations)->tp_descr_get(
|
annotations = Py_TYPE(annotations)->tp_descr_get(
|
||||||
|
@ -1466,7 +1459,7 @@ type_get_annotations(PyTypeObject *type, void *context)
|
||||||
Py_INCREF(annotations);
|
Py_INCREF(annotations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
else if (!PyErr_Occurred()) {
|
||||||
annotations = PyDict_New();
|
annotations = PyDict_New();
|
||||||
if (annotations) {
|
if (annotations) {
|
||||||
int result = PyDict_SetItem(
|
int result = PyDict_SetItem(
|
||||||
|
@ -1498,11 +1491,10 @@ type_set_annotations(PyTypeObject *type, PyObject *value, void *context)
|
||||||
result = PyDict_SetItem(dict, &_Py_ID(__annotations__), value);
|
result = PyDict_SetItem(dict, &_Py_ID(__annotations__), value);
|
||||||
} else {
|
} else {
|
||||||
/* delete */
|
/* delete */
|
||||||
if (!PyDict_Contains(dict, &_Py_ID(__annotations__))) {
|
|
||||||
PyErr_Format(PyExc_AttributeError, "__annotations__");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
result = PyDict_DelItem(dict, &_Py_ID(__annotations__));
|
result = PyDict_DelItem(dict, &_Py_ID(__annotations__));
|
||||||
|
if (result < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) {
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "__annotations__");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue