@@ -2065,19 +2065,46 @@ type_set_annotations(PyObject *tp, PyObject *value, void *Py_UNUSED(closure))
20652065 return -1 ;
20662066 }
20672067
2068- int result ;
20692068 PyObject * dict = PyType_GetDict (type );
2070- if (value != NULL ) {
2071- /* set */
2072- result = PyDict_SetItem (dict , & _Py_ID (__annotations_cache__ ), value );
2073- } else {
2074- /* delete */
2075- result = PyDict_Pop (dict , & _Py_ID (__annotations_cache__ ), NULL );
2076- if (result == 0 ) {
2077- PyErr_SetString (PyExc_AttributeError , "__annotations__" );
2069+ int result = PyDict_ContainsString (dict , "__annotations__" );
2070+ if (result < 0 ) {
2071+ Py_DECREF (dict );
2072+ return -1 ;
2073+ }
2074+ if (result ) {
2075+ // If __annotations__ is currently in the dict, we update it,
2076+ if (value != NULL ) {
2077+ result = PyDict_SetItem (dict , & _Py_ID (__annotations__ ), value );
2078+ } else {
2079+ result = PyDict_Pop (dict , & _Py_ID (__annotations__ ), NULL );
2080+ if (result == 0 ) {
2081+ // Somebody else just deleted it?
2082+ PyErr_SetString (PyExc_AttributeError , "__annotations__" );
2083+ Py_DECREF (dict );
2084+ return -1 ;
2085+ }
2086+ }
2087+ if (result < 0 ) {
20782088 Py_DECREF (dict );
20792089 return -1 ;
20802090 }
2091+ // Also clear __annotations_cache__ just in case.
2092+ result = PyDict_Pop (dict , & _Py_ID (__annotations_cache__ ), NULL );
2093+ }
2094+ else {
2095+ // Else we update only __annotations_cache__.
2096+ if (value != NULL ) {
2097+ /* set */
2098+ result = PyDict_SetItem (dict , & _Py_ID (__annotations_cache__ ), value );
2099+ } else {
2100+ /* delete */
2101+ result = PyDict_Pop (dict , & _Py_ID (__annotations_cache__ ), NULL );
2102+ if (result == 0 ) {
2103+ PyErr_SetString (PyExc_AttributeError , "__annotations__" );
2104+ Py_DECREF (dict );
2105+ return -1 ;
2106+ }
2107+ }
20812108 }
20822109 if (result < 0 ) {
20832110 Py_DECREF (dict );
0 commit comments