mirror of
https://github.com/python/cpython.git
synced 2025-08-22 09:45:06 +00:00
Issue 21101: Internal API for dict getitem and setitem where the hash value is known.
This commit is contained in:
parent
1b5eebcfa3
commit
4b74fba62f
2 changed files with 60 additions and 0 deletions
|
@ -50,6 +50,8 @@ PyAPI_DATA(PyTypeObject) PyDictValues_Type;
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyDict_New(void);
|
PyAPI_FUNC(PyObject *) PyDict_New(void);
|
||||||
PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);
|
PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);
|
||||||
|
PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key,
|
||||||
|
Py_hash_t hash);
|
||||||
PyAPI_FUNC(PyObject *) PyDict_GetItemWithError(PyObject *mp, PyObject *key);
|
PyAPI_FUNC(PyObject *) PyDict_GetItemWithError(PyObject *mp, PyObject *key);
|
||||||
PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp,
|
PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp,
|
||||||
struct _Py_Identifier *key);
|
struct _Py_Identifier *key);
|
||||||
|
@ -58,6 +60,8 @@ PyAPI_FUNC(PyObject *) PyDict_SetDefault(
|
||||||
PyObject *mp, PyObject *key, PyObject *defaultobj);
|
PyObject *mp, PyObject *key, PyObject *defaultobj);
|
||||||
#endif
|
#endif
|
||||||
PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item);
|
PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item);
|
||||||
|
PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key,
|
||||||
|
PyObject *item, Py_hash_t hash);
|
||||||
PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key);
|
PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key);
|
||||||
PyAPI_FUNC(void) PyDict_Clear(PyObject *mp);
|
PyAPI_FUNC(void) PyDict_Clear(PyObject *mp);
|
||||||
PyAPI_FUNC(int) PyDict_Next(
|
PyAPI_FUNC(int) PyDict_Next(
|
||||||
|
|
|
@ -1101,6 +1101,44 @@ PyDict_GetItem(PyObject *op, PyObject *key)
|
||||||
return *value_addr;
|
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.
|
/* Variant of PyDict_GetItem() that doesn't suppress exceptions.
|
||||||
This returns NULL *with* an exception set if an exception occurred.
|
This returns NULL *with* an exception set if an exception occurred.
|
||||||
It returns NULL *without* an exception set if the key wasn't present.
|
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);
|
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
|
int
|
||||||
PyDict_DelItem(PyObject *op, PyObject *key)
|
PyDict_DelItem(PyObject *op, PyObject *key)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue