8000 [3.11] gh-106719: Fix __annotations__ getter and setter in the type a… · python/cpython@fb04874 · GitHub
[go: up one dir, main page]

Skip to content

Commit fb04874

Browse files
[3.11] gh-106719: Fix __annotations__ getter and setter in the type and module types (GH-106720) (GH-106850)
No longer suppress arbitrary errors. Simplify the code. (cherry picked from commit e1c295e)
1 parent a7acc5c commit fb04874

File tree

3 files changed

+35
-48
lines changed

3 files changed

+35
-48
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
No longer suppress arbitrary errors in the ``__annotations__`` getter and
2+
setter in the type and module types.

Objects/moduleobject.c

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -881,26 +881,20 @@ static PyObject *
881881
module_get_annotations(PyModuleObject *m, void *Py_UNUSED(ignored))
882882
{
883883
PyObject *dict = PyObject_GetAttr((PyObject *)m, &_Py_ID(__dict__));
884-
885-
if ((dict == NULL) || !PyDict_Check(dict)) {
884+
if (dict == NULL) {
885+
return NULL;
886+
}
887+
if (!PyDict_Check(dict)) {
886888
PyErr_Format(PyExc_TypeError, "<module>.__dict__ is not a dictionary");
887-
Py_XDECREF(dict);
889+
Py_DECREF(dict);
888890
return NULL;
889891
}
890892

891-
PyObject *annotations;
892-
/* there's no _PyDict_GetItemId without WithError, so let's LBYL. */
893-
if (PyDict_Contains(dict, &_Py_ID(__annotations__))) {
894-
annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__));
895-
/*
896-
** _PyDict_GetItemIdWithError could still fail,
897-
** for instance with a well-timed Ctrl-C or a MemoryError.
898-
** so let's be totally safe.
899-
*/
900-
if (annotations) {
901-
Py_INCREF(annotations);
902-
}
903-
} else {
893+
PyObject *annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__));
894+
if (annotations) {
895+
Py_INCREF(annotations);
896+
}
897+
else if (!PyErr_Occurred()) {
904898
annotations = PyDict_New();
905899
if (annotations) {
906900
int result = PyDict_SetItem(
@@ -919,28 +913,28 @@ module_set_annotations(PyModuleObject *m, PyObject *value, void *Py_UNUSED(ignor
919913
{
920914
int ret = -1;
921915
PyObject *dict = PyObject_GetAttr((PyObject *)m, &_Py_ID(__dict__));
922-
923-
if ((dict == NULL) || !PyDict_Check(dict)) {
916+
if (dict == NULL) {
917+
return -1;
918+
}
919+
if (!PyDict_Check(dict)) {
924920
PyErr_Format(PyExc_TypeError, "<module>.__dict__ is not a dictionary");
925921
goto exit;
926922
}
927923

928924
if (value != NULL) {
929925
/* set */
930926
ret = PyDict_SetItem(dict, &_Py_ID(__annotations__), value);
931-
goto exit;
932927
}
933-
934-
/* delete */
935-
if (!PyDict_Contains(dict, &_Py_ID(__annotations__))) {
936-
PyErr_Format(PyExc_AttributeError, "__annotations__");
937-
goto exit;
928+
else {
929+
/* delete */
930+
ret = PyDict_DelItem(dict, &_Py_ID(__annotations__));
931+
if (ret < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) {
932+
PyErr_SetString(PyExc_AttributeError, "__annotations__");
933+
}
938934
}
939935

940-
ret = PyDict_DelItem(dict, &_Py_ID(__annotations__));
941-
942936
exit:
943-
Py_XDECREF(dict);
937+
Py_DECREF(dict);
944938
return ret;
945939
}
946940

Objects/typeobject.c

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -912,24 +912,16 @@ type_get_annotations(PyTypeObject *type, void *context)
912912
}
913913

914914
PyObject *annotations;
915-
/* there's no _PyDict_GetItemId without WithError, so let's LBYL. */
916-
if (PyDict_Contains(type->tp_dict, &_Py_ID(__annotations__))) {
917-
annotations = PyDict_GetItemWithError(
918-
type->tp_dict, &_Py_ID(__annotations__));
919-
/*
920-
** PyDict_GetItemWithError could still fail,
921-
** for instance with a well-timed Ctrl-C or a MemoryError.
922-
** so let's be totally safe.
923-
*/
924-
if (annotations) {
925-
if (Py_TYPE(annotations)->tp_descr_get) {
926-
annotations = Py_TYPE(annotations)->tp_descr_get(
927-
annotations, NULL, (PyObject *)type);
928-
} else {
929-
Py_INCREF(annotations);
930-
}
915+
annotations = PyDict_GetItemWithError(type->tp_dict, &_Py_ID(__annotations__));
916+
if (annotations) {
917+
if (Py_TYPE(annotations)->tp_descr_get) {
918+
annotations = Py_TYPE(annotations)->tp_descr_get(
919+
annotations, NULL, (PyObject *)type);
920+
} else {
921+
Py_INCREF(annotations);
931922
}
932-
} else {
923+
}
924+
else if (!PyErr_Occurred()) {
933925
annotations = PyDict_New();
934926
if (annotations) {
935927
int result = PyDict_SetItem(
@@ -960,11 +952,10 @@ type_set_annotations(PyTypeObject *type, PyObject *value, void *context)
960952
result = PyDict_SetItem(type->tp_dict, &_Py_ID(__annotations__), value);
961953
} else {
962954
/* delete */
963-
if (!PyDict_Contains(type->tp_dict, &_Py_ID(__annotations__))) {
964-
PyErr_Format(PyExc_AttributeError, "__annotations__");
965-
return -1;
966-
}
967955
result = PyDict_DelItem(type->tp_dict, &_Py_ID(__annotations__));
956+
if (result < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) {
957+
PyErr_SetString(PyExc_AttributeError, "__annotations__");
958+
}
968959
}
969960

970961
if (result == 0) {

0 commit comments

Comments
 (0)
0