|
|
|
@ -1101,6 +1101,44 @@ PyDict_GetItem(PyObject *op, PyObject *key) |
|
|
|
return *value_addr; |
|
|
|
} |
|
|
|
|
|
|
|
PyObject * |
|
|
|
_PyDict_GetItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) |
|
|
|
{ |
|
|
|
PyDictObject *mp = (PyDictObject *)op; |
|
|
|
PyDictKeyEntry *ep; |
|
|
|
PyThreadState *tstate; |
|
|
|
PyObject **value_addr; |
|
|
|
|
|
|
|
if (!PyDict_Check(op)) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
/* We can arrive here with a NULL tstate during initialization: try |
|
|
|
running "python -Wi" for an example related to string interning. |
|
|
|
Let's just hope that no exception occurs then... This must be |
|
|
|
_PyThreadState_Current and not PyThreadState_GET() because in debug |
|
|
|
mode, the latter complains if tstate is NULL. */ |
|
|
|
tstate = (PyThreadState*)_Py_atomic_load_relaxed( |
|
|
|
&_PyThreadState_Current); |
|
|
|
if (tstate != NULL && tstate->curexc_type != NULL) { |
|
|
|
/* preserve the existing exception */ |
|
|
|
PyObject *err_type, *err_value, *err_tb; |
|
|
|
PyErr_Fetch(&err_type, &err_value, &err_tb); |
|
|
|
ep = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr); |
|
|
|
/* ignore errors */ |
|
|
|
PyErr_Restore(err_type, err_value, err_tb); |
|
|
|
if (ep == NULL) |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
else { |
|
|
|
ep = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr); |
|
|
|
if (ep == NULL) { |
|
|
|
PyErr_Clear(); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
return *value_addr; |
|
|
|
} |
|
|
|
|
|
|
|
/* Variant of PyDict_GetItem() that doesn't suppress exceptions. |
|
|
|
This returns NULL *with* an exception set if an exception occurred. |
|
|
|
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) |
|
|
|
return insertdict(mp, key, hash, value); |
|
|
|
} |
|
|
|
|
|
|
|
int |
|
|
|
_PyDict_SetItem_KnownHash(PyObject *op, PyObject *key, PyObject *value, |
|
|
|
Py_hash_t hash) |
|
|
|
{ |
|
|
|
PyDictObject *mp; |
|
|
|
|
|
|
|
if (!PyDict_Check(op)) { |
|
|
|
PyErr_BadInternalCall(); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
assert(key); |
|
|
|
assert(value); |
|
|
|
mp = (PyDictObject *)op; |
|
|
|
|
|
|
|
/* insertdict() handles any resizing that might be necessary */ |
|
|
|
return insertdict(mp, key, hash, value); |
|
|
|
} |
|
|
|
|
|
|
|
int |
|
|
|
PyDict_DelItem(PyObject *op, PyObject *key) |
|
|
|
{ |
|
|
|
|