@@ -1101,6 +1101,44 @@ PyDict_GetItem(PyObject *op, PyObject *key)
11011101 return * value_addr ;
11021102}
11031103
1104+ PyObject *
1105+ _PyDict_GetItem_KnownHash (PyObject * op , PyObject * key , Py_hash_t hash )
1106+ {
1107+ PyDictObject * mp = (PyDictObject * )op ;
1108+ PyDictKeyEntry * ep ;
1109+ PyThreadState * tstate ;
1110+ PyObject * * value_addr ;
1111+
1112+ if (!PyDict_Check (op ))
1113+ return NULL ;
1114+
1115+ /* We can arrive here with a NULL tstate during initialization: try
1116+ running "python -Wi" for an example related to string interning.
1117+ Let's just hope that no exception occurs then... This must be
1118+ _PyThreadState_Current and not PyThreadState_GET() because in debug
1119+ mode, the latter complains if tstate is NULL. */
1120+ tstate = (PyThreadState * )_Py_atomic_load_relaxed (
1121+ & _PyThreadState_Current );
1122+ if (tstate != NULL && tstate -> curexc_type != NULL ) {
1123+ /* preserve the existing exception */
1124+ PyObject * err_type , * err_value , * err_tb ;
1125+ PyErr_Fetch (& err_type , & err_value , & err_tb );
1126+ ep = (mp -> ma_keys -> dk_lookup )(mp , key , hash , & value_addr );
1127+ /* ignore errors */
1128+ PyErr_Restore (err_type , err_value , err_tb );
1129+ if (ep == NULL )
1130+ return NULL ;
1131+ }
1132+ else {
1133+ ep = (mp -> ma_keys -> dk_lookup )(mp , key , hash , & value_addr );
1134+ if (ep == NULL ) {
1135+ PyErr_Clear ();
1136+ return NULL ;
1137+ }
1138+ }
1139+ return * value_addr ;
1140+ }
1141+
11041142/* Variant of PyDict_GetItem() that doesn't suppress exceptions.
11051143 This returns NULL *with* an exception set if an exception occurred.
11061144 It returns NULL *without* an exception set if the key wasn't present.
@@ -1207,6 +1245,24 @@ PyDict_SetItem(PyObject *op, PyObject *key, PyObject *value)
12071245 return insertdict (mp , key , hash , value );
12081246}
12091247
1248+ int
1249+ _PyDict_SetItem_KnownHash (PyObject * op , PyObject * key , PyObject * value ,
1250+ Py_hash_t hash )
1251+ {
1252+ PyDictObject * mp ;
1253+
1254+ if (!PyDict_Check (op )) {
1255+ PyErr_BadInternalCall ();
1256+ return -1 ;
1257+ }
1258+ assert (key );
1259+ assert (value );
1260+ mp = (PyDictObject * )op ;
1261+
1262+ /* insertdict() handles any resizing that might be necessary */
1263+ return insertdict (mp , key , hash , value );
1264+ }
1265+
12101266int
12111267PyDict_DelItem (PyObject * op , PyObject * key )
12121268{
0 commit comments