Skip to content

Commit 45de5b2

Browse files
committed
Adding deepget method to dictionary
1 parent f520f22 commit 45de5b2

File tree

3 files changed

+75
-1
lines changed

3 files changed

+75
-1
lines changed

Include/dictobject.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ PyAPI_DATA(PyTypeObject) PyDict_Type;
1717
#define PyDict_Check(op) \
1818
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS)
1919
#define PyDict_CheckExact(op) Py_IS_TYPE((op), &PyDict_Type)
20-
2120
PyAPI_FUNC(PyObject *) PyDict_New(void);
2221
PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);
2322
PyAPI_FUNC(PyObject *) PyDict_GetItemWithError(PyObject *mp, PyObject *key);

Objects/clinic/dictobject.c.h

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Objects/dictobject.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4312,6 +4312,40 @@ dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value)
43124312
return val;
43134313
}
43144314

4315+
static PyObject *
4316+
dict_deepget_impl(PyDictObject *self, PyObject * const *keylist, PyObject *default_value)
4317+
{
4318+
Py_ssize_t n = PyList_GET_SIZE(keylist);
4319+
if (n == 0) {
4320+
return default_value;
4321+
}
4322+
4323+
PyObject *val = (PyObject *)self; // Start with top-level dict
4324+
for (Py_ssize_t i = 0; i < n; i++) {
4325+
PyObject *key = PyList_GET_ITEM(keylist, i);
4326+
4327+
if (!PyDict_Check(val)) {
4328+
return default_value;
4329+
}
4330+
4331+
Py_hash_t hash = _PyObject_HashFast(key);
4332+
if (hash == -1) {
4333+
dict_unhashable_type(key);
4334+
return default_value;
4335+
}
4336+
4337+
PyObject *next = NULL;
4338+
Py_ssize_t ix = _Py_dict_lookup_threadsafe((PyDictObject *)val, key, hash, &next);
4339+
if (ix == DKIX_ERROR || ix == DKIX_EMPTY || next == NULL) {
4340+
return Py_NewRef(default_value);
4341+
}
4342+
4343+
val = next;
4344+
}
4345+
4346+
return Py_NewRef(val);
4347+
}
4348+
43154349
static int
43164350
dict_setdefault_ref_lock_held(PyObject *d, PyObject *key, PyObject *default_value,
43174351
PyObject **result, int incref_result)
@@ -4741,6 +4775,7 @@ static PyMethodDef mapp_methods[] = {
47414775
getitem__doc__},
47424776
DICT___SIZEOF___METHODDEF
47434777
DICT_GET_METHODDEF
4778+
DICT_DEEPGET_METHODDEF
47444779
DICT_SETDEFAULT_METHODDEF
47454780
DICT_POP_METHODDEF
47464781
DICT_POPITEM_METHODDEF

0 commit comments

Comments
 (0)