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