Coverage Report

Created: 2025-07-11 06:59

/src/Python-3.8.3/Objects/dictobject.c
Line
Count
Source (jump to first uncovered line)
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
112k
#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.08M
#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
359k
#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.1k
#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.26M
#define DK_SIZE(dk) ((dk)->dk_size)
291
#if SIZEOF_VOID_P > 4
292
#define DK_IXSIZE(dk)                          \
293
1.63M
    (DK_SIZE(dk) <= 0xff ?                     \
294
1.63M
        1 : DK_SIZE(dk) <= 0xffff ?            \
295
527k
            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.63M
    ((PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[DK_SIZE(dk) * DK_IXSIZE(dk)]))
305
306
1.47M
#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.7k
{
314
16.7k
    _Py_INC_REFTOTAL;
315
16.7k
    dk->dk_refcnt++;
316
16.7k
}
317
318
static inline void
319
dictkeys_decref(PyDictKeysObject *dk)
320
23.5k
{
321
23.5k
    assert(dk->dk_refcnt > 0);
322
23.5k
    _Py_DEC_REFTOTAL;
323
23.5k
    if (--dk->dk_refcnt == 0) {
324
8.17k
        free_keys_object(dk);
325
8.17k
    }
326
23.5k
}
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.87M
{
332
2.87M
    Py_ssize_t s = DK_SIZE(keys);
333
2.87M
    Py_ssize_t ix;
334
335
2.87M
    if (s <= 0xff) {
336
1.80M
        int8_t *indices = (int8_t*)(keys->dk_indices);
337
1.80M
        ix = indices[i];
338
1.80M
    }
339
1.07M
    else if (s <= 0xffff) {
340
1.07M
        int16_t *indices = (int16_t*)(keys->dk_indices);
341
1.07M
        ix = indices[i];
342
1.07M
    }
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.87M
    assert(ix >= DKIX_DUMMY);
354
2.87M
    return ix;
355
2.87M
}
356
357
/* write to indices. */
358
static inline void
359
dictkeys_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix)
360
580k
{
361
580k
    Py_ssize_t s = DK_SIZE(keys);
362
363
580k
    assert(ix >= DKIX_DUMMY);
364
365
580k
    if (s <= 0xff) {
366
215k
        int8_t *indices = (int8_t*)(keys->dk_indices);
367
215k
        assert(ix <= 0x7f);
368
215k
        indices[i] = (char)ix;
369
215k
    }
370
364k
    else if (s <= 0xffff) {
371
364k
        int16_t *indices = (int16_t*)(keys->dk_indices);
372
364k
        assert(ix <= 0x7fff);
373
364k
        indices[i] = (int16_t)ix;
374
364k
    }
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
580k
}
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.5k
#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
87
#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.18k
#define GROWTH_RATE(d) ((d)->ma_used*3)
426
427
#define ENSURE_ALLOWS_DELETIONS(d) \
428
5.24k
    if ((d)->ma_keys->dk_lookup == lookdict_unicode_nodummy) { \
429
2.75k
        (d)->ma_keys->dk_lookup = lookdict_unicode; \
430
2.75k
    }
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
462k
#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
438k
#  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
22.0k
{
532
22.0k
    PyDictKeysObject *dk;
533
22.0k
    Py_ssize_t es, usable;
534
535
22.0k
    assert(size >= PyDict_MINSIZE);
536
22.0k
    assert(IS_POWER_OF_2(size));
537
538
22.0k
    usable = USABLE_FRACTION(size);
539
22.0k
    if (size <= 0xff) {
540
21.3k
        es = 1;
541
21.3k
    }
542
745
    else if (size <= 0xffff) {
543
745
        es = 2;
544
745
    }
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
22.0k
    if (size == PyDict_MINSIZE && numfreekeys > 0) {
555
9.96k
        dk = keys_free_list[--numfreekeys];
556
9.96k
    }
557
12.1k
    else {
558
12.1k
        dk = PyObject_MALLOC(sizeof(PyDictKeysObject)
559
12.1k
                             + es * size
560
12.1k
                             + sizeof(PyDictKeyEntry) * usable);
561
12.1k
        if (dk == NULL) {
562
0
            PyErr_NoMemory();
563
0
            return NULL;
564
0
        }
565
12.1k
    }
566
22.0k
    _Py_INC_REFTOTAL;
567
22.0k
    dk->dk_refcnt = 1;
568
22.0k
    dk->dk_size = size;
569
22.0k
    dk->dk_usable = usable;
570
22.0k
    dk->dk_lookup = lookdict_unicode_nodummy;
571
22.0k
    dk->dk_nentries = 0;
572
22.0k
    memset(&dk->dk_indices[0], 0xff, es * size);
573
22.0k
    memset(DK_ENTRIES(dk), 0, sizeof(PyDictKeyEntry) * usable);
574
22.0k
    return dk;
575
22.0k
}
576
577
static void
578
free_keys_object(PyDictKeysObject *keys)
579
8.17k
{
580
8.17k
    PyDictKeyEntry *entries = DK_ENTRIES(keys);
581
8.17k
    Py_ssize_t i, n;
582
147k
    for (i = 0, n = keys->dk_nentries; i < n; i++) {
583
139k
        Py_XDECREF(entries[i].me_key);
584
139k
        Py_XDECREF(entries[i].me_value);
585
139k
    }
586
8.17k
    if (keys->dk_size == PyDict_MINSIZE && numfreekeys < PyDict_MAXFREELIST) {
587
5.93k
        keys_free_list[numfreekeys++] = keys;
588
5.93k
        return;
589
5.93k
    }
590
2.24k
    PyObject_FREE(keys);
591
2.24k
}
592
593
1.98k
#define new_values(size) PyMem_NEW(PyObject *, size)
594
988
#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.5k
{
600
19.5k
    PyDictObject *mp;
601
19.5k
    assert(keys != NULL);
602
19.5k
    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
8.14k
    else {
609
8.14k
        mp = PyObject_GC_New(PyDictObject, &PyDict_Type);
610
8.14k
        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
8.14k
    }
618
19.5k
    mp->ma_keys = keys;
619
19.5k
    mp->ma_values = values;
620
19.5k
    mp->ma_used = 0;
621
19.5k
    mp->ma_version_tag = DICT_NEXT_VERSION();
622
19.5k
    ASSERT_CONSISTENT(mp);
623
19.5k
    return (PyObject *)mp;
624
19.5k
}
625
626
/* Consumes a reference to the keys object */
627
static PyObject *
628
new_dict_with_shared_keys(PyDictKeysObject *keys)
629
1.92k
{
630
1.92k
    PyObject **values;
631
1.92k
    Py_ssize_t i, size;
632
633
1.92k
    size = USABLE_FRACTION(DK_SIZE(keys));
634
1.92k
    values = new_values(size);
635
1.92k
    if (values == NULL) {
636
0
        dictkeys_decref(keys);
637
0
        return PyErr_NoMemory();
638
0
    }
639
16.2k
    for (i = 0; i < size; i++) {
640
14.3k
        values[i] = NULL;
641
14.3k
    }
642
1.92k
    return new_dict(keys, values);
643
1.92k
}
644
645
646
static PyObject *
647
clone_combined_dict(PyDictObject *orig)
648
2.82k
{
649
2.82k
    assert(PyDict_CheckExact(orig));
650
2.82k
    assert(orig->ma_values == NULL);
651
2.82k
    assert(orig->ma_keys->dk_refcnt == 1);
652
653
2.82k
    Py_ssize_t keys_size = _PyDict_KeysSize(orig->ma_keys);
654
2.82k
    PyDictKeysObject *keys = PyObject_Malloc(keys_size);
655
2.82k
    if (keys == NULL) {
656
0
        PyErr_NoMemory();
657
0
        return NULL;
658
0
    }
659
660
2.82k
    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.82k
    PyDictKeyEntry *ep0 = DK_ENTRIES(keys);
666
2.82k
    Py_ssize_t n = keys->dk_nentries;
667
35.0k
    for (Py_ssize_t i = 0; i < n; i++) {
668
32.1k
        PyDictKeyEntry *entry = &ep0[i];
669
32.1k
        PyObject *value = entry->me_value;
670
32.1k
        if (value != NULL) {
671
31.1k
            Py_INCREF(value);
672
31.1k
            Py_INCREF(entry->me_key);
673
31.1k
        }
674
32.1k
    }
675
676
2.82k
    PyDictObject *new = (PyDictObject *)new_dict(keys, NULL);
677
2.82k
    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.82k
    new->ma_used = orig->ma_used;
683
2.82k
    ASSERT_CONSISTENT(new);
684
2.82k
    if (_PyObject_GC_IS_TRACKED(orig)) {
685
        /* Maintain tracking. */
686
2.48k
        _PyObject_GC_TRACK(new);
687
2.48k
    }
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.82k
    _Py_INC_REFTOTAL;
694
695
2.82k
    return (PyObject *)new;
696
2.82k
}
697
698
PyObject *
699
PyDict_New(void)
700
14.7k
{
701
14.7k
    dictkeys_incref(Py_EMPTY_KEYS);
702
14.7k
    return new_dict(Py_EMPTY_KEYS, empty_values);
703
14.7k
}
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.24k
{
709
5.24k
    size_t mask = DK_MASK(k);
710
5.24k
    size_t perturb = (size_t)hash;
711
5.24k
    size_t i = (size_t)hash & mask;
712
713
6.67k
    for (;;) {
714
6.67k
        Py_ssize_t ix = dictkeys_get_index(k, i);
715
6.67k
        if (ix == index) {
716
5.24k
            return i;
717
5.24k
        }
718
1.43k
        if (ix == DKIX_EMPTY) {
719
0
            return DKIX_EMPTY;
720
0
        }
721
1.43k
        perturb >>= PERTURB_SHIFT;
722
1.43k
        i = mask & (i*5 + perturb + 1);
723
1.43k
    }
724
5.24k
    Py_UNREACHABLE();
725
5.24k
}
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
211k
{
755
211k
    size_t i, mask, perturb;
756
211k
    PyDictKeysObject *dk;
757
211k
    PyDictKeyEntry *ep0;
758
759
211k
top:
760
211k
    dk = mp->ma_keys;
761
211k
    ep0 = DK_ENTRIES(dk);
762
211k
    mask = DK_MASK(dk);
763
211k
    perturb = hash;
764
211k
    i = (size_t)hash & mask;
765
766
348k
    for (;;) {
767
348k
        Py_ssize_t ix = dictkeys_get_index(dk, i);
768
348k
        if (ix == DKIX_EMPTY) {
769
112k
            *value_addr = NULL;
770
112k
            return ix;
771
112k
        }
772
236k
        if (ix >= 0) {
773
235k
            PyDictKeyEntry *ep = &ep0[ix];
774
235k
            assert(ep->me_key != NULL);
775
235k
            if (ep->me_key == key) {
776
15.2k
                *value_addr = ep->me_value;
777
15.2k
                return ix;
778
15.2k
            }
779
220k
            if (ep->me_hash == hash) {
780
83.7k
                PyObject *startkey = ep->me_key;
781
83.7k
                Py_INCREF(startkey);
782
83.7k
                int cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
783
83.7k
                Py_DECREF(startkey);
784
83.7k
                if (cmp < 0) {
785
0
                    *value_addr = NULL;
786
0
                    return DKIX_ERROR;
787
0
                }
788
83.7k
                if (dk == mp->ma_keys && ep->me_key == startkey) {
789
83.7k
                    if (cmp > 0) {
790
83.7k
                        *value_addr = ep->me_value;
791
83.7k
                        return ix;
792
83.7k
                    }
793
83.7k
                }
794
0
                else {
795
                    /* The dict was mutated, restart */
796
0
                    goto top;
797
0
                }
798
83.7k
            }
799
220k
        }
800
137k
        perturb >>= PERTURB_SHIFT;
801
137k
        i = (i*5 + perturb + 1) & mask;
802
137k
    }
803
211k
    Py_UNREACHABLE();
804
211k
}
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
241k
{
811
241k
    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
241k
    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
241k
    PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
822
241k
    size_t mask = DK_MASK(mp->ma_keys);
823
241k
    size_t perturb = (size_t)hash;
824
241k
    size_t i = (size_t)hash & mask;
825
826
477k
    for (;;) {
827
477k
        Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
828
477k
        if (ix == DKIX_EMPTY) {
829
195k
            *value_addr = NULL;
830
195k
            return DKIX_EMPTY;
831
195k
        }
832
281k
        if (ix >= 0) {
833
254k
            PyDictKeyEntry *ep = &ep0[ix];
834
254k
            assert(ep->me_key != NULL);
835
254k
            assert(PyUnicode_CheckExact(ep->me_key));
836
254k
            if (ep->me_key == key ||
837
254k
                    (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
838
45.9k
                *value_addr = ep->me_value;
839
45.9k
                return ix;
840
45.9k
            }
841
254k
        }
842
236k
        perturb >>= PERTURB_SHIFT;
843
236k
        i = mask & (i*5 + perturb + 1);
844
236k
    }
845
241k
    Py_UNREACHABLE();
846
241k
}
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
723k
{
854
723k
    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
723k
    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
723k
    PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
865
723k
    size_t mask = DK_MASK(mp->ma_keys);
866
723k
    size_t perturb = (size_t)hash;
867
723k
    size_t i = (size_t)hash & mask;
868
869
1.13M
    for (;;) {
870
1.13M
        Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
871
1.13M
        assert (ix != DKIX_DUMMY);
872
1.13M
        if (ix == DKIX_EMPTY) {
873
469k
            *value_addr = NULL;
874
469k
            return DKIX_EMPTY;
875
469k
        }
876
664k
        PyDictKeyEntry *ep = &ep0[ix];
877
664k
        assert(ep->me_key != NULL);
878
664k
        assert(PyUnicode_CheckExact(ep->me_key));
879
664k
        if (ep->me_key == key ||
880
664k
            (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
881
254k
            *value_addr = ep->me_value;
882
254k
            return ix;
883
254k
        }
884
409k
        perturb >>= PERTURB_SHIFT;
885
409k
        i = mask & (i*5 + perturb + 1);
886
409k
    }
887
723k
    Py_UNREACHABLE();
888
723k
}
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
49.0k
{
899
    /* mp must split table */
900
49.0k
    assert(mp->ma_values != NULL);
901
49.0k
    if (!PyUnicode_CheckExact(key)) {
902
36
        Py_ssize_t ix = lookdict(mp, key, hash, value_addr);
903
36
        if (ix >= 0) {
904
0
            *value_addr = mp->ma_values[ix];
905
0
        }
906
36
        return ix;
907
36
    }
908
909
49.0k
    PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
910
49.0k
    size_t mask = DK_MASK(mp->ma_keys);
911
49.0k
    size_t perturb = (size_t)hash;
912
49.0k
    size_t i = (size_t)hash & mask;
913
914
63.3k
    for (;;) {
915
63.3k
        Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
916
63.3k
        assert (ix != DKIX_DUMMY);
917
63.3k
        if (ix == DKIX_EMPTY) {
918
10.3k
            *value_addr = NULL;
919
10.3k
            return DKIX_EMPTY;
920
10.3k
        }
921
53.0k
        PyDictKeyEntry *ep = &ep0[ix];
922
53.0k
        assert(ep->me_key != NULL);
923
53.0k
        assert(PyUnicode_CheckExact(ep->me_key));
924
53.0k
        if (ep->me_key == key ||
925
53.0k
            (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
926
38.7k
            *value_addr = mp->ma_values[ix];
927
38.7k
            return ix;
928
38.7k
        }
929
14.2k
        perturb >>= PERTURB_SHIFT;
930
14.2k
        i = mask & (i*5 + perturb + 1);
931
14.2k
    }
932
49.0k
    Py_UNREACHABLE();
933
49.0k
}
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
372k
    do { \
952
372k
        if (!_PyObject_GC_IS_TRACKED(mp)) { \
953
285k
            if (_PyObject_GC_MAY_BE_TRACKED(key) || \
954
285k
                _PyObject_GC_MAY_BE_TRACKED(value)) { \
955
9.35k
                _PyObject_GC_TRACK(mp); \
956
9.35k
            } \
957
285k
        } \
958
372k
    } 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
240k
{
1003
240k
    assert(keys != NULL);
1004
1005
240k
    const size_t mask = DK_MASK(keys);
1006
240k
    size_t i = hash & mask;
1007
240k
    Py_ssize_t ix = dictkeys_get_index(keys, i);
1008
457k
    for (size_t perturb = hash; ix >= 0;) {
1009
216k
        perturb >>= PERTURB_SHIFT;
1010
216k
        i = (i*5 + perturb + 1) & mask;
1011
216k
        ix = dictkeys_get_index(keys, i);
1012
216k
    }
1013
240k
    return i;
1014
240k
}
1015
1016
static int
1017
insertion_resize(PyDictObject *mp)
1018
9.18k
{
1019
9.18k
    return dictresize(mp, GROWTH_RATE(mp));
1020
9.18k
}
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
317k
{
1030
317k
    PyObject *old_value;
1031
317k
    PyDictKeyEntry *ep;
1032
1033
317k
    Py_INCREF(key);
1034
317k
    Py_INCREF(value);
1035
317k
    if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) {
1036
0
        if (insertion_resize(mp) < 0)
1037
0
            goto Fail;
1038
0
    }
1039
1040
317k
    Py_ssize_t ix = mp->ma_keys->dk_lookup(mp, key, hash, &old_value);
1041
317k
    if (ix == DKIX_ERROR)
1042
0
        goto Fail;
1043
1044
317k
    assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict);
1045
317k
    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
317k
    if (_PyDict_HasSplitTable(mp) &&
1051
317k
        ((ix >= 0 && old_value == NULL && mp->ma_used != ix) ||
1052
13.7k
         (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
317k
    if (ix == DKIX_EMPTY) {
1059
        /* Insert into new slot. */
1060
197k
        assert(old_value == NULL);
1061
197k
        if (mp->ma_keys->dk_usable <= 0) {
1062
            /* Need to resize. */
1063
9.02k
            if (insertion_resize(mp) < 0)
1064
0
                goto Fail;
1065
9.02k
        }
1066
197k
        Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash);
1067
197k
        ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries];
1068
197k
        dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
1069
197k
        ep->me_key = key;
1070
197k
        ep->me_hash = hash;
1071
197k
        if (mp->ma_values) {
1072
701
            assert (mp->ma_values[mp->ma_keys->dk_nentries] == NULL);
1073
701
            mp->ma_values[mp->ma_keys->dk_nentries] = value;
1074
701
        }
1075
196k
        else {
1076
196k
            ep->me_value = value;
1077
196k
        }
1078
197k
        mp->ma_used++;
1079
197k
        mp->ma_version_tag = DICT_NEXT_VERSION();
1080
197k
        mp->ma_keys->dk_usable--;
1081
197k
        mp->ma_keys->dk_nentries++;
1082
197k
        assert(mp->ma_keys->dk_usable >= 0);
1083
197k
        ASSERT_CONSISTENT(mp);
1084
197k
        return 0;
1085
197k
    }
1086
1087
120k
    if (old_value != value) {
1088
82.5k
        if (_PyDict_HasSplitTable(mp)) {
1089
12.5k
            mp->ma_values[ix] = value;
1090
12.5k
            if (old_value == NULL) {
1091
                /* pending state */
1092
8.51k
                assert(ix == mp->ma_used);
1093
8.51k
                mp->ma_used++;
1094
8.51k
            }
1095
12.5k
        }
1096
69.9k
        else {
1097
69.9k
            assert(old_value != NULL);
1098
69.9k
            DK_ENTRIES(mp->ma_keys)[ix].me_value = value;
1099
69.9k
        }
1100
82.5k
        mp->ma_version_tag = DICT_NEXT_VERSION();
1101
82.5k
    }
1102
120k
    Py_XDECREF(old_value); /* which **CAN** re-enter (see issue #22653) */
1103
120k
    ASSERT_CONSISTENT(mp);
1104
120k
    Py_DECREF(key);
1105
120k
    return 0;
1106
1107
0
Fail:
1108
0
    Py_DECREF(value);
1109
0
    Py_DECREF(key);
1110
0
    return -1;
1111
317k
}
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.8k
{
1118
11.8k
    assert(mp->ma_keys == Py_EMPTY_KEYS);
1119
1120
11.8k
    PyDictKeysObject *newkeys = new_keys_object(PyDict_MINSIZE);
1121
11.8k
    if (newkeys == NULL) {
1122
0
        return -1;
1123
0
    }
1124
11.8k
    if (!PyUnicode_CheckExact(key)) {
1125
2.06k
        newkeys->dk_lookup = lookdict;
1126
2.06k
    }
1127
11.8k
    dictkeys_decref(Py_EMPTY_KEYS);
1128
11.8k
    mp->ma_keys = newkeys;
1129
11.8k
    mp->ma_values = NULL;
1130
1131
11.8k
    Py_INCREF(key);
1132
11.8k
    Py_INCREF(value);
1133
11.8k
    MAINTAIN_TRACKING(mp, key, value);
1134
1135
11.8k
    size_t hashpos = (size_t)hash & (PyDict_MINSIZE-1);
1136
11.8k
    PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys);
1137
11.8k
    dictkeys_set_index(mp->ma_keys, hashpos, 0);
1138
11.8k
    ep->me_key = key;
1139
11.8k
    ep->me_hash = hash;
1140
11.8k
    ep->me_value = value;
1141
11.8k
    mp->ma_used++;
1142
11.8k
    mp->ma_version_tag = DICT_NEXT_VERSION();
1143
11.8k
    mp->ma_keys->dk_usable--;
1144
11.8k
    mp->ma_keys->dk_nentries++;
1145
11.8k
    return 0;
1146
11.8k
}
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.22k
{
1154
9.22k
    size_t mask = (size_t)DK_SIZE(keys) - 1;
1155
331k
    for (Py_ssize_t ix = 0; ix != n; ix++, ep++) {
1156
322k
        Py_hash_t hash = ep->me_hash;
1157
322k
        size_t i = hash & mask;
1158
392k
        for (size_t perturb = hash; dictkeys_get_index(keys, i) != DKIX_EMPTY;) {
1159
69.4k
            perturb >>= PERTURB_SHIFT;
1160
69.4k
            i = mask & (i*5 + perturb + 1);
1161
69.4k
        }
1162
322k
        dictkeys_set_index(keys, i, ix);
1163
322k
    }
1164
9.22k
}
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.22k
{
1179
9.22k
    Py_ssize_t newsize, numentries;
1180
9.22k
    PyDictKeysObject *oldkeys;
1181
9.22k
    PyObject **oldvalues;
1182
9.22k
    PyDictKeyEntry *oldentries, *newentries;
1183
1184
    /* Find the smallest table size > minused. */
1185
9.22k
    for (newsize = PyDict_MINSIZE;
1186
28.8k
         newsize < minsize && newsize > 0;
1187
19.5k
         newsize <<= 1)
1188
19.5k
        ;
1189
9.22k
    if (newsize <= 0) {
1190
0
        PyErr_NoMemory();
1191
0
        return -1;
1192
0
    }
1193
1194
9.22k
    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.22k
    mp->ma_keys = new_keys_object(newsize);
1203
9.22k
    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.22k
    assert(mp->ma_keys->dk_usable >= mp->ma_used);
1209
9.22k
    if (oldkeys->dk_lookup == lookdict)
1210
2.40k
        mp->ma_keys->dk_lookup = lookdict;
1211
1212
9.22k
    numentries = mp->ma_used;
1213
9.22k
    oldentries = DK_ENTRIES(oldkeys);
1214
9.22k
    newentries = DK_ENTRIES(mp->ma_keys);
1215
9.22k
    oldvalues = mp->ma_values;
1216
9.22k
    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
451
        for (Py_ssize_t i = 0; i < numentries; i++) {
1222
350
            assert(oldvalues[i] != NULL);
1223
350
            PyDictKeyEntry *ep = &oldentries[i];
1224
350
            PyObject *key = ep->me_key;
1225
350
            Py_INCREF(key);
1226
350
            newentries[i].me_key = key;
1227
350
            newentries[i].me_hash = ep->me_hash;
1228
350
            newentries[i].me_value = oldvalues[i];
1229
350
        }
1230
1231
101
        dictkeys_decref(oldkeys);
1232
101
        mp->ma_values = NULL;
1233
101
        if (oldvalues != empty_values) {
1234
68
            free_values(oldvalues);
1235
68
        }
1236
101
    }
1237
9.11k
    else {  // combined table.
1238
9.11k
        if (oldkeys->dk_nentries == numentries) {
1239
8.40k
            memcpy(newentries, oldentries, numentries * sizeof(PyDictKeyEntry));
1240
8.40k
        }
1241
710
        else {
1242
710
            PyDictKeyEntry *ep = oldentries;
1243
66.8k
            for (Py_ssize_t i = 0; i < numentries; i++) {
1244
67.4k
                while (ep->me_value == NULL)
1245
1.30k
                    ep++;
1246
66.1k
                newentries[i] = *ep++;
1247
66.1k
            }
1248
710
        }
1249
1250
9.11k
        assert(oldkeys->dk_lookup != lookdict_split);
1251
9.11k
        assert(oldkeys->dk_refcnt == 1);
1252
9.11k
        if (oldkeys->dk_size == PyDict_MINSIZE &&
1253
9.11k
            numfreekeys < PyDict_MAXFREELIST) {
1254
4.08k
            _Py_DEC_REFTOTAL;
1255
4.08k
            keys_free_list[numfreekeys++] = oldkeys;
1256
4.08k
        }
1257
5.03k
        else {
1258
5.03k
            _Py_DEC_REFTOTAL;
1259
5.03k
            PyObject_FREE(oldkeys);
1260
5.03k
        }
1261
9.11k
    }
1262
1263
9.22k
    build_indices(mp->ma_keys, newentries, numentries);
1264
9.22k
    mp->ma_keys->dk_usable -= numentries;
1265
9.22k
    mp->ma_keys->dk_nentries = numentries;
1266
9.22k
    return 0;
1267
9.22k
}
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
67
{
1274
67
    Py_ssize_t i;
1275
67
    Py_ssize_t size;
1276
67
    PyDictObject *mp = (PyDictObject *)op;
1277
1278
67
    if (!PyDict_CheckExact(op))
1279
0
        return NULL;
1280
67
    if (!_PyDict_HasSplitTable(mp)) {
1281
67
        PyDictKeyEntry *ep0;
1282
67
        PyObject **values;
1283
67
        assert(mp->ma_keys->dk_refcnt == 1);
1284
67
        if (mp->ma_keys->dk_lookup == lookdict) {
1285
0
            return NULL;
1286
0
        }
1287
67
        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
67
        assert(mp->ma_keys->dk_lookup == lookdict_unicode_nodummy);
1293
        /* Copy values into a new array */
1294
67
        ep0 = DK_ENTRIES(mp->ma_keys);
1295
67
        size = USABLE_FRACTION(DK_SIZE(mp->ma_keys));
1296
67
        values = new_values(size);
1297
67
        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
770
        for (i = 0; i < size; i++) {
1303
703
            values[i] = ep0[i].me_value;
1304
703
            ep0[i].me_value = NULL;
1305
703
        }
1306
67
        mp->ma_keys->dk_lookup = lookdict_split;
1307
67
        mp->ma_values = values;
1308
67
    }
1309
67
    dictkeys_incref(mp->ma_keys);
1310
67
    return mp->ma_keys;
1311
67
}
1312
1313
PyObject *
1314
_PyDict_NewPresized(Py_ssize_t minused)
1315
3.48k
{
1316
3.48k
    const Py_ssize_t max_presize = 128 * 1024;
1317
3.48k
    Py_ssize_t newsize;
1318
3.48k
    PyDictKeysObject *new_keys;
1319
1320
3.48k
    if (minused <= USABLE_FRACTION(PyDict_MINSIZE)) {
1321
3.42k
        return PyDict_New();
1322
3.42k
    }
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
53
    if (minused > USABLE_FRACTION(max_presize)) {
1328
0
        newsize = max_presize;
1329
0
    }
1330
53
    else {
1331
53
        Py_ssize_t minsize = ESTIMATE_SIZE(minused);
1332
53
        newsize = PyDict_MINSIZE*2;
1333
128
        while (newsize < minsize) {
1334
75
            newsize <<= 1;
1335
75
        }
1336
53
    }
1337
53
    assert(IS_POWER_OF_2(newsize));
1338
1339
53
    new_keys = new_keys_object(newsize);
1340
53
    if (new_keys == NULL)
1341
0
        return NULL;
1342
53
    return new_dict(new_keys, NULL);
1343
53
}
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
17.7k
{
1358
17.7k
    Py_hash_t hash;
1359
17.7k
    Py_ssize_t ix;
1360
17.7k
    PyDictObject *mp = (PyDictObject *)op;
1361
17.7k
    PyThreadState *tstate;
1362
17.7k
    PyObject *value;
1363
1364
17.7k
    if (!PyDict_Check(op))
1365
0
        return NULL;
1366
17.7k
    if (!PyUnicode_CheckExact(key) ||
1367
17.7k
        (hash = ((PyASCIIObject *) key)->hash) == -1)
1368
1.21k
    {
1369
1.21k
        hash = PyObject_Hash(key);
1370
1.21k
        if (hash == -1) {
1371
0
            PyErr_Clear();
1372
0
            return NULL;
1373
0
        }
1374
1.21k
    }
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
17.7k
    tstate = _PyThreadState_GET();
1382
17.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
17.7k
    else {
1393
17.7k
        ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
1394
17.7k
        if (ix < 0) {
1395
9.01k
            PyErr_Clear();
1396
9.01k
            return NULL;
1397
9.01k
        }
1398
17.7k
    }
1399
8.75k
    return value;
1400
17.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
473k
{
1409
473k
    Py_ssize_t ix;
1410
473k
    PyDictObject *mp = (PyDictObject *)op;
1411
473k
    PyObject *value;
1412
1413
473k
    if (!PyDict_Check(op)) {
1414
0
        PyErr_BadInternalCall();
1415
0
        return NULL;
1416
0
    }
1417
1418
473k
    ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
1419
473k
    if (ix < 0) {
1420
442k
        return NULL;
1421
442k
    }
1422
31.3k
    return value;
1423
473k
}
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
212k
{
1432
212k
    Py_ssize_t ix;
1433
212k
    Py_hash_t hash;
1434
212k
    PyDictObject*mp = (PyDictObject *)op;
1435
212k
    PyObject *value;
1436
1437
212k
    if (!PyDict_Check(op)) {
1438
0
        PyErr_BadInternalCall();
1439
0
        return NULL;
1440
0
    }
1441
212k
    if (!PyUnicode_CheckExact(key) ||
1442
212k
        (hash = ((PyASCIIObject *) key)->hash) == -1)
1443
2.36k
    {
1444
2.36k
        hash = PyObject_Hash(key);
1445
2.36k
        if (hash == -1) {
1446
0
            return NULL;
1447
0
        }
1448
2.36k
    }
1449
1450
212k
    ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
1451
212k
    if (ix < 0)
1452
73.3k
        return NULL;
1453
139k
    return value;
1454
212k
}
1455
1456
PyObject *
1457
_PyDict_GetItemIdWithError(PyObject *dp, struct _Py_Identifier *key)
1458
29.9k
{
1459
29.9k
    PyObject *kv;
1460
29.9k
    kv = _PyUnicode_FromId(key); /* borrowed */
1461
29.9k
    if (kv == NULL)
1462
0
        return NULL;
1463
29.9k
    return PyDict_GetItemWithError(dp, kv);
1464
29.9k
}
1465
1466
PyObject *
1467
_PyDict_GetItemStringWithError(PyObject *v, const char *key)
1468
489
{
1469
489
    PyObject *kv, *rv;
1470
489
    kv = PyUnicode_FromString(key);
1471
489
    if (kv == NULL) {
1472
0
        return NULL;
1473
0
    }
1474
489
    rv = PyDict_GetItemWithError(v, kv);
1475
489
    Py_DECREF(kv);
1476
489
    return rv;
1477
489
}
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
77.7k
{
1489
77.7k
    Py_ssize_t ix;
1490
77.7k
    Py_hash_t hash;
1491
77.7k
    PyObject *value;
1492
1493
77.7k
    if (!PyUnicode_CheckExact(key) ||
1494
77.7k
        (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
77.7k
    ix = globals->ma_keys->dk_lookup(globals, key, hash, &value);
1503
77.7k
    if (ix == DKIX_ERROR)
1504
0
        return NULL;
1505
77.7k
    if (ix != DKIX_EMPTY && value != NULL)
1506
58.0k
        return value;
1507
1508
    /* namespace 2: builtins */
1509
19.7k
    ix = builtins->ma_keys->dk_lookup(builtins, key, hash, &value);
1510
19.7k
    if (ix < 0)
1511
56
        return NULL;
1512
19.6k
    return value;
1513
19.7k
}
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
328k
{
1524
328k
    PyDictObject *mp;
1525
328k
    Py_hash_t hash;
1526
328k
    if (!PyDict_Check(op)) {
1527
0
        PyErr_BadInternalCall();
1528
0
        return -1;
1529
0
    }
1530
328k
    assert(key);
1531
328k
    assert(value);
1532
328k
    mp = (PyDictObject *)op;
1533
328k
    if (!PyUnicode_CheckExact(key) ||
1534
328k
        (hash = ((PyASCIIObject *) key)->hash) == -1)
1535
210k
    {
1536
210k
        hash = PyObject_Hash(key);
1537
210k
        if (hash == -1)
1538
0
            return -1;
1539
210k
    }
1540
1541
328k
    if (mp->ma_keys == Py_EMPTY_KEYS) {
1542
11.7k
        return insert_to_emptydict(mp, key, hash, value);
1543
11.7k
    }
1544
    /* insertdict() handles any resizing that might be necessary */
1545
316k
    return insertdict(mp, key, hash, value);
1546
328k
}
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.79k
{
1574
4.79k
    PyObject *old_key;
1575
4.79k
    PyDictKeyEntry *ep;
1576
1577
4.79k
    Py_ssize_t hashpos = lookdict_index(mp->ma_keys, hash, ix);
1578
4.79k
    assert(hashpos >= 0);
1579
1580
4.79k
    mp->ma_used--;
1581
4.79k
    mp->ma_version_tag = DICT_NEXT_VERSION();
1582
4.79k
    ep = &DK_ENTRIES(mp->ma_keys)[ix];
1583
4.79k
    dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
1584
4.79k
    ENSURE_ALLOWS_DELETIONS(mp);
1585
4.79k
    old_key = ep->me_key;
1586
4.79k
    ep->me_key = NULL;
1587
4.79k
    ep->me_value = NULL;
1588
4.79k
    Py_DECREF(old_key);
1589
4.79k
    Py_DECREF(old_value);
1590
1591
4.79k
    ASSERT_CONSISTENT(mp);
1592
4.79k
    return 0;
1593
4.79k
}
1594
1595
int
1596
PyDict_DelItem(PyObject *op, PyObject *key)
1597
4.79k
{
1598
4.79k
    Py_hash_t hash;
1599
4.79k
    assert(key);
1600
4.79k
    if (!PyUnicode_CheckExact(key) ||
1601
4.79k
        (hash = ((PyASCIIObject *) key)->hash) == -1) {
1602
452
        hash = PyObject_Hash(key);
1603
452
        if (hash == -1)
1604
0
            return -1;
1605
452
    }
1606
1607
4.79k
    return _PyDict_DelItem_KnownHash(op, key, hash);
1608
4.79k
}
1609
1610
int
1611
_PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
1612
4.79k
{
1613
4.79k
    Py_ssize_t ix;
1614
4.79k
    PyDictObject *mp;
1615
4.79k
    PyObject *old_value;
1616
1617
4.79k
    if (!PyDict_Check(op)) {
1618
0
        PyErr_BadInternalCall();
1619
0
        return -1;
1620
0
    }
1621
4.79k
    assert(key);
1622
4.79k
    assert(hash != -1);
1623
4.79k
    mp = (PyDictObject *)op;
1624
4.79k
    ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
1625
4.79k
    if (ix == DKIX_ERROR)
1626
0
        return -1;
1627
4.79k
    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.79k
    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.79k
    return delitem_common(mp, hash, ix, old_value);
1642
4.79k
}
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
13.8k
{
1743
13.8k
    Py_ssize_t i;
1744
13.8k
    PyDictObject *mp;
1745
13.8k
    PyDictKeyEntry *entry_ptr;
1746
13.8k
    PyObject *value;
1747
1748
13.8k
    if (!PyDict_Check(op))
1749
0
        return 0;
1750
13.8k
    mp = (PyDictObject *)op;
1751
13.8k
    i = *ppos;
1752
13.8k
    if (mp->ma_values) {
1753
66
        if (i < 0 || i >= mp->ma_used)
1754
66
            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
13.7k
    else {
1761
13.7k
        Py_ssize_t n = mp->ma_keys->dk_nentries;
1762
13.7k
        if (i < 0 || i >= n)
1763
2.04k
            return 0;
1764
11.7k
        entry_ptr = &DK_ENTRIES(mp->ma_keys)[i];
1765
12.7k
        while (i < n && entry_ptr->me_value == NULL) {
1766
1.05k
            entry_ptr++;
1767
1.05k
            i++;
1768
1.05k
        }
1769
11.7k
        if (i >= n)
1770
15
            return 0;
1771
11.7k
        value = entry_ptr->me_value;
1772
11.7k
    }
1773
11.7k
    *ppos = i+1;
1774
11.7k
    if (pkey)
1775
11.6k
        *pkey = entry_ptr->me_key;
1776
11.7k
    if (phash)
1777
17
        *phash = entry_ptr->me_hash;
1778
11.7k
    if (pvalue)
1779
11.7k
        *pvalue = value;
1780
11.7k
    return 1;
1781
13.8k
}
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
13.8k
{
1804
13.8k
    return _PyDict_Next(op, ppos, pkey, pvalue, NULL);
1805
13.8k
}
1806
1807
/* Internal version of dict.pop(). */
1808
PyObject *
1809
_PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *deflt)
1810
449
{
1811
449
    Py_ssize_t ix, hashpos;
1812
449
    PyObject *old_value, *old_key;
1813
449
    PyDictKeyEntry *ep;
1814
449
    PyDictObject *mp;
1815
1816
449
    assert(PyDict_Check(dict));
1817
449
    mp = (PyDictObject *)dict;
1818
1819
449
    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
449
    ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
1828
449
    if (ix == DKIX_ERROR)
1829
0
        return NULL;
1830
449
    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
444
    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
444
    hashpos = lookdict_index(mp->ma_keys, hash, ix);
1849
444
    assert(hashpos >= 0);
1850
444
    assert(old_value != NULL);
1851
444
    mp->ma_used--;
1852
444
    mp->ma_version_tag = DICT_NEXT_VERSION();
1853
444
    dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
1854
444
    ep = &DK_ENTRIES(mp->ma_keys)[ix];
1855
444
    ENSURE_ALLOWS_DELETIONS(mp);
1856
444
    old_key = ep->me_key;
1857
444
    ep->me_key = NULL;
1858
444
    ep->me_value = NULL;
1859
444
    Py_DECREF(old_key);
1860
1861
444
    ASSERT_CONSISTENT(mp);
1862
444
    return old_value;
1863
444
}
1864
1865
PyObject *
1866
_PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt)
1867
458
{
1868
458
    Py_hash_t hash;
1869
1870
458
    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
449
    if (!PyUnicode_CheckExact(key) ||
1879
449
        (hash = ((PyASCIIObject *) key)->hash) == -1) {
1880
0
        hash = PyObject_Hash(key);
1881
0
        if (hash == -1)
1882
0
            return NULL;
1883
0
    }
1884
449
    return _PyDict_Pop_KnownHash(dict, key, hash, deflt);
1885
449
}
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.5k
{
1980
11.5k
    PyObject **values = mp->ma_values;
1981
11.5k
    PyDictKeysObject *keys = mp->ma_keys;
1982
11.5k
    Py_ssize_t i, n;
1983
1984
    /* bpo-31095: UnTrack is needed before calling any callbacks */
1985
11.5k
    PyObject_GC_UnTrack(mp);
1986
11.5k
    Py_TRASHCAN_BEGIN(mp, dict_dealloc)
1987
11.5k
    if (values != NULL) {
1988
3.47k
        if (values != empty_values) {
1989
5.06k
            for (i = 0, n = mp->ma_keys->dk_nentries; i < n; i++) {
1990
4.14k
                Py_XDECREF(values[i]);
1991
4.14k
            }
1992
920
            free_values(values);
1993
920
        }
1994
3.47k
        dictkeys_decref(keys);
1995
3.47k
    }
1996
8.10k
    else if (keys != NULL) {
1997
8.10k
        assert(keys->dk_refcnt == 1);
1998
8.10k
        dictkeys_decref(keys);
1999
8.10k
    }
2000
11.5k
    if (numfree < PyDict_MAXFREELIST && Py_TYPE(mp) == &PyDict_Type)
2001
11.5k
        free_list[numfree++] = mp;
2002
5
    else
2003
5
        Py_TYPE(mp)->tp_free((PyObject *)mp);
2004
11.5k
    Py_TRASHCAN_END
2005
11.5k
}
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
4.06k
{
2100
4.06k
    Py_ssize_t ix;
2101
4.06k
    Py_hash_t hash;
2102
4.06k
    PyObject *value;
2103
2104
4.06k
    if (!PyUnicode_CheckExact(key) ||
2105
4.06k
        (hash = ((PyASCIIObject *) key)->hash) == -1) {
2106
752
        hash = PyObject_Hash(key);
2107
752
        if (hash == -1)
2108
0
            return NULL;
2109
752
    }
2110
4.06k
    ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
2111
4.06k
    if (ix == DKIX_ERROR)
2112
0
        return NULL;
2113
4.06k
    if (ix == DKIX_EMPTY || value == NULL) {
2114
505
        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
505
        _PyErr_SetKeyError(key);
2129
505
        return NULL;
2130
505
    }
2131
3.55k
    Py_INCREF(value);
2132
3.55k
    return value;
2133
4.06k
}
2134
2135
static int
2136
dict_ass_sub(PyDictObject *mp, PyObject *v, PyObject *w)
2137
4.29k
{
2138
4.29k
    if (w == NULL)
2139
2.06k
        return PyDict_DelItem((PyObject *)mp, v);
2140
2.22k
    else
2141
2.22k
        return PyDict_SetItem((PyObject *)mp, v, w);
2142
4.29k
}
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
103
{
2153
103
    PyObject *v;
2154
103
    Py_ssize_t i, j;
2155
103
    PyDictKeyEntry *ep;
2156
103
    Py_ssize_t n, offset;
2157
103
    PyObject **value_ptr;
2158
2159
103
  again:
2160
103
    n = mp->ma_used;
2161
103
    v = PyList_New(n);
2162
103
    if (v == NULL)
2163
0
        return NULL;
2164
103
    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
103
    ep = DK_ENTRIES(mp->ma_keys);
2172
103
    if (mp->ma_values) {
2173
0
        value_ptr = mp->ma_values;
2174
0
        offset = sizeof(PyObject *);
2175
0
    }
2176
103
    else {
2177
103
        value_ptr = &ep[0].me_value;
2178
103
        offset = sizeof(PyDictKeyEntry);
2179
103
    }
2180
10.6k
    for (i = 0, j = 0; j < n; i++) {
2181
10.5k
        if (*value_ptr != NULL) {
2182
10.5k
            PyObject *key = ep[i].me_key;
2183
10.5k
            Py_INCREF(key);
2184
10.5k
            PyList_SET_ITEM(v, j, key);
2185
10.5k
            j++;
2186
10.5k
        }
2187
10.5k
        value_ptr = (PyObject **)(((char *)value_ptr) + offset);
2188
10.5k
    }
2189
103
    assert(j == n);
2190
103
    return v;
2191
103
}
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
168
{
2318
168
    PyObject *arg = NULL;
2319
168
    int result = 0;
2320
2321
168
    if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) {
2322
0
        result = -1;
2323
0
    }
2324
168
    else if (arg != NULL) {
2325
146
        _Py_IDENTIFIER(keys);
2326
146
        PyObject *func;
2327
146
        if (_PyObject_LookupAttrId(arg, &PyId_keys, &func) < 0) {
2328
0
            result = -1;
2329
0
        }
2330
146
        else if (func != NULL) {
2331
145
            Py_DECREF(func);
2332
145
            result = PyDict_Merge(self, arg, 1);
2333
145
        }
2334
1
        else {
2335
1
            result = PyDict_MergeFromSeq2(self, arg, 1);
2336
1
        }
2337
146
    }
2338
2339
168
    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
168
    return result;
2346
168
}
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
145
{
2354
145
    if (dict_update_common(self, args, kwds, "update") != -1)
2355
145
        Py_RETURN_NONE;
2356
0
    return NULL;
2357
145
}
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
220
{
2457
220
    PyDictObject *mp, *other;
2458
220
    Py_ssize_t i, n;
2459
220
    PyDictKeyEntry *entry, *ep0;
2460
2461
220
    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
220
    if (a == NULL || !PyDict_Check(a) || b == NULL) {
2469
0
        PyErr_BadInternalCall();
2470
0
        return -1;
2471
0
    }
2472
220
    mp = (PyDictObject*)a;
2473
220
    if (PyDict_Check(b) && (Py_TYPE(b)->tp_iter == (getiterfunc)dict_iter)) {
2474
219
        other = (PyDictObject*)b;
2475
219
        if (other == mp || other->ma_used == 0)
2476
            /* a.update(a) or a.update({}); nothing to do */
2477
155
            return 0;
2478
64
        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
33
            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
64
        if (USABLE_FRACTION(mp->ma_keys->dk_size) < other->ma_used) {
2489
34
            if (dictresize(mp, ESTIMATE_SIZE(mp->ma_used + other->ma_used))) {
2490
0
               return -1;
2491
0
            }
2492
34
        }
2493
64
        ep0 = DK_ENTRIES(other->ma_keys);
2494
812
        for (i = 0, n = other->ma_keys->dk_nentries; i < n; i++) {
2495
748
            PyObject *key, *value;
2496
748
            Py_hash_t hash;
2497
748
            entry = &ep0[i];
2498
748
            key = entry->me_key;
2499
748
            hash = entry->me_hash;
2500
748
            if (other->ma_values)
2501
0
                value = other->ma_values[i];
2502
748
            else
2503
748
                value = entry->me_value;
2504
2505
748
            if (value != NULL) {
2506
726
                int err = 0;
2507
726
                Py_INCREF(key);
2508
726
                Py_INCREF(value);
2509
726
                if (override == 1)
2510
726
                    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
726
                Py_DECREF(value);
2526
726
                Py_DECREF(key);
2527
726
                if (err != 0)
2528
0
                    return -1;
2529
2530
726
                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
726
            }
2536
748
        }
2537
64
    }
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
65
    ASSERT_CONSISTENT(a);
2596
65
    return 0;
2597
220
}
2598
2599
int
2600
PyDict_Update(PyObject *a, PyObject *b)
2601
42
{
2602
42
    return dict_merge(a, b, 1);
2603
42
}
2604
2605
int
2606
PyDict_Merge(PyObject *a, PyObject *b, int override)
2607
150
{
2608
    /* XXX Deprecate override not in (0, 1). */
2609
150
    return dict_merge(a, b, override != 0);
2610
150
}
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.84k
{
2627
2.84k
    PyObject *copy;
2628
2.84k
    PyDictObject *mp;
2629
2.84k
    Py_ssize_t i, n;
2630
2631
2.84k
    if (o == NULL || !PyDict_Check(o)) {
2632
0
        PyErr_BadInternalCall();
2633
0
        return NULL;
2634
0
    }
2635
2636
2.84k
    mp = (PyDictObject *)o;
2637
2.84k
    if (mp->ma_used == 0) {
2638
        /* The dict is empty; just return a new dict. */
2639
14
        return PyDict_New();
2640
14
    }
2641
2642
2.83k
    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.83k
    if (PyDict_CheckExact(mp) && mp->ma_values == NULL &&
2670
2.83k
            (mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3))
2671
2.82k
    {
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.82k
        return clone_combined_dict(mp);
2687
2.82k
    }
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
103
{
2711
103
    if (mp == NULL || !PyDict_Check(mp)) {
2712
0
        PyErr_BadInternalCall();
2713
0
        return NULL;
2714
0
    }
2715
103
    return dict_keys((PyDictObject *)mp);
2716
103
}
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
958
{
2857
958
    PyObject *val = NULL;
2858
958
    Py_hash_t hash;
2859
958
    Py_ssize_t ix;
2860
2861
958
    if (!PyUnicode_CheckExact(key) ||
2862
958
        (hash = ((PyASCIIObject *) key)->hash) == -1) {
2863
80
        hash = PyObject_Hash(key);
2864
80
        if (hash == -1)
2865
0
            return NULL;
2866
80
    }
2867
958
    ix = (self->ma_keys->dk_lookup) (self, key, hash, &val);
2868
958
    if (ix == DKIX_ERROR)
2869
0
        return NULL;
2870
958
    if (ix == DKIX_EMPTY || val == NULL) {
2871
510
        val = default_value;
2872
510
    }
2873
958
    Py_INCREF(val);
2874
958
    return val;
2875
958
}
2876
2877
PyObject *
2878
PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj)
2879
93.0k
{
2880
93.0k
    PyDictObject *mp = (PyDictObject *)d;
2881
93.0k
    PyObject *value;
2882
93.0k
    Py_hash_t hash;
2883
2884
93.0k
    if (!PyDict_Check(d)) {
2885
0
        PyErr_BadInternalCall();
2886
0
        return NULL;
2887
0
    }
2888
2889
93.0k
    if (!PyUnicode_CheckExact(key) ||
2890
93.0k
        (hash = ((PyASCIIObject *) key)->hash) == -1) {
2891
93.0k
        hash = PyObject_Hash(key);
2892
93.0k
        if (hash == -1)
2893
0
            return NULL;
2894
93.0k
    }
2895
93.0k
    if (mp->ma_keys == Py_EMPTY_KEYS) {
2896
30
        if (insert_to_emptydict(mp, key, hash, defaultobj) < 0) {
2897
0
            return NULL;
2898
0
        }
2899
30
        return defaultobj;
2900
30
    }
2901
2902
93.0k
    if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) {
2903
0
        if (insertion_resize(mp) < 0)
2904
0
            return NULL;
2905
0
    }
2906
2907
93.0k
    Py_ssize_t ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
2908
93.0k
    if (ix == DKIX_ERROR)
2909
0
        return NULL;
2910
2911
93.0k
    if (_PyDict_HasSplitTable(mp) &&
2912
93.0k
        ((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
93.0k
    if (ix == DKIX_EMPTY) {
2921
43.1k
        PyDictKeyEntry *ep, *ep0;
2922
43.1k
        value = defaultobj;
2923
43.1k
        if (mp->ma_keys->dk_usable <= 0) {
2924
157
            if (insertion_resize(mp) < 0) {
2925
0
                return NULL;
2926
0
            }
2927
157
        }
2928
43.1k
        Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash);
2929
43.1k
        ep0 = DK_ENTRIES(mp->ma_keys);
2930
43.1k
        ep = &ep0[mp->ma_keys->dk_nentries];
2931
43.1k
        dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
2932
43.1k
        Py_INCREF(key);
2933
43.1k
        Py_INCREF(value);
2934
43.1k
        MAINTAIN_TRACKING(mp, key, value);
2935
43.1k
        ep->me_key = key;
2936
43.1k
        ep->me_hash = hash;
2937
43.1k
        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
43.1k
        else {
2942
43.1k
            ep->me_value = value;
2943
43.1k
        }
2944
43.1k
        mp->ma_used++;
2945
43.1k
        mp->ma_version_tag = DICT_NEXT_VERSION();
2946
43.1k
        mp->ma_keys->dk_usable--;
2947
43.1k
        mp->ma_keys->dk_nentries++;
2948
43.1k
        assert(mp->ma_keys->dk_usable >= 0);
2949
43.1k
    }
2950
49.9k
    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
93.0k
    ASSERT_CONSISTENT(mp);
2962
93.0k
    return value;
2963
93.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
458
{
3010
458
    PyObject *return_value = NULL;
3011
458
    PyObject *key;
3012
458
    PyObject *default_value = NULL;
3013
3014
458
    if (!_PyArg_CheckPositional("pop", nargs, 1, 2)) {
3015
0
        goto exit;
3016
0
    }
3017
458
    key = args[0];
3018
458
    if (nargs < 2) {
3019
439
        goto skip_optional;
3020
439
    }
3021
19
    default_value = args[1];
3022
458
skip_optional:
3023
458
    return_value = _PyDict_Pop((PyObject*)self, key, default_value);
3024
3025
458
exit:
3026
458
    return return_value;
3027
458
}
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
13.4k
{
3101
13.4k
    PyDictObject *mp = (PyDictObject *)op;
3102
13.4k
    PyDictKeysObject *keys = mp->ma_keys;
3103
13.4k
    PyDictKeyEntry *entries = DK_ENTRIES(keys);
3104
13.4k
    Py_ssize_t i, n = keys->dk_nentries;
3105
3106
13.4k
    if (keys->dk_lookup == lookdict) {
3107
7.25k
        for (i = 0; i < n; i++) {
3108
5.38k
            if (entries[i].me_value != NULL) {
3109
5.34k
                Py_VISIT(entries[i].me_value);
3110
5.34k
                Py_VISIT(entries[i].me_key);
3111
5.34k
            }
3112
5.38k
        }
3113
1.87k
    }
3114
11.5k
    else {
3115
11.5k
        if (mp->ma_values != NULL) {
3116
10.5k
            for (i = 0; i < n; i++) {
3117
9.23k
                Py_VISIT(mp->ma_values[i]);
3118
9.23k
            }
3119
1.36k
        }
3120
10.2k
        else {
3121
169k
            for (i = 0; i < n; i++) {
3122
159k
                Py_VISIT(entries[i].me_value);
3123
159k
            }
3124
10.2k
        }
3125
11.5k
    }
3126
13.4k
    return 0;
3127
13.4k
}
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.82k
{
3161
2.82k
    return (sizeof(PyDictKeysObject)
3162
2.82k
            + DK_IXSIZE(keys) * DK_SIZE(keys)
3163
2.82k
            + USABLE_FRACTION(DK_SIZE(keys)) * sizeof(PyDictKeyEntry));
3164
2.82k
}
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.86k
{
3232
2.86k
    Py_hash_t hash;
3233
2.86k
    Py_ssize_t ix;
3234
2.86k
    PyDictObject *mp = (PyDictObject *)op;
3235
2.86k
    PyObject *value;
3236
3237
2.86k
    if (!PyUnicode_CheckExact(key) ||
3238
2.86k
        (hash = ((PyASCIIObject *) key)->hash) == -1) {
3239
610
        hash = PyObject_Hash(key);
3240
610
        if (hash == -1)
3241
0
            return -1;
3242
610
    }
3243
2.86k
    ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
3244
2.86k
    if (ix == DKIX_ERROR)
3245
0
        return -1;
3246
2.86k
    return (ix != DKIX_EMPTY && value != NULL);
3247
2.86k
}
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
15.7k
{
3373
15.7k
    PyObject *kv;
3374
15.7k
    kv = _PyUnicode_FromId(key); /* borrowed */
3375
15.7k
    if (kv == NULL) {
3376
0
        PyErr_Clear();
3377
0
        return NULL;
3378
0
    }
3379
15.7k
    return PyDict_GetItem(dp, kv);
3380
15.7k
}
3381
3382
/* For backward compatibility with old dictionary interface */
3383
3384
PyObject *
3385
PyDict_GetItemString(PyObject *v, const char *key)
3386
1.21k
{
3387
1.21k
    PyObject *kv, *rv;
3388
1.21k
    kv = PyUnicode_FromString(key);
3389
1.21k
    if (kv == NULL) {
3390
0
        PyErr_Clear();
3391
0
        return NULL;
3392
0
    }
3393
1.21k
    rv = PyDict_GetItem(v, kv);
3394
1.21k
    Py_DECREF(kv);
3395
1.21k
    return rv;
3396
1.21k
}
3397
3398
int
3399
_PyDict_SetItemId(PyObject *v, struct _Py_Identifier *key, PyObject *item)
3400
8.88k
{
3401
8.88k
    PyObject *kv;
3402
8.88k
    kv = _PyUnicode_FromId(key); /* borrowed */
3403
8.88k
    if (kv == NULL)
3404
0
        return -1;
3405
8.88k
    return PyDict_SetItem(v, kv, item);
3406
8.88k
}
3407
3408
int
3409
PyDict_SetItemString(PyObject *v, const char *key, PyObject *item)
3410
11.8k
{
3411
11.8k
    PyObject *kv;
3412
11.8k
    int err;
3413
11.8k
    kv = PyUnicode_FromString(key);
3414
11.8k
    if (kv == NULL)
3415
0
        return -1;
3416
11.8k
    PyUnicode_InternInPlace(&kv); /* XXX Should we really? */
3417
11.8k
    err = PyDict_SetItem(v, kv, item);
3418
11.8k
    Py_DECREF(kv);
3419
11.8k
    return err;
3420
11.8k
}
3421
3422
int
3423
_PyDict_DelItemId(PyObject *v, _Py_Identifier *key)
3424
1.52k
{
3425
1.52k
    PyObject *kv = _PyUnicode_FromId(key); /* borrowed */
3426
1.52k
    if (kv == NULL)
3427
0
        return -1;
3428
1.52k
    return PyDict_DelItem(v, kv);
3429
1.52k
}
3430
3431
int
3432
PyDict_DelItemString(PyObject *v, const char *key)
3433
28
{
3434
28
    PyObject *kv;
3435
28
    int err;
3436
28
    kv = PyUnicode_FromString(key);
3437
28
    if (kv == NULL)
3438
0
        return -1;
3439
28
    err = PyDict_DelItem(v, kv);
3440
28
    Py_DECREF(kv);
3441
28
    return err;
3442
28
}
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
584
{
3458
584
    dictiterobject *di;
3459
584
    di = PyObject_GC_New(dictiterobject, itertype);
3460
584
    if (di == NULL) {
3461
0
        return NULL;
3462
0
    }
3463
584
    Py_INCREF(dict);
3464
584
    di->di_dict = dict;
3465
584
    di->di_used = dict->ma_used;
3466
584
    di->len = dict->ma_used;
3467
584
    if (itertype == &PyDictRevIterKey_Type ||
3468
584
         itertype == &PyDictRevIterItem_Type ||
3469
584
         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
584
    else {
3478
584
        di->di_pos = 0;
3479
584
    }
3480
584
    if (itertype == &PyDictIterItem_Type ||
3481
584
        itertype == &PyDictRevIterItem_Type) {
3482
535
        di->di_result = PyTuple_Pack(2, Py_None, Py_None);
3483
535
        if (di->di_result == NULL) {
3484
0
            Py_DECREF(di);
3485
0
            return NULL;
3486
0
        }
3487
535
    }
3488
49
    else {
3489
49
        di->di_result = NULL;
3490
49
    }
3491
584
    _PyObject_GC_TRACK(di);
3492
584
    return (PyObject *)di;
3493
584
}
3494
3495
static void
3496
dictiter_dealloc(dictiterobject *di)
3497
584
{
3498
    /* bpo-31095: UnTrack is needed before calling any callbacks */
3499
584
    _PyObject_GC_UNTRACK(di);
3500
584
    Py_XDECREF(di->di_dict);
3501
584
    Py_XDECREF(di->di_result);
3502
584
    PyObject_GC_Del(di);
3503
584
}
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
458
{
3516
458
    Py_ssize_t len = 0;
3517
458
    if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used)
3518
458
        len = di->len;
3519
458
    return PyLong_FromSize_t(len);
3520
458
}
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.49k
{
3717
4.49k
    PyObject *key, *value, *result;
3718
4.49k
    Py_ssize_t i;
3719
4.49k
    PyDictObject *d = di->di_dict;
3720
3721
4.49k
    if (d == NULL)
3722
0
        return NULL;
3723
4.49k
    assert (PyDict_Check(d));
3724
3725
4.49k
    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.49k
    i = di->di_pos;
3733
4.49k
    assert(i >= 0);
3734
4.49k
    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.48k
    else {
3742
4.48k
        Py_ssize_t n = d->ma_keys->dk_nentries;
3743
4.48k
        PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i];
3744
4.80k
        while (i < n && entry_ptr->me_value == NULL) {
3745
325
            entry_ptr++;
3746
325
            i++;
3747
325
        }
3748
4.48k
        if (i >= n)
3749
504
            goto fail;
3750
3.97k
        key = entry_ptr->me_key;
3751
3.97k
        value = entry_ptr->me_value;
3752
3.97k
    }
3753
    // We found an element, but did not expect it
3754
3.97k
    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.97k
    di->di_pos = i+1;
3760
3.97k
    di->len--;
3761
3.97k
    Py_INCREF(key);
3762
3.97k
    Py_INCREF(value);
3763
3.97k
    result = di->di_result;
3764
3.97k
    if (Py_REFCNT(result) == 1) {
3765
1.22k
        PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
3766
1.22k
        PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
3767
1.22k
        PyTuple_SET_ITEM(result, 0, key);  /* steals reference */
3768
1.22k
        PyTuple_SET_ITEM(result, 1, value);  /* steals reference */
3769
1.22k
        Py_INCREF(result);
3770
1.22k
        Py_DECREF(oldkey);
3771
1.22k
        Py_DECREF(oldvalue);
3772
1.22k
    }
3773
2.75k
    else {
3774
2.75k
        result = PyTuple_New(2);
3775
2.75k
        if (result == NULL)
3776
0
            return NULL;
3777
2.75k
        PyTuple_SET_ITEM(result, 0, key);  /* steals reference */
3778
2.75k
        PyTuple_SET_ITEM(result, 1, value);  /* steals reference */
3779
2.75k
    }
3780
3.97k
    return result;
3781
3782
513
fail:
3783
513
    di->di_dict = NULL;
3784
513
    Py_DECREF(d);
3785
513
    return NULL;
3786
3.97k
}
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
607
{
3984
    /* bpo-31095: UnTrack is needed before calling any callbacks */
3985
607
    _PyObject_GC_UNTRACK(dv);
3986
607
    Py_XDECREF(dv->dv_dict);
3987
607
    PyObject_GC_Del(dv);
3988
607
}
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
607
{
4009
607
    _PyDictViewObject *dv;
4010
607
    if (dict == NULL) {
4011
0
        PyErr_BadInternalCall();
4012
0
        return NULL;
4013
0
    }
4014
607
    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
607
    dv = PyObject_GC_New(_PyDictViewObject, type);
4022
607
    if (dv == NULL)
4023
0
        return NULL;
4024
607
    Py_INCREF(dict);
4025
607
    dv->dv_dict = (PyDictObject *)dict;
4026
607
    _PyObject_GC_TRACK(dv);
4027
607
    return (PyObject *)dv;
4028
607
}
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
15
{
4152
15
    if (dv->dv_dict == NULL) {
4153
0
        Py_RETURN_NONE;
4154
0
    }
4155
15
    return dictiter_new(dv->dv_dict, &PyDictIterKey_Type);
4156
15
}
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
29
{
4379
29
    return _PyDictView_New(dict, &PyDictKeys_Type);
4380
29
}
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
535
{
4396
535
    if (dv->dv_dict == NULL) {
4397
0
        Py_RETURN_NONE;
4398
0
    }
4399
535
    return dictiter_new(dv->dv_dict, &PyDictIterItem_Type);
4400
535
}
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
549
{
4485
549
    return _PyDictView_New(dict, &PyDictItems_Type);
4486
549
}
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
15
{
4502
15
    if (dv->dv_dict == NULL) {
4503
0
        Py_RETURN_NONE;
4504
0
    }
4505
15
    return dictiter_new(dv->dv_dict, &PyDictIterValue_Type);
4506
15
}
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
29
{
4566
29
    return _PyDictView_New(dict, &PyDictValues_Type);
4567
29
}
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
974
{
4584
974
    PyDictKeysObject *keys = new_keys_object(PyDict_MINSIZE);
4585
974
    if (keys == NULL)
4586
0
        PyErr_Clear();
4587
974
    else
4588
974
        keys->dk_lookup = lookdict_split;
4589
974
    return keys;
4590
974
}
4591
4592
28.2k
#define CACHED_KEYS(tp) (((PyHeapTypeObject*)tp)->ht_cached_keys)
4593
4594
PyObject *
4595
PyObject_GenericGetDict(PyObject *obj, void *context)
4596
296
{
4597
296
    PyObject *dict, **dictptr = _PyObject_GetDictPtr(obj);
4598
296
    if (dictptr == NULL) {
4599
0
        PyErr_SetString(PyExc_AttributeError,
4600
0
                        "This object has no __dict__");
4601
0
        return NULL;
4602
0
    }
4603
296
    dict = *dictptr;
4604
296
    if (dict == NULL) {
4605
281
        PyTypeObject *tp = Py_TYPE(obj);
4606
281
        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
281
        else {
4611
281
            *dictptr = dict = PyDict_New();
4612
281
        }
4613
281
    }
4614
296
    Py_XINCREF(dict);
4615
296
    return dict;
4616
296
}
4617
4618
int
4619
_PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
4620
                      PyObject *key, PyObject *value)
4621
23.2k
{
4622
23.2k
    PyObject *dict;
4623
23.2k
    int res;
4624
23.2k
    PyDictKeysObject *cached;
4625
4626
23.2k
    assert(dictptr != NULL);
4627
23.2k
    if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && (cached = CACHED_KEYS(tp))) {
4628
14.3k
        assert(dictptr != NULL);
4629
14.3k
        dict = *dictptr;
4630
14.3k
        if (dict == NULL) {
4631
1.92k
            dictkeys_incref(cached);
4632
1.92k
            dict = new_dict_with_shared_keys(cached);
4633
1.92k
            if (dict == NULL)
4634
0
                return -1;
4635
1.92k
            *dictptr = dict;
4636
1.92k
        }
4637
14.3k
        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
14.3k
        else {
4647
14.3k
            int was_shared = (cached == ((PyDictObject *)dict)->ma_keys);
4648
14.3k
            res = PyDict_SetItem(dict, key, value);
4649
14.3k
            if (was_shared &&
4650
14.3k
                    (cached = CACHED_KEYS(tp)) != NULL &&
4651
14.3k
                    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
68
                if (cached->dk_refcnt == 1) {
4667
67
                    CACHED_KEYS(tp) = make_keys_shared(dict);
4668
67
                }
4669
1
                else {
4670
1
                    CACHED_KEYS(tp) = NULL;
4671
1
                }
4672
68
                dictkeys_decref(cached);
4673
68
                if (CACHED_KEYS(tp) == NULL && PyErr_Occurred())
4674
0
                    return -1;
4675
68
            }
4676
14.3k
        }
4677
14.3k
    } else {
4678
8.91k
        dict = *dictptr;
4679
8.91k
        if (dict == NULL) {
4680
690
            dict = PyDict_New();
4681
690
            if (dict == NULL)
4682
0
                return -1;
4683
690
            *dictptr = dict;
4684
690
        }
4685
8.91k
        if (value == NULL) {
4686
0
            res = PyDict_DelItem(dict, key);
4687
8.91k
        } else {
4688
8.91k
            res = PyDict_SetItem(dict, key, value);
4689
8.91k
        }
4690
8.91k
    }
4691
23.2k
    return res;
4692
23.2k
}
4693
4694
void
4695
_PyDictKeys_DecRef(PyDictKeysObject *keys)
4696
3
{
4697
3
    dictkeys_decref(keys);
4698
3
}