Issue #14417: Mutating a dict during lookup now restarts the lookup instead of raising a RuntimeError (undoes issue #14205).
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 077f3cd..fd1d46c 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -439,12 +439,15 @@
     register size_t i;
     register size_t perturb;
     register PyDictKeyEntry *freeslot;
-    register size_t mask = DK_MASK(mp->ma_keys);
-    PyDictKeyEntry *ep0 = &mp->ma_keys->dk_entries[0];
+    register size_t mask;
+    PyDictKeyEntry *ep0;
     register PyDictKeyEntry *ep;
     register int cmp;
     PyObject *startkey;
 
+top:
+    mask = DK_MASK(mp->ma_keys);
+    ep0 = &mp->ma_keys->dk_entries[0];
     i = (size_t)hash & mask;
     ep = &ep0[i];
     if (ep->me_key == NULL || ep->me_key == key) {
@@ -468,9 +471,8 @@
                 }
             }
             else {
-                PyErr_SetString(PyExc_RuntimeError,
-                                "dictionary changed size during lookup");
-                return NULL;
+                /* The dict was mutated, restart */
+                goto top;
             }
         }
         freeslot = NULL;
@@ -510,9 +512,8 @@
                 }
             }
             else {
-                PyErr_SetString(PyExc_RuntimeError,
-                                "dictionary changed size during lookup");
-                return NULL;
+                /* The dict was mutated, restart */
+                goto top;
             }
         }
         else if (ep->me_key == dummy && freeslot == NULL)