blob: 6c3fc62d2ecc7ee1f86622b2058bd769f4e3f5ec [file] [log] [blame]
Guido van Rossum2bc13791999-03-24 19:06:42 +00001/* Dictionary object implementation using a hash table */
Guido van Rossum9bfef441993-03-29 10:43:31 +00002
Raymond Hettinger930427b2003-05-03 06:51:59 +00003/* The distribution includes a separate file, Objects/dictnotes.txt,
Tim Peters60b29962006-01-01 01:19:23 +00004 describing explorations into dictionary design and optimization.
Raymond Hettinger930427b2003-05-03 06:51:59 +00005 It covers typical dictionary use patterns, the parameters for
6 tuning dictionaries, and several ideas for possible optimizations.
7*/
8
Victor Stinner742da042016-09-07 17:40:12 -07009/* PyDictKeysObject
10
11This implements the dictionary's hashtable.
12
Raymond Hettingerb12785d2016-10-22 09:58:14 -070013As 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
Victor Stinner742da042016-09-07 17:40:12 -070016
17layout:
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
33dk_indices is actual hashtable. It holds index in entries, or DKIX_EMPTY(-1)
34or DKIX_DUMMY(-2).
35Size 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
dalgarno359143c2019-09-10 10:45:07 +010042dk_entries is array of PyDictKeyEntry. Its size is USABLE_FRACTION(dk_size).
Victor Stinner742da042016-09-07 17:40:12 -070043DK_ENTRIES(dk) can be used to get pointer to entries.
44
45NOTE: Since negative value is used for DKIX_EMPTY and DKIX_DUMMY, type of
46dk_indices entry is signed integer and int16 is used for table which
47dk_size == 256.
48*/
49
Benjamin Peterson7d95e402012-04-23 11:24:50 -040050
51/*
Benjamin Peterson7d95e402012-04-23 11:24:50 -040052The DictObject can be in one of two forms.
Victor Stinner742da042016-09-07 17:40:12 -070053
Benjamin Peterson7d95e402012-04-23 11:24:50 -040054Either:
55 A combined table:
56 ma_values == NULL, dk_refcnt == 1.
57 Values are stored in the me_value field of the PyDictKeysObject.
Benjamin Peterson7d95e402012-04-23 11:24:50 -040058Or:
59 A split table:
60 ma_values != NULL, dk_refcnt >= 1
61 Values are stored in the ma_values array.
Victor Stinner742da042016-09-07 17:40:12 -070062 Only string (unicode) keys are allowed.
63 All dicts sharing same key must have same insertion order.
Benjamin Peterson7d95e402012-04-23 11:24:50 -040064
Victor Stinner742da042016-09-07 17:40:12 -070065There are four kinds of slots in the table (slot is index, and
66DK_ENTRIES(keys)[index] if index >= 0):
67
681. 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
722. 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
773. 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
844. Pending. index >= 0, key != NULL, and value == NULL (split only)
85 Not yet inserted in split-table.
Benjamin Peterson7d95e402012-04-23 11:24:50 -040086*/
87
Victor Stinner742da042016-09-07 17:40:12 -070088/*
89Preserving insertion order
Benjamin Peterson7d95e402012-04-23 11:24:50 -040090
Victor Stinner742da042016-09-07 17:40:12 -070091It's simple for combined table. Since dk_entries is mostly append only, we can
92get insertion order by just iterating dk_entries.
93
94One exception is .popitem(). It removes last item in dk_entries and decrement
95dk_nentries to achieve amortized O(1). Since there are DKIX_DUMMY remains in
96dk_indices, we can't increment dk_usable even though dk_nentries is
97decremented.
98
99In split table, inserting into pending entry is allowed only for dk_entries[ix]
100where ix == mp->ma_used. Inserting into other index and deleting item cause
101converting the dict to the combined table.
102*/
103
104/* PyDict_MINSIZE is the starting size for any new dict.
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400105 * 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 */
Victor Stinner742da042016-09-07 17:40:12 -0700111#define PyDict_MINSIZE 8
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400112
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000113#include "Python.h"
Inada Naokid9323a82020-08-07 14:08:55 +0900114#include "pycore_bitutils.h" // _Py_bit_length
Victor Stinnere5014be2020-04-14 17:52:15 +0200115#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
Victor Stinner59d3dce2020-06-02 14:03:25 +0200116#include "pycore_object.h" // _PyObject_GC_TRACK()
117#include "pycore_pyerrors.h" // _PyErr_Fetch()
Victor Stinnere5014be2020-04-14 17:52:15 +0200118#include "pycore_pystate.h" // _PyThreadState_GET()
Eric Snow96c6af92015-05-29 22:21:39 -0600119#include "dict-common.h"
Victor Stinnere5014be2020-04-14 17:52:15 +0200120#include "stringlib/eq.h" // unicode_eq()
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000121
Larry Hastings61272b72014-01-07 12:41:53 -0800122/*[clinic input]
Larry Hastingsc2047262014-01-25 20:43:29 -0800123class dict "PyDictObject *" "&PyDict_Type"
Larry Hastings61272b72014-01-07 12:41:53 -0800124[clinic start generated code]*/
Larry Hastings581ee362014-01-28 05:00:08 -0800125/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f157a5a0ce9589d6]*/
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800126
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400127
128/*
129To ensure the lookup algorithm terminates, there must be at least one Unused
130slot (NULL key) in the table.
131To avoid slowing down lookups on a near-full table, we resize the table when
132it's USABLE_FRACTION (currently two-thirds) full.
133*/
Guido van Rossum16e93a81997-01-28 00:00:11 +0000134
Tim Peterseb28ef22001-06-02 05:27:19 +0000135#define PERTURB_SHIFT 5
136
Guido van Rossum16e93a81997-01-28 00:00:11 +0000137/*
Tim Peterseb28ef22001-06-02 05:27:19 +0000138Major subtleties ahead: Most hash schemes depend on having a "good" hash
139function, in the sense of simulating randomness. Python doesn't: its most
R David Murray537ad7a2016-07-10 12:33:18 -0400140important hash functions (for ints) are very regular in common
Tim Peterseb28ef22001-06-02 05:27:19 +0000141cases:
Tim Peters15d49292001-05-27 07:39:22 +0000142
R David Murray537ad7a2016-07-10 12:33:18 -0400143 >>>[hash(i) for i in range(4)]
Guido van Rossumdc5f6b22006-08-24 21:29:26 +0000144 [0, 1, 2, 3]
Tim Peters15d49292001-05-27 07:39:22 +0000145
Tim Peterseb28ef22001-06-02 05:27:19 +0000146This isn't necessarily bad! To the contrary, in a table of size 2**i, taking
147the low-order i bits as the initial table index is extremely fast, and there
R David Murray537ad7a2016-07-10 12:33:18 -0400148are no collisions at all for dicts indexed by a contiguous range of ints. So
149this gives better-than-random behavior in common cases, and that's very
150desirable.
Tim Peters15d49292001-05-27 07:39:22 +0000151
Tim Peterseb28ef22001-06-02 05:27:19 +0000152OTOH, when collisions occur, the tendency to fill contiguous slices of the
153hash table makes a good collision resolution strategy crucial. Taking only
154the last i bits of the hash code is also vulnerable: for example, consider
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155the list [i << 16 for i in range(20000)] as a set of keys. Since ints are
Guido van Rossumdc5f6b22006-08-24 21:29:26 +0000156their own hash codes, and this fits in a dict of size 2**15, the last 15 bits
157 of every hash code are all 0: they *all* map to the same table index.
Tim Peters15d49292001-05-27 07:39:22 +0000158
Tim Peterseb28ef22001-06-02 05:27:19 +0000159But catering to unusual cases should not slow the usual ones, so we just take
160the last i bits anyway. It's up to collision resolution to do the rest. If
161we *usually* find the key we're looking for on the first try (and, it turns
162out, we usually do -- the table load factor is kept under 2/3, so the odds
163are solidly in our favor), then it makes best sense to keep the initial index
164computation dirt cheap.
Tim Peters15d49292001-05-27 07:39:22 +0000165
Tim Peterseb28ef22001-06-02 05:27:19 +0000166The first half of collision resolution is to visit table indices via this
167recurrence:
Tim Peters15d49292001-05-27 07:39:22 +0000168
Tim Peterseb28ef22001-06-02 05:27:19 +0000169 j = ((5*j) + 1) mod 2**i
Tim Peters15d49292001-05-27 07:39:22 +0000170
Tim Peterseb28ef22001-06-02 05:27:19 +0000171For any initial j in range(2**i), repeating that 2**i times generates each
172int in range(2**i) exactly once (see any text on random-number generation for
173proof). By itself, this doesn't help much: like linear probing (setting
174j += 1, or j -= 1, on each loop trip), it scans the table entries in a fixed
175order. This would be bad, except that's not the only thing we do, and it's
176actually *good* in the common cases where hash keys are consecutive. In an
177example that's really too small to make this entirely clear, for a table of
178size 2**3 the order of indices is:
Tim Peters15d49292001-05-27 07:39:22 +0000179
Tim Peterseb28ef22001-06-02 05:27:19 +0000180 0 -> 1 -> 6 -> 7 -> 4 -> 5 -> 2 -> 3 -> 0 [and here it's repeating]
181
182If two things come in at index 5, the first place we look after is index 2,
183not 6, so if another comes in at index 6 the collision at 5 didn't hurt it.
184Linear probing is deadly in this case because there the fixed probe order
185is the *same* as the order consecutive keys are likely to arrive. But it's
186extremely unlikely hash codes will follow a 5*j+1 recurrence by accident,
187and certain that consecutive hash codes do not.
188
189The other half of the strategy is to get the other bits of the hash code
190into play. This is done by initializing a (unsigned) vrbl "perturb" to the
191full hash code, and changing the recurrence to:
192
Tim Peterseb28ef22001-06-02 05:27:19 +0000193 perturb >>= PERTURB_SHIFT;
INADA Naoki267941c2016-10-06 15:19:07 +0900194 j = (5*j) + 1 + perturb;
Tim Peterseb28ef22001-06-02 05:27:19 +0000195 use j % 2**i as the next table index;
196
197Now the probe sequence depends (eventually) on every bit in the hash code,
198and the pseudo-scrambling property of recurring on 5*j+1 is more valuable,
199because it quickly magnifies small differences in the bits that didn't affect
200the initial index. Note that because perturb is unsigned, if the recurrence
201is executed often enough perturb eventually becomes and remains 0. At that
202point (very rarely reached) the recurrence is on (just) 5*j+1 again, and
203that's certain to find an empty slot eventually (since it generates every int
204in range(2**i), and we make sure there's always at least one empty slot).
205
206Selecting a good value for PERTURB_SHIFT is a balancing act. You want it
207small so that the high bits of the hash code continue to affect the probe
208sequence across iterations; but you want it large so that in really bad cases
209the high-order hash bits have an effect on early iterations. 5 was "the
210best" in minimizing total collisions across experiments Tim Peters ran (on
211both normal and pathological cases), but 4 and 6 weren't significantly worse.
212
Guido van Rossumdc5f6b22006-08-24 21:29:26 +0000213Historical: Reimer Behrends contributed the idea of using a polynomial-based
Tim Peterseb28ef22001-06-02 05:27:19 +0000214approach, using repeated multiplication by x in GF(2**n) where an irreducible
215polynomial for each table size was chosen such that x was a primitive root.
216Christian Tismer later extended that to use division by x instead, as an
217efficient way to get the high bits of the hash code into play. This scheme
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000218also gave excellent collision statistics, but was more expensive: two
219if-tests were required inside the loop; computing "the next" index took about
220the same number of operations but without as much potential parallelism
221(e.g., computing 5*j can go on at the same time as computing 1+perturb in the
222above, and then shifting perturb can be done while the table index is being
223masked); and the PyDictObject struct required a member to hold the table's
224polynomial. In Tim's experiments the current scheme ran faster, produced
225equally good collision statistics, needed less code & used less memory.
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000226
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000227*/
Tim Petersdea48ec2001-05-22 20:40:22 +0000228
Fred Drake1bff34a2000-08-31 19:31:38 +0000229/* forward declarations */
Victor Stinner742da042016-09-07 17:40:12 -0700230static Py_ssize_t lookdict(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900231 Py_hash_t hash, PyObject **value_addr);
Victor Stinner742da042016-09-07 17:40:12 -0700232static Py_ssize_t lookdict_unicode(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900233 Py_hash_t hash, PyObject **value_addr);
Victor Stinner742da042016-09-07 17:40:12 -0700234static Py_ssize_t
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400235lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900236 Py_hash_t hash, PyObject **value_addr);
Victor Stinner742da042016-09-07 17:40:12 -0700237static Py_ssize_t lookdict_split(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900238 Py_hash_t hash, PyObject **value_addr);
Fred Drake1bff34a2000-08-31 19:31:38 +0000239
Inada Naokid9323a82020-08-07 14:08:55 +0900240static int dictresize(PyDictObject *mp, Py_ssize_t newsize);
Tim Petersdea48ec2001-05-22 20:40:22 +0000241
INADA Naoki2aaf98c2018-09-26 12:59:00 +0900242static PyObject* dict_iter(PyDictObject *dict);
243
Benjamin Peterson3c569292016-09-08 13:16:41 -0700244/*Global counter used to set ma_version_tag field of dictionary.
Victor Stinner3b6a6b42016-09-08 12:51:24 -0700245 * It is incremented each time that a dictionary is created and each
246 * time that a dictionary is modified. */
247static uint64_t pydict_global_version = 0;
248
249#define DICT_NEXT_VERSION() (++pydict_global_version)
250
Serhiy Storchaka1009bf12015-04-03 23:53:51 +0300251#include "clinic/dictobject.c.h"
252
Victor Stinner522691c2020-06-23 16:40:40 +0200253
254static struct _Py_dict_state *
255get_dict_state(void)
256{
257 PyInterpreterState *interp = _PyInterpreterState_GET();
258 return &interp->dict_state;
259}
260
261
Victor Stinnerae00a5a2020-04-29 02:29:20 +0200262void
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200263_PyDict_ClearFreeList(PyThreadState *tstate)
Christian Heimes77c02eb2008-02-09 02:18:51 +0000264{
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200265 struct _Py_dict_state *state = &tstate->interp->dict_state;
266 while (state->numfree) {
267 PyDictObject *op = state->free_list[--state->numfree];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000268 assert(PyDict_CheckExact(op));
269 PyObject_GC_Del(op);
270 }
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200271 while (state->keys_numfree) {
272 PyObject_FREE(state->keys_free_list[--state->keys_numfree]);
Victor Stinner742da042016-09-07 17:40:12 -0700273 }
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200274}
275
276
277void
278_PyDict_Fini(PyThreadState *tstate)
279{
280 _PyDict_ClearFreeList(tstate);
281#ifdef Py_DEBUG
Victor Stinner522691c2020-06-23 16:40:40 +0200282 struct _Py_dict_state *state = get_dict_state();
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200283 state->numfree = -1;
284 state->keys_numfree = -1;
Victor Stinnerb4b53862020-05-05 19:55:29 +0200285#endif
Antoine Pitrou9a812cb2011-11-15 00:00:12 +0100286}
287
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200288
David Malcolm49526f42012-06-22 14:55:41 -0400289/* Print summary info about the state of the optimized allocator */
290void
291_PyDict_DebugMallocStats(FILE *out)
292{
Victor Stinner522691c2020-06-23 16:40:40 +0200293 struct _Py_dict_state *state = get_dict_state();
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200294 _PyDebugAllocatorStats(out, "free PyDictObject",
295 state->numfree, sizeof(PyDictObject));
David Malcolm49526f42012-06-22 14:55:41 -0400296}
297
298
Victor Stinner742da042016-09-07 17:40:12 -0700299#define DK_SIZE(dk) ((dk)->dk_size)
300#if SIZEOF_VOID_P > 4
Victor Stinner58f7c5a2016-09-08 11:37:36 -0700301#define DK_IXSIZE(dk) \
302 (DK_SIZE(dk) <= 0xff ? \
303 1 : DK_SIZE(dk) <= 0xffff ? \
304 2 : DK_SIZE(dk) <= 0xffffffff ? \
Benjamin Peterson3c569292016-09-08 13:16:41 -0700305 4 : sizeof(int64_t))
Victor Stinner742da042016-09-07 17:40:12 -0700306#else
Victor Stinner58f7c5a2016-09-08 11:37:36 -0700307#define DK_IXSIZE(dk) \
308 (DK_SIZE(dk) <= 0xff ? \
309 1 : DK_SIZE(dk) <= 0xffff ? \
Benjamin Peterson3c569292016-09-08 13:16:41 -0700310 2 : sizeof(int32_t))
Victor Stinner742da042016-09-07 17:40:12 -0700311#endif
Victor Stinner58f7c5a2016-09-08 11:37:36 -0700312#define DK_ENTRIES(dk) \
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700313 ((PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[DK_SIZE(dk) * DK_IXSIZE(dk)]))
Victor Stinner742da042016-09-07 17:40:12 -0700314
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400315#define DK_MASK(dk) (((dk)->dk_size)-1)
316#define IS_POWER_OF_2(x) (((x) & (x-1)) == 0)
317
INADA Naokia7576492018-11-14 18:39:27 +0900318static void free_keys_object(PyDictKeysObject *keys);
319
320static inline void
321dictkeys_incref(PyDictKeysObject *dk)
322{
Victor Stinner49932fe2020-02-03 17:55:05 +0100323#ifdef Py_REF_DEBUG
324 _Py_RefTotal++;
325#endif
INADA Naokia7576492018-11-14 18:39:27 +0900326 dk->dk_refcnt++;
327}
328
329static inline void
330dictkeys_decref(PyDictKeysObject *dk)
331{
332 assert(dk->dk_refcnt > 0);
Victor Stinner49932fe2020-02-03 17:55:05 +0100333#ifdef Py_REF_DEBUG
334 _Py_RefTotal--;
335#endif
INADA Naokia7576492018-11-14 18:39:27 +0900336 if (--dk->dk_refcnt == 0) {
337 free_keys_object(dk);
338 }
339}
340
Victor Stinner742da042016-09-07 17:40:12 -0700341/* lookup indices. returns DKIX_EMPTY, DKIX_DUMMY, or ix >=0 */
Benjamin Peterson73222252016-09-08 09:58:47 -0700342static inline Py_ssize_t
Andy Lester62d21c92020-03-25 23:13:01 -0500343dictkeys_get_index(const PyDictKeysObject *keys, Py_ssize_t i)
Victor Stinner742da042016-09-07 17:40:12 -0700344{
345 Py_ssize_t s = DK_SIZE(keys);
Victor Stinner71211e32016-09-08 10:52:46 -0700346 Py_ssize_t ix;
347
Victor Stinner742da042016-09-07 17:40:12 -0700348 if (s <= 0xff) {
Andy Lester62d21c92020-03-25 23:13:01 -0500349 const int8_t *indices = (const int8_t*)(keys->dk_indices);
Victor Stinner208857e2016-09-08 11:35:46 -0700350 ix = indices[i];
Victor Stinner742da042016-09-07 17:40:12 -0700351 }
352 else if (s <= 0xffff) {
Andy Lester62d21c92020-03-25 23:13:01 -0500353 const int16_t *indices = (const int16_t*)(keys->dk_indices);
Victor Stinner208857e2016-09-08 11:35:46 -0700354 ix = indices[i];
Victor Stinner742da042016-09-07 17:40:12 -0700355 }
Benjamin Peterson3c569292016-09-08 13:16:41 -0700356#if SIZEOF_VOID_P > 4
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300357 else if (s > 0xffffffff) {
Andy Lester62d21c92020-03-25 23:13:01 -0500358 const int64_t *indices = (const int64_t*)(keys->dk_indices);
Victor Stinner208857e2016-09-08 11:35:46 -0700359 ix = indices[i];
Victor Stinner742da042016-09-07 17:40:12 -0700360 }
Benjamin Peterson3c569292016-09-08 13:16:41 -0700361#endif
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300362 else {
Andy Lester62d21c92020-03-25 23:13:01 -0500363 const int32_t *indices = (const int32_t*)(keys->dk_indices);
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300364 ix = indices[i];
365 }
Victor Stinner71211e32016-09-08 10:52:46 -0700366 assert(ix >= DKIX_DUMMY);
367 return ix;
Victor Stinner742da042016-09-07 17:40:12 -0700368}
369
370/* write to indices. */
Benjamin Peterson73222252016-09-08 09:58:47 -0700371static inline void
INADA Naokia7576492018-11-14 18:39:27 +0900372dictkeys_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix)
Victor Stinner742da042016-09-07 17:40:12 -0700373{
374 Py_ssize_t s = DK_SIZE(keys);
Victor Stinner71211e32016-09-08 10:52:46 -0700375
376 assert(ix >= DKIX_DUMMY);
377
Victor Stinner742da042016-09-07 17:40:12 -0700378 if (s <= 0xff) {
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700379 int8_t *indices = (int8_t*)(keys->dk_indices);
Victor Stinner71211e32016-09-08 10:52:46 -0700380 assert(ix <= 0x7f);
Victor Stinner208857e2016-09-08 11:35:46 -0700381 indices[i] = (char)ix;
Victor Stinner742da042016-09-07 17:40:12 -0700382 }
383 else if (s <= 0xffff) {
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700384 int16_t *indices = (int16_t*)(keys->dk_indices);
Victor Stinner71211e32016-09-08 10:52:46 -0700385 assert(ix <= 0x7fff);
Victor Stinner208857e2016-09-08 11:35:46 -0700386 indices[i] = (int16_t)ix;
Victor Stinner742da042016-09-07 17:40:12 -0700387 }
Benjamin Peterson3c569292016-09-08 13:16:41 -0700388#if SIZEOF_VOID_P > 4
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300389 else if (s > 0xffffffff) {
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700390 int64_t *indices = (int64_t*)(keys->dk_indices);
Victor Stinner208857e2016-09-08 11:35:46 -0700391 indices[i] = ix;
Victor Stinner742da042016-09-07 17:40:12 -0700392 }
Benjamin Peterson3c569292016-09-08 13:16:41 -0700393#endif
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300394 else {
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700395 int32_t *indices = (int32_t*)(keys->dk_indices);
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300396 assert(ix <= 0x7fffffff);
397 indices[i] = (int32_t)ix;
398 }
Victor Stinner742da042016-09-07 17:40:12 -0700399}
400
401
Antoine Pitroua504a7a2012-06-24 21:03:45 +0200402/* USABLE_FRACTION is the maximum dictionary load.
Victor Stinner742da042016-09-07 17:40:12 -0700403 * Increasing this ratio makes dictionaries more dense resulting in more
404 * collisions. Decreasing it improves sparseness at the expense of spreading
405 * indices over more cache lines and at the cost of total memory consumed.
Antoine Pitroua504a7a2012-06-24 21:03:45 +0200406 *
407 * USABLE_FRACTION must obey the following:
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400408 * (0 < USABLE_FRACTION(n) < n) for all n >= 2
409 *
Victor Stinner742da042016-09-07 17:40:12 -0700410 * USABLE_FRACTION should be quick to calculate.
411 * Fractions around 1/2 to 2/3 seem to work well in practice.
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400412 */
Victor Stinner742da042016-09-07 17:40:12 -0700413#define USABLE_FRACTION(n) (((n) << 1)/3)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400414
Inada Naokid9323a82020-08-07 14:08:55 +0900415/* Find the smallest dk_size >= minsize. */
416static inline Py_ssize_t
417calculate_keysize(Py_ssize_t minsize)
418{
419#if SIZEOF_LONG == SIZEOF_SIZE_T
420 minsize = (minsize | PyDict_MINSIZE) - 1;
421 return 1LL << _Py_bit_length(minsize | (PyDict_MINSIZE-1));
422#elif defined(_MSC_VER)
423 // On 64bit Windows, sizeof(long) == 4.
424 minsize = (minsize | PyDict_MINSIZE) - 1;
425 unsigned long msb;
426 _BitScanReverse64(&msb, (uint64_t)minsize);
427 return 1LL << (msb + 1);
428#else
429 Py_ssize_t size;
430 for (size = PyDict_MINSIZE;
431 size < minsize && size > 0;
432 size <<= 1)
433 ;
434 return size;
435#endif
436}
437
438/* estimate_keysize is reverse function of USABLE_FRACTION.
439 *
Victor Stinner742da042016-09-07 17:40:12 -0700440 * This can be used to reserve enough size to insert n entries without
441 * resizing.
442 */
Inada Naokid9323a82020-08-07 14:08:55 +0900443static inline Py_ssize_t
444estimate_keysize(Py_ssize_t n)
445{
446 return calculate_keysize((n*3 + 1) / 2);
447}
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400448
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400449
Victor Stinnera9f61a52013-07-16 22:17:26 +0200450/* GROWTH_RATE. Growth rate upon hitting maximum load.
INADA Naoki5fbc5112018-04-17 15:53:34 +0900451 * Currently set to used*3.
Victor Stinnera9f61a52013-07-16 22:17:26 +0200452 * This means that dicts double in size when growing without deletions,
Raymond Hettinger36f74aa2013-05-17 03:01:13 -0700453 * but have more head room when the number of deletions is on a par with the
INADA Naoki5fbc5112018-04-17 15:53:34 +0900454 * number of insertions. See also bpo-17563 and bpo-33205.
455 *
Raymond Hettinger36f74aa2013-05-17 03:01:13 -0700456 * GROWTH_RATE was set to used*4 up to version 3.2.
457 * GROWTH_RATE was set to used*2 in version 3.3.0
INADA Naoki5fbc5112018-04-17 15:53:34 +0900458 * GROWTH_RATE was set to used*2 + capacity/2 in 3.4.0-3.6.0.
Antoine Pitroua504a7a2012-06-24 21:03:45 +0200459 */
INADA Naoki5fbc5112018-04-17 15:53:34 +0900460#define GROWTH_RATE(d) ((d)->ma_used*3)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400461
462#define ENSURE_ALLOWS_DELETIONS(d) \
463 if ((d)->ma_keys->dk_lookup == lookdict_unicode_nodummy) { \
464 (d)->ma_keys->dk_lookup = lookdict_unicode; \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400466
467/* This immutable, empty PyDictKeysObject is used for PyDict_Clear()
468 * (which cannot fail and thus can do no allocation).
469 */
470static PyDictKeysObject empty_keys_struct = {
Serhiy Storchaka97932e42016-09-26 23:01:23 +0300471 1, /* dk_refcnt */
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400472 1, /* dk_size */
473 lookdict_split, /* dk_lookup */
474 0, /* dk_usable (immutable) */
Victor Stinner742da042016-09-07 17:40:12 -0700475 0, /* dk_nentries */
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700476 {DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY,
477 DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY}, /* dk_indices */
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400478};
479
480static PyObject *empty_values[1] = { NULL };
481
482#define Py_EMPTY_KEYS &empty_keys_struct
483
Victor Stinner611b0fa2016-09-14 15:02:01 +0200484/* Uncomment to check the dict content in _PyDict_CheckConsistency() */
485/* #define DEBUG_PYDICT */
486
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200487#ifdef DEBUG_PYDICT
488# define ASSERT_CONSISTENT(op) assert(_PyDict_CheckConsistency((PyObject *)(op), 1))
489#else
490# define ASSERT_CONSISTENT(op) assert(_PyDict_CheckConsistency((PyObject *)(op), 0))
491#endif
Victor Stinner611b0fa2016-09-14 15:02:01 +0200492
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200493
494int
495_PyDict_CheckConsistency(PyObject *op, int check_content)
Victor Stinner611b0fa2016-09-14 15:02:01 +0200496{
Victor Stinner68762572019-10-07 18:42:01 +0200497#define CHECK(expr) \
498 do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0)
499
500 assert(op != NULL);
501 CHECK(PyDict_Check(op));
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200502 PyDictObject *mp = (PyDictObject *)op;
Victor Stinner50fe3f82018-10-26 18:47:15 +0200503
Victor Stinner611b0fa2016-09-14 15:02:01 +0200504 PyDictKeysObject *keys = mp->ma_keys;
505 int splitted = _PyDict_HasSplitTable(mp);
506 Py_ssize_t usable = USABLE_FRACTION(keys->dk_size);
Victor Stinner611b0fa2016-09-14 15:02:01 +0200507
Victor Stinner68762572019-10-07 18:42:01 +0200508 CHECK(0 <= mp->ma_used && mp->ma_used <= usable);
509 CHECK(IS_POWER_OF_2(keys->dk_size));
510 CHECK(0 <= keys->dk_usable && keys->dk_usable <= usable);
511 CHECK(0 <= keys->dk_nentries && keys->dk_nentries <= usable);
512 CHECK(keys->dk_usable + keys->dk_nentries <= usable);
Victor Stinner611b0fa2016-09-14 15:02:01 +0200513
514 if (!splitted) {
515 /* combined table */
Victor Stinner68762572019-10-07 18:42:01 +0200516 CHECK(keys->dk_refcnt == 1);
Victor Stinner611b0fa2016-09-14 15:02:01 +0200517 }
518
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200519 if (check_content) {
520 PyDictKeyEntry *entries = DK_ENTRIES(keys);
521 Py_ssize_t i;
Victor Stinner611b0fa2016-09-14 15:02:01 +0200522
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200523 for (i=0; i < keys->dk_size; i++) {
524 Py_ssize_t ix = dictkeys_get_index(keys, i);
Victor Stinner68762572019-10-07 18:42:01 +0200525 CHECK(DKIX_DUMMY <= ix && ix <= usable);
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200526 }
Victor Stinner611b0fa2016-09-14 15:02:01 +0200527
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200528 for (i=0; i < usable; i++) {
529 PyDictKeyEntry *entry = &entries[i];
530 PyObject *key = entry->me_key;
531
532 if (key != NULL) {
533 if (PyUnicode_CheckExact(key)) {
534 Py_hash_t hash = ((PyASCIIObject *)key)->hash;
Victor Stinner68762572019-10-07 18:42:01 +0200535 CHECK(hash != -1);
536 CHECK(entry->me_hash == hash);
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200537 }
538 else {
539 /* test_dict fails if PyObject_Hash() is called again */
Victor Stinner68762572019-10-07 18:42:01 +0200540 CHECK(entry->me_hash != -1);
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200541 }
542 if (!splitted) {
Victor Stinner68762572019-10-07 18:42:01 +0200543 CHECK(entry->me_value != NULL);
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200544 }
Victor Stinner611b0fa2016-09-14 15:02:01 +0200545 }
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200546
547 if (splitted) {
Victor Stinner68762572019-10-07 18:42:01 +0200548 CHECK(entry->me_value == NULL);
Victor Stinner611b0fa2016-09-14 15:02:01 +0200549 }
550 }
551
552 if (splitted) {
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200553 /* splitted table */
554 for (i=0; i < mp->ma_used; i++) {
Victor Stinner68762572019-10-07 18:42:01 +0200555 CHECK(mp->ma_values[i] != NULL);
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200556 }
Victor Stinner611b0fa2016-09-14 15:02:01 +0200557 }
558 }
Victor Stinner611b0fa2016-09-14 15:02:01 +0200559 return 1;
Victor Stinner68762572019-10-07 18:42:01 +0200560
561#undef CHECK
Victor Stinner611b0fa2016-09-14 15:02:01 +0200562}
Victor Stinner611b0fa2016-09-14 15:02:01 +0200563
564
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200565static PyDictKeysObject*
566new_keys_object(Py_ssize_t size)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400567{
568 PyDictKeysObject *dk;
Victor Stinner742da042016-09-07 17:40:12 -0700569 Py_ssize_t es, usable;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400570
Victor Stinner742da042016-09-07 17:40:12 -0700571 assert(size >= PyDict_MINSIZE);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400572 assert(IS_POWER_OF_2(size));
Victor Stinner742da042016-09-07 17:40:12 -0700573
574 usable = USABLE_FRACTION(size);
575 if (size <= 0xff) {
576 es = 1;
577 }
578 else if (size <= 0xffff) {
579 es = 2;
580 }
581#if SIZEOF_VOID_P > 4
582 else if (size <= 0xffffffff) {
583 es = 4;
584 }
585#endif
586 else {
587 es = sizeof(Py_ssize_t);
588 }
589
Victor Stinner522691c2020-06-23 16:40:40 +0200590 struct _Py_dict_state *state = get_dict_state();
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200591#ifdef Py_DEBUG
592 // new_keys_object() must not be called after _PyDict_Fini()
593 assert(state->keys_numfree != -1);
594#endif
595 if (size == PyDict_MINSIZE && state->keys_numfree > 0) {
596 dk = state->keys_free_list[--state->keys_numfree];
Victor Stinner742da042016-09-07 17:40:12 -0700597 }
Victor Stinnerb4b53862020-05-05 19:55:29 +0200598 else
Victor Stinnerb4b53862020-05-05 19:55:29 +0200599 {
Victor Stinner98ee9d52016-09-08 09:33:56 -0700600 dk = PyObject_MALLOC(sizeof(PyDictKeysObject)
Victor Stinner98ee9d52016-09-08 09:33:56 -0700601 + es * size
602 + sizeof(PyDictKeyEntry) * usable);
Victor Stinner742da042016-09-07 17:40:12 -0700603 if (dk == NULL) {
604 PyErr_NoMemory();
605 return NULL;
606 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400607 }
Victor Stinner49932fe2020-02-03 17:55:05 +0100608#ifdef Py_REF_DEBUG
609 _Py_RefTotal++;
610#endif
INADA Naokia7576492018-11-14 18:39:27 +0900611 dk->dk_refcnt = 1;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400612 dk->dk_size = size;
Victor Stinner742da042016-09-07 17:40:12 -0700613 dk->dk_usable = usable;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400614 dk->dk_lookup = lookdict_unicode_nodummy;
Victor Stinner742da042016-09-07 17:40:12 -0700615 dk->dk_nentries = 0;
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700616 memset(&dk->dk_indices[0], 0xff, es * size);
Victor Stinner742da042016-09-07 17:40:12 -0700617 memset(DK_ENTRIES(dk), 0, sizeof(PyDictKeyEntry) * usable);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400618 return dk;
619}
620
621static void
622free_keys_object(PyDictKeysObject *keys)
623{
Victor Stinner742da042016-09-07 17:40:12 -0700624 PyDictKeyEntry *entries = DK_ENTRIES(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400625 Py_ssize_t i, n;
Victor Stinner742da042016-09-07 17:40:12 -0700626 for (i = 0, n = keys->dk_nentries; i < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400627 Py_XDECREF(entries[i].me_key);
628 Py_XDECREF(entries[i].me_value);
629 }
Victor Stinner522691c2020-06-23 16:40:40 +0200630 struct _Py_dict_state *state = get_dict_state();
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200631#ifdef Py_DEBUG
632 // free_keys_object() must not be called after _PyDict_Fini()
633 assert(state->keys_numfree != -1);
634#endif
635 if (keys->dk_size == PyDict_MINSIZE && state->keys_numfree < PyDict_MAXFREELIST) {
636 state->keys_free_list[state->keys_numfree++] = keys;
Victor Stinner742da042016-09-07 17:40:12 -0700637 return;
638 }
Raymond Hettingerce5179f2016-01-31 08:56:21 -0800639 PyObject_FREE(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400640}
641
642#define new_values(size) PyMem_NEW(PyObject *, size)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400643#define free_values(values) PyMem_FREE(values)
644
645/* Consumes a reference to the keys object */
646static PyObject *
647new_dict(PyDictKeysObject *keys, PyObject **values)
648{
649 PyDictObject *mp;
Victor Stinnerc9b7f512013-07-08 22:19:20 +0200650 assert(keys != NULL);
Victor Stinner522691c2020-06-23 16:40:40 +0200651 struct _Py_dict_state *state = get_dict_state();
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200652#ifdef Py_DEBUG
653 // new_dict() must not be called after _PyDict_Fini()
654 assert(state->numfree != -1);
655#endif
656 if (state->numfree) {
657 mp = state->free_list[--state->numfree];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 assert (mp != NULL);
Dong-hee Na1b55b652020-02-17 19:09:15 +0900659 assert (Py_IS_TYPE(mp, &PyDict_Type));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 _Py_NewReference((PyObject *)mp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000661 }
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200662 else {
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400663 mp = PyObject_GC_New(PyDictObject, &PyDict_Type);
664 if (mp == NULL) {
INADA Naokia7576492018-11-14 18:39:27 +0900665 dictkeys_decref(keys);
Zackery Spytz3d07c1e2019-03-23 20:23:29 -0600666 if (values != empty_values) {
667 free_values(values);
668 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400669 return NULL;
670 }
671 }
672 mp->ma_keys = keys;
673 mp->ma_values = values;
674 mp->ma_used = 0;
Victor Stinner3b6a6b42016-09-08 12:51:24 -0700675 mp->ma_version_tag = DICT_NEXT_VERSION();
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200676 ASSERT_CONSISTENT(mp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 return (PyObject *)mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000678}
679
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400680/* Consumes a reference to the keys object */
681static PyObject *
682new_dict_with_shared_keys(PyDictKeysObject *keys)
683{
684 PyObject **values;
685 Py_ssize_t i, size;
686
Victor Stinner742da042016-09-07 17:40:12 -0700687 size = USABLE_FRACTION(DK_SIZE(keys));
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400688 values = new_values(size);
689 if (values == NULL) {
INADA Naokia7576492018-11-14 18:39:27 +0900690 dictkeys_decref(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400691 return PyErr_NoMemory();
692 }
693 for (i = 0; i < size; i++) {
694 values[i] = NULL;
695 }
696 return new_dict(keys, values);
697}
698
Yury Selivanovb0a7a032018-01-22 11:54:41 -0500699
Inada Naokidb6d9a52020-08-04 11:08:06 +0900700static PyDictKeysObject *
701clone_combined_dict_keys(PyDictObject *orig)
Yury Selivanovb0a7a032018-01-22 11:54:41 -0500702{
Inada Naokidb6d9a52020-08-04 11:08:06 +0900703 assert(PyDict_Check(orig));
704 assert(Py_TYPE(orig)->tp_iter == (getiterfunc)dict_iter);
Yury Selivanovb0a7a032018-01-22 11:54:41 -0500705 assert(orig->ma_values == NULL);
706 assert(orig->ma_keys->dk_refcnt == 1);
707
708 Py_ssize_t keys_size = _PyDict_KeysSize(orig->ma_keys);
709 PyDictKeysObject *keys = PyObject_Malloc(keys_size);
710 if (keys == NULL) {
711 PyErr_NoMemory();
712 return NULL;
713 }
714
715 memcpy(keys, orig->ma_keys, keys_size);
716
717 /* After copying key/value pairs, we need to incref all
718 keys and values and they are about to be co-owned by a
719 new dict object. */
720 PyDictKeyEntry *ep0 = DK_ENTRIES(keys);
721 Py_ssize_t n = keys->dk_nentries;
722 for (Py_ssize_t i = 0; i < n; i++) {
723 PyDictKeyEntry *entry = &ep0[i];
724 PyObject *value = entry->me_value;
725 if (value != NULL) {
726 Py_INCREF(value);
727 Py_INCREF(entry->me_key);
728 }
729 }
730
Yury Selivanov0b752282018-07-06 12:20:07 -0400731 /* Since we copied the keys table we now have an extra reference
Victor Stinner49932fe2020-02-03 17:55:05 +0100732 in the system. Manually call increment _Py_RefTotal to signal that
INADA Naokia7576492018-11-14 18:39:27 +0900733 we have it now; calling dictkeys_incref would be an error as
Yury Selivanov0b752282018-07-06 12:20:07 -0400734 keys->dk_refcnt is already set to 1 (after memcpy). */
Victor Stinner49932fe2020-02-03 17:55:05 +0100735#ifdef Py_REF_DEBUG
736 _Py_RefTotal++;
737#endif
Inada Naokidb6d9a52020-08-04 11:08:06 +0900738 return keys;
Yury Selivanovb0a7a032018-01-22 11:54:41 -0500739}
740
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400741PyObject *
742PyDict_New(void)
743{
Inada Naokif2a18672019-03-12 17:25:44 +0900744 dictkeys_incref(Py_EMPTY_KEYS);
745 return new_dict(Py_EMPTY_KEYS, empty_values);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400746}
747
Victor Stinner742da042016-09-07 17:40:12 -0700748/* Search index of hash table from offset of entry table */
749static Py_ssize_t
750lookdict_index(PyDictKeysObject *k, Py_hash_t hash, Py_ssize_t index)
751{
Victor Stinner742da042016-09-07 17:40:12 -0700752 size_t mask = DK_MASK(k);
INADA Naoki073ae482017-06-23 15:22:50 +0900753 size_t perturb = (size_t)hash;
754 size_t i = (size_t)hash & mask;
Victor Stinner742da042016-09-07 17:40:12 -0700755
INADA Naoki073ae482017-06-23 15:22:50 +0900756 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900757 Py_ssize_t ix = dictkeys_get_index(k, i);
Victor Stinner742da042016-09-07 17:40:12 -0700758 if (ix == index) {
759 return i;
760 }
761 if (ix == DKIX_EMPTY) {
762 return DKIX_EMPTY;
763 }
INADA Naoki073ae482017-06-23 15:22:50 +0900764 perturb >>= PERTURB_SHIFT;
765 i = mask & (i*5 + perturb + 1);
Victor Stinner742da042016-09-07 17:40:12 -0700766 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700767 Py_UNREACHABLE();
Victor Stinner742da042016-09-07 17:40:12 -0700768}
769
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000770/*
771The basic lookup function used by all operations.
Guido van Rossum16e93a81997-01-28 00:00:11 +0000772This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000773Open addressing is preferred over chaining since the link overhead for
774chaining would be substantial (100% with typical malloc overhead).
775
Tim Peterseb28ef22001-06-02 05:27:19 +0000776The initial probe index is computed as hash mod the table size. Subsequent
777probe indices are computed as explained earlier.
Guido van Rossum2bc13791999-03-24 19:06:42 +0000778
779All arithmetic on hash should ignore overflow.
Guido van Rossum16e93a81997-01-28 00:00:11 +0000780
Guido van Rossumdc5f6b22006-08-24 21:29:26 +0000781The details in this version are due to Tim Peters, building on many past
Tim Peterseb28ef22001-06-02 05:27:19 +0000782contributions by Reimer Behrends, Jyrki Alakuijala, Vladimir Marangozov and
Guido van Rossumdc5f6b22006-08-24 21:29:26 +0000783Christian Tismer.
Fred Drake1bff34a2000-08-31 19:31:38 +0000784
Victor Stinner742da042016-09-07 17:40:12 -0700785lookdict() is general-purpose, and may return DKIX_ERROR if (and only if) a
Victor Stinnera4348cc2016-09-08 12:01:25 -0700786comparison raises an exception.
Guido van Rossum89d8c602007-09-18 17:26:56 +0000787lookdict_unicode() below is specialized to string keys, comparison of which can
INADA Naoki1b8df102017-02-20 22:48:10 +0900788never raise an exception; that function can never return DKIX_ERROR when key
789is string. Otherwise, it falls back to lookdict().
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400790lookdict_unicode_nodummy is further specialized for string keys that cannot be
791the <dummy> value.
INADA Naoki778928b2017-08-03 23:45:15 +0900792For both, when the key isn't found a DKIX_EMPTY is returned.
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000793*/
Victor Stinnerc7a8f672016-11-15 15:13:40 +0100794static Py_ssize_t _Py_HOT_FUNCTION
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400795lookdict(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900796 Py_hash_t hash, PyObject **value_addr)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000797{
INADA Naoki778928b2017-08-03 23:45:15 +0900798 size_t i, mask, perturb;
Victor Stinner742da042016-09-07 17:40:12 -0700799 PyDictKeysObject *dk;
INADA Naoki778928b2017-08-03 23:45:15 +0900800 PyDictKeyEntry *ep0;
Tim Peterseb28ef22001-06-02 05:27:19 +0000801
Antoine Pitrou9a234902012-05-13 20:48:01 +0200802top:
Victor Stinner742da042016-09-07 17:40:12 -0700803 dk = mp->ma_keys;
Victor Stinner742da042016-09-07 17:40:12 -0700804 ep0 = DK_ENTRIES(dk);
INADA Naoki778928b2017-08-03 23:45:15 +0900805 mask = DK_MASK(dk);
806 perturb = hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000807 i = (size_t)hash & mask;
Victor Stinner742da042016-09-07 17:40:12 -0700808
INADA Naoki778928b2017-08-03 23:45:15 +0900809 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900810 Py_ssize_t ix = dictkeys_get_index(dk, i);
Victor Stinner742da042016-09-07 17:40:12 -0700811 if (ix == DKIX_EMPTY) {
Victor Stinner742da042016-09-07 17:40:12 -0700812 *value_addr = NULL;
813 return ix;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400814 }
INADA Naoki778928b2017-08-03 23:45:15 +0900815 if (ix >= 0) {
816 PyDictKeyEntry *ep = &ep0[ix];
817 assert(ep->me_key != NULL);
818 if (ep->me_key == key) {
819 *value_addr = ep->me_value;
820 return ix;
Victor Stinner742da042016-09-07 17:40:12 -0700821 }
INADA Naoki778928b2017-08-03 23:45:15 +0900822 if (ep->me_hash == hash) {
823 PyObject *startkey = ep->me_key;
824 Py_INCREF(startkey);
825 int cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
826 Py_DECREF(startkey);
827 if (cmp < 0) {
828 *value_addr = NULL;
829 return DKIX_ERROR;
830 }
831 if (dk == mp->ma_keys && ep->me_key == startkey) {
832 if (cmp > 0) {
833 *value_addr = ep->me_value;
834 return ix;
Victor Stinner742da042016-09-07 17:40:12 -0700835 }
INADA Naoki778928b2017-08-03 23:45:15 +0900836 }
837 else {
838 /* The dict was mutated, restart */
839 goto top;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400840 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000842 }
INADA Naoki778928b2017-08-03 23:45:15 +0900843 perturb >>= PERTURB_SHIFT;
844 i = (i*5 + perturb + 1) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000845 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700846 Py_UNREACHABLE();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000847}
848
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400849/* Specialized version for string-only keys */
Victor Stinnerc7a8f672016-11-15 15:13:40 +0100850static Py_ssize_t _Py_HOT_FUNCTION
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400851lookdict_unicode(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900852 Py_hash_t hash, PyObject **value_addr)
Fred Drake1bff34a2000-08-31 19:31:38 +0000853{
Victor Stinner742da042016-09-07 17:40:12 -0700854 assert(mp->ma_values == NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000855 /* Make sure this function doesn't have to handle non-unicode keys,
856 including subclasses of str; e.g., one reason to subclass
857 unicodes is to override __eq__, and for speed we don't cater to
858 that here. */
859 if (!PyUnicode_CheckExact(key)) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400860 mp->ma_keys->dk_lookup = lookdict;
INADA Naoki778928b2017-08-03 23:45:15 +0900861 return lookdict(mp, key, hash, value_addr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000862 }
Tim Peters15d49292001-05-27 07:39:22 +0000863
INADA Naoki778928b2017-08-03 23:45:15 +0900864 PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
865 size_t mask = DK_MASK(mp->ma_keys);
866 size_t perturb = (size_t)hash;
867 size_t i = (size_t)hash & mask;
868
869 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900870 Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
Victor Stinner742da042016-09-07 17:40:12 -0700871 if (ix == DKIX_EMPTY) {
Victor Stinner742da042016-09-07 17:40:12 -0700872 *value_addr = NULL;
873 return DKIX_EMPTY;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400874 }
INADA Naoki778928b2017-08-03 23:45:15 +0900875 if (ix >= 0) {
876 PyDictKeyEntry *ep = &ep0[ix];
877 assert(ep->me_key != NULL);
878 assert(PyUnicode_CheckExact(ep->me_key));
879 if (ep->me_key == key ||
880 (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
881 *value_addr = ep->me_value;
882 return ix;
Victor Stinner742da042016-09-07 17:40:12 -0700883 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400884 }
INADA Naoki778928b2017-08-03 23:45:15 +0900885 perturb >>= PERTURB_SHIFT;
886 i = mask & (i*5 + perturb + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000887 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700888 Py_UNREACHABLE();
Fred Drake1bff34a2000-08-31 19:31:38 +0000889}
890
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400891/* Faster version of lookdict_unicode when it is known that no <dummy> keys
892 * will be present. */
Victor Stinnerc7a8f672016-11-15 15:13:40 +0100893static Py_ssize_t _Py_HOT_FUNCTION
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400894lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900895 Py_hash_t hash, PyObject **value_addr)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400896{
Victor Stinner742da042016-09-07 17:40:12 -0700897 assert(mp->ma_values == NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400898 /* Make sure this function doesn't have to handle non-unicode keys,
899 including subclasses of str; e.g., one reason to subclass
900 unicodes is to override __eq__, and for speed we don't cater to
901 that here. */
902 if (!PyUnicode_CheckExact(key)) {
903 mp->ma_keys->dk_lookup = lookdict;
INADA Naoki778928b2017-08-03 23:45:15 +0900904 return lookdict(mp, key, hash, value_addr);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400905 }
INADA Naoki778928b2017-08-03 23:45:15 +0900906
907 PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
908 size_t mask = DK_MASK(mp->ma_keys);
909 size_t perturb = (size_t)hash;
910 size_t i = (size_t)hash & mask;
911
912 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900913 Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
Victor Stinner742da042016-09-07 17:40:12 -0700914 assert (ix != DKIX_DUMMY);
915 if (ix == DKIX_EMPTY) {
Victor Stinner742da042016-09-07 17:40:12 -0700916 *value_addr = NULL;
917 return DKIX_EMPTY;
918 }
INADA Naoki778928b2017-08-03 23:45:15 +0900919 PyDictKeyEntry *ep = &ep0[ix];
920 assert(ep->me_key != NULL);
921 assert(PyUnicode_CheckExact(ep->me_key));
Victor Stinner742da042016-09-07 17:40:12 -0700922 if (ep->me_key == key ||
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400923 (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
INADA Naokiba609772016-12-07 20:41:42 +0900924 *value_addr = ep->me_value;
Victor Stinner742da042016-09-07 17:40:12 -0700925 return ix;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400926 }
INADA Naoki778928b2017-08-03 23:45:15 +0900927 perturb >>= PERTURB_SHIFT;
928 i = mask & (i*5 + perturb + 1);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400929 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700930 Py_UNREACHABLE();
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400931}
932
933/* Version of lookdict for split tables.
934 * All split tables and only split tables use this lookup function.
935 * Split tables only contain unicode keys and no dummy keys,
936 * so algorithm is the same as lookdict_unicode_nodummy.
937 */
Victor Stinnerc7a8f672016-11-15 15:13:40 +0100938static Py_ssize_t _Py_HOT_FUNCTION
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400939lookdict_split(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900940 Py_hash_t hash, PyObject **value_addr)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400941{
Victor Stinner742da042016-09-07 17:40:12 -0700942 /* mp must split table */
943 assert(mp->ma_values != NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400944 if (!PyUnicode_CheckExact(key)) {
INADA Naoki778928b2017-08-03 23:45:15 +0900945 Py_ssize_t ix = lookdict(mp, key, hash, value_addr);
Victor Stinner742da042016-09-07 17:40:12 -0700946 if (ix >= 0) {
INADA Naokiba609772016-12-07 20:41:42 +0900947 *value_addr = mp->ma_values[ix];
Victor Stinner742da042016-09-07 17:40:12 -0700948 }
949 return ix;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400950 }
Victor Stinner742da042016-09-07 17:40:12 -0700951
INADA Naoki778928b2017-08-03 23:45:15 +0900952 PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
953 size_t mask = DK_MASK(mp->ma_keys);
954 size_t perturb = (size_t)hash;
955 size_t i = (size_t)hash & mask;
956
957 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900958 Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
INADA Naoki778928b2017-08-03 23:45:15 +0900959 assert (ix != DKIX_DUMMY);
Victor Stinner742da042016-09-07 17:40:12 -0700960 if (ix == DKIX_EMPTY) {
Victor Stinner742da042016-09-07 17:40:12 -0700961 *value_addr = NULL;
962 return DKIX_EMPTY;
963 }
INADA Naoki778928b2017-08-03 23:45:15 +0900964 PyDictKeyEntry *ep = &ep0[ix];
965 assert(ep->me_key != NULL);
966 assert(PyUnicode_CheckExact(ep->me_key));
Victor Stinner742da042016-09-07 17:40:12 -0700967 if (ep->me_key == key ||
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400968 (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
INADA Naokiba609772016-12-07 20:41:42 +0900969 *value_addr = mp->ma_values[ix];
Victor Stinner742da042016-09-07 17:40:12 -0700970 return ix;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400971 }
INADA Naoki778928b2017-08-03 23:45:15 +0900972 perturb >>= PERTURB_SHIFT;
973 i = mask & (i*5 + perturb + 1);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400974 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700975 Py_UNREACHABLE();
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400976}
977
Benjamin Petersonfb886362010-04-24 18:21:17 +0000978int
979_PyDict_HasOnlyStringKeys(PyObject *dict)
980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 Py_ssize_t pos = 0;
982 PyObject *key, *value;
Benjamin Petersonf6096542010-11-17 22:33:12 +0000983 assert(PyDict_Check(dict));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 /* Shortcut */
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400985 if (((PyDictObject *)dict)->ma_keys->dk_lookup != lookdict)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000986 return 1;
987 while (PyDict_Next(dict, &pos, &key, &value))
988 if (!PyUnicode_Check(key))
989 return 0;
990 return 1;
Benjamin Petersonfb886362010-04-24 18:21:17 +0000991}
992
Antoine Pitrou3a652b12009-03-23 18:52:06 +0000993#define MAINTAIN_TRACKING(mp, key, value) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000994 do { \
995 if (!_PyObject_GC_IS_TRACKED(mp)) { \
996 if (_PyObject_GC_MAY_BE_TRACKED(key) || \
997 _PyObject_GC_MAY_BE_TRACKED(value)) { \
998 _PyObject_GC_TRACK(mp); \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 } \
1000 } \
1001 } while(0)
Antoine Pitrou3a652b12009-03-23 18:52:06 +00001002
1003void
1004_PyDict_MaybeUntrack(PyObject *op)
1005{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 PyDictObject *mp;
1007 PyObject *value;
Victor Stinner742da042016-09-07 17:40:12 -07001008 Py_ssize_t i, numentries;
1009 PyDictKeyEntry *ep0;
Antoine Pitrou3a652b12009-03-23 18:52:06 +00001010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011 if (!PyDict_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op))
1012 return;
1013
1014 mp = (PyDictObject *) op;
Victor Stinner742da042016-09-07 17:40:12 -07001015 ep0 = DK_ENTRIES(mp->ma_keys);
1016 numentries = mp->ma_keys->dk_nentries;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001017 if (_PyDict_HasSplitTable(mp)) {
Victor Stinner742da042016-09-07 17:40:12 -07001018 for (i = 0; i < numentries; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001019 if ((value = mp->ma_values[i]) == NULL)
1020 continue;
1021 if (_PyObject_GC_MAY_BE_TRACKED(value)) {
Victor Stinner742da042016-09-07 17:40:12 -07001022 assert(!_PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001023 return;
1024 }
1025 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001027 else {
Victor Stinner742da042016-09-07 17:40:12 -07001028 for (i = 0; i < numentries; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001029 if ((value = ep0[i].me_value) == NULL)
1030 continue;
1031 if (_PyObject_GC_MAY_BE_TRACKED(value) ||
1032 _PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key))
1033 return;
1034 }
1035 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 _PyObject_GC_UNTRACK(op);
Antoine Pitrou3a652b12009-03-23 18:52:06 +00001037}
1038
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001039/* Internal function to find slot for an item from its hash
Victor Stinner3c336c52016-09-12 14:17:40 +02001040 when it is known that the key is not present in the dict.
1041
1042 The dict must be combined. */
INADA Naokiba609772016-12-07 20:41:42 +09001043static Py_ssize_t
INADA Naoki778928b2017-08-03 23:45:15 +09001044find_empty_slot(PyDictKeysObject *keys, Py_hash_t hash)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001045{
INADA Naoki778928b2017-08-03 23:45:15 +09001046 assert(keys != NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001047
INADA Naoki778928b2017-08-03 23:45:15 +09001048 const size_t mask = DK_MASK(keys);
1049 size_t i = hash & mask;
INADA Naokia7576492018-11-14 18:39:27 +09001050 Py_ssize_t ix = dictkeys_get_index(keys, i);
INADA Naoki778928b2017-08-03 23:45:15 +09001051 for (size_t perturb = hash; ix >= 0;) {
INADA Naoki267941c2016-10-06 15:19:07 +09001052 perturb >>= PERTURB_SHIFT;
INADA Naoki778928b2017-08-03 23:45:15 +09001053 i = (i*5 + perturb + 1) & mask;
INADA Naokia7576492018-11-14 18:39:27 +09001054 ix = dictkeys_get_index(keys, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 }
INADA Naoki778928b2017-08-03 23:45:15 +09001056 return i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001057}
1058
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001059static int
1060insertion_resize(PyDictObject *mp)
1061{
Inada Naokid9323a82020-08-07 14:08:55 +09001062 return dictresize(mp, calculate_keysize(GROWTH_RATE(mp)));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001063}
Antoine Pitroue965d972012-02-27 00:45:12 +01001064
1065/*
1066Internal routine to insert a new item into the table.
1067Used both by the internal resize routine and by the public insert routine.
Antoine Pitroue965d972012-02-27 00:45:12 +01001068Returns -1 if an error occurred, or 0 on success.
1069*/
1070static int
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001071insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
Antoine Pitroue965d972012-02-27 00:45:12 +01001072{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001073 PyObject *old_value;
INADA Naokiba609772016-12-07 20:41:42 +09001074 PyDictKeyEntry *ep;
Antoine Pitroue965d972012-02-27 00:45:12 +01001075
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001076 Py_INCREF(key);
1077 Py_INCREF(value);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001078 if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) {
1079 if (insertion_resize(mp) < 0)
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001080 goto Fail;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001081 }
1082
INADA Naoki778928b2017-08-03 23:45:15 +09001083 Py_ssize_t ix = mp->ma_keys->dk_lookup(mp, key, hash, &old_value);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001084 if (ix == DKIX_ERROR)
1085 goto Fail;
Victor Stinner742da042016-09-07 17:40:12 -07001086
Antoine Pitroud6967322014-10-18 00:35:00 +02001087 assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001088 MAINTAIN_TRACKING(mp, key, value);
Victor Stinner742da042016-09-07 17:40:12 -07001089
1090 /* When insertion order is different from shared key, we can't share
1091 * the key anymore. Convert this instance to combine table.
1092 */
1093 if (_PyDict_HasSplitTable(mp) &&
INADA Naokiba609772016-12-07 20:41:42 +09001094 ((ix >= 0 && old_value == NULL && mp->ma_used != ix) ||
Victor Stinner742da042016-09-07 17:40:12 -07001095 (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) {
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001096 if (insertion_resize(mp) < 0)
1097 goto Fail;
Victor Stinner742da042016-09-07 17:40:12 -07001098 ix = DKIX_EMPTY;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001099 }
Victor Stinner742da042016-09-07 17:40:12 -07001100
1101 if (ix == DKIX_EMPTY) {
1102 /* Insert into new slot. */
INADA Naokiba609772016-12-07 20:41:42 +09001103 assert(old_value == NULL);
Victor Stinner742da042016-09-07 17:40:12 -07001104 if (mp->ma_keys->dk_usable <= 0) {
1105 /* Need to resize. */
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001106 if (insertion_resize(mp) < 0)
1107 goto Fail;
Victor Stinner742da042016-09-07 17:40:12 -07001108 }
INADA Naoki778928b2017-08-03 23:45:15 +09001109 Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash);
INADA Naokiba609772016-12-07 20:41:42 +09001110 ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries];
INADA Naokia7576492018-11-14 18:39:27 +09001111 dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
Victor Stinner742da042016-09-07 17:40:12 -07001112 ep->me_key = key;
1113 ep->me_hash = hash;
1114 if (mp->ma_values) {
1115 assert (mp->ma_values[mp->ma_keys->dk_nentries] == NULL);
1116 mp->ma_values[mp->ma_keys->dk_nentries] = value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001117 }
1118 else {
Victor Stinner742da042016-09-07 17:40:12 -07001119 ep->me_value = value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001120 }
1121 mp->ma_used++;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07001122 mp->ma_version_tag = DICT_NEXT_VERSION();
Victor Stinner742da042016-09-07 17:40:12 -07001123 mp->ma_keys->dk_usable--;
1124 mp->ma_keys->dk_nentries++;
1125 assert(mp->ma_keys->dk_usable >= 0);
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001126 ASSERT_CONSISTENT(mp);
Victor Stinner742da042016-09-07 17:40:12 -07001127 return 0;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001128 }
Victor Stinner742da042016-09-07 17:40:12 -07001129
Inada Naoki91234a12019-06-03 21:30:58 +09001130 if (old_value != value) {
1131 if (_PyDict_HasSplitTable(mp)) {
1132 mp->ma_values[ix] = value;
1133 if (old_value == NULL) {
1134 /* pending state */
1135 assert(ix == mp->ma_used);
1136 mp->ma_used++;
1137 }
INADA Naokiba609772016-12-07 20:41:42 +09001138 }
Inada Naoki91234a12019-06-03 21:30:58 +09001139 else {
1140 assert(old_value != NULL);
1141 DK_ENTRIES(mp->ma_keys)[ix].me_value = value;
1142 }
1143 mp->ma_version_tag = DICT_NEXT_VERSION();
INADA Naokiba609772016-12-07 20:41:42 +09001144 }
INADA Naokiba609772016-12-07 20:41:42 +09001145 Py_XDECREF(old_value); /* which **CAN** re-enter (see issue #22653) */
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001146 ASSERT_CONSISTENT(mp);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001147 Py_DECREF(key);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001148 return 0;
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001149
1150Fail:
1151 Py_DECREF(value);
1152 Py_DECREF(key);
1153 return -1;
Antoine Pitroue965d972012-02-27 00:45:12 +01001154}
1155
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001156// Same to insertdict but specialized for ma_keys = Py_EMPTY_KEYS.
1157static int
1158insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash,
1159 PyObject *value)
1160{
1161 assert(mp->ma_keys == Py_EMPTY_KEYS);
1162
1163 PyDictKeysObject *newkeys = new_keys_object(PyDict_MINSIZE);
1164 if (newkeys == NULL) {
1165 return -1;
1166 }
1167 if (!PyUnicode_CheckExact(key)) {
1168 newkeys->dk_lookup = lookdict;
1169 }
1170 dictkeys_decref(Py_EMPTY_KEYS);
1171 mp->ma_keys = newkeys;
1172 mp->ma_values = NULL;
1173
1174 Py_INCREF(key);
1175 Py_INCREF(value);
1176 MAINTAIN_TRACKING(mp, key, value);
1177
1178 size_t hashpos = (size_t)hash & (PyDict_MINSIZE-1);
Dong-hee Nac39d1dd2019-10-11 17:43:11 +09001179 PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys);
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001180 dictkeys_set_index(mp->ma_keys, hashpos, 0);
1181 ep->me_key = key;
1182 ep->me_hash = hash;
1183 ep->me_value = value;
1184 mp->ma_used++;
1185 mp->ma_version_tag = DICT_NEXT_VERSION();
1186 mp->ma_keys->dk_usable--;
1187 mp->ma_keys->dk_nentries++;
1188 return 0;
1189}
1190
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001191/*
luzpaza5293b42017-11-05 07:37:50 -06001192Internal routine used by dictresize() to build a hashtable of entries.
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001193*/
1194static void
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001195build_indices(PyDictKeysObject *keys, PyDictKeyEntry *ep, Py_ssize_t n)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001196{
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001197 size_t mask = (size_t)DK_SIZE(keys) - 1;
1198 for (Py_ssize_t ix = 0; ix != n; ix++, ep++) {
1199 Py_hash_t hash = ep->me_hash;
1200 size_t i = hash & mask;
INADA Naokia7576492018-11-14 18:39:27 +09001201 for (size_t perturb = hash; dictkeys_get_index(keys, i) != DKIX_EMPTY;) {
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001202 perturb >>= PERTURB_SHIFT;
INADA Naoki870c2862017-06-24 09:03:19 +09001203 i = mask & (i*5 + perturb + 1);
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001204 }
INADA Naokia7576492018-11-14 18:39:27 +09001205 dictkeys_set_index(keys, i, ix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001207}
1208
1209/*
1210Restructure the table by allocating a new table and reinserting all
1211items again. When entries have been deleted, the new table may
1212actually be smaller than the old one.
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001213If a table is split (its keys and hashes are shared, its values are not),
1214then the values are temporarily copied into the table, it is resized as
1215a combined table, then the me_value slots in the old table are NULLed out.
1216After resizing a table is always combined,
1217but can be resplit by make_keys_shared().
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001218*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001219static int
Inada Naokid9323a82020-08-07 14:08:55 +09001220dictresize(PyDictObject *mp, Py_ssize_t newsize)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001221{
Inada Naokid9323a82020-08-07 14:08:55 +09001222 Py_ssize_t numentries;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001223 PyDictKeysObject *oldkeys;
1224 PyObject **oldvalues;
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001225 PyDictKeyEntry *oldentries, *newentries;
Tim Peters91a364d2001-05-19 07:04:38 +00001226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001227 if (newsize <= 0) {
1228 PyErr_NoMemory();
1229 return -1;
1230 }
Inada Naokid9323a82020-08-07 14:08:55 +09001231 assert(IS_POWER_OF_2(newsize));
1232 assert(newsize >= PyDict_MINSIZE);
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001233
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001234 oldkeys = mp->ma_keys;
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001235
1236 /* NOTE: Current odict checks mp->ma_keys to detect resize happen.
1237 * So we can't reuse oldkeys even if oldkeys->dk_size == newsize.
1238 * TODO: Try reusing oldkeys when reimplement odict.
1239 */
1240
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001241 /* Allocate a new table. */
1242 mp->ma_keys = new_keys_object(newsize);
1243 if (mp->ma_keys == NULL) {
1244 mp->ma_keys = oldkeys;
1245 return -1;
1246 }
Victor Stinner3d3f2642016-12-15 17:21:23 +01001247 // New table must be large enough.
1248 assert(mp->ma_keys->dk_usable >= mp->ma_used);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001249 if (oldkeys->dk_lookup == lookdict)
1250 mp->ma_keys->dk_lookup = lookdict;
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001251
1252 numentries = mp->ma_used;
1253 oldentries = DK_ENTRIES(oldkeys);
1254 newentries = DK_ENTRIES(mp->ma_keys);
1255 oldvalues = mp->ma_values;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001256 if (oldvalues != NULL) {
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001257 /* Convert split table into new combined table.
1258 * We must incref keys; we can transfer values.
1259 * Note that values of split table is always dense.
1260 */
1261 for (Py_ssize_t i = 0; i < numentries; i++) {
1262 assert(oldvalues[i] != NULL);
1263 PyDictKeyEntry *ep = &oldentries[i];
1264 PyObject *key = ep->me_key;
1265 Py_INCREF(key);
1266 newentries[i].me_key = key;
1267 newentries[i].me_hash = ep->me_hash;
1268 newentries[i].me_value = oldvalues[i];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001269 }
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001270
INADA Naokia7576492018-11-14 18:39:27 +09001271 dictkeys_decref(oldkeys);
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001272 mp->ma_values = NULL;
Victor Stinner742da042016-09-07 17:40:12 -07001273 if (oldvalues != empty_values) {
1274 free_values(oldvalues);
1275 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001276 }
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001277 else { // combined table.
1278 if (oldkeys->dk_nentries == numentries) {
1279 memcpy(newentries, oldentries, numentries * sizeof(PyDictKeyEntry));
1280 }
1281 else {
1282 PyDictKeyEntry *ep = oldentries;
1283 for (Py_ssize_t i = 0; i < numentries; i++) {
1284 while (ep->me_value == NULL)
1285 ep++;
1286 newentries[i] = *ep++;
1287 }
1288 }
1289
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001290 assert(oldkeys->dk_lookup != lookdict_split);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001291 assert(oldkeys->dk_refcnt == 1);
Victor Stinner49932fe2020-02-03 17:55:05 +01001292#ifdef Py_REF_DEBUG
1293 _Py_RefTotal--;
1294#endif
Victor Stinner522691c2020-06-23 16:40:40 +02001295 struct _Py_dict_state *state = get_dict_state();
Victor Stinnerb4e85ca2020-06-23 11:33:18 +02001296#ifdef Py_DEBUG
1297 // dictresize() must not be called after _PyDict_Fini()
1298 assert(state->keys_numfree != -1);
Victor Stinnerb4b53862020-05-05 19:55:29 +02001299#endif
Victor Stinnerb4e85ca2020-06-23 11:33:18 +02001300 if (oldkeys->dk_size == PyDict_MINSIZE &&
1301 state->keys_numfree < PyDict_MAXFREELIST)
Victor Stinnerb4b53862020-05-05 19:55:29 +02001302 {
Victor Stinnerb4e85ca2020-06-23 11:33:18 +02001303 state->keys_free_list[state->keys_numfree++] = oldkeys;
1304 }
1305 else {
INADA Naokia7576492018-11-14 18:39:27 +09001306 PyObject_FREE(oldkeys);
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001307 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001308 }
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001309
1310 build_indices(mp->ma_keys, newentries, numentries);
1311 mp->ma_keys->dk_usable -= numentries;
1312 mp->ma_keys->dk_nentries = numentries;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 return 0;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001314}
1315
Benjamin Peterson15ee8212012-04-24 14:44:18 -04001316/* Returns NULL if unable to split table.
1317 * A NULL return does not necessarily indicate an error */
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001318static PyDictKeysObject *
1319make_keys_shared(PyObject *op)
1320{
1321 Py_ssize_t i;
1322 Py_ssize_t size;
1323 PyDictObject *mp = (PyDictObject *)op;
1324
Benjamin Peterson15ee8212012-04-24 14:44:18 -04001325 if (!PyDict_CheckExact(op))
1326 return NULL;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001327 if (!_PyDict_HasSplitTable(mp)) {
1328 PyDictKeyEntry *ep0;
1329 PyObject **values;
1330 assert(mp->ma_keys->dk_refcnt == 1);
1331 if (mp->ma_keys->dk_lookup == lookdict) {
1332 return NULL;
1333 }
1334 else if (mp->ma_keys->dk_lookup == lookdict_unicode) {
1335 /* Remove dummy keys */
1336 if (dictresize(mp, DK_SIZE(mp->ma_keys)))
1337 return NULL;
1338 }
1339 assert(mp->ma_keys->dk_lookup == lookdict_unicode_nodummy);
1340 /* Copy values into a new array */
Victor Stinner742da042016-09-07 17:40:12 -07001341 ep0 = DK_ENTRIES(mp->ma_keys);
1342 size = USABLE_FRACTION(DK_SIZE(mp->ma_keys));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001343 values = new_values(size);
1344 if (values == NULL) {
1345 PyErr_SetString(PyExc_MemoryError,
1346 "Not enough memory to allocate new values array");
1347 return NULL;
1348 }
1349 for (i = 0; i < size; i++) {
1350 values[i] = ep0[i].me_value;
1351 ep0[i].me_value = NULL;
1352 }
1353 mp->ma_keys->dk_lookup = lookdict_split;
1354 mp->ma_values = values;
1355 }
INADA Naokia7576492018-11-14 18:39:27 +09001356 dictkeys_incref(mp->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001357 return mp->ma_keys;
1358}
Christian Heimes99170a52007-12-19 02:07:34 +00001359
1360PyObject *
1361_PyDict_NewPresized(Py_ssize_t minused)
1362{
INADA Naoki92c50ee2016-11-22 00:57:02 +09001363 const Py_ssize_t max_presize = 128 * 1024;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001364 Py_ssize_t newsize;
1365 PyDictKeysObject *new_keys;
INADA Naoki92c50ee2016-11-22 00:57:02 +09001366
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001367 if (minused <= USABLE_FRACTION(PyDict_MINSIZE)) {
Inada Naokif2a18672019-03-12 17:25:44 +09001368 return PyDict_New();
1369 }
INADA Naoki92c50ee2016-11-22 00:57:02 +09001370 /* There are no strict guarantee that returned dict can contain minused
1371 * items without resize. So we create medium size dict instead of very
1372 * large dict or MemoryError.
1373 */
1374 if (minused > USABLE_FRACTION(max_presize)) {
1375 newsize = max_presize;
1376 }
1377 else {
Inada Naokid9323a82020-08-07 14:08:55 +09001378 newsize = estimate_keysize(minused);
INADA Naoki92c50ee2016-11-22 00:57:02 +09001379 }
INADA Naoki92c50ee2016-11-22 00:57:02 +09001380
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001381 new_keys = new_keys_object(newsize);
1382 if (new_keys == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 return NULL;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001384 return new_dict(new_keys, NULL);
Christian Heimes99170a52007-12-19 02:07:34 +00001385}
1386
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001387/* Note that, for historical reasons, PyDict_GetItem() suppresses all errors
1388 * that may occur (originally dicts supported only string keys, and exceptions
1389 * weren't possible). So, while the original intent was that a NULL return
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001390 * meant the key wasn't present, in reality it can mean that, or that an error
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001391 * (suppressed) occurred while computing the key's hash, or that some error
1392 * (suppressed) occurred when comparing keys in the dict's internal probe
1393 * sequence. A nasty example of the latter is when a Python-coded comparison
1394 * function hits a stack-depth error, which can cause this to return NULL
1395 * even if the key is present.
1396 */
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001397PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00001398PyDict_GetItem(PyObject *op, PyObject *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001399{
Victor Stinner59d3dce2020-06-02 14:03:25 +02001400 if (!PyDict_Check(op)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401 return NULL;
Victor Stinner59d3dce2020-06-02 14:03:25 +02001402 }
1403 PyDictObject *mp = (PyDictObject *)op;
1404
1405 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001407 (hash = ((PyASCIIObject *) key)->hash) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 {
1409 hash = PyObject_Hash(key);
1410 if (hash == -1) {
1411 PyErr_Clear();
1412 return NULL;
1413 }
1414 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001415
Victor Stinner59d3dce2020-06-02 14:03:25 +02001416 PyThreadState *tstate = _PyThreadState_GET();
1417#ifdef Py_DEBUG
1418 // bpo-40839: Before Python 3.10, it was possible to call PyDict_GetItem()
1419 // with the GIL released.
1420 _Py_EnsureTstateNotNULL(tstate);
1421#endif
1422
1423 /* Preserve the existing exception */
1424 PyObject *exc_type, *exc_value, *exc_tb;
1425 PyObject *value;
1426 Py_ssize_t ix;
1427
1428 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
1429 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
1430
1431 /* Ignore any exception raised by the lookup */
1432 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
1433
1434 if (ix < 0) {
1435 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 }
INADA Naokiba609772016-12-07 20:41:42 +09001437 return value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001438}
1439
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02001440/* Same as PyDict_GetItemWithError() but with hash supplied by caller.
1441 This returns NULL *with* an exception set if an exception occurred.
1442 It returns NULL *without* an exception set if the key wasn't present.
1443*/
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001444PyObject *
1445_PyDict_GetItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
1446{
Victor Stinner742da042016-09-07 17:40:12 -07001447 Py_ssize_t ix;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001448 PyDictObject *mp = (PyDictObject *)op;
INADA Naokiba609772016-12-07 20:41:42 +09001449 PyObject *value;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001450
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02001451 if (!PyDict_Check(op)) {
1452 PyErr_BadInternalCall();
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001453 return NULL;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001454 }
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02001455
INADA Naoki778928b2017-08-03 23:45:15 +09001456 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02001457 if (ix < 0) {
1458 return NULL;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001459 }
INADA Naokiba609772016-12-07 20:41:42 +09001460 return value;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001461}
1462
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001463/* Variant of PyDict_GetItem() that doesn't suppress exceptions.
1464 This returns NULL *with* an exception set if an exception occurred.
1465 It returns NULL *without* an exception set if the key wasn't present.
1466*/
1467PyObject *
1468PyDict_GetItemWithError(PyObject *op, PyObject *key)
1469{
Victor Stinner742da042016-09-07 17:40:12 -07001470 Py_ssize_t ix;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001471 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 PyDictObject*mp = (PyDictObject *)op;
INADA Naokiba609772016-12-07 20:41:42 +09001473 PyObject *value;
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001474
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 if (!PyDict_Check(op)) {
1476 PyErr_BadInternalCall();
1477 return NULL;
1478 }
1479 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001480 (hash = ((PyASCIIObject *) key)->hash) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 {
1482 hash = PyObject_Hash(key);
1483 if (hash == -1) {
1484 return NULL;
1485 }
1486 }
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001487
INADA Naoki778928b2017-08-03 23:45:15 +09001488 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07001489 if (ix < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001491 return value;
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001492}
1493
Brett Cannonfd074152012-04-14 14:10:13 -04001494PyObject *
1495_PyDict_GetItemIdWithError(PyObject *dp, struct _Py_Identifier *key)
1496{
1497 PyObject *kv;
1498 kv = _PyUnicode_FromId(key); /* borrowed */
1499 if (kv == NULL)
1500 return NULL;
scoder6067d4b2020-05-11 06:04:31 +02001501 Py_hash_t hash = ((PyASCIIObject *) kv)->hash;
1502 assert (hash != -1); /* interned strings have their hash value initialised */
1503 return _PyDict_GetItem_KnownHash(dp, kv, hash);
Brett Cannonfd074152012-04-14 14:10:13 -04001504}
1505
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001506PyObject *
1507_PyDict_GetItemStringWithError(PyObject *v, const char *key)
1508{
1509 PyObject *kv, *rv;
1510 kv = PyUnicode_FromString(key);
1511 if (kv == NULL) {
1512 return NULL;
1513 }
1514 rv = PyDict_GetItemWithError(v, kv);
1515 Py_DECREF(kv);
1516 return rv;
1517}
1518
Victor Stinnerb4efc962015-11-20 09:24:02 +01001519/* Fast version of global value lookup (LOAD_GLOBAL).
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001520 * Lookup in globals, then builtins.
Victor Stinnerb4efc962015-11-20 09:24:02 +01001521 *
1522 * Raise an exception and return NULL if an error occurred (ex: computing the
1523 * key hash failed, key comparison failed, ...). Return NULL if the key doesn't
1524 * exist. Return the value if the key exists.
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001525 */
1526PyObject *
1527_PyDict_LoadGlobal(PyDictObject *globals, PyDictObject *builtins, PyObject *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001528{
Victor Stinner742da042016-09-07 17:40:12 -07001529 Py_ssize_t ix;
Victor Stinnerb4efc962015-11-20 09:24:02 +01001530 Py_hash_t hash;
INADA Naokiba609772016-12-07 20:41:42 +09001531 PyObject *value;
Victor Stinnerb4efc962015-11-20 09:24:02 +01001532
1533 if (!PyUnicode_CheckExact(key) ||
1534 (hash = ((PyASCIIObject *) key)->hash) == -1)
1535 {
1536 hash = PyObject_Hash(key);
1537 if (hash == -1)
1538 return NULL;
Antoine Pitroue965d972012-02-27 00:45:12 +01001539 }
Victor Stinnerb4efc962015-11-20 09:24:02 +01001540
1541 /* namespace 1: globals */
INADA Naoki778928b2017-08-03 23:45:15 +09001542 ix = globals->ma_keys->dk_lookup(globals, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07001543 if (ix == DKIX_ERROR)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001544 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001545 if (ix != DKIX_EMPTY && value != NULL)
1546 return value;
Victor Stinnerb4efc962015-11-20 09:24:02 +01001547
1548 /* namespace 2: builtins */
INADA Naoki778928b2017-08-03 23:45:15 +09001549 ix = builtins->ma_keys->dk_lookup(builtins, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07001550 if (ix < 0)
Victor Stinnerb4efc962015-11-20 09:24:02 +01001551 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001552 return value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001553}
1554
Antoine Pitroue965d972012-02-27 00:45:12 +01001555/* CAUTION: PyDict_SetItem() must guarantee that it won't resize the
1556 * dictionary if it's merely replacing the value for an existing key.
1557 * This means that it's safe to loop over a dictionary with PyDict_Next()
1558 * and occasionally replace a value -- but you can't insert new keys or
1559 * remove them.
1560 */
1561int
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001562PyDict_SetItem(PyObject *op, PyObject *key, PyObject *value)
Antoine Pitroue965d972012-02-27 00:45:12 +01001563{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001564 PyDictObject *mp;
1565 Py_hash_t hash;
Antoine Pitroue965d972012-02-27 00:45:12 +01001566 if (!PyDict_Check(op)) {
1567 PyErr_BadInternalCall();
1568 return -1;
1569 }
1570 assert(key);
1571 assert(value);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001572 mp = (PyDictObject *)op;
1573 if (!PyUnicode_CheckExact(key) ||
1574 (hash = ((PyASCIIObject *) key)->hash) == -1)
1575 {
Antoine Pitroue965d972012-02-27 00:45:12 +01001576 hash = PyObject_Hash(key);
1577 if (hash == -1)
1578 return -1;
1579 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001580
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001581 if (mp->ma_keys == Py_EMPTY_KEYS) {
1582 return insert_to_emptydict(mp, key, hash, value);
1583 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001584 /* insertdict() handles any resizing that might be necessary */
1585 return insertdict(mp, key, hash, value);
Antoine Pitroue965d972012-02-27 00:45:12 +01001586}
1587
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001588int
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001589_PyDict_SetItem_KnownHash(PyObject *op, PyObject *key, PyObject *value,
1590 Py_hash_t hash)
1591{
1592 PyDictObject *mp;
1593
1594 if (!PyDict_Check(op)) {
1595 PyErr_BadInternalCall();
1596 return -1;
1597 }
1598 assert(key);
1599 assert(value);
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001600 assert(hash != -1);
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001601 mp = (PyDictObject *)op;
1602
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001603 if (mp->ma_keys == Py_EMPTY_KEYS) {
1604 return insert_to_emptydict(mp, key, hash, value);
1605 }
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001606 /* insertdict() handles any resizing that might be necessary */
1607 return insertdict(mp, key, hash, value);
1608}
1609
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001610static int
INADA Naoki778928b2017-08-03 23:45:15 +09001611delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix,
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001612 PyObject *old_value)
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001613{
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001614 PyObject *old_key;
Antoine Pitroud741ed42016-12-27 14:23:43 +01001615 PyDictKeyEntry *ep;
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001616
INADA Naoki778928b2017-08-03 23:45:15 +09001617 Py_ssize_t hashpos = lookdict_index(mp->ma_keys, hash, ix);
1618 assert(hashpos >= 0);
1619
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001620 mp->ma_used--;
Antoine Pitroud741ed42016-12-27 14:23:43 +01001621 mp->ma_version_tag = DICT_NEXT_VERSION();
1622 ep = &DK_ENTRIES(mp->ma_keys)[ix];
INADA Naokia7576492018-11-14 18:39:27 +09001623 dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
Antoine Pitroud741ed42016-12-27 14:23:43 +01001624 ENSURE_ALLOWS_DELETIONS(mp);
1625 old_key = ep->me_key;
1626 ep->me_key = NULL;
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001627 ep->me_value = NULL;
Antoine Pitroud741ed42016-12-27 14:23:43 +01001628 Py_DECREF(old_key);
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001629 Py_DECREF(old_value);
Antoine Pitroud741ed42016-12-27 14:23:43 +01001630
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001631 ASSERT_CONSISTENT(mp);
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001632 return 0;
1633}
1634
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001635int
Tim Peters1f5871e2000-07-04 17:44:48 +00001636PyDict_DelItem(PyObject *op, PyObject *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001637{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001638 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 assert(key);
1640 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001641 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 hash = PyObject_Hash(key);
1643 if (hash == -1)
1644 return -1;
1645 }
Victor Stinner742da042016-09-07 17:40:12 -07001646
1647 return _PyDict_DelItem_KnownHash(op, key, hash);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001648}
1649
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001650int
1651_PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
1652{
INADA Naoki778928b2017-08-03 23:45:15 +09001653 Py_ssize_t ix;
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001654 PyDictObject *mp;
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001655 PyObject *old_value;
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001656
1657 if (!PyDict_Check(op)) {
1658 PyErr_BadInternalCall();
1659 return -1;
1660 }
1661 assert(key);
1662 assert(hash != -1);
1663 mp = (PyDictObject *)op;
INADA Naoki778928b2017-08-03 23:45:15 +09001664 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Victor Stinner742da042016-09-07 17:40:12 -07001665 if (ix == DKIX_ERROR)
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001666 return -1;
INADA Naokiba609772016-12-07 20:41:42 +09001667 if (ix == DKIX_EMPTY || old_value == NULL) {
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001668 _PyErr_SetKeyError(key);
1669 return -1;
1670 }
Victor Stinner78601a32016-09-09 19:28:36 -07001671
1672 // Split table doesn't allow deletion. Combine it.
1673 if (_PyDict_HasSplitTable(mp)) {
1674 if (dictresize(mp, DK_SIZE(mp->ma_keys))) {
1675 return -1;
1676 }
INADA Naoki778928b2017-08-03 23:45:15 +09001677 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Victor Stinner78601a32016-09-09 19:28:36 -07001678 assert(ix >= 0);
1679 }
1680
INADA Naoki778928b2017-08-03 23:45:15 +09001681 return delitem_common(mp, hash, ix, old_value);
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001682}
1683
Antoine Pitroud741ed42016-12-27 14:23:43 +01001684/* This function promises that the predicate -> deletion sequence is atomic
1685 * (i.e. protected by the GIL), assuming the predicate itself doesn't
1686 * release the GIL.
1687 */
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001688int
1689_PyDict_DelItemIf(PyObject *op, PyObject *key,
1690 int (*predicate)(PyObject *value))
1691{
Antoine Pitroud741ed42016-12-27 14:23:43 +01001692 Py_ssize_t hashpos, ix;
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001693 PyDictObject *mp;
1694 Py_hash_t hash;
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001695 PyObject *old_value;
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001696 int res;
1697
1698 if (!PyDict_Check(op)) {
1699 PyErr_BadInternalCall();
1700 return -1;
1701 }
1702 assert(key);
1703 hash = PyObject_Hash(key);
1704 if (hash == -1)
1705 return -1;
1706 mp = (PyDictObject *)op;
INADA Naoki778928b2017-08-03 23:45:15 +09001707 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Antoine Pitroud741ed42016-12-27 14:23:43 +01001708 if (ix == DKIX_ERROR)
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001709 return -1;
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001710 if (ix == DKIX_EMPTY || old_value == NULL) {
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001711 _PyErr_SetKeyError(key);
1712 return -1;
1713 }
Antoine Pitroud741ed42016-12-27 14:23:43 +01001714
1715 // Split table doesn't allow deletion. Combine it.
1716 if (_PyDict_HasSplitTable(mp)) {
1717 if (dictresize(mp, DK_SIZE(mp->ma_keys))) {
1718 return -1;
1719 }
INADA Naoki778928b2017-08-03 23:45:15 +09001720 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Antoine Pitroud741ed42016-12-27 14:23:43 +01001721 assert(ix >= 0);
1722 }
1723
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001724 res = predicate(old_value);
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001725 if (res == -1)
1726 return -1;
INADA Naoki778928b2017-08-03 23:45:15 +09001727
1728 hashpos = lookdict_index(mp->ma_keys, hash, ix);
1729 assert(hashpos >= 0);
1730
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001731 if (res > 0)
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001732 return delitem_common(mp, hashpos, ix, old_value);
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001733 else
1734 return 0;
1735}
1736
1737
Guido van Rossum25831651993-05-19 14:50:45 +00001738void
Tim Peters1f5871e2000-07-04 17:44:48 +00001739PyDict_Clear(PyObject *op)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001740{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001741 PyDictObject *mp;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001742 PyDictKeysObject *oldkeys;
1743 PyObject **oldvalues;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001744 Py_ssize_t i, n;
Tim Petersdea48ec2001-05-22 20:40:22 +00001745
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 if (!PyDict_Check(op))
1747 return;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001748 mp = ((PyDictObject *)op);
1749 oldkeys = mp->ma_keys;
1750 oldvalues = mp->ma_values;
1751 if (oldvalues == empty_values)
1752 return;
1753 /* Empty the dict... */
INADA Naokia7576492018-11-14 18:39:27 +09001754 dictkeys_incref(Py_EMPTY_KEYS);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001755 mp->ma_keys = Py_EMPTY_KEYS;
1756 mp->ma_values = empty_values;
1757 mp->ma_used = 0;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07001758 mp->ma_version_tag = DICT_NEXT_VERSION();
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001759 /* ...then clear the keys and values */
1760 if (oldvalues != NULL) {
Victor Stinner742da042016-09-07 17:40:12 -07001761 n = oldkeys->dk_nentries;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001762 for (i = 0; i < n; i++)
1763 Py_CLEAR(oldvalues[i]);
1764 free_values(oldvalues);
INADA Naokia7576492018-11-14 18:39:27 +09001765 dictkeys_decref(oldkeys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001766 }
1767 else {
1768 assert(oldkeys->dk_refcnt == 1);
INADA Naokia7576492018-11-14 18:39:27 +09001769 dictkeys_decref(oldkeys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001770 }
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001771 ASSERT_CONSISTENT(mp);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001772}
1773
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001774/* Internal version of PyDict_Next that returns a hash value in addition
1775 * to the key and value.
1776 * Return 1 on success, return 0 when the reached the end of the dictionary
1777 * (or if op is not a dictionary)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001778 */
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001779int
1780_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
1781 PyObject **pvalue, Py_hash_t *phash)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001782{
INADA Naokica2d8be2016-11-04 16:59:10 +09001783 Py_ssize_t i;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001784 PyDictObject *mp;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001785 PyDictKeyEntry *entry_ptr;
1786 PyObject *value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001787
1788 if (!PyDict_Check(op))
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001789 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790 mp = (PyDictObject *)op;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001791 i = *ppos;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001792 if (mp->ma_values) {
INADA Naokica2d8be2016-11-04 16:59:10 +09001793 if (i < 0 || i >= mp->ma_used)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001794 return 0;
INADA Naokica2d8be2016-11-04 16:59:10 +09001795 /* values of split table is always dense */
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001796 entry_ptr = &DK_ENTRIES(mp->ma_keys)[i];
INADA Naokica2d8be2016-11-04 16:59:10 +09001797 value = mp->ma_values[i];
1798 assert(value != NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001799 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001800 else {
INADA Naokica2d8be2016-11-04 16:59:10 +09001801 Py_ssize_t n = mp->ma_keys->dk_nentries;
1802 if (i < 0 || i >= n)
1803 return 0;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001804 entry_ptr = &DK_ENTRIES(mp->ma_keys)[i];
1805 while (i < n && entry_ptr->me_value == NULL) {
1806 entry_ptr++;
1807 i++;
Victor Stinner742da042016-09-07 17:40:12 -07001808 }
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001809 if (i >= n)
1810 return 0;
1811 value = entry_ptr->me_value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001812 }
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001813 *ppos = i+1;
1814 if (pkey)
1815 *pkey = entry_ptr->me_key;
1816 if (phash)
1817 *phash = entry_ptr->me_hash;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001818 if (pvalue)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001819 *pvalue = value;
1820 return 1;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001821}
1822
Tim Peters080c88b2003-02-15 03:01:11 +00001823/*
1824 * Iterate over a dict. Use like so:
1825 *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001826 * Py_ssize_t i;
Tim Peters080c88b2003-02-15 03:01:11 +00001827 * PyObject *key, *value;
1828 * i = 0; # important! i should not otherwise be changed by you
Neal Norwitz07323012003-02-15 14:45:12 +00001829 * while (PyDict_Next(yourdict, &i, &key, &value)) {
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001830 * Refer to borrowed references in key and value.
Tim Peters080c88b2003-02-15 03:01:11 +00001831 * }
1832 *
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001833 * Return 1 on success, return 0 when the reached the end of the dictionary
1834 * (or if op is not a dictionary)
1835 *
Tim Peters080c88b2003-02-15 03:01:11 +00001836 * CAUTION: In general, it isn't safe to use PyDict_Next in a loop that
Tim Peters67830702001-03-21 19:23:56 +00001837 * mutates the dict. One exception: it is safe if the loop merely changes
1838 * the values associated with the keys (but doesn't insert new keys or
1839 * delete keys), via PyDict_SetItem().
1840 */
Guido van Rossum25831651993-05-19 14:50:45 +00001841int
Martin v. Löwis18e16552006-02-15 17:27:45 +00001842PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001843{
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001844 return _PyDict_Next(op, ppos, pkey, pvalue, NULL);
Thomas Wouterscf297e42007-02-23 15:07:44 +00001845}
1846
Eric Snow96c6af92015-05-29 22:21:39 -06001847/* Internal version of dict.pop(). */
1848PyObject *
Serhiy Storchaka42e1ea92017-01-12 19:12:21 +02001849_PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *deflt)
Eric Snow96c6af92015-05-29 22:21:39 -06001850{
Victor Stinner742da042016-09-07 17:40:12 -07001851 Py_ssize_t ix, hashpos;
Eric Snow96c6af92015-05-29 22:21:39 -06001852 PyObject *old_value, *old_key;
1853 PyDictKeyEntry *ep;
Yury Selivanov684ef2c2016-10-28 19:01:21 -04001854 PyDictObject *mp;
1855
1856 assert(PyDict_Check(dict));
1857 mp = (PyDictObject *)dict;
Eric Snow96c6af92015-05-29 22:21:39 -06001858
1859 if (mp->ma_used == 0) {
1860 if (deflt) {
1861 Py_INCREF(deflt);
1862 return deflt;
1863 }
1864 _PyErr_SetKeyError(key);
1865 return NULL;
1866 }
INADA Naoki778928b2017-08-03 23:45:15 +09001867 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Victor Stinner742da042016-09-07 17:40:12 -07001868 if (ix == DKIX_ERROR)
Eric Snow96c6af92015-05-29 22:21:39 -06001869 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001870 if (ix == DKIX_EMPTY || old_value == NULL) {
Eric Snow96c6af92015-05-29 22:21:39 -06001871 if (deflt) {
1872 Py_INCREF(deflt);
1873 return deflt;
1874 }
1875 _PyErr_SetKeyError(key);
1876 return NULL;
1877 }
Victor Stinner3b6a6b42016-09-08 12:51:24 -07001878
Victor Stinner78601a32016-09-09 19:28:36 -07001879 // Split table doesn't allow deletion. Combine it.
1880 if (_PyDict_HasSplitTable(mp)) {
1881 if (dictresize(mp, DK_SIZE(mp->ma_keys))) {
1882 return NULL;
1883 }
INADA Naoki778928b2017-08-03 23:45:15 +09001884 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Victor Stinner78601a32016-09-09 19:28:36 -07001885 assert(ix >= 0);
1886 }
1887
INADA Naoki778928b2017-08-03 23:45:15 +09001888 hashpos = lookdict_index(mp->ma_keys, hash, ix);
1889 assert(hashpos >= 0);
Victor Stinner78601a32016-09-09 19:28:36 -07001890 assert(old_value != NULL);
Eric Snow96c6af92015-05-29 22:21:39 -06001891 mp->ma_used--;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07001892 mp->ma_version_tag = DICT_NEXT_VERSION();
INADA Naokia7576492018-11-14 18:39:27 +09001893 dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
Victor Stinner78601a32016-09-09 19:28:36 -07001894 ep = &DK_ENTRIES(mp->ma_keys)[ix];
1895 ENSURE_ALLOWS_DELETIONS(mp);
1896 old_key = ep->me_key;
1897 ep->me_key = NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001898 ep->me_value = NULL;
Victor Stinner78601a32016-09-09 19:28:36 -07001899 Py_DECREF(old_key);
Victor Stinner611b0fa2016-09-14 15:02:01 +02001900
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001901 ASSERT_CONSISTENT(mp);
Eric Snow96c6af92015-05-29 22:21:39 -06001902 return old_value;
1903}
1904
Serhiy Storchaka67796522017-01-12 18:34:33 +02001905PyObject *
Serhiy Storchaka42e1ea92017-01-12 19:12:21 +02001906_PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt)
Serhiy Storchaka67796522017-01-12 18:34:33 +02001907{
1908 Py_hash_t hash;
1909
Serhiy Storchaka42e1ea92017-01-12 19:12:21 +02001910 if (((PyDictObject *)dict)->ma_used == 0) {
Serhiy Storchaka67796522017-01-12 18:34:33 +02001911 if (deflt) {
1912 Py_INCREF(deflt);
1913 return deflt;
1914 }
1915 _PyErr_SetKeyError(key);
1916 return NULL;
1917 }
1918 if (!PyUnicode_CheckExact(key) ||
1919 (hash = ((PyASCIIObject *) key)->hash) == -1) {
1920 hash = PyObject_Hash(key);
1921 if (hash == -1)
1922 return NULL;
1923 }
Serhiy Storchaka42e1ea92017-01-12 19:12:21 +02001924 return _PyDict_Pop_KnownHash(dict, key, hash, deflt);
Serhiy Storchaka67796522017-01-12 18:34:33 +02001925}
1926
Eric Snow96c6af92015-05-29 22:21:39 -06001927/* Internal version of dict.from_keys(). It is subclass-friendly. */
1928PyObject *
1929_PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)
1930{
1931 PyObject *it; /* iter(iterable) */
1932 PyObject *key;
1933 PyObject *d;
1934 int status;
1935
Victor Stinnera5ed5f02016-12-06 18:45:50 +01001936 d = _PyObject_CallNoArg(cls);
Eric Snow96c6af92015-05-29 22:21:39 -06001937 if (d == NULL)
1938 return NULL;
1939
1940 if (PyDict_CheckExact(d) && ((PyDictObject *)d)->ma_used == 0) {
1941 if (PyDict_CheckExact(iterable)) {
1942 PyDictObject *mp = (PyDictObject *)d;
1943 PyObject *oldvalue;
1944 Py_ssize_t pos = 0;
1945 PyObject *key;
1946 Py_hash_t hash;
1947
Inada Naokid9323a82020-08-07 14:08:55 +09001948 if (dictresize(mp, estimate_keysize(PyDict_GET_SIZE(iterable)))) {
Eric Snow96c6af92015-05-29 22:21:39 -06001949 Py_DECREF(d);
1950 return NULL;
1951 }
1952
1953 while (_PyDict_Next(iterable, &pos, &key, &oldvalue, &hash)) {
1954 if (insertdict(mp, key, hash, value)) {
1955 Py_DECREF(d);
1956 return NULL;
1957 }
1958 }
1959 return d;
1960 }
1961 if (PyAnySet_CheckExact(iterable)) {
1962 PyDictObject *mp = (PyDictObject *)d;
1963 Py_ssize_t pos = 0;
1964 PyObject *key;
1965 Py_hash_t hash;
1966
Inada Naokid9323a82020-08-07 14:08:55 +09001967 if (dictresize(mp, estimate_keysize(PySet_GET_SIZE(iterable)))) {
Eric Snow96c6af92015-05-29 22:21:39 -06001968 Py_DECREF(d);
1969 return NULL;
1970 }
1971
1972 while (_PySet_NextEntry(iterable, &pos, &key, &hash)) {
1973 if (insertdict(mp, key, hash, value)) {
1974 Py_DECREF(d);
1975 return NULL;
1976 }
1977 }
1978 return d;
1979 }
1980 }
1981
1982 it = PyObject_GetIter(iterable);
1983 if (it == NULL){
1984 Py_DECREF(d);
1985 return NULL;
1986 }
1987
1988 if (PyDict_CheckExact(d)) {
1989 while ((key = PyIter_Next(it)) != NULL) {
1990 status = PyDict_SetItem(d, key, value);
1991 Py_DECREF(key);
1992 if (status < 0)
1993 goto Fail;
1994 }
1995 } else {
1996 while ((key = PyIter_Next(it)) != NULL) {
1997 status = PyObject_SetItem(d, key, value);
1998 Py_DECREF(key);
1999 if (status < 0)
2000 goto Fail;
2001 }
2002 }
2003
2004 if (PyErr_Occurred())
2005 goto Fail;
2006 Py_DECREF(it);
2007 return d;
2008
2009Fail:
2010 Py_DECREF(it);
2011 Py_DECREF(d);
2012 return NULL;
2013}
2014
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002015/* Methods */
2016
2017static void
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002018dict_dealloc(PyDictObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002019{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002020 PyObject **values = mp->ma_values;
2021 PyDictKeysObject *keys = mp->ma_keys;
2022 Py_ssize_t i, n;
INADA Naokia6296d32017-08-24 14:55:17 +09002023
2024 /* bpo-31095: UnTrack is needed before calling any callbacks */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 PyObject_GC_UnTrack(mp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02002026 Py_TRASHCAN_BEGIN(mp, dict_dealloc)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002027 if (values != NULL) {
2028 if (values != empty_values) {
Victor Stinner742da042016-09-07 17:40:12 -07002029 for (i = 0, n = mp->ma_keys->dk_nentries; i < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002030 Py_XDECREF(values[i]);
2031 }
2032 free_values(values);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002033 }
INADA Naokia7576492018-11-14 18:39:27 +09002034 dictkeys_decref(keys);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002035 }
Victor Stinnerac2a4fe2013-07-16 22:19:00 +02002036 else if (keys != NULL) {
Antoine Pitrou2d169b22012-05-12 23:43:44 +02002037 assert(keys->dk_refcnt == 1);
INADA Naokia7576492018-11-14 18:39:27 +09002038 dictkeys_decref(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002039 }
Victor Stinner522691c2020-06-23 16:40:40 +02002040 struct _Py_dict_state *state = get_dict_state();
Victor Stinnerb4e85ca2020-06-23 11:33:18 +02002041#ifdef Py_DEBUG
2042 // new_dict() must not be called after _PyDict_Fini()
2043 assert(state->numfree != -1);
Victor Stinnerb4b53862020-05-05 19:55:29 +02002044#endif
Victor Stinnerb4e85ca2020-06-23 11:33:18 +02002045 if (state->numfree < PyDict_MAXFREELIST && Py_IS_TYPE(mp, &PyDict_Type)) {
2046 state->free_list[state->numfree++] = mp;
2047 }
2048 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002049 Py_TYPE(mp)->tp_free((PyObject *)mp);
Victor Stinnerb4b53862020-05-05 19:55:29 +02002050 }
Jeroen Demeyer351c6742019-05-10 19:21:11 +02002051 Py_TRASHCAN_END
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002052}
2053
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002054
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002055static PyObject *
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002056dict_repr(PyDictObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002057{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002058 Py_ssize_t i;
Victor Stinnerf91929b2013-11-19 13:07:38 +01002059 PyObject *key = NULL, *value = NULL;
2060 _PyUnicodeWriter writer;
2061 int first;
Guido van Rossum255443b1998-04-10 22:47:14 +00002062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002063 i = Py_ReprEnter((PyObject *)mp);
2064 if (i != 0) {
2065 return i > 0 ? PyUnicode_FromString("{...}") : NULL;
2066 }
Guido van Rossum255443b1998-04-10 22:47:14 +00002067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 if (mp->ma_used == 0) {
Victor Stinnerf91929b2013-11-19 13:07:38 +01002069 Py_ReprLeave((PyObject *)mp);
2070 return PyUnicode_FromString("{}");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002071 }
Tim Petersa7259592001-06-16 05:11:17 +00002072
Victor Stinnerf91929b2013-11-19 13:07:38 +01002073 _PyUnicodeWriter_Init(&writer);
2074 writer.overallocate = 1;
2075 /* "{" + "1: 2" + ", 3: 4" * (len - 1) + "}" */
2076 writer.min_length = 1 + 4 + (2 + 4) * (mp->ma_used - 1) + 1;
Tim Petersa7259592001-06-16 05:11:17 +00002077
Victor Stinnerf91929b2013-11-19 13:07:38 +01002078 if (_PyUnicodeWriter_WriteChar(&writer, '{') < 0)
2079 goto error;
Tim Petersa7259592001-06-16 05:11:17 +00002080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002081 /* Do repr() on each key+value pair, and insert ": " between them.
2082 Note that repr may mutate the dict. */
2083 i = 0;
Victor Stinnerf91929b2013-11-19 13:07:38 +01002084 first = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 while (PyDict_Next((PyObject *)mp, &i, &key, &value)) {
Victor Stinnerf91929b2013-11-19 13:07:38 +01002086 PyObject *s;
2087 int res;
2088
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002089 /* Prevent repr from deleting key or value during key format. */
2090 Py_INCREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002091 Py_INCREF(value);
Victor Stinnerf97dfd72013-07-18 01:00:45 +02002092
Victor Stinnerf91929b2013-11-19 13:07:38 +01002093 if (!first) {
2094 if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0)
2095 goto error;
2096 }
2097 first = 0;
2098
2099 s = PyObject_Repr(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002100 if (s == NULL)
Victor Stinnerf91929b2013-11-19 13:07:38 +01002101 goto error;
2102 res = _PyUnicodeWriter_WriteStr(&writer, s);
2103 Py_DECREF(s);
2104 if (res < 0)
2105 goto error;
2106
2107 if (_PyUnicodeWriter_WriteASCIIString(&writer, ": ", 2) < 0)
2108 goto error;
2109
2110 s = PyObject_Repr(value);
2111 if (s == NULL)
2112 goto error;
2113 res = _PyUnicodeWriter_WriteStr(&writer, s);
2114 Py_DECREF(s);
2115 if (res < 0)
2116 goto error;
2117
2118 Py_CLEAR(key);
2119 Py_CLEAR(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 }
Tim Petersa7259592001-06-16 05:11:17 +00002121
Victor Stinnerf91929b2013-11-19 13:07:38 +01002122 writer.overallocate = 0;
2123 if (_PyUnicodeWriter_WriteChar(&writer, '}') < 0)
2124 goto error;
Tim Petersa7259592001-06-16 05:11:17 +00002125
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002126 Py_ReprLeave((PyObject *)mp);
Victor Stinnerf91929b2013-11-19 13:07:38 +01002127
2128 return _PyUnicodeWriter_Finish(&writer);
2129
2130error:
2131 Py_ReprLeave((PyObject *)mp);
2132 _PyUnicodeWriter_Dealloc(&writer);
2133 Py_XDECREF(key);
2134 Py_XDECREF(value);
2135 return NULL;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002136}
2137
Martin v. Löwis18e16552006-02-15 17:27:45 +00002138static Py_ssize_t
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002139dict_length(PyDictObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002140{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002141 return mp->ma_used;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002142}
2143
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002144static PyObject *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002145dict_subscript(PyDictObject *mp, PyObject *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002146{
Victor Stinner742da042016-09-07 17:40:12 -07002147 Py_ssize_t ix;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002148 Py_hash_t hash;
INADA Naokiba609772016-12-07 20:41:42 +09002149 PyObject *value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002152 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002153 hash = PyObject_Hash(key);
2154 if (hash == -1)
2155 return NULL;
2156 }
INADA Naoki778928b2017-08-03 23:45:15 +09002157 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07002158 if (ix == DKIX_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09002160 if (ix == DKIX_EMPTY || value == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 if (!PyDict_CheckExact(mp)) {
2162 /* Look up __missing__ method if we're a subclass. */
2163 PyObject *missing, *res;
Benjamin Petersonce798522012-01-22 11:24:29 -05002164 _Py_IDENTIFIER(__missing__);
2165 missing = _PyObject_LookupSpecial((PyObject *)mp, &PyId___missing__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 if (missing != NULL) {
Petr Viktorinffd97532020-02-11 17:46:57 +01002167 res = PyObject_CallOneArg(missing, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 Py_DECREF(missing);
2169 return res;
2170 }
2171 else if (PyErr_Occurred())
2172 return NULL;
2173 }
Raymond Hettinger69492da2013-09-02 15:59:26 -07002174 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 return NULL;
2176 }
INADA Naokiba609772016-12-07 20:41:42 +09002177 Py_INCREF(value);
2178 return value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002179}
2180
2181static int
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002182dict_ass_sub(PyDictObject *mp, PyObject *v, PyObject *w)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002183{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 if (w == NULL)
2185 return PyDict_DelItem((PyObject *)mp, v);
2186 else
2187 return PyDict_SetItem((PyObject *)mp, v, w);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002188}
2189
Guido van Rossuma9e7a811997-05-13 21:02:11 +00002190static PyMappingMethods dict_as_mapping = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 (lenfunc)dict_length, /*mp_length*/
2192 (binaryfunc)dict_subscript, /*mp_subscript*/
2193 (objobjargproc)dict_ass_sub, /*mp_ass_subscript*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002194};
2195
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002196static PyObject *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002197dict_keys(PyDictObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002198{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002199 PyObject *v;
2200 Py_ssize_t i, j;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002201 PyDictKeyEntry *ep;
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002202 Py_ssize_t n, offset;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002203 PyObject **value_ptr;
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002204
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002205 again:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002206 n = mp->ma_used;
2207 v = PyList_New(n);
2208 if (v == NULL)
2209 return NULL;
2210 if (n != mp->ma_used) {
2211 /* Durnit. The allocations caused the dict to resize.
2212 * Just start over, this shouldn't normally happen.
2213 */
2214 Py_DECREF(v);
2215 goto again;
2216 }
Victor Stinner742da042016-09-07 17:40:12 -07002217 ep = DK_ENTRIES(mp->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002218 if (mp->ma_values) {
2219 value_ptr = mp->ma_values;
2220 offset = sizeof(PyObject *);
2221 }
2222 else {
2223 value_ptr = &ep[0].me_value;
2224 offset = sizeof(PyDictKeyEntry);
2225 }
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002226 for (i = 0, j = 0; j < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002227 if (*value_ptr != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002228 PyObject *key = ep[i].me_key;
2229 Py_INCREF(key);
2230 PyList_SET_ITEM(v, j, key);
2231 j++;
2232 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002233 value_ptr = (PyObject **)(((char *)value_ptr) + offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002234 }
2235 assert(j == n);
2236 return v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002237}
2238
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002239static PyObject *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002240dict_values(PyDictObject *mp)
Guido van Rossum25831651993-05-19 14:50:45 +00002241{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002242 PyObject *v;
2243 Py_ssize_t i, j;
Benjamin Petersonf0acae22016-09-08 09:50:08 -07002244 PyDictKeyEntry *ep;
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002245 Py_ssize_t n, offset;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002246 PyObject **value_ptr;
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002247
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002248 again:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 n = mp->ma_used;
2250 v = PyList_New(n);
2251 if (v == NULL)
2252 return NULL;
2253 if (n != mp->ma_used) {
2254 /* Durnit. The allocations caused the dict to resize.
2255 * Just start over, this shouldn't normally happen.
2256 */
2257 Py_DECREF(v);
2258 goto again;
2259 }
Benjamin Petersonf0acae22016-09-08 09:50:08 -07002260 ep = DK_ENTRIES(mp->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002261 if (mp->ma_values) {
2262 value_ptr = mp->ma_values;
2263 offset = sizeof(PyObject *);
2264 }
2265 else {
Benjamin Petersonf0acae22016-09-08 09:50:08 -07002266 value_ptr = &ep[0].me_value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002267 offset = sizeof(PyDictKeyEntry);
2268 }
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002269 for (i = 0, j = 0; j < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002270 PyObject *value = *value_ptr;
2271 value_ptr = (PyObject **)(((char *)value_ptr) + offset);
2272 if (value != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 Py_INCREF(value);
2274 PyList_SET_ITEM(v, j, value);
2275 j++;
2276 }
2277 }
2278 assert(j == n);
2279 return v;
Guido van Rossum25831651993-05-19 14:50:45 +00002280}
2281
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002282static PyObject *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002283dict_items(PyDictObject *mp)
Guido van Rossum25831651993-05-19 14:50:45 +00002284{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002285 PyObject *v;
2286 Py_ssize_t i, j, n;
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002287 Py_ssize_t offset;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002288 PyObject *item, *key;
2289 PyDictKeyEntry *ep;
2290 PyObject **value_ptr;
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002292 /* Preallocate the list of tuples, to avoid allocations during
2293 * the loop over the items, which could trigger GC, which
2294 * could resize the dict. :-(
2295 */
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002296 again:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002297 n = mp->ma_used;
2298 v = PyList_New(n);
2299 if (v == NULL)
2300 return NULL;
2301 for (i = 0; i < n; i++) {
2302 item = PyTuple_New(2);
2303 if (item == NULL) {
2304 Py_DECREF(v);
2305 return NULL;
2306 }
2307 PyList_SET_ITEM(v, i, item);
2308 }
2309 if (n != mp->ma_used) {
2310 /* Durnit. The allocations caused the dict to resize.
2311 * Just start over, this shouldn't normally happen.
2312 */
2313 Py_DECREF(v);
2314 goto again;
2315 }
2316 /* Nothing we do below makes any function calls. */
Victor Stinner742da042016-09-07 17:40:12 -07002317 ep = DK_ENTRIES(mp->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002318 if (mp->ma_values) {
2319 value_ptr = mp->ma_values;
2320 offset = sizeof(PyObject *);
2321 }
2322 else {
2323 value_ptr = &ep[0].me_value;
2324 offset = sizeof(PyDictKeyEntry);
2325 }
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002326 for (i = 0, j = 0; j < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002327 PyObject *value = *value_ptr;
2328 value_ptr = (PyObject **)(((char *)value_ptr) + offset);
2329 if (value != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002330 key = ep[i].me_key;
2331 item = PyList_GET_ITEM(v, j);
2332 Py_INCREF(key);
2333 PyTuple_SET_ITEM(item, 0, key);
2334 Py_INCREF(value);
2335 PyTuple_SET_ITEM(item, 1, value);
2336 j++;
2337 }
2338 }
2339 assert(j == n);
2340 return v;
Guido van Rossum25831651993-05-19 14:50:45 +00002341}
2342
Larry Hastings5c661892014-01-24 06:17:25 -08002343/*[clinic input]
2344@classmethod
2345dict.fromkeys
Larry Hastings5c661892014-01-24 06:17:25 -08002346 iterable: object
2347 value: object=None
2348 /
2349
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002350Create a new dictionary with keys from iterable and values set to value.
Larry Hastings5c661892014-01-24 06:17:25 -08002351[clinic start generated code]*/
2352
Larry Hastings5c661892014-01-24 06:17:25 -08002353static PyObject *
2354dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002355/*[clinic end generated code: output=8fb98e4b10384999 input=382ba4855d0f74c3]*/
Larry Hastings5c661892014-01-24 06:17:25 -08002356{
Eric Snow96c6af92015-05-29 22:21:39 -06002357 return _PyDict_FromKeys((PyObject *)type, iterable, value);
Raymond Hettingere33d3df2002-11-27 07:29:33 +00002358}
2359
Brandt Buchereb8ac572020-02-24 19:47:34 -08002360/* Single-arg dict update; used by dict_update_common and operators. */
2361static int
2362dict_update_arg(PyObject *self, PyObject *arg)
2363{
2364 if (PyDict_CheckExact(arg)) {
2365 return PyDict_Merge(self, arg, 1);
2366 }
2367 _Py_IDENTIFIER(keys);
2368 PyObject *func;
2369 if (_PyObject_LookupAttrId(arg, &PyId_keys, &func) < 0) {
2370 return -1;
2371 }
2372 if (func != NULL) {
2373 Py_DECREF(func);
2374 return PyDict_Merge(self, arg, 1);
2375 }
2376 return PyDict_MergeFromSeq2(self, arg, 1);
2377}
2378
Raymond Hettinger31017ae2004-03-04 08:25:44 +00002379static int
Victor Stinner742da042016-09-07 17:40:12 -07002380dict_update_common(PyObject *self, PyObject *args, PyObject *kwds,
2381 const char *methname)
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002382{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002383 PyObject *arg = NULL;
2384 int result = 0;
Raymond Hettinger31017ae2004-03-04 08:25:44 +00002385
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002386 if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 result = -1;
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002388 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002389 else if (arg != NULL) {
Brandt Buchereb8ac572020-02-24 19:47:34 -08002390 result = dict_update_arg(self, arg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002391 }
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 if (result == 0 && kwds != NULL) {
2394 if (PyArg_ValidateKeywordArguments(kwds))
2395 result = PyDict_Merge(self, kwds, 1);
2396 else
2397 result = -1;
2398 }
2399 return result;
Raymond Hettinger31017ae2004-03-04 08:25:44 +00002400}
2401
Victor Stinner91f0d4a2017-01-19 12:45:06 +01002402/* Note: dict.update() uses the METH_VARARGS|METH_KEYWORDS calling convention.
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002403 Using METH_FASTCALL|METH_KEYWORDS would make dict.update(**dict2) calls
2404 slower, see the issue #29312. */
Raymond Hettinger31017ae2004-03-04 08:25:44 +00002405static PyObject *
2406dict_update(PyObject *self, PyObject *args, PyObject *kwds)
2407{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 if (dict_update_common(self, args, kwds, "update") != -1)
2409 Py_RETURN_NONE;
2410 return NULL;
Tim Peters6d6c1a32001-08-02 04:15:00 +00002411}
2412
Guido van Rossum05ac6de2001-08-10 20:28:28 +00002413/* Update unconditionally replaces existing items.
2414 Merge has a 3rd argument 'override'; if set, it acts like Update,
Tim Peters1fc240e2001-10-26 05:06:50 +00002415 otherwise it leaves existing items unchanged.
2416
2417 PyDict_{Update,Merge} update/merge from a mapping object.
2418
Tim Petersf582b822001-12-11 18:51:08 +00002419 PyDict_MergeFromSeq2 updates/merges from any iterable object
Tim Peters1fc240e2001-10-26 05:06:50 +00002420 producing iterable objects of length 2.
2421*/
2422
Tim Petersf582b822001-12-11 18:51:08 +00002423int
Tim Peters1fc240e2001-10-26 05:06:50 +00002424PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)
2425{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 PyObject *it; /* iter(seq2) */
2427 Py_ssize_t i; /* index into seq2 of current element */
2428 PyObject *item; /* seq2[i] */
2429 PyObject *fast; /* item as a 2-tuple or 2-list */
Tim Peters1fc240e2001-10-26 05:06:50 +00002430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002431 assert(d != NULL);
2432 assert(PyDict_Check(d));
2433 assert(seq2 != NULL);
Tim Peters1fc240e2001-10-26 05:06:50 +00002434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002435 it = PyObject_GetIter(seq2);
2436 if (it == NULL)
2437 return -1;
Tim Peters1fc240e2001-10-26 05:06:50 +00002438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002439 for (i = 0; ; ++i) {
2440 PyObject *key, *value;
2441 Py_ssize_t n;
Tim Peters1fc240e2001-10-26 05:06:50 +00002442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002443 fast = NULL;
2444 item = PyIter_Next(it);
2445 if (item == NULL) {
2446 if (PyErr_Occurred())
2447 goto Fail;
2448 break;
2449 }
Tim Peters1fc240e2001-10-26 05:06:50 +00002450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002451 /* Convert item to sequence, and verify length 2. */
2452 fast = PySequence_Fast(item, "");
2453 if (fast == NULL) {
2454 if (PyErr_ExceptionMatches(PyExc_TypeError))
2455 PyErr_Format(PyExc_TypeError,
2456 "cannot convert dictionary update "
2457 "sequence element #%zd to a sequence",
2458 i);
2459 goto Fail;
2460 }
2461 n = PySequence_Fast_GET_SIZE(fast);
2462 if (n != 2) {
2463 PyErr_Format(PyExc_ValueError,
2464 "dictionary update sequence element #%zd "
2465 "has length %zd; 2 is required",
2466 i, n);
2467 goto Fail;
2468 }
Tim Peters1fc240e2001-10-26 05:06:50 +00002469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002470 /* Update/merge with this (key, value) pair. */
2471 key = PySequence_Fast_GET_ITEM(fast, 0);
2472 value = PySequence_Fast_GET_ITEM(fast, 1);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002473 Py_INCREF(key);
2474 Py_INCREF(value);
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002475 if (override) {
2476 if (PyDict_SetItem(d, key, value) < 0) {
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002477 Py_DECREF(key);
2478 Py_DECREF(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002479 goto Fail;
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002480 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002481 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002482 else if (PyDict_GetItemWithError(d, key) == NULL) {
2483 if (PyErr_Occurred() || PyDict_SetItem(d, key, value) < 0) {
2484 Py_DECREF(key);
2485 Py_DECREF(value);
2486 goto Fail;
2487 }
2488 }
2489
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002490 Py_DECREF(key);
2491 Py_DECREF(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002492 Py_DECREF(fast);
2493 Py_DECREF(item);
2494 }
Tim Peters1fc240e2001-10-26 05:06:50 +00002495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002496 i = 0;
Victor Stinner0fc91ee2019-04-12 21:51:34 +02002497 ASSERT_CONSISTENT(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002498 goto Return;
Tim Peters1fc240e2001-10-26 05:06:50 +00002499Fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002500 Py_XDECREF(item);
2501 Py_XDECREF(fast);
2502 i = -1;
Tim Peters1fc240e2001-10-26 05:06:50 +00002503Return:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002504 Py_DECREF(it);
2505 return Py_SAFE_DOWNCAST(i, Py_ssize_t, int);
Tim Peters1fc240e2001-10-26 05:06:50 +00002506}
2507
doko@ubuntu.comc96df682016-10-11 08:04:02 +02002508static int
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002509dict_merge(PyObject *a, PyObject *b, int override)
Guido van Rossum05ac6de2001-08-10 20:28:28 +00002510{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002511 PyDictObject *mp, *other;
2512 Py_ssize_t i, n;
Victor Stinner742da042016-09-07 17:40:12 -07002513 PyDictKeyEntry *entry, *ep0;
Tim Peters6d6c1a32001-08-02 04:15:00 +00002514
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002515 assert(0 <= override && override <= 2);
2516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002517 /* We accept for the argument either a concrete dictionary object,
2518 * or an abstract "mapping" object. For the former, we can do
2519 * things quite efficiently. For the latter, we only require that
2520 * PyMapping_Keys() and PyObject_GetItem() be supported.
2521 */
2522 if (a == NULL || !PyDict_Check(a) || b == NULL) {
2523 PyErr_BadInternalCall();
2524 return -1;
2525 }
2526 mp = (PyDictObject*)a;
INADA Naoki2aaf98c2018-09-26 12:59:00 +09002527 if (PyDict_Check(b) && (Py_TYPE(b)->tp_iter == (getiterfunc)dict_iter)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002528 other = (PyDictObject*)b;
2529 if (other == mp || other->ma_used == 0)
2530 /* a.update(a) or a.update({}); nothing to do */
2531 return 0;
Inada Naokidb6d9a52020-08-04 11:08:06 +09002532 if (mp->ma_used == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002533 /* Since the target dict is empty, PyDict_GetItem()
2534 * always returns NULL. Setting override to 1
2535 * skips the unnecessary test.
2536 */
2537 override = 1;
Inada Naokidb6d9a52020-08-04 11:08:06 +09002538 PyDictKeysObject *okeys = other->ma_keys;
2539
2540 // If other is clean, combined, and just allocated, just clone it.
2541 if (other->ma_values == NULL &&
2542 other->ma_used == okeys->dk_nentries &&
2543 (okeys->dk_size == PyDict_MINSIZE ||
2544 USABLE_FRACTION(okeys->dk_size/2) < other->ma_used)) {
2545 PyDictKeysObject *keys = clone_combined_dict_keys(other);
2546 if (keys == NULL) {
2547 return -1;
2548 }
2549
2550 dictkeys_decref(mp->ma_keys);
2551 mp->ma_keys = keys;
2552 if (mp->ma_values != NULL) {
2553 if (mp->ma_values != empty_values) {
2554 free_values(mp->ma_values);
2555 }
2556 mp->ma_values = NULL;
2557 }
2558
2559 mp->ma_used = other->ma_used;
2560 mp->ma_version_tag = DICT_NEXT_VERSION();
2561 ASSERT_CONSISTENT(mp);
2562
2563 if (_PyObject_GC_IS_TRACKED(other) && !_PyObject_GC_IS_TRACKED(mp)) {
2564 /* Maintain tracking. */
2565 _PyObject_GC_TRACK(mp);
2566 }
2567
2568 return 0;
2569 }
2570 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002571 /* Do one big resize at the start, rather than
2572 * incrementally resizing as we insert new items. Expect
2573 * that there will be no (or few) overlapping keys.
2574 */
INADA Naokib1152be2016-10-27 19:26:50 +09002575 if (USABLE_FRACTION(mp->ma_keys->dk_size) < other->ma_used) {
Inada Naokid9323a82020-08-07 14:08:55 +09002576 if (dictresize(mp, estimate_keysize(mp->ma_used + other->ma_used))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002577 return -1;
INADA Naokib1152be2016-10-27 19:26:50 +09002578 }
2579 }
Victor Stinner742da042016-09-07 17:40:12 -07002580 ep0 = DK_ENTRIES(other->ma_keys);
2581 for (i = 0, n = other->ma_keys->dk_nentries; i < n; i++) {
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002582 PyObject *key, *value;
2583 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07002584 entry = &ep0[i];
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002585 key = entry->me_key;
2586 hash = entry->me_hash;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002587 if (other->ma_values)
2588 value = other->ma_values[i];
2589 else
2590 value = entry->me_value;
2591
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002592 if (value != NULL) {
2593 int err = 0;
2594 Py_INCREF(key);
2595 Py_INCREF(value);
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02002596 if (override == 1)
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002597 err = insertdict(mp, key, hash, value);
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02002598 else if (_PyDict_GetItem_KnownHash(a, key, hash) == NULL) {
2599 if (PyErr_Occurred()) {
2600 Py_DECREF(value);
2601 Py_DECREF(key);
2602 return -1;
2603 }
2604 err = insertdict(mp, key, hash, value);
2605 }
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002606 else if (override != 0) {
2607 _PyErr_SetKeyError(key);
2608 Py_DECREF(value);
2609 Py_DECREF(key);
2610 return -1;
2611 }
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002612 Py_DECREF(value);
2613 Py_DECREF(key);
2614 if (err != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002615 return -1;
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002616
Victor Stinner742da042016-09-07 17:40:12 -07002617 if (n != other->ma_keys->dk_nentries) {
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002618 PyErr_SetString(PyExc_RuntimeError,
2619 "dict mutated during update");
2620 return -1;
2621 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002622 }
2623 }
2624 }
2625 else {
2626 /* Do it the generic, slower way */
2627 PyObject *keys = PyMapping_Keys(b);
2628 PyObject *iter;
2629 PyObject *key, *value;
2630 int status;
Barry Warsaw66a0d1d2001-06-26 20:08:32 +00002631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002632 if (keys == NULL)
2633 /* Docstring says this is equivalent to E.keys() so
2634 * if E doesn't have a .keys() method we want
2635 * AttributeError to percolate up. Might as well
2636 * do the same for any other error.
2637 */
2638 return -1;
Barry Warsaw66a0d1d2001-06-26 20:08:32 +00002639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002640 iter = PyObject_GetIter(keys);
2641 Py_DECREF(keys);
2642 if (iter == NULL)
2643 return -1;
Barry Warsaw66a0d1d2001-06-26 20:08:32 +00002644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002645 for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002646 if (override != 1) {
2647 if (PyDict_GetItemWithError(a, key) != NULL) {
2648 if (override != 0) {
2649 _PyErr_SetKeyError(key);
2650 Py_DECREF(key);
2651 Py_DECREF(iter);
2652 return -1;
2653 }
2654 Py_DECREF(key);
2655 continue;
2656 }
2657 else if (PyErr_Occurred()) {
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002658 Py_DECREF(key);
2659 Py_DECREF(iter);
2660 return -1;
2661 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002662 }
2663 value = PyObject_GetItem(b, key);
2664 if (value == NULL) {
2665 Py_DECREF(iter);
2666 Py_DECREF(key);
2667 return -1;
2668 }
2669 status = PyDict_SetItem(a, key, value);
2670 Py_DECREF(key);
2671 Py_DECREF(value);
2672 if (status < 0) {
2673 Py_DECREF(iter);
2674 return -1;
2675 }
2676 }
2677 Py_DECREF(iter);
2678 if (PyErr_Occurred())
2679 /* Iterator completed, via error */
2680 return -1;
2681 }
Victor Stinner0fc91ee2019-04-12 21:51:34 +02002682 ASSERT_CONSISTENT(a);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002683 return 0;
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002684}
2685
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002686int
2687PyDict_Update(PyObject *a, PyObject *b)
2688{
2689 return dict_merge(a, b, 1);
2690}
2691
2692int
2693PyDict_Merge(PyObject *a, PyObject *b, int override)
2694{
2695 /* XXX Deprecate override not in (0, 1). */
2696 return dict_merge(a, b, override != 0);
2697}
2698
2699int
2700_PyDict_MergeEx(PyObject *a, PyObject *b, int override)
2701{
2702 return dict_merge(a, b, override);
2703}
2704
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002705static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302706dict_copy(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002707{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002708 return PyDict_Copy((PyObject*)mp);
Jeremy Hyltona12c7a72000-03-30 22:27:31 +00002709}
2710
2711PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00002712PyDict_Copy(PyObject *o)
Jeremy Hyltona12c7a72000-03-30 22:27:31 +00002713{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002714 PyObject *copy;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002715 PyDictObject *mp;
2716 Py_ssize_t i, n;
Jeremy Hyltona12c7a72000-03-30 22:27:31 +00002717
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002718 if (o == NULL || !PyDict_Check(o)) {
2719 PyErr_BadInternalCall();
2720 return NULL;
2721 }
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002722
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002723 mp = (PyDictObject *)o;
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002724 if (mp->ma_used == 0) {
2725 /* The dict is empty; just return a new dict. */
2726 return PyDict_New();
2727 }
2728
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002729 if (_PyDict_HasSplitTable(mp)) {
2730 PyDictObject *split_copy;
Victor Stinner742da042016-09-07 17:40:12 -07002731 Py_ssize_t size = USABLE_FRACTION(DK_SIZE(mp->ma_keys));
2732 PyObject **newvalues;
2733 newvalues = new_values(size);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002734 if (newvalues == NULL)
2735 return PyErr_NoMemory();
2736 split_copy = PyObject_GC_New(PyDictObject, &PyDict_Type);
2737 if (split_copy == NULL) {
2738 free_values(newvalues);
2739 return NULL;
2740 }
2741 split_copy->ma_values = newvalues;
2742 split_copy->ma_keys = mp->ma_keys;
2743 split_copy->ma_used = mp->ma_used;
INADA Naokid1c82c52018-04-03 11:43:53 +09002744 split_copy->ma_version_tag = DICT_NEXT_VERSION();
INADA Naokia7576492018-11-14 18:39:27 +09002745 dictkeys_incref(mp->ma_keys);
Victor Stinner742da042016-09-07 17:40:12 -07002746 for (i = 0, n = size; i < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002747 PyObject *value = mp->ma_values[i];
2748 Py_XINCREF(value);
2749 split_copy->ma_values[i] = value;
2750 }
Benjamin Peterson7ce67e42012-04-24 10:32:57 -04002751 if (_PyObject_GC_IS_TRACKED(mp))
2752 _PyObject_GC_TRACK(split_copy);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002753 return (PyObject *)split_copy;
2754 }
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002755
Inada Naokidb6d9a52020-08-04 11:08:06 +09002756 if (Py_TYPE(mp)->tp_iter == (getiterfunc)dict_iter &&
2757 mp->ma_values == NULL &&
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002758 (mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3))
2759 {
2760 /* Use fast-copy if:
2761
Inada Naokidb6d9a52020-08-04 11:08:06 +09002762 (1) type(mp) doesn't override tp_iter; and
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002763
2764 (2) 'mp' is not a split-dict; and
2765
2766 (3) if 'mp' is non-compact ('del' operation does not resize dicts),
2767 do fast-copy only if it has at most 1/3 non-used keys.
2768
Ville Skyttä61f82e02018-04-20 23:08:45 +03002769 The last condition (3) is important to guard against a pathological
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002770 case when a large dict is almost emptied with multiple del/pop
2771 operations and copied after that. In cases like this, we defer to
2772 PyDict_Merge, which produces a compacted copy.
2773 */
Inada Naokidb6d9a52020-08-04 11:08:06 +09002774 PyDictKeysObject *keys = clone_combined_dict_keys(mp);
2775 if (keys == NULL) {
2776 return NULL;
2777 }
2778 PyDictObject *new = (PyDictObject *)new_dict(keys, NULL);
2779 if (new == NULL) {
2780 /* In case of an error, `new_dict()` takes care of
2781 cleaning up `keys`. */
2782 return NULL;
2783 }
2784
2785 new->ma_used = mp->ma_used;
2786 ASSERT_CONSISTENT(new);
2787 if (_PyObject_GC_IS_TRACKED(mp)) {
2788 /* Maintain tracking. */
2789 _PyObject_GC_TRACK(new);
2790 }
2791
2792 return (PyObject *)new;
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002793 }
2794
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002795 copy = PyDict_New();
2796 if (copy == NULL)
2797 return NULL;
Inada Naokidb6d9a52020-08-04 11:08:06 +09002798 if (dict_merge(copy, o, 1) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002799 return copy;
2800 Py_DECREF(copy);
2801 return NULL;
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002802}
2803
Martin v. Löwis18e16552006-02-15 17:27:45 +00002804Py_ssize_t
Tim Peters1f5871e2000-07-04 17:44:48 +00002805PyDict_Size(PyObject *mp)
Guido van Rossum4199fac1993-11-05 10:18:44 +00002806{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002807 if (mp == NULL || !PyDict_Check(mp)) {
2808 PyErr_BadInternalCall();
2809 return -1;
2810 }
2811 return ((PyDictObject *)mp)->ma_used;
Guido van Rossum4199fac1993-11-05 10:18:44 +00002812}
2813
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002814PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00002815PyDict_Keys(PyObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002816{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002817 if (mp == NULL || !PyDict_Check(mp)) {
2818 PyErr_BadInternalCall();
2819 return NULL;
2820 }
2821 return dict_keys((PyDictObject *)mp);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002822}
2823
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002824PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00002825PyDict_Values(PyObject *mp)
Guido van Rossum25831651993-05-19 14:50:45 +00002826{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002827 if (mp == NULL || !PyDict_Check(mp)) {
2828 PyErr_BadInternalCall();
2829 return NULL;
2830 }
2831 return dict_values((PyDictObject *)mp);
Guido van Rossum25831651993-05-19 14:50:45 +00002832}
2833
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002834PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00002835PyDict_Items(PyObject *mp)
Guido van Rossum25831651993-05-19 14:50:45 +00002836{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002837 if (mp == NULL || !PyDict_Check(mp)) {
2838 PyErr_BadInternalCall();
2839 return NULL;
2840 }
2841 return dict_items((PyDictObject *)mp);
Guido van Rossum25831651993-05-19 14:50:45 +00002842}
2843
Tim Peterse63415e2001-05-08 04:38:29 +00002844/* Return 1 if dicts equal, 0 if not, -1 if error.
2845 * Gets out as soon as any difference is detected.
2846 * Uses only Py_EQ comparison.
2847 */
2848static int
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002849dict_equal(PyDictObject *a, PyDictObject *b)
Tim Peterse63415e2001-05-08 04:38:29 +00002850{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002851 Py_ssize_t i;
Tim Peterse63415e2001-05-08 04:38:29 +00002852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002853 if (a->ma_used != b->ma_used)
2854 /* can't be equal if # of entries differ */
2855 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002856 /* Same # of entries -- check all of 'em. Exit early on any diff. */
Victor Stinner742da042016-09-07 17:40:12 -07002857 for (i = 0; i < a->ma_keys->dk_nentries; i++) {
2858 PyDictKeyEntry *ep = &DK_ENTRIES(a->ma_keys)[i];
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002859 PyObject *aval;
2860 if (a->ma_values)
2861 aval = a->ma_values[i];
2862 else
2863 aval = ep->me_value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002864 if (aval != NULL) {
2865 int cmp;
2866 PyObject *bval;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002867 PyObject *key = ep->me_key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002868 /* temporarily bump aval's refcount to ensure it stays
2869 alive until we're done with it */
2870 Py_INCREF(aval);
2871 /* ditto for key */
2872 Py_INCREF(key);
Antoine Pitrou0e9958b2012-12-02 19:10:07 +01002873 /* reuse the known hash value */
INADA Naoki778928b2017-08-03 23:45:15 +09002874 b->ma_keys->dk_lookup(b, key, ep->me_hash, &bval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002875 if (bval == NULL) {
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002876 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002877 Py_DECREF(aval);
2878 if (PyErr_Occurred())
2879 return -1;
2880 return 0;
2881 }
Dong-hee Na2d5bf562019-12-31 10:04:22 +09002882 Py_INCREF(bval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002883 cmp = PyObject_RichCompareBool(aval, bval, Py_EQ);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002884 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002885 Py_DECREF(aval);
Dong-hee Na2d5bf562019-12-31 10:04:22 +09002886 Py_DECREF(bval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002887 if (cmp <= 0) /* error or not equal */
2888 return cmp;
2889 }
2890 }
2891 return 1;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002892}
Tim Peterse63415e2001-05-08 04:38:29 +00002893
2894static PyObject *
2895dict_richcompare(PyObject *v, PyObject *w, int op)
2896{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002897 int cmp;
2898 PyObject *res;
Tim Peterse63415e2001-05-08 04:38:29 +00002899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002900 if (!PyDict_Check(v) || !PyDict_Check(w)) {
2901 res = Py_NotImplemented;
2902 }
2903 else if (op == Py_EQ || op == Py_NE) {
2904 cmp = dict_equal((PyDictObject *)v, (PyDictObject *)w);
2905 if (cmp < 0)
2906 return NULL;
2907 res = (cmp == (op == Py_EQ)) ? Py_True : Py_False;
2908 }
2909 else
2910 res = Py_NotImplemented;
2911 Py_INCREF(res);
2912 return res;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002913}
Tim Peterse63415e2001-05-08 04:38:29 +00002914
Larry Hastings61272b72014-01-07 12:41:53 -08002915/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002916
2917@coexist
2918dict.__contains__
2919
2920 key: object
2921 /
2922
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002923True if the dictionary has the specified key, else False.
Larry Hastings61272b72014-01-07 12:41:53 -08002924[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002925
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002926static PyObject *
Larry Hastingsc2047262014-01-25 20:43:29 -08002927dict___contains__(PyDictObject *self, PyObject *key)
Serhiy Storchaka19d25972017-02-04 08:05:07 +02002928/*[clinic end generated code: output=a3d03db709ed6e6b input=fe1cb42ad831e820]*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002929{
Larry Hastingsc2047262014-01-25 20:43:29 -08002930 register PyDictObject *mp = self;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002931 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07002932 Py_ssize_t ix;
INADA Naokiba609772016-12-07 20:41:42 +09002933 PyObject *value;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002935 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002936 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002937 hash = PyObject_Hash(key);
2938 if (hash == -1)
2939 return NULL;
2940 }
INADA Naoki778928b2017-08-03 23:45:15 +09002941 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07002942 if (ix == DKIX_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002943 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09002944 if (ix == DKIX_EMPTY || value == NULL)
Victor Stinner742da042016-09-07 17:40:12 -07002945 Py_RETURN_FALSE;
2946 Py_RETURN_TRUE;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002947}
2948
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01002949/*[clinic input]
2950dict.get
2951
2952 key: object
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02002953 default: object = None
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01002954 /
2955
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002956Return the value for key if key is in the dictionary, else default.
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01002957[clinic start generated code]*/
2958
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002959static PyObject *
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02002960dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002961/*[clinic end generated code: output=bba707729dee05bf input=279ddb5790b6b107]*/
Barry Warsawc38c5da1997-10-06 17:49:20 +00002962{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002963 PyObject *val = NULL;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002964 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07002965 Py_ssize_t ix;
Barry Warsawc38c5da1997-10-06 17:49:20 +00002966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002967 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002968 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002969 hash = PyObject_Hash(key);
2970 if (hash == -1)
2971 return NULL;
2972 }
INADA Naoki778928b2017-08-03 23:45:15 +09002973 ix = (self->ma_keys->dk_lookup) (self, key, hash, &val);
Victor Stinner742da042016-09-07 17:40:12 -07002974 if (ix == DKIX_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002975 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09002976 if (ix == DKIX_EMPTY || val == NULL) {
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02002977 val = default_value;
INADA Naokiba609772016-12-07 20:41:42 +09002978 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002979 Py_INCREF(val);
2980 return val;
Barry Warsawc38c5da1997-10-06 17:49:20 +00002981}
2982
Benjamin Peterson00e98862013-03-07 22:16:29 -05002983PyObject *
2984PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj)
Guido van Rossum164452c2000-08-08 16:12:54 +00002985{
Benjamin Peterson00e98862013-03-07 22:16:29 -05002986 PyDictObject *mp = (PyDictObject *)d;
INADA Naoki93f26f72016-11-02 18:45:16 +09002987 PyObject *value;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002988 Py_hash_t hash;
Guido van Rossum164452c2000-08-08 16:12:54 +00002989
Benjamin Peterson00e98862013-03-07 22:16:29 -05002990 if (!PyDict_Check(d)) {
2991 PyErr_BadInternalCall();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002992 return NULL;
Benjamin Peterson00e98862013-03-07 22:16:29 -05002993 }
INADA Naoki93f26f72016-11-02 18:45:16 +09002994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002995 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002996 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002997 hash = PyObject_Hash(key);
2998 if (hash == -1)
2999 return NULL;
3000 }
Inada Naoki2ddc7f62019-03-18 20:38:33 +09003001 if (mp->ma_keys == Py_EMPTY_KEYS) {
3002 if (insert_to_emptydict(mp, key, hash, defaultobj) < 0) {
3003 return NULL;
3004 }
3005 return defaultobj;
3006 }
INADA Naoki93f26f72016-11-02 18:45:16 +09003007
3008 if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) {
3009 if (insertion_resize(mp) < 0)
3010 return NULL;
3011 }
3012
INADA Naoki778928b2017-08-03 23:45:15 +09003013 Py_ssize_t ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07003014 if (ix == DKIX_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003015 return NULL;
INADA Naoki93f26f72016-11-02 18:45:16 +09003016
3017 if (_PyDict_HasSplitTable(mp) &&
INADA Naokiba609772016-12-07 20:41:42 +09003018 ((ix >= 0 && value == NULL && mp->ma_used != ix) ||
INADA Naoki93f26f72016-11-02 18:45:16 +09003019 (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) {
3020 if (insertion_resize(mp) < 0) {
3021 return NULL;
3022 }
INADA Naoki93f26f72016-11-02 18:45:16 +09003023 ix = DKIX_EMPTY;
3024 }
3025
3026 if (ix == DKIX_EMPTY) {
3027 PyDictKeyEntry *ep, *ep0;
3028 value = defaultobj;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003029 if (mp->ma_keys->dk_usable <= 0) {
Victor Stinner3c336c52016-09-12 14:17:40 +02003030 if (insertion_resize(mp) < 0) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003031 return NULL;
Victor Stinner3c336c52016-09-12 14:17:40 +02003032 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003033 }
INADA Naoki778928b2017-08-03 23:45:15 +09003034 Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash);
INADA Naoki93f26f72016-11-02 18:45:16 +09003035 ep0 = DK_ENTRIES(mp->ma_keys);
3036 ep = &ep0[mp->ma_keys->dk_nentries];
INADA Naokia7576492018-11-14 18:39:27 +09003037 dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
Benjamin Petersonb1efa532013-03-04 09:47:50 -05003038 Py_INCREF(key);
INADA Naoki93f26f72016-11-02 18:45:16 +09003039 Py_INCREF(value);
3040 MAINTAIN_TRACKING(mp, key, value);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003041 ep->me_key = key;
3042 ep->me_hash = hash;
INADA Naokiba609772016-12-07 20:41:42 +09003043 if (_PyDict_HasSplitTable(mp)) {
INADA Naoki93f26f72016-11-02 18:45:16 +09003044 assert(mp->ma_values[mp->ma_keys->dk_nentries] == NULL);
3045 mp->ma_values[mp->ma_keys->dk_nentries] = value;
Victor Stinner742da042016-09-07 17:40:12 -07003046 }
3047 else {
INADA Naoki93f26f72016-11-02 18:45:16 +09003048 ep->me_value = value;
Victor Stinner742da042016-09-07 17:40:12 -07003049 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003050 mp->ma_used++;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07003051 mp->ma_version_tag = DICT_NEXT_VERSION();
INADA Naoki93f26f72016-11-02 18:45:16 +09003052 mp->ma_keys->dk_usable--;
3053 mp->ma_keys->dk_nentries++;
3054 assert(mp->ma_keys->dk_usable >= 0);
3055 }
INADA Naokiba609772016-12-07 20:41:42 +09003056 else if (value == NULL) {
INADA Naoki93f26f72016-11-02 18:45:16 +09003057 value = defaultobj;
3058 assert(_PyDict_HasSplitTable(mp));
3059 assert(ix == mp->ma_used);
3060 Py_INCREF(value);
3061 MAINTAIN_TRACKING(mp, key, value);
INADA Naokiba609772016-12-07 20:41:42 +09003062 mp->ma_values[ix] = value;
INADA Naoki93f26f72016-11-02 18:45:16 +09003063 mp->ma_used++;
3064 mp->ma_version_tag = DICT_NEXT_VERSION();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003065 }
INADA Naoki93f26f72016-11-02 18:45:16 +09003066
Victor Stinner0fc91ee2019-04-12 21:51:34 +02003067 ASSERT_CONSISTENT(mp);
INADA Naoki93f26f72016-11-02 18:45:16 +09003068 return value;
Guido van Rossum164452c2000-08-08 16:12:54 +00003069}
3070
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003071/*[clinic input]
3072dict.setdefault
3073
3074 key: object
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02003075 default: object = None
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003076 /
3077
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02003078Insert key with a value of default if key is not in the dictionary.
3079
3080Return the value for key if key is in the dictionary, else default.
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003081[clinic start generated code]*/
3082
Benjamin Peterson00e98862013-03-07 22:16:29 -05003083static PyObject *
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02003084dict_setdefault_impl(PyDictObject *self, PyObject *key,
3085 PyObject *default_value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02003086/*[clinic end generated code: output=f8c1101ebf69e220 input=0f063756e815fd9d]*/
Benjamin Peterson00e98862013-03-07 22:16:29 -05003087{
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003088 PyObject *val;
Benjamin Peterson00e98862013-03-07 22:16:29 -05003089
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02003090 val = PyDict_SetDefault((PyObject *)self, key, default_value);
Benjamin Peterson00e98862013-03-07 22:16:29 -05003091 Py_XINCREF(val);
3092 return val;
3093}
Guido van Rossum164452c2000-08-08 16:12:54 +00003094
3095static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303096dict_clear(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +00003097{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003098 PyDict_Clear((PyObject *)mp);
3099 Py_RETURN_NONE;
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +00003100}
3101
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003102/*[clinic input]
3103dict.pop
3104
3105 key: object
3106 default: object = NULL
3107 /
3108
Serhiy Storchaka279f4462019-09-14 12:24:05 +03003109D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003110
Serhiy Storchaka6bf323732020-07-19 09:18:55 +03003111If the key is not found, return the default if given; otherwise,
3112raise a KeyError.
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003113[clinic start generated code]*/
3114
Guido van Rossumba6ab842000-12-12 22:02:18 +00003115static PyObject *
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003116dict_pop_impl(PyDictObject *self, PyObject *key, PyObject *default_value)
Serhiy Storchaka6bf323732020-07-19 09:18:55 +03003117/*[clinic end generated code: output=3abb47b89f24c21c input=e221baa01044c44c]*/
Guido van Rossume027d982002-04-12 15:11:59 +00003118{
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003119 return _PyDict_Pop((PyObject*)self, key, default_value);
Guido van Rossume027d982002-04-12 15:11:59 +00003120}
3121
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003122/*[clinic input]
3123dict.popitem
3124
3125Remove and return a (key, value) pair as a 2-tuple.
3126
3127Pairs are returned in LIFO (last-in, first-out) order.
3128Raises KeyError if the dict is empty.
3129[clinic start generated code]*/
3130
Guido van Rossume027d982002-04-12 15:11:59 +00003131static PyObject *
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003132dict_popitem_impl(PyDictObject *self)
3133/*[clinic end generated code: output=e65fcb04420d230d input=1c38a49f21f64941]*/
Guido van Rossumba6ab842000-12-12 22:02:18 +00003134{
Victor Stinner742da042016-09-07 17:40:12 -07003135 Py_ssize_t i, j;
3136 PyDictKeyEntry *ep0, *ep;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003137 PyObject *res;
Guido van Rossumba6ab842000-12-12 22:02:18 +00003138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003139 /* Allocate the result tuple before checking the size. Believe it
3140 * or not, this allocation could trigger a garbage collection which
3141 * could empty the dict, so if we checked the size first and that
3142 * happened, the result would be an infinite loop (searching for an
3143 * entry that no longer exists). Note that the usual popitem()
3144 * idiom is "while d: k, v = d.popitem()". so needing to throw the
3145 * tuple away if the dict *is* empty isn't a significant
3146 * inefficiency -- possible, but unlikely in practice.
3147 */
3148 res = PyTuple_New(2);
3149 if (res == NULL)
3150 return NULL;
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003151 if (self->ma_used == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003152 Py_DECREF(res);
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003153 PyErr_SetString(PyExc_KeyError, "popitem(): dictionary is empty");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003154 return NULL;
3155 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003156 /* Convert split table to combined table */
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003157 if (self->ma_keys->dk_lookup == lookdict_split) {
3158 if (dictresize(self, DK_SIZE(self->ma_keys))) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003159 Py_DECREF(res);
3160 return NULL;
3161 }
3162 }
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003163 ENSURE_ALLOWS_DELETIONS(self);
Victor Stinner742da042016-09-07 17:40:12 -07003164
3165 /* Pop last item */
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003166 ep0 = DK_ENTRIES(self->ma_keys);
3167 i = self->ma_keys->dk_nentries - 1;
Victor Stinner742da042016-09-07 17:40:12 -07003168 while (i >= 0 && ep0[i].me_value == NULL) {
3169 i--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003170 }
Victor Stinner742da042016-09-07 17:40:12 -07003171 assert(i >= 0);
3172
3173 ep = &ep0[i];
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003174 j = lookdict_index(self->ma_keys, ep->me_hash, i);
Victor Stinner742da042016-09-07 17:40:12 -07003175 assert(j >= 0);
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003176 assert(dictkeys_get_index(self->ma_keys, j) == i);
3177 dictkeys_set_index(self->ma_keys, j, DKIX_DUMMY);
Victor Stinner742da042016-09-07 17:40:12 -07003178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003179 PyTuple_SET_ITEM(res, 0, ep->me_key);
3180 PyTuple_SET_ITEM(res, 1, ep->me_value);
Victor Stinner742da042016-09-07 17:40:12 -07003181 ep->me_key = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003182 ep->me_value = NULL;
Victor Stinner742da042016-09-07 17:40:12 -07003183 /* We can't dk_usable++ since there is DKIX_DUMMY in indices */
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003184 self->ma_keys->dk_nentries = i;
3185 self->ma_used--;
3186 self->ma_version_tag = DICT_NEXT_VERSION();
Victor Stinner0fc91ee2019-04-12 21:51:34 +02003187 ASSERT_CONSISTENT(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003188 return res;
Guido van Rossumba6ab842000-12-12 22:02:18 +00003189}
3190
Jeremy Hylton8caad492000-06-23 14:18:11 +00003191static int
3192dict_traverse(PyObject *op, visitproc visit, void *arg)
3193{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003194 PyDictObject *mp = (PyDictObject *)op;
Benjamin Peterson55f44522016-09-05 12:12:59 -07003195 PyDictKeysObject *keys = mp->ma_keys;
Serhiy Storchaka46825d22016-09-26 21:29:34 +03003196 PyDictKeyEntry *entries = DK_ENTRIES(keys);
Victor Stinner742da042016-09-07 17:40:12 -07003197 Py_ssize_t i, n = keys->dk_nentries;
3198
Benjamin Peterson55f44522016-09-05 12:12:59 -07003199 if (keys->dk_lookup == lookdict) {
3200 for (i = 0; i < n; i++) {
3201 if (entries[i].me_value != NULL) {
3202 Py_VISIT(entries[i].me_value);
3203 Py_VISIT(entries[i].me_key);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003204 }
3205 }
Victor Stinner742da042016-09-07 17:40:12 -07003206 }
3207 else {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003208 if (mp->ma_values != NULL) {
Benjamin Peterson55f44522016-09-05 12:12:59 -07003209 for (i = 0; i < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003210 Py_VISIT(mp->ma_values[i]);
3211 }
3212 }
3213 else {
Benjamin Peterson55f44522016-09-05 12:12:59 -07003214 for (i = 0; i < n; i++) {
3215 Py_VISIT(entries[i].me_value);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003216 }
3217 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003218 }
3219 return 0;
Jeremy Hylton8caad492000-06-23 14:18:11 +00003220}
3221
3222static int
3223dict_tp_clear(PyObject *op)
3224{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003225 PyDict_Clear(op);
3226 return 0;
Jeremy Hylton8caad492000-06-23 14:18:11 +00003227}
3228
Guido van Rossum8ce8a782007-11-01 19:42:39 +00003229static PyObject *dictiter_new(PyDictObject *, PyTypeObject *);
Guido van Rossum09e563a2001-05-01 12:10:21 +00003230
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +02003231Py_ssize_t
Eric Snow96c6af92015-05-29 22:21:39 -06003232_PyDict_SizeOf(PyDictObject *mp)
Martin v. Löwis00709aa2008-06-04 14:18:43 +00003233{
Victor Stinner742da042016-09-07 17:40:12 -07003234 Py_ssize_t size, usable, res;
Martin v. Löwis00709aa2008-06-04 14:18:43 +00003235
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003236 size = DK_SIZE(mp->ma_keys);
Victor Stinner742da042016-09-07 17:40:12 -07003237 usable = USABLE_FRACTION(size);
3238
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02003239 res = _PyObject_SIZE(Py_TYPE(mp));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003240 if (mp->ma_values)
Victor Stinner742da042016-09-07 17:40:12 -07003241 res += usable * sizeof(PyObject*);
Martin v. Loewis4f2f3b62012-04-24 19:13:57 +02003242 /* If the dictionary is split, the keys portion is accounted-for
3243 in the type object. */
3244 if (mp->ma_keys->dk_refcnt == 1)
Victor Stinner98ee9d52016-09-08 09:33:56 -07003245 res += (sizeof(PyDictKeysObject)
Victor Stinner98ee9d52016-09-08 09:33:56 -07003246 + DK_IXSIZE(mp->ma_keys) * size
3247 + sizeof(PyDictKeyEntry) * usable);
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +02003248 return res;
Martin v. Loewis4f2f3b62012-04-24 19:13:57 +02003249}
3250
3251Py_ssize_t
3252_PyDict_KeysSize(PyDictKeysObject *keys)
3253{
Victor Stinner98ee9d52016-09-08 09:33:56 -07003254 return (sizeof(PyDictKeysObject)
Victor Stinner98ee9d52016-09-08 09:33:56 -07003255 + DK_IXSIZE(keys) * DK_SIZE(keys)
3256 + USABLE_FRACTION(DK_SIZE(keys)) * sizeof(PyDictKeyEntry));
Martin v. Löwis00709aa2008-06-04 14:18:43 +00003257}
3258
doko@ubuntu.com17210f52016-01-14 14:04:59 +01003259static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303260dict_sizeof(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +02003261{
3262 return PyLong_FromSsize_t(_PyDict_SizeOf(mp));
3263}
3264
Brandt Buchereb8ac572020-02-24 19:47:34 -08003265static PyObject *
3266dict_or(PyObject *self, PyObject *other)
3267{
3268 if (!PyDict_Check(self) || !PyDict_Check(other)) {
3269 Py_RETURN_NOTIMPLEMENTED;
3270 }
3271 PyObject *new = PyDict_Copy(self);
3272 if (new == NULL) {
3273 return NULL;
3274 }
3275 if (dict_update_arg(new, other)) {
3276 Py_DECREF(new);
3277 return NULL;
3278 }
3279 return new;
3280}
3281
3282static PyObject *
3283dict_ior(PyObject *self, PyObject *other)
3284{
3285 if (dict_update_arg(self, other)) {
3286 return NULL;
3287 }
3288 Py_INCREF(self);
3289 return self;
3290}
3291
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00003292PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]");
3293
Martin v. Löwis00709aa2008-06-04 14:18:43 +00003294PyDoc_STRVAR(sizeof__doc__,
3295"D.__sizeof__() -> size of D in memory, in bytes");
3296
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003297PyDoc_STRVAR(update__doc__,
Brett Cannonf2754162013-05-11 14:46:48 -04003298"D.update([E, ]**F) -> None. Update D from dict/iterable E and F.\n\
3299If E is present and has a .keys() method, then does: for k in E: D[k] = E[k]\n\
3300If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v\n\
3301In either case, this is followed by: for k in F: D[k] = F[k]");
Tim Petersf7f88b12000-12-13 23:18:45 +00003302
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003303PyDoc_STRVAR(clear__doc__,
3304"D.clear() -> None. Remove all items from D.");
Tim Petersf7f88b12000-12-13 23:18:45 +00003305
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003306PyDoc_STRVAR(copy__doc__,
3307"D.copy() -> a shallow copy of D");
Tim Petersf7f88b12000-12-13 23:18:45 +00003308
Guido van Rossumb90c8482007-02-10 01:11:45 +00003309/* Forward */
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303310static PyObject *dictkeys_new(PyObject *, PyObject *);
3311static PyObject *dictitems_new(PyObject *, PyObject *);
3312static PyObject *dictvalues_new(PyObject *, PyObject *);
Guido van Rossumb90c8482007-02-10 01:11:45 +00003313
Guido van Rossum45c85d12007-07-27 16:31:40 +00003314PyDoc_STRVAR(keys__doc__,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003315 "D.keys() -> a set-like object providing a view on D's keys");
Guido van Rossum45c85d12007-07-27 16:31:40 +00003316PyDoc_STRVAR(items__doc__,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003317 "D.items() -> a set-like object providing a view on D's items");
Guido van Rossum45c85d12007-07-27 16:31:40 +00003318PyDoc_STRVAR(values__doc__,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003319 "D.values() -> an object providing a view on D's values");
Guido van Rossumb90c8482007-02-10 01:11:45 +00003320
Guido van Rossumc0b618a1997-05-02 03:12:38 +00003321static PyMethodDef mapp_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -07003322 DICT___CONTAINS___METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003323 {"__getitem__", (PyCFunction)(void(*)(void))dict_subscript, METH_O | METH_COEXIST,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003324 getitem__doc__},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003325 {"__sizeof__", (PyCFunction)(void(*)(void))dict_sizeof, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003326 sizeof__doc__},
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003327 DICT_GET_METHODDEF
3328 DICT_SETDEFAULT_METHODDEF
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003329 DICT_POP_METHODDEF
3330 DICT_POPITEM_METHODDEF
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303331 {"keys", dictkeys_new, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003332 keys__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303333 {"items", dictitems_new, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003334 items__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303335 {"values", dictvalues_new, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003336 values__doc__},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003337 {"update", (PyCFunction)(void(*)(void))dict_update, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003338 update__doc__},
Larry Hastings5c661892014-01-24 06:17:25 -08003339 DICT_FROMKEYS_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003340 {"clear", (PyCFunction)dict_clear, METH_NOARGS,
3341 clear__doc__},
3342 {"copy", (PyCFunction)dict_copy, METH_NOARGS,
3343 copy__doc__},
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003344 DICT___REVERSED___METHODDEF
Guido van Rossum48b069a2020-04-07 09:50:06 -07003345 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003346 {NULL, NULL} /* sentinel */
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003347};
3348
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00003349/* Return 1 if `key` is in dict `op`, 0 if not, and -1 on error. */
Raymond Hettingerbc0f2ab2003-11-25 21:12:14 +00003350int
3351PyDict_Contains(PyObject *op, PyObject *key)
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003352{
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003353 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07003354 Py_ssize_t ix;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003355 PyDictObject *mp = (PyDictObject *)op;
INADA Naokiba609772016-12-07 20:41:42 +09003356 PyObject *value;
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003358 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003359 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003360 hash = PyObject_Hash(key);
3361 if (hash == -1)
3362 return -1;
3363 }
INADA Naoki778928b2017-08-03 23:45:15 +09003364 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07003365 if (ix == DKIX_ERROR)
3366 return -1;
INADA Naokiba609772016-12-07 20:41:42 +09003367 return (ix != DKIX_EMPTY && value != NULL);
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003368}
3369
Thomas Wouterscf297e42007-02-23 15:07:44 +00003370/* Internal version of PyDict_Contains used when the hash value is already known */
3371int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003372_PyDict_Contains(PyObject *op, PyObject *key, Py_hash_t hash)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003373{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003374 PyDictObject *mp = (PyDictObject *)op;
INADA Naokiba609772016-12-07 20:41:42 +09003375 PyObject *value;
Victor Stinner742da042016-09-07 17:40:12 -07003376 Py_ssize_t ix;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003377
INADA Naoki778928b2017-08-03 23:45:15 +09003378 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07003379 if (ix == DKIX_ERROR)
3380 return -1;
INADA Naokiba609772016-12-07 20:41:42 +09003381 return (ix != DKIX_EMPTY && value != NULL);
Thomas Wouterscf297e42007-02-23 15:07:44 +00003382}
3383
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003384/* Hack to implement "key in dict" */
3385static PySequenceMethods dict_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003386 0, /* sq_length */
3387 0, /* sq_concat */
3388 0, /* sq_repeat */
3389 0, /* sq_item */
3390 0, /* sq_slice */
3391 0, /* sq_ass_item */
3392 0, /* sq_ass_slice */
3393 PyDict_Contains, /* sq_contains */
3394 0, /* sq_inplace_concat */
3395 0, /* sq_inplace_repeat */
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003396};
3397
Brandt Buchereb8ac572020-02-24 19:47:34 -08003398static PyNumberMethods dict_as_number = {
3399 .nb_or = dict_or,
3400 .nb_inplace_or = dict_ior,
3401};
3402
Guido van Rossum09e563a2001-05-01 12:10:21 +00003403static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +00003404dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3405{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003406 PyObject *self;
Victor Stinnera9f61a52013-07-16 22:17:26 +02003407 PyDictObject *d;
Tim Peters6d6c1a32001-08-02 04:15:00 +00003408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003409 assert(type != NULL && type->tp_alloc != NULL);
3410 self = type->tp_alloc(type, 0);
Victor Stinnera9f61a52013-07-16 22:17:26 +02003411 if (self == NULL)
3412 return NULL;
Victor Stinnera9f61a52013-07-16 22:17:26 +02003413 d = (PyDictObject *)self;
Victor Stinnerac2a4fe2013-07-16 22:19:00 +02003414
Victor Stinnera9f61a52013-07-16 22:17:26 +02003415 /* The object has been implicitly tracked by tp_alloc */
Inada Naokidb6d9a52020-08-04 11:08:06 +09003416 if (type == &PyDict_Type) {
Victor Stinnera9f61a52013-07-16 22:17:26 +02003417 _PyObject_GC_UNTRACK(d);
Inada Naokidb6d9a52020-08-04 11:08:06 +09003418 }
Victor Stinnerac2a4fe2013-07-16 22:19:00 +02003419
3420 d->ma_used = 0;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07003421 d->ma_version_tag = DICT_NEXT_VERSION();
Inada Naokidb6d9a52020-08-04 11:08:06 +09003422 dictkeys_incref(Py_EMPTY_KEYS);
3423 d->ma_keys = Py_EMPTY_KEYS;
3424 d->ma_values = empty_values;
Victor Stinner0fc91ee2019-04-12 21:51:34 +02003425 ASSERT_CONSISTENT(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003426 return self;
Tim Peters6d6c1a32001-08-02 04:15:00 +00003427}
3428
Tim Peters25786c02001-09-02 08:22:48 +00003429static int
3430dict_init(PyObject *self, PyObject *args, PyObject *kwds)
3431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003432 return dict_update_common(self, args, kwds, "dict");
Tim Peters25786c02001-09-02 08:22:48 +00003433}
3434
Tim Peters6d6c1a32001-08-02 04:15:00 +00003435static PyObject *
Dong-hee Nae27916b2020-04-02 09:55:43 +09003436dict_vectorcall(PyObject *type, PyObject * const*args,
3437 size_t nargsf, PyObject *kwnames)
3438{
3439 assert(PyType_Check(type));
3440 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
3441 if (!_PyArg_CheckPositional("dict", nargs, 0, 1)) {
3442 return NULL;
3443 }
3444
3445 PyObject *self = dict_new((PyTypeObject *)type, NULL, NULL);
3446 if (self == NULL) {
3447 return NULL;
3448 }
3449 if (nargs == 1) {
3450 if (dict_update_arg(self, args[0]) < 0) {
3451 Py_DECREF(self);
3452 return NULL;
3453 }
3454 args++;
3455 }
3456 if (kwnames != NULL) {
3457 for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(kwnames); i++) {
3458 if (PyDict_SetItem(self, PyTuple_GET_ITEM(kwnames, i), args[i]) < 0) {
3459 Py_DECREF(self);
3460 return NULL;
3461 }
3462 }
3463 }
3464 return self;
3465}
3466
3467static PyObject *
Guido van Rossum8ce8a782007-11-01 19:42:39 +00003468dict_iter(PyDictObject *dict)
Guido van Rossum09e563a2001-05-01 12:10:21 +00003469{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003470 return dictiter_new(dict, &PyDictIterKey_Type);
Guido van Rossum09e563a2001-05-01 12:10:21 +00003471}
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003472
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003473PyDoc_STRVAR(dictionary_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00003474"dict() -> new empty dictionary\n"
Tim Petersa427a2b2001-10-29 22:25:45 +00003475"dict(mapping) -> new dictionary initialized from a mapping object's\n"
Ezio Melotti7f807b72010-03-01 04:08:34 +00003476" (key, value) pairs\n"
3477"dict(iterable) -> new dictionary initialized as if via:\n"
Tim Peters4d859532001-10-27 18:27:48 +00003478" d = {}\n"
Ezio Melotti7f807b72010-03-01 04:08:34 +00003479" for k, v in iterable:\n"
Just van Rossuma797d812002-11-23 09:45:04 +00003480" d[k] = v\n"
3481"dict(**kwargs) -> new dictionary initialized with the name=value pairs\n"
3482" in the keyword argument list. For example: dict(one=1, two=2)");
Tim Peters25786c02001-09-02 08:22:48 +00003483
Guido van Rossumc0b618a1997-05-02 03:12:38 +00003484PyTypeObject PyDict_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003485 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3486 "dict",
3487 sizeof(PyDictObject),
3488 0,
3489 (destructor)dict_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003490 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003491 0, /* tp_getattr */
3492 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003493 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003494 (reprfunc)dict_repr, /* tp_repr */
Brandt Buchereb8ac572020-02-24 19:47:34 -08003495 &dict_as_number, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003496 &dict_as_sequence, /* tp_as_sequence */
3497 &dict_as_mapping, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00003498 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003499 0, /* tp_call */
3500 0, /* tp_str */
3501 PyObject_GenericGetAttr, /* tp_getattro */
3502 0, /* tp_setattro */
3503 0, /* tp_as_buffer */
3504 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
3505 Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DICT_SUBCLASS, /* tp_flags */
3506 dictionary_doc, /* tp_doc */
3507 dict_traverse, /* tp_traverse */
3508 dict_tp_clear, /* tp_clear */
3509 dict_richcompare, /* tp_richcompare */
3510 0, /* tp_weaklistoffset */
3511 (getiterfunc)dict_iter, /* tp_iter */
3512 0, /* tp_iternext */
3513 mapp_methods, /* tp_methods */
3514 0, /* tp_members */
3515 0, /* tp_getset */
3516 0, /* tp_base */
3517 0, /* tp_dict */
3518 0, /* tp_descr_get */
3519 0, /* tp_descr_set */
3520 0, /* tp_dictoffset */
3521 dict_init, /* tp_init */
3522 PyType_GenericAlloc, /* tp_alloc */
3523 dict_new, /* tp_new */
3524 PyObject_GC_Del, /* tp_free */
Dong-hee Nae27916b2020-04-02 09:55:43 +09003525 .tp_vectorcall = dict_vectorcall,
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003526};
3527
Victor Stinner3c1e4812012-03-26 22:10:51 +02003528PyObject *
3529_PyDict_GetItemId(PyObject *dp, struct _Py_Identifier *key)
3530{
3531 PyObject *kv;
3532 kv = _PyUnicode_FromId(key); /* borrowed */
Victor Stinner5b3b1002013-07-22 23:50:57 +02003533 if (kv == NULL) {
3534 PyErr_Clear();
Victor Stinner3c1e4812012-03-26 22:10:51 +02003535 return NULL;
Victor Stinner5b3b1002013-07-22 23:50:57 +02003536 }
Victor Stinner3c1e4812012-03-26 22:10:51 +02003537 return PyDict_GetItem(dp, kv);
3538}
3539
Guido van Rossum3cca2451997-05-16 14:23:33 +00003540/* For backward compatibility with old dictionary interface */
3541
Guido van Rossumc0b618a1997-05-02 03:12:38 +00003542PyObject *
Martin v. Löwis32b4a1b2002-12-11 13:21:12 +00003543PyDict_GetItemString(PyObject *v, const char *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003544{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003545 PyObject *kv, *rv;
3546 kv = PyUnicode_FromString(key);
Victor Stinnerfdcbab92013-07-16 22:16:05 +02003547 if (kv == NULL) {
3548 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003549 return NULL;
Victor Stinnerfdcbab92013-07-16 22:16:05 +02003550 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003551 rv = PyDict_GetItem(v, kv);
3552 Py_DECREF(kv);
3553 return rv;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003554}
3555
3556int
Victor Stinner3c1e4812012-03-26 22:10:51 +02003557_PyDict_SetItemId(PyObject *v, struct _Py_Identifier *key, PyObject *item)
3558{
3559 PyObject *kv;
3560 kv = _PyUnicode_FromId(key); /* borrowed */
3561 if (kv == NULL)
3562 return -1;
3563 return PyDict_SetItem(v, kv, item);
3564}
3565
3566int
Martin v. Löwis32b4a1b2002-12-11 13:21:12 +00003567PyDict_SetItemString(PyObject *v, const char *key, PyObject *item)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003568{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003569 PyObject *kv;
3570 int err;
3571 kv = PyUnicode_FromString(key);
3572 if (kv == NULL)
3573 return -1;
3574 PyUnicode_InternInPlace(&kv); /* XXX Should we really? */
3575 err = PyDict_SetItem(v, kv, item);
3576 Py_DECREF(kv);
3577 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003578}
3579
3580int
Victor Stinner5fd2e5a2013-11-06 18:58:22 +01003581_PyDict_DelItemId(PyObject *v, _Py_Identifier *key)
3582{
3583 PyObject *kv = _PyUnicode_FromId(key); /* borrowed */
3584 if (kv == NULL)
3585 return -1;
3586 return PyDict_DelItem(v, kv);
3587}
3588
3589int
Martin v. Löwis32b4a1b2002-12-11 13:21:12 +00003590PyDict_DelItemString(PyObject *v, const char *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003591{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003592 PyObject *kv;
3593 int err;
3594 kv = PyUnicode_FromString(key);
3595 if (kv == NULL)
3596 return -1;
3597 err = PyDict_DelItem(v, kv);
3598 Py_DECREF(kv);
3599 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003600}
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003601
Raymond Hettinger019a1482004-03-18 02:41:19 +00003602/* Dictionary iterator types */
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003603
3604typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003605 PyObject_HEAD
3606 PyDictObject *di_dict; /* Set to NULL when iterator is exhausted */
3607 Py_ssize_t di_used;
3608 Py_ssize_t di_pos;
3609 PyObject* di_result; /* reusable result tuple for iteritems */
3610 Py_ssize_t len;
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003611} dictiterobject;
3612
3613static PyObject *
Guido van Rossum8ce8a782007-11-01 19:42:39 +00003614dictiter_new(PyDictObject *dict, PyTypeObject *itertype)
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003615{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003616 dictiterobject *di;
3617 di = PyObject_GC_New(dictiterobject, itertype);
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003618 if (di == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003619 return NULL;
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003620 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003621 Py_INCREF(dict);
3622 di->di_dict = dict;
3623 di->di_used = dict->ma_used;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003624 di->len = dict->ma_used;
Dong-hee Na24dc2f82019-10-20 05:01:08 +09003625 if (itertype == &PyDictRevIterKey_Type ||
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003626 itertype == &PyDictRevIterItem_Type ||
Dong-hee Na24dc2f82019-10-20 05:01:08 +09003627 itertype == &PyDictRevIterValue_Type) {
3628 if (dict->ma_values) {
3629 di->di_pos = dict->ma_used - 1;
3630 }
3631 else {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003632 di->di_pos = dict->ma_keys->dk_nentries - 1;
Dong-hee Na24dc2f82019-10-20 05:01:08 +09003633 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003634 }
3635 else {
3636 di->di_pos = 0;
3637 }
3638 if (itertype == &PyDictIterItem_Type ||
3639 itertype == &PyDictRevIterItem_Type) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003640 di->di_result = PyTuple_Pack(2, Py_None, Py_None);
3641 if (di->di_result == NULL) {
3642 Py_DECREF(di);
3643 return NULL;
3644 }
3645 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003646 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003647 di->di_result = NULL;
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003648 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003649 _PyObject_GC_TRACK(di);
3650 return (PyObject *)di;
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003651}
3652
3653static void
3654dictiter_dealloc(dictiterobject *di)
3655{
INADA Naokia6296d32017-08-24 14:55:17 +09003656 /* bpo-31095: UnTrack is needed before calling any callbacks */
3657 _PyObject_GC_UNTRACK(di);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003658 Py_XDECREF(di->di_dict);
3659 Py_XDECREF(di->di_result);
3660 PyObject_GC_Del(di);
Antoine Pitrou7ddda782009-01-01 15:35:33 +00003661}
3662
3663static int
3664dictiter_traverse(dictiterobject *di, visitproc visit, void *arg)
3665{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003666 Py_VISIT(di->di_dict);
3667 Py_VISIT(di->di_result);
3668 return 0;
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003669}
3670
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00003671static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303672dictiter_len(dictiterobject *di, PyObject *Py_UNUSED(ignored))
Raymond Hettinger0ce6dc82004-03-18 08:38:00 +00003673{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003674 Py_ssize_t len = 0;
3675 if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used)
3676 len = di->len;
3677 return PyLong_FromSize_t(len);
Raymond Hettinger0ce6dc82004-03-18 08:38:00 +00003678}
3679
Guido van Rossumb90c8482007-02-10 01:11:45 +00003680PyDoc_STRVAR(length_hint_doc,
3681 "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00003682
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003683static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303684dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored));
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003685
3686PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
3687
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00003688static PyMethodDef dictiter_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003689 {"__length_hint__", (PyCFunction)(void(*)(void))dictiter_len, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003690 length_hint_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003691 {"__reduce__", (PyCFunction)(void(*)(void))dictiter_reduce, METH_NOARGS,
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003692 reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003693 {NULL, NULL} /* sentinel */
Raymond Hettinger0ce6dc82004-03-18 08:38:00 +00003694};
3695
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003696static PyObject*
3697dictiter_iternextkey(dictiterobject *di)
Guido van Rossum213c7a62001-04-23 14:08:49 +00003698{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003699 PyObject *key;
INADA Naokica2d8be2016-11-04 16:59:10 +09003700 Py_ssize_t i;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02003701 PyDictKeysObject *k;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003702 PyDictObject *d = di->di_dict;
Guido van Rossum213c7a62001-04-23 14:08:49 +00003703
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003704 if (d == NULL)
3705 return NULL;
3706 assert (PyDict_Check(d));
Guido van Rossum2147df72002-07-16 20:30:22 +00003707
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003708 if (di->di_used != d->ma_used) {
3709 PyErr_SetString(PyExc_RuntimeError,
3710 "dictionary changed size during iteration");
3711 di->di_used = -1; /* Make this state sticky */
3712 return NULL;
3713 }
Guido van Rossum2147df72002-07-16 20:30:22 +00003714
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003715 i = di->di_pos;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003716 k = d->ma_keys;
INADA Naokica2d8be2016-11-04 16:59:10 +09003717 assert(i >= 0);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003718 if (d->ma_values) {
INADA Naokica2d8be2016-11-04 16:59:10 +09003719 if (i >= d->ma_used)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003720 goto fail;
3721 key = DK_ENTRIES(k)[i].me_key;
INADA Naokica2d8be2016-11-04 16:59:10 +09003722 assert(d->ma_values[i] != NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003723 }
3724 else {
INADA Naokica2d8be2016-11-04 16:59:10 +09003725 Py_ssize_t n = k->dk_nentries;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003726 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i];
3727 while (i < n && entry_ptr->me_value == NULL) {
3728 entry_ptr++;
3729 i++;
3730 }
3731 if (i >= n)
3732 goto fail;
3733 key = entry_ptr->me_key;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003734 }
Thomas Perl796cc6e2019-03-28 07:03:25 +01003735 // We found an element (key), but did not expect it
3736 if (di->len == 0) {
3737 PyErr_SetString(PyExc_RuntimeError,
3738 "dictionary keys changed during iteration");
3739 goto fail;
3740 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003741 di->di_pos = i+1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003742 di->len--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003743 Py_INCREF(key);
3744 return key;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003745
3746fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003747 di->di_dict = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +03003748 Py_DECREF(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003749 return NULL;
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003750}
3751
Raymond Hettinger019a1482004-03-18 02:41:19 +00003752PyTypeObject PyDictIterKey_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003753 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3754 "dict_keyiterator", /* tp_name */
3755 sizeof(dictiterobject), /* tp_basicsize */
3756 0, /* tp_itemsize */
3757 /* methods */
3758 (destructor)dictiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003759 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003760 0, /* tp_getattr */
3761 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003762 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003763 0, /* tp_repr */
3764 0, /* tp_as_number */
3765 0, /* tp_as_sequence */
3766 0, /* tp_as_mapping */
3767 0, /* tp_hash */
3768 0, /* tp_call */
3769 0, /* tp_str */
3770 PyObject_GenericGetAttr, /* tp_getattro */
3771 0, /* tp_setattro */
3772 0, /* tp_as_buffer */
3773 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
3774 0, /* tp_doc */
3775 (traverseproc)dictiter_traverse, /* tp_traverse */
3776 0, /* tp_clear */
3777 0, /* tp_richcompare */
3778 0, /* tp_weaklistoffset */
3779 PyObject_SelfIter, /* tp_iter */
3780 (iternextfunc)dictiter_iternextkey, /* tp_iternext */
3781 dictiter_methods, /* tp_methods */
3782 0,
Raymond Hettinger019a1482004-03-18 02:41:19 +00003783};
3784
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003785static PyObject *
3786dictiter_iternextvalue(dictiterobject *di)
Raymond Hettinger019a1482004-03-18 02:41:19 +00003787{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003788 PyObject *value;
INADA Naokica2d8be2016-11-04 16:59:10 +09003789 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003790 PyDictObject *d = di->di_dict;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003791
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003792 if (d == NULL)
3793 return NULL;
3794 assert (PyDict_Check(d));
Raymond Hettinger019a1482004-03-18 02:41:19 +00003795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003796 if (di->di_used != d->ma_used) {
3797 PyErr_SetString(PyExc_RuntimeError,
3798 "dictionary changed size during iteration");
3799 di->di_used = -1; /* Make this state sticky */
3800 return NULL;
3801 }
Raymond Hettinger019a1482004-03-18 02:41:19 +00003802
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003803 i = di->di_pos;
INADA Naokica2d8be2016-11-04 16:59:10 +09003804 assert(i >= 0);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003805 if (d->ma_values) {
INADA Naokica2d8be2016-11-04 16:59:10 +09003806 if (i >= d->ma_used)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003807 goto fail;
INADA Naokica2d8be2016-11-04 16:59:10 +09003808 value = d->ma_values[i];
3809 assert(value != NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003810 }
3811 else {
INADA Naokica2d8be2016-11-04 16:59:10 +09003812 Py_ssize_t n = d->ma_keys->dk_nentries;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003813 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i];
3814 while (i < n && entry_ptr->me_value == NULL) {
3815 entry_ptr++;
3816 i++;
3817 }
3818 if (i >= n)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003819 goto fail;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003820 value = entry_ptr->me_value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003821 }
Thomas Perlb8311cf2019-04-02 11:30:10 +02003822 // We found an element, but did not expect it
3823 if (di->len == 0) {
3824 PyErr_SetString(PyExc_RuntimeError,
3825 "dictionary keys changed during iteration");
3826 goto fail;
3827 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003828 di->di_pos = i+1;
3829 di->len--;
3830 Py_INCREF(value);
3831 return value;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003832
3833fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003834 di->di_dict = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +03003835 Py_DECREF(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003836 return NULL;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003837}
3838
3839PyTypeObject PyDictIterValue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003840 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3841 "dict_valueiterator", /* tp_name */
3842 sizeof(dictiterobject), /* tp_basicsize */
3843 0, /* tp_itemsize */
3844 /* methods */
3845 (destructor)dictiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003846 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003847 0, /* tp_getattr */
3848 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003849 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003850 0, /* tp_repr */
3851 0, /* tp_as_number */
3852 0, /* tp_as_sequence */
3853 0, /* tp_as_mapping */
3854 0, /* tp_hash */
3855 0, /* tp_call */
3856 0, /* tp_str */
3857 PyObject_GenericGetAttr, /* tp_getattro */
3858 0, /* tp_setattro */
3859 0, /* tp_as_buffer */
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003860 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003861 0, /* tp_doc */
3862 (traverseproc)dictiter_traverse, /* tp_traverse */
3863 0, /* tp_clear */
3864 0, /* tp_richcompare */
3865 0, /* tp_weaklistoffset */
3866 PyObject_SelfIter, /* tp_iter */
3867 (iternextfunc)dictiter_iternextvalue, /* tp_iternext */
3868 dictiter_methods, /* tp_methods */
3869 0,
Raymond Hettinger019a1482004-03-18 02:41:19 +00003870};
3871
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003872static PyObject *
3873dictiter_iternextitem(dictiterobject *di)
Raymond Hettinger019a1482004-03-18 02:41:19 +00003874{
Serhiy Storchaka753bca32017-05-20 12:30:02 +03003875 PyObject *key, *value, *result;
INADA Naokica2d8be2016-11-04 16:59:10 +09003876 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003877 PyDictObject *d = di->di_dict;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003878
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003879 if (d == NULL)
3880 return NULL;
3881 assert (PyDict_Check(d));
Raymond Hettinger019a1482004-03-18 02:41:19 +00003882
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003883 if (di->di_used != d->ma_used) {
3884 PyErr_SetString(PyExc_RuntimeError,
3885 "dictionary changed size during iteration");
3886 di->di_used = -1; /* Make this state sticky */
3887 return NULL;
3888 }
Raymond Hettinger019a1482004-03-18 02:41:19 +00003889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003890 i = di->di_pos;
INADA Naokica2d8be2016-11-04 16:59:10 +09003891 assert(i >= 0);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003892 if (d->ma_values) {
INADA Naokica2d8be2016-11-04 16:59:10 +09003893 if (i >= d->ma_used)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003894 goto fail;
3895 key = DK_ENTRIES(d->ma_keys)[i].me_key;
INADA Naokica2d8be2016-11-04 16:59:10 +09003896 value = d->ma_values[i];
3897 assert(value != NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003898 }
3899 else {
INADA Naokica2d8be2016-11-04 16:59:10 +09003900 Py_ssize_t n = d->ma_keys->dk_nentries;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003901 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i];
3902 while (i < n && entry_ptr->me_value == NULL) {
3903 entry_ptr++;
3904 i++;
3905 }
3906 if (i >= n)
3907 goto fail;
3908 key = entry_ptr->me_key;
3909 value = entry_ptr->me_value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003910 }
Thomas Perlb8311cf2019-04-02 11:30:10 +02003911 // We found an element, but did not expect it
3912 if (di->len == 0) {
3913 PyErr_SetString(PyExc_RuntimeError,
3914 "dictionary keys changed during iteration");
3915 goto fail;
3916 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003917 di->di_pos = i+1;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003918 di->len--;
Serhiy Storchaka753bca32017-05-20 12:30:02 +03003919 Py_INCREF(key);
3920 Py_INCREF(value);
3921 result = di->di_result;
3922 if (Py_REFCNT(result) == 1) {
3923 PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
3924 PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
3925 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
3926 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003927 Py_INCREF(result);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03003928 Py_DECREF(oldkey);
3929 Py_DECREF(oldvalue);
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003930 }
3931 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003932 result = PyTuple_New(2);
3933 if (result == NULL)
3934 return NULL;
Serhiy Storchaka753bca32017-05-20 12:30:02 +03003935 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
3936 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003937 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003938 return result;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003939
3940fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003941 di->di_dict = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +03003942 Py_DECREF(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003943 return NULL;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003944}
3945
3946PyTypeObject PyDictIterItem_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003947 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3948 "dict_itemiterator", /* tp_name */
3949 sizeof(dictiterobject), /* tp_basicsize */
3950 0, /* tp_itemsize */
3951 /* methods */
3952 (destructor)dictiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003953 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003954 0, /* tp_getattr */
3955 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003956 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003957 0, /* tp_repr */
3958 0, /* tp_as_number */
3959 0, /* tp_as_sequence */
3960 0, /* tp_as_mapping */
3961 0, /* tp_hash */
3962 0, /* tp_call */
3963 0, /* tp_str */
3964 PyObject_GenericGetAttr, /* tp_getattro */
3965 0, /* tp_setattro */
3966 0, /* tp_as_buffer */
3967 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
3968 0, /* tp_doc */
3969 (traverseproc)dictiter_traverse, /* tp_traverse */
3970 0, /* tp_clear */
3971 0, /* tp_richcompare */
3972 0, /* tp_weaklistoffset */
3973 PyObject_SelfIter, /* tp_iter */
3974 (iternextfunc)dictiter_iternextitem, /* tp_iternext */
3975 dictiter_methods, /* tp_methods */
3976 0,
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003977};
Guido van Rossumb90c8482007-02-10 01:11:45 +00003978
3979
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003980/* dictreviter */
3981
3982static PyObject *
3983dictreviter_iternext(dictiterobject *di)
3984{
3985 PyDictObject *d = di->di_dict;
3986
3987 if (d == NULL) {
3988 return NULL;
3989 }
3990 assert (PyDict_Check(d));
3991
3992 if (di->di_used != d->ma_used) {
3993 PyErr_SetString(PyExc_RuntimeError,
3994 "dictionary changed size during iteration");
3995 di->di_used = -1; /* Make this state sticky */
3996 return NULL;
3997 }
3998
3999 Py_ssize_t i = di->di_pos;
4000 PyDictKeysObject *k = d->ma_keys;
4001 PyObject *key, *value, *result;
4002
Serhiy Storchaka2e3d8732019-10-23 14:48:08 +03004003 if (i < 0) {
4004 goto fail;
4005 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004006 if (d->ma_values) {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004007 key = DK_ENTRIES(k)[i].me_key;
4008 value = d->ma_values[i];
4009 assert (value != NULL);
4010 }
4011 else {
4012 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i];
Serhiy Storchaka2e3d8732019-10-23 14:48:08 +03004013 while (entry_ptr->me_value == NULL) {
4014 if (--i < 0) {
4015 goto fail;
4016 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004017 entry_ptr--;
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004018 }
4019 key = entry_ptr->me_key;
4020 value = entry_ptr->me_value;
4021 }
4022 di->di_pos = i-1;
4023 di->len--;
4024
Dong-hee Na1b55b652020-02-17 19:09:15 +09004025 if (Py_IS_TYPE(di, &PyDictRevIterKey_Type)) {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004026 Py_INCREF(key);
4027 return key;
4028 }
Dong-hee Na1b55b652020-02-17 19:09:15 +09004029 else if (Py_IS_TYPE(di, &PyDictRevIterValue_Type)) {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004030 Py_INCREF(value);
4031 return value;
4032 }
Dong-hee Na1b55b652020-02-17 19:09:15 +09004033 else if (Py_IS_TYPE(di, &PyDictRevIterItem_Type)) {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004034 Py_INCREF(key);
4035 Py_INCREF(value);
4036 result = di->di_result;
4037 if (Py_REFCNT(result) == 1) {
4038 PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
4039 PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
4040 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
4041 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
4042 Py_INCREF(result);
4043 Py_DECREF(oldkey);
4044 Py_DECREF(oldvalue);
4045 }
4046 else {
4047 result = PyTuple_New(2);
4048 if (result == NULL) {
4049 return NULL;
4050 }
4051 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
4052 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
4053 }
4054 return result;
4055 }
4056 else {
4057 Py_UNREACHABLE();
4058 }
4059
4060fail:
4061 di->di_dict = NULL;
4062 Py_DECREF(d);
4063 return NULL;
4064}
4065
4066PyTypeObject PyDictRevIterKey_Type = {
4067 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4068 "dict_reversekeyiterator",
4069 sizeof(dictiterobject),
4070 .tp_dealloc = (destructor)dictiter_dealloc,
4071 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
4072 .tp_traverse = (traverseproc)dictiter_traverse,
4073 .tp_iter = PyObject_SelfIter,
4074 .tp_iternext = (iternextfunc)dictreviter_iternext,
4075 .tp_methods = dictiter_methods
4076};
4077
4078
4079/*[clinic input]
4080dict.__reversed__
4081
4082Return a reverse iterator over the dict keys.
4083[clinic start generated code]*/
4084
4085static PyObject *
4086dict___reversed___impl(PyDictObject *self)
4087/*[clinic end generated code: output=e674483336d1ed51 input=23210ef3477d8c4d]*/
4088{
4089 assert (PyDict_Check(self));
4090 return dictiter_new(self, &PyDictRevIterKey_Type);
4091}
4092
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004093static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304094dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004095{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02004096 _Py_IDENTIFIER(iter);
Sergey Fedoseev63958442018-10-20 05:43:33 +05004097 /* copy the iterator state */
4098 dictiterobject tmp = *di;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004099 Py_XINCREF(tmp.di_dict);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004100
Sergey Fedoseev63958442018-10-20 05:43:33 +05004101 PyObject *list = PySequence_List((PyObject*)&tmp);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004102 Py_XDECREF(tmp.di_dict);
Sergey Fedoseev63958442018-10-20 05:43:33 +05004103 if (list == NULL) {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004104 return NULL;
4105 }
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02004106 return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004107}
4108
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004109PyTypeObject PyDictRevIterItem_Type = {
4110 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4111 "dict_reverseitemiterator",
4112 sizeof(dictiterobject),
4113 .tp_dealloc = (destructor)dictiter_dealloc,
4114 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
4115 .tp_traverse = (traverseproc)dictiter_traverse,
4116 .tp_iter = PyObject_SelfIter,
4117 .tp_iternext = (iternextfunc)dictreviter_iternext,
4118 .tp_methods = dictiter_methods
4119};
4120
4121PyTypeObject PyDictRevIterValue_Type = {
4122 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4123 "dict_reversevalueiterator",
4124 sizeof(dictiterobject),
4125 .tp_dealloc = (destructor)dictiter_dealloc,
4126 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
4127 .tp_traverse = (traverseproc)dictiter_traverse,
4128 .tp_iter = PyObject_SelfIter,
4129 .tp_iternext = (iternextfunc)dictreviter_iternext,
4130 .tp_methods = dictiter_methods
4131};
4132
Guido van Rossum3ac67412007-02-10 18:55:06 +00004133/***********************************************/
Guido van Rossumb90c8482007-02-10 01:11:45 +00004134/* View objects for keys(), items(), values(). */
Guido van Rossum3ac67412007-02-10 18:55:06 +00004135/***********************************************/
4136
Guido van Rossumb90c8482007-02-10 01:11:45 +00004137/* The instance lay-out is the same for all three; but the type differs. */
4138
Guido van Rossumb90c8482007-02-10 01:11:45 +00004139static void
Eric Snow96c6af92015-05-29 22:21:39 -06004140dictview_dealloc(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004141{
INADA Naokia6296d32017-08-24 14:55:17 +09004142 /* bpo-31095: UnTrack is needed before calling any callbacks */
4143 _PyObject_GC_UNTRACK(dv);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004144 Py_XDECREF(dv->dv_dict);
4145 PyObject_GC_Del(dv);
Antoine Pitrou7ddda782009-01-01 15:35:33 +00004146}
4147
4148static int
Eric Snow96c6af92015-05-29 22:21:39 -06004149dictview_traverse(_PyDictViewObject *dv, visitproc visit, void *arg)
Antoine Pitrou7ddda782009-01-01 15:35:33 +00004150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004151 Py_VISIT(dv->dv_dict);
4152 return 0;
Guido van Rossumb90c8482007-02-10 01:11:45 +00004153}
4154
Guido van Rossum83825ac2007-02-10 04:54:19 +00004155static Py_ssize_t
Eric Snow96c6af92015-05-29 22:21:39 -06004156dictview_len(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004157{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004158 Py_ssize_t len = 0;
4159 if (dv->dv_dict != NULL)
4160 len = dv->dv_dict->ma_used;
4161 return len;
Guido van Rossumb90c8482007-02-10 01:11:45 +00004162}
4163
Eric Snow96c6af92015-05-29 22:21:39 -06004164PyObject *
4165_PyDictView_New(PyObject *dict, PyTypeObject *type)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004166{
Eric Snow96c6af92015-05-29 22:21:39 -06004167 _PyDictViewObject *dv;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004168 if (dict == NULL) {
4169 PyErr_BadInternalCall();
4170 return NULL;
4171 }
4172 if (!PyDict_Check(dict)) {
4173 /* XXX Get rid of this restriction later */
4174 PyErr_Format(PyExc_TypeError,
4175 "%s() requires a dict argument, not '%s'",
Victor Stinner58ac7002020-02-07 03:04:21 +01004176 type->tp_name, Py_TYPE(dict)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004177 return NULL;
4178 }
Eric Snow96c6af92015-05-29 22:21:39 -06004179 dv = PyObject_GC_New(_PyDictViewObject, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004180 if (dv == NULL)
4181 return NULL;
4182 Py_INCREF(dict);
4183 dv->dv_dict = (PyDictObject *)dict;
4184 _PyObject_GC_TRACK(dv);
4185 return (PyObject *)dv;
Guido van Rossumb90c8482007-02-10 01:11:45 +00004186}
4187
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004188static PyObject *
Pablo Galindo10c3b212020-06-15 02:05:20 +01004189dictview_mapping(PyObject *view, void *Py_UNUSED(ignored)) {
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004190 assert(view != NULL);
4191 assert(PyDictKeys_Check(view)
4192 || PyDictValues_Check(view)
4193 || PyDictItems_Check(view));
4194 PyObject *mapping = (PyObject *)((_PyDictViewObject *)view)->dv_dict;
4195 return PyDictProxy_New(mapping);
4196}
4197
4198static PyGetSetDef dictview_getset[] = {
Pablo Galindo10c3b212020-06-15 02:05:20 +01004199 {"mapping", dictview_mapping, (setter)NULL,
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004200 "dictionary that this view refers to", NULL},
4201 {0}
4202};
4203
Neal Norwitze36f2ba2007-02-26 23:12:28 +00004204/* TODO(guido): The views objects are not complete:
4205
4206 * support more set operations
4207 * support arbitrary mappings?
4208 - either these should be static or exported in dictobject.h
4209 - if public then they should probably be in builtins
4210*/
4211
Guido van Rossumaac530c2007-08-24 22:33:45 +00004212/* Return 1 if self is a subset of other, iterating over self;
4213 0 if not; -1 if an error occurred. */
Guido van Rossumd9214d12007-02-12 02:23:40 +00004214static int
4215all_contained_in(PyObject *self, PyObject *other)
4216{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004217 PyObject *iter = PyObject_GetIter(self);
4218 int ok = 1;
Guido van Rossumd9214d12007-02-12 02:23:40 +00004219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004220 if (iter == NULL)
4221 return -1;
4222 for (;;) {
4223 PyObject *next = PyIter_Next(iter);
4224 if (next == NULL) {
4225 if (PyErr_Occurred())
4226 ok = -1;
4227 break;
4228 }
4229 ok = PySequence_Contains(other, next);
4230 Py_DECREF(next);
4231 if (ok <= 0)
4232 break;
4233 }
4234 Py_DECREF(iter);
4235 return ok;
Guido van Rossumd9214d12007-02-12 02:23:40 +00004236}
4237
4238static PyObject *
4239dictview_richcompare(PyObject *self, PyObject *other, int op)
4240{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004241 Py_ssize_t len_self, len_other;
4242 int ok;
4243 PyObject *result;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004245 assert(self != NULL);
4246 assert(PyDictViewSet_Check(self));
4247 assert(other != NULL);
Guido van Rossumd9214d12007-02-12 02:23:40 +00004248
Brian Curtindfc80e32011-08-10 20:28:54 -05004249 if (!PyAnySet_Check(other) && !PyDictViewSet_Check(other))
4250 Py_RETURN_NOTIMPLEMENTED;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004252 len_self = PyObject_Size(self);
4253 if (len_self < 0)
4254 return NULL;
4255 len_other = PyObject_Size(other);
4256 if (len_other < 0)
4257 return NULL;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004259 ok = 0;
4260 switch(op) {
Guido van Rossumaac530c2007-08-24 22:33:45 +00004261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004262 case Py_NE:
4263 case Py_EQ:
4264 if (len_self == len_other)
4265 ok = all_contained_in(self, other);
4266 if (op == Py_NE && ok >= 0)
4267 ok = !ok;
4268 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004270 case Py_LT:
4271 if (len_self < len_other)
4272 ok = all_contained_in(self, other);
4273 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004275 case Py_LE:
4276 if (len_self <= len_other)
4277 ok = all_contained_in(self, other);
4278 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004280 case Py_GT:
4281 if (len_self > len_other)
4282 ok = all_contained_in(other, self);
4283 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004285 case Py_GE:
4286 if (len_self >= len_other)
4287 ok = all_contained_in(other, self);
4288 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004290 }
4291 if (ok < 0)
4292 return NULL;
4293 result = ok ? Py_True : Py_False;
4294 Py_INCREF(result);
4295 return result;
Guido van Rossumd9214d12007-02-12 02:23:40 +00004296}
4297
Raymond Hettingerb0d56af2009-03-03 10:52:49 +00004298static PyObject *
Eric Snow96c6af92015-05-29 22:21:39 -06004299dictview_repr(_PyDictViewObject *dv)
Raymond Hettingerb0d56af2009-03-03 10:52:49 +00004300{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004301 PyObject *seq;
bennorthd7773d92018-01-26 15:46:01 +00004302 PyObject *result = NULL;
4303 Py_ssize_t rc;
Raymond Hettingerb0d56af2009-03-03 10:52:49 +00004304
bennorthd7773d92018-01-26 15:46:01 +00004305 rc = Py_ReprEnter((PyObject *)dv);
4306 if (rc != 0) {
4307 return rc > 0 ? PyUnicode_FromString("...") : NULL;
4308 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004309 seq = PySequence_List((PyObject *)dv);
bennorthd7773d92018-01-26 15:46:01 +00004310 if (seq == NULL) {
4311 goto Done;
4312 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004313 result = PyUnicode_FromFormat("%s(%R)", Py_TYPE(dv)->tp_name, seq);
4314 Py_DECREF(seq);
bennorthd7773d92018-01-26 15:46:01 +00004315
4316Done:
4317 Py_ReprLeave((PyObject *)dv);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004318 return result;
Raymond Hettingerb0d56af2009-03-03 10:52:49 +00004319}
4320
Guido van Rossum3ac67412007-02-10 18:55:06 +00004321/*** dict_keys ***/
Guido van Rossumb90c8482007-02-10 01:11:45 +00004322
4323static PyObject *
Eric Snow96c6af92015-05-29 22:21:39 -06004324dictkeys_iter(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004325{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004326 if (dv->dv_dict == NULL) {
4327 Py_RETURN_NONE;
4328 }
4329 return dictiter_new(dv->dv_dict, &PyDictIterKey_Type);
Guido van Rossum3ac67412007-02-10 18:55:06 +00004330}
4331
4332static int
Eric Snow96c6af92015-05-29 22:21:39 -06004333dictkeys_contains(_PyDictViewObject *dv, PyObject *obj)
Guido van Rossum3ac67412007-02-10 18:55:06 +00004334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004335 if (dv->dv_dict == NULL)
4336 return 0;
4337 return PyDict_Contains((PyObject *)dv->dv_dict, obj);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004338}
4339
Guido van Rossum83825ac2007-02-10 04:54:19 +00004340static PySequenceMethods dictkeys_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004341 (lenfunc)dictview_len, /* sq_length */
4342 0, /* sq_concat */
4343 0, /* sq_repeat */
4344 0, /* sq_item */
4345 0, /* sq_slice */
4346 0, /* sq_ass_item */
4347 0, /* sq_ass_slice */
4348 (objobjproc)dictkeys_contains, /* sq_contains */
Guido van Rossum83825ac2007-02-10 04:54:19 +00004349};
4350
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004351// Create an set object from dictviews object.
4352// Returns a new reference.
4353// This utility function is used by set operations.
Guido van Rossum523259b2007-08-24 23:41:22 +00004354static PyObject*
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004355dictviews_to_set(PyObject *self)
Guido van Rossum523259b2007-08-24 23:41:22 +00004356{
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004357 PyObject *left = self;
4358 if (PyDictKeys_Check(self)) {
4359 // PySet_New() has fast path for the dict object.
4360 PyObject *dict = (PyObject *)((_PyDictViewObject *)self)->dv_dict;
4361 if (PyDict_CheckExact(dict)) {
4362 left = dict;
4363 }
4364 }
4365 return PySet_New(left);
4366}
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004367
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004368static PyObject*
4369dictviews_sub(PyObject *self, PyObject *other)
4370{
4371 PyObject *result = dictviews_to_set(self);
4372 if (result == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004373 return NULL;
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004374 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004375
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004376 _Py_IDENTIFIER(difference_update);
4377 PyObject *tmp = _PyObject_CallMethodIdOneArg(
4378 result, &PyId_difference_update, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004379 if (tmp == NULL) {
4380 Py_DECREF(result);
4381 return NULL;
4382 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004384 Py_DECREF(tmp);
4385 return result;
Guido van Rossum523259b2007-08-24 23:41:22 +00004386}
4387
Forest Gregg998cf1f2019-08-26 02:17:43 -05004388static int
4389dictitems_contains(_PyDictViewObject *dv, PyObject *obj);
4390
4391PyObject *
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04004392_PyDictView_Intersect(PyObject* self, PyObject *other)
Guido van Rossum523259b2007-08-24 23:41:22 +00004393{
Forest Gregg998cf1f2019-08-26 02:17:43 -05004394 PyObject *result;
4395 PyObject *it;
4396 PyObject *key;
4397 Py_ssize_t len_self;
4398 int rv;
4399 int (*dict_contains)(_PyDictViewObject *, PyObject *);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004400
Forest Gregg998cf1f2019-08-26 02:17:43 -05004401 /* Python interpreter swaps parameters when dict view
4402 is on right side of & */
4403 if (!PyDictViewSet_Check(self)) {
4404 PyObject *tmp = other;
4405 other = self;
4406 self = tmp;
4407 }
4408
4409 len_self = dictview_len((_PyDictViewObject *)self);
4410
4411 /* if other is a set and self is smaller than other,
4412 reuse set intersection logic */
Dong-hee Na1b55b652020-02-17 19:09:15 +09004413 if (Py_IS_TYPE(other, &PySet_Type) && len_self <= PyObject_Size(other)) {
Forest Gregg998cf1f2019-08-26 02:17:43 -05004414 _Py_IDENTIFIER(intersection);
4415 return _PyObject_CallMethodIdObjArgs(other, &PyId_intersection, self, NULL);
4416 }
4417
4418 /* if other is another dict view, and it is bigger than self,
4419 swap them */
4420 if (PyDictViewSet_Check(other)) {
4421 Py_ssize_t len_other = dictview_len((_PyDictViewObject *)other);
4422 if (len_other > len_self) {
4423 PyObject *tmp = other;
4424 other = self;
4425 self = tmp;
4426 }
4427 }
4428
4429 /* at this point, two things should be true
4430 1. self is a dictview
4431 2. if other is a dictview then it is smaller than self */
4432 result = PySet_New(NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004433 if (result == NULL)
4434 return NULL;
Guido van Rossum523259b2007-08-24 23:41:22 +00004435
Forest Gregg998cf1f2019-08-26 02:17:43 -05004436 it = PyObject_GetIter(other);
Zackery Spytzb16e3822019-10-13 05:49:05 -06004437 if (it == NULL) {
4438 Py_DECREF(result);
4439 return NULL;
4440 }
Forest Gregg998cf1f2019-08-26 02:17:43 -05004441
Forest Gregg998cf1f2019-08-26 02:17:43 -05004442 if (PyDictKeys_Check(self)) {
4443 dict_contains = dictkeys_contains;
4444 }
4445 /* else PyDictItems_Check(self) */
4446 else {
4447 dict_contains = dictitems_contains;
4448 }
4449
4450 while ((key = PyIter_Next(it)) != NULL) {
4451 rv = dict_contains((_PyDictViewObject *)self, key);
4452 if (rv < 0) {
4453 goto error;
4454 }
4455 if (rv) {
4456 if (PySet_Add(result, key)) {
4457 goto error;
4458 }
4459 }
4460 Py_DECREF(key);
4461 }
4462 Py_DECREF(it);
4463 if (PyErr_Occurred()) {
4464 Py_DECREF(result);
4465 return NULL;
4466 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004467 return result;
Forest Gregg998cf1f2019-08-26 02:17:43 -05004468
4469error:
4470 Py_DECREF(it);
4471 Py_DECREF(result);
4472 Py_DECREF(key);
4473 return NULL;
Guido van Rossum523259b2007-08-24 23:41:22 +00004474}
4475
4476static PyObject*
4477dictviews_or(PyObject* self, PyObject *other)
4478{
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004479 PyObject *result = dictviews_to_set(self);
4480 if (result == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004481 return NULL;
4482 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004483
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004484 if (_PySet_Update(result, other) < 0) {
4485 Py_DECREF(result);
4486 return NULL;
4487 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004488 return result;
Guido van Rossum523259b2007-08-24 23:41:22 +00004489}
4490
Dennis Sweeney07d81122020-06-10 01:56:56 -04004491static PyObject *
4492dictitems_xor(PyObject *self, PyObject *other)
4493{
4494 assert(PyDictItems_Check(self));
4495 assert(PyDictItems_Check(other));
4496 PyObject *d1 = (PyObject *)((_PyDictViewObject *)self)->dv_dict;
4497 PyObject *d2 = (PyObject *)((_PyDictViewObject *)other)->dv_dict;
4498
4499 PyObject *temp_dict = PyDict_Copy(d1);
4500 if (temp_dict == NULL) {
4501 return NULL;
4502 }
4503 PyObject *result_set = PySet_New(NULL);
4504 if (result_set == NULL) {
4505 Py_CLEAR(temp_dict);
4506 return NULL;
4507 }
4508
4509 PyObject *key = NULL, *val1 = NULL, *val2 = NULL;
4510 Py_ssize_t pos = 0;
4511 Py_hash_t hash;
4512
4513 while (_PyDict_Next(d2, &pos, &key, &val2, &hash)) {
4514 Py_INCREF(key);
4515 Py_INCREF(val2);
4516 val1 = _PyDict_GetItem_KnownHash(temp_dict, key, hash);
4517
4518 int to_delete;
4519 if (val1 == NULL) {
4520 if (PyErr_Occurred()) {
4521 goto error;
4522 }
4523 to_delete = 0;
4524 }
4525 else {
4526 Py_INCREF(val1);
4527 to_delete = PyObject_RichCompareBool(val1, val2, Py_EQ);
4528 if (to_delete < 0) {
4529 goto error;
4530 }
4531 }
4532
4533 if (to_delete) {
4534 if (_PyDict_DelItem_KnownHash(temp_dict, key, hash) < 0) {
4535 goto error;
4536 }
4537 }
4538 else {
4539 PyObject *pair = PyTuple_Pack(2, key, val2);
4540 if (pair == NULL) {
4541 goto error;
4542 }
4543 if (PySet_Add(result_set, pair) < 0) {
4544 Py_DECREF(pair);
4545 goto error;
4546 }
4547 Py_DECREF(pair);
4548 }
4549 Py_DECREF(key);
4550 Py_XDECREF(val1);
4551 Py_DECREF(val2);
4552 }
4553 key = val1 = val2 = NULL;
4554
4555 _Py_IDENTIFIER(items);
4556 PyObject *remaining_pairs = _PyObject_CallMethodIdNoArgs(temp_dict,
4557 &PyId_items);
4558 if (remaining_pairs == NULL) {
4559 goto error;
4560 }
4561 if (_PySet_Update(result_set, remaining_pairs) < 0) {
4562 Py_DECREF(remaining_pairs);
4563 goto error;
4564 }
4565 Py_DECREF(temp_dict);
4566 Py_DECREF(remaining_pairs);
4567 return result_set;
4568
4569error:
4570 Py_XDECREF(temp_dict);
4571 Py_XDECREF(result_set);
4572 Py_XDECREF(key);
4573 Py_XDECREF(val1);
4574 Py_XDECREF(val2);
4575 return NULL;
4576}
4577
Guido van Rossum523259b2007-08-24 23:41:22 +00004578static PyObject*
4579dictviews_xor(PyObject* self, PyObject *other)
4580{
Dennis Sweeney07d81122020-06-10 01:56:56 -04004581 if (PyDictItems_Check(self) && PyDictItems_Check(other)) {
4582 return dictitems_xor(self, other);
4583 }
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004584 PyObject *result = dictviews_to_set(self);
4585 if (result == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004586 return NULL;
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004587 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004588
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004589 _Py_IDENTIFIER(symmetric_difference_update);
4590 PyObject *tmp = _PyObject_CallMethodIdOneArg(
4591 result, &PyId_symmetric_difference_update, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004592 if (tmp == NULL) {
4593 Py_DECREF(result);
4594 return NULL;
4595 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004597 Py_DECREF(tmp);
4598 return result;
Guido van Rossum523259b2007-08-24 23:41:22 +00004599}
4600
4601static PyNumberMethods dictviews_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004602 0, /*nb_add*/
4603 (binaryfunc)dictviews_sub, /*nb_subtract*/
4604 0, /*nb_multiply*/
4605 0, /*nb_remainder*/
4606 0, /*nb_divmod*/
4607 0, /*nb_power*/
4608 0, /*nb_negative*/
4609 0, /*nb_positive*/
4610 0, /*nb_absolute*/
4611 0, /*nb_bool*/
4612 0, /*nb_invert*/
4613 0, /*nb_lshift*/
4614 0, /*nb_rshift*/
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04004615 (binaryfunc)_PyDictView_Intersect, /*nb_and*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004616 (binaryfunc)dictviews_xor, /*nb_xor*/
4617 (binaryfunc)dictviews_or, /*nb_or*/
Guido van Rossum523259b2007-08-24 23:41:22 +00004618};
4619
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004620static PyObject*
4621dictviews_isdisjoint(PyObject *self, PyObject *other)
4622{
4623 PyObject *it;
4624 PyObject *item = NULL;
4625
4626 if (self == other) {
Eric Snow96c6af92015-05-29 22:21:39 -06004627 if (dictview_len((_PyDictViewObject *)self) == 0)
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004628 Py_RETURN_TRUE;
4629 else
4630 Py_RETURN_FALSE;
4631 }
4632
4633 /* Iterate over the shorter object (only if other is a set,
4634 * because PySequence_Contains may be expensive otherwise): */
4635 if (PyAnySet_Check(other) || PyDictViewSet_Check(other)) {
Eric Snow96c6af92015-05-29 22:21:39 -06004636 Py_ssize_t len_self = dictview_len((_PyDictViewObject *)self);
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004637 Py_ssize_t len_other = PyObject_Size(other);
4638 if (len_other == -1)
4639 return NULL;
4640
4641 if ((len_other > len_self)) {
4642 PyObject *tmp = other;
4643 other = self;
4644 self = tmp;
4645 }
4646 }
4647
4648 it = PyObject_GetIter(other);
4649 if (it == NULL)
4650 return NULL;
4651
4652 while ((item = PyIter_Next(it)) != NULL) {
4653 int contains = PySequence_Contains(self, item);
4654 Py_DECREF(item);
4655 if (contains == -1) {
4656 Py_DECREF(it);
4657 return NULL;
4658 }
4659
4660 if (contains) {
4661 Py_DECREF(it);
4662 Py_RETURN_FALSE;
4663 }
4664 }
4665 Py_DECREF(it);
4666 if (PyErr_Occurred())
4667 return NULL; /* PyIter_Next raised an exception. */
4668 Py_RETURN_TRUE;
4669}
4670
4671PyDoc_STRVAR(isdisjoint_doc,
4672"Return True if the view and the given iterable have a null intersection.");
4673
Serhiy Storchaka81524022018-11-27 13:05:02 +02004674static PyObject* dictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored));
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004675
4676PyDoc_STRVAR(reversed_keys_doc,
4677"Return a reverse iterator over the dict keys.");
4678
Guido van Rossumb90c8482007-02-10 01:11:45 +00004679static PyMethodDef dictkeys_methods[] = {
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004680 {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O,
4681 isdisjoint_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004682 {"__reversed__", (PyCFunction)(void(*)(void))dictkeys_reversed, METH_NOARGS,
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004683 reversed_keys_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004684 {NULL, NULL} /* sentinel */
Guido van Rossumb90c8482007-02-10 01:11:45 +00004685};
4686
4687PyTypeObject PyDictKeys_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004688 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4689 "dict_keys", /* tp_name */
Eric Snow96c6af92015-05-29 22:21:39 -06004690 sizeof(_PyDictViewObject), /* tp_basicsize */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004691 0, /* tp_itemsize */
4692 /* methods */
4693 (destructor)dictview_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004694 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004695 0, /* tp_getattr */
4696 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004697 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004698 (reprfunc)dictview_repr, /* tp_repr */
4699 &dictviews_as_number, /* tp_as_number */
4700 &dictkeys_as_sequence, /* tp_as_sequence */
4701 0, /* tp_as_mapping */
4702 0, /* tp_hash */
4703 0, /* tp_call */
4704 0, /* tp_str */
4705 PyObject_GenericGetAttr, /* tp_getattro */
4706 0, /* tp_setattro */
4707 0, /* tp_as_buffer */
4708 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
4709 0, /* tp_doc */
4710 (traverseproc)dictview_traverse, /* tp_traverse */
4711 0, /* tp_clear */
4712 dictview_richcompare, /* tp_richcompare */
4713 0, /* tp_weaklistoffset */
4714 (getiterfunc)dictkeys_iter, /* tp_iter */
4715 0, /* tp_iternext */
4716 dictkeys_methods, /* tp_methods */
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004717 .tp_getset = dictview_getset,
Guido van Rossumb90c8482007-02-10 01:11:45 +00004718};
4719
4720static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304721dictkeys_new(PyObject *dict, PyObject *Py_UNUSED(ignored))
Guido van Rossumb90c8482007-02-10 01:11:45 +00004722{
Eric Snow96c6af92015-05-29 22:21:39 -06004723 return _PyDictView_New(dict, &PyDictKeys_Type);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004724}
4725
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004726static PyObject *
Serhiy Storchaka81524022018-11-27 13:05:02 +02004727dictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored))
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004728{
4729 if (dv->dv_dict == NULL) {
4730 Py_RETURN_NONE;
4731 }
4732 return dictiter_new(dv->dv_dict, &PyDictRevIterKey_Type);
4733}
4734
Guido van Rossum3ac67412007-02-10 18:55:06 +00004735/*** dict_items ***/
Guido van Rossumb90c8482007-02-10 01:11:45 +00004736
4737static PyObject *
Eric Snow96c6af92015-05-29 22:21:39 -06004738dictitems_iter(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004739{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004740 if (dv->dv_dict == NULL) {
4741 Py_RETURN_NONE;
4742 }
4743 return dictiter_new(dv->dv_dict, &PyDictIterItem_Type);
Guido van Rossum3ac67412007-02-10 18:55:06 +00004744}
4745
4746static int
Eric Snow96c6af92015-05-29 22:21:39 -06004747dictitems_contains(_PyDictViewObject *dv, PyObject *obj)
Guido van Rossum3ac67412007-02-10 18:55:06 +00004748{
Serhiy Storchaka753bca32017-05-20 12:30:02 +03004749 int result;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004750 PyObject *key, *value, *found;
4751 if (dv->dv_dict == NULL)
4752 return 0;
4753 if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 2)
4754 return 0;
4755 key = PyTuple_GET_ITEM(obj, 0);
4756 value = PyTuple_GET_ITEM(obj, 1);
Raymond Hettinger6692f012016-09-18 21:46:08 -07004757 found = PyDict_GetItemWithError((PyObject *)dv->dv_dict, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004758 if (found == NULL) {
4759 if (PyErr_Occurred())
4760 return -1;
4761 return 0;
4762 }
Serhiy Storchaka753bca32017-05-20 12:30:02 +03004763 Py_INCREF(found);
Serhiy Storchaka18b711c2019-08-04 14:12:48 +03004764 result = PyObject_RichCompareBool(found, value, Py_EQ);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03004765 Py_DECREF(found);
4766 return result;
Guido van Rossumb90c8482007-02-10 01:11:45 +00004767}
4768
Guido van Rossum83825ac2007-02-10 04:54:19 +00004769static PySequenceMethods dictitems_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004770 (lenfunc)dictview_len, /* sq_length */
4771 0, /* sq_concat */
4772 0, /* sq_repeat */
4773 0, /* sq_item */
4774 0, /* sq_slice */
4775 0, /* sq_ass_item */
4776 0, /* sq_ass_slice */
4777 (objobjproc)dictitems_contains, /* sq_contains */
Guido van Rossum83825ac2007-02-10 04:54:19 +00004778};
4779
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004780static PyObject* dictitems_reversed(_PyDictViewObject *dv);
4781
4782PyDoc_STRVAR(reversed_items_doc,
4783"Return a reverse iterator over the dict items.");
4784
Guido van Rossumb90c8482007-02-10 01:11:45 +00004785static PyMethodDef dictitems_methods[] = {
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004786 {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O,
4787 isdisjoint_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004788 {"__reversed__", (PyCFunction)(void(*)(void))dictitems_reversed, METH_NOARGS,
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004789 reversed_items_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004790 {NULL, NULL} /* sentinel */
Guido van Rossumb90c8482007-02-10 01:11:45 +00004791};
4792
4793PyTypeObject PyDictItems_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004794 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4795 "dict_items", /* tp_name */
Eric Snow96c6af92015-05-29 22:21:39 -06004796 sizeof(_PyDictViewObject), /* tp_basicsize */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004797 0, /* tp_itemsize */
4798 /* methods */
4799 (destructor)dictview_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004800 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004801 0, /* tp_getattr */
4802 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004803 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004804 (reprfunc)dictview_repr, /* tp_repr */
4805 &dictviews_as_number, /* tp_as_number */
4806 &dictitems_as_sequence, /* tp_as_sequence */
4807 0, /* tp_as_mapping */
4808 0, /* tp_hash */
4809 0, /* tp_call */
4810 0, /* tp_str */
4811 PyObject_GenericGetAttr, /* tp_getattro */
4812 0, /* tp_setattro */
4813 0, /* tp_as_buffer */
4814 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
4815 0, /* tp_doc */
4816 (traverseproc)dictview_traverse, /* tp_traverse */
4817 0, /* tp_clear */
4818 dictview_richcompare, /* tp_richcompare */
4819 0, /* tp_weaklistoffset */
4820 (getiterfunc)dictitems_iter, /* tp_iter */
4821 0, /* tp_iternext */
4822 dictitems_methods, /* tp_methods */
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004823 .tp_getset = dictview_getset,
Guido van Rossumb90c8482007-02-10 01:11:45 +00004824};
4825
4826static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304827dictitems_new(PyObject *dict, PyObject *Py_UNUSED(ignored))
Guido van Rossumb90c8482007-02-10 01:11:45 +00004828{
Eric Snow96c6af92015-05-29 22:21:39 -06004829 return _PyDictView_New(dict, &PyDictItems_Type);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004830}
4831
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004832static PyObject *
4833dictitems_reversed(_PyDictViewObject *dv)
4834{
4835 if (dv->dv_dict == NULL) {
4836 Py_RETURN_NONE;
4837 }
4838 return dictiter_new(dv->dv_dict, &PyDictRevIterItem_Type);
4839}
4840
Guido van Rossum3ac67412007-02-10 18:55:06 +00004841/*** dict_values ***/
Guido van Rossumb90c8482007-02-10 01:11:45 +00004842
4843static PyObject *
Eric Snow96c6af92015-05-29 22:21:39 -06004844dictvalues_iter(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004845{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004846 if (dv->dv_dict == NULL) {
4847 Py_RETURN_NONE;
4848 }
4849 return dictiter_new(dv->dv_dict, &PyDictIterValue_Type);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004850}
4851
Guido van Rossum83825ac2007-02-10 04:54:19 +00004852static PySequenceMethods dictvalues_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004853 (lenfunc)dictview_len, /* sq_length */
4854 0, /* sq_concat */
4855 0, /* sq_repeat */
4856 0, /* sq_item */
4857 0, /* sq_slice */
4858 0, /* sq_ass_item */
4859 0, /* sq_ass_slice */
4860 (objobjproc)0, /* sq_contains */
Guido van Rossum83825ac2007-02-10 04:54:19 +00004861};
4862
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004863static PyObject* dictvalues_reversed(_PyDictViewObject *dv);
4864
4865PyDoc_STRVAR(reversed_values_doc,
4866"Return a reverse iterator over the dict values.");
4867
Guido van Rossumb90c8482007-02-10 01:11:45 +00004868static PyMethodDef dictvalues_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004869 {"__reversed__", (PyCFunction)(void(*)(void))dictvalues_reversed, METH_NOARGS,
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004870 reversed_values_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004871 {NULL, NULL} /* sentinel */
Guido van Rossumb90c8482007-02-10 01:11:45 +00004872};
4873
4874PyTypeObject PyDictValues_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004875 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4876 "dict_values", /* tp_name */
Eric Snow96c6af92015-05-29 22:21:39 -06004877 sizeof(_PyDictViewObject), /* tp_basicsize */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004878 0, /* tp_itemsize */
4879 /* methods */
4880 (destructor)dictview_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004881 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004882 0, /* tp_getattr */
4883 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004884 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004885 (reprfunc)dictview_repr, /* tp_repr */
4886 0, /* tp_as_number */
4887 &dictvalues_as_sequence, /* tp_as_sequence */
4888 0, /* tp_as_mapping */
4889 0, /* tp_hash */
4890 0, /* tp_call */
4891 0, /* tp_str */
4892 PyObject_GenericGetAttr, /* tp_getattro */
4893 0, /* tp_setattro */
4894 0, /* tp_as_buffer */
4895 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
4896 0, /* tp_doc */
4897 (traverseproc)dictview_traverse, /* tp_traverse */
4898 0, /* tp_clear */
4899 0, /* tp_richcompare */
4900 0, /* tp_weaklistoffset */
4901 (getiterfunc)dictvalues_iter, /* tp_iter */
4902 0, /* tp_iternext */
4903 dictvalues_methods, /* tp_methods */
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004904 .tp_getset = dictview_getset,
Guido van Rossumb90c8482007-02-10 01:11:45 +00004905};
4906
4907static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304908dictvalues_new(PyObject *dict, PyObject *Py_UNUSED(ignored))
Guido van Rossumb90c8482007-02-10 01:11:45 +00004909{
Eric Snow96c6af92015-05-29 22:21:39 -06004910 return _PyDictView_New(dict, &PyDictValues_Type);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004911}
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004912
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004913static PyObject *
4914dictvalues_reversed(_PyDictViewObject *dv)
4915{
4916 if (dv->dv_dict == NULL) {
4917 Py_RETURN_NONE;
4918 }
4919 return dictiter_new(dv->dv_dict, &PyDictRevIterValue_Type);
4920}
4921
4922
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004923/* Returns NULL if cannot allocate a new PyDictKeysObject,
4924 but does not set an error */
4925PyDictKeysObject *
4926_PyDict_NewKeysForClass(void)
4927{
Victor Stinner742da042016-09-07 17:40:12 -07004928 PyDictKeysObject *keys = new_keys_object(PyDict_MINSIZE);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004929 if (keys == NULL)
4930 PyErr_Clear();
4931 else
4932 keys->dk_lookup = lookdict_split;
4933 return keys;
4934}
4935
4936#define CACHED_KEYS(tp) (((PyHeapTypeObject*)tp)->ht_cached_keys)
4937
4938PyObject *
4939PyObject_GenericGetDict(PyObject *obj, void *context)
4940{
4941 PyObject *dict, **dictptr = _PyObject_GetDictPtr(obj);
4942 if (dictptr == NULL) {
4943 PyErr_SetString(PyExc_AttributeError,
4944 "This object has no __dict__");
4945 return NULL;
4946 }
4947 dict = *dictptr;
4948 if (dict == NULL) {
4949 PyTypeObject *tp = Py_TYPE(obj);
4950 if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && CACHED_KEYS(tp)) {
INADA Naokia7576492018-11-14 18:39:27 +09004951 dictkeys_incref(CACHED_KEYS(tp));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004952 *dictptr = dict = new_dict_with_shared_keys(CACHED_KEYS(tp));
4953 }
4954 else {
4955 *dictptr = dict = PyDict_New();
4956 }
4957 }
4958 Py_XINCREF(dict);
4959 return dict;
4960}
4961
4962int
4963_PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
Victor Stinner742da042016-09-07 17:40:12 -07004964 PyObject *key, PyObject *value)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004965{
4966 PyObject *dict;
4967 int res;
4968 PyDictKeysObject *cached;
4969
4970 assert(dictptr != NULL);
4971 if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && (cached = CACHED_KEYS(tp))) {
4972 assert(dictptr != NULL);
4973 dict = *dictptr;
4974 if (dict == NULL) {
INADA Naokia7576492018-11-14 18:39:27 +09004975 dictkeys_incref(cached);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004976 dict = new_dict_with_shared_keys(cached);
4977 if (dict == NULL)
4978 return -1;
4979 *dictptr = dict;
4980 }
4981 if (value == NULL) {
4982 res = PyDict_DelItem(dict, key);
INADA Naoki2294f3a2017-02-12 13:51:30 +09004983 // Since key sharing dict doesn't allow deletion, PyDict_DelItem()
4984 // always converts dict to combined form.
4985 if ((cached = CACHED_KEYS(tp)) != NULL) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004986 CACHED_KEYS(tp) = NULL;
INADA Naokia7576492018-11-14 18:39:27 +09004987 dictkeys_decref(cached);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004988 }
Victor Stinner3d3f2642016-12-15 17:21:23 +01004989 }
4990 else {
INADA Naoki2294f3a2017-02-12 13:51:30 +09004991 int was_shared = (cached == ((PyDictObject *)dict)->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004992 res = PyDict_SetItem(dict, key, value);
INADA Naoki2294f3a2017-02-12 13:51:30 +09004993 if (was_shared &&
4994 (cached = CACHED_KEYS(tp)) != NULL &&
4995 cached != ((PyDictObject *)dict)->ma_keys) {
Victor Stinner3d3f2642016-12-15 17:21:23 +01004996 /* PyDict_SetItem() may call dictresize and convert split table
4997 * into combined table. In such case, convert it to split
4998 * table again and update type's shared key only when this is
4999 * the only dict sharing key with the type.
5000 *
5001 * This is to allow using shared key in class like this:
5002 *
5003 * class C:
5004 * def __init__(self):
5005 * # one dict resize happens
5006 * self.a, self.b, self.c = 1, 2, 3
5007 * self.d, self.e, self.f = 4, 5, 6
5008 * a = C()
5009 */
Benjamin Peterson15ee8212012-04-24 14:44:18 -04005010 if (cached->dk_refcnt == 1) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04005011 CACHED_KEYS(tp) = make_keys_shared(dict);
Victor Stinner742da042016-09-07 17:40:12 -07005012 }
5013 else {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04005014 CACHED_KEYS(tp) = NULL;
5015 }
INADA Naokia7576492018-11-14 18:39:27 +09005016 dictkeys_decref(cached);
Benjamin Peterson15ee8212012-04-24 14:44:18 -04005017 if (CACHED_KEYS(tp) == NULL && PyErr_Occurred())
5018 return -1;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04005019 }
5020 }
5021 } else {
5022 dict = *dictptr;
5023 if (dict == NULL) {
5024 dict = PyDict_New();
5025 if (dict == NULL)
5026 return -1;
5027 *dictptr = dict;
5028 }
5029 if (value == NULL) {
5030 res = PyDict_DelItem(dict, key);
5031 } else {
5032 res = PyDict_SetItem(dict, key, value);
5033 }
5034 }
5035 return res;
5036}
5037
5038void
5039_PyDictKeys_DecRef(PyDictKeysObject *keys)
5040{
INADA Naokia7576492018-11-14 18:39:27 +09005041 dictkeys_decref(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04005042}