Coverage Report

Created: 2026-06-14 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/Python-3.8.3/Objects/dictobject.c
Line
Count
Source
1
/* Dictionary object implementation using a hash table */
2
3
/* The distribution includes a separate file, Objects/dictnotes.txt,
4
   describing explorations into dictionary design and optimization.
5
   It covers typical dictionary use patterns, the parameters for
6
   tuning dictionaries, and several ideas for possible optimizations.
7
*/
8
9
/* PyDictKeysObject
10
11
This implements the dictionary's hashtable.
12
13
As of Python 3.6, this is compact and ordered. Basic idea is described here:
14
* https://mail.python.org/pipermail/python-dev/2012-December/123028.html
15
* https://morepypy.blogspot.com/2015/01/faster-more-memory-efficient-and-more.html
16
17
layout:
18
19
+---------------+
20
| dk_refcnt     |
21
| dk_size       |
22
| dk_lookup     |
23
| dk_usable     |
24
| dk_nentries   |
25
+---------------+
26
| dk_indices    |
27
|               |
28
+---------------+
29
| dk_entries    |
30
|               |
31
+---------------+
32
33
dk_indices is actual hashtable.  It holds index in entries, or DKIX_EMPTY(-1)
34
or DKIX_DUMMY(-2).
35
Size of indices is dk_size.  Type of each index in indices is vary on dk_size:
36
37
* int8  for          dk_size <= 128
38
* int16 for 256   <= dk_size <= 2**15
39
* int32 for 2**16 <= dk_size <= 2**31
40
* int64 for 2**32 <= dk_size
41
42
dk_entries is array of PyDictKeyEntry.  Its size is USABLE_FRACTION(dk_size).
43
DK_ENTRIES(dk) can be used to get pointer to entries.
44
45
NOTE: Since negative value is used for DKIX_EMPTY and DKIX_DUMMY, type of
46
dk_indices entry is signed integer and int16 is used for table which
47
dk_size == 256.
48
*/
49
50
51
/*
52
The DictObject can be in one of two forms.
53
54
Either:
55
  A combined table:
56
    ma_values == NULL, dk_refcnt == 1.
57
    Values are stored in the me_value field of the PyDictKeysObject.
58
Or:
59
  A split table:
60
    ma_values != NULL, dk_refcnt >= 1
61
    Values are stored in the ma_values array.
62
    Only string (unicode) keys are allowed.
63
    All dicts sharing same key must have same insertion order.
64
65
There are four kinds of slots in the table (slot is index, and
66
DK_ENTRIES(keys)[index] if index >= 0):
67
68
1. Unused.  index == DKIX_EMPTY
69
   Does not hold an active (key, value) pair now and never did.  Unused can
70
   transition to Active upon key insertion.  This is each slot's initial state.
71
72
2. Active.  index >= 0, me_key != NULL and me_value != NULL
73
   Holds an active (key, value) pair.  Active can transition to Dummy or
74
   Pending upon key deletion (for combined and split tables respectively).
75
   This is the only case in which me_value != NULL.
76
77
3. Dummy.  index == DKIX_DUMMY  (combined only)
78
   Previously held an active (key, value) pair, but that was deleted and an
79
   active pair has not yet overwritten the slot.  Dummy can transition to
80
   Active upon key insertion.  Dummy slots cannot be made Unused again
81
   else the probe sequence in case of collision would have no way to know
82
   they were once active.
83
84
4. Pending. index >= 0, key != NULL, and value == NULL  (split only)
85
   Not yet inserted in split-table.
86
*/
87
88
/*
89
Preserving insertion order
90
91
It's simple for combined table.  Since dk_entries is mostly append only, we can
92
get insertion order by just iterating dk_entries.
93
94
One exception is .popitem().  It removes last item in dk_entries and decrement
95
dk_nentries to achieve amortized O(1).  Since there are DKIX_DUMMY remains in
96
dk_indices, we can't increment dk_usable even though dk_nentries is
97
decremented.
98
99
In split table, inserting into pending entry is allowed only for dk_entries[ix]
100
where ix == mp->ma_used. Inserting into other index and deleting item cause
101
converting the dict to the combined table.
102
*/
103
104
/* PyDict_MINSIZE is the starting size for any new dict.
105
 * 8 allows dicts with no more than 5 active entries; experiments suggested
106
 * this suffices for the majority of dicts (consisting mostly of usually-small
107
 * dicts created to pass keyword arguments).
108
 * Making this 8, rather than 4 reduces the number of resizes for most
109
 * dictionaries, without any significant extra memory use.
110
 */
111
111k
#define PyDict_MINSIZE 8
112
113
#include "Python.h"
114
#include "pycore_object.h"
115
#include "pycore_pystate.h"
116
#include "dict-common.h"
117
#include "stringlib/eq.h"    /* to get unicode_eq() */
118
119
/*[clinic input]
120
class dict "PyDictObject *" "&PyDict_Type"
121
[clinic start generated code]*/
122
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f157a5a0ce9589d6]*/
123
124
125
/*
126
To ensure the lookup algorithm terminates, there must be at least one Unused
127
slot (NULL key) in the table.
128
To avoid slowing down lookups on a near-full table, we resize the table when
129
it's USABLE_FRACTION (currently two-thirds) full.
130
*/
131
132
1.11M
#define PERTURB_SHIFT 5
133
134
/*
135
Major subtleties ahead:  Most hash schemes depend on having a "good" hash
136
function, in the sense of simulating randomness.  Python doesn't:  its most
137
important hash functions (for ints) are very regular in common
138
cases:
139
140
  >>>[hash(i) for i in range(4)]
141
  [0, 1, 2, 3]
142
143
This isn't necessarily bad!  To the contrary, in a table of size 2**i, taking
144
the low-order i bits as the initial table index is extremely fast, and there
145
are no collisions at all for dicts indexed by a contiguous range of ints. So
146
this gives better-than-random behavior in common cases, and that's very
147
desirable.
148
149
OTOH, when collisions occur, the tendency to fill contiguous slices of the
150
hash table makes a good collision resolution strategy crucial.  Taking only
151
the last i bits of the hash code is also vulnerable:  for example, consider
152
the list [i << 16 for i in range(20000)] as a set of keys.  Since ints are
153
their own hash codes, and this fits in a dict of size 2**15, the last 15 bits
154
 of every hash code are all 0:  they *all* map to the same table index.
155
156
But catering to unusual cases should not slow the usual ones, so we just take
157
the last i bits anyway.  It's up to collision resolution to do the rest.  If
158
we *usually* find the key we're looking for on the first try (and, it turns
159
out, we usually do -- the table load factor is kept under 2/3, so the odds
160
are solidly in our favor), then it makes best sense to keep the initial index
161
computation dirt cheap.
162
163
The first half of collision resolution is to visit table indices via this
164
recurrence:
165
166
    j = ((5*j) + 1) mod 2**i
167
168
For any initial j in range(2**i), repeating that 2**i times generates each
169
int in range(2**i) exactly once (see any text on random-number generation for
170
proof).  By itself, this doesn't help much:  like linear probing (setting
171
j += 1, or j -= 1, on each loop trip), it scans the table entries in a fixed
172
order.  This would be bad, except that's not the only thing we do, and it's
173
actually *good* in the common cases where hash keys are consecutive.  In an
174
example that's really too small to make this entirely clear, for a table of
175
size 2**3 the order of indices is:
176
177
    0 -> 1 -> 6 -> 7 -> 4 -> 5 -> 2 -> 3 -> 0 [and here it's repeating]
178
179
If two things come in at index 5, the first place we look after is index 2,
180
not 6, so if another comes in at index 6 the collision at 5 didn't hurt it.
181
Linear probing is deadly in this case because there the fixed probe order
182
is the *same* as the order consecutive keys are likely to arrive.  But it's
183
extremely unlikely hash codes will follow a 5*j+1 recurrence by accident,
184
and certain that consecutive hash codes do not.
185
186
The other half of the strategy is to get the other bits of the hash code
187
into play.  This is done by initializing a (unsigned) vrbl "perturb" to the
188
full hash code, and changing the recurrence to:
189
190
    perturb >>= PERTURB_SHIFT;
191
    j = (5*j) + 1 + perturb;
192
    use j % 2**i as the next table index;
193
194
Now the probe sequence depends (eventually) on every bit in the hash code,
195
and the pseudo-scrambling property of recurring on 5*j+1 is more valuable,
196
because it quickly magnifies small differences in the bits that didn't affect
197
the initial index.  Note that because perturb is unsigned, if the recurrence
198
is executed often enough perturb eventually becomes and remains 0.  At that
199
point (very rarely reached) the recurrence is on (just) 5*j+1 again, and
200
that's certain to find an empty slot eventually (since it generates every int
201
in range(2**i), and we make sure there's always at least one empty slot).
202
203
Selecting a good value for PERTURB_SHIFT is a balancing act.  You want it
204
small so that the high bits of the hash code continue to affect the probe
205
sequence across iterations; but you want it large so that in really bad cases
206
the high-order hash bits have an effect on early iterations.  5 was "the
207
best" in minimizing total collisions across experiments Tim Peters ran (on
208
both normal and pathological cases), but 4 and 6 weren't significantly worse.
209
210
Historical: Reimer Behrends contributed the idea of using a polynomial-based
211
approach, using repeated multiplication by x in GF(2**n) where an irreducible
212
polynomial for each table size was chosen such that x was a primitive root.
213
Christian Tismer later extended that to use division by x instead, as an
214
efficient way to get the high bits of the hash code into play.  This scheme
215
also gave excellent collision statistics, but was more expensive:  two
216
if-tests were required inside the loop; computing "the next" index took about
217
the same number of operations but without as much potential parallelism
218
(e.g., computing 5*j can go on at the same time as computing 1+perturb in the
219
above, and then shifting perturb can be done while the table index is being
220
masked); and the PyDictObject struct required a member to hold the table's
221
polynomial.  In Tim's experiments the current scheme ran faster, produced
222
equally good collision statistics, needed less code & used less memory.
223
224
*/
225
226
/* forward declarations */
227
static Py_ssize_t lookdict(PyDictObject *mp, PyObject *key,
228
                           Py_hash_t hash, PyObject **value_addr);
229
static Py_ssize_t lookdict_unicode(PyDictObject *mp, PyObject *key,
230
                                   Py_hash_t hash, PyObject **value_addr);
231
static Py_ssize_t
232
lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key,
233
                         Py_hash_t hash, PyObject **value_addr);
234
static Py_ssize_t lookdict_split(PyDictObject *mp, PyObject *key,
235
                                 Py_hash_t hash, PyObject **value_addr);
236
237
static int dictresize(PyDictObject *mp, Py_ssize_t minused);
238
239
static PyObject* dict_iter(PyDictObject *dict);
240
241
/*Global counter used to set ma_version_tag field of dictionary.
242
 * It is incremented each time that a dictionary is created and each
243
 * time that a dictionary is modified. */
244
static uint64_t pydict_global_version = 0;
245
246
376k
#define DICT_NEXT_VERSION() (++pydict_global_version)
247
248
/* Dictionary reuse scheme to save calls to malloc and free */
249
#ifndef PyDict_MAXFREELIST
250
33.2k
#define PyDict_MAXFREELIST 80
251
#endif
252
static PyDictObject *free_list[PyDict_MAXFREELIST];
253
static int numfree = 0;
254
static PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
255
static int numfreekeys = 0;
256
257
#include "clinic/dictobject.c.h"
258
259
int
260
PyDict_ClearFreeList(void)
261
0
{
262
0
    PyDictObject *op;
263
0
    int ret = numfree + numfreekeys;
264
0
    while (numfree) {
265
0
        op = free_list[--numfree];
266
0
        assert(PyDict_CheckExact(op));
267
0
        PyObject_GC_Del(op);
268
0
    }
269
0
    while (numfreekeys) {
270
0
        PyObject_FREE(keys_free_list[--numfreekeys]);
271
0
    }
272
0
    return ret;
273
0
}
274
275
/* Print summary info about the state of the optimized allocator */
276
void
277
_PyDict_DebugMallocStats(FILE *out)
278
0
{
279
0
    _PyDebugAllocatorStats(out,
280
0
                           "free PyDictObject", numfree, sizeof(PyDictObject));
281
0
}
282
283
284
void
285
PyDict_Fini(void)
286
0
{
287
0
    PyDict_ClearFreeList();
288
0
}
289
290
7.33M
#define DK_SIZE(dk) ((dk)->dk_size)
291
#if SIZEOF_VOID_P > 4
292
#define DK_IXSIZE(dk)                          \
293
1.61M
    (DK_SIZE(dk) <= 0xff ?                     \
294
1.61M
        1 : DK_SIZE(dk) <= 0xffff ?            \
295
543k
            2 : DK_SIZE(dk) <= 0xffffffff ?    \
296
0
                4 : sizeof(int64_t))
297
#else
298
#define DK_IXSIZE(dk)                          \
299
    (DK_SIZE(dk) <= 0xff ?                     \
300
        1 : DK_SIZE(dk) <= 0xffff ?            \
301
            2 : sizeof(int32_t))
302
#endif
303
#define DK_ENTRIES(dk) \
304
1.60M
    ((PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[DK_SIZE(dk) * DK_IXSIZE(dk)]))
305
306
1.45M
#define DK_MASK(dk) (((dk)->dk_size)-1)
307
#define IS_POWER_OF_2(x) (((x) & (x-1)) == 0)
308
309
static void free_keys_object(PyDictKeysObject *keys);
310
311
static inline void
312
dictkeys_incref(PyDictKeysObject *dk)
313
16.4k
{
314
16.4k
    _Py_INC_REFTOTAL;
315
16.4k
    dk->dk_refcnt++;
316
16.4k
}
317
318
static inline void
319
dictkeys_decref(PyDictKeysObject *dk)
320
23.4k
{
321
23.4k
    assert(dk->dk_refcnt > 0);
322
23.4k
    _Py_DEC_REFTOTAL;
323
23.4k
    if (--dk->dk_refcnt == 0) {
324
8.24k
        free_keys_object(dk);
325
8.24k
    }
326
23.4k
}
327
328
/* lookup indices.  returns DKIX_EMPTY, DKIX_DUMMY, or ix >=0 */
329
static inline Py_ssize_t
330
dictkeys_get_index(PyDictKeysObject *keys, Py_ssize_t i)
331
2.92M
{
332
2.92M
    Py_ssize_t s = DK_SIZE(keys);
333
2.92M
    Py_ssize_t ix;
334
335
2.92M
    if (s <= 0xff) {
336
1.75M
        int8_t *indices = (int8_t*)(keys->dk_indices);
337
1.75M
        ix = indices[i];
338
1.75M
    }
339
1.16M
    else if (s <= 0xffff) {
340
1.16M
        int16_t *indices = (int16_t*)(keys->dk_indices);
341
1.16M
        ix = indices[i];
342
1.16M
    }
343
0
#if SIZEOF_VOID_P > 4
344
0
    else if (s > 0xffffffff) {
345
0
        int64_t *indices = (int64_t*)(keys->dk_indices);
346
0
        ix = indices[i];
347
0
    }
348
0
#endif
349
0
    else {
350
0
        int32_t *indices = (int32_t*)(keys->dk_indices);
351
0
        ix = indices[i];
352
0
    }
353
2.92M
    assert(ix >= DKIX_DUMMY);
354
2.92M
    return ix;
355
2.92M
}
356
357
/* write to indices. */
358
static inline void
359
dictkeys_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix)
360
637k
{
361
637k
    Py_ssize_t s = DK_SIZE(keys);
362
363
637k
    assert(ix >= DKIX_DUMMY);
364
365
637k
    if (s <= 0xff) {
366
219k
        int8_t *indices = (int8_t*)(keys->dk_indices);
367
219k
        assert(ix <= 0x7f);
368
219k
        indices[i] = (char)ix;
369
219k
    }
370
417k
    else if (s <= 0xffff) {
371
417k
        int16_t *indices = (int16_t*)(keys->dk_indices);
372
417k
        assert(ix <= 0x7fff);
373
417k
        indices[i] = (int16_t)ix;
374
417k
    }
375
0
#if SIZEOF_VOID_P > 4
376
0
    else if (s > 0xffffffff) {
377
0
        int64_t *indices = (int64_t*)(keys->dk_indices);
378
0
        indices[i] = ix;
379
0
    }
380
0
#endif
381
0
    else {
382
0
        int32_t *indices = (int32_t*)(keys->dk_indices);
383
0
        assert(ix <= 0x7fffffff);
384
0
        indices[i] = (int32_t)ix;
385
0
    }
386
637k
}
387
388
389
/* USABLE_FRACTION is the maximum dictionary load.
390
 * Increasing this ratio makes dictionaries more dense resulting in more
391
 * collisions.  Decreasing it improves sparseness at the expense of spreading
392
 * indices over more cache lines and at the cost of total memory consumed.
393
 *
394
 * USABLE_FRACTION must obey the following:
395
 *     (0 < USABLE_FRACTION(n) < n) for all n >= 2
396
 *
397
 * USABLE_FRACTION should be quick to calculate.
398
 * Fractions around 1/2 to 2/3 seem to work well in practice.
399
 */
400
30.2k
#define USABLE_FRACTION(n) (((n) << 1)/3)
401
402
/* ESTIMATE_SIZE is reverse function of USABLE_FRACTION.
403
 * This can be used to reserve enough size to insert n entries without
404
 * resizing.
405
 */
406
83
#define ESTIMATE_SIZE(n)  (((n)*3+1) >> 1)
407
408
/* Alternative fraction that is otherwise close enough to 2n/3 to make
409
 * little difference. 8 * 2/3 == 8 * 5/8 == 5. 16 * 2/3 == 16 * 5/8 == 10.
410
 * 32 * 2/3 = 21, 32 * 5/8 = 20.
411
 * Its advantage is that it is faster to compute on machines with slow division.
412
 * #define USABLE_FRACTION(n) (((n) >> 1) + ((n) >> 2) - ((n) >> 3))
413
 */
414
415
/* GROWTH_RATE. Growth rate upon hitting maximum load.
416
 * Currently set to used*3.
417
 * This means that dicts double in size when growing without deletions,
418
 * but have more head room when the number of deletions is on a par with the
419
 * number of insertions.  See also bpo-17563 and bpo-33205.
420
 *
421
 * GROWTH_RATE was set to used*4 up to version 3.2.
422
 * GROWTH_RATE was set to used*2 in version 3.3.0
423
 * GROWTH_RATE was set to used*2 + capacity/2 in 3.4.0-3.6.0.
424
 */
425
9.22k
#define GROWTH_RATE(d) ((d)->ma_used*3)
426
427
#define ENSURE_ALLOWS_DELETIONS(d) \
428
5.15k
    if ((d)->ma_keys->dk_lookup == lookdict_unicode_nodummy) { \
429
2.79k
        (d)->ma_keys->dk_lookup = lookdict_unicode; \
430
2.79k
    }
431
432
/* This immutable, empty PyDictKeysObject is used for PyDict_Clear()
433
 * (which cannot fail and thus can do no allocation).
434
 */
435
static PyDictKeysObject empty_keys_struct = {
436
        1, /* dk_refcnt */
437
        1, /* dk_size */
438
        lookdict_split, /* dk_lookup */
439
        0, /* dk_usable (immutable) */
440
        0, /* dk_nentries */
441
        {DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY,
442
         DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY}, /* dk_indices */
443
};
444
445
static PyObject *empty_values[1] = { NULL };
446
447
465k
#define Py_EMPTY_KEYS &empty_keys_struct
448
449
/* Uncomment to check the dict content in _PyDict_CheckConsistency() */
450
/* #define DEBUG_PYDICT */
451
452
#ifdef DEBUG_PYDICT
453
#  define ASSERT_CONSISTENT(op) assert(_PyDict_CheckConsistency((PyObject *)(op), 1))
454
#else
455
440k
#  define ASSERT_CONSISTENT(op) assert(_PyDict_CheckConsistency((PyObject *)(op), 0))
456
#endif
457
458
459
int
460
_PyDict_CheckConsistency(PyObject *op, int check_content)
461
0
{
462
0
#define CHECK(expr) \
463
0
    do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0)
464
465
0
    assert(op != NULL);
466
0
    CHECK(PyDict_Check(op));
467
0
    PyDictObject *mp = (PyDictObject *)op;
468
469
0
    PyDictKeysObject *keys = mp->ma_keys;
470
0
    int splitted = _PyDict_HasSplitTable(mp);
471
0
    Py_ssize_t usable = USABLE_FRACTION(keys->dk_size);
472
473
0
    CHECK(0 <= mp->ma_used && mp->ma_used <= usable);
474
0
    CHECK(IS_POWER_OF_2(keys->dk_size));
475
0
    CHECK(0 <= keys->dk_usable && keys->dk_usable <= usable);
476
0
    CHECK(0 <= keys->dk_nentries && keys->dk_nentries <= usable);
477
0
    CHECK(keys->dk_usable + keys->dk_nentries <= usable);
478
479
0
    if (!splitted) {
480
        /* combined table */
481
0
        CHECK(keys->dk_refcnt == 1);
482
0
    }
483
484
0
    if (check_content) {
485
0
        PyDictKeyEntry *entries = DK_ENTRIES(keys);
486
0
        Py_ssize_t i;
487
488
0
        for (i=0; i < keys->dk_size; i++) {
489
0
            Py_ssize_t ix = dictkeys_get_index(keys, i);
490
0
            CHECK(DKIX_DUMMY <= ix && ix <= usable);
491
0
        }
492
493
0
        for (i=0; i < usable; i++) {
494
0
            PyDictKeyEntry *entry = &entries[i];
495
0
            PyObject *key = entry->me_key;
496
497
0
            if (key != NULL) {
498
0
                if (PyUnicode_CheckExact(key)) {
499
0
                    Py_hash_t hash = ((PyASCIIObject *)key)->hash;
500
0
                    CHECK(hash != -1);
501
0
                    CHECK(entry->me_hash == hash);
502
0
                }
503
0
                else {
504
                    /* test_dict fails if PyObject_Hash() is called again */
505
0
                    CHECK(entry->me_hash != -1);
506
0
                }
507
0
                if (!splitted) {
508
0
                    CHECK(entry->me_value != NULL);
509
0
                }
510
0
            }
511
512
0
            if (splitted) {
513
0
                CHECK(entry->me_value == NULL);
514
0
            }
515
0
        }
516
517
0
        if (splitted) {
518
            /* splitted table */
519
0
            for (i=0; i < mp->ma_used; i++) {
520
0
                CHECK(mp->ma_values[i] != NULL);
521
0
            }
522
0
        }
523
0
    }
524
0
    return 1;
525
526
0
#undef CHECK
527
0
}
528
529
530
static PyDictKeysObject *new_keys_object(Py_ssize_t size)
531
21.8k
{
532
21.8k
    PyDictKeysObject *dk;
533
21.8k
    Py_ssize_t es, usable;
534
535
21.8k
    assert(size >= PyDict_MINSIZE);
536
21.8k
    assert(IS_POWER_OF_2(size));
537
538
21.8k
    usable = USABLE_FRACTION(size);
539
21.8k
    if (size <= 0xff) {
540
20.9k
        es = 1;
541
20.9k
    }
542
863
    else if (size <= 0xffff) {
543
863
        es = 2;
544
863
    }
545
0
#if SIZEOF_VOID_P > 4
546
0
    else if (size <= 0xffffffff) {
547
0
        es = 4;
548
0
    }
549
0
#endif
550
0
    else {
551
0
        es = sizeof(Py_ssize_t);
552
0
    }
553
554
21.8k
    if (size == PyDict_MINSIZE && numfreekeys > 0) {
555
9.89k
        dk = keys_free_list[--numfreekeys];
556
9.89k
    }
557
11.9k
    else {
558
11.9k
        dk = PyObject_MALLOC(sizeof(PyDictKeysObject)
559
11.9k
                             + es * size
560
11.9k
                             + sizeof(PyDictKeyEntry) * usable);
561
11.9k
        if (dk == NULL) {
562
0
            PyErr_NoMemory();
563
0
            return NULL;
564
0
        }
565
11.9k
    }
566
21.8k
    _Py_INC_REFTOTAL;
567
21.8k
    dk->dk_refcnt = 1;
568
21.8k
    dk->dk_size = size;
569
21.8k
    dk->dk_usable = usable;
570
21.8k
    dk->dk_lookup = lookdict_unicode_nodummy;
571
21.8k
    dk->dk_nentries = 0;
572
21.8k
    memset(&dk->dk_indices[0], 0xff, es * size);
573
21.8k
    memset(DK_ENTRIES(dk), 0, sizeof(PyDictKeyEntry) * usable);
574
21.8k
    return dk;
575
21.8k
}
576
577
static void
578
free_keys_object(PyDictKeysObject *keys)
579
8.24k
{
580
8.24k
    PyDictKeyEntry *entries = DK_ENTRIES(keys);
581
8.24k
    Py_ssize_t i, n;
582
178k
    for (i = 0, n = keys->dk_nentries; i < n; i++) {
583
170k
        Py_XDECREF(entries[i].me_key);
584
170k
        Py_XDECREF(entries[i].me_value);
585
170k
    }
586
8.24k
    if (keys->dk_size == PyDict_MINSIZE && numfreekeys < PyDict_MAXFREELIST) {
587
6.00k
        keys_free_list[numfreekeys++] = keys;
588
6.00k
        return;
589
6.00k
    }
590
2.23k
    PyObject_FREE(keys);
591
2.23k
}
592
593
1.87k
#define new_values(size) PyMem_NEW(PyObject *, size)
594
937
#define free_values(values) PyMem_FREE(values)
595
596
/* Consumes a reference to the keys object */
597
static PyObject *
598
new_dict(PyDictKeysObject *keys, PyObject **values)
599
19.0k
{
600
19.0k
    PyDictObject *mp;
601
19.0k
    assert(keys != NULL);
602
19.0k
    if (numfree) {
603
11.4k
        mp = free_list[--numfree];
604
11.4k
        assert (mp != NULL);
605
11.4k
        assert (Py_TYPE(mp) == &PyDict_Type);
606
11.4k
        _Py_NewReference((PyObject *)mp);
607
11.4k
    }
608
7.59k
    else {
609
7.59k
        mp = PyObject_GC_New(PyDictObject, &PyDict_Type);
610
7.59k
        if (mp == NULL) {
611
0
            dictkeys_decref(keys);
612
0
            if (values != empty_values) {
613
0
                free_values(values);
614
0
            }
615
0
            return NULL;
616
0
        }
617
7.59k
    }
618
19.0k
    mp->ma_keys = keys;
619
19.0k
    mp->ma_values = values;
620
19.0k
    mp->ma_used = 0;
621
19.0k
    mp->ma_version_tag = DICT_NEXT_VERSION();
622
19.0k
    ASSERT_CONSISTENT(mp);
623
19.0k
    return (PyObject *)mp;
624
19.0k
}
625
626
/* Consumes a reference to the keys object */
627
static PyObject *
628
new_dict_with_shared_keys(PyDictKeysObject *keys)
629
1.81k
{
630
1.81k
    PyObject **values;
631
1.81k
    Py_ssize_t i, size;
632
633
1.81k
    size = USABLE_FRACTION(DK_SIZE(keys));
634
1.81k
    values = new_values(size);
635
1.81k
    if (values == NULL) {
636
0
        dictkeys_decref(keys);
637
0
        return PyErr_NoMemory();
638
0
    }
639
15.3k
    for (i = 0; i < size; i++) {
640
13.5k
        values[i] = NULL;
641
13.5k
    }
642
1.81k
    return new_dict(keys, values);
643
1.81k
}
644
645
646
static PyObject *
647
clone_combined_dict(PyDictObject *orig)
648
2.63k
{
649
2.63k
    assert(PyDict_CheckExact(orig));
650
2.63k
    assert(orig->ma_values == NULL);
651
2.63k
    assert(orig->ma_keys->dk_refcnt == 1);
652
653
2.63k
    Py_ssize_t keys_size = _PyDict_KeysSize(orig->ma_keys);
654
2.63k
    PyDictKeysObject *keys = PyObject_Malloc(keys_size);
655
2.63k
    if (keys == NULL) {
656
0
        PyErr_NoMemory();
657
0
        return NULL;
658
0
    }
659
660
2.63k
    memcpy(keys, orig->ma_keys, keys_size);
661
662
    /* After copying key/value pairs, we need to incref all
663
       keys and values and they are about to be co-owned by a
664
       new dict object. */
665
2.63k
    PyDictKeyEntry *ep0 = DK_ENTRIES(keys);
666
2.63k
    Py_ssize_t n = keys->dk_nentries;
667
32.6k
    for (Py_ssize_t i = 0; i < n; i++) {
668
30.0k
        PyDictKeyEntry *entry = &ep0[i];
669
30.0k
        PyObject *value = entry->me_value;
670
30.0k
        if (value != NULL) {
671
29.0k
            Py_INCREF(value);
672
29.0k
            Py_INCREF(entry->me_key);
673
29.0k
        }
674
30.0k
    }
675
676
2.63k
    PyDictObject *new = (PyDictObject *)new_dict(keys, NULL);
677
2.63k
    if (new == NULL) {
678
        /* In case of an error, `new_dict()` takes care of
679
           cleaning up `keys`. */
680
0
        return NULL;
681
0
    }
682
2.63k
    new->ma_used = orig->ma_used;
683
2.63k
    ASSERT_CONSISTENT(new);
684
2.63k
    if (_PyObject_GC_IS_TRACKED(orig)) {
685
        /* Maintain tracking. */
686
2.31k
        _PyObject_GC_TRACK(new);
687
2.31k
    }
688
689
    /* Since we copied the keys table we now have an extra reference
690
       in the system.  Manually call _Py_INC_REFTOTAL to signal that
691
       we have it now; calling dictkeys_incref would be an error as
692
       keys->dk_refcnt is already set to 1 (after memcpy). */
693
2.63k
    _Py_INC_REFTOTAL;
694
695
2.63k
    return (PyObject *)new;
696
2.63k
}
697
698
PyObject *
699
PyDict_New(void)
700
14.5k
{
701
14.5k
    dictkeys_incref(Py_EMPTY_KEYS);
702
14.5k
    return new_dict(Py_EMPTY_KEYS, empty_values);
703
14.5k
}
704
705
/* Search index of hash table from offset of entry table */
706
static Py_ssize_t
707
lookdict_index(PyDictKeysObject *k, Py_hash_t hash, Py_ssize_t index)
708
5.15k
{
709
5.15k
    size_t mask = DK_MASK(k);
710
5.15k
    size_t perturb = (size_t)hash;
711
5.15k
    size_t i = (size_t)hash & mask;
712
713
7.10k
    for (;;) {
714
7.10k
        Py_ssize_t ix = dictkeys_get_index(k, i);
715
7.10k
        if (ix == index) {
716
5.15k
            return i;
717
5.15k
        }
718
1.95k
        if (ix == DKIX_EMPTY) {
719
0
            return DKIX_EMPTY;
720
0
        }
721
1.95k
        perturb >>= PERTURB_SHIFT;
722
1.95k
        i = mask & (i*5 + perturb + 1);
723
1.95k
    }
724
5.15k
    Py_UNREACHABLE();
725
5.15k
}
726
727
/*
728
The basic lookup function used by all operations.
729
This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
730
Open addressing is preferred over chaining since the link overhead for
731
chaining would be substantial (100% with typical malloc overhead).
732
733
The initial probe index is computed as hash mod the table size. Subsequent
734
probe indices are computed as explained earlier.
735
736
All arithmetic on hash should ignore overflow.
737
738
The details in this version are due to Tim Peters, building on many past
739
contributions by Reimer Behrends, Jyrki Alakuijala, Vladimir Marangozov and
740
Christian Tismer.
741
742
lookdict() is general-purpose, and may return DKIX_ERROR if (and only if) a
743
comparison raises an exception.
744
lookdict_unicode() below is specialized to string keys, comparison of which can
745
never raise an exception; that function can never return DKIX_ERROR when key
746
is string.  Otherwise, it falls back to lookdict().
747
lookdict_unicode_nodummy is further specialized for string keys that cannot be
748
the <dummy> value.
749
For both, when the key isn't found a DKIX_EMPTY is returned.
750
*/
751
static Py_ssize_t _Py_HOT_FUNCTION
752
lookdict(PyDictObject *mp, PyObject *key,
753
         Py_hash_t hash, PyObject **value_addr)
754
225k
{
755
225k
    size_t i, mask, perturb;
756
225k
    PyDictKeysObject *dk;
757
225k
    PyDictKeyEntry *ep0;
758
759
225k
top:
760
225k
    dk = mp->ma_keys;
761
225k
    ep0 = DK_ENTRIES(dk);
762
225k
    mask = DK_MASK(dk);
763
225k
    perturb = hash;
764
225k
    i = (size_t)hash & mask;
765
766
384k
    for (;;) {
767
384k
        Py_ssize_t ix = dictkeys_get_index(dk, i);
768
384k
        if (ix == DKIX_EMPTY) {
769
143k
            *value_addr = NULL;
770
143k
            return ix;
771
143k
        }
772
240k
        if (ix >= 0) {
773
240k
            PyDictKeyEntry *ep = &ep0[ix];
774
240k
            assert(ep->me_key != NULL);
775
240k
            if (ep->me_key == key) {
776
13.9k
                *value_addr = ep->me_value;
777
13.9k
                return ix;
778
13.9k
            }
779
226k
            if (ep->me_hash == hash) {
780
68.1k
                PyObject *startkey = ep->me_key;
781
68.1k
                Py_INCREF(startkey);
782
68.1k
                int cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
783
68.1k
                Py_DECREF(startkey);
784
68.1k
                if (cmp < 0) {
785
0
                    *value_addr = NULL;
786
0
                    return DKIX_ERROR;
787
0
                }
788
68.1k
                if (dk == mp->ma_keys && ep->me_key == startkey) {
789
68.1k
                    if (cmp > 0) {
790
68.1k
                        *value_addr = ep->me_value;
791
68.1k
                        return ix;
792
68.1k
                    }
793
68.1k
                }
794
0
                else {
795
                    /* The dict was mutated, restart */
796
0
                    goto top;
797
0
                }
798
68.1k
            }
799
226k
        }
800
158k
        perturb >>= PERTURB_SHIFT;
801
158k
        i = (i*5 + perturb + 1) & mask;
802
158k
    }
803
225k
    Py_UNREACHABLE();
804
225k
}
805
806
/* Specialized version for string-only keys */
807
static Py_ssize_t _Py_HOT_FUNCTION
808
lookdict_unicode(PyDictObject *mp, PyObject *key,
809
                 Py_hash_t hash, PyObject **value_addr)
810
225k
{
811
225k
    assert(mp->ma_values == NULL);
812
    /* Make sure this function doesn't have to handle non-unicode keys,
813
       including subclasses of str; e.g., one reason to subclass
814
       unicodes is to override __eq__, and for speed we don't cater to
815
       that here. */
816
225k
    if (!PyUnicode_CheckExact(key)) {
817
0
        mp->ma_keys->dk_lookup = lookdict;
818
0
        return lookdict(mp, key, hash, value_addr);
819
0
    }
820
821
225k
    PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
822
225k
    size_t mask = DK_MASK(mp->ma_keys);
823
225k
    size_t perturb = (size_t)hash;
824
225k
    size_t i = (size_t)hash & mask;
825
826
442k
    for (;;) {
827
442k
        Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
828
442k
        if (ix == DKIX_EMPTY) {
829
182k
            *value_addr = NULL;
830
182k
            return DKIX_EMPTY;
831
182k
        }
832
259k
        if (ix >= 0) {
833
236k
            PyDictKeyEntry *ep = &ep0[ix];
834
236k
            assert(ep->me_key != NULL);
835
236k
            assert(PyUnicode_CheckExact(ep->me_key));
836
236k
            if (ep->me_key == key ||
837
218k
                    (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
838
43.3k
                *value_addr = ep->me_value;
839
43.3k
                return ix;
840
43.3k
            }
841
236k
        }
842
216k
        perturb >>= PERTURB_SHIFT;
843
216k
        i = mask & (i*5 + perturb + 1);
844
216k
    }
845
225k
    Py_UNREACHABLE();
846
225k
}
847
848
/* Faster version of lookdict_unicode when it is known that no <dummy> keys
849
 * will be present. */
850
static Py_ssize_t _Py_HOT_FUNCTION
851
lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key,
852
                         Py_hash_t hash, PyObject **value_addr)
853
685k
{
854
685k
    assert(mp->ma_values == NULL);
855
    /* Make sure this function doesn't have to handle non-unicode keys,
856
       including subclasses of str; e.g., one reason to subclass
857
       unicodes is to override __eq__, and for speed we don't cater to
858
       that here. */
859
685k
    if (!PyUnicode_CheckExact(key)) {
860
28
        mp->ma_keys->dk_lookup = lookdict;
861
28
        return lookdict(mp, key, hash, value_addr);
862
28
    }
863
864
685k
    PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
865
685k
    size_t mask = DK_MASK(mp->ma_keys);
866
685k
    size_t perturb = (size_t)hash;
867
685k
    size_t i = (size_t)hash & mask;
868
869
1.09M
    for (;;) {
870
1.09M
        Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
871
1.09M
        assert (ix != DKIX_DUMMY);
872
1.09M
        if (ix == DKIX_EMPTY) {
873
441k
            *value_addr = NULL;
874
441k
            return DKIX_EMPTY;
875
441k
        }
876
651k
        PyDictKeyEntry *ep = &ep0[ix];
877
651k
        assert(ep->me_key != NULL);
878
651k
        assert(PyUnicode_CheckExact(ep->me_key));
879
651k
        if (ep->me_key == key ||
880
432k
            (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
881
244k
            *value_addr = ep->me_value;
882
244k
            return ix;
883
244k
        }
884
406k
        perturb >>= PERTURB_SHIFT;
885
406k
        i = mask & (i*5 + perturb + 1);
886
406k
    }
887
685k
    Py_UNREACHABLE();
888
685k
}
889
890
/* Version of lookdict for split tables.
891
 * All split tables and only split tables use this lookup function.
892
 * Split tables only contain unicode keys and no dummy keys,
893
 * so algorithm is the same as lookdict_unicode_nodummy.
894
 */
895
static Py_ssize_t _Py_HOT_FUNCTION
896
lookdict_split(PyDictObject *mp, PyObject *key,
897
               Py_hash_t hash, PyObject **value_addr)
898
46.5k
{
899
    /* mp must split table */
900
46.5k
    assert(mp->ma_values != NULL);
901
46.5k
    if (!PyUnicode_CheckExact(key)) {
902
34
        Py_ssize_t ix = lookdict(mp, key, hash, value_addr);
903
34
        if (ix >= 0) {
904
0
            *value_addr = mp->ma_values[ix];
905
0
        }
906
34
        return ix;
907
34
    }
908
909
46.4k
    PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
910
46.4k
    size_t mask = DK_MASK(mp->ma_keys);
911
46.4k
    size_t perturb = (size_t)hash;
912
46.4k
    size_t i = (size_t)hash & mask;
913
914
67.2k
    for (;;) {
915
67.2k
        Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
916
67.2k
        assert (ix != DKIX_DUMMY);
917
67.2k
        if (ix == DKIX_EMPTY) {
918
9.72k
            *value_addr = NULL;
919
9.72k
            return DKIX_EMPTY;
920
9.72k
        }
921
57.5k
        PyDictKeyEntry *ep = &ep0[ix];
922
57.5k
        assert(ep->me_key != NULL);
923
57.5k
        assert(PyUnicode_CheckExact(ep->me_key));
924
57.5k
        if (ep->me_key == key ||
925
36.7k
            (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
926
36.7k
            *value_addr = mp->ma_values[ix];
927
36.7k
            return ix;
928
36.7k
        }
929
20.7k
        perturb >>= PERTURB_SHIFT;
930
20.7k
        i = mask & (i*5 + perturb + 1);
931
20.7k
    }
932
46.4k
    Py_UNREACHABLE();
933
46.4k
}
934
935
int
936
_PyDict_HasOnlyStringKeys(PyObject *dict)
937
0
{
938
0
    Py_ssize_t pos = 0;
939
0
    PyObject *key, *value;
940
0
    assert(PyDict_Check(dict));
941
    /* Shortcut */
942
0
    if (((PyDictObject *)dict)->ma_keys->dk_lookup != lookdict)
943
0
        return 1;
944
0
    while (PyDict_Next(dict, &pos, &key, &value))
945
0
        if (!PyUnicode_Check(key))
946
0
            return 0;
947
0
    return 1;
948
0
}
949
950
#define MAINTAIN_TRACKING(mp, key, value) \
951
378k
    do { \
952
378k
        if (!_PyObject_GC_IS_TRACKED(mp)) { \
953
296k
            if (_PyObject_GC_MAY_BE_TRACKED(key) || \
954
296k
                _PyObject_GC_MAY_BE_TRACKED(value)) { \
955
9.22k
                _PyObject_GC_TRACK(mp); \
956
9.22k
            } \
957
296k
        } \
958
378k
    } while(0)
959
960
void
961
_PyDict_MaybeUntrack(PyObject *op)
962
0
{
963
0
    PyDictObject *mp;
964
0
    PyObject *value;
965
0
    Py_ssize_t i, numentries;
966
0
    PyDictKeyEntry *ep0;
967
968
0
    if (!PyDict_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op))
969
0
        return;
970
971
0
    mp = (PyDictObject *) op;
972
0
    ep0 = DK_ENTRIES(mp->ma_keys);
973
0
    numentries = mp->ma_keys->dk_nentries;
974
0
    if (_PyDict_HasSplitTable(mp)) {
975
0
        for (i = 0; i < numentries; i++) {
976
0
            if ((value = mp->ma_values[i]) == NULL)
977
0
                continue;
978
0
            if (_PyObject_GC_MAY_BE_TRACKED(value)) {
979
0
                assert(!_PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key));
980
0
                return;
981
0
            }
982
0
        }
983
0
    }
984
0
    else {
985
0
        for (i = 0; i < numentries; i++) {
986
0
            if ((value = ep0[i].me_value) == NULL)
987
0
                continue;
988
0
            if (_PyObject_GC_MAY_BE_TRACKED(value) ||
989
0
                _PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key))
990
0
                return;
991
0
        }
992
0
    }
993
0
    _PyObject_GC_UNTRACK(op);
994
0
}
995
996
/* Internal function to find slot for an item from its hash
997
   when it is known that the key is not present in the dict.
998
999
   The dict must be combined. */
1000
static Py_ssize_t
1001
find_empty_slot(PyDictKeysObject *keys, Py_hash_t hash)
1002
264k
{
1003
264k
    assert(keys != NULL);
1004
1005
264k
    const size_t mask = DK_MASK(keys);
1006
264k
    size_t i = hash & mask;
1007
264k
    Py_ssize_t ix = dictkeys_get_index(keys, i);
1008
497k
    for (size_t perturb = hash; ix >= 0;) {
1009
232k
        perturb >>= PERTURB_SHIFT;
1010
232k
        i = (i*5 + perturb + 1) & mask;
1011
232k
        ix = dictkeys_get_index(keys, i);
1012
232k
    }
1013
264k
    return i;
1014
264k
}
1015
1016
static int
1017
insertion_resize(PyDictObject *mp)
1018
9.22k
{
1019
9.22k
    return dictresize(mp, GROWTH_RATE(mp));
1020
9.22k
}
1021
1022
/*
1023
Internal routine to insert a new item into the table.
1024
Used both by the internal resize routine and by the public insert routine.
1025
Returns -1 if an error occurred, or 0 on success.
1026
*/
1027
static int
1028
insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
1029
326k
{
1030
326k
    PyObject *old_value;
1031
326k
    PyDictKeyEntry *ep;
1032
1033
326k
    Py_INCREF(key);
1034
326k
    Py_INCREF(value);
1035
326k
    if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) {
1036
0
        if (insertion_resize(mp) < 0)
1037
0
            goto Fail;
1038
0
    }
1039
1040
326k
    Py_ssize_t ix = mp->ma_keys->dk_lookup(mp, key, hash, &old_value);
1041
326k
    if (ix == DKIX_ERROR)
1042
0
        goto Fail;
1043
1044
326k
    assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict);
1045
326k
    MAINTAIN_TRACKING(mp, key, value);
1046
1047
    /* When insertion order is different from shared key, we can't share
1048
     * the key anymore.  Convert this instance to combine table.
1049
     */
1050
326k
    if (_PyDict_HasSplitTable(mp) &&
1051
13.0k
        ((ix >= 0 && old_value == NULL && mp->ma_used != ix) ||
1052
13.0k
         (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) {
1053
1
        if (insertion_resize(mp) < 0)
1054
0
            goto Fail;
1055
1
        ix = DKIX_EMPTY;
1056
1
    }
1057
1058
326k
    if (ix == DKIX_EMPTY) {
1059
        /* Insert into new slot. */
1060
223k
        assert(old_value == NULL);
1061
223k
        if (mp->ma_keys->dk_usable <= 0) {
1062
            /* Need to resize. */
1063
9.07k
            if (insertion_resize(mp) < 0)
1064
0
                goto Fail;
1065
9.07k
        }
1066
223k
        Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash);
1067
223k
        ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries];
1068
223k
        dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
1069
223k
        ep->me_key = key;
1070
223k
        ep->me_hash = hash;
1071
223k
        if (mp->ma_values) {
1072
659
            assert (mp->ma_values[mp->ma_keys->dk_nentries] == NULL);
1073
659
            mp->ma_values[mp->ma_keys->dk_nentries] = value;
1074
659
        }
1075
223k
        else {
1076
223k
            ep->me_value = value;
1077
223k
        }
1078
223k
        mp->ma_used++;
1079
223k
        mp->ma_version_tag = DICT_NEXT_VERSION();
1080
223k
        mp->ma_keys->dk_usable--;
1081
223k
        mp->ma_keys->dk_nentries++;
1082
223k
        assert(mp->ma_keys->dk_usable >= 0);
1083
223k
        ASSERT_CONSISTENT(mp);
1084
223k
        return 0;
1085
223k
    }
1086
1087
103k
    if (old_value != value) {
1088
75.8k
        if (_PyDict_HasSplitTable(mp)) {
1089
11.8k
            mp->ma_values[ix] = value;
1090
11.8k
            if (old_value == NULL) {
1091
                /* pending state */
1092
8.03k
                assert(ix == mp->ma_used);
1093
8.03k
                mp->ma_used++;
1094
8.03k
            }
1095
11.8k
        }
1096
63.9k
        else {
1097
63.9k
            assert(old_value != NULL);
1098
63.9k
            DK_ENTRIES(mp->ma_keys)[ix].me_value = value;
1099
63.9k
        }
1100
75.8k
        mp->ma_version_tag = DICT_NEXT_VERSION();
1101
75.8k
    }
1102
103k
    Py_XDECREF(old_value); /* which **CAN** re-enter (see issue #22653) */
1103
103k
    ASSERT_CONSISTENT(mp);
1104
103k
    Py_DECREF(key);
1105
103k
    return 0;
1106
1107
0
Fail:
1108
0
    Py_DECREF(value);
1109
0
    Py_DECREF(key);
1110
0
    return -1;
1111
326k
}
1112
1113
// Same to insertdict but specialized for ma_keys = Py_EMPTY_KEYS.
1114
static int
1115
insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash,
1116
                    PyObject *value)
1117
11.6k
{
1118
11.6k
    assert(mp->ma_keys == Py_EMPTY_KEYS);
1119
1120
11.6k
    PyDictKeysObject *newkeys = new_keys_object(PyDict_MINSIZE);
1121
11.6k
    if (newkeys == NULL) {
1122
0
        return -1;
1123
0
    }
1124
11.6k
    if (!PyUnicode_CheckExact(key)) {
1125
2.26k
        newkeys->dk_lookup = lookdict;
1126
2.26k
    }
1127
11.6k
    dictkeys_decref(Py_EMPTY_KEYS);
1128
11.6k
    mp->ma_keys = newkeys;
1129
11.6k
    mp->ma_values = NULL;
1130
1131
11.6k
    Py_INCREF(key);
1132
11.6k
    Py_INCREF(value);
1133
11.6k
    MAINTAIN_TRACKING(mp, key, value);
1134
1135
11.6k
    size_t hashpos = (size_t)hash & (PyDict_MINSIZE-1);
1136
11.6k
    PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys);
1137
11.6k
    dictkeys_set_index(mp->ma_keys, hashpos, 0);
1138
11.6k
    ep->me_key = key;
1139
11.6k
    ep->me_hash = hash;
1140
11.6k
    ep->me_value = value;
1141
11.6k
    mp->ma_used++;
1142
11.6k
    mp->ma_version_tag = DICT_NEXT_VERSION();
1143
11.6k
    mp->ma_keys->dk_usable--;
1144
11.6k
    mp->ma_keys->dk_nentries++;
1145
11.6k
    return 0;
1146
11.6k
}
1147
1148
/*
1149
Internal routine used by dictresize() to build a hashtable of entries.
1150
*/
1151
static void
1152
build_indices(PyDictKeysObject *keys, PyDictKeyEntry *ep, Py_ssize_t n)
1153
9.25k
{
1154
9.25k
    size_t mask = (size_t)DK_SIZE(keys) - 1;
1155
365k
    for (Py_ssize_t ix = 0; ix != n; ix++, ep++) {
1156
356k
        Py_hash_t hash = ep->me_hash;
1157
356k
        size_t i = hash & mask;
1158
430k
        for (size_t perturb = hash; dictkeys_get_index(keys, i) != DKIX_EMPTY;) {
1159
74.3k
            perturb >>= PERTURB_SHIFT;
1160
74.3k
            i = mask & (i*5 + perturb + 1);
1161
74.3k
        }
1162
356k
        dictkeys_set_index(keys, i, ix);
1163
356k
    }
1164
9.25k
}
1165
1166
/*
1167
Restructure the table by allocating a new table and reinserting all
1168
items again.  When entries have been deleted, the new table may
1169
actually be smaller than the old one.
1170
If a table is split (its keys and hashes are shared, its values are not),
1171
then the values are temporarily copied into the table, it is resized as
1172
a combined table, then the me_value slots in the old table are NULLed out.
1173
After resizing a table is always combined,
1174
but can be resplit by make_keys_shared().
1175
*/
1176
static int
1177
dictresize(PyDictObject *mp, Py_ssize_t minsize)
1178
9.25k
{
1179
9.25k
    Py_ssize_t newsize, numentries;
1180
9.25k
    PyDictKeysObject *oldkeys;
1181
9.25k
    PyObject **oldvalues;
1182
9.25k
    PyDictKeyEntry *oldentries, *newentries;
1183
1184
    /* Find the smallest table size > minused. */
1185
9.25k
    for (newsize = PyDict_MINSIZE;
1186
29.7k
         newsize < minsize && newsize > 0;
1187
20.4k
         newsize <<= 1)
1188
20.4k
        ;
1189
9.25k
    if (newsize <= 0) {
1190
0
        PyErr_NoMemory();
1191
0
        return -1;
1192
0
    }
1193
1194
9.25k
    oldkeys = mp->ma_keys;
1195
1196
    /* NOTE: Current odict checks mp->ma_keys to detect resize happen.
1197
     * So we can't reuse oldkeys even if oldkeys->dk_size == newsize.
1198
     * TODO: Try reusing oldkeys when reimplement odict.
1199
     */
1200
1201
    /* Allocate a new table. */
1202
9.25k
    mp->ma_keys = new_keys_object(newsize);
1203
9.25k
    if (mp->ma_keys == NULL) {
1204
0
        mp->ma_keys = oldkeys;
1205
0
        return -1;
1206
0
    }
1207
    // New table must be large enough.
1208
9.25k
    assert(mp->ma_keys->dk_usable >= mp->ma_used);
1209
9.25k
    if (oldkeys->dk_lookup == lookdict)
1210
2.88k
        mp->ma_keys->dk_lookup = lookdict;
1211
1212
9.25k
    numentries = mp->ma_used;
1213
9.25k
    oldentries = DK_ENTRIES(oldkeys);
1214
9.25k
    newentries = DK_ENTRIES(mp->ma_keys);
1215
9.25k
    oldvalues = mp->ma_values;
1216
9.25k
    if (oldvalues != NULL) {
1217
        /* Convert split table into new combined table.
1218
         * We must incref keys; we can transfer values.
1219
         * Note that values of split table is always dense.
1220
         */
1221
426
        for (Py_ssize_t i = 0; i < numentries; i++) {
1222
330
            assert(oldvalues[i] != NULL);
1223
330
            PyDictKeyEntry *ep = &oldentries[i];
1224
330
            PyObject *key = ep->me_key;
1225
330
            Py_INCREF(key);
1226
330
            newentries[i].me_key = key;
1227
330
            newentries[i].me_hash = ep->me_hash;
1228
330
            newentries[i].me_value = oldvalues[i];
1229
330
        }
1230
1231
96
        dictkeys_decref(oldkeys);
1232
96
        mp->ma_values = NULL;
1233
96
        if (oldvalues != empty_values) {
1234
64
            free_values(oldvalues);
1235
64
        }
1236
96
    }
1237
9.16k
    else {  // combined table.
1238
9.16k
        if (oldkeys->dk_nentries == numentries) {
1239
8.49k
            memcpy(newentries, oldentries, numentries * sizeof(PyDictKeyEntry));
1240
8.49k
        }
1241
663
        else {
1242
663
            PyDictKeyEntry *ep = oldentries;
1243
62.1k
            for (Py_ssize_t i = 0; i < numentries; i++) {
1244
62.6k
                while (ep->me_value == NULL)
1245
1.21k
                    ep++;
1246
61.4k
                newentries[i] = *ep++;
1247
61.4k
            }
1248
663
        }
1249
1250
9.16k
        assert(oldkeys->dk_lookup != lookdict_split);
1251
9.16k
        assert(oldkeys->dk_refcnt == 1);
1252
9.16k
        if (oldkeys->dk_size == PyDict_MINSIZE &&
1253
3.95k
            numfreekeys < PyDict_MAXFREELIST) {
1254
3.95k
            _Py_DEC_REFTOTAL;
1255
3.95k
            keys_free_list[numfreekeys++] = oldkeys;
1256
3.95k
        }
1257
5.20k
        else {
1258
5.20k
            _Py_DEC_REFTOTAL;
1259
5.20k
            PyObject_FREE(oldkeys);
1260
5.20k
        }
1261
9.16k
    }
1262
1263
9.25k
    build_indices(mp->ma_keys, newentries, numentries);
1264
9.25k
    mp->ma_keys->dk_usable -= numentries;
1265
9.25k
    mp->ma_keys->dk_nentries = numentries;
1266
9.25k
    return 0;
1267
9.25k
}
1268
1269
/* Returns NULL if unable to split table.
1270
 * A NULL return does not necessarily indicate an error */
1271
static PyDictKeysObject *
1272
make_keys_shared(PyObject *op)
1273
63
{
1274
63
    Py_ssize_t i;
1275
63
    Py_ssize_t size;
1276
63
    PyDictObject *mp = (PyDictObject *)op;
1277
1278
63
    if (!PyDict_CheckExact(op))
1279
0
        return NULL;
1280
63
    if (!_PyDict_HasSplitTable(mp)) {
1281
63
        PyDictKeyEntry *ep0;
1282
63
        PyObject **values;
1283
63
        assert(mp->ma_keys->dk_refcnt == 1);
1284
63
        if (mp->ma_keys->dk_lookup == lookdict) {
1285
0
            return NULL;
1286
0
        }
1287
63
        else if (mp->ma_keys->dk_lookup == lookdict_unicode) {
1288
            /* Remove dummy keys */
1289
0
            if (dictresize(mp, DK_SIZE(mp->ma_keys)))
1290
0
                return NULL;
1291
0
        }
1292
63
        assert(mp->ma_keys->dk_lookup == lookdict_unicode_nodummy);
1293
        /* Copy values into a new array */
1294
63
        ep0 = DK_ENTRIES(mp->ma_keys);
1295
63
        size = USABLE_FRACTION(DK_SIZE(mp->ma_keys));
1296
63
        values = new_values(size);
1297
63
        if (values == NULL) {
1298
0
            PyErr_SetString(PyExc_MemoryError,
1299
0
                "Not enough memory to allocate new values array");
1300
0
            return NULL;
1301
0
        }
1302
726
        for (i = 0; i < size; i++) {
1303
663
            values[i] = ep0[i].me_value;
1304
663
            ep0[i].me_value = NULL;
1305
663
        }
1306
63
        mp->ma_keys->dk_lookup = lookdict_split;
1307
63
        mp->ma_values = values;
1308
63
    }
1309
63
    dictkeys_incref(mp->ma_keys);
1310
63
    return mp->ma_keys;
1311
63
}
1312
1313
PyObject *
1314
_PyDict_NewPresized(Py_ssize_t minused)
1315
3.79k
{
1316
3.79k
    const Py_ssize_t max_presize = 128 * 1024;
1317
3.79k
    Py_ssize_t newsize;
1318
3.79k
    PyDictKeysObject *new_keys;
1319
1320
3.79k
    if (minused <= USABLE_FRACTION(PyDict_MINSIZE)) {
1321
3.74k
        return PyDict_New();
1322
3.74k
    }
1323
    /* There are no strict guarantee that returned dict can contain minused
1324
     * items without resize.  So we create medium size dict instead of very
1325
     * large dict or MemoryError.
1326
     */
1327
50
    if (minused > USABLE_FRACTION(max_presize)) {
1328
0
        newsize = max_presize;
1329
0
    }
1330
50
    else {
1331
50
        Py_ssize_t minsize = ESTIMATE_SIZE(minused);
1332
50
        newsize = PyDict_MINSIZE*2;
1333
120
        while (newsize < minsize) {
1334
70
            newsize <<= 1;
1335
70
        }
1336
50
    }
1337
50
    assert(IS_POWER_OF_2(newsize));
1338
1339
50
    new_keys = new_keys_object(newsize);
1340
50
    if (new_keys == NULL)
1341
0
        return NULL;
1342
50
    return new_dict(new_keys, NULL);
1343
50
}
1344
1345
/* Note that, for historical reasons, PyDict_GetItem() suppresses all errors
1346
 * that may occur (originally dicts supported only string keys, and exceptions
1347
 * weren't possible).  So, while the original intent was that a NULL return
1348
 * meant the key wasn't present, in reality it can mean that, or that an error
1349
 * (suppressed) occurred while computing the key's hash, or that some error
1350
 * (suppressed) occurred when comparing keys in the dict's internal probe
1351
 * sequence.  A nasty example of the latter is when a Python-coded comparison
1352
 * function hits a stack-depth error, which can cause this to return NULL
1353
 * even if the key is present.
1354
 */
1355
PyObject *
1356
PyDict_GetItem(PyObject *op, PyObject *key)
1357
16.7k
{
1358
16.7k
    Py_hash_t hash;
1359
16.7k
    Py_ssize_t ix;
1360
16.7k
    PyDictObject *mp = (PyDictObject *)op;
1361
16.7k
    PyThreadState *tstate;
1362
16.7k
    PyObject *value;
1363
1364
16.7k
    if (!PyDict_Check(op))
1365
0
        return NULL;
1366
16.7k
    if (!PyUnicode_CheckExact(key) ||
1367
16.7k
        (hash = ((PyASCIIObject *) key)->hash) == -1)
1368
1.13k
    {
1369
1.13k
        hash = PyObject_Hash(key);
1370
1.13k
        if (hash == -1) {
1371
0
            PyErr_Clear();
1372
0
            return NULL;
1373
0
        }
1374
1.13k
    }
1375
1376
    /* We can arrive here with a NULL tstate during initialization: try
1377
       running "python -Wi" for an example related to string interning.
1378
       Let's just hope that no exception occurs then...  This must be
1379
       _PyThreadState_GET() and not PyThreadState_Get() because the latter
1380
       abort Python if tstate is NULL. */
1381
16.7k
    tstate = _PyThreadState_GET();
1382
16.7k
    if (tstate != NULL && tstate->curexc_type != NULL) {
1383
        /* preserve the existing exception */
1384
0
        PyObject *err_type, *err_value, *err_tb;
1385
0
        PyErr_Fetch(&err_type, &err_value, &err_tb);
1386
0
        ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
1387
        /* ignore errors */
1388
0
        PyErr_Restore(err_type, err_value, err_tb);
1389
0
        if (ix < 0)
1390
0
            return NULL;
1391
0
    }
1392
16.7k
    else {
1393
16.7k
        ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
1394
16.7k
        if (ix < 0) {
1395
8.42k
            PyErr_Clear();
1396
8.42k
            return NULL;
1397
8.42k
        }
1398
16.7k
    }
1399
8.27k
    return value;
1400
16.7k
}
1401
1402
/* Same as PyDict_GetItemWithError() but with hash supplied by caller.
1403
   This returns NULL *with* an exception set if an exception occurred.
1404
   It returns NULL *without* an exception set if the key wasn't present.
1405
*/
1406
PyObject *
1407
_PyDict_GetItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
1408
441k
{
1409
441k
    Py_ssize_t ix;
1410
441k
    PyDictObject *mp = (PyDictObject *)op;
1411
441k
    PyObject *value;
1412
1413
441k
    if (!PyDict_Check(op)) {
1414
0
        PyErr_BadInternalCall();
1415
0
        return NULL;
1416
0
    }
1417
1418
441k
    ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
1419
441k
    if (ix < 0) {
1420
412k
        return NULL;
1421
412k
    }
1422
29.0k
    return value;
1423
441k
}
1424
1425
/* Variant of PyDict_GetItem() that doesn't suppress exceptions.
1426
   This returns NULL *with* an exception set if an exception occurred.
1427
   It returns NULL *without* an exception set if the key wasn't present.
1428
*/
1429
PyObject *
1430
PyDict_GetItemWithError(PyObject *op, PyObject *key)
1431
206k
{
1432
206k
    Py_ssize_t ix;
1433
206k
    Py_hash_t hash;
1434
206k
    PyDictObject*mp = (PyDictObject *)op;
1435
206k
    PyObject *value;
1436
1437
206k
    if (!PyDict_Check(op)) {
1438
0
        PyErr_BadInternalCall();
1439
0
        return NULL;
1440
0
    }
1441
206k
    if (!PyUnicode_CheckExact(key) ||
1442
205k
        (hash = ((PyASCIIObject *) key)->hash) == -1)
1443
2.20k
    {
1444
2.20k
        hash = PyObject_Hash(key);
1445
2.20k
        if (hash == -1) {
1446
0
            return NULL;
1447
0
        }
1448
2.20k
    }
1449
1450
206k
    ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
1451
206k
    if (ix < 0)
1452
70.7k
        return NULL;
1453
135k
    return value;
1454
206k
}
1455
1456
PyObject *
1457
_PyDict_GetItemIdWithError(PyObject *dp, struct _Py_Identifier *key)
1458
28.2k
{
1459
28.2k
    PyObject *kv;
1460
28.2k
    kv = _PyUnicode_FromId(key); /* borrowed */
1461
28.2k
    if (kv == NULL)
1462
0
        return NULL;
1463
28.2k
    return PyDict_GetItemWithError(dp, kv);
1464
28.2k
}
1465
1466
PyObject *
1467
_PyDict_GetItemStringWithError(PyObject *v, const char *key)
1468
456
{
1469
456
    PyObject *kv, *rv;
1470
456
    kv = PyUnicode_FromString(key);
1471
456
    if (kv == NULL) {
1472
0
        return NULL;
1473
0
    }
1474
456
    rv = PyDict_GetItemWithError(v, kv);
1475
456
    Py_DECREF(kv);
1476
456
    return rv;
1477
456
}
1478
1479
/* Fast version of global value lookup (LOAD_GLOBAL).
1480
 * Lookup in globals, then builtins.
1481
 *
1482
 * Raise an exception and return NULL if an error occurred (ex: computing the
1483
 * key hash failed, key comparison failed, ...). Return NULL if the key doesn't
1484
 * exist. Return the value if the key exists.
1485
 */
1486
PyObject *
1487
_PyDict_LoadGlobal(PyDictObject *globals, PyDictObject *builtins, PyObject *key)
1488
73.4k
{
1489
73.4k
    Py_ssize_t ix;
1490
73.4k
    Py_hash_t hash;
1491
73.4k
    PyObject *value;
1492
1493
73.4k
    if (!PyUnicode_CheckExact(key) ||
1494
73.4k
        (hash = ((PyASCIIObject *) key)->hash) == -1)
1495
0
    {
1496
0
        hash = PyObject_Hash(key);
1497
0
        if (hash == -1)
1498
0
            return NULL;
1499
0
    }
1500
1501
    /* namespace 1: globals */
1502
73.4k
    ix = globals->ma_keys->dk_lookup(globals, key, hash, &value);
1503
73.4k
    if (ix == DKIX_ERROR)
1504
0
        return NULL;
1505
73.4k
    if (ix != DKIX_EMPTY && value != NULL)
1506
54.7k
        return value;
1507
1508
    /* namespace 2: builtins */
1509
18.6k
    ix = builtins->ma_keys->dk_lookup(builtins, key, hash, &value);
1510
18.6k
    if (ix < 0)
1511
52
        return NULL;
1512
18.6k
    return value;
1513
18.6k
}
1514
1515
/* CAUTION: PyDict_SetItem() must guarantee that it won't resize the
1516
 * dictionary if it's merely replacing the value for an existing key.
1517
 * This means that it's safe to loop over a dictionary with PyDict_Next()
1518
 * and occasionally replace a value -- but you can't insert new keys or
1519
 * remove them.
1520
 */
1521
int
1522
PyDict_SetItem(PyObject *op, PyObject *key, PyObject *value)
1523
337k
{
1524
337k
    PyDictObject *mp;
1525
337k
    Py_hash_t hash;
1526
337k
    if (!PyDict_Check(op)) {
1527
0
        PyErr_BadInternalCall();
1528
0
        return -1;
1529
0
    }
1530
337k
    assert(key);
1531
337k
    assert(value);
1532
337k
    mp = (PyDictObject *)op;
1533
337k
    if (!PyUnicode_CheckExact(key) ||
1534
112k
        (hash = ((PyASCIIObject *) key)->hash) == -1)
1535
225k
    {
1536
225k
        hash = PyObject_Hash(key);
1537
225k
        if (hash == -1)
1538
0
            return -1;
1539
225k
    }
1540
1541
337k
    if (mp->ma_keys == Py_EMPTY_KEYS) {
1542
11.5k
        return insert_to_emptydict(mp, key, hash, value);
1543
11.5k
    }
1544
    /* insertdict() handles any resizing that might be necessary */
1545
326k
    return insertdict(mp, key, hash, value);
1546
337k
}
1547
1548
int
1549
_PyDict_SetItem_KnownHash(PyObject *op, PyObject *key, PyObject *value,
1550
                         Py_hash_t hash)
1551
0
{
1552
0
    PyDictObject *mp;
1553
1554
0
    if (!PyDict_Check(op)) {
1555
0
        PyErr_BadInternalCall();
1556
0
        return -1;
1557
0
    }
1558
0
    assert(key);
1559
0
    assert(value);
1560
0
    assert(hash != -1);
1561
0
    mp = (PyDictObject *)op;
1562
1563
0
    if (mp->ma_keys == Py_EMPTY_KEYS) {
1564
0
        return insert_to_emptydict(mp, key, hash, value);
1565
0
    }
1566
    /* insertdict() handles any resizing that might be necessary */
1567
0
    return insertdict(mp, key, hash, value);
1568
0
}
1569
1570
static int
1571
delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix,
1572
               PyObject *old_value)
1573
4.73k
{
1574
4.73k
    PyObject *old_key;
1575
4.73k
    PyDictKeyEntry *ep;
1576
1577
4.73k
    Py_ssize_t hashpos = lookdict_index(mp->ma_keys, hash, ix);
1578
4.73k
    assert(hashpos >= 0);
1579
1580
4.73k
    mp->ma_used--;
1581
4.73k
    mp->ma_version_tag = DICT_NEXT_VERSION();
1582
4.73k
    ep = &DK_ENTRIES(mp->ma_keys)[ix];
1583
4.73k
    dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
1584
4.73k
    ENSURE_ALLOWS_DELETIONS(mp);
1585
4.73k
    old_key = ep->me_key;
1586
4.73k
    ep->me_key = NULL;
1587
4.73k
    ep->me_value = NULL;
1588
4.73k
    Py_DECREF(old_key);
1589
4.73k
    Py_DECREF(old_value);
1590
1591
4.73k
    ASSERT_CONSISTENT(mp);
1592
4.73k
    return 0;
1593
4.73k
}
1594
1595
int
1596
PyDict_DelItem(PyObject *op, PyObject *key)
1597
4.73k
{
1598
4.73k
    Py_hash_t hash;
1599
4.73k
    assert(key);
1600
4.73k
    if (!PyUnicode_CheckExact(key) ||
1601
4.34k
        (hash = ((PyASCIIObject *) key)->hash) == -1) {
1602
424
        hash = PyObject_Hash(key);
1603
424
        if (hash == -1)
1604
0
            return -1;
1605
424
    }
1606
1607
4.73k
    return _PyDict_DelItem_KnownHash(op, key, hash);
1608
4.73k
}
1609
1610
int
1611
_PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
1612
4.73k
{
1613
4.73k
    Py_ssize_t ix;
1614
4.73k
    PyDictObject *mp;
1615
4.73k
    PyObject *old_value;
1616
1617
4.73k
    if (!PyDict_Check(op)) {
1618
0
        PyErr_BadInternalCall();
1619
0
        return -1;
1620
0
    }
1621
4.73k
    assert(key);
1622
4.73k
    assert(hash != -1);
1623
4.73k
    mp = (PyDictObject *)op;
1624
4.73k
    ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
1625
4.73k
    if (ix == DKIX_ERROR)
1626
0
        return -1;
1627
4.73k
    if (ix == DKIX_EMPTY || old_value == NULL) {
1628
0
        _PyErr_SetKeyError(key);
1629
0
        return -1;
1630
0
    }
1631
1632
    // Split table doesn't allow deletion.  Combine it.
1633
4.73k
    if (_PyDict_HasSplitTable(mp)) {
1634
0
        if (dictresize(mp, DK_SIZE(mp->ma_keys))) {
1635
0
            return -1;
1636
0
        }
1637
0
        ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
1638
0
        assert(ix >= 0);
1639
0
    }
1640
1641
4.73k
    return delitem_common(mp, hash, ix, old_value);
1642
4.73k
}
1643
1644
/* This function promises that the predicate -> deletion sequence is atomic
1645
 * (i.e. protected by the GIL), assuming the predicate itself doesn't
1646
 * release the GIL.
1647
 */
1648
int
1649
_PyDict_DelItemIf(PyObject *op, PyObject *key,
1650
                  int (*predicate)(PyObject *value))
1651
0
{
1652
0
    Py_ssize_t hashpos, ix;
1653
0
    PyDictObject *mp;
1654
0
    Py_hash_t hash;
1655
0
    PyObject *old_value;
1656
0
    int res;
1657
1658
0
    if (!PyDict_Check(op)) {
1659
0
        PyErr_BadInternalCall();
1660
0
        return -1;
1661
0
    }
1662
0
    assert(key);
1663
0
    hash = PyObject_Hash(key);
1664
0
    if (hash == -1)
1665
0
        return -1;
1666
0
    mp = (PyDictObject *)op;
1667
0
    ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
1668
0
    if (ix == DKIX_ERROR)
1669
0
        return -1;
1670
0
    if (ix == DKIX_EMPTY || old_value == NULL) {
1671
0
        _PyErr_SetKeyError(key);
1672
0
        return -1;
1673
0
    }
1674
1675
    // Split table doesn't allow deletion.  Combine it.
1676
0
    if (_PyDict_HasSplitTable(mp)) {
1677
0
        if (dictresize(mp, DK_SIZE(mp->ma_keys))) {
1678
0
            return -1;
1679
0
        }
1680
0
        ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
1681
0
        assert(ix >= 0);
1682
0
    }
1683
1684
0
    res = predicate(old_value);
1685
0
    if (res == -1)
1686
0
        return -1;
1687
1688
0
    hashpos = lookdict_index(mp->ma_keys, hash, ix);
1689
0
    assert(hashpos >= 0);
1690
1691
0
    if (res > 0)
1692
0
        return delitem_common(mp, hashpos, ix, old_value);
1693
0
    else
1694
0
        return 0;
1695
0
}
1696
1697
1698
void
1699
PyDict_Clear(PyObject *op)
1700
12
{
1701
12
    PyDictObject *mp;
1702
12
    PyDictKeysObject *oldkeys;
1703
12
    PyObject **oldvalues;
1704
12
    Py_ssize_t i, n;
1705
1706
12
    if (!PyDict_Check(op))
1707
0
        return;
1708
12
    mp = ((PyDictObject *)op);
1709
12
    oldkeys = mp->ma_keys;
1710
12
    oldvalues = mp->ma_values;
1711
12
    if (oldvalues == empty_values)
1712
6
        return;
1713
    /* Empty the dict... */
1714
6
    dictkeys_incref(Py_EMPTY_KEYS);
1715
6
    mp->ma_keys = Py_EMPTY_KEYS;
1716
6
    mp->ma_values = empty_values;
1717
6
    mp->ma_used = 0;
1718
6
    mp->ma_version_tag = DICT_NEXT_VERSION();
1719
    /* ...then clear the keys and values */
1720
6
    if (oldvalues != NULL) {
1721
0
        n = oldkeys->dk_nentries;
1722
0
        for (i = 0; i < n; i++)
1723
0
            Py_CLEAR(oldvalues[i]);
1724
0
        free_values(oldvalues);
1725
0
        dictkeys_decref(oldkeys);
1726
0
    }
1727
6
    else {
1728
6
       assert(oldkeys->dk_refcnt == 1);
1729
6
       dictkeys_decref(oldkeys);
1730
6
    }
1731
6
    ASSERT_CONSISTENT(mp);
1732
6
}
1733
1734
/* Internal version of PyDict_Next that returns a hash value in addition
1735
 * to the key and value.
1736
 * Return 1 on success, return 0 when the reached the end of the dictionary
1737
 * (or if op is not a dictionary)
1738
 */
1739
int
1740
_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
1741
             PyObject **pvalue, Py_hash_t *phash)
1742
12.9k
{
1743
12.9k
    Py_ssize_t i;
1744
12.9k
    PyDictObject *mp;
1745
12.9k
    PyDictKeyEntry *entry_ptr;
1746
12.9k
    PyObject *value;
1747
1748
12.9k
    if (!PyDict_Check(op))
1749
0
        return 0;
1750
12.9k
    mp = (PyDictObject *)op;
1751
12.9k
    i = *ppos;
1752
12.9k
    if (mp->ma_values) {
1753
63
        if (i < 0 || i >= mp->ma_used)
1754
63
            return 0;
1755
        /* values of split table is always dense */
1756
0
        entry_ptr = &DK_ENTRIES(mp->ma_keys)[i];
1757
0
        value = mp->ma_values[i];
1758
0
        assert(value != NULL);
1759
0
    }
1760
12.9k
    else {
1761
12.9k
        Py_ssize_t n = mp->ma_keys->dk_nentries;
1762
12.9k
        if (i < 0 || i >= n)
1763
1.91k
            return 0;
1764
10.9k
        entry_ptr = &DK_ENTRIES(mp->ma_keys)[i];
1765
11.9k
        while (i < n && entry_ptr->me_value == NULL) {
1766
987
            entry_ptr++;
1767
987
            i++;
1768
987
        }
1769
10.9k
        if (i >= n)
1770
14
            return 0;
1771
10.9k
        value = entry_ptr->me_value;
1772
10.9k
    }
1773
10.9k
    *ppos = i+1;
1774
10.9k
    if (pkey)
1775
10.9k
        *pkey = entry_ptr->me_key;
1776
10.9k
    if (phash)
1777
17
        *phash = entry_ptr->me_hash;
1778
10.9k
    if (pvalue)
1779
10.9k
        *pvalue = value;
1780
10.9k
    return 1;
1781
12.9k
}
1782
1783
/*
1784
 * Iterate over a dict.  Use like so:
1785
 *
1786
 *     Py_ssize_t i;
1787
 *     PyObject *key, *value;
1788
 *     i = 0;   # important!  i should not otherwise be changed by you
1789
 *     while (PyDict_Next(yourdict, &i, &key, &value)) {
1790
 *         Refer to borrowed references in key and value.
1791
 *     }
1792
 *
1793
 * Return 1 on success, return 0 when the reached the end of the dictionary
1794
 * (or if op is not a dictionary)
1795
 *
1796
 * CAUTION:  In general, it isn't safe to use PyDict_Next in a loop that
1797
 * mutates the dict.  One exception:  it is safe if the loop merely changes
1798
 * the values associated with the keys (but doesn't insert new keys or
1799
 * delete keys), via PyDict_SetItem().
1800
 */
1801
int
1802
PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
1803
12.9k
{
1804
12.9k
    return _PyDict_Next(op, ppos, pkey, pvalue, NULL);
1805
12.9k
}
1806
1807
/* Internal version of dict.pop(). */
1808
PyObject *
1809
_PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *deflt)
1810
420
{
1811
420
    Py_ssize_t ix, hashpos;
1812
420
    PyObject *old_value, *old_key;
1813
420
    PyDictKeyEntry *ep;
1814
420
    PyDictObject *mp;
1815
1816
420
    assert(PyDict_Check(dict));
1817
420
    mp = (PyDictObject *)dict;
1818
1819
420
    if (mp->ma_used == 0) {
1820
0
        if (deflt) {
1821
0
            Py_INCREF(deflt);
1822
0
            return deflt;
1823
0
        }
1824
0
        _PyErr_SetKeyError(key);
1825
0
        return NULL;
1826
0
    }
1827
420
    ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
1828
420
    if (ix == DKIX_ERROR)
1829
0
        return NULL;
1830
420
    if (ix == DKIX_EMPTY || old_value == NULL) {
1831
5
        if (deflt) {
1832
5
            Py_INCREF(deflt);
1833
5
            return deflt;
1834
5
        }
1835
0
        _PyErr_SetKeyError(key);
1836
0
        return NULL;
1837
5
    }
1838
1839
    // Split table doesn't allow deletion.  Combine it.
1840
415
    if (_PyDict_HasSplitTable(mp)) {
1841
0
        if (dictresize(mp, DK_SIZE(mp->ma_keys))) {
1842
0
            return NULL;
1843
0
        }
1844
0
        ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
1845
0
        assert(ix >= 0);
1846
0
    }
1847
1848
415
    hashpos = lookdict_index(mp->ma_keys, hash, ix);
1849
415
    assert(hashpos >= 0);
1850
415
    assert(old_value != NULL);
1851
415
    mp->ma_used--;
1852
415
    mp->ma_version_tag = DICT_NEXT_VERSION();
1853
415
    dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
1854
415
    ep = &DK_ENTRIES(mp->ma_keys)[ix];
1855
415
    ENSURE_ALLOWS_DELETIONS(mp);
1856
415
    old_key = ep->me_key;
1857
415
    ep->me_key = NULL;
1858
415
    ep->me_value = NULL;
1859
415
    Py_DECREF(old_key);
1860
1861
415
    ASSERT_CONSISTENT(mp);
1862
415
    return old_value;
1863
415
}
1864
1865
PyObject *
1866
_PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt)
1867
429
{
1868
429
    Py_hash_t hash;
1869
1870
429
    if (((PyDictObject *)dict)->ma_used == 0) {
1871
9
        if (deflt) {
1872
9
            Py_INCREF(deflt);
1873
9
            return deflt;
1874
9
        }
1875
0
        _PyErr_SetKeyError(key);
1876
0
        return NULL;
1877
9
    }
1878
420
    if (!PyUnicode_CheckExact(key) ||
1879
420
        (hash = ((PyASCIIObject *) key)->hash) == -1) {
1880
0
        hash = PyObject_Hash(key);
1881
0
        if (hash == -1)
1882
0
            return NULL;
1883
0
    }
1884
420
    return _PyDict_Pop_KnownHash(dict, key, hash, deflt);
1885
420
}
1886
1887
/* Internal version of dict.from_keys().  It is subclass-friendly. */
1888
PyObject *
1889
_PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)
1890
17
{
1891
17
    PyObject *it;       /* iter(iterable) */
1892
17
    PyObject *key;
1893
17
    PyObject *d;
1894
17
    int status;
1895
1896
17
    d = _PyObject_CallNoArg(cls);
1897
17
    if (d == NULL)
1898
0
        return NULL;
1899
1900
17
    if (PyDict_CheckExact(d) && ((PyDictObject *)d)->ma_used == 0) {
1901
17
        if (PyDict_CheckExact(iterable)) {
1902
0
            PyDictObject *mp = (PyDictObject *)d;
1903
0
            PyObject *oldvalue;
1904
0
            Py_ssize_t pos = 0;
1905
0
            PyObject *key;
1906
0
            Py_hash_t hash;
1907
1908
0
            if (dictresize(mp, ESTIMATE_SIZE(PyDict_GET_SIZE(iterable)))) {
1909
0
                Py_DECREF(d);
1910
0
                return NULL;
1911
0
            }
1912
1913
0
            while (_PyDict_Next(iterable, &pos, &key, &oldvalue, &hash)) {
1914
0
                if (insertdict(mp, key, hash, value)) {
1915
0
                    Py_DECREF(d);
1916
0
                    return NULL;
1917
0
                }
1918
0
            }
1919
0
            return d;
1920
0
        }
1921
17
        if (PyAnySet_CheckExact(iterable)) {
1922
0
            PyDictObject *mp = (PyDictObject *)d;
1923
0
            Py_ssize_t pos = 0;
1924
0
            PyObject *key;
1925
0
            Py_hash_t hash;
1926
1927
0
            if (dictresize(mp, ESTIMATE_SIZE(PySet_GET_SIZE(iterable)))) {
1928
0
                Py_DECREF(d);
1929
0
                return NULL;
1930
0
            }
1931
1932
0
            while (_PySet_NextEntry(iterable, &pos, &key, &hash)) {
1933
0
                if (insertdict(mp, key, hash, value)) {
1934
0
                    Py_DECREF(d);
1935
0
                    return NULL;
1936
0
                }
1937
0
            }
1938
0
            return d;
1939
0
        }
1940
17
    }
1941
1942
17
    it = PyObject_GetIter(iterable);
1943
17
    if (it == NULL){
1944
0
        Py_DECREF(d);
1945
0
        return NULL;
1946
0
    }
1947
1948
17
    if (PyDict_CheckExact(d)) {
1949
82
        while ((key = PyIter_Next(it)) != NULL) {
1950
65
            status = PyDict_SetItem(d, key, value);
1951
65
            Py_DECREF(key);
1952
65
            if (status < 0)
1953
0
                goto Fail;
1954
65
        }
1955
17
    } else {
1956
0
        while ((key = PyIter_Next(it)) != NULL) {
1957
0
            status = PyObject_SetItem(d, key, value);
1958
0
            Py_DECREF(key);
1959
0
            if (status < 0)
1960
0
                goto Fail;
1961
0
        }
1962
0
    }
1963
1964
17
    if (PyErr_Occurred())
1965
0
        goto Fail;
1966
17
    Py_DECREF(it);
1967
17
    return d;
1968
1969
0
Fail:
1970
0
    Py_DECREF(it);
1971
0
    Py_DECREF(d);
1972
0
    return NULL;
1973
17
}
1974
1975
/* Methods */
1976
1977
static void
1978
dict_dealloc(PyDictObject *mp)
1979
11.6k
{
1980
11.6k
    PyObject **values = mp->ma_values;
1981
11.6k
    PyDictKeysObject *keys = mp->ma_keys;
1982
11.6k
    Py_ssize_t i, n;
1983
1984
    /* bpo-31095: UnTrack is needed before calling any callbacks */
1985
11.6k
    PyObject_GC_UnTrack(mp);
1986
11.6k
    Py_TRASHCAN_BEGIN(mp, dict_dealloc)
1987
11.6k
    if (values != NULL) {
1988
3.46k
        if (values != empty_values) {
1989
4.81k
            for (i = 0, n = mp->ma_keys->dk_nentries; i < n; i++) {
1990
3.94k
                Py_XDECREF(values[i]);
1991
3.94k
            }
1992
873
            free_values(values);
1993
873
        }
1994
3.46k
        dictkeys_decref(keys);
1995
3.46k
    }
1996
8.16k
    else if (keys != NULL) {
1997
8.16k
        assert(keys->dk_refcnt == 1);
1998
8.16k
        dictkeys_decref(keys);
1999
8.16k
    }
2000
11.6k
    if (numfree < PyDict_MAXFREELIST && Py_TYPE(mp) == &PyDict_Type)
2001
11.6k
        free_list[numfree++] = mp;
2002
5
    else
2003
5
        Py_TYPE(mp)->tp_free((PyObject *)mp);
2004
11.6k
    Py_TRASHCAN_END
2005
11.6k
}
2006
2007
2008
static PyObject *
2009
dict_repr(PyDictObject *mp)
2010
0
{
2011
0
    Py_ssize_t i;
2012
0
    PyObject *key = NULL, *value = NULL;
2013
0
    _PyUnicodeWriter writer;
2014
0
    int first;
2015
2016
0
    i = Py_ReprEnter((PyObject *)mp);
2017
0
    if (i != 0) {
2018
0
        return i > 0 ? PyUnicode_FromString("{...}") : NULL;
2019
0
    }
2020
2021
0
    if (mp->ma_used == 0) {
2022
0
        Py_ReprLeave((PyObject *)mp);
2023
0
        return PyUnicode_FromString("{}");
2024
0
    }
2025
2026
0
    _PyUnicodeWriter_Init(&writer);
2027
0
    writer.overallocate = 1;
2028
    /* "{" + "1: 2" + ", 3: 4" * (len - 1) + "}" */
2029
0
    writer.min_length = 1 + 4 + (2 + 4) * (mp->ma_used - 1) + 1;
2030
2031
0
    if (_PyUnicodeWriter_WriteChar(&writer, '{') < 0)
2032
0
        goto error;
2033
2034
    /* Do repr() on each key+value pair, and insert ": " between them.
2035
       Note that repr may mutate the dict. */
2036
0
    i = 0;
2037
0
    first = 1;
2038
0
    while (PyDict_Next((PyObject *)mp, &i, &key, &value)) {
2039
0
        PyObject *s;
2040
0
        int res;
2041
2042
        /* Prevent repr from deleting key or value during key format. */
2043
0
        Py_INCREF(key);
2044
0
        Py_INCREF(value);
2045
2046
0
        if (!first) {
2047
0
            if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0)
2048
0
                goto error;
2049
0
        }
2050
0
        first = 0;
2051
2052
0
        s = PyObject_Repr(key);
2053
0
        if (s == NULL)
2054
0
            goto error;
2055
0
        res = _PyUnicodeWriter_WriteStr(&writer, s);
2056
0
        Py_DECREF(s);
2057
0
        if (res < 0)
2058
0
            goto error;
2059
2060
0
        if (_PyUnicodeWriter_WriteASCIIString(&writer, ": ", 2) < 0)
2061
0
            goto error;
2062
2063
0
        s = PyObject_Repr(value);
2064
0
        if (s == NULL)
2065
0
            goto error;
2066
0
        res = _PyUnicodeWriter_WriteStr(&writer, s);
2067
0
        Py_DECREF(s);
2068
0
        if (res < 0)
2069
0
            goto error;
2070
2071
0
        Py_CLEAR(key);
2072
0
        Py_CLEAR(value);
2073
0
    }
2074
2075
0
    writer.overallocate = 0;
2076
0
    if (_PyUnicodeWriter_WriteChar(&writer, '}') < 0)
2077
0
        goto error;
2078
2079
0
    Py_ReprLeave((PyObject *)mp);
2080
2081
0
    return _PyUnicodeWriter_Finish(&writer);
2082
2083
0
error:
2084
0
    Py_ReprLeave((PyObject *)mp);
2085
0
    _PyUnicodeWriter_Dealloc(&writer);
2086
0
    Py_XDECREF(key);
2087
0
    Py_XDECREF(value);
2088
0
    return NULL;
2089
0
}
2090
2091
static Py_ssize_t
2092
dict_length(PyDictObject *mp)
2093
85
{
2094
85
    return mp->ma_used;
2095
85
}
2096
2097
static PyObject *
2098
dict_subscript(PyDictObject *mp, PyObject *key)
2099
3.88k
{
2100
3.88k
    Py_ssize_t ix;
2101
3.88k
    Py_hash_t hash;
2102
3.88k
    PyObject *value;
2103
2104
3.88k
    if (!PyUnicode_CheckExact(key) ||
2105
3.20k
        (hash = ((PyASCIIObject *) key)->hash) == -1) {
2106
749
        hash = PyObject_Hash(key);
2107
749
        if (hash == -1)
2108
0
            return NULL;
2109
749
    }
2110
3.88k
    ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
2111
3.88k
    if (ix == DKIX_ERROR)
2112
0
        return NULL;
2113
3.88k
    if (ix == DKIX_EMPTY || value == NULL) {
2114
478
        if (!PyDict_CheckExact(mp)) {
2115
            /* Look up __missing__ method if we're a subclass. */
2116
22
            PyObject *missing, *res;
2117
22
            _Py_IDENTIFIER(__missing__);
2118
22
            missing = _PyObject_LookupSpecial((PyObject *)mp, &PyId___missing__);
2119
22
            if (missing != NULL) {
2120
0
                res = PyObject_CallFunctionObjArgs(missing,
2121
0
                                                   key, NULL);
2122
0
                Py_DECREF(missing);
2123
0
                return res;
2124
0
            }
2125
22
            else if (PyErr_Occurred())
2126
0
                return NULL;
2127
22
        }
2128
478
        _PyErr_SetKeyError(key);
2129
478
        return NULL;
2130
478
    }
2131
3.40k
    Py_INCREF(value);
2132
3.40k
    return value;
2133
3.88k
}
2134
2135
static int
2136
dict_ass_sub(PyDictObject *mp, PyObject *v, PyObject *w)
2137
4.28k
{
2138
4.28k
    if (w == NULL)
2139
2.18k
        return PyDict_DelItem((PyObject *)mp, v);
2140
2.09k
    else
2141
2.09k
        return PyDict_SetItem((PyObject *)mp, v, w);
2142
4.28k
}
2143
2144
static PyMappingMethods dict_as_mapping = {
2145
    (lenfunc)dict_length, /*mp_length*/
2146
    (binaryfunc)dict_subscript, /*mp_subscript*/
2147
    (objobjargproc)dict_ass_sub, /*mp_ass_subscript*/
2148
};
2149
2150
static PyObject *
2151
dict_keys(PyDictObject *mp)
2152
97
{
2153
97
    PyObject *v;
2154
97
    Py_ssize_t i, j;
2155
97
    PyDictKeyEntry *ep;
2156
97
    Py_ssize_t n, offset;
2157
97
    PyObject **value_ptr;
2158
2159
97
  again:
2160
97
    n = mp->ma_used;
2161
97
    v = PyList_New(n);
2162
97
    if (v == NULL)
2163
0
        return NULL;
2164
97
    if (n != mp->ma_used) {
2165
        /* Durnit.  The allocations caused the dict to resize.
2166
         * Just start over, this shouldn't normally happen.
2167
         */
2168
0
        Py_DECREF(v);
2169
0
        goto again;
2170
0
    }
2171
97
    ep = DK_ENTRIES(mp->ma_keys);
2172
97
    if (mp->ma_values) {
2173
0
        value_ptr = mp->ma_values;
2174
0
        offset = sizeof(PyObject *);
2175
0
    }
2176
97
    else {
2177
97
        value_ptr = &ep[0].me_value;
2178
97
        offset = sizeof(PyDictKeyEntry);
2179
97
    }
2180
9.94k
    for (i = 0, j = 0; j < n; i++) {
2181
9.84k
        if (*value_ptr != NULL) {
2182
9.84k
            PyObject *key = ep[i].me_key;
2183
9.84k
            Py_INCREF(key);
2184
9.84k
            PyList_SET_ITEM(v, j, key);
2185
9.84k
            j++;
2186
9.84k
        }
2187
9.84k
        value_ptr = (PyObject **)(((char *)value_ptr) + offset);
2188
9.84k
    }
2189
97
    assert(j == n);
2190
97
    return v;
2191
97
}
2192
2193
static PyObject *
2194
dict_values(PyDictObject *mp)
2195
0
{
2196
0
    PyObject *v;
2197
0
    Py_ssize_t i, j;
2198
0
    PyDictKeyEntry *ep;
2199
0
    Py_ssize_t n, offset;
2200
0
    PyObject **value_ptr;
2201
2202
0
  again:
2203
0
    n = mp->ma_used;
2204
0
    v = PyList_New(n);
2205
0
    if (v == NULL)
2206
0
        return NULL;
2207
0
    if (n != mp->ma_used) {
2208
        /* Durnit.  The allocations caused the dict to resize.
2209
         * Just start over, this shouldn't normally happen.
2210
         */
2211
0
        Py_DECREF(v);
2212
0
        goto again;
2213
0
    }
2214
0
    ep = DK_ENTRIES(mp->ma_keys);
2215
0
    if (mp->ma_values) {
2216
0
        value_ptr = mp->ma_values;
2217
0
        offset = sizeof(PyObject *);
2218
0
    }
2219
0
    else {
2220
0
        value_ptr = &ep[0].me_value;
2221
0
        offset = sizeof(PyDictKeyEntry);
2222
0
    }
2223
0
    for (i = 0, j = 0; j < n; i++) {
2224
0
        PyObject *value = *value_ptr;
2225
0
        value_ptr = (PyObject **)(((char *)value_ptr) + offset);
2226
0
        if (value != NULL) {
2227
0
            Py_INCREF(value);
2228
0
            PyList_SET_ITEM(v, j, value);
2229
0
            j++;
2230
0
        }
2231
0
    }
2232
0
    assert(j == n);
2233
0
    return v;
2234
0
}
2235
2236
static PyObject *
2237
dict_items(PyDictObject *mp)
2238
0
{
2239
0
    PyObject *v;
2240
0
    Py_ssize_t i, j, n;
2241
0
    Py_ssize_t offset;
2242
0
    PyObject *item, *key;
2243
0
    PyDictKeyEntry *ep;
2244
0
    PyObject **value_ptr;
2245
2246
    /* Preallocate the list of tuples, to avoid allocations during
2247
     * the loop over the items, which could trigger GC, which
2248
     * could resize the dict. :-(
2249
     */
2250
0
  again:
2251
0
    n = mp->ma_used;
2252
0
    v = PyList_New(n);
2253
0
    if (v == NULL)
2254
0
        return NULL;
2255
0
    for (i = 0; i < n; i++) {
2256
0
        item = PyTuple_New(2);
2257
0
        if (item == NULL) {
2258
0
            Py_DECREF(v);
2259
0
            return NULL;
2260
0
        }
2261
0
        PyList_SET_ITEM(v, i, item);
2262
0
    }
2263
0
    if (n != mp->ma_used) {
2264
        /* Durnit.  The allocations caused the dict to resize.
2265
         * Just start over, this shouldn't normally happen.
2266
         */
2267
0
        Py_DECREF(v);
2268
0
        goto again;
2269
0
    }
2270
    /* Nothing we do below makes any function calls. */
2271
0
    ep = DK_ENTRIES(mp->ma_keys);
2272
0
    if (mp->ma_values) {
2273
0
        value_ptr = mp->ma_values;
2274
0
        offset = sizeof(PyObject *);
2275
0
    }
2276
0
    else {
2277
0
        value_ptr = &ep[0].me_value;
2278
0
        offset = sizeof(PyDictKeyEntry);
2279
0
    }
2280
0
    for (i = 0, j = 0; j < n; i++) {
2281
0
        PyObject *value = *value_ptr;
2282
0
        value_ptr = (PyObject **)(((char *)value_ptr) + offset);
2283
0
        if (value != NULL) {
2284
0
            key = ep[i].me_key;
2285
0
            item = PyList_GET_ITEM(v, j);
2286
0
            Py_INCREF(key);
2287
0
            PyTuple_SET_ITEM(item, 0, key);
2288
0
            Py_INCREF(value);
2289
0
            PyTuple_SET_ITEM(item, 1, value);
2290
0
            j++;
2291
0
        }
2292
0
    }
2293
0
    assert(j == n);
2294
0
    return v;
2295
0
}
2296
2297
/*[clinic input]
2298
@classmethod
2299
dict.fromkeys
2300
    iterable: object
2301
    value: object=None
2302
    /
2303
2304
Create a new dictionary with keys from iterable and values set to value.
2305
[clinic start generated code]*/
2306
2307
static PyObject *
2308
dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value)
2309
/*[clinic end generated code: output=8fb98e4b10384999 input=382ba4855d0f74c3]*/
2310
17
{
2311
17
    return _PyDict_FromKeys((PyObject *)type, iterable, value);
2312
17
}
2313
2314
static int
2315
dict_update_common(PyObject *self, PyObject *args, PyObject *kwds,
2316
                   const char *methname)
2317
158
{
2318
158
    PyObject *arg = NULL;
2319
158
    int result = 0;
2320
2321
158
    if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) {
2322
0
        result = -1;
2323
0
    }
2324
158
    else if (arg != NULL) {
2325
136
        _Py_IDENTIFIER(keys);
2326
136
        PyObject *func;
2327
136
        if (_PyObject_LookupAttrId(arg, &PyId_keys, &func) < 0) {
2328
0
            result = -1;
2329
0
        }
2330
136
        else if (func != NULL) {
2331
135
            Py_DECREF(func);
2332
135
            result = PyDict_Merge(self, arg, 1);
2333
135
        }
2334
1
        else {
2335
1
            result = PyDict_MergeFromSeq2(self, arg, 1);
2336
1
        }
2337
136
    }
2338
2339
158
    if (result == 0 && kwds != NULL) {
2340
0
        if (PyArg_ValidateKeywordArguments(kwds))
2341
0
            result = PyDict_Merge(self, kwds, 1);
2342
0
        else
2343
0
            result = -1;
2344
0
    }
2345
158
    return result;
2346
158
}
2347
2348
/* Note: dict.update() uses the METH_VARARGS|METH_KEYWORDS calling convention.
2349
   Using METH_FASTCALL|METH_KEYWORDS would make dict.update(**dict2) calls
2350
   slower, see the issue #29312. */
2351
static PyObject *
2352
dict_update(PyObject *self, PyObject *args, PyObject *kwds)
2353
135
{
2354
135
    if (dict_update_common(self, args, kwds, "update") != -1)
2355
135
        Py_RETURN_NONE;
2356
0
    return NULL;
2357
135
}
2358
2359
/* Update unconditionally replaces existing items.
2360
   Merge has a 3rd argument 'override'; if set, it acts like Update,
2361
   otherwise it leaves existing items unchanged.
2362
2363
   PyDict_{Update,Merge} update/merge from a mapping object.
2364
2365
   PyDict_MergeFromSeq2 updates/merges from any iterable object
2366
   producing iterable objects of length 2.
2367
*/
2368
2369
int
2370
PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)
2371
1
{
2372
1
    PyObject *it;       /* iter(seq2) */
2373
1
    Py_ssize_t i;       /* index into seq2 of current element */
2374
1
    PyObject *item;     /* seq2[i] */
2375
1
    PyObject *fast;     /* item as a 2-tuple or 2-list */
2376
2377
1
    assert(d != NULL);
2378
1
    assert(PyDict_Check(d));
2379
1
    assert(seq2 != NULL);
2380
2381
1
    it = PyObject_GetIter(seq2);
2382
1
    if (it == NULL)
2383
0
        return -1;
2384
2385
1
    for (i = 0; ; ++i) {
2386
1
        PyObject *key, *value;
2387
1
        Py_ssize_t n;
2388
2389
1
        fast = NULL;
2390
1
        item = PyIter_Next(it);
2391
1
        if (item == NULL) {
2392
1
            if (PyErr_Occurred())
2393
0
                goto Fail;
2394
1
            break;
2395
1
        }
2396
2397
        /* Convert item to sequence, and verify length 2. */
2398
0
        fast = PySequence_Fast(item, "");
2399
0
        if (fast == NULL) {
2400
0
            if (PyErr_ExceptionMatches(PyExc_TypeError))
2401
0
                PyErr_Format(PyExc_TypeError,
2402
0
                    "cannot convert dictionary update "
2403
0
                    "sequence element #%zd to a sequence",
2404
0
                    i);
2405
0
            goto Fail;
2406
0
        }
2407
0
        n = PySequence_Fast_GET_SIZE(fast);
2408
0
        if (n != 2) {
2409
0
            PyErr_Format(PyExc_ValueError,
2410
0
                         "dictionary update sequence element #%zd "
2411
0
                         "has length %zd; 2 is required",
2412
0
                         i, n);
2413
0
            goto Fail;
2414
0
        }
2415
2416
        /* Update/merge with this (key, value) pair. */
2417
0
        key = PySequence_Fast_GET_ITEM(fast, 0);
2418
0
        value = PySequence_Fast_GET_ITEM(fast, 1);
2419
0
        Py_INCREF(key);
2420
0
        Py_INCREF(value);
2421
0
        if (override) {
2422
0
            if (PyDict_SetItem(d, key, value) < 0) {
2423
0
                Py_DECREF(key);
2424
0
                Py_DECREF(value);
2425
0
                goto Fail;
2426
0
            }
2427
0
        }
2428
0
        else if (PyDict_GetItemWithError(d, key) == NULL) {
2429
0
            if (PyErr_Occurred() || PyDict_SetItem(d, key, value) < 0) {
2430
0
                Py_DECREF(key);
2431
0
                Py_DECREF(value);
2432
0
                goto Fail;
2433
0
            }
2434
0
        }
2435
2436
0
        Py_DECREF(key);
2437
0
        Py_DECREF(value);
2438
0
        Py_DECREF(fast);
2439
0
        Py_DECREF(item);
2440
0
    }
2441
2442
1
    i = 0;
2443
1
    ASSERT_CONSISTENT(d);
2444
1
    goto Return;
2445
0
Fail:
2446
0
    Py_XDECREF(item);
2447
0
    Py_XDECREF(fast);
2448
0
    i = -1;
2449
1
Return:
2450
1
    Py_DECREF(it);
2451
1
    return Py_SAFE_DOWNCAST(i, Py_ssize_t, int);
2452
0
}
2453
2454
static int
2455
dict_merge(PyObject *a, PyObject *b, int override)
2456
207
{
2457
207
    PyDictObject *mp, *other;
2458
207
    Py_ssize_t i, n;
2459
207
    PyDictKeyEntry *entry, *ep0;
2460
2461
207
    assert(0 <= override && override <= 2);
2462
2463
    /* We accept for the argument either a concrete dictionary object,
2464
     * or an abstract "mapping" object.  For the former, we can do
2465
     * things quite efficiently.  For the latter, we only require that
2466
     * PyMapping_Keys() and PyObject_GetItem() be supported.
2467
     */
2468
207
    if (a == NULL || !PyDict_Check(a) || b == NULL) {
2469
0
        PyErr_BadInternalCall();
2470
0
        return -1;
2471
0
    }
2472
207
    mp = (PyDictObject*)a;
2473
207
    if (PyDict_Check(b) && (Py_TYPE(b)->tp_iter == (getiterfunc)dict_iter)) {
2474
206
        other = (PyDictObject*)b;
2475
206
        if (other == mp || other->ma_used == 0)
2476
            /* a.update(a) or a.update({}); nothing to do */
2477
145
            return 0;
2478
61
        if (mp->ma_used == 0)
2479
            /* Since the target dict is empty, PyDict_GetItem()
2480
             * always returns NULL.  Setting override to 1
2481
             * skips the unnecessary test.
2482
             */
2483
32
            override = 1;
2484
        /* Do one big resize at the start, rather than
2485
         * incrementally resizing as we insert new items.  Expect
2486
         * that there will be no (or few) overlapping keys.
2487
         */
2488
61
        if (USABLE_FRACTION(mp->ma_keys->dk_size) < other->ma_used) {
2489
33
            if (dictresize(mp, ESTIMATE_SIZE(mp->ma_used + other->ma_used))) {
2490
0
               return -1;
2491
0
            }
2492
33
        }
2493
61
        ep0 = DK_ENTRIES(other->ma_keys);
2494
767
        for (i = 0, n = other->ma_keys->dk_nentries; i < n; i++) {
2495
706
            PyObject *key, *value;
2496
706
            Py_hash_t hash;
2497
706
            entry = &ep0[i];
2498
706
            key = entry->me_key;
2499
706
            hash = entry->me_hash;
2500
706
            if (other->ma_values)
2501
0
                value = other->ma_values[i];
2502
706
            else
2503
706
                value = entry->me_value;
2504
2505
706
            if (value != NULL) {
2506
684
                int err = 0;
2507
684
                Py_INCREF(key);
2508
684
                Py_INCREF(value);
2509
684
                if (override == 1)
2510
684
                    err = insertdict(mp, key, hash, value);
2511
0
                else if (_PyDict_GetItem_KnownHash(a, key, hash) == NULL) {
2512
0
                    if (PyErr_Occurred()) {
2513
0
                        Py_DECREF(value);
2514
0
                        Py_DECREF(key);
2515
0
                        return -1;
2516
0
                    }
2517
0
                    err = insertdict(mp, key, hash, value);
2518
0
                }
2519
0
                else if (override != 0) {
2520
0
                    _PyErr_SetKeyError(key);
2521
0
                    Py_DECREF(value);
2522
0
                    Py_DECREF(key);
2523
0
                    return -1;
2524
0
                }
2525
684
                Py_DECREF(value);
2526
684
                Py_DECREF(key);
2527
684
                if (err != 0)
2528
0
                    return -1;
2529
2530
684
                if (n != other->ma_keys->dk_nentries) {
2531
0
                    PyErr_SetString(PyExc_RuntimeError,
2532
0
                                    "dict mutated during update");
2533
0
                    return -1;
2534
0
                }
2535
684
            }
2536
706
        }
2537
61
    }
2538
1
    else {
2539
        /* Do it the generic, slower way */
2540
1
        PyObject *keys = PyMapping_Keys(b);
2541
1
        PyObject *iter;
2542
1
        PyObject *key, *value;
2543
1
        int status;
2544
2545
1
        if (keys == NULL)
2546
            /* Docstring says this is equivalent to E.keys() so
2547
             * if E doesn't have a .keys() method we want
2548
             * AttributeError to percolate up.  Might as well
2549
             * do the same for any other error.
2550
             */
2551
0
            return -1;
2552
2553
1
        iter = PyObject_GetIter(keys);
2554
1
        Py_DECREF(keys);
2555
1
        if (iter == NULL)
2556
0
            return -1;
2557
2558
18
        for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) {
2559
17
            if (override != 1) {
2560
0
                if (PyDict_GetItemWithError(a, key) != NULL) {
2561
0
                    if (override != 0) {
2562
0
                        _PyErr_SetKeyError(key);
2563
0
                        Py_DECREF(key);
2564
0
                        Py_DECREF(iter);
2565
0
                        return -1;
2566
0
                    }
2567
0
                    Py_DECREF(key);
2568
0
                    continue;
2569
0
                }
2570
0
                else if (PyErr_Occurred()) {
2571
0
                    Py_DECREF(key);
2572
0
                    Py_DECREF(iter);
2573
0
                    return -1;
2574
0
                }
2575
0
            }
2576
17
            value = PyObject_GetItem(b, key);
2577
17
            if (value == NULL) {
2578
0
                Py_DECREF(iter);
2579
0
                Py_DECREF(key);
2580
0
                return -1;
2581
0
            }
2582
17
            status = PyDict_SetItem(a, key, value);
2583
17
            Py_DECREF(key);
2584
17
            Py_DECREF(value);
2585
17
            if (status < 0) {
2586
0
                Py_DECREF(iter);
2587
0
                return -1;
2588
0
            }
2589
17
        }
2590
1
        Py_DECREF(iter);
2591
1
        if (PyErr_Occurred())
2592
            /* Iterator completed, via error */
2593
0
            return -1;
2594
1
    }
2595
62
    ASSERT_CONSISTENT(a);
2596
62
    return 0;
2597
207
}
2598
2599
int
2600
PyDict_Update(PyObject *a, PyObject *b)
2601
39
{
2602
39
    return dict_merge(a, b, 1);
2603
39
}
2604
2605
int
2606
PyDict_Merge(PyObject *a, PyObject *b, int override)
2607
140
{
2608
    /* XXX Deprecate override not in (0, 1). */
2609
140
    return dict_merge(a, b, override != 0);
2610
140
}
2611
2612
int
2613
_PyDict_MergeEx(PyObject *a, PyObject *b, int override)
2614
28
{
2615
28
    return dict_merge(a, b, override);
2616
28
}
2617
2618
static PyObject *
2619
dict_copy(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
2620
0
{
2621
0
    return PyDict_Copy((PyObject*)mp);
2622
0
}
2623
2624
PyObject *
2625
PyDict_Copy(PyObject *o)
2626
2.65k
{
2627
2.65k
    PyObject *copy;
2628
2.65k
    PyDictObject *mp;
2629
2.65k
    Py_ssize_t i, n;
2630
2631
2.65k
    if (o == NULL || !PyDict_Check(o)) {
2632
0
        PyErr_BadInternalCall();
2633
0
        return NULL;
2634
0
    }
2635
2636
2.65k
    mp = (PyDictObject *)o;
2637
2.65k
    if (mp->ma_used == 0) {
2638
        /* The dict is empty; just return a new dict. */
2639
13
        return PyDict_New();
2640
13
    }
2641
2642
2.64k
    if (_PyDict_HasSplitTable(mp)) {
2643
0
        PyDictObject *split_copy;
2644
0
        Py_ssize_t size = USABLE_FRACTION(DK_SIZE(mp->ma_keys));
2645
0
        PyObject **newvalues;
2646
0
        newvalues = new_values(size);
2647
0
        if (newvalues == NULL)
2648
0
            return PyErr_NoMemory();
2649
0
        split_copy = PyObject_GC_New(PyDictObject, &PyDict_Type);
2650
0
        if (split_copy == NULL) {
2651
0
            free_values(newvalues);
2652
0
            return NULL;
2653
0
        }
2654
0
        split_copy->ma_values = newvalues;
2655
0
        split_copy->ma_keys = mp->ma_keys;
2656
0
        split_copy->ma_used = mp->ma_used;
2657
0
        split_copy->ma_version_tag = DICT_NEXT_VERSION();
2658
0
        dictkeys_incref(mp->ma_keys);
2659
0
        for (i = 0, n = size; i < n; i++) {
2660
0
            PyObject *value = mp->ma_values[i];
2661
0
            Py_XINCREF(value);
2662
0
            split_copy->ma_values[i] = value;
2663
0
        }
2664
0
        if (_PyObject_GC_IS_TRACKED(mp))
2665
0
            _PyObject_GC_TRACK(split_copy);
2666
0
        return (PyObject *)split_copy;
2667
0
    }
2668
2669
2.64k
    if (PyDict_CheckExact(mp) && mp->ma_values == NULL &&
2670
2.63k
            (mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3))
2671
2.63k
    {
2672
        /* Use fast-copy if:
2673
2674
           (1) 'mp' is an instance of a subclassed dict; and
2675
2676
           (2) 'mp' is not a split-dict; and
2677
2678
           (3) if 'mp' is non-compact ('del' operation does not resize dicts),
2679
               do fast-copy only if it has at most 1/3 non-used keys.
2680
2681
           The last condition (3) is important to guard against a pathological
2682
           case when a large dict is almost emptied with multiple del/pop
2683
           operations and copied after that.  In cases like this, we defer to
2684
           PyDict_Merge, which produces a compacted copy.
2685
        */
2686
2.63k
        return clone_combined_dict(mp);
2687
2.63k
    }
2688
2689
5
    copy = PyDict_New();
2690
5
    if (copy == NULL)
2691
0
        return NULL;
2692
5
    if (PyDict_Merge(copy, o, 1) == 0)
2693
5
        return copy;
2694
0
    Py_DECREF(copy);
2695
0
    return NULL;
2696
5
}
2697
2698
Py_ssize_t
2699
PyDict_Size(PyObject *mp)
2700
0
{
2701
0
    if (mp == NULL || !PyDict_Check(mp)) {
2702
0
        PyErr_BadInternalCall();
2703
0
        return -1;
2704
0
    }
2705
0
    return ((PyDictObject *)mp)->ma_used;
2706
0
}
2707
2708
PyObject *
2709
PyDict_Keys(PyObject *mp)
2710
97
{
2711
97
    if (mp == NULL || !PyDict_Check(mp)) {
2712
0
        PyErr_BadInternalCall();
2713
0
        return NULL;
2714
0
    }
2715
97
    return dict_keys((PyDictObject *)mp);
2716
97
}
2717
2718
PyObject *
2719
PyDict_Values(PyObject *mp)
2720
0
{
2721
0
    if (mp == NULL || !PyDict_Check(mp)) {
2722
0
        PyErr_BadInternalCall();
2723
0
        return NULL;
2724
0
    }
2725
0
    return dict_values((PyDictObject *)mp);
2726
0
}
2727
2728
PyObject *
2729
PyDict_Items(PyObject *mp)
2730
0
{
2731
0
    if (mp == NULL || !PyDict_Check(mp)) {
2732
0
        PyErr_BadInternalCall();
2733
0
        return NULL;
2734
0
    }
2735
0
    return dict_items((PyDictObject *)mp);
2736
0
}
2737
2738
/* Return 1 if dicts equal, 0 if not, -1 if error.
2739
 * Gets out as soon as any difference is detected.
2740
 * Uses only Py_EQ comparison.
2741
 */
2742
static int
2743
dict_equal(PyDictObject *a, PyDictObject *b)
2744
0
{
2745
0
    Py_ssize_t i;
2746
2747
0
    if (a->ma_used != b->ma_used)
2748
        /* can't be equal if # of entries differ */
2749
0
        return 0;
2750
    /* Same # of entries -- check all of 'em.  Exit early on any diff. */
2751
0
    for (i = 0; i < a->ma_keys->dk_nentries; i++) {
2752
0
        PyDictKeyEntry *ep = &DK_ENTRIES(a->ma_keys)[i];
2753
0
        PyObject *aval;
2754
0
        if (a->ma_values)
2755
0
            aval = a->ma_values[i];
2756
0
        else
2757
0
            aval = ep->me_value;
2758
0
        if (aval != NULL) {
2759
0
            int cmp;
2760
0
            PyObject *bval;
2761
0
            PyObject *key = ep->me_key;
2762
            /* temporarily bump aval's refcount to ensure it stays
2763
               alive until we're done with it */
2764
0
            Py_INCREF(aval);
2765
            /* ditto for key */
2766
0
            Py_INCREF(key);
2767
            /* reuse the known hash value */
2768
0
            b->ma_keys->dk_lookup(b, key, ep->me_hash, &bval);
2769
0
            if (bval == NULL) {
2770
0
                Py_DECREF(key);
2771
0
                Py_DECREF(aval);
2772
0
                if (PyErr_Occurred())
2773
0
                    return -1;
2774
0
                return 0;
2775
0
            }
2776
0
            Py_INCREF(bval);
2777
0
            cmp = PyObject_RichCompareBool(aval, bval, Py_EQ);
2778
0
            Py_DECREF(key);
2779
0
            Py_DECREF(aval);
2780
0
            Py_DECREF(bval);
2781
0
            if (cmp <= 0)  /* error or not equal */
2782
0
                return cmp;
2783
0
        }
2784
0
    }
2785
0
    return 1;
2786
0
}
2787
2788
static PyObject *
2789
dict_richcompare(PyObject *v, PyObject *w, int op)
2790
0
{
2791
0
    int cmp;
2792
0
    PyObject *res;
2793
2794
0
    if (!PyDict_Check(v) || !PyDict_Check(w)) {
2795
0
        res = Py_NotImplemented;
2796
0
    }
2797
0
    else if (op == Py_EQ || op == Py_NE) {
2798
0
        cmp = dict_equal((PyDictObject *)v, (PyDictObject *)w);
2799
0
        if (cmp < 0)
2800
0
            return NULL;
2801
0
        res = (cmp == (op == Py_EQ)) ? Py_True : Py_False;
2802
0
    }
2803
0
    else
2804
0
        res = Py_NotImplemented;
2805
0
    Py_INCREF(res);
2806
0
    return res;
2807
0
}
2808
2809
/*[clinic input]
2810
2811
@coexist
2812
dict.__contains__
2813
2814
  key: object
2815
  /
2816
2817
True if the dictionary has the specified key, else False.
2818
[clinic start generated code]*/
2819
2820
static PyObject *
2821
dict___contains__(PyDictObject *self, PyObject *key)
2822
/*[clinic end generated code: output=a3d03db709ed6e6b input=fe1cb42ad831e820]*/
2823
27
{
2824
27
    register PyDictObject *mp = self;
2825
27
    Py_hash_t hash;
2826
27
    Py_ssize_t ix;
2827
27
    PyObject *value;
2828
2829
27
    if (!PyUnicode_CheckExact(key) ||
2830
27
        (hash = ((PyASCIIObject *) key)->hash) == -1) {
2831
0
        hash = PyObject_Hash(key);
2832
0
        if (hash == -1)
2833
0
            return NULL;
2834
0
    }
2835
27
    ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
2836
27
    if (ix == DKIX_ERROR)
2837
0
        return NULL;
2838
27
    if (ix == DKIX_EMPTY || value == NULL)
2839
22
        Py_RETURN_FALSE;
2840
27
    Py_RETURN_TRUE;
2841
27
}
2842
2843
/*[clinic input]
2844
dict.get
2845
2846
    key: object
2847
    default: object = None
2848
    /
2849
2850
Return the value for key if key is in the dictionary, else default.
2851
[clinic start generated code]*/
2852
2853
static PyObject *
2854
dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value)
2855
/*[clinic end generated code: output=bba707729dee05bf input=279ddb5790b6b107]*/
2856
909
{
2857
909
    PyObject *val = NULL;
2858
909
    Py_hash_t hash;
2859
909
    Py_ssize_t ix;
2860
2861
909
    if (!PyUnicode_CheckExact(key) ||
2862
889
        (hash = ((PyASCIIObject *) key)->hash) == -1) {
2863
78
        hash = PyObject_Hash(key);
2864
78
        if (hash == -1)
2865
0
            return NULL;
2866
78
    }
2867
909
    ix = (self->ma_keys->dk_lookup) (self, key, hash, &val);
2868
909
    if (ix == DKIX_ERROR)
2869
0
        return NULL;
2870
909
    if (ix == DKIX_EMPTY || val == NULL) {
2871
484
        val = default_value;
2872
484
    }
2873
909
    Py_INCREF(val);
2874
909
    return val;
2875
909
}
2876
2877
PyObject *
2878
PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj)
2879
87.0k
{
2880
87.0k
    PyDictObject *mp = (PyDictObject *)d;
2881
87.0k
    PyObject *value;
2882
87.0k
    Py_hash_t hash;
2883
2884
87.0k
    if (!PyDict_Check(d)) {
2885
0
        PyErr_BadInternalCall();
2886
0
        return NULL;
2887
0
    }
2888
2889
87.0k
    if (!PyUnicode_CheckExact(key) ||
2890
87.0k
        (hash = ((PyASCIIObject *) key)->hash) == -1) {
2891
87.0k
        hash = PyObject_Hash(key);
2892
87.0k
        if (hash == -1)
2893
0
            return NULL;
2894
87.0k
    }
2895
87.0k
    if (mp->ma_keys == Py_EMPTY_KEYS) {
2896
28
        if (insert_to_emptydict(mp, key, hash, defaultobj) < 0) {
2897
0
            return NULL;
2898
0
        }
2899
28
        return defaultobj;
2900
28
    }
2901
2902
87.0k
    if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) {
2903
0
        if (insertion_resize(mp) < 0)
2904
0
            return NULL;
2905
0
    }
2906
2907
87.0k
    Py_ssize_t ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
2908
87.0k
    if (ix == DKIX_ERROR)
2909
0
        return NULL;
2910
2911
87.0k
    if (_PyDict_HasSplitTable(mp) &&
2912
0
        ((ix >= 0 && value == NULL && mp->ma_used != ix) ||
2913
0
         (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) {
2914
0
        if (insertion_resize(mp) < 0) {
2915
0
            return NULL;
2916
0
        }
2917
0
        ix = DKIX_EMPTY;
2918
0
    }
2919
2920
87.0k
    if (ix == DKIX_EMPTY) {
2921
40.4k
        PyDictKeyEntry *ep, *ep0;
2922
40.4k
        value = defaultobj;
2923
40.4k
        if (mp->ma_keys->dk_usable <= 0) {
2924
147
            if (insertion_resize(mp) < 0) {
2925
0
                return NULL;
2926
0
            }
2927
147
        }
2928
40.4k
        Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash);
2929
40.4k
        ep0 = DK_ENTRIES(mp->ma_keys);
2930
40.4k
        ep = &ep0[mp->ma_keys->dk_nentries];
2931
40.4k
        dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
2932
40.4k
        Py_INCREF(key);
2933
40.4k
        Py_INCREF(value);
2934
40.4k
        MAINTAIN_TRACKING(mp, key, value);
2935
40.4k
        ep->me_key = key;
2936
40.4k
        ep->me_hash = hash;
2937
40.4k
        if (_PyDict_HasSplitTable(mp)) {
2938
0
            assert(mp->ma_values[mp->ma_keys->dk_nentries] == NULL);
2939
0
            mp->ma_values[mp->ma_keys->dk_nentries] = value;
2940
0
        }
2941
40.4k
        else {
2942
40.4k
            ep->me_value = value;
2943
40.4k
        }
2944
40.4k
        mp->ma_used++;
2945
40.4k
        mp->ma_version_tag = DICT_NEXT_VERSION();
2946
40.4k
        mp->ma_keys->dk_usable--;
2947
40.4k
        mp->ma_keys->dk_nentries++;
2948
40.4k
        assert(mp->ma_keys->dk_usable >= 0);
2949
40.4k
    }
2950
46.5k
    else if (value == NULL) {
2951
0
        value = defaultobj;
2952
0
        assert(_PyDict_HasSplitTable(mp));
2953
0
        assert(ix == mp->ma_used);
2954
0
        Py_INCREF(value);
2955
0
        MAINTAIN_TRACKING(mp, key, value);
2956
0
        mp->ma_values[ix] = value;
2957
0
        mp->ma_used++;
2958
0
        mp->ma_version_tag = DICT_NEXT_VERSION();
2959
0
    }
2960
2961
87.0k
    ASSERT_CONSISTENT(mp);
2962
87.0k
    return value;
2963
87.0k
}
2964
2965
/*[clinic input]
2966
dict.setdefault
2967
2968
    key: object
2969
    default: object = None
2970
    /
2971
2972
Insert key with a value of default if key is not in the dictionary.
2973
2974
Return the value for key if key is in the dictionary, else default.
2975
[clinic start generated code]*/
2976
2977
static PyObject *
2978
dict_setdefault_impl(PyDictObject *self, PyObject *key,
2979
                     PyObject *default_value)
2980
/*[clinic end generated code: output=f8c1101ebf69e220 input=0f063756e815fd9d]*/
2981
7
{
2982
7
    PyObject *val;
2983
2984
7
    val = PyDict_SetDefault((PyObject *)self, key, default_value);
2985
7
    Py_XINCREF(val);
2986
7
    return val;
2987
7
}
2988
2989
static PyObject *
2990
dict_clear(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
2991
0
{
2992
0
    PyDict_Clear((PyObject *)mp);
2993
0
    Py_RETURN_NONE;
2994
0
}
2995
2996
/*
2997
We don't use Argument Clinic for dict.pop because it doesn't support
2998
custom signature for now.
2999
*/
3000
PyDoc_STRVAR(dict_pop__doc__,
3001
"D.pop(k[,d]) -> v, remove specified key and return the corresponding value.\n\
3002
If key is not found, d is returned if given, otherwise KeyError is raised");
3003
3004
#define DICT_POP_METHODDEF    \
3005
    {"pop", (PyCFunction)(void(*)(void))dict_pop, METH_FASTCALL, dict_pop__doc__},
3006
3007
static PyObject *
3008
dict_pop(PyDictObject *self, PyObject *const *args, Py_ssize_t nargs)
3009
429
{
3010
429
    PyObject *return_value = NULL;
3011
429
    PyObject *key;
3012
429
    PyObject *default_value = NULL;
3013
3014
429
    if (!_PyArg_CheckPositional("pop", nargs, 1, 2)) {
3015
0
        goto exit;
3016
0
    }
3017
429
    key = args[0];
3018
429
    if (nargs < 2) {
3019
410
        goto skip_optional;
3020
410
    }
3021
19
    default_value = args[1];
3022
429
skip_optional:
3023
429
    return_value = _PyDict_Pop((PyObject*)self, key, default_value);
3024
3025
429
exit:
3026
429
    return return_value;
3027
429
}
3028
3029
/*[clinic input]
3030
dict.popitem
3031
3032
Remove and return a (key, value) pair as a 2-tuple.
3033
3034
Pairs are returned in LIFO (last-in, first-out) order.
3035
Raises KeyError if the dict is empty.
3036
[clinic start generated code]*/
3037
3038
static PyObject *
3039
dict_popitem_impl(PyDictObject *self)
3040
/*[clinic end generated code: output=e65fcb04420d230d input=1c38a49f21f64941]*/
3041
0
{
3042
0
    Py_ssize_t i, j;
3043
0
    PyDictKeyEntry *ep0, *ep;
3044
0
    PyObject *res;
3045
3046
    /* Allocate the result tuple before checking the size.  Believe it
3047
     * or not, this allocation could trigger a garbage collection which
3048
     * could empty the dict, so if we checked the size first and that
3049
     * happened, the result would be an infinite loop (searching for an
3050
     * entry that no longer exists).  Note that the usual popitem()
3051
     * idiom is "while d: k, v = d.popitem()". so needing to throw the
3052
     * tuple away if the dict *is* empty isn't a significant
3053
     * inefficiency -- possible, but unlikely in practice.
3054
     */
3055
0
    res = PyTuple_New(2);
3056
0
    if (res == NULL)
3057
0
        return NULL;
3058
0
    if (self->ma_used == 0) {
3059
0
        Py_DECREF(res);
3060
0
        PyErr_SetString(PyExc_KeyError, "popitem(): dictionary is empty");
3061
0
        return NULL;
3062
0
    }
3063
    /* Convert split table to combined table */
3064
0
    if (self->ma_keys->dk_lookup == lookdict_split) {
3065
0
        if (dictresize(self, DK_SIZE(self->ma_keys))) {
3066
0
            Py_DECREF(res);
3067
0
            return NULL;
3068
0
        }
3069
0
    }
3070
0
    ENSURE_ALLOWS_DELETIONS(self);
3071
3072
    /* Pop last item */
3073
0
    ep0 = DK_ENTRIES(self->ma_keys);
3074
0
    i = self->ma_keys->dk_nentries - 1;
3075
0
    while (i >= 0 && ep0[i].me_value == NULL) {
3076
0
        i--;
3077
0
    }
3078
0
    assert(i >= 0);
3079
3080
0
    ep = &ep0[i];
3081
0
    j = lookdict_index(self->ma_keys, ep->me_hash, i);
3082
0
    assert(j >= 0);
3083
0
    assert(dictkeys_get_index(self->ma_keys, j) == i);
3084
0
    dictkeys_set_index(self->ma_keys, j, DKIX_DUMMY);
3085
3086
0
    PyTuple_SET_ITEM(res, 0, ep->me_key);
3087
0
    PyTuple_SET_ITEM(res, 1, ep->me_value);
3088
0
    ep->me_key = NULL;
3089
0
    ep->me_value = NULL;
3090
    /* We can't dk_usable++ since there is DKIX_DUMMY in indices */
3091
0
    self->ma_keys->dk_nentries = i;
3092
0
    self->ma_used--;
3093
0
    self->ma_version_tag = DICT_NEXT_VERSION();
3094
0
    ASSERT_CONSISTENT(self);
3095
0
    return res;
3096
0
}
3097
3098
static int
3099
dict_traverse(PyObject *op, visitproc visit, void *arg)
3100
12.5k
{
3101
12.5k
    PyDictObject *mp = (PyDictObject *)op;
3102
12.5k
    PyDictKeysObject *keys = mp->ma_keys;
3103
12.5k
    PyDictKeyEntry *entries = DK_ENTRIES(keys);
3104
12.5k
    Py_ssize_t i, n = keys->dk_nentries;
3105
3106
12.5k
    if (keys->dk_lookup == lookdict) {
3107
6.78k
        for (i = 0; i < n; i++) {
3108
5.03k
            if (entries[i].me_value != NULL) {
3109
5.00k
                Py_VISIT(entries[i].me_value);
3110
5.00k
                Py_VISIT(entries[i].me_key);
3111
5.00k
            }
3112
5.03k
        }
3113
1.75k
    }
3114
10.8k
    else {
3115
10.8k
        if (mp->ma_values != NULL) {
3116
9.89k
            for (i = 0; i < n; i++) {
3117
8.62k
                Py_VISIT(mp->ma_values[i]);
3118
8.62k
            }
3119
1.26k
        }
3120
9.54k
        else {
3121
158k
            for (i = 0; i < n; i++) {
3122
149k
                Py_VISIT(entries[i].me_value);
3123
149k
            }
3124
9.54k
        }
3125
10.8k
    }
3126
12.5k
    return 0;
3127
12.5k
}
3128
3129
static int
3130
dict_tp_clear(PyObject *op)
3131
6
{
3132
6
    PyDict_Clear(op);
3133
6
    return 0;
3134
6
}
3135
3136
static PyObject *dictiter_new(PyDictObject *, PyTypeObject *);
3137
3138
Py_ssize_t
3139
_PyDict_SizeOf(PyDictObject *mp)
3140
0
{
3141
0
    Py_ssize_t size, usable, res;
3142
3143
0
    size = DK_SIZE(mp->ma_keys);
3144
0
    usable = USABLE_FRACTION(size);
3145
3146
0
    res = _PyObject_SIZE(Py_TYPE(mp));
3147
0
    if (mp->ma_values)
3148
0
        res += usable * sizeof(PyObject*);
3149
    /* If the dictionary is split, the keys portion is accounted-for
3150
       in the type object. */
3151
0
    if (mp->ma_keys->dk_refcnt == 1)
3152
0
        res += (sizeof(PyDictKeysObject)
3153
0
                + DK_IXSIZE(mp->ma_keys) * size
3154
0
                + sizeof(PyDictKeyEntry) * usable);
3155
0
    return res;
3156
0
}
3157
3158
Py_ssize_t
3159
_PyDict_KeysSize(PyDictKeysObject *keys)
3160
2.63k
{
3161
2.63k
    return (sizeof(PyDictKeysObject)
3162
2.63k
            + DK_IXSIZE(keys) * DK_SIZE(keys)
3163
2.63k
            + USABLE_FRACTION(DK_SIZE(keys)) * sizeof(PyDictKeyEntry));
3164
2.63k
}
3165
3166
static PyObject *
3167
dict_sizeof(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
3168
0
{
3169
0
    return PyLong_FromSsize_t(_PyDict_SizeOf(mp));
3170
0
}
3171
3172
PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]");
3173
3174
PyDoc_STRVAR(sizeof__doc__,
3175
"D.__sizeof__() -> size of D in memory, in bytes");
3176
3177
PyDoc_STRVAR(update__doc__,
3178
"D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.\n\
3179
If E is present and has a .keys() method, then does:  for k in E: D[k] = E[k]\n\
3180
If E is present and lacks a .keys() method, then does:  for k, v in E: D[k] = v\n\
3181
In either case, this is followed by: for k in F:  D[k] = F[k]");
3182
3183
PyDoc_STRVAR(clear__doc__,
3184
"D.clear() -> None.  Remove all items from D.");
3185
3186
PyDoc_STRVAR(copy__doc__,
3187
"D.copy() -> a shallow copy of D");
3188
3189
/* Forward */
3190
static PyObject *dictkeys_new(PyObject *, PyObject *);
3191
static PyObject *dictitems_new(PyObject *, PyObject *);
3192
static PyObject *dictvalues_new(PyObject *, PyObject *);
3193
3194
PyDoc_STRVAR(keys__doc__,
3195
             "D.keys() -> a set-like object providing a view on D's keys");
3196
PyDoc_STRVAR(items__doc__,
3197
             "D.items() -> a set-like object providing a view on D's items");
3198
PyDoc_STRVAR(values__doc__,
3199
             "D.values() -> an object providing a view on D's values");
3200
3201
static PyMethodDef mapp_methods[] = {
3202
    DICT___CONTAINS___METHODDEF
3203
    {"__getitem__", (PyCFunction)(void(*)(void))dict_subscript,        METH_O | METH_COEXIST,
3204
     getitem__doc__},
3205
    {"__sizeof__",      (PyCFunction)(void(*)(void))dict_sizeof,       METH_NOARGS,
3206
     sizeof__doc__},
3207
    DICT_GET_METHODDEF
3208
    DICT_SETDEFAULT_METHODDEF
3209
    DICT_POP_METHODDEF
3210
    DICT_POPITEM_METHODDEF
3211
    {"keys",            dictkeys_new,                   METH_NOARGS,
3212
    keys__doc__},
3213
    {"items",           dictitems_new,                  METH_NOARGS,
3214
    items__doc__},
3215
    {"values",          dictvalues_new,                 METH_NOARGS,
3216
    values__doc__},
3217
    {"update",          (PyCFunction)(void(*)(void))dict_update, METH_VARARGS | METH_KEYWORDS,
3218
     update__doc__},
3219
    DICT_FROMKEYS_METHODDEF
3220
    {"clear",           (PyCFunction)dict_clear,        METH_NOARGS,
3221
     clear__doc__},
3222
    {"copy",            (PyCFunction)dict_copy,         METH_NOARGS,
3223
     copy__doc__},
3224
    DICT___REVERSED___METHODDEF
3225
    {NULL,              NULL}   /* sentinel */
3226
};
3227
3228
/* Return 1 if `key` is in dict `op`, 0 if not, and -1 on error. */
3229
int
3230
PyDict_Contains(PyObject *op, PyObject *key)
3231
2.72k
{
3232
2.72k
    Py_hash_t hash;
3233
2.72k
    Py_ssize_t ix;
3234
2.72k
    PyDictObject *mp = (PyDictObject *)op;
3235
2.72k
    PyObject *value;
3236
3237
2.72k
    if (!PyUnicode_CheckExact(key) ||
3238
2.16k
        (hash = ((PyASCIIObject *) key)->hash) == -1) {
3239
606
        hash = PyObject_Hash(key);
3240
606
        if (hash == -1)
3241
0
            return -1;
3242
606
    }
3243
2.72k
    ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
3244
2.72k
    if (ix == DKIX_ERROR)
3245
0
        return -1;
3246
2.72k
    return (ix != DKIX_EMPTY && value != NULL);
3247
2.72k
}
3248
3249
/* Internal version of PyDict_Contains used when the hash value is already known */
3250
int
3251
_PyDict_Contains(PyObject *op, PyObject *key, Py_hash_t hash)
3252
0
{
3253
0
    PyDictObject *mp = (PyDictObject *)op;
3254
0
    PyObject *value;
3255
0
    Py_ssize_t ix;
3256
3257
0
    ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
3258
0
    if (ix == DKIX_ERROR)
3259
0
        return -1;
3260
0
    return (ix != DKIX_EMPTY && value != NULL);
3261
0
}
3262
3263
/* Hack to implement "key in dict" */
3264
static PySequenceMethods dict_as_sequence = {
3265
    0,                          /* sq_length */
3266
    0,                          /* sq_concat */
3267
    0,                          /* sq_repeat */
3268
    0,                          /* sq_item */
3269
    0,                          /* sq_slice */
3270
    0,                          /* sq_ass_item */
3271
    0,                          /* sq_ass_slice */
3272
    PyDict_Contains,            /* sq_contains */
3273
    0,                          /* sq_inplace_concat */
3274
    0,                          /* sq_inplace_repeat */
3275
};
3276
3277
static PyObject *
3278
dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3279
23
{
3280
23
    PyObject *self;
3281
23
    PyDictObject *d;
3282
3283
23
    assert(type != NULL && type->tp_alloc != NULL);
3284
23
    self = type->tp_alloc(type, 0);
3285
23
    if (self == NULL)
3286
0
        return NULL;
3287
23
    d = (PyDictObject *)self;
3288
3289
    /* The object has been implicitly tracked by tp_alloc */
3290
23
    if (type == &PyDict_Type)
3291
18
        _PyObject_GC_UNTRACK(d);
3292
3293
23
    d->ma_used = 0;
3294
23
    d->ma_version_tag = DICT_NEXT_VERSION();
3295
23
    d->ma_keys = new_keys_object(PyDict_MINSIZE);
3296
23
    if (d->ma_keys == NULL) {
3297
0
        Py_DECREF(self);
3298
0
        return NULL;
3299
0
    }
3300
23
    ASSERT_CONSISTENT(d);
3301
23
    return self;
3302
23
}
3303
3304
static int
3305
dict_init(PyObject *self, PyObject *args, PyObject *kwds)
3306
23
{
3307
23
    return dict_update_common(self, args, kwds, "dict");
3308
23
}
3309
3310
static PyObject *
3311
dict_iter(PyDictObject *dict)
3312
19
{
3313
19
    return dictiter_new(dict, &PyDictIterKey_Type);
3314
19
}
3315
3316
PyDoc_STRVAR(dictionary_doc,
3317
"dict() -> new empty dictionary\n"
3318
"dict(mapping) -> new dictionary initialized from a mapping object's\n"
3319
"    (key, value) pairs\n"
3320
"dict(iterable) -> new dictionary initialized as if via:\n"
3321
"    d = {}\n"
3322
"    for k, v in iterable:\n"
3323
"        d[k] = v\n"
3324
"dict(**kwargs) -> new dictionary initialized with the name=value pairs\n"
3325
"    in the keyword argument list.  For example:  dict(one=1, two=2)");
3326
3327
PyTypeObject PyDict_Type = {
3328
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
3329
    "dict",
3330
    sizeof(PyDictObject),
3331
    0,
3332
    (destructor)dict_dealloc,                   /* tp_dealloc */
3333
    0,                                          /* tp_vectorcall_offset */
3334
    0,                                          /* tp_getattr */
3335
    0,                                          /* tp_setattr */
3336
    0,                                          /* tp_as_async */
3337
    (reprfunc)dict_repr,                        /* tp_repr */
3338
    0,                                          /* tp_as_number */
3339
    &dict_as_sequence,                          /* tp_as_sequence */
3340
    &dict_as_mapping,                           /* tp_as_mapping */
3341
    PyObject_HashNotImplemented,                /* tp_hash */
3342
    0,                                          /* tp_call */
3343
    0,                                          /* tp_str */
3344
    PyObject_GenericGetAttr,                    /* tp_getattro */
3345
    0,                                          /* tp_setattro */
3346
    0,                                          /* tp_as_buffer */
3347
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
3348
        Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DICT_SUBCLASS,         /* tp_flags */
3349
    dictionary_doc,                             /* tp_doc */
3350
    dict_traverse,                              /* tp_traverse */
3351
    dict_tp_clear,                              /* tp_clear */
3352
    dict_richcompare,                           /* tp_richcompare */
3353
    0,                                          /* tp_weaklistoffset */
3354
    (getiterfunc)dict_iter,                     /* tp_iter */
3355
    0,                                          /* tp_iternext */
3356
    mapp_methods,                               /* tp_methods */
3357
    0,                                          /* tp_members */
3358
    0,                                          /* tp_getset */
3359
    0,                                          /* tp_base */
3360
    0,                                          /* tp_dict */
3361
    0,                                          /* tp_descr_get */
3362
    0,                                          /* tp_descr_set */
3363
    0,                                          /* tp_dictoffset */
3364
    dict_init,                                  /* tp_init */
3365
    PyType_GenericAlloc,                        /* tp_alloc */
3366
    dict_new,                                   /* tp_new */
3367
    PyObject_GC_Del,                            /* tp_free */
3368
};
3369
3370
PyObject *
3371
_PyDict_GetItemId(PyObject *dp, struct _Py_Identifier *key)
3372
14.8k
{
3373
14.8k
    PyObject *kv;
3374
14.8k
    kv = _PyUnicode_FromId(key); /* borrowed */
3375
14.8k
    if (kv == NULL) {
3376
0
        PyErr_Clear();
3377
0
        return NULL;
3378
0
    }
3379
14.8k
    return PyDict_GetItem(dp, kv);
3380
14.8k
}
3381
3382
/* For backward compatibility with old dictionary interface */
3383
3384
PyObject *
3385
PyDict_GetItemString(PyObject *v, const char *key)
3386
1.13k
{
3387
1.13k
    PyObject *kv, *rv;
3388
1.13k
    kv = PyUnicode_FromString(key);
3389
1.13k
    if (kv == NULL) {
3390
0
        PyErr_Clear();
3391
0
        return NULL;
3392
0
    }
3393
1.13k
    rv = PyDict_GetItem(v, kv);
3394
1.13k
    Py_DECREF(kv);
3395
1.13k
    return rv;
3396
1.13k
}
3397
3398
int
3399
_PyDict_SetItemId(PyObject *v, struct _Py_Identifier *key, PyObject *item)
3400
8.27k
{
3401
8.27k
    PyObject *kv;
3402
8.27k
    kv = _PyUnicode_FromId(key); /* borrowed */
3403
8.27k
    if (kv == NULL)
3404
0
        return -1;
3405
8.27k
    return PyDict_SetItem(v, kv, item);
3406
8.27k
}
3407
3408
int
3409
PyDict_SetItemString(PyObject *v, const char *key, PyObject *item)
3410
11.0k
{
3411
11.0k
    PyObject *kv;
3412
11.0k
    int err;
3413
11.0k
    kv = PyUnicode_FromString(key);
3414
11.0k
    if (kv == NULL)
3415
0
        return -1;
3416
11.0k
    PyUnicode_InternInPlace(&kv); /* XXX Should we really? */
3417
11.0k
    err = PyDict_SetItem(v, kv, item);
3418
11.0k
    Py_DECREF(kv);
3419
11.0k
    return err;
3420
11.0k
}
3421
3422
int
3423
_PyDict_DelItemId(PyObject *v, _Py_Identifier *key)
3424
1.42k
{
3425
1.42k
    PyObject *kv = _PyUnicode_FromId(key); /* borrowed */
3426
1.42k
    if (kv == NULL)
3427
0
        return -1;
3428
1.42k
    return PyDict_DelItem(v, kv);
3429
1.42k
}
3430
3431
int
3432
PyDict_DelItemString(PyObject *v, const char *key)
3433
26
{
3434
26
    PyObject *kv;
3435
26
    int err;
3436
26
    kv = PyUnicode_FromString(key);
3437
26
    if (kv == NULL)
3438
0
        return -1;
3439
26
    err = PyDict_DelItem(v, kv);
3440
26
    Py_DECREF(kv);
3441
26
    return err;
3442
26
}
3443
3444
/* Dictionary iterator types */
3445
3446
typedef struct {
3447
    PyObject_HEAD
3448
    PyDictObject *di_dict; /* Set to NULL when iterator is exhausted */
3449
    Py_ssize_t di_used;
3450
    Py_ssize_t di_pos;
3451
    PyObject* di_result; /* reusable result tuple for iteritems */
3452
    Py_ssize_t len;
3453
} dictiterobject;
3454
3455
static PyObject *
3456
dictiter_new(PyDictObject *dict, PyTypeObject *itertype)
3457
548
{
3458
548
    dictiterobject *di;
3459
548
    di = PyObject_GC_New(dictiterobject, itertype);
3460
548
    if (di == NULL) {
3461
0
        return NULL;
3462
0
    }
3463
548
    Py_INCREF(dict);
3464
548
    di->di_dict = dict;
3465
548
    di->di_used = dict->ma_used;
3466
548
    di->len = dict->ma_used;
3467
548
    if (itertype == &PyDictRevIterKey_Type ||
3468
548
         itertype == &PyDictRevIterItem_Type ||
3469
548
         itertype == &PyDictRevIterValue_Type) {
3470
0
        if (dict->ma_values) {
3471
0
            di->di_pos = dict->ma_used - 1;
3472
0
        }
3473
0
        else {
3474
0
            di->di_pos = dict->ma_keys->dk_nentries - 1;
3475
0
        }
3476
0
    }
3477
548
    else {
3478
548
        di->di_pos = 0;
3479
548
    }
3480
548
    if (itertype == &PyDictIterItem_Type ||
3481
501
        itertype == &PyDictRevIterItem_Type) {
3482
501
        di->di_result = PyTuple_Pack(2, Py_None, Py_None);
3483
501
        if (di->di_result == NULL) {
3484
0
            Py_DECREF(di);
3485
0
            return NULL;
3486
0
        }
3487
501
    }
3488
47
    else {
3489
47
        di->di_result = NULL;
3490
47
    }
3491
548
    _PyObject_GC_TRACK(di);
3492
548
    return (PyObject *)di;
3493
548
}
3494
3495
static void
3496
dictiter_dealloc(dictiterobject *di)
3497
548
{
3498
    /* bpo-31095: UnTrack is needed before calling any callbacks */
3499
548
    _PyObject_GC_UNTRACK(di);
3500
548
    Py_XDECREF(di->di_dict);
3501
548
    Py_XDECREF(di->di_result);
3502
548
    PyObject_GC_Del(di);
3503
548
}
3504
3505
static int
3506
dictiter_traverse(dictiterobject *di, visitproc visit, void *arg)
3507
28
{
3508
28
    Py_VISIT(di->di_dict);
3509
28
    Py_VISIT(di->di_result);
3510
28
    return 0;
3511
28
}
3512
3513
static PyObject *
3514
dictiter_len(dictiterobject *di, PyObject *Py_UNUSED(ignored))
3515
426
{
3516
426
    Py_ssize_t len = 0;
3517
426
    if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used)
3518
426
        len = di->len;
3519
426
    return PyLong_FromSize_t(len);
3520
426
}
3521
3522
PyDoc_STRVAR(length_hint_doc,
3523
             "Private method returning an estimate of len(list(it)).");
3524
3525
static PyObject *
3526
dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored));
3527
3528
PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
3529
3530
static PyMethodDef dictiter_methods[] = {
3531
    {"__length_hint__", (PyCFunction)(void(*)(void))dictiter_len, METH_NOARGS,
3532
     length_hint_doc},
3533
     {"__reduce__", (PyCFunction)(void(*)(void))dictiter_reduce, METH_NOARGS,
3534
     reduce_doc},
3535
    {NULL,              NULL}           /* sentinel */
3536
};
3537
3538
static PyObject*
3539
dictiter_iternextkey(dictiterobject *di)
3540
186
{
3541
186
    PyObject *key;
3542
186
    Py_ssize_t i;
3543
186
    PyDictKeysObject *k;
3544
186
    PyDictObject *d = di->di_dict;
3545
3546
186
    if (d == NULL)
3547
0
        return NULL;
3548
186
    assert (PyDict_Check(d));
3549
3550
186
    if (di->di_used != d->ma_used) {
3551
0
        PyErr_SetString(PyExc_RuntimeError,
3552
0
                        "dictionary changed size during iteration");
3553
0
        di->di_used = -1; /* Make this state sticky */
3554
0
        return NULL;
3555
0
    }
3556
3557
186
    i = di->di_pos;
3558
186
    k = d->ma_keys;
3559
186
    assert(i >= 0);
3560
186
    if (d->ma_values) {
3561
0
        if (i >= d->ma_used)
3562
0
            goto fail;
3563
0
        key = DK_ENTRIES(k)[i].me_key;
3564
0
        assert(d->ma_values[i] != NULL);
3565
0
    }
3566
186
    else {
3567
186
        Py_ssize_t n = k->dk_nentries;
3568
186
        PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i];
3569
186
        while (i < n && entry_ptr->me_value == NULL) {
3570
0
            entry_ptr++;
3571
0
            i++;
3572
0
        }
3573
186
        if (i >= n)
3574
20
            goto fail;
3575
166
        key = entry_ptr->me_key;
3576
166
    }
3577
    // We found an element (key), but did not expect it
3578
166
    if (di->len == 0) {
3579
0
        PyErr_SetString(PyExc_RuntimeError,
3580
0
                        "dictionary keys changed during iteration");
3581
0
        goto fail;
3582
0
    }
3583
166
    di->di_pos = i+1;
3584
166
    di->len--;
3585
166
    Py_INCREF(key);
3586
166
    return key;
3587
3588
20
fail:
3589
20
    di->di_dict = NULL;
3590
20
    Py_DECREF(d);
3591
20
    return NULL;
3592
166
}
3593
3594
PyTypeObject PyDictIterKey_Type = {
3595
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
3596
    "dict_keyiterator",                         /* tp_name */
3597
    sizeof(dictiterobject),                     /* tp_basicsize */
3598
    0,                                          /* tp_itemsize */
3599
    /* methods */
3600
    (destructor)dictiter_dealloc,               /* tp_dealloc */
3601
    0,                                          /* tp_vectorcall_offset */
3602
    0,                                          /* tp_getattr */
3603
    0,                                          /* tp_setattr */
3604
    0,                                          /* tp_as_async */
3605
    0,                                          /* tp_repr */
3606
    0,                                          /* tp_as_number */
3607
    0,                                          /* tp_as_sequence */
3608
    0,                                          /* tp_as_mapping */
3609
    0,                                          /* tp_hash */
3610
    0,                                          /* tp_call */
3611
    0,                                          /* tp_str */
3612
    PyObject_GenericGetAttr,                    /* tp_getattro */
3613
    0,                                          /* tp_setattro */
3614
    0,                                          /* tp_as_buffer */
3615
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
3616
    0,                                          /* tp_doc */
3617
    (traverseproc)dictiter_traverse,            /* tp_traverse */
3618
    0,                                          /* tp_clear */
3619
    0,                                          /* tp_richcompare */
3620
    0,                                          /* tp_weaklistoffset */
3621
    PyObject_SelfIter,                          /* tp_iter */
3622
    (iternextfunc)dictiter_iternextkey,         /* tp_iternext */
3623
    dictiter_methods,                           /* tp_methods */
3624
    0,
3625
};
3626
3627
static PyObject *
3628
dictiter_iternextvalue(dictiterobject *di)
3629
66
{
3630
66
    PyObject *value;
3631
66
    Py_ssize_t i;
3632
66
    PyDictObject *d = di->di_dict;
3633
3634
66
    if (d == NULL)
3635
0
        return NULL;
3636
66
    assert (PyDict_Check(d));
3637
3638
66
    if (di->di_used != d->ma_used) {
3639
0
        PyErr_SetString(PyExc_RuntimeError,
3640
0
                        "dictionary changed size during iteration");
3641
0
        di->di_used = -1; /* Make this state sticky */
3642
0
        return NULL;
3643
0
    }
3644
3645
66
    i = di->di_pos;
3646
66
    assert(i >= 0);
3647
66
    if (d->ma_values) {
3648
0
        if (i >= d->ma_used)
3649
0
            goto fail;
3650
0
        value = d->ma_values[i];
3651
0
        assert(value != NULL);
3652
0
    }
3653
66
    else {
3654
66
        Py_ssize_t n = d->ma_keys->dk_nentries;
3655
66
        PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i];
3656
66
        while (i < n && entry_ptr->me_value == NULL) {
3657
0
            entry_ptr++;
3658
0
            i++;
3659
0
        }
3660
66
        if (i >= n)
3661
1
            goto fail;
3662
65
        value = entry_ptr->me_value;
3663
65
    }
3664
    // We found an element, but did not expect it
3665
65
    if (di->len == 0) {
3666
0
        PyErr_SetString(PyExc_RuntimeError,
3667
0
                        "dictionary keys changed during iteration");
3668
0
        goto fail;
3669
0
    }
3670
65
    di->di_pos = i+1;
3671
65
    di->len--;
3672
65
    Py_INCREF(value);
3673
65
    return value;
3674
3675
1
fail:
3676
1
    di->di_dict = NULL;
3677
1
    Py_DECREF(d);
3678
1
    return NULL;
3679
65
}
3680
3681
PyTypeObject PyDictIterValue_Type = {
3682
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
3683
    "dict_valueiterator",                       /* tp_name */
3684
    sizeof(dictiterobject),                     /* tp_basicsize */
3685
    0,                                          /* tp_itemsize */
3686
    /* methods */
3687
    (destructor)dictiter_dealloc,               /* tp_dealloc */
3688
    0,                                          /* tp_vectorcall_offset */
3689
    0,                                          /* tp_getattr */
3690
    0,                                          /* tp_setattr */
3691
    0,                                          /* tp_as_async */
3692
    0,                                          /* tp_repr */
3693
    0,                                          /* tp_as_number */
3694
    0,                                          /* tp_as_sequence */
3695
    0,                                          /* tp_as_mapping */
3696
    0,                                          /* tp_hash */
3697
    0,                                          /* tp_call */
3698
    0,                                          /* tp_str */
3699
    PyObject_GenericGetAttr,                    /* tp_getattro */
3700
    0,                                          /* tp_setattro */
3701
    0,                                          /* tp_as_buffer */
3702
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
3703
    0,                                          /* tp_doc */
3704
    (traverseproc)dictiter_traverse,            /* tp_traverse */
3705
    0,                                          /* tp_clear */
3706
    0,                                          /* tp_richcompare */
3707
    0,                                          /* tp_weaklistoffset */
3708
    PyObject_SelfIter,                          /* tp_iter */
3709
    (iternextfunc)dictiter_iternextvalue,       /* tp_iternext */
3710
    dictiter_methods,                           /* tp_methods */
3711
    0,
3712
};
3713
3714
static PyObject *
3715
dictiter_iternextitem(dictiterobject *di)
3716
4.24k
{
3717
4.24k
    PyObject *key, *value, *result;
3718
4.24k
    Py_ssize_t i;
3719
4.24k
    PyDictObject *d = di->di_dict;
3720
3721
4.24k
    if (d == NULL)
3722
0
        return NULL;
3723
4.24k
    assert (PyDict_Check(d));
3724
3725
4.24k
    if (di->di_used != d->ma_used) {
3726
0
        PyErr_SetString(PyExc_RuntimeError,
3727
0
                        "dictionary changed size during iteration");
3728
0
        di->di_used = -1; /* Make this state sticky */
3729
0
        return NULL;
3730
0
    }
3731
3732
4.24k
    i = di->di_pos;
3733
4.24k
    assert(i >= 0);
3734
4.24k
    if (d->ma_values) {
3735
9
        if (i >= d->ma_used)
3736
9
            goto fail;
3737
0
        key = DK_ENTRIES(d->ma_keys)[i].me_key;
3738
0
        value = d->ma_values[i];
3739
0
        assert(value != NULL);
3740
0
    }
3741
4.23k
    else {
3742
4.23k
        Py_ssize_t n = d->ma_keys->dk_nentries;
3743
4.23k
        PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i];
3744
4.53k
        while (i < n && entry_ptr->me_value == NULL) {
3745
303
            entry_ptr++;
3746
303
            i++;
3747
303
        }
3748
4.23k
        if (i >= n)
3749
471
            goto fail;
3750
3.76k
        key = entry_ptr->me_key;
3751
3.76k
        value = entry_ptr->me_value;
3752
3.76k
    }
3753
    // We found an element, but did not expect it
3754
3.76k
    if (di->len == 0) {
3755
0
        PyErr_SetString(PyExc_RuntimeError,
3756
0
                        "dictionary keys changed during iteration");
3757
0
        goto fail;
3758
0
    }
3759
3.76k
    di->di_pos = i+1;
3760
3.76k
    di->len--;
3761
3.76k
    Py_INCREF(key);
3762
3.76k
    Py_INCREF(value);
3763
3.76k
    result = di->di_result;
3764
3.76k
    if (Py_REFCNT(result) == 1) {
3765
1.18k
        PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
3766
1.18k
        PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
3767
1.18k
        PyTuple_SET_ITEM(result, 0, key);  /* steals reference */
3768
1.18k
        PyTuple_SET_ITEM(result, 1, value);  /* steals reference */
3769
1.18k
        Py_INCREF(result);
3770
1.18k
        Py_DECREF(oldkey);
3771
1.18k
        Py_DECREF(oldvalue);
3772
1.18k
    }
3773
2.57k
    else {
3774
2.57k
        result = PyTuple_New(2);
3775
2.57k
        if (result == NULL)
3776
0
            return NULL;
3777
2.57k
        PyTuple_SET_ITEM(result, 0, key);  /* steals reference */
3778
2.57k
        PyTuple_SET_ITEM(result, 1, value);  /* steals reference */
3779
2.57k
    }
3780
3.76k
    return result;
3781
3782
480
fail:
3783
480
    di->di_dict = NULL;
3784
480
    Py_DECREF(d);
3785
480
    return NULL;
3786
3.76k
}
3787
3788
PyTypeObject PyDictIterItem_Type = {
3789
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
3790
    "dict_itemiterator",                        /* tp_name */
3791
    sizeof(dictiterobject),                     /* tp_basicsize */
3792
    0,                                          /* tp_itemsize */
3793
    /* methods */
3794
    (destructor)dictiter_dealloc,               /* tp_dealloc */
3795
    0,                                          /* tp_vectorcall_offset */
3796
    0,                                          /* tp_getattr */
3797
    0,                                          /* tp_setattr */
3798
    0,                                          /* tp_as_async */
3799
    0,                                          /* tp_repr */
3800
    0,                                          /* tp_as_number */
3801
    0,                                          /* tp_as_sequence */
3802
    0,                                          /* tp_as_mapping */
3803
    0,                                          /* tp_hash */
3804
    0,                                          /* tp_call */
3805
    0,                                          /* tp_str */
3806
    PyObject_GenericGetAttr,                    /* tp_getattro */
3807
    0,                                          /* tp_setattro */
3808
    0,                                          /* tp_as_buffer */
3809
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
3810
    0,                                          /* tp_doc */
3811
    (traverseproc)dictiter_traverse,            /* tp_traverse */
3812
    0,                                          /* tp_clear */
3813
    0,                                          /* tp_richcompare */
3814
    0,                                          /* tp_weaklistoffset */
3815
    PyObject_SelfIter,                          /* tp_iter */
3816
    (iternextfunc)dictiter_iternextitem,        /* tp_iternext */
3817
    dictiter_methods,                           /* tp_methods */
3818
    0,
3819
};
3820
3821
3822
/* dictreviter */
3823
3824
static PyObject *
3825
dictreviter_iternext(dictiterobject *di)
3826
0
{
3827
0
    PyDictObject *d = di->di_dict;
3828
3829
0
    if (d == NULL) {
3830
0
        return NULL;
3831
0
    }
3832
0
    assert (PyDict_Check(d));
3833
3834
0
    if (di->di_used != d->ma_used) {
3835
0
        PyErr_SetString(PyExc_RuntimeError,
3836
0
                         "dictionary changed size during iteration");
3837
0
        di->di_used = -1; /* Make this state sticky */
3838
0
        return NULL;
3839
0
    }
3840
3841
0
    Py_ssize_t i = di->di_pos;
3842
0
    PyDictKeysObject *k = d->ma_keys;
3843
0
    PyObject *key, *value, *result;
3844
3845
0
    if (i < 0) {
3846
0
        goto fail;
3847
0
    }
3848
0
    if (d->ma_values) {
3849
0
        key = DK_ENTRIES(k)[i].me_key;
3850
0
        value = d->ma_values[i];
3851
0
        assert (value != NULL);
3852
0
    }
3853
0
    else {
3854
0
        PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i];
3855
0
        while (entry_ptr->me_value == NULL) {
3856
0
            if (--i < 0) {
3857
0
                goto fail;
3858
0
            }
3859
0
            entry_ptr--;
3860
0
        }
3861
0
        key = entry_ptr->me_key;
3862
0
        value = entry_ptr->me_value;
3863
0
    }
3864
0
    di->di_pos = i-1;
3865
0
    di->len--;
3866
3867
0
    if (Py_TYPE(di) == &PyDictRevIterKey_Type) {
3868
0
        Py_INCREF(key);
3869
0
        return key;
3870
0
    }
3871
0
    else if (Py_TYPE(di) == &PyDictRevIterValue_Type) {
3872
0
        Py_INCREF(value);
3873
0
        return value;
3874
0
    }
3875
0
    else if (Py_TYPE(di) == &PyDictRevIterItem_Type) {
3876
0
        Py_INCREF(key);
3877
0
        Py_INCREF(value);
3878
0
        result = di->di_result;
3879
0
        if (Py_REFCNT(result) == 1) {
3880
0
            PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
3881
0
            PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
3882
0
            PyTuple_SET_ITEM(result, 0, key);  /* steals reference */
3883
0
            PyTuple_SET_ITEM(result, 1, value);  /* steals reference */
3884
0
            Py_INCREF(result);
3885
0
            Py_DECREF(oldkey);
3886
0
            Py_DECREF(oldvalue);
3887
0
        }
3888
0
        else {
3889
0
            result = PyTuple_New(2);
3890
0
            if (result == NULL) {
3891
0
                return NULL;
3892
0
            }
3893
0
            PyTuple_SET_ITEM(result, 0, key); /* steals reference */
3894
0
            PyTuple_SET_ITEM(result, 1, value); /* steals reference */
3895
0
        }
3896
0
        return result;
3897
0
    }
3898
0
    else {
3899
0
        Py_UNREACHABLE();
3900
0
    }
3901
3902
0
fail:
3903
0
    di->di_dict = NULL;
3904
0
    Py_DECREF(d);
3905
0
    return NULL;
3906
0
}
3907
3908
PyTypeObject PyDictRevIterKey_Type = {
3909
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
3910
    "dict_reversekeyiterator",
3911
    sizeof(dictiterobject),
3912
    .tp_dealloc = (destructor)dictiter_dealloc,
3913
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
3914
    .tp_traverse = (traverseproc)dictiter_traverse,
3915
    .tp_iter = PyObject_SelfIter,
3916
    .tp_iternext = (iternextfunc)dictreviter_iternext,
3917
    .tp_methods = dictiter_methods
3918
};
3919
3920
3921
/*[clinic input]
3922
dict.__reversed__
3923
3924
Return a reverse iterator over the dict keys.
3925
[clinic start generated code]*/
3926
3927
static PyObject *
3928
dict___reversed___impl(PyDictObject *self)
3929
/*[clinic end generated code: output=e674483336d1ed51 input=23210ef3477d8c4d]*/
3930
0
{
3931
0
    assert (PyDict_Check(self));
3932
0
    return dictiter_new(self, &PyDictRevIterKey_Type);
3933
0
}
3934
3935
static PyObject *
3936
dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored))
3937
0
{
3938
0
    _Py_IDENTIFIER(iter);
3939
    /* copy the iterator state */
3940
0
    dictiterobject tmp = *di;
3941
0
    Py_XINCREF(tmp.di_dict);
3942
3943
0
    PyObject *list = PySequence_List((PyObject*)&tmp);
3944
0
    Py_XDECREF(tmp.di_dict);
3945
0
    if (list == NULL) {
3946
0
        return NULL;
3947
0
    }
3948
0
    return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list);
3949
0
}
3950
3951
PyTypeObject PyDictRevIterItem_Type = {
3952
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
3953
    "dict_reverseitemiterator",
3954
    sizeof(dictiterobject),
3955
    .tp_dealloc = (destructor)dictiter_dealloc,
3956
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
3957
    .tp_traverse = (traverseproc)dictiter_traverse,
3958
    .tp_iter = PyObject_SelfIter,
3959
    .tp_iternext = (iternextfunc)dictreviter_iternext,
3960
    .tp_methods = dictiter_methods
3961
};
3962
3963
PyTypeObject PyDictRevIterValue_Type = {
3964
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
3965
    "dict_reversevalueiterator",
3966
    sizeof(dictiterobject),
3967
    .tp_dealloc = (destructor)dictiter_dealloc,
3968
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
3969
    .tp_traverse = (traverseproc)dictiter_traverse,
3970
    .tp_iter = PyObject_SelfIter,
3971
    .tp_iternext = (iternextfunc)dictreviter_iternext,
3972
    .tp_methods = dictiter_methods
3973
};
3974
3975
/***********************************************/
3976
/* View objects for keys(), items(), values(). */
3977
/***********************************************/
3978
3979
/* The instance lay-out is the same for all three; but the type differs. */
3980
3981
static void
3982
dictview_dealloc(_PyDictViewObject *dv)
3983
568
{
3984
    /* bpo-31095: UnTrack is needed before calling any callbacks */
3985
568
    _PyObject_GC_UNTRACK(dv);
3986
568
    Py_XDECREF(dv->dv_dict);
3987
568
    PyObject_GC_Del(dv);
3988
568
}
3989
3990
static int
3991
dictview_traverse(_PyDictViewObject *dv, visitproc visit, void *arg)
3992
0
{
3993
0
    Py_VISIT(dv->dv_dict);
3994
0
    return 0;
3995
0
}
3996
3997
static Py_ssize_t
3998
dictview_len(_PyDictViewObject *dv)
3999
5
{
4000
5
    Py_ssize_t len = 0;
4001
5
    if (dv->dv_dict != NULL)
4002
5
        len = dv->dv_dict->ma_used;
4003
5
    return len;
4004
5
}
4005
4006
PyObject *
4007
_PyDictView_New(PyObject *dict, PyTypeObject *type)
4008
568
{
4009
568
    _PyDictViewObject *dv;
4010
568
    if (dict == NULL) {
4011
0
        PyErr_BadInternalCall();
4012
0
        return NULL;
4013
0
    }
4014
568
    if (!PyDict_Check(dict)) {
4015
        /* XXX Get rid of this restriction later */
4016
0
        PyErr_Format(PyExc_TypeError,
4017
0
                     "%s() requires a dict argument, not '%s'",
4018
0
                     type->tp_name, dict->ob_type->tp_name);
4019
0
        return NULL;
4020
0
    }
4021
568
    dv = PyObject_GC_New(_PyDictViewObject, type);
4022
568
    if (dv == NULL)
4023
0
        return NULL;
4024
568
    Py_INCREF(dict);
4025
568
    dv->dv_dict = (PyDictObject *)dict;
4026
568
    _PyObject_GC_TRACK(dv);
4027
568
    return (PyObject *)dv;
4028
568
}
4029
4030
/* TODO(guido): The views objects are not complete:
4031
4032
 * support more set operations
4033
 * support arbitrary mappings?
4034
   - either these should be static or exported in dictobject.h
4035
   - if public then they should probably be in builtins
4036
*/
4037
4038
/* Return 1 if self is a subset of other, iterating over self;
4039
   0 if not; -1 if an error occurred. */
4040
static int
4041
all_contained_in(PyObject *self, PyObject *other)
4042
0
{
4043
0
    PyObject *iter = PyObject_GetIter(self);
4044
0
    int ok = 1;
4045
4046
0
    if (iter == NULL)
4047
0
        return -1;
4048
0
    for (;;) {
4049
0
        PyObject *next = PyIter_Next(iter);
4050
0
        if (next == NULL) {
4051
0
            if (PyErr_Occurred())
4052
0
                ok = -1;
4053
0
            break;
4054
0
        }
4055
0
        ok = PySequence_Contains(other, next);
4056
0
        Py_DECREF(next);
4057
0
        if (ok <= 0)
4058
0
            break;
4059
0
    }
4060
0
    Py_DECREF(iter);
4061
0
    return ok;
4062
0
}
4063
4064
static PyObject *
4065
dictview_richcompare(PyObject *self, PyObject *other, int op)
4066
0
{
4067
0
    Py_ssize_t len_self, len_other;
4068
0
    int ok;
4069
0
    PyObject *result;
4070
4071
0
    assert(self != NULL);
4072
0
    assert(PyDictViewSet_Check(self));
4073
0
    assert(other != NULL);
4074
4075
0
    if (!PyAnySet_Check(other) && !PyDictViewSet_Check(other))
4076
0
        Py_RETURN_NOTIMPLEMENTED;
4077
4078
0
    len_self = PyObject_Size(self);
4079
0
    if (len_self < 0)
4080
0
        return NULL;
4081
0
    len_other = PyObject_Size(other);
4082
0
    if (len_other < 0)
4083
0
        return NULL;
4084
4085
0
    ok = 0;
4086
0
    switch(op) {
4087
4088
0
    case Py_NE:
4089
0
    case Py_EQ:
4090
0
        if (len_self == len_other)
4091
0
            ok = all_contained_in(self, other);
4092
0
        if (op == Py_NE && ok >= 0)
4093
0
            ok = !ok;
4094
0
        break;
4095
4096
0
    case Py_LT:
4097
0
        if (len_self < len_other)
4098
0
            ok = all_contained_in(self, other);
4099
0
        break;
4100
4101
0
      case Py_LE:
4102
0
          if (len_self <= len_other)
4103
0
              ok = all_contained_in(self, other);
4104
0
          break;
4105
4106
0
    case Py_GT:
4107
0
        if (len_self > len_other)
4108
0
            ok = all_contained_in(other, self);
4109
0
        break;
4110
4111
0
    case Py_GE:
4112
0
        if (len_self >= len_other)
4113
0
            ok = all_contained_in(other, self);
4114
0
        break;
4115
4116
0
    }
4117
0
    if (ok < 0)
4118
0
        return NULL;
4119
0
    result = ok ? Py_True : Py_False;
4120
0
    Py_INCREF(result);
4121
0
    return result;
4122
0
}
4123
4124
static PyObject *
4125
dictview_repr(_PyDictViewObject *dv)
4126
0
{
4127
0
    PyObject *seq;
4128
0
    PyObject *result = NULL;
4129
0
    Py_ssize_t rc;
4130
4131
0
    rc = Py_ReprEnter((PyObject *)dv);
4132
0
    if (rc != 0) {
4133
0
        return rc > 0 ? PyUnicode_FromString("...") : NULL;
4134
0
    }
4135
0
    seq = PySequence_List((PyObject *)dv);
4136
0
    if (seq == NULL) {
4137
0
        goto Done;
4138
0
    }
4139
0
    result = PyUnicode_FromFormat("%s(%R)", Py_TYPE(dv)->tp_name, seq);
4140
0
    Py_DECREF(seq);
4141
4142
0
Done:
4143
0
    Py_ReprLeave((PyObject *)dv);
4144
0
    return result;
4145
0
}
4146
4147
/*** dict_keys ***/
4148
4149
static PyObject *
4150
dictkeys_iter(_PyDictViewObject *dv)
4151
14
{
4152
14
    if (dv->dv_dict == NULL) {
4153
0
        Py_RETURN_NONE;
4154
0
    }
4155
14
    return dictiter_new(dv->dv_dict, &PyDictIterKey_Type);
4156
14
}
4157
4158
static int
4159
dictkeys_contains(_PyDictViewObject *dv, PyObject *obj)
4160
0
{
4161
0
    if (dv->dv_dict == NULL)
4162
0
        return 0;
4163
0
    return PyDict_Contains((PyObject *)dv->dv_dict, obj);
4164
0
}
4165
4166
static PySequenceMethods dictkeys_as_sequence = {
4167
    (lenfunc)dictview_len,              /* sq_length */
4168
    0,                                  /* sq_concat */
4169
    0,                                  /* sq_repeat */
4170
    0,                                  /* sq_item */
4171
    0,                                  /* sq_slice */
4172
    0,                                  /* sq_ass_item */
4173
    0,                                  /* sq_ass_slice */
4174
    (objobjproc)dictkeys_contains,      /* sq_contains */
4175
};
4176
4177
static PyObject*
4178
dictviews_sub(PyObject* self, PyObject *other)
4179
0
{
4180
0
    PyObject *result = PySet_New(self);
4181
0
    PyObject *tmp;
4182
0
    _Py_IDENTIFIER(difference_update);
4183
4184
0
    if (result == NULL)
4185
0
        return NULL;
4186
4187
0
    tmp = _PyObject_CallMethodIdObjArgs(result, &PyId_difference_update, other, NULL);
4188
0
    if (tmp == NULL) {
4189
0
        Py_DECREF(result);
4190
0
        return NULL;
4191
0
    }
4192
4193
0
    Py_DECREF(tmp);
4194
0
    return result;
4195
0
}
4196
4197
PyObject*
4198
_PyDictView_Intersect(PyObject* self, PyObject *other)
4199
0
{
4200
0
    PyObject *result = PySet_New(self);
4201
0
    PyObject *tmp;
4202
0
    _Py_IDENTIFIER(intersection_update);
4203
4204
0
    if (result == NULL)
4205
0
        return NULL;
4206
4207
0
    tmp = _PyObject_CallMethodIdObjArgs(result, &PyId_intersection_update, other, NULL);
4208
0
    if (tmp == NULL) {
4209
0
        Py_DECREF(result);
4210
0
        return NULL;
4211
0
    }
4212
4213
0
    Py_DECREF(tmp);
4214
0
    return result;
4215
0
}
4216
4217
static PyObject*
4218
dictviews_or(PyObject* self, PyObject *other)
4219
0
{
4220
0
    PyObject *result = PySet_New(self);
4221
0
    PyObject *tmp;
4222
0
    _Py_IDENTIFIER(update);
4223
4224
0
    if (result == NULL)
4225
0
        return NULL;
4226
4227
0
    tmp = _PyObject_CallMethodIdObjArgs(result, &PyId_update, other, NULL);
4228
0
    if (tmp == NULL) {
4229
0
        Py_DECREF(result);
4230
0
        return NULL;
4231
0
    }
4232
4233
0
    Py_DECREF(tmp);
4234
0
    return result;
4235
0
}
4236
4237
static PyObject*
4238
dictviews_xor(PyObject* self, PyObject *other)
4239
0
{
4240
0
    PyObject *result = PySet_New(self);
4241
0
    PyObject *tmp;
4242
0
    _Py_IDENTIFIER(symmetric_difference_update);
4243
4244
0
    if (result == NULL)
4245
0
        return NULL;
4246
4247
0
    tmp = _PyObject_CallMethodIdObjArgs(result, &PyId_symmetric_difference_update, other, NULL);
4248
0
    if (tmp == NULL) {
4249
0
        Py_DECREF(result);
4250
0
        return NULL;
4251
0
    }
4252
4253
0
    Py_DECREF(tmp);
4254
0
    return result;
4255
0
}
4256
4257
static PyNumberMethods dictviews_as_number = {
4258
    0,                                  /*nb_add*/
4259
    (binaryfunc)dictviews_sub,          /*nb_subtract*/
4260
    0,                                  /*nb_multiply*/
4261
    0,                                  /*nb_remainder*/
4262
    0,                                  /*nb_divmod*/
4263
    0,                                  /*nb_power*/
4264
    0,                                  /*nb_negative*/
4265
    0,                                  /*nb_positive*/
4266
    0,                                  /*nb_absolute*/
4267
    0,                                  /*nb_bool*/
4268
    0,                                  /*nb_invert*/
4269
    0,                                  /*nb_lshift*/
4270
    0,                                  /*nb_rshift*/
4271
    (binaryfunc)_PyDictView_Intersect,  /*nb_and*/
4272
    (binaryfunc)dictviews_xor,          /*nb_xor*/
4273
    (binaryfunc)dictviews_or,           /*nb_or*/
4274
};
4275
4276
static PyObject*
4277
dictviews_isdisjoint(PyObject *self, PyObject *other)
4278
0
{
4279
0
    PyObject *it;
4280
0
    PyObject *item = NULL;
4281
4282
0
    if (self == other) {
4283
0
        if (dictview_len((_PyDictViewObject *)self) == 0)
4284
0
            Py_RETURN_TRUE;
4285
0
        else
4286
0
            Py_RETURN_FALSE;
4287
0
    }
4288
4289
    /* Iterate over the shorter object (only if other is a set,
4290
     * because PySequence_Contains may be expensive otherwise): */
4291
0
    if (PyAnySet_Check(other) || PyDictViewSet_Check(other)) {
4292
0
        Py_ssize_t len_self = dictview_len((_PyDictViewObject *)self);
4293
0
        Py_ssize_t len_other = PyObject_Size(other);
4294
0
        if (len_other == -1)
4295
0
            return NULL;
4296
4297
0
        if ((len_other > len_self)) {
4298
0
            PyObject *tmp = other;
4299
0
            other = self;
4300
0
            self = tmp;
4301
0
        }
4302
0
    }
4303
4304
0
    it = PyObject_GetIter(other);
4305
0
    if (it == NULL)
4306
0
        return NULL;
4307
4308
0
    while ((item = PyIter_Next(it)) != NULL) {
4309
0
        int contains = PySequence_Contains(self, item);
4310
0
        Py_DECREF(item);
4311
0
        if (contains == -1) {
4312
0
            Py_DECREF(it);
4313
0
            return NULL;
4314
0
        }
4315
4316
0
        if (contains) {
4317
0
            Py_DECREF(it);
4318
0
            Py_RETURN_FALSE;
4319
0
        }
4320
0
    }
4321
0
    Py_DECREF(it);
4322
0
    if (PyErr_Occurred())
4323
0
        return NULL; /* PyIter_Next raised an exception. */
4324
0
    Py_RETURN_TRUE;
4325
0
}
4326
4327
PyDoc_STRVAR(isdisjoint_doc,
4328
"Return True if the view and the given iterable have a null intersection.");
4329
4330
static PyObject* dictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored));
4331
4332
PyDoc_STRVAR(reversed_keys_doc,
4333
"Return a reverse iterator over the dict keys.");
4334
4335
static PyMethodDef dictkeys_methods[] = {
4336
    {"isdisjoint",      (PyCFunction)dictviews_isdisjoint,  METH_O,
4337
     isdisjoint_doc},
4338
    {"__reversed__",    (PyCFunction)(void(*)(void))dictkeys_reversed,    METH_NOARGS,
4339
     reversed_keys_doc},
4340
    {NULL,              NULL}           /* sentinel */
4341
};
4342
4343
PyTypeObject PyDictKeys_Type = {
4344
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
4345
    "dict_keys",                                /* tp_name */
4346
    sizeof(_PyDictViewObject),                  /* tp_basicsize */
4347
    0,                                          /* tp_itemsize */
4348
    /* methods */
4349
    (destructor)dictview_dealloc,               /* tp_dealloc */
4350
    0,                                          /* tp_vectorcall_offset */
4351
    0,                                          /* tp_getattr */
4352
    0,                                          /* tp_setattr */
4353
    0,                                          /* tp_as_async */
4354
    (reprfunc)dictview_repr,                    /* tp_repr */
4355
    &dictviews_as_number,                       /* tp_as_number */
4356
    &dictkeys_as_sequence,                      /* tp_as_sequence */
4357
    0,                                          /* tp_as_mapping */
4358
    0,                                          /* tp_hash */
4359
    0,                                          /* tp_call */
4360
    0,                                          /* tp_str */
4361
    PyObject_GenericGetAttr,                    /* tp_getattro */
4362
    0,                                          /* tp_setattro */
4363
    0,                                          /* tp_as_buffer */
4364
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
4365
    0,                                          /* tp_doc */
4366
    (traverseproc)dictview_traverse,            /* tp_traverse */
4367
    0,                                          /* tp_clear */
4368
    dictview_richcompare,                       /* tp_richcompare */
4369
    0,                                          /* tp_weaklistoffset */
4370
    (getiterfunc)dictkeys_iter,                 /* tp_iter */
4371
    0,                                          /* tp_iternext */
4372
    dictkeys_methods,                           /* tp_methods */
4373
    0,
4374
};
4375
4376
static PyObject *
4377
dictkeys_new(PyObject *dict, PyObject *Py_UNUSED(ignored))
4378
27
{
4379
27
    return _PyDictView_New(dict, &PyDictKeys_Type);
4380
27
}
4381
4382
static PyObject *
4383
dictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored))
4384
0
{
4385
0
    if (dv->dv_dict == NULL) {
4386
0
        Py_RETURN_NONE;
4387
0
    }
4388
0
    return dictiter_new(dv->dv_dict, &PyDictRevIterKey_Type);
4389
0
}
4390
4391
/*** dict_items ***/
4392
4393
static PyObject *
4394
dictitems_iter(_PyDictViewObject *dv)
4395
501
{
4396
501
    if (dv->dv_dict == NULL) {
4397
0
        Py_RETURN_NONE;
4398
0
    }
4399
501
    return dictiter_new(dv->dv_dict, &PyDictIterItem_Type);
4400
501
}
4401
4402
static int
4403
dictitems_contains(_PyDictViewObject *dv, PyObject *obj)
4404
0
{
4405
0
    int result;
4406
0
    PyObject *key, *value, *found;
4407
0
    if (dv->dv_dict == NULL)
4408
0
        return 0;
4409
0
    if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 2)
4410
0
        return 0;
4411
0
    key = PyTuple_GET_ITEM(obj, 0);
4412
0
    value = PyTuple_GET_ITEM(obj, 1);
4413
0
    found = PyDict_GetItemWithError((PyObject *)dv->dv_dict, key);
4414
0
    if (found == NULL) {
4415
0
        if (PyErr_Occurred())
4416
0
            return -1;
4417
0
        return 0;
4418
0
    }
4419
0
    Py_INCREF(found);
4420
0
    result = PyObject_RichCompareBool(value, found, Py_EQ);
4421
0
    Py_DECREF(found);
4422
0
    return result;
4423
0
}
4424
4425
static PySequenceMethods dictitems_as_sequence = {
4426
    (lenfunc)dictview_len,              /* sq_length */
4427
    0,                                  /* sq_concat */
4428
    0,                                  /* sq_repeat */
4429
    0,                                  /* sq_item */
4430
    0,                                  /* sq_slice */
4431
    0,                                  /* sq_ass_item */
4432
    0,                                  /* sq_ass_slice */
4433
    (objobjproc)dictitems_contains,     /* sq_contains */
4434
};
4435
4436
static PyObject* dictitems_reversed(_PyDictViewObject *dv);
4437
4438
PyDoc_STRVAR(reversed_items_doc,
4439
"Return a reverse iterator over the dict items.");
4440
4441
static PyMethodDef dictitems_methods[] = {
4442
    {"isdisjoint",      (PyCFunction)dictviews_isdisjoint,  METH_O,
4443
     isdisjoint_doc},
4444
    {"__reversed__",    (PyCFunction)(void(*)(void))dictitems_reversed,    METH_NOARGS,
4445
     reversed_items_doc},
4446
    {NULL,              NULL}           /* sentinel */
4447
};
4448
4449
PyTypeObject PyDictItems_Type = {
4450
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
4451
    "dict_items",                               /* tp_name */
4452
    sizeof(_PyDictViewObject),                  /* tp_basicsize */
4453
    0,                                          /* tp_itemsize */
4454
    /* methods */
4455
    (destructor)dictview_dealloc,               /* tp_dealloc */
4456
    0,                                          /* tp_vectorcall_offset */
4457
    0,                                          /* tp_getattr */
4458
    0,                                          /* tp_setattr */
4459
    0,                                          /* tp_as_async */
4460
    (reprfunc)dictview_repr,                    /* tp_repr */
4461
    &dictviews_as_number,                       /* tp_as_number */
4462
    &dictitems_as_sequence,                     /* tp_as_sequence */
4463
    0,                                          /* tp_as_mapping */
4464
    0,                                          /* tp_hash */
4465
    0,                                          /* tp_call */
4466
    0,                                          /* tp_str */
4467
    PyObject_GenericGetAttr,                    /* tp_getattro */
4468
    0,                                          /* tp_setattro */
4469
    0,                                          /* tp_as_buffer */
4470
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
4471
    0,                                          /* tp_doc */
4472
    (traverseproc)dictview_traverse,            /* tp_traverse */
4473
    0,                                          /* tp_clear */
4474
    dictview_richcompare,                       /* tp_richcompare */
4475
    0,                                          /* tp_weaklistoffset */
4476
    (getiterfunc)dictitems_iter,                /* tp_iter */
4477
    0,                                          /* tp_iternext */
4478
    dictitems_methods,                          /* tp_methods */
4479
    0,
4480
};
4481
4482
static PyObject *
4483
dictitems_new(PyObject *dict, PyObject *Py_UNUSED(ignored))
4484
514
{
4485
514
    return _PyDictView_New(dict, &PyDictItems_Type);
4486
514
}
4487
4488
static PyObject *
4489
dictitems_reversed(_PyDictViewObject *dv)
4490
0
{
4491
0
    if (dv->dv_dict == NULL) {
4492
0
        Py_RETURN_NONE;
4493
0
    }
4494
0
    return dictiter_new(dv->dv_dict, &PyDictRevIterItem_Type);
4495
0
}
4496
4497
/*** dict_values ***/
4498
4499
static PyObject *
4500
dictvalues_iter(_PyDictViewObject *dv)
4501
14
{
4502
14
    if (dv->dv_dict == NULL) {
4503
0
        Py_RETURN_NONE;
4504
0
    }
4505
14
    return dictiter_new(dv->dv_dict, &PyDictIterValue_Type);
4506
14
}
4507
4508
static PySequenceMethods dictvalues_as_sequence = {
4509
    (lenfunc)dictview_len,              /* sq_length */
4510
    0,                                  /* sq_concat */
4511
    0,                                  /* sq_repeat */
4512
    0,                                  /* sq_item */
4513
    0,                                  /* sq_slice */
4514
    0,                                  /* sq_ass_item */
4515
    0,                                  /* sq_ass_slice */
4516
    (objobjproc)0,                      /* sq_contains */
4517
};
4518
4519
static PyObject* dictvalues_reversed(_PyDictViewObject *dv);
4520
4521
PyDoc_STRVAR(reversed_values_doc,
4522
"Return a reverse iterator over the dict values.");
4523
4524
static PyMethodDef dictvalues_methods[] = {
4525
    {"__reversed__",    (PyCFunction)(void(*)(void))dictvalues_reversed,    METH_NOARGS,
4526
     reversed_values_doc},
4527
    {NULL,              NULL}           /* sentinel */
4528
};
4529
4530
PyTypeObject PyDictValues_Type = {
4531
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
4532
    "dict_values",                              /* tp_name */
4533
    sizeof(_PyDictViewObject),                  /* tp_basicsize */
4534
    0,                                          /* tp_itemsize */
4535
    /* methods */
4536
    (destructor)dictview_dealloc,               /* tp_dealloc */
4537
    0,                                          /* tp_vectorcall_offset */
4538
    0,                                          /* tp_getattr */
4539
    0,                                          /* tp_setattr */
4540
    0,                                          /* tp_as_async */
4541
    (reprfunc)dictview_repr,                    /* tp_repr */
4542
    0,                                          /* tp_as_number */
4543
    &dictvalues_as_sequence,                    /* tp_as_sequence */
4544
    0,                                          /* tp_as_mapping */
4545
    0,                                          /* tp_hash */
4546
    0,                                          /* tp_call */
4547
    0,                                          /* tp_str */
4548
    PyObject_GenericGetAttr,                    /* tp_getattro */
4549
    0,                                          /* tp_setattro */
4550
    0,                                          /* tp_as_buffer */
4551
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
4552
    0,                                          /* tp_doc */
4553
    (traverseproc)dictview_traverse,            /* tp_traverse */
4554
    0,                                          /* tp_clear */
4555
    0,                                          /* tp_richcompare */
4556
    0,                                          /* tp_weaklistoffset */
4557
    (getiterfunc)dictvalues_iter,               /* tp_iter */
4558
    0,                                          /* tp_iternext */
4559
    dictvalues_methods,                         /* tp_methods */
4560
    0,
4561
};
4562
4563
static PyObject *
4564
dictvalues_new(PyObject *dict, PyObject *Py_UNUSED(ignored))
4565
27
{
4566
27
    return _PyDictView_New(dict, &PyDictValues_Type);
4567
27
}
4568
4569
static PyObject *
4570
dictvalues_reversed(_PyDictViewObject *dv)
4571
0
{
4572
0
    if (dv->dv_dict == NULL) {
4573
0
        Py_RETURN_NONE;
4574
0
    }
4575
0
    return dictiter_new(dv->dv_dict, &PyDictRevIterValue_Type);
4576
0
}
4577
4578
4579
/* Returns NULL if cannot allocate a new PyDictKeysObject,
4580
   but does not set an error */
4581
PyDictKeysObject *
4582
_PyDict_NewKeysForClass(void)
4583
910
{
4584
910
    PyDictKeysObject *keys = new_keys_object(PyDict_MINSIZE);
4585
910
    if (keys == NULL)
4586
0
        PyErr_Clear();
4587
910
    else
4588
910
        keys->dk_lookup = lookdict_split;
4589
910
    return keys;
4590
910
}
4591
4592
26.7k
#define CACHED_KEYS(tp) (((PyHeapTypeObject*)tp)->ht_cached_keys)
4593
4594
PyObject *
4595
PyObject_GenericGetDict(PyObject *obj, void *context)
4596
276
{
4597
276
    PyObject *dict, **dictptr = _PyObject_GetDictPtr(obj);
4598
276
    if (dictptr == NULL) {
4599
0
        PyErr_SetString(PyExc_AttributeError,
4600
0
                        "This object has no __dict__");
4601
0
        return NULL;
4602
0
    }
4603
276
    dict = *dictptr;
4604
276
    if (dict == NULL) {
4605
261
        PyTypeObject *tp = Py_TYPE(obj);
4606
261
        if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && CACHED_KEYS(tp)) {
4607
0
            dictkeys_incref(CACHED_KEYS(tp));
4608
0
            *dictptr = dict = new_dict_with_shared_keys(CACHED_KEYS(tp));
4609
0
        }
4610
261
        else {
4611
261
            *dictptr = dict = PyDict_New();
4612
261
        }
4613
261
    }
4614
276
    Py_XINCREF(dict);
4615
276
    return dict;
4616
276
}
4617
4618
int
4619
_PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
4620
                      PyObject *key, PyObject *value)
4621
21.8k
{
4622
21.8k
    PyObject *dict;
4623
21.8k
    int res;
4624
21.8k
    PyDictKeysObject *cached;
4625
4626
21.8k
    assert(dictptr != NULL);
4627
21.8k
    if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && (cached = CACHED_KEYS(tp))) {
4628
13.5k
        assert(dictptr != NULL);
4629
13.5k
        dict = *dictptr;
4630
13.5k
        if (dict == NULL) {
4631
1.81k
            dictkeys_incref(cached);
4632
1.81k
            dict = new_dict_with_shared_keys(cached);
4633
1.81k
            if (dict == NULL)
4634
0
                return -1;
4635
1.81k
            *dictptr = dict;
4636
1.81k
        }
4637
13.5k
        if (value == NULL) {
4638
0
            res = PyDict_DelItem(dict, key);
4639
            // Since key sharing dict doesn't allow deletion, PyDict_DelItem()
4640
            // always converts dict to combined form.
4641
0
            if ((cached = CACHED_KEYS(tp)) != NULL) {
4642
0
                CACHED_KEYS(tp) = NULL;
4643
0
                dictkeys_decref(cached);
4644
0
            }
4645
0
        }
4646
13.5k
        else {
4647
13.5k
            int was_shared = (cached == ((PyDictObject *)dict)->ma_keys);
4648
13.5k
            res = PyDict_SetItem(dict, key, value);
4649
13.5k
            if (was_shared &&
4650
13.0k
                    (cached = CACHED_KEYS(tp)) != NULL &&
4651
13.0k
                    cached != ((PyDictObject *)dict)->ma_keys) {
4652
                /* PyDict_SetItem() may call dictresize and convert split table
4653
                 * into combined table.  In such case, convert it to split
4654
                 * table again and update type's shared key only when this is
4655
                 * the only dict sharing key with the type.
4656
                 *
4657
                 * This is to allow using shared key in class like this:
4658
                 *
4659
                 *     class C:
4660
                 *         def __init__(self):
4661
                 *             # one dict resize happens
4662
                 *             self.a, self.b, self.c = 1, 2, 3
4663
                 *             self.d, self.e, self.f = 4, 5, 6
4664
                 *     a = C()
4665
                 */
4666
64
                if (cached->dk_refcnt == 1) {
4667
63
                    CACHED_KEYS(tp) = make_keys_shared(dict);
4668
63
                }
4669
1
                else {
4670
1
                    CACHED_KEYS(tp) = NULL;
4671
1
                }
4672
64
                dictkeys_decref(cached);
4673
64
                if (CACHED_KEYS(tp) == NULL && PyErr_Occurred())
4674
0
                    return -1;
4675
64
            }
4676
13.5k
        }
4677
13.5k
    } else {
4678
8.30k
        dict = *dictptr;
4679
8.30k
        if (dict == NULL) {
4680
643
            dict = PyDict_New();
4681
643
            if (dict == NULL)
4682
0
                return -1;
4683
643
            *dictptr = dict;
4684
643
        }
4685
8.30k
        if (value == NULL) {
4686
0
            res = PyDict_DelItem(dict, key);
4687
8.30k
        } else {
4688
8.30k
            res = PyDict_SetItem(dict, key, value);
4689
8.30k
        }
4690
8.30k
    }
4691
21.8k
    return res;
4692
21.8k
}
4693
4694
void
4695
_PyDictKeys_DecRef(PyDictKeysObject *keys)
4696
3
{
4697
3
    dictkeys_decref(keys);
4698
3
}