bpo-35459: Use PyDict_GetItemWithError() instead of PyDict_GetItem(). (GH-11112)

diff --git a/Modules/_csv.c b/Modules/_csv.c
index 6c00974..d86f63e 100644
--- a/Modules/_csv.c
+++ b/Modules/_csv.c
@@ -132,7 +132,7 @@
 {
     PyObject *dialect_obj;
 
-    dialect_obj = PyDict_GetItem(_csvstate_global->dialects, name_obj);
+    dialect_obj = PyDict_GetItemWithError(_csvstate_global->dialects, name_obj);
     if (dialect_obj == NULL) {
         if (!PyErr_Occurred())
             PyErr_Format(_csvstate_global->error_obj, "unknown dialect");
@@ -1434,8 +1434,12 @@
 static PyObject *
 csv_unregister_dialect(PyObject *module, PyObject *name_obj)
 {
-    if (PyDict_DelItem(_csvstate_global->dialects, name_obj) < 0)
-        return PyErr_Format(_csvstate_global->error_obj, "unknown dialect");
+    if (PyDict_DelItem(_csvstate_global->dialects, name_obj) < 0) {
+        if (PyErr_ExceptionMatches(PyExc_KeyError)) {
+            PyErr_Format(_csvstate_global->error_obj, "unknown dialect");
+        }
+        return NULL;
+    }
     Py_RETURN_NONE;
 }
 
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index b1a9629..1e58cd0 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -339,7 +339,7 @@
     if (attrib_str == NULL) {
         return NULL;
     }
-    PyObject *attrib = PyDict_GetItem(kwds, attrib_str);
+    PyObject *attrib = PyDict_GetItemWithError(kwds, attrib_str);
 
     if (attrib) {
         /* If attrib was found in kwds, copy its value and remove it from
@@ -356,7 +356,8 @@
             Py_DECREF(attrib);
             attrib = NULL;
         }
-    } else {
+    }
+    else if (!PyErr_Occurred()) {
         attrib = PyDict_New();
     }
 
@@ -1393,9 +1394,13 @@
     if (!self->extra || self->extra->attrib == Py_None)
         value = default_value;
     else {
-        value = PyDict_GetItem(self->extra->attrib, key);
-        if (!value)
+        value = PyDict_GetItemWithError(self->extra->attrib, key);
+        if (!value) {
+            if (PyErr_Occurred()) {
+                return NULL;
+            }
             value = default_value;
+        }
     }
 
     Py_INCREF(value);
@@ -2848,11 +2853,12 @@
     if (!key)
         return NULL;
 
-    value = PyDict_GetItem(self->names, key);
+    value = PyDict_GetItemWithError(self->names, key);
 
     if (value) {
         Py_INCREF(value);
-    } else {
+    }
+    else if (!PyErr_Occurred()) {
         /* new name.  convert to universal name, and decode as
            necessary */
 
@@ -2974,7 +2980,7 @@
     if (!key)
         return;
 
-    value = PyDict_GetItem(self->entity, key);
+    value = PyDict_GetItemWithError(self->entity, key);
 
     if (value) {
         if (TreeBuilder_CheckExact(self->target))
diff --git a/Modules/_json.c b/Modules/_json.c
index 53e1e88..94a7c0d 100644
--- a/Modules/_json.c
+++ b/Modules/_json.c
@@ -746,12 +746,15 @@
             key = scanstring_unicode(pystr, idx + 1, s->strict, &next_idx);
             if (key == NULL)
                 goto bail;
-            memokey = PyDict_GetItem(s->memo, key);
+            memokey = PyDict_GetItemWithError(s->memo, key);
             if (memokey != NULL) {
                 Py_INCREF(memokey);
                 Py_DECREF(key);
                 key = memokey;
             }
+            else if (PyErr_Occurred()) {
+                goto bail;
+            }
             else {
                 if (PyDict_SetItem(s->memo, key, key) < 0)
                     goto bail;
diff --git a/Modules/_sre.c b/Modules/_sre.c
index 21c41b5..5cea756 100644
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -1899,15 +1899,7 @@
     void* ptr;
     Py_ssize_t i, j;
 
-    if (index < 0 || index >= self->groups) {
-        /* raise IndexError if we were given a bad group number */
-        PyErr_SetString(
-            PyExc_IndexError,
-            "no such group"
-            );
-        return NULL;
-    }
-
+    assert(0 <= index && index < self->groups);
     index *= 2;
 
     if (self->string == Py_None || self->mark[index] < 0) {
@@ -1940,17 +1932,25 @@
         return 0;
 
     if (PyIndex_Check(index)) {
-        return PyNumber_AsSsize_t(index, NULL);
+        i = PyNumber_AsSsize_t(index, NULL);
     }
+    else {
+        i = -1;
 
-    i = -1;
-
-    if (self->pattern->groupindex) {
-        index = PyDict_GetItem(self->pattern->groupindex, index);
-        if (index && PyLong_Check(index)) {
-            i = PyLong_AsSsize_t(index);
+        if (self->pattern->groupindex) {
+            index = PyDict_GetItemWithError(self->pattern->groupindex, index);
+            if (index && PyLong_Check(index)) {
+                i = PyLong_AsSsize_t(index);
+            }
         }
     }
+    if (i < 0 || i >= self->groups) {
+        /* raise IndexError if we were given a bad group number */
+        if (!PyErr_Occurred()) {
+            PyErr_SetString(PyExc_IndexError, "no such group");
+        }
+        return -1;
+    }
 
     return i;
 }
@@ -1958,7 +1958,13 @@
 static PyObject*
 match_getslice(MatchObject* self, PyObject* index, PyObject* def)
 {
-    return match_getslice_by_index(self, match_getindex(self, index), def);
+    Py_ssize_t i = match_getindex(self, index);
+
+    if (i < 0) {
+        return NULL;
+    }
+
+    return match_getslice_by_index(self, i, def);
 }
 
 /*[clinic input]
@@ -2114,11 +2120,7 @@
 {
     Py_ssize_t index = match_getindex(self, group);
 
-    if (index < 0 || index >= self->groups) {
-        PyErr_SetString(
-            PyExc_IndexError,
-            "no such group"
-            );
+    if (index < 0) {
         return -1;
     }
 
@@ -2141,11 +2143,7 @@
 {
     Py_ssize_t index = match_getindex(self, group);
 
-    if (index < 0 || index >= self->groups) {
-        PyErr_SetString(
-            PyExc_IndexError,
-            "no such group"
-            );
+    if (index < 0) {
         return -1;
     }
 
@@ -2195,11 +2193,7 @@
 {
     Py_ssize_t index = match_getindex(self, group);
 
-    if (index < 0 || index >= self->groups) {
-        PyErr_SetString(
-            PyExc_IndexError,
-            "no such group"
-            );
+    if (index < 0) {
         return NULL;
     }
 
diff --git a/Modules/_struct.c b/Modules/_struct.c
index 5954c13..90839b2 100644
--- a/Modules/_struct.c
+++ b/Modules/_struct.c
@@ -2088,12 +2088,15 @@
             return 0;
     }
 
-    s_object = PyDict_GetItem(cache, fmt);
+    s_object = PyDict_GetItemWithError(cache, fmt);
     if (s_object != NULL) {
         Py_INCREF(s_object);
         *ptr = (PyStructObject *)s_object;
         return Py_CLEANUP_SUPPORTED;
     }
+    else if (PyErr_Occurred()) {
+        return 0;
+    }
 
     s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
     if (s_object != NULL) {
diff --git a/Modules/_testmultiphase.c b/Modules/_testmultiphase.c
index c6dfc2f..db5bb7d 100644
--- a/Modules/_testmultiphase.c
+++ b/Modules/_testmultiphase.c
@@ -53,11 +53,14 @@
 Example_getattro(ExampleObject *self, PyObject *name)
 {
     if (self->x_attr != NULL) {
-        PyObject *v = PyDict_GetItem(self->x_attr, name);
+        PyObject *v = PyDict_GetItemWithError(self->x_attr, name);
         if (v != NULL) {
             Py_INCREF(v);
             return v;
         }
+        else if (PyErr_Occurred()) {
+            return NULL;
+        }
     }
     return PyObject_GenericGetAttr((PyObject *)self, name);
 }
@@ -72,7 +75,7 @@
     }
     if (v == NULL) {
         int rv = PyDict_DelItemString(self->x_attr, name);
-        if (rv < 0)
+        if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
             PyErr_SetString(PyExc_AttributeError,
                 "delete non-existing Example attribute");
         return rv;
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index aacce69..73babaf 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -814,8 +814,11 @@
         return NULL;
     }
 
-    dummy = PyDict_GetItem(tdict, self->key);
+    dummy = PyDict_GetItemWithError(tdict, self->key);
     if (dummy == NULL) {
+        if (PyErr_Occurred()) {
+            return NULL;
+        }
         ldict = _local_create_dummy(self);
         if (ldict == NULL)
             return NULL;
@@ -931,14 +934,17 @@
             (PyObject *)self, name, ldict, 0);
 
     /* Optimization: just look in dict ourselves */
-    value = PyDict_GetItem(ldict, name);
-    if (value == NULL)
-        /* Fall back on generic to get __class__ and __dict__ */
-        return _PyObject_GenericGetAttrWithDict(
-            (PyObject *)self, name, ldict, 0);
-
-    Py_INCREF(value);
-    return value;
+    value = PyDict_GetItemWithError(ldict, name);
+    if (value != NULL) {
+        Py_INCREF(value);
+        return value;
+    }
+    else if (PyErr_Occurred()) {
+        return NULL;
+    }
+    /* Fall back on generic to get __class__ and __dict__ */
+    return _PyObject_GenericGetAttrWithDict(
+        (PyObject *)self, name, ldict, 0);
 }
 
 /* Called when a dummy is destroyed. */
@@ -958,7 +964,7 @@
     self = (localobject *) obj;
     if (self->dummies != NULL) {
         PyObject *ldict;
-        ldict = PyDict_GetItem(self->dummies, dummyweakref);
+        ldict = PyDict_GetItemWithError(self->dummies, dummyweakref);
         if (ldict != NULL) {
             PyDict_DelItem(self->dummies, dummyweakref);
         }
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
index 581ae2c..c589dd1 100644
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -4418,6 +4418,7 @@
 static PyObject *
 zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
+    _Py_IDENTIFIER(fillvalue);
     ziplongestobject *lz;
     Py_ssize_t i;
     PyObject *ittuple;  /* tuple of iterators */
@@ -4426,10 +4427,15 @@
     Py_ssize_t tuplesize;
 
     if (kwds != NULL && PyDict_CheckExact(kwds) && PyDict_GET_SIZE(kwds) > 0) {
-        fillvalue = PyDict_GetItemString(kwds, "fillvalue");
-        if (fillvalue == NULL || PyDict_GET_SIZE(kwds) > 1) {
-            PyErr_SetString(PyExc_TypeError,
-                "zip_longest() got an unexpected keyword argument");
+        fillvalue = NULL;
+        if (PyDict_GET_SIZE(kwds) == 1) {
+            fillvalue = _PyDict_GetItemIdWithError(kwds, &PyId_fillvalue);
+        }
+        if (fillvalue == NULL) {
+            if (!PyErr_Occurred()) {
+                PyErr_SetString(PyExc_TypeError,
+                    "zip_longest() got an unexpected keyword argument");
+            }
             return NULL;
         }
     }
diff --git a/Modules/main.c b/Modules/main.c
index a062991..f6e7889 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -508,10 +508,14 @@
 static int
 pymain_sys_path_add_path0(PyInterpreterState *interp, PyObject *path0)
 {
+    _Py_IDENTIFIER(path);
     PyObject *sys_path;
     PyObject *sysdict = interp->sysdict;
     if (sysdict != NULL) {
-        sys_path = PyDict_GetItemString(sysdict, "path");
+        sys_path = _PyDict_GetItemIdWithError(sysdict, &PyId_path);
+        if (sys_path == NULL && PyErr_Occurred()) {
+            goto error;
+        }
     }
     else {
         sys_path = NULL;
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 05afe9e..540ee9d 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -9837,6 +9837,9 @@
      */
     if (PyDict_DelItem(posix_putenv_garbage, name)) {
         /* really not much we can do; just leak */
+        if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
+            return NULL;
+        }
         PyErr_Clear();
     }
     Py_RETURN_NONE;
diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c
index 9384081..2e8be37 100644
--- a/Modules/pyexpat.c
+++ b/Modules/pyexpat.c
@@ -226,10 +226,13 @@
         return result;
     if (!self->intern)
         return result;
-    value = PyDict_GetItem(self->intern, result);
+    value = PyDict_GetItemWithError(self->intern, result);
     if (!value) {
-        if (PyDict_SetItem(self->intern, result, result) == 0)
+        if (!PyErr_Occurred() &&
+            PyDict_SetItem(self->intern, result, result) == 0)
+        {
             return result;
+        }
         else {
             Py_DECREF(result);
             return NULL;
@@ -1604,13 +1607,18 @@
         hi->getset.set = (setter)xmlparse_handler_setter;
         hi->getset.closure = &handler_info[i];
 
-        PyObject *descr;
-        if (PyDict_GetItemString(Xmlparsetype.tp_dict, hi->name))
-            continue;
-        descr = PyDescr_NewGetSet(&Xmlparsetype, &hi->getset);
-
+        PyObject *descr = PyDescr_NewGetSet(&Xmlparsetype, &hi->getset);
         if (descr == NULL)
             return -1;
+
+        if (PyDict_GetItemWithError(Xmlparsetype.tp_dict, PyDescr_NAME(descr))) {
+            Py_DECREF(descr);
+            continue;
+        }
+        else if (PyErr_Occurred()) {
+            Py_DECREF(descr);
+            return -1;
+        }
         if (PyDict_SetItem(Xmlparsetype.tp_dict, PyDescr_NAME(descr), descr) < 0) {
             Py_DECREF(descr);
             return -1;
@@ -1682,8 +1690,8 @@
         Py_DECREF(m);
         return NULL;
     }
-    errors_module = PyDict_GetItem(d, errmod_name);
-    if (errors_module == NULL) {
+    errors_module = PyDict_GetItemWithError(d, errmod_name);
+    if (errors_module == NULL && !PyErr_Occurred()) {
         errors_module = PyModule_New(MODULE_NAME ".errors");
         if (errors_module != NULL) {
             _PyImport_SetModule(errmod_name, errors_module);
@@ -1692,8 +1700,8 @@
         }
     }
     Py_DECREF(errmod_name);
-    model_module = PyDict_GetItem(d, modelmod_name);
-    if (model_module == NULL) {
+    model_module = PyDict_GetItemWithError(d, modelmod_name);
+    if (model_module == NULL && !PyErr_Occurred()) {
         model_module = PyModule_New(MODULE_NAME ".model");
         if (model_module != NULL) {
             _PyImport_SetModule(modelmod_name, model_module);
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c
index 7f62ab1..88130a1 100644
--- a/Modules/selectmodule.c
+++ b/Modules/selectmodule.c
@@ -499,9 +499,11 @@
     key = PyLong_FromLong(fd);
     if (key == NULL)
         return NULL;
-    if (PyDict_GetItem(self->dict, key) == NULL) {
-        errno = ENOENT;
-        PyErr_SetFromErrno(PyExc_OSError);
+    if (PyDict_GetItemWithError(self->dict, key) == NULL) {
+        if (!PyErr_Occurred()) {
+            errno = ENOENT;
+            PyErr_SetFromErrno(PyExc_OSError);
+        }
         Py_DECREF(key);
         return NULL;
     }
diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c
index 5586989..190f993 100644
--- a/Modules/xxlimited.c
+++ b/Modules/xxlimited.c
@@ -78,11 +78,14 @@
 Xxo_getattro(XxoObject *self, PyObject *name)
 {
     if (self->x_attr != NULL) {
-        PyObject *v = PyDict_GetItem(self->x_attr, name);
+        PyObject *v = PyDict_GetItemWithError(self->x_attr, name);
         if (v != NULL) {
             Py_INCREF(v);
             return v;
         }
+        else if (PyErr_Occurred()) {
+            return NULL;
+        }
     }
     return PyObject_GenericGetAttr((PyObject *)self, name);
 }
@@ -97,7 +100,7 @@
     }
     if (v == NULL) {
         int rv = PyDict_DelItemString(self->x_attr, name);
-        if (rv < 0)
+        if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
             PyErr_SetString(PyExc_AttributeError,
                 "delete non-existing Xxo attribute");
         return rv;
diff --git a/Modules/xxmodule.c b/Modules/xxmodule.c
index c0564ea..d546901 100644
--- a/Modules/xxmodule.c
+++ b/Modules/xxmodule.c
@@ -66,11 +66,14 @@
 Xxo_getattro(XxoObject *self, PyObject *name)
 {
     if (self->x_attr != NULL) {
-        PyObject *v = PyDict_GetItem(self->x_attr, name);
+        PyObject *v = PyDict_GetItemWithError(self->x_attr, name);
         if (v != NULL) {
             Py_INCREF(v);
             return v;
         }
+        else if (PyErr_Occurred()) {
+            return NULL;
+        }
     }
     return PyObject_GenericGetAttr((PyObject *)self, name);
 }
@@ -85,7 +88,7 @@
     }
     if (v == NULL) {
         int rv = PyDict_DelItemString(self->x_attr, name);
-        if (rv < 0)
+        if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
             PyErr_SetString(PyExc_AttributeError,
                 "delete non-existing Xxo attribute");
         return rv;