Skip to content

Commit a92c420

Browse files
committed
Simplify dict_keys, dict_values, and dict_items
1 parent 00f502c commit a92c420

File tree

1 file changed

+29
-89
lines changed

1 file changed

+29
-89
lines changed

Objects/dictobject.c

Lines changed: 29 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -2111,7 +2111,7 @@ _PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
21112111
if (i >= n)
21122112
return 0;
21132113
key = entry_ptr->me_key;
2114-
hash = ((PyASCIIObject*)key)->hash;
2114+
hash = unicode_get_hash(entry_ptr->me_key);
21152115
value = entry_ptr->me_value;
21162116
}
21172117
else {
@@ -2518,36 +2518,15 @@ dict_keys(PyDictObject *mp)
25182518
Py_DECREF(v);
25192519
goto again;
25202520
}
2521-
if (DK_IS_UNICODE(mp->ma_keys)) {
2522-
PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(mp->ma_keys);
2523-
key_ptr = &ep->me_key;
2524-
key_offset = sizeof(PyDictUnicodeEntry);
25252521

2526-
if (mp->ma_values) {
2527-
value_ptr = mp->ma_values->values;
2528-
value_offset = sizeof(PyObject *);
2529-
}
2530-
else {
2531-
value_ptr = &ep->me_value;
2532-
value_offset = key_offset;
2533-
}
2534-
}
2535-
else {
2536-
PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys);
2537-
key_ptr = &ep->me_key;
2538-
value_ptr = &ep->me_value;
2539-
key_offset = value_offset = sizeof(PyDictKeyEntry);
2540-
}
2541-
2542-
for (i = 0, j = 0; j < n; i++) {
2543-
if (*value_ptr != NULL) {
2544-
PyObject *key = *key_ptr;
2545-
Py_INCREF(key);
2546-
PyList_SET_ITEM(v, j, key);
2547-
j++;
2548-
}
2549-
key_ptr = (PyObject **)(((char *)key_ptr) + key_offset);
2550-
value_ptr = (PyObject **)(((char *)value_ptr) + value_offset);
2522+
/* Nothing we do below makes any function calls. */
2523+
Py_ssize_t j = 0, pos = 0;
2524+
PyObject *key;
2525+
while (_PyDict_Next((PyObject*)mp, &pos, &key, NULL, NULL)) {
2526+
assert(j < n);
2527+
Py_INCREF(key);
2528+
PyList_SET_ITEM(v, j, key);
2529+
j++;
25512530
}
25522531
assert(j == n);
25532532
return v;
@@ -2557,9 +2536,7 @@ static PyObject *
25572536
dict_values(PyDictObject *mp)
25582537
{
25592538
PyObject *v;
2560-
Py_ssize_t i, j;
2561-
Py_ssize_t n, offset;
2562-
PyObject **value_ptr;
2539+
Py_ssize_t n;
25632540

25642541
again:
25652542
n = mp->ma_used;
@@ -2573,31 +2550,15 @@ dict_values(PyDictObject *mp)
25732550
Py_DECREF(v);
25742551
goto again;
25752552
}
2576-
if (DK_IS_UNICODE(mp->ma_keys)) {
2577-
if (mp->ma_values) {
2578-
value_ptr = mp->ma_values->values;
2579-
offset = sizeof(PyObject *);
2580-
}
2581-
else {
2582-
PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(mp->ma_keys);
2583-
value_ptr = &ep->me_value;
2584-
offset = sizeof(PyDictUnicodeEntry);
2585-
}
2586-
}
2587-
else {
2588-
PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys);
2589-
value_ptr = &ep->me_value;
2590-
offset = sizeof(PyDictKeyEntry);
2591-
}
25922553

2593-
for (i = 0, j = 0; j < n; i++) {
2594-
PyObject *value = *value_ptr;
2595-
value_ptr = (PyObject **)(((char *)value_ptr) + offset);
2596-
if (value != NULL) {
2597-
Py_INCREF(value);
2598-
PyList_SET_ITEM(v, j, value);
2599-
j++;
2600-
}
2554+
/* Nothing we do below makes any function calls. */
2555+
Py_ssize_t j = 0, pos = 0;
2556+
PyObject *value;
2557+
while (_PyDict_Next((PyObject*)mp, &pos, NULL, &value, NULL)) {
2558+
assert(j < n);
2559+
Py_INCREF(value);
2560+
PyList_SET_ITEM(v, j, value);
2561+
j++;
26012562
}
26022563
assert(j == n);
26032564
return v;
@@ -2609,8 +2570,6 @@ dict_items(PyDictObject *mp)
26092570
PyObject *v;
26102571
Py_ssize_t i, j, n;
26112572
PyObject *item;
2612-
PyObject **key_ptr, **value_ptr;
2613-
Py_ssize_t key_offset, value_offset;
26142573

26152574
/* Preallocate the list of tuples, to avoid allocations during
26162575
* the loop over the items, which could trigger GC, which
@@ -2636,37 +2595,18 @@ dict_items(PyDictObject *mp)
26362595
Py_DECREF(v);
26372596
goto again;
26382597
}
2639-
/* Nothing we do below makes any function calls. */
2640-
if (DK_IS_UNICODE(mp->ma_keys)) {
2641-
PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(mp->ma_keys);
2642-
key_ptr = &ep->me_key;
2643-
value_ptr = &ep->me_value;
2644-
key_offset = value_offset = sizeof(PyDictUnicodeEntry);
2645-
if (mp->ma_values) {
2646-
value_ptr = mp->ma_values->values;
2647-
value_offset = sizeof(PyObject *);
2648-
}
2649-
}
2650-
else {
2651-
PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys);
2652-
key_ptr = &ep->me_key;
2653-
value_ptr = &ep->me_value;
2654-
key_offset = value_offset = sizeof(PyDictKeyEntry);
2655-
}
26562598

2657-
for (i = 0, j = 0; j < n; i++) {
2658-
PyObject *value = *value_ptr;
2659-
PyObject *key = *key_ptr;
2660-
key_ptr = (PyObject **)(((char *)key_ptr) + key_offset);
2661-
value_ptr = (PyObject **)(((char *)value_ptr) + value_offset);
2662-
if (value != NULL) {
2663-
item = PyList_GET_ITEM(v, j);
2664-
Py_INCREF(key);
2665-
PyTuple_SET_ITEM(item, 0, key);
2666-
Py_INCREF(value);
2667-
PyTuple_SET_ITEM(item, 1, value);
2668-
j++;
2669-
}
2599+
/* Nothing we do below makes any function calls. */
2600+
Py_ssize_t j = 0, pos = 0;
2601+
PyObject *key, *value;
2602+
while (_PyDict_Next((PyObject*)mp, &pos, &key, &value, NULL)) {
2603+
assert(j < n);
2604+
PyObject *item = PyList_GET_ITEM(v, j);
2605+
Py_INCREF(key);
2606+
PyTuple_SET_ITEM(item, 0, key);
2607+
Py_INCREF(value);
2608+
PyTuple_SET_ITEM(item, 1, value);
2609+
j++;
26702610
}
26712611
assert(j == n);
26722612
return v;

0 commit comments

Comments
 (0)