blob: 0aeee7011e8441e533697c2829fff07f0bec6c41 [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 Stinnerbcb094b2021-02-19 15:10:45 +0100263_PyDict_ClearFreeList(PyInterpreterState *interp)
Christian Heimes77c02eb2008-02-09 02:18:51 +0000264{
Victor Stinnerbcb094b2021-02-19 15:10:45 +0100265 struct _Py_dict_state *state = &interp->dict_state;
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200266 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) {
Victor Stinner32bd68c2020-12-01 10:37:39 +0100272 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
Victor Stinnerbcb094b2021-02-19 15:10:45 +0100278_PyDict_Fini(PyInterpreterState *interp)
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200279{
Victor Stinnerbcb094b2021-02-19 15:10:45 +0100280 _PyDict_ClearFreeList(interp);
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200281#ifdef Py_DEBUG
Victor Stinnerbcb094b2021-02-19 15:10:45 +0100282 struct _Py_dict_state *state = &interp->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 Stinner32bd68c2020-12-01 10:37:39 +0100600 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 }
Victor Stinner32bd68c2020-12-01 10:37:39 +0100639 PyObject_Free(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400640}
641
642#define new_values(size) PyMem_NEW(PyObject *, size)
Victor Stinner00d7abd2020-12-01 09:56:42 +0100643#define free_values(values) PyMem_Free(values)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400644
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)) {
INADA Naoki778928b2017-08-03 23:45:15 +0900860 return lookdict(mp, key, hash, value_addr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000861 }
Tim Peters15d49292001-05-27 07:39:22 +0000862
INADA Naoki778928b2017-08-03 23:45:15 +0900863 PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
864 size_t mask = DK_MASK(mp->ma_keys);
865 size_t perturb = (size_t)hash;
866 size_t i = (size_t)hash & mask;
867
868 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900869 Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
Victor Stinner742da042016-09-07 17:40:12 -0700870 if (ix == DKIX_EMPTY) {
Victor Stinner742da042016-09-07 17:40:12 -0700871 *value_addr = NULL;
872 return DKIX_EMPTY;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400873 }
INADA Naoki778928b2017-08-03 23:45:15 +0900874 if (ix >= 0) {
875 PyDictKeyEntry *ep = &ep0[ix];
876 assert(ep->me_key != NULL);
877 assert(PyUnicode_CheckExact(ep->me_key));
878 if (ep->me_key == key ||
879 (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
880 *value_addr = ep->me_value;
881 return ix;
Victor Stinner742da042016-09-07 17:40:12 -0700882 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400883 }
INADA Naoki778928b2017-08-03 23:45:15 +0900884 perturb >>= PERTURB_SHIFT;
885 i = mask & (i*5 + perturb + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700887 Py_UNREACHABLE();
Fred Drake1bff34a2000-08-31 19:31:38 +0000888}
889
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400890/* Faster version of lookdict_unicode when it is known that no <dummy> keys
891 * will be present. */
Victor Stinnerc7a8f672016-11-15 15:13:40 +0100892static Py_ssize_t _Py_HOT_FUNCTION
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400893lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900894 Py_hash_t hash, PyObject **value_addr)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400895{
Victor Stinner742da042016-09-07 17:40:12 -0700896 assert(mp->ma_values == NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400897 /* Make sure this function doesn't have to handle non-unicode keys,
898 including subclasses of str; e.g., one reason to subclass
899 unicodes is to override __eq__, and for speed we don't cater to
900 that here. */
901 if (!PyUnicode_CheckExact(key)) {
INADA Naoki778928b2017-08-03 23:45:15 +0900902 return lookdict(mp, key, hash, value_addr);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400903 }
INADA Naoki778928b2017-08-03 23:45:15 +0900904
905 PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
906 size_t mask = DK_MASK(mp->ma_keys);
907 size_t perturb = (size_t)hash;
908 size_t i = (size_t)hash & mask;
909
910 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900911 Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
Victor Stinner742da042016-09-07 17:40:12 -0700912 assert (ix != DKIX_DUMMY);
913 if (ix == DKIX_EMPTY) {
Victor Stinner742da042016-09-07 17:40:12 -0700914 *value_addr = NULL;
915 return DKIX_EMPTY;
916 }
INADA Naoki778928b2017-08-03 23:45:15 +0900917 PyDictKeyEntry *ep = &ep0[ix];
918 assert(ep->me_key != NULL);
919 assert(PyUnicode_CheckExact(ep->me_key));
Victor Stinner742da042016-09-07 17:40:12 -0700920 if (ep->me_key == key ||
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400921 (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
INADA Naokiba609772016-12-07 20:41:42 +0900922 *value_addr = ep->me_value;
Victor Stinner742da042016-09-07 17:40:12 -0700923 return ix;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400924 }
INADA Naoki778928b2017-08-03 23:45:15 +0900925 perturb >>= PERTURB_SHIFT;
926 i = mask & (i*5 + perturb + 1);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400927 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700928 Py_UNREACHABLE();
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400929}
930
931/* Version of lookdict for split tables.
932 * All split tables and only split tables use this lookup function.
933 * Split tables only contain unicode keys and no dummy keys,
934 * so algorithm is the same as lookdict_unicode_nodummy.
935 */
Victor Stinnerc7a8f672016-11-15 15:13:40 +0100936static Py_ssize_t _Py_HOT_FUNCTION
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400937lookdict_split(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900938 Py_hash_t hash, PyObject **value_addr)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400939{
Victor Stinner742da042016-09-07 17:40:12 -0700940 /* mp must split table */
941 assert(mp->ma_values != NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400942 if (!PyUnicode_CheckExact(key)) {
INADA Naoki778928b2017-08-03 23:45:15 +0900943 Py_ssize_t ix = lookdict(mp, key, hash, value_addr);
Victor Stinner742da042016-09-07 17:40:12 -0700944 if (ix >= 0) {
INADA Naokiba609772016-12-07 20:41:42 +0900945 *value_addr = mp->ma_values[ix];
Victor Stinner742da042016-09-07 17:40:12 -0700946 }
947 return ix;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400948 }
Victor Stinner742da042016-09-07 17:40:12 -0700949
INADA Naoki778928b2017-08-03 23:45:15 +0900950 PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
951 size_t mask = DK_MASK(mp->ma_keys);
952 size_t perturb = (size_t)hash;
953 size_t i = (size_t)hash & mask;
954
955 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900956 Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
INADA Naoki778928b2017-08-03 23:45:15 +0900957 assert (ix != DKIX_DUMMY);
Victor Stinner742da042016-09-07 17:40:12 -0700958 if (ix == DKIX_EMPTY) {
Victor Stinner742da042016-09-07 17:40:12 -0700959 *value_addr = NULL;
960 return DKIX_EMPTY;
961 }
INADA Naoki778928b2017-08-03 23:45:15 +0900962 PyDictKeyEntry *ep = &ep0[ix];
963 assert(ep->me_key != NULL);
964 assert(PyUnicode_CheckExact(ep->me_key));
Victor Stinner742da042016-09-07 17:40:12 -0700965 if (ep->me_key == key ||
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400966 (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
INADA Naokiba609772016-12-07 20:41:42 +0900967 *value_addr = mp->ma_values[ix];
Victor Stinner742da042016-09-07 17:40:12 -0700968 return ix;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400969 }
INADA Naoki778928b2017-08-03 23:45:15 +0900970 perturb >>= PERTURB_SHIFT;
971 i = mask & (i*5 + perturb + 1);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400972 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700973 Py_UNREACHABLE();
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400974}
975
Benjamin Petersonfb886362010-04-24 18:21:17 +0000976int
977_PyDict_HasOnlyStringKeys(PyObject *dict)
978{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 Py_ssize_t pos = 0;
980 PyObject *key, *value;
Benjamin Petersonf6096542010-11-17 22:33:12 +0000981 assert(PyDict_Check(dict));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 /* Shortcut */
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400983 if (((PyDictObject *)dict)->ma_keys->dk_lookup != lookdict)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 return 1;
985 while (PyDict_Next(dict, &pos, &key, &value))
986 if (!PyUnicode_Check(key))
987 return 0;
988 return 1;
Benjamin Petersonfb886362010-04-24 18:21:17 +0000989}
990
Antoine Pitrou3a652b12009-03-23 18:52:06 +0000991#define MAINTAIN_TRACKING(mp, key, value) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000992 do { \
993 if (!_PyObject_GC_IS_TRACKED(mp)) { \
994 if (_PyObject_GC_MAY_BE_TRACKED(key) || \
995 _PyObject_GC_MAY_BE_TRACKED(value)) { \
996 _PyObject_GC_TRACK(mp); \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000997 } \
998 } \
999 } while(0)
Antoine Pitrou3a652b12009-03-23 18:52:06 +00001000
1001void
1002_PyDict_MaybeUntrack(PyObject *op)
1003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 PyDictObject *mp;
1005 PyObject *value;
Victor Stinner742da042016-09-07 17:40:12 -07001006 Py_ssize_t i, numentries;
1007 PyDictKeyEntry *ep0;
Antoine Pitrou3a652b12009-03-23 18:52:06 +00001008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 if (!PyDict_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op))
1010 return;
1011
1012 mp = (PyDictObject *) op;
Victor Stinner742da042016-09-07 17:40:12 -07001013 ep0 = DK_ENTRIES(mp->ma_keys);
1014 numentries = mp->ma_keys->dk_nentries;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001015 if (_PyDict_HasSplitTable(mp)) {
Victor Stinner742da042016-09-07 17:40:12 -07001016 for (i = 0; i < numentries; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001017 if ((value = mp->ma_values[i]) == NULL)
1018 continue;
1019 if (_PyObject_GC_MAY_BE_TRACKED(value)) {
Victor Stinner742da042016-09-07 17:40:12 -07001020 assert(!_PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001021 return;
1022 }
1023 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001025 else {
Victor Stinner742da042016-09-07 17:40:12 -07001026 for (i = 0; i < numentries; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001027 if ((value = ep0[i].me_value) == NULL)
1028 continue;
1029 if (_PyObject_GC_MAY_BE_TRACKED(value) ||
1030 _PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key))
1031 return;
1032 }
1033 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 _PyObject_GC_UNTRACK(op);
Antoine Pitrou3a652b12009-03-23 18:52:06 +00001035}
1036
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001037/* Internal function to find slot for an item from its hash
Victor Stinner3c336c52016-09-12 14:17:40 +02001038 when it is known that the key is not present in the dict.
1039
1040 The dict must be combined. */
INADA Naokiba609772016-12-07 20:41:42 +09001041static Py_ssize_t
INADA Naoki778928b2017-08-03 23:45:15 +09001042find_empty_slot(PyDictKeysObject *keys, Py_hash_t hash)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001043{
INADA Naoki778928b2017-08-03 23:45:15 +09001044 assert(keys != NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001045
INADA Naoki778928b2017-08-03 23:45:15 +09001046 const size_t mask = DK_MASK(keys);
1047 size_t i = hash & mask;
INADA Naokia7576492018-11-14 18:39:27 +09001048 Py_ssize_t ix = dictkeys_get_index(keys, i);
INADA Naoki778928b2017-08-03 23:45:15 +09001049 for (size_t perturb = hash; ix >= 0;) {
INADA Naoki267941c2016-10-06 15:19:07 +09001050 perturb >>= PERTURB_SHIFT;
INADA Naoki778928b2017-08-03 23:45:15 +09001051 i = (i*5 + perturb + 1) & mask;
INADA Naokia7576492018-11-14 18:39:27 +09001052 ix = dictkeys_get_index(keys, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001053 }
INADA Naoki778928b2017-08-03 23:45:15 +09001054 return i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001055}
1056
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001057static int
1058insertion_resize(PyDictObject *mp)
1059{
Inada Naokid9323a82020-08-07 14:08:55 +09001060 return dictresize(mp, calculate_keysize(GROWTH_RATE(mp)));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001061}
Antoine Pitroue965d972012-02-27 00:45:12 +01001062
1063/*
1064Internal routine to insert a new item into the table.
1065Used both by the internal resize routine and by the public insert routine.
Antoine Pitroue965d972012-02-27 00:45:12 +01001066Returns -1 if an error occurred, or 0 on success.
1067*/
1068static int
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001069insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
Antoine Pitroue965d972012-02-27 00:45:12 +01001070{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001071 PyObject *old_value;
INADA Naokiba609772016-12-07 20:41:42 +09001072 PyDictKeyEntry *ep;
Antoine Pitroue965d972012-02-27 00:45:12 +01001073
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001074 Py_INCREF(key);
1075 Py_INCREF(value);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001076 if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) {
1077 if (insertion_resize(mp) < 0)
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001078 goto Fail;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001079 }
1080
INADA Naoki778928b2017-08-03 23:45:15 +09001081 Py_ssize_t ix = mp->ma_keys->dk_lookup(mp, key, hash, &old_value);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001082 if (ix == DKIX_ERROR)
1083 goto Fail;
Victor Stinner742da042016-09-07 17:40:12 -07001084
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001085 MAINTAIN_TRACKING(mp, key, value);
Victor Stinner742da042016-09-07 17:40:12 -07001086
1087 /* When insertion order is different from shared key, we can't share
1088 * the key anymore. Convert this instance to combine table.
1089 */
1090 if (_PyDict_HasSplitTable(mp) &&
INADA Naokiba609772016-12-07 20:41:42 +09001091 ((ix >= 0 && old_value == NULL && mp->ma_used != ix) ||
Victor Stinner742da042016-09-07 17:40:12 -07001092 (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) {
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001093 if (insertion_resize(mp) < 0)
1094 goto Fail;
Victor Stinner742da042016-09-07 17:40:12 -07001095 ix = DKIX_EMPTY;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001096 }
Victor Stinner742da042016-09-07 17:40:12 -07001097
1098 if (ix == DKIX_EMPTY) {
1099 /* Insert into new slot. */
INADA Naokiba609772016-12-07 20:41:42 +09001100 assert(old_value == NULL);
Victor Stinner742da042016-09-07 17:40:12 -07001101 if (mp->ma_keys->dk_usable <= 0) {
1102 /* Need to resize. */
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001103 if (insertion_resize(mp) < 0)
1104 goto Fail;
Victor Stinner742da042016-09-07 17:40:12 -07001105 }
Hristo Venev8557edb2021-04-29 05:06:03 +03001106 if (!PyUnicode_CheckExact(key) && mp->ma_keys->dk_lookup != lookdict) {
1107 mp->ma_keys->dk_lookup = lookdict;
1108 }
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 {
Victor Stinner32bd68c2020-12-01 10:37:39 +01001306 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
Pablo Galindo109826c2020-10-20 06:22:44 +01001440Py_ssize_t
1441_PyDict_GetItemHint(PyDictObject *mp, PyObject *key,
Victor Stinnerd5fc9982021-02-21 12:02:04 +01001442 Py_ssize_t hint, PyObject **value)
Pablo Galindo109826c2020-10-20 06:22:44 +01001443{
Pablo Galindo109826c2020-10-20 06:22:44 +01001444 assert(*value == NULL);
1445 assert(PyDict_CheckExact((PyObject*)mp));
1446 assert(PyUnicode_CheckExact(key));
1447
Pablo Galindo492d5132020-10-25 06:08:17 +00001448 if (hint >= 0 && hint < mp->ma_keys->dk_nentries) {
Pablo Galindo109826c2020-10-20 06:22:44 +01001449 PyObject *res = NULL;
1450
1451 PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys) + (size_t)hint;
1452 if (ep->me_key == key) {
1453 if (mp->ma_keys->dk_lookup == lookdict_split) {
1454 assert(mp->ma_values != NULL);
1455 res = mp->ma_values[(size_t)hint];
1456 }
1457 else {
1458 res = ep->me_value;
1459 }
1460 if (res != NULL) {
1461 *value = res;
1462 return hint;
1463 }
1464 }
1465 }
1466
Victor Stinnerd5fc9982021-02-21 12:02:04 +01001467 Py_hash_t hash = ((PyASCIIObject *) key)->hash;
1468 if (hash == -1) {
Pablo Galindo109826c2020-10-20 06:22:44 +01001469 hash = PyObject_Hash(key);
1470 if (hash == -1) {
Pablo Galindo109826c2020-10-20 06:22:44 +01001471 return -1;
1472 }
1473 }
1474
Victor Stinnerd5fc9982021-02-21 12:02:04 +01001475 return (mp->ma_keys->dk_lookup)(mp, key, hash, value);
Pablo Galindo109826c2020-10-20 06:22:44 +01001476}
1477
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02001478/* Same as PyDict_GetItemWithError() but with hash supplied by caller.
1479 This returns NULL *with* an exception set if an exception occurred.
1480 It returns NULL *without* an exception set if the key wasn't present.
1481*/
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001482PyObject *
1483_PyDict_GetItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
1484{
Victor Stinner742da042016-09-07 17:40:12 -07001485 Py_ssize_t ix;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001486 PyDictObject *mp = (PyDictObject *)op;
INADA Naokiba609772016-12-07 20:41:42 +09001487 PyObject *value;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001488
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02001489 if (!PyDict_Check(op)) {
1490 PyErr_BadInternalCall();
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001491 return NULL;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001492 }
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02001493
INADA Naoki778928b2017-08-03 23:45:15 +09001494 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02001495 if (ix < 0) {
1496 return NULL;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001497 }
INADA Naokiba609772016-12-07 20:41:42 +09001498 return value;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001499}
1500
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001501/* Variant of PyDict_GetItem() that doesn't suppress exceptions.
1502 This returns NULL *with* an exception set if an exception occurred.
1503 It returns NULL *without* an exception set if the key wasn't present.
1504*/
1505PyObject *
1506PyDict_GetItemWithError(PyObject *op, PyObject *key)
1507{
Victor Stinner742da042016-09-07 17:40:12 -07001508 Py_ssize_t ix;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001509 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 PyDictObject*mp = (PyDictObject *)op;
INADA Naokiba609772016-12-07 20:41:42 +09001511 PyObject *value;
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 if (!PyDict_Check(op)) {
1514 PyErr_BadInternalCall();
1515 return NULL;
1516 }
1517 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001518 (hash = ((PyASCIIObject *) key)->hash) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 {
1520 hash = PyObject_Hash(key);
1521 if (hash == -1) {
1522 return NULL;
1523 }
1524 }
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001525
INADA Naoki778928b2017-08-03 23:45:15 +09001526 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07001527 if (ix < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001529 return value;
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001530}
1531
Brett Cannonfd074152012-04-14 14:10:13 -04001532PyObject *
1533_PyDict_GetItemIdWithError(PyObject *dp, struct _Py_Identifier *key)
1534{
1535 PyObject *kv;
1536 kv = _PyUnicode_FromId(key); /* borrowed */
1537 if (kv == NULL)
1538 return NULL;
scoder6067d4b2020-05-11 06:04:31 +02001539 Py_hash_t hash = ((PyASCIIObject *) kv)->hash;
1540 assert (hash != -1); /* interned strings have their hash value initialised */
1541 return _PyDict_GetItem_KnownHash(dp, kv, hash);
Brett Cannonfd074152012-04-14 14:10:13 -04001542}
1543
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001544PyObject *
1545_PyDict_GetItemStringWithError(PyObject *v, const char *key)
1546{
1547 PyObject *kv, *rv;
1548 kv = PyUnicode_FromString(key);
1549 if (kv == NULL) {
1550 return NULL;
1551 }
1552 rv = PyDict_GetItemWithError(v, kv);
1553 Py_DECREF(kv);
1554 return rv;
1555}
1556
Victor Stinnerb4efc962015-11-20 09:24:02 +01001557/* Fast version of global value lookup (LOAD_GLOBAL).
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001558 * Lookup in globals, then builtins.
Victor Stinnerb4efc962015-11-20 09:24:02 +01001559 *
1560 * Raise an exception and return NULL if an error occurred (ex: computing the
1561 * key hash failed, key comparison failed, ...). Return NULL if the key doesn't
1562 * exist. Return the value if the key exists.
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001563 */
1564PyObject *
1565_PyDict_LoadGlobal(PyDictObject *globals, PyDictObject *builtins, PyObject *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001566{
Victor Stinner742da042016-09-07 17:40:12 -07001567 Py_ssize_t ix;
Victor Stinnerb4efc962015-11-20 09:24:02 +01001568 Py_hash_t hash;
INADA Naokiba609772016-12-07 20:41:42 +09001569 PyObject *value;
Victor Stinnerb4efc962015-11-20 09:24:02 +01001570
1571 if (!PyUnicode_CheckExact(key) ||
1572 (hash = ((PyASCIIObject *) key)->hash) == -1)
1573 {
1574 hash = PyObject_Hash(key);
1575 if (hash == -1)
1576 return NULL;
Antoine Pitroue965d972012-02-27 00:45:12 +01001577 }
Victor Stinnerb4efc962015-11-20 09:24:02 +01001578
1579 /* namespace 1: globals */
INADA Naoki778928b2017-08-03 23:45:15 +09001580 ix = globals->ma_keys->dk_lookup(globals, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07001581 if (ix == DKIX_ERROR)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001582 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001583 if (ix != DKIX_EMPTY && value != NULL)
1584 return value;
Victor Stinnerb4efc962015-11-20 09:24:02 +01001585
1586 /* namespace 2: builtins */
INADA Naoki778928b2017-08-03 23:45:15 +09001587 ix = builtins->ma_keys->dk_lookup(builtins, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07001588 if (ix < 0)
Victor Stinnerb4efc962015-11-20 09:24:02 +01001589 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001590 return value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001591}
1592
Antoine Pitroue965d972012-02-27 00:45:12 +01001593/* CAUTION: PyDict_SetItem() must guarantee that it won't resize the
1594 * dictionary if it's merely replacing the value for an existing key.
1595 * This means that it's safe to loop over a dictionary with PyDict_Next()
1596 * and occasionally replace a value -- but you can't insert new keys or
1597 * remove them.
1598 */
1599int
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001600PyDict_SetItem(PyObject *op, PyObject *key, PyObject *value)
Antoine Pitroue965d972012-02-27 00:45:12 +01001601{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001602 PyDictObject *mp;
1603 Py_hash_t hash;
Antoine Pitroue965d972012-02-27 00:45:12 +01001604 if (!PyDict_Check(op)) {
1605 PyErr_BadInternalCall();
1606 return -1;
1607 }
1608 assert(key);
1609 assert(value);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001610 mp = (PyDictObject *)op;
1611 if (!PyUnicode_CheckExact(key) ||
1612 (hash = ((PyASCIIObject *) key)->hash) == -1)
1613 {
Antoine Pitroue965d972012-02-27 00:45:12 +01001614 hash = PyObject_Hash(key);
1615 if (hash == -1)
1616 return -1;
1617 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001618
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001619 if (mp->ma_keys == Py_EMPTY_KEYS) {
1620 return insert_to_emptydict(mp, key, hash, value);
1621 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001622 /* insertdict() handles any resizing that might be necessary */
1623 return insertdict(mp, key, hash, value);
Antoine Pitroue965d972012-02-27 00:45:12 +01001624}
1625
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001626int
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001627_PyDict_SetItem_KnownHash(PyObject *op, PyObject *key, PyObject *value,
1628 Py_hash_t hash)
1629{
1630 PyDictObject *mp;
1631
1632 if (!PyDict_Check(op)) {
1633 PyErr_BadInternalCall();
1634 return -1;
1635 }
1636 assert(key);
1637 assert(value);
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001638 assert(hash != -1);
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001639 mp = (PyDictObject *)op;
1640
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001641 if (mp->ma_keys == Py_EMPTY_KEYS) {
1642 return insert_to_emptydict(mp, key, hash, value);
1643 }
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001644 /* insertdict() handles any resizing that might be necessary */
1645 return insertdict(mp, key, hash, value);
1646}
1647
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001648static int
INADA Naoki778928b2017-08-03 23:45:15 +09001649delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix,
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001650 PyObject *old_value)
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001651{
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001652 PyObject *old_key;
Antoine Pitroud741ed42016-12-27 14:23:43 +01001653 PyDictKeyEntry *ep;
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001654
INADA Naoki778928b2017-08-03 23:45:15 +09001655 Py_ssize_t hashpos = lookdict_index(mp->ma_keys, hash, ix);
1656 assert(hashpos >= 0);
1657
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001658 mp->ma_used--;
Antoine Pitroud741ed42016-12-27 14:23:43 +01001659 mp->ma_version_tag = DICT_NEXT_VERSION();
1660 ep = &DK_ENTRIES(mp->ma_keys)[ix];
INADA Naokia7576492018-11-14 18:39:27 +09001661 dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
Antoine Pitroud741ed42016-12-27 14:23:43 +01001662 ENSURE_ALLOWS_DELETIONS(mp);
1663 old_key = ep->me_key;
1664 ep->me_key = NULL;
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001665 ep->me_value = NULL;
Antoine Pitroud741ed42016-12-27 14:23:43 +01001666 Py_DECREF(old_key);
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001667 Py_DECREF(old_value);
Antoine Pitroud741ed42016-12-27 14:23:43 +01001668
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001669 ASSERT_CONSISTENT(mp);
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001670 return 0;
1671}
1672
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001673int
Tim Peters1f5871e2000-07-04 17:44:48 +00001674PyDict_DelItem(PyObject *op, PyObject *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001675{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001676 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001677 assert(key);
1678 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001679 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 hash = PyObject_Hash(key);
1681 if (hash == -1)
1682 return -1;
1683 }
Victor Stinner742da042016-09-07 17:40:12 -07001684
1685 return _PyDict_DelItem_KnownHash(op, key, hash);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001686}
1687
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001688int
1689_PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
1690{
INADA Naoki778928b2017-08-03 23:45:15 +09001691 Py_ssize_t ix;
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001692 PyDictObject *mp;
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001693 PyObject *old_value;
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001694
1695 if (!PyDict_Check(op)) {
1696 PyErr_BadInternalCall();
1697 return -1;
1698 }
1699 assert(key);
1700 assert(hash != -1);
1701 mp = (PyDictObject *)op;
INADA Naoki778928b2017-08-03 23:45:15 +09001702 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Victor Stinner742da042016-09-07 17:40:12 -07001703 if (ix == DKIX_ERROR)
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001704 return -1;
INADA Naokiba609772016-12-07 20:41:42 +09001705 if (ix == DKIX_EMPTY || old_value == NULL) {
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001706 _PyErr_SetKeyError(key);
1707 return -1;
1708 }
Victor Stinner78601a32016-09-09 19:28:36 -07001709
1710 // Split table doesn't allow deletion. Combine it.
1711 if (_PyDict_HasSplitTable(mp)) {
1712 if (dictresize(mp, DK_SIZE(mp->ma_keys))) {
1713 return -1;
1714 }
INADA Naoki778928b2017-08-03 23:45:15 +09001715 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Victor Stinner78601a32016-09-09 19:28:36 -07001716 assert(ix >= 0);
1717 }
1718
INADA Naoki778928b2017-08-03 23:45:15 +09001719 return delitem_common(mp, hash, ix, old_value);
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001720}
1721
Antoine Pitroud741ed42016-12-27 14:23:43 +01001722/* This function promises that the predicate -> deletion sequence is atomic
1723 * (i.e. protected by the GIL), assuming the predicate itself doesn't
1724 * release the GIL.
1725 */
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001726int
1727_PyDict_DelItemIf(PyObject *op, PyObject *key,
1728 int (*predicate)(PyObject *value))
1729{
Antoine Pitroud741ed42016-12-27 14:23:43 +01001730 Py_ssize_t hashpos, ix;
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001731 PyDictObject *mp;
1732 Py_hash_t hash;
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001733 PyObject *old_value;
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001734 int res;
1735
1736 if (!PyDict_Check(op)) {
1737 PyErr_BadInternalCall();
1738 return -1;
1739 }
1740 assert(key);
1741 hash = PyObject_Hash(key);
1742 if (hash == -1)
1743 return -1;
1744 mp = (PyDictObject *)op;
INADA Naoki778928b2017-08-03 23:45:15 +09001745 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Antoine Pitroud741ed42016-12-27 14:23:43 +01001746 if (ix == DKIX_ERROR)
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001747 return -1;
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001748 if (ix == DKIX_EMPTY || old_value == NULL) {
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001749 _PyErr_SetKeyError(key);
1750 return -1;
1751 }
Antoine Pitroud741ed42016-12-27 14:23:43 +01001752
1753 // Split table doesn't allow deletion. Combine it.
1754 if (_PyDict_HasSplitTable(mp)) {
1755 if (dictresize(mp, DK_SIZE(mp->ma_keys))) {
1756 return -1;
1757 }
INADA Naoki778928b2017-08-03 23:45:15 +09001758 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Antoine Pitroud741ed42016-12-27 14:23:43 +01001759 assert(ix >= 0);
1760 }
1761
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001762 res = predicate(old_value);
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001763 if (res == -1)
1764 return -1;
INADA Naoki778928b2017-08-03 23:45:15 +09001765
1766 hashpos = lookdict_index(mp->ma_keys, hash, ix);
1767 assert(hashpos >= 0);
1768
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001769 if (res > 0)
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001770 return delitem_common(mp, hashpos, ix, old_value);
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001771 else
1772 return 0;
1773}
1774
1775
Guido van Rossum25831651993-05-19 14:50:45 +00001776void
Tim Peters1f5871e2000-07-04 17:44:48 +00001777PyDict_Clear(PyObject *op)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001778{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 PyDictObject *mp;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001780 PyDictKeysObject *oldkeys;
1781 PyObject **oldvalues;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001782 Py_ssize_t i, n;
Tim Petersdea48ec2001-05-22 20:40:22 +00001783
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 if (!PyDict_Check(op))
1785 return;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001786 mp = ((PyDictObject *)op);
1787 oldkeys = mp->ma_keys;
1788 oldvalues = mp->ma_values;
1789 if (oldvalues == empty_values)
1790 return;
1791 /* Empty the dict... */
INADA Naokia7576492018-11-14 18:39:27 +09001792 dictkeys_incref(Py_EMPTY_KEYS);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001793 mp->ma_keys = Py_EMPTY_KEYS;
1794 mp->ma_values = empty_values;
1795 mp->ma_used = 0;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07001796 mp->ma_version_tag = DICT_NEXT_VERSION();
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001797 /* ...then clear the keys and values */
1798 if (oldvalues != NULL) {
Victor Stinner742da042016-09-07 17:40:12 -07001799 n = oldkeys->dk_nentries;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001800 for (i = 0; i < n; i++)
1801 Py_CLEAR(oldvalues[i]);
1802 free_values(oldvalues);
INADA Naokia7576492018-11-14 18:39:27 +09001803 dictkeys_decref(oldkeys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001804 }
1805 else {
1806 assert(oldkeys->dk_refcnt == 1);
INADA Naokia7576492018-11-14 18:39:27 +09001807 dictkeys_decref(oldkeys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001808 }
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001809 ASSERT_CONSISTENT(mp);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001810}
1811
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001812/* Internal version of PyDict_Next that returns a hash value in addition
1813 * to the key and value.
1814 * Return 1 on success, return 0 when the reached the end of the dictionary
1815 * (or if op is not a dictionary)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001816 */
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001817int
1818_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
1819 PyObject **pvalue, Py_hash_t *phash)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001820{
INADA Naokica2d8be2016-11-04 16:59:10 +09001821 Py_ssize_t i;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001822 PyDictObject *mp;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001823 PyDictKeyEntry *entry_ptr;
1824 PyObject *value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001825
1826 if (!PyDict_Check(op))
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001827 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828 mp = (PyDictObject *)op;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001829 i = *ppos;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001830 if (mp->ma_values) {
INADA Naokica2d8be2016-11-04 16:59:10 +09001831 if (i < 0 || i >= mp->ma_used)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001832 return 0;
INADA Naokica2d8be2016-11-04 16:59:10 +09001833 /* values of split table is always dense */
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001834 entry_ptr = &DK_ENTRIES(mp->ma_keys)[i];
INADA Naokica2d8be2016-11-04 16:59:10 +09001835 value = mp->ma_values[i];
1836 assert(value != NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001838 else {
INADA Naokica2d8be2016-11-04 16:59:10 +09001839 Py_ssize_t n = mp->ma_keys->dk_nentries;
1840 if (i < 0 || i >= n)
1841 return 0;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001842 entry_ptr = &DK_ENTRIES(mp->ma_keys)[i];
1843 while (i < n && entry_ptr->me_value == NULL) {
1844 entry_ptr++;
1845 i++;
Victor Stinner742da042016-09-07 17:40:12 -07001846 }
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001847 if (i >= n)
1848 return 0;
1849 value = entry_ptr->me_value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 }
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001851 *ppos = i+1;
1852 if (pkey)
1853 *pkey = entry_ptr->me_key;
1854 if (phash)
1855 *phash = entry_ptr->me_hash;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001856 if (pvalue)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001857 *pvalue = value;
1858 return 1;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001859}
1860
Tim Peters080c88b2003-02-15 03:01:11 +00001861/*
1862 * Iterate over a dict. Use like so:
1863 *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001864 * Py_ssize_t i;
Tim Peters080c88b2003-02-15 03:01:11 +00001865 * PyObject *key, *value;
1866 * i = 0; # important! i should not otherwise be changed by you
Neal Norwitz07323012003-02-15 14:45:12 +00001867 * while (PyDict_Next(yourdict, &i, &key, &value)) {
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001868 * Refer to borrowed references in key and value.
Tim Peters080c88b2003-02-15 03:01:11 +00001869 * }
1870 *
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001871 * Return 1 on success, return 0 when the reached the end of the dictionary
1872 * (or if op is not a dictionary)
1873 *
Tim Peters080c88b2003-02-15 03:01:11 +00001874 * CAUTION: In general, it isn't safe to use PyDict_Next in a loop that
Tim Peters67830702001-03-21 19:23:56 +00001875 * mutates the dict. One exception: it is safe if the loop merely changes
1876 * the values associated with the keys (but doesn't insert new keys or
1877 * delete keys), via PyDict_SetItem().
1878 */
Guido van Rossum25831651993-05-19 14:50:45 +00001879int
Martin v. Löwis18e16552006-02-15 17:27:45 +00001880PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001881{
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001882 return _PyDict_Next(op, ppos, pkey, pvalue, NULL);
Thomas Wouterscf297e42007-02-23 15:07:44 +00001883}
1884
Eric Snow96c6af92015-05-29 22:21:39 -06001885/* Internal version of dict.pop(). */
1886PyObject *
Serhiy Storchaka42e1ea92017-01-12 19:12:21 +02001887_PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *deflt)
Eric Snow96c6af92015-05-29 22:21:39 -06001888{
Victor Stinner742da042016-09-07 17:40:12 -07001889 Py_ssize_t ix, hashpos;
Eric Snow96c6af92015-05-29 22:21:39 -06001890 PyObject *old_value, *old_key;
1891 PyDictKeyEntry *ep;
Yury Selivanov684ef2c2016-10-28 19:01:21 -04001892 PyDictObject *mp;
1893
1894 assert(PyDict_Check(dict));
1895 mp = (PyDictObject *)dict;
Eric Snow96c6af92015-05-29 22:21:39 -06001896
1897 if (mp->ma_used == 0) {
1898 if (deflt) {
1899 Py_INCREF(deflt);
1900 return deflt;
1901 }
1902 _PyErr_SetKeyError(key);
1903 return NULL;
1904 }
INADA Naoki778928b2017-08-03 23:45:15 +09001905 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Victor Stinner742da042016-09-07 17:40:12 -07001906 if (ix == DKIX_ERROR)
Eric Snow96c6af92015-05-29 22:21:39 -06001907 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001908 if (ix == DKIX_EMPTY || old_value == NULL) {
Eric Snow96c6af92015-05-29 22:21:39 -06001909 if (deflt) {
1910 Py_INCREF(deflt);
1911 return deflt;
1912 }
1913 _PyErr_SetKeyError(key);
1914 return NULL;
1915 }
Victor Stinner3b6a6b42016-09-08 12:51:24 -07001916
Victor Stinner78601a32016-09-09 19:28:36 -07001917 // Split table doesn't allow deletion. Combine it.
1918 if (_PyDict_HasSplitTable(mp)) {
1919 if (dictresize(mp, DK_SIZE(mp->ma_keys))) {
1920 return NULL;
1921 }
INADA Naoki778928b2017-08-03 23:45:15 +09001922 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Victor Stinner78601a32016-09-09 19:28:36 -07001923 assert(ix >= 0);
1924 }
1925
INADA Naoki778928b2017-08-03 23:45:15 +09001926 hashpos = lookdict_index(mp->ma_keys, hash, ix);
1927 assert(hashpos >= 0);
Victor Stinner78601a32016-09-09 19:28:36 -07001928 assert(old_value != NULL);
Eric Snow96c6af92015-05-29 22:21:39 -06001929 mp->ma_used--;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07001930 mp->ma_version_tag = DICT_NEXT_VERSION();
INADA Naokia7576492018-11-14 18:39:27 +09001931 dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
Victor Stinner78601a32016-09-09 19:28:36 -07001932 ep = &DK_ENTRIES(mp->ma_keys)[ix];
1933 ENSURE_ALLOWS_DELETIONS(mp);
1934 old_key = ep->me_key;
1935 ep->me_key = NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001936 ep->me_value = NULL;
Victor Stinner78601a32016-09-09 19:28:36 -07001937 Py_DECREF(old_key);
Victor Stinner611b0fa2016-09-14 15:02:01 +02001938
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001939 ASSERT_CONSISTENT(mp);
Eric Snow96c6af92015-05-29 22:21:39 -06001940 return old_value;
1941}
1942
Serhiy Storchaka67796522017-01-12 18:34:33 +02001943PyObject *
Serhiy Storchaka42e1ea92017-01-12 19:12:21 +02001944_PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt)
Serhiy Storchaka67796522017-01-12 18:34:33 +02001945{
1946 Py_hash_t hash;
1947
Serhiy Storchaka42e1ea92017-01-12 19:12:21 +02001948 if (((PyDictObject *)dict)->ma_used == 0) {
Serhiy Storchaka67796522017-01-12 18:34:33 +02001949 if (deflt) {
1950 Py_INCREF(deflt);
1951 return deflt;
1952 }
1953 _PyErr_SetKeyError(key);
1954 return NULL;
1955 }
1956 if (!PyUnicode_CheckExact(key) ||
1957 (hash = ((PyASCIIObject *) key)->hash) == -1) {
1958 hash = PyObject_Hash(key);
1959 if (hash == -1)
1960 return NULL;
1961 }
Serhiy Storchaka42e1ea92017-01-12 19:12:21 +02001962 return _PyDict_Pop_KnownHash(dict, key, hash, deflt);
Serhiy Storchaka67796522017-01-12 18:34:33 +02001963}
1964
Eric Snow96c6af92015-05-29 22:21:39 -06001965/* Internal version of dict.from_keys(). It is subclass-friendly. */
1966PyObject *
1967_PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)
1968{
1969 PyObject *it; /* iter(iterable) */
1970 PyObject *key;
1971 PyObject *d;
1972 int status;
1973
Victor Stinnera5ed5f02016-12-06 18:45:50 +01001974 d = _PyObject_CallNoArg(cls);
Eric Snow96c6af92015-05-29 22:21:39 -06001975 if (d == NULL)
1976 return NULL;
1977
1978 if (PyDict_CheckExact(d) && ((PyDictObject *)d)->ma_used == 0) {
1979 if (PyDict_CheckExact(iterable)) {
1980 PyDictObject *mp = (PyDictObject *)d;
1981 PyObject *oldvalue;
1982 Py_ssize_t pos = 0;
1983 PyObject *key;
1984 Py_hash_t hash;
1985
Inada Naokid9323a82020-08-07 14:08:55 +09001986 if (dictresize(mp, estimate_keysize(PyDict_GET_SIZE(iterable)))) {
Eric Snow96c6af92015-05-29 22:21:39 -06001987 Py_DECREF(d);
1988 return NULL;
1989 }
1990
1991 while (_PyDict_Next(iterable, &pos, &key, &oldvalue, &hash)) {
1992 if (insertdict(mp, key, hash, value)) {
1993 Py_DECREF(d);
1994 return NULL;
1995 }
1996 }
1997 return d;
1998 }
1999 if (PyAnySet_CheckExact(iterable)) {
2000 PyDictObject *mp = (PyDictObject *)d;
2001 Py_ssize_t pos = 0;
2002 PyObject *key;
2003 Py_hash_t hash;
2004
Inada Naokid9323a82020-08-07 14:08:55 +09002005 if (dictresize(mp, estimate_keysize(PySet_GET_SIZE(iterable)))) {
Eric Snow96c6af92015-05-29 22:21:39 -06002006 Py_DECREF(d);
2007 return NULL;
2008 }
2009
2010 while (_PySet_NextEntry(iterable, &pos, &key, &hash)) {
2011 if (insertdict(mp, key, hash, value)) {
2012 Py_DECREF(d);
2013 return NULL;
2014 }
2015 }
2016 return d;
2017 }
2018 }
2019
2020 it = PyObject_GetIter(iterable);
2021 if (it == NULL){
2022 Py_DECREF(d);
2023 return NULL;
2024 }
2025
2026 if (PyDict_CheckExact(d)) {
2027 while ((key = PyIter_Next(it)) != NULL) {
2028 status = PyDict_SetItem(d, key, value);
2029 Py_DECREF(key);
2030 if (status < 0)
2031 goto Fail;
2032 }
2033 } else {
2034 while ((key = PyIter_Next(it)) != NULL) {
2035 status = PyObject_SetItem(d, key, value);
2036 Py_DECREF(key);
2037 if (status < 0)
2038 goto Fail;
2039 }
2040 }
2041
2042 if (PyErr_Occurred())
2043 goto Fail;
2044 Py_DECREF(it);
2045 return d;
2046
2047Fail:
2048 Py_DECREF(it);
2049 Py_DECREF(d);
2050 return NULL;
2051}
2052
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002053/* Methods */
2054
2055static void
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002056dict_dealloc(PyDictObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002057{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002058 PyObject **values = mp->ma_values;
2059 PyDictKeysObject *keys = mp->ma_keys;
2060 Py_ssize_t i, n;
INADA Naokia6296d32017-08-24 14:55:17 +09002061
2062 /* bpo-31095: UnTrack is needed before calling any callbacks */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002063 PyObject_GC_UnTrack(mp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02002064 Py_TRASHCAN_BEGIN(mp, dict_dealloc)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002065 if (values != NULL) {
2066 if (values != empty_values) {
Victor Stinner742da042016-09-07 17:40:12 -07002067 for (i = 0, n = mp->ma_keys->dk_nentries; i < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002068 Py_XDECREF(values[i]);
2069 }
2070 free_values(values);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002071 }
INADA Naokia7576492018-11-14 18:39:27 +09002072 dictkeys_decref(keys);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 }
Victor Stinnerac2a4fe2013-07-16 22:19:00 +02002074 else if (keys != NULL) {
Antoine Pitrou2d169b22012-05-12 23:43:44 +02002075 assert(keys->dk_refcnt == 1);
INADA Naokia7576492018-11-14 18:39:27 +09002076 dictkeys_decref(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002077 }
Victor Stinner522691c2020-06-23 16:40:40 +02002078 struct _Py_dict_state *state = get_dict_state();
Victor Stinnerb4e85ca2020-06-23 11:33:18 +02002079#ifdef Py_DEBUG
2080 // new_dict() must not be called after _PyDict_Fini()
2081 assert(state->numfree != -1);
Victor Stinnerb4b53862020-05-05 19:55:29 +02002082#endif
Victor Stinnerb4e85ca2020-06-23 11:33:18 +02002083 if (state->numfree < PyDict_MAXFREELIST && Py_IS_TYPE(mp, &PyDict_Type)) {
2084 state->free_list[state->numfree++] = mp;
2085 }
2086 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002087 Py_TYPE(mp)->tp_free((PyObject *)mp);
Victor Stinnerb4b53862020-05-05 19:55:29 +02002088 }
Jeroen Demeyer351c6742019-05-10 19:21:11 +02002089 Py_TRASHCAN_END
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002090}
2091
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002092
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002093static PyObject *
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002094dict_repr(PyDictObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002095{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 Py_ssize_t i;
Victor Stinnerf91929b2013-11-19 13:07:38 +01002097 PyObject *key = NULL, *value = NULL;
2098 _PyUnicodeWriter writer;
2099 int first;
Guido van Rossum255443b1998-04-10 22:47:14 +00002100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 i = Py_ReprEnter((PyObject *)mp);
2102 if (i != 0) {
2103 return i > 0 ? PyUnicode_FromString("{...}") : NULL;
2104 }
Guido van Rossum255443b1998-04-10 22:47:14 +00002105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002106 if (mp->ma_used == 0) {
Victor Stinnerf91929b2013-11-19 13:07:38 +01002107 Py_ReprLeave((PyObject *)mp);
2108 return PyUnicode_FromString("{}");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 }
Tim Petersa7259592001-06-16 05:11:17 +00002110
Victor Stinnerf91929b2013-11-19 13:07:38 +01002111 _PyUnicodeWriter_Init(&writer);
2112 writer.overallocate = 1;
2113 /* "{" + "1: 2" + ", 3: 4" * (len - 1) + "}" */
2114 writer.min_length = 1 + 4 + (2 + 4) * (mp->ma_used - 1) + 1;
Tim Petersa7259592001-06-16 05:11:17 +00002115
Victor Stinnerf91929b2013-11-19 13:07:38 +01002116 if (_PyUnicodeWriter_WriteChar(&writer, '{') < 0)
2117 goto error;
Tim Petersa7259592001-06-16 05:11:17 +00002118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002119 /* Do repr() on each key+value pair, and insert ": " between them.
2120 Note that repr may mutate the dict. */
2121 i = 0;
Victor Stinnerf91929b2013-11-19 13:07:38 +01002122 first = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 while (PyDict_Next((PyObject *)mp, &i, &key, &value)) {
Victor Stinnerf91929b2013-11-19 13:07:38 +01002124 PyObject *s;
2125 int res;
2126
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002127 /* Prevent repr from deleting key or value during key format. */
2128 Py_INCREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002129 Py_INCREF(value);
Victor Stinnerf97dfd72013-07-18 01:00:45 +02002130
Victor Stinnerf91929b2013-11-19 13:07:38 +01002131 if (!first) {
2132 if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0)
2133 goto error;
2134 }
2135 first = 0;
2136
2137 s = PyObject_Repr(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002138 if (s == NULL)
Victor Stinnerf91929b2013-11-19 13:07:38 +01002139 goto error;
2140 res = _PyUnicodeWriter_WriteStr(&writer, s);
2141 Py_DECREF(s);
2142 if (res < 0)
2143 goto error;
2144
2145 if (_PyUnicodeWriter_WriteASCIIString(&writer, ": ", 2) < 0)
2146 goto error;
2147
2148 s = PyObject_Repr(value);
2149 if (s == NULL)
2150 goto error;
2151 res = _PyUnicodeWriter_WriteStr(&writer, s);
2152 Py_DECREF(s);
2153 if (res < 0)
2154 goto error;
2155
2156 Py_CLEAR(key);
2157 Py_CLEAR(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002158 }
Tim Petersa7259592001-06-16 05:11:17 +00002159
Victor Stinnerf91929b2013-11-19 13:07:38 +01002160 writer.overallocate = 0;
2161 if (_PyUnicodeWriter_WriteChar(&writer, '}') < 0)
2162 goto error;
Tim Petersa7259592001-06-16 05:11:17 +00002163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 Py_ReprLeave((PyObject *)mp);
Victor Stinnerf91929b2013-11-19 13:07:38 +01002165
2166 return _PyUnicodeWriter_Finish(&writer);
2167
2168error:
2169 Py_ReprLeave((PyObject *)mp);
2170 _PyUnicodeWriter_Dealloc(&writer);
2171 Py_XDECREF(key);
2172 Py_XDECREF(value);
2173 return NULL;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002174}
2175
Martin v. Löwis18e16552006-02-15 17:27:45 +00002176static Py_ssize_t
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002177dict_length(PyDictObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002178{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002179 return mp->ma_used;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002180}
2181
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002182static PyObject *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002183dict_subscript(PyDictObject *mp, PyObject *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002184{
Victor Stinner742da042016-09-07 17:40:12 -07002185 Py_ssize_t ix;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002186 Py_hash_t hash;
INADA Naokiba609772016-12-07 20:41:42 +09002187 PyObject *value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002190 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 hash = PyObject_Hash(key);
2192 if (hash == -1)
2193 return NULL;
2194 }
INADA Naoki778928b2017-08-03 23:45:15 +09002195 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07002196 if (ix == DKIX_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002197 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09002198 if (ix == DKIX_EMPTY || value == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 if (!PyDict_CheckExact(mp)) {
2200 /* Look up __missing__ method if we're a subclass. */
2201 PyObject *missing, *res;
Benjamin Petersonce798522012-01-22 11:24:29 -05002202 _Py_IDENTIFIER(__missing__);
2203 missing = _PyObject_LookupSpecial((PyObject *)mp, &PyId___missing__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002204 if (missing != NULL) {
Petr Viktorinffd97532020-02-11 17:46:57 +01002205 res = PyObject_CallOneArg(missing, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002206 Py_DECREF(missing);
2207 return res;
2208 }
2209 else if (PyErr_Occurred())
2210 return NULL;
2211 }
Raymond Hettinger69492da2013-09-02 15:59:26 -07002212 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002213 return NULL;
2214 }
INADA Naokiba609772016-12-07 20:41:42 +09002215 Py_INCREF(value);
2216 return value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002217}
2218
2219static int
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002220dict_ass_sub(PyDictObject *mp, PyObject *v, PyObject *w)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002221{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002222 if (w == NULL)
2223 return PyDict_DelItem((PyObject *)mp, v);
2224 else
2225 return PyDict_SetItem((PyObject *)mp, v, w);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002226}
2227
Guido van Rossuma9e7a811997-05-13 21:02:11 +00002228static PyMappingMethods dict_as_mapping = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002229 (lenfunc)dict_length, /*mp_length*/
2230 (binaryfunc)dict_subscript, /*mp_subscript*/
2231 (objobjargproc)dict_ass_sub, /*mp_ass_subscript*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002232};
2233
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002234static PyObject *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002235dict_keys(PyDictObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002236{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002237 PyObject *v;
2238 Py_ssize_t i, j;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002239 PyDictKeyEntry *ep;
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002240 Py_ssize_t n, offset;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002241 PyObject **value_ptr;
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002242
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002243 again:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002244 n = mp->ma_used;
2245 v = PyList_New(n);
2246 if (v == NULL)
2247 return NULL;
2248 if (n != mp->ma_used) {
2249 /* Durnit. The allocations caused the dict to resize.
2250 * Just start over, this shouldn't normally happen.
2251 */
2252 Py_DECREF(v);
2253 goto again;
2254 }
Victor Stinner742da042016-09-07 17:40:12 -07002255 ep = DK_ENTRIES(mp->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002256 if (mp->ma_values) {
2257 value_ptr = mp->ma_values;
2258 offset = sizeof(PyObject *);
2259 }
2260 else {
2261 value_ptr = &ep[0].me_value;
2262 offset = sizeof(PyDictKeyEntry);
2263 }
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002264 for (i = 0, j = 0; j < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002265 if (*value_ptr != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002266 PyObject *key = ep[i].me_key;
2267 Py_INCREF(key);
2268 PyList_SET_ITEM(v, j, key);
2269 j++;
2270 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002271 value_ptr = (PyObject **)(((char *)value_ptr) + offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002272 }
2273 assert(j == n);
2274 return v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002275}
2276
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002277static PyObject *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002278dict_values(PyDictObject *mp)
Guido van Rossum25831651993-05-19 14:50:45 +00002279{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002280 PyObject *v;
2281 Py_ssize_t i, j;
Benjamin Petersonf0acae22016-09-08 09:50:08 -07002282 PyDictKeyEntry *ep;
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002283 Py_ssize_t n, offset;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002284 PyObject **value_ptr;
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002285
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002286 again:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002287 n = mp->ma_used;
2288 v = PyList_New(n);
2289 if (v == NULL)
2290 return NULL;
2291 if (n != mp->ma_used) {
2292 /* Durnit. The allocations caused the dict to resize.
2293 * Just start over, this shouldn't normally happen.
2294 */
2295 Py_DECREF(v);
2296 goto again;
2297 }
Benjamin Petersonf0acae22016-09-08 09:50:08 -07002298 ep = DK_ENTRIES(mp->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002299 if (mp->ma_values) {
2300 value_ptr = mp->ma_values;
2301 offset = sizeof(PyObject *);
2302 }
2303 else {
Benjamin Petersonf0acae22016-09-08 09:50:08 -07002304 value_ptr = &ep[0].me_value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002305 offset = sizeof(PyDictKeyEntry);
2306 }
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002307 for (i = 0, j = 0; j < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002308 PyObject *value = *value_ptr;
2309 value_ptr = (PyObject **)(((char *)value_ptr) + offset);
2310 if (value != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002311 Py_INCREF(value);
2312 PyList_SET_ITEM(v, j, value);
2313 j++;
2314 }
2315 }
2316 assert(j == n);
2317 return v;
Guido van Rossum25831651993-05-19 14:50:45 +00002318}
2319
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002320static PyObject *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002321dict_items(PyDictObject *mp)
Guido van Rossum25831651993-05-19 14:50:45 +00002322{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002323 PyObject *v;
2324 Py_ssize_t i, j, n;
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002325 Py_ssize_t offset;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002326 PyObject *item, *key;
2327 PyDictKeyEntry *ep;
2328 PyObject **value_ptr;
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002330 /* Preallocate the list of tuples, to avoid allocations during
2331 * the loop over the items, which could trigger GC, which
2332 * could resize the dict. :-(
2333 */
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002334 again:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002335 n = mp->ma_used;
2336 v = PyList_New(n);
2337 if (v == NULL)
2338 return NULL;
2339 for (i = 0; i < n; i++) {
2340 item = PyTuple_New(2);
2341 if (item == NULL) {
2342 Py_DECREF(v);
2343 return NULL;
2344 }
2345 PyList_SET_ITEM(v, i, item);
2346 }
2347 if (n != mp->ma_used) {
2348 /* Durnit. The allocations caused the dict to resize.
2349 * Just start over, this shouldn't normally happen.
2350 */
2351 Py_DECREF(v);
2352 goto again;
2353 }
2354 /* Nothing we do below makes any function calls. */
Victor Stinner742da042016-09-07 17:40:12 -07002355 ep = DK_ENTRIES(mp->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002356 if (mp->ma_values) {
2357 value_ptr = mp->ma_values;
2358 offset = sizeof(PyObject *);
2359 }
2360 else {
2361 value_ptr = &ep[0].me_value;
2362 offset = sizeof(PyDictKeyEntry);
2363 }
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002364 for (i = 0, j = 0; j < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002365 PyObject *value = *value_ptr;
2366 value_ptr = (PyObject **)(((char *)value_ptr) + offset);
2367 if (value != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002368 key = ep[i].me_key;
2369 item = PyList_GET_ITEM(v, j);
2370 Py_INCREF(key);
2371 PyTuple_SET_ITEM(item, 0, key);
2372 Py_INCREF(value);
2373 PyTuple_SET_ITEM(item, 1, value);
2374 j++;
2375 }
2376 }
2377 assert(j == n);
2378 return v;
Guido van Rossum25831651993-05-19 14:50:45 +00002379}
2380
Larry Hastings5c661892014-01-24 06:17:25 -08002381/*[clinic input]
2382@classmethod
2383dict.fromkeys
Larry Hastings5c661892014-01-24 06:17:25 -08002384 iterable: object
2385 value: object=None
2386 /
2387
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002388Create a new dictionary with keys from iterable and values set to value.
Larry Hastings5c661892014-01-24 06:17:25 -08002389[clinic start generated code]*/
2390
Larry Hastings5c661892014-01-24 06:17:25 -08002391static PyObject *
2392dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002393/*[clinic end generated code: output=8fb98e4b10384999 input=382ba4855d0f74c3]*/
Larry Hastings5c661892014-01-24 06:17:25 -08002394{
Eric Snow96c6af92015-05-29 22:21:39 -06002395 return _PyDict_FromKeys((PyObject *)type, iterable, value);
Raymond Hettingere33d3df2002-11-27 07:29:33 +00002396}
2397
Brandt Buchereb8ac572020-02-24 19:47:34 -08002398/* Single-arg dict update; used by dict_update_common and operators. */
2399static int
2400dict_update_arg(PyObject *self, PyObject *arg)
2401{
2402 if (PyDict_CheckExact(arg)) {
2403 return PyDict_Merge(self, arg, 1);
2404 }
2405 _Py_IDENTIFIER(keys);
2406 PyObject *func;
2407 if (_PyObject_LookupAttrId(arg, &PyId_keys, &func) < 0) {
2408 return -1;
2409 }
2410 if (func != NULL) {
2411 Py_DECREF(func);
2412 return PyDict_Merge(self, arg, 1);
2413 }
2414 return PyDict_MergeFromSeq2(self, arg, 1);
2415}
2416
Raymond Hettinger31017ae2004-03-04 08:25:44 +00002417static int
Victor Stinner742da042016-09-07 17:40:12 -07002418dict_update_common(PyObject *self, PyObject *args, PyObject *kwds,
2419 const char *methname)
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002420{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 PyObject *arg = NULL;
2422 int result = 0;
Raymond Hettinger31017ae2004-03-04 08:25:44 +00002423
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002424 if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002425 result = -1;
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002426 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002427 else if (arg != NULL) {
Brandt Buchereb8ac572020-02-24 19:47:34 -08002428 result = dict_update_arg(self, arg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002429 }
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002431 if (result == 0 && kwds != NULL) {
2432 if (PyArg_ValidateKeywordArguments(kwds))
2433 result = PyDict_Merge(self, kwds, 1);
2434 else
2435 result = -1;
2436 }
2437 return result;
Raymond Hettinger31017ae2004-03-04 08:25:44 +00002438}
2439
Victor Stinner91f0d4a2017-01-19 12:45:06 +01002440/* Note: dict.update() uses the METH_VARARGS|METH_KEYWORDS calling convention.
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002441 Using METH_FASTCALL|METH_KEYWORDS would make dict.update(**dict2) calls
2442 slower, see the issue #29312. */
Raymond Hettinger31017ae2004-03-04 08:25:44 +00002443static PyObject *
2444dict_update(PyObject *self, PyObject *args, PyObject *kwds)
2445{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002446 if (dict_update_common(self, args, kwds, "update") != -1)
2447 Py_RETURN_NONE;
2448 return NULL;
Tim Peters6d6c1a32001-08-02 04:15:00 +00002449}
2450
Guido van Rossum05ac6de2001-08-10 20:28:28 +00002451/* Update unconditionally replaces existing items.
2452 Merge has a 3rd argument 'override'; if set, it acts like Update,
Tim Peters1fc240e2001-10-26 05:06:50 +00002453 otherwise it leaves existing items unchanged.
2454
2455 PyDict_{Update,Merge} update/merge from a mapping object.
2456
Tim Petersf582b822001-12-11 18:51:08 +00002457 PyDict_MergeFromSeq2 updates/merges from any iterable object
Tim Peters1fc240e2001-10-26 05:06:50 +00002458 producing iterable objects of length 2.
2459*/
2460
Tim Petersf582b822001-12-11 18:51:08 +00002461int
Tim Peters1fc240e2001-10-26 05:06:50 +00002462PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)
2463{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002464 PyObject *it; /* iter(seq2) */
2465 Py_ssize_t i; /* index into seq2 of current element */
2466 PyObject *item; /* seq2[i] */
2467 PyObject *fast; /* item as a 2-tuple or 2-list */
Tim Peters1fc240e2001-10-26 05:06:50 +00002468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002469 assert(d != NULL);
2470 assert(PyDict_Check(d));
2471 assert(seq2 != NULL);
Tim Peters1fc240e2001-10-26 05:06:50 +00002472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002473 it = PyObject_GetIter(seq2);
2474 if (it == NULL)
2475 return -1;
Tim Peters1fc240e2001-10-26 05:06:50 +00002476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002477 for (i = 0; ; ++i) {
2478 PyObject *key, *value;
2479 Py_ssize_t n;
Tim Peters1fc240e2001-10-26 05:06:50 +00002480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002481 fast = NULL;
2482 item = PyIter_Next(it);
2483 if (item == NULL) {
2484 if (PyErr_Occurred())
2485 goto Fail;
2486 break;
2487 }
Tim Peters1fc240e2001-10-26 05:06:50 +00002488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002489 /* Convert item to sequence, and verify length 2. */
2490 fast = PySequence_Fast(item, "");
2491 if (fast == NULL) {
2492 if (PyErr_ExceptionMatches(PyExc_TypeError))
2493 PyErr_Format(PyExc_TypeError,
2494 "cannot convert dictionary update "
2495 "sequence element #%zd to a sequence",
2496 i);
2497 goto Fail;
2498 }
2499 n = PySequence_Fast_GET_SIZE(fast);
2500 if (n != 2) {
2501 PyErr_Format(PyExc_ValueError,
2502 "dictionary update sequence element #%zd "
2503 "has length %zd; 2 is required",
2504 i, n);
2505 goto Fail;
2506 }
Tim Peters1fc240e2001-10-26 05:06:50 +00002507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002508 /* Update/merge with this (key, value) pair. */
2509 key = PySequence_Fast_GET_ITEM(fast, 0);
2510 value = PySequence_Fast_GET_ITEM(fast, 1);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002511 Py_INCREF(key);
2512 Py_INCREF(value);
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002513 if (override) {
2514 if (PyDict_SetItem(d, key, value) < 0) {
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002515 Py_DECREF(key);
2516 Py_DECREF(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002517 goto Fail;
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002518 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002519 }
Serhiy Storchakab510e102020-10-26 12:47:57 +02002520 else {
2521 if (PyDict_SetDefault(d, key, value) == NULL) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002522 Py_DECREF(key);
2523 Py_DECREF(value);
2524 goto Fail;
2525 }
2526 }
2527
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002528 Py_DECREF(key);
2529 Py_DECREF(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002530 Py_DECREF(fast);
2531 Py_DECREF(item);
2532 }
Tim Peters1fc240e2001-10-26 05:06:50 +00002533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002534 i = 0;
Victor Stinner0fc91ee2019-04-12 21:51:34 +02002535 ASSERT_CONSISTENT(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002536 goto Return;
Tim Peters1fc240e2001-10-26 05:06:50 +00002537Fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002538 Py_XDECREF(item);
2539 Py_XDECREF(fast);
2540 i = -1;
Tim Peters1fc240e2001-10-26 05:06:50 +00002541Return:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002542 Py_DECREF(it);
2543 return Py_SAFE_DOWNCAST(i, Py_ssize_t, int);
Tim Peters1fc240e2001-10-26 05:06:50 +00002544}
2545
doko@ubuntu.comc96df682016-10-11 08:04:02 +02002546static int
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002547dict_merge(PyObject *a, PyObject *b, int override)
Guido van Rossum05ac6de2001-08-10 20:28:28 +00002548{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002549 PyDictObject *mp, *other;
2550 Py_ssize_t i, n;
Victor Stinner742da042016-09-07 17:40:12 -07002551 PyDictKeyEntry *entry, *ep0;
Tim Peters6d6c1a32001-08-02 04:15:00 +00002552
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002553 assert(0 <= override && override <= 2);
2554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002555 /* We accept for the argument either a concrete dictionary object,
2556 * or an abstract "mapping" object. For the former, we can do
2557 * things quite efficiently. For the latter, we only require that
2558 * PyMapping_Keys() and PyObject_GetItem() be supported.
2559 */
2560 if (a == NULL || !PyDict_Check(a) || b == NULL) {
2561 PyErr_BadInternalCall();
2562 return -1;
2563 }
2564 mp = (PyDictObject*)a;
INADA Naoki2aaf98c2018-09-26 12:59:00 +09002565 if (PyDict_Check(b) && (Py_TYPE(b)->tp_iter == (getiterfunc)dict_iter)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002566 other = (PyDictObject*)b;
2567 if (other == mp || other->ma_used == 0)
2568 /* a.update(a) or a.update({}); nothing to do */
2569 return 0;
Inada Naokidb6d9a52020-08-04 11:08:06 +09002570 if (mp->ma_used == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002571 /* Since the target dict is empty, PyDict_GetItem()
2572 * always returns NULL. Setting override to 1
2573 * skips the unnecessary test.
2574 */
2575 override = 1;
Inada Naokidb6d9a52020-08-04 11:08:06 +09002576 PyDictKeysObject *okeys = other->ma_keys;
2577
2578 // If other is clean, combined, and just allocated, just clone it.
2579 if (other->ma_values == NULL &&
2580 other->ma_used == okeys->dk_nentries &&
2581 (okeys->dk_size == PyDict_MINSIZE ||
2582 USABLE_FRACTION(okeys->dk_size/2) < other->ma_used)) {
2583 PyDictKeysObject *keys = clone_combined_dict_keys(other);
2584 if (keys == NULL) {
2585 return -1;
2586 }
2587
2588 dictkeys_decref(mp->ma_keys);
2589 mp->ma_keys = keys;
2590 if (mp->ma_values != NULL) {
2591 if (mp->ma_values != empty_values) {
2592 free_values(mp->ma_values);
2593 }
2594 mp->ma_values = NULL;
2595 }
2596
2597 mp->ma_used = other->ma_used;
2598 mp->ma_version_tag = DICT_NEXT_VERSION();
2599 ASSERT_CONSISTENT(mp);
2600
2601 if (_PyObject_GC_IS_TRACKED(other) && !_PyObject_GC_IS_TRACKED(mp)) {
2602 /* Maintain tracking. */
2603 _PyObject_GC_TRACK(mp);
2604 }
2605
2606 return 0;
2607 }
2608 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002609 /* Do one big resize at the start, rather than
2610 * incrementally resizing as we insert new items. Expect
2611 * that there will be no (or few) overlapping keys.
2612 */
INADA Naokib1152be2016-10-27 19:26:50 +09002613 if (USABLE_FRACTION(mp->ma_keys->dk_size) < other->ma_used) {
Inada Naokid9323a82020-08-07 14:08:55 +09002614 if (dictresize(mp, estimate_keysize(mp->ma_used + other->ma_used))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002615 return -1;
INADA Naokib1152be2016-10-27 19:26:50 +09002616 }
2617 }
Victor Stinner742da042016-09-07 17:40:12 -07002618 ep0 = DK_ENTRIES(other->ma_keys);
2619 for (i = 0, n = other->ma_keys->dk_nentries; i < n; i++) {
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002620 PyObject *key, *value;
2621 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07002622 entry = &ep0[i];
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002623 key = entry->me_key;
2624 hash = entry->me_hash;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002625 if (other->ma_values)
2626 value = other->ma_values[i];
2627 else
2628 value = entry->me_value;
2629
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002630 if (value != NULL) {
2631 int err = 0;
2632 Py_INCREF(key);
2633 Py_INCREF(value);
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02002634 if (override == 1)
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002635 err = insertdict(mp, key, hash, value);
Serhiy Storchakab510e102020-10-26 12:47:57 +02002636 else {
2637 err = _PyDict_Contains_KnownHash(a, key, hash);
2638 if (err == 0) {
2639 err = insertdict(mp, key, hash, value);
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02002640 }
Serhiy Storchakab510e102020-10-26 12:47:57 +02002641 else if (err > 0) {
2642 if (override != 0) {
2643 _PyErr_SetKeyError(key);
2644 Py_DECREF(value);
2645 Py_DECREF(key);
2646 return -1;
2647 }
2648 err = 0;
2649 }
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002650 }
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002651 Py_DECREF(value);
2652 Py_DECREF(key);
2653 if (err != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002654 return -1;
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002655
Victor Stinner742da042016-09-07 17:40:12 -07002656 if (n != other->ma_keys->dk_nentries) {
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002657 PyErr_SetString(PyExc_RuntimeError,
2658 "dict mutated during update");
2659 return -1;
2660 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002661 }
2662 }
2663 }
2664 else {
2665 /* Do it the generic, slower way */
2666 PyObject *keys = PyMapping_Keys(b);
2667 PyObject *iter;
2668 PyObject *key, *value;
2669 int status;
Barry Warsaw66a0d1d2001-06-26 20:08:32 +00002670
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002671 if (keys == NULL)
2672 /* Docstring says this is equivalent to E.keys() so
2673 * if E doesn't have a .keys() method we want
2674 * AttributeError to percolate up. Might as well
2675 * do the same for any other error.
2676 */
2677 return -1;
Barry Warsaw66a0d1d2001-06-26 20:08:32 +00002678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002679 iter = PyObject_GetIter(keys);
2680 Py_DECREF(keys);
2681 if (iter == NULL)
2682 return -1;
Barry Warsaw66a0d1d2001-06-26 20:08:32 +00002683
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002684 for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002685 if (override != 1) {
Serhiy Storchakab510e102020-10-26 12:47:57 +02002686 status = PyDict_Contains(a, key);
2687 if (status != 0) {
2688 if (status > 0) {
2689 if (override == 0) {
2690 Py_DECREF(key);
2691 continue;
2692 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002693 _PyErr_SetKeyError(key);
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002694 }
2695 Py_DECREF(key);
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002696 Py_DECREF(iter);
2697 return -1;
2698 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002699 }
2700 value = PyObject_GetItem(b, key);
2701 if (value == NULL) {
2702 Py_DECREF(iter);
2703 Py_DECREF(key);
2704 return -1;
2705 }
2706 status = PyDict_SetItem(a, key, value);
2707 Py_DECREF(key);
2708 Py_DECREF(value);
2709 if (status < 0) {
2710 Py_DECREF(iter);
2711 return -1;
2712 }
2713 }
2714 Py_DECREF(iter);
2715 if (PyErr_Occurred())
2716 /* Iterator completed, via error */
2717 return -1;
2718 }
Victor Stinner0fc91ee2019-04-12 21:51:34 +02002719 ASSERT_CONSISTENT(a);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002720 return 0;
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002721}
2722
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002723int
2724PyDict_Update(PyObject *a, PyObject *b)
2725{
2726 return dict_merge(a, b, 1);
2727}
2728
2729int
2730PyDict_Merge(PyObject *a, PyObject *b, int override)
2731{
2732 /* XXX Deprecate override not in (0, 1). */
2733 return dict_merge(a, b, override != 0);
2734}
2735
2736int
2737_PyDict_MergeEx(PyObject *a, PyObject *b, int override)
2738{
2739 return dict_merge(a, b, override);
2740}
2741
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002742static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302743dict_copy(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002744{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002745 return PyDict_Copy((PyObject*)mp);
Jeremy Hyltona12c7a72000-03-30 22:27:31 +00002746}
2747
2748PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00002749PyDict_Copy(PyObject *o)
Jeremy Hyltona12c7a72000-03-30 22:27:31 +00002750{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002751 PyObject *copy;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002752 PyDictObject *mp;
2753 Py_ssize_t i, n;
Jeremy Hyltona12c7a72000-03-30 22:27:31 +00002754
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002755 if (o == NULL || !PyDict_Check(o)) {
2756 PyErr_BadInternalCall();
2757 return NULL;
2758 }
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002759
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002760 mp = (PyDictObject *)o;
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002761 if (mp->ma_used == 0) {
2762 /* The dict is empty; just return a new dict. */
2763 return PyDict_New();
2764 }
2765
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002766 if (_PyDict_HasSplitTable(mp)) {
2767 PyDictObject *split_copy;
Victor Stinner742da042016-09-07 17:40:12 -07002768 Py_ssize_t size = USABLE_FRACTION(DK_SIZE(mp->ma_keys));
2769 PyObject **newvalues;
2770 newvalues = new_values(size);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002771 if (newvalues == NULL)
2772 return PyErr_NoMemory();
2773 split_copy = PyObject_GC_New(PyDictObject, &PyDict_Type);
2774 if (split_copy == NULL) {
2775 free_values(newvalues);
2776 return NULL;
2777 }
2778 split_copy->ma_values = newvalues;
2779 split_copy->ma_keys = mp->ma_keys;
2780 split_copy->ma_used = mp->ma_used;
INADA Naokid1c82c52018-04-03 11:43:53 +09002781 split_copy->ma_version_tag = DICT_NEXT_VERSION();
INADA Naokia7576492018-11-14 18:39:27 +09002782 dictkeys_incref(mp->ma_keys);
Victor Stinner742da042016-09-07 17:40:12 -07002783 for (i = 0, n = size; i < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002784 PyObject *value = mp->ma_values[i];
2785 Py_XINCREF(value);
2786 split_copy->ma_values[i] = value;
2787 }
Benjamin Peterson7ce67e42012-04-24 10:32:57 -04002788 if (_PyObject_GC_IS_TRACKED(mp))
2789 _PyObject_GC_TRACK(split_copy);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002790 return (PyObject *)split_copy;
2791 }
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002792
Inada Naokidb6d9a52020-08-04 11:08:06 +09002793 if (Py_TYPE(mp)->tp_iter == (getiterfunc)dict_iter &&
2794 mp->ma_values == NULL &&
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002795 (mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3))
2796 {
2797 /* Use fast-copy if:
2798
Inada Naokidb6d9a52020-08-04 11:08:06 +09002799 (1) type(mp) doesn't override tp_iter; and
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002800
2801 (2) 'mp' is not a split-dict; and
2802
2803 (3) if 'mp' is non-compact ('del' operation does not resize dicts),
2804 do fast-copy only if it has at most 1/3 non-used keys.
2805
Ville Skyttä61f82e02018-04-20 23:08:45 +03002806 The last condition (3) is important to guard against a pathological
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002807 case when a large dict is almost emptied with multiple del/pop
2808 operations and copied after that. In cases like this, we defer to
2809 PyDict_Merge, which produces a compacted copy.
2810 */
Inada Naokidb6d9a52020-08-04 11:08:06 +09002811 PyDictKeysObject *keys = clone_combined_dict_keys(mp);
2812 if (keys == NULL) {
2813 return NULL;
2814 }
2815 PyDictObject *new = (PyDictObject *)new_dict(keys, NULL);
2816 if (new == NULL) {
2817 /* In case of an error, `new_dict()` takes care of
2818 cleaning up `keys`. */
2819 return NULL;
2820 }
2821
2822 new->ma_used = mp->ma_used;
2823 ASSERT_CONSISTENT(new);
2824 if (_PyObject_GC_IS_TRACKED(mp)) {
2825 /* Maintain tracking. */
2826 _PyObject_GC_TRACK(new);
2827 }
2828
2829 return (PyObject *)new;
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002830 }
2831
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002832 copy = PyDict_New();
2833 if (copy == NULL)
2834 return NULL;
Inada Naokidb6d9a52020-08-04 11:08:06 +09002835 if (dict_merge(copy, o, 1) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002836 return copy;
2837 Py_DECREF(copy);
2838 return NULL;
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002839}
2840
Martin v. Löwis18e16552006-02-15 17:27:45 +00002841Py_ssize_t
Tim Peters1f5871e2000-07-04 17:44:48 +00002842PyDict_Size(PyObject *mp)
Guido van Rossum4199fac1993-11-05 10:18:44 +00002843{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002844 if (mp == NULL || !PyDict_Check(mp)) {
2845 PyErr_BadInternalCall();
2846 return -1;
2847 }
2848 return ((PyDictObject *)mp)->ma_used;
Guido van Rossum4199fac1993-11-05 10:18:44 +00002849}
2850
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002851PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00002852PyDict_Keys(PyObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002853{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002854 if (mp == NULL || !PyDict_Check(mp)) {
2855 PyErr_BadInternalCall();
2856 return NULL;
2857 }
2858 return dict_keys((PyDictObject *)mp);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002859}
2860
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002861PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00002862PyDict_Values(PyObject *mp)
Guido van Rossum25831651993-05-19 14:50:45 +00002863{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002864 if (mp == NULL || !PyDict_Check(mp)) {
2865 PyErr_BadInternalCall();
2866 return NULL;
2867 }
2868 return dict_values((PyDictObject *)mp);
Guido van Rossum25831651993-05-19 14:50:45 +00002869}
2870
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002871PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00002872PyDict_Items(PyObject *mp)
Guido van Rossum25831651993-05-19 14:50:45 +00002873{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002874 if (mp == NULL || !PyDict_Check(mp)) {
2875 PyErr_BadInternalCall();
2876 return NULL;
2877 }
2878 return dict_items((PyDictObject *)mp);
Guido van Rossum25831651993-05-19 14:50:45 +00002879}
2880
Tim Peterse63415e2001-05-08 04:38:29 +00002881/* Return 1 if dicts equal, 0 if not, -1 if error.
2882 * Gets out as soon as any difference is detected.
2883 * Uses only Py_EQ comparison.
2884 */
2885static int
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002886dict_equal(PyDictObject *a, PyDictObject *b)
Tim Peterse63415e2001-05-08 04:38:29 +00002887{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002888 Py_ssize_t i;
Tim Peterse63415e2001-05-08 04:38:29 +00002889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002890 if (a->ma_used != b->ma_used)
2891 /* can't be equal if # of entries differ */
2892 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002893 /* Same # of entries -- check all of 'em. Exit early on any diff. */
Victor Stinner742da042016-09-07 17:40:12 -07002894 for (i = 0; i < a->ma_keys->dk_nentries; i++) {
2895 PyDictKeyEntry *ep = &DK_ENTRIES(a->ma_keys)[i];
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002896 PyObject *aval;
2897 if (a->ma_values)
2898 aval = a->ma_values[i];
2899 else
2900 aval = ep->me_value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002901 if (aval != NULL) {
2902 int cmp;
2903 PyObject *bval;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002904 PyObject *key = ep->me_key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002905 /* temporarily bump aval's refcount to ensure it stays
2906 alive until we're done with it */
2907 Py_INCREF(aval);
2908 /* ditto for key */
2909 Py_INCREF(key);
Antoine Pitrou0e9958b2012-12-02 19:10:07 +01002910 /* reuse the known hash value */
INADA Naoki778928b2017-08-03 23:45:15 +09002911 b->ma_keys->dk_lookup(b, key, ep->me_hash, &bval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002912 if (bval == NULL) {
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002913 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002914 Py_DECREF(aval);
2915 if (PyErr_Occurred())
2916 return -1;
2917 return 0;
2918 }
Dong-hee Na2d5bf562019-12-31 10:04:22 +09002919 Py_INCREF(bval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002920 cmp = PyObject_RichCompareBool(aval, bval, Py_EQ);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002921 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002922 Py_DECREF(aval);
Dong-hee Na2d5bf562019-12-31 10:04:22 +09002923 Py_DECREF(bval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002924 if (cmp <= 0) /* error or not equal */
2925 return cmp;
2926 }
2927 }
2928 return 1;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002929}
Tim Peterse63415e2001-05-08 04:38:29 +00002930
2931static PyObject *
2932dict_richcompare(PyObject *v, PyObject *w, int op)
2933{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002934 int cmp;
2935 PyObject *res;
Tim Peterse63415e2001-05-08 04:38:29 +00002936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002937 if (!PyDict_Check(v) || !PyDict_Check(w)) {
2938 res = Py_NotImplemented;
2939 }
2940 else if (op == Py_EQ || op == Py_NE) {
2941 cmp = dict_equal((PyDictObject *)v, (PyDictObject *)w);
2942 if (cmp < 0)
2943 return NULL;
2944 res = (cmp == (op == Py_EQ)) ? Py_True : Py_False;
2945 }
2946 else
2947 res = Py_NotImplemented;
2948 Py_INCREF(res);
2949 return res;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002950}
Tim Peterse63415e2001-05-08 04:38:29 +00002951
Larry Hastings61272b72014-01-07 12:41:53 -08002952/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002953
2954@coexist
2955dict.__contains__
2956
2957 key: object
2958 /
2959
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002960True if the dictionary has the specified key, else False.
Larry Hastings61272b72014-01-07 12:41:53 -08002961[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002962
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002963static PyObject *
Larry Hastingsc2047262014-01-25 20:43:29 -08002964dict___contains__(PyDictObject *self, PyObject *key)
Serhiy Storchaka19d25972017-02-04 08:05:07 +02002965/*[clinic end generated code: output=a3d03db709ed6e6b input=fe1cb42ad831e820]*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002966{
Larry Hastingsc2047262014-01-25 20:43:29 -08002967 register PyDictObject *mp = self;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002968 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07002969 Py_ssize_t ix;
INADA Naokiba609772016-12-07 20:41:42 +09002970 PyObject *value;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002972 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002973 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002974 hash = PyObject_Hash(key);
2975 if (hash == -1)
2976 return NULL;
2977 }
INADA Naoki778928b2017-08-03 23:45:15 +09002978 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07002979 if (ix == DKIX_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002980 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09002981 if (ix == DKIX_EMPTY || value == NULL)
Victor Stinner742da042016-09-07 17:40:12 -07002982 Py_RETURN_FALSE;
2983 Py_RETURN_TRUE;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002984}
2985
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01002986/*[clinic input]
2987dict.get
2988
2989 key: object
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02002990 default: object = None
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01002991 /
2992
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002993Return the value for key if key is in the dictionary, else default.
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01002994[clinic start generated code]*/
2995
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002996static PyObject *
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02002997dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002998/*[clinic end generated code: output=bba707729dee05bf input=279ddb5790b6b107]*/
Barry Warsawc38c5da1997-10-06 17:49:20 +00002999{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003000 PyObject *val = NULL;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003001 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07003002 Py_ssize_t ix;
Barry Warsawc38c5da1997-10-06 17:49:20 +00003003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003004 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003005 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003006 hash = PyObject_Hash(key);
3007 if (hash == -1)
3008 return NULL;
3009 }
INADA Naoki778928b2017-08-03 23:45:15 +09003010 ix = (self->ma_keys->dk_lookup) (self, key, hash, &val);
Victor Stinner742da042016-09-07 17:40:12 -07003011 if (ix == DKIX_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003012 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09003013 if (ix == DKIX_EMPTY || val == NULL) {
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02003014 val = default_value;
INADA Naokiba609772016-12-07 20:41:42 +09003015 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003016 Py_INCREF(val);
3017 return val;
Barry Warsawc38c5da1997-10-06 17:49:20 +00003018}
3019
Benjamin Peterson00e98862013-03-07 22:16:29 -05003020PyObject *
3021PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj)
Guido van Rossum164452c2000-08-08 16:12:54 +00003022{
Benjamin Peterson00e98862013-03-07 22:16:29 -05003023 PyDictObject *mp = (PyDictObject *)d;
INADA Naoki93f26f72016-11-02 18:45:16 +09003024 PyObject *value;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003025 Py_hash_t hash;
Guido van Rossum164452c2000-08-08 16:12:54 +00003026
Benjamin Peterson00e98862013-03-07 22:16:29 -05003027 if (!PyDict_Check(d)) {
3028 PyErr_BadInternalCall();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003029 return NULL;
Benjamin Peterson00e98862013-03-07 22:16:29 -05003030 }
INADA Naoki93f26f72016-11-02 18:45:16 +09003031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003032 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003033 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003034 hash = PyObject_Hash(key);
3035 if (hash == -1)
3036 return NULL;
3037 }
Inada Naoki2ddc7f62019-03-18 20:38:33 +09003038 if (mp->ma_keys == Py_EMPTY_KEYS) {
3039 if (insert_to_emptydict(mp, key, hash, defaultobj) < 0) {
3040 return NULL;
3041 }
3042 return defaultobj;
3043 }
INADA Naoki93f26f72016-11-02 18:45:16 +09003044
3045 if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) {
3046 if (insertion_resize(mp) < 0)
3047 return NULL;
3048 }
3049
INADA Naoki778928b2017-08-03 23:45:15 +09003050 Py_ssize_t ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07003051 if (ix == DKIX_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003052 return NULL;
INADA Naoki93f26f72016-11-02 18:45:16 +09003053
3054 if (_PyDict_HasSplitTable(mp) &&
INADA Naokiba609772016-12-07 20:41:42 +09003055 ((ix >= 0 && value == NULL && mp->ma_used != ix) ||
INADA Naoki93f26f72016-11-02 18:45:16 +09003056 (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) {
3057 if (insertion_resize(mp) < 0) {
3058 return NULL;
3059 }
INADA Naoki93f26f72016-11-02 18:45:16 +09003060 ix = DKIX_EMPTY;
3061 }
3062
3063 if (ix == DKIX_EMPTY) {
3064 PyDictKeyEntry *ep, *ep0;
3065 value = defaultobj;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003066 if (mp->ma_keys->dk_usable <= 0) {
Victor Stinner3c336c52016-09-12 14:17:40 +02003067 if (insertion_resize(mp) < 0) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003068 return NULL;
Victor Stinner3c336c52016-09-12 14:17:40 +02003069 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003070 }
Hristo Venev8557edb2021-04-29 05:06:03 +03003071 if (!PyUnicode_CheckExact(key) && mp->ma_keys->dk_lookup != lookdict) {
3072 mp->ma_keys->dk_lookup = lookdict;
3073 }
INADA Naoki778928b2017-08-03 23:45:15 +09003074 Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash);
INADA Naoki93f26f72016-11-02 18:45:16 +09003075 ep0 = DK_ENTRIES(mp->ma_keys);
3076 ep = &ep0[mp->ma_keys->dk_nentries];
INADA Naokia7576492018-11-14 18:39:27 +09003077 dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
Benjamin Petersonb1efa532013-03-04 09:47:50 -05003078 Py_INCREF(key);
INADA Naoki93f26f72016-11-02 18:45:16 +09003079 Py_INCREF(value);
3080 MAINTAIN_TRACKING(mp, key, value);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003081 ep->me_key = key;
3082 ep->me_hash = hash;
INADA Naokiba609772016-12-07 20:41:42 +09003083 if (_PyDict_HasSplitTable(mp)) {
INADA Naoki93f26f72016-11-02 18:45:16 +09003084 assert(mp->ma_values[mp->ma_keys->dk_nentries] == NULL);
3085 mp->ma_values[mp->ma_keys->dk_nentries] = value;
Victor Stinner742da042016-09-07 17:40:12 -07003086 }
3087 else {
INADA Naoki93f26f72016-11-02 18:45:16 +09003088 ep->me_value = value;
Victor Stinner742da042016-09-07 17:40:12 -07003089 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003090 mp->ma_used++;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07003091 mp->ma_version_tag = DICT_NEXT_VERSION();
INADA Naoki93f26f72016-11-02 18:45:16 +09003092 mp->ma_keys->dk_usable--;
3093 mp->ma_keys->dk_nentries++;
3094 assert(mp->ma_keys->dk_usable >= 0);
3095 }
INADA Naokiba609772016-12-07 20:41:42 +09003096 else if (value == NULL) {
INADA Naoki93f26f72016-11-02 18:45:16 +09003097 value = defaultobj;
3098 assert(_PyDict_HasSplitTable(mp));
3099 assert(ix == mp->ma_used);
3100 Py_INCREF(value);
3101 MAINTAIN_TRACKING(mp, key, value);
INADA Naokiba609772016-12-07 20:41:42 +09003102 mp->ma_values[ix] = value;
INADA Naoki93f26f72016-11-02 18:45:16 +09003103 mp->ma_used++;
3104 mp->ma_version_tag = DICT_NEXT_VERSION();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003105 }
INADA Naoki93f26f72016-11-02 18:45:16 +09003106
Victor Stinner0fc91ee2019-04-12 21:51:34 +02003107 ASSERT_CONSISTENT(mp);
INADA Naoki93f26f72016-11-02 18:45:16 +09003108 return value;
Guido van Rossum164452c2000-08-08 16:12:54 +00003109}
3110
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003111/*[clinic input]
3112dict.setdefault
3113
3114 key: object
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02003115 default: object = None
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003116 /
3117
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02003118Insert key with a value of default if key is not in the dictionary.
3119
3120Return the value for key if key is in the dictionary, else default.
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003121[clinic start generated code]*/
3122
Benjamin Peterson00e98862013-03-07 22:16:29 -05003123static PyObject *
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02003124dict_setdefault_impl(PyDictObject *self, PyObject *key,
3125 PyObject *default_value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02003126/*[clinic end generated code: output=f8c1101ebf69e220 input=0f063756e815fd9d]*/
Benjamin Peterson00e98862013-03-07 22:16:29 -05003127{
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003128 PyObject *val;
Benjamin Peterson00e98862013-03-07 22:16:29 -05003129
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02003130 val = PyDict_SetDefault((PyObject *)self, key, default_value);
Benjamin Peterson00e98862013-03-07 22:16:29 -05003131 Py_XINCREF(val);
3132 return val;
3133}
Guido van Rossum164452c2000-08-08 16:12:54 +00003134
3135static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303136dict_clear(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +00003137{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003138 PyDict_Clear((PyObject *)mp);
3139 Py_RETURN_NONE;
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +00003140}
3141
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003142/*[clinic input]
3143dict.pop
3144
3145 key: object
3146 default: object = NULL
3147 /
3148
Serhiy Storchaka279f4462019-09-14 12:24:05 +03003149D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003150
Serhiy Storchaka6bf323732020-07-19 09:18:55 +03003151If the key is not found, return the default if given; otherwise,
3152raise a KeyError.
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003153[clinic start generated code]*/
3154
Guido van Rossumba6ab842000-12-12 22:02:18 +00003155static PyObject *
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003156dict_pop_impl(PyDictObject *self, PyObject *key, PyObject *default_value)
Serhiy Storchaka6bf323732020-07-19 09:18:55 +03003157/*[clinic end generated code: output=3abb47b89f24c21c input=e221baa01044c44c]*/
Guido van Rossume027d982002-04-12 15:11:59 +00003158{
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003159 return _PyDict_Pop((PyObject*)self, key, default_value);
Guido van Rossume027d982002-04-12 15:11:59 +00003160}
3161
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003162/*[clinic input]
3163dict.popitem
3164
3165Remove and return a (key, value) pair as a 2-tuple.
3166
3167Pairs are returned in LIFO (last-in, first-out) order.
3168Raises KeyError if the dict is empty.
3169[clinic start generated code]*/
3170
Guido van Rossume027d982002-04-12 15:11:59 +00003171static PyObject *
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003172dict_popitem_impl(PyDictObject *self)
3173/*[clinic end generated code: output=e65fcb04420d230d input=1c38a49f21f64941]*/
Guido van Rossumba6ab842000-12-12 22:02:18 +00003174{
Victor Stinner742da042016-09-07 17:40:12 -07003175 Py_ssize_t i, j;
3176 PyDictKeyEntry *ep0, *ep;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003177 PyObject *res;
Guido van Rossumba6ab842000-12-12 22:02:18 +00003178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003179 /* Allocate the result tuple before checking the size. Believe it
3180 * or not, this allocation could trigger a garbage collection which
3181 * could empty the dict, so if we checked the size first and that
3182 * happened, the result would be an infinite loop (searching for an
3183 * entry that no longer exists). Note that the usual popitem()
3184 * idiom is "while d: k, v = d.popitem()". so needing to throw the
3185 * tuple away if the dict *is* empty isn't a significant
3186 * inefficiency -- possible, but unlikely in practice.
3187 */
3188 res = PyTuple_New(2);
3189 if (res == NULL)
3190 return NULL;
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003191 if (self->ma_used == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003192 Py_DECREF(res);
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003193 PyErr_SetString(PyExc_KeyError, "popitem(): dictionary is empty");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003194 return NULL;
3195 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003196 /* Convert split table to combined table */
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003197 if (self->ma_keys->dk_lookup == lookdict_split) {
3198 if (dictresize(self, DK_SIZE(self->ma_keys))) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003199 Py_DECREF(res);
3200 return NULL;
3201 }
3202 }
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003203 ENSURE_ALLOWS_DELETIONS(self);
Victor Stinner742da042016-09-07 17:40:12 -07003204
3205 /* Pop last item */
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003206 ep0 = DK_ENTRIES(self->ma_keys);
3207 i = self->ma_keys->dk_nentries - 1;
Victor Stinner742da042016-09-07 17:40:12 -07003208 while (i >= 0 && ep0[i].me_value == NULL) {
3209 i--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003210 }
Victor Stinner742da042016-09-07 17:40:12 -07003211 assert(i >= 0);
3212
3213 ep = &ep0[i];
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003214 j = lookdict_index(self->ma_keys, ep->me_hash, i);
Victor Stinner742da042016-09-07 17:40:12 -07003215 assert(j >= 0);
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003216 assert(dictkeys_get_index(self->ma_keys, j) == i);
3217 dictkeys_set_index(self->ma_keys, j, DKIX_DUMMY);
Victor Stinner742da042016-09-07 17:40:12 -07003218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003219 PyTuple_SET_ITEM(res, 0, ep->me_key);
3220 PyTuple_SET_ITEM(res, 1, ep->me_value);
Victor Stinner742da042016-09-07 17:40:12 -07003221 ep->me_key = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003222 ep->me_value = NULL;
Victor Stinner742da042016-09-07 17:40:12 -07003223 /* We can't dk_usable++ since there is DKIX_DUMMY in indices */
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003224 self->ma_keys->dk_nentries = i;
3225 self->ma_used--;
3226 self->ma_version_tag = DICT_NEXT_VERSION();
Victor Stinner0fc91ee2019-04-12 21:51:34 +02003227 ASSERT_CONSISTENT(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003228 return res;
Guido van Rossumba6ab842000-12-12 22:02:18 +00003229}
3230
Jeremy Hylton8caad492000-06-23 14:18:11 +00003231static int
3232dict_traverse(PyObject *op, visitproc visit, void *arg)
3233{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003234 PyDictObject *mp = (PyDictObject *)op;
Benjamin Peterson55f44522016-09-05 12:12:59 -07003235 PyDictKeysObject *keys = mp->ma_keys;
Serhiy Storchaka46825d22016-09-26 21:29:34 +03003236 PyDictKeyEntry *entries = DK_ENTRIES(keys);
Victor Stinner742da042016-09-07 17:40:12 -07003237 Py_ssize_t i, n = keys->dk_nentries;
3238
Benjamin Peterson55f44522016-09-05 12:12:59 -07003239 if (keys->dk_lookup == lookdict) {
3240 for (i = 0; i < n; i++) {
3241 if (entries[i].me_value != NULL) {
3242 Py_VISIT(entries[i].me_value);
3243 Py_VISIT(entries[i].me_key);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003244 }
3245 }
Victor Stinner742da042016-09-07 17:40:12 -07003246 }
3247 else {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003248 if (mp->ma_values != NULL) {
Benjamin Peterson55f44522016-09-05 12:12:59 -07003249 for (i = 0; i < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003250 Py_VISIT(mp->ma_values[i]);
3251 }
3252 }
3253 else {
Benjamin Peterson55f44522016-09-05 12:12:59 -07003254 for (i = 0; i < n; i++) {
3255 Py_VISIT(entries[i].me_value);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003256 }
3257 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003258 }
3259 return 0;
Jeremy Hylton8caad492000-06-23 14:18:11 +00003260}
3261
3262static int
3263dict_tp_clear(PyObject *op)
3264{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003265 PyDict_Clear(op);
3266 return 0;
Jeremy Hylton8caad492000-06-23 14:18:11 +00003267}
3268
Guido van Rossum8ce8a782007-11-01 19:42:39 +00003269static PyObject *dictiter_new(PyDictObject *, PyTypeObject *);
Guido van Rossum09e563a2001-05-01 12:10:21 +00003270
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +02003271Py_ssize_t
Eric Snow96c6af92015-05-29 22:21:39 -06003272_PyDict_SizeOf(PyDictObject *mp)
Martin v. Löwis00709aa2008-06-04 14:18:43 +00003273{
Victor Stinner742da042016-09-07 17:40:12 -07003274 Py_ssize_t size, usable, res;
Martin v. Löwis00709aa2008-06-04 14:18:43 +00003275
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003276 size = DK_SIZE(mp->ma_keys);
Victor Stinner742da042016-09-07 17:40:12 -07003277 usable = USABLE_FRACTION(size);
3278
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02003279 res = _PyObject_SIZE(Py_TYPE(mp));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003280 if (mp->ma_values)
Victor Stinner742da042016-09-07 17:40:12 -07003281 res += usable * sizeof(PyObject*);
Martin v. Loewis4f2f3b62012-04-24 19:13:57 +02003282 /* If the dictionary is split, the keys portion is accounted-for
3283 in the type object. */
3284 if (mp->ma_keys->dk_refcnt == 1)
Victor Stinner98ee9d52016-09-08 09:33:56 -07003285 res += (sizeof(PyDictKeysObject)
Victor Stinner98ee9d52016-09-08 09:33:56 -07003286 + DK_IXSIZE(mp->ma_keys) * size
3287 + sizeof(PyDictKeyEntry) * usable);
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +02003288 return res;
Martin v. Loewis4f2f3b62012-04-24 19:13:57 +02003289}
3290
3291Py_ssize_t
3292_PyDict_KeysSize(PyDictKeysObject *keys)
3293{
Victor Stinner98ee9d52016-09-08 09:33:56 -07003294 return (sizeof(PyDictKeysObject)
Victor Stinner98ee9d52016-09-08 09:33:56 -07003295 + DK_IXSIZE(keys) * DK_SIZE(keys)
3296 + USABLE_FRACTION(DK_SIZE(keys)) * sizeof(PyDictKeyEntry));
Martin v. Löwis00709aa2008-06-04 14:18:43 +00003297}
3298
doko@ubuntu.com17210f52016-01-14 14:04:59 +01003299static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303300dict_sizeof(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +02003301{
3302 return PyLong_FromSsize_t(_PyDict_SizeOf(mp));
3303}
3304
Brandt Buchereb8ac572020-02-24 19:47:34 -08003305static PyObject *
3306dict_or(PyObject *self, PyObject *other)
3307{
3308 if (!PyDict_Check(self) || !PyDict_Check(other)) {
3309 Py_RETURN_NOTIMPLEMENTED;
3310 }
3311 PyObject *new = PyDict_Copy(self);
3312 if (new == NULL) {
3313 return NULL;
3314 }
3315 if (dict_update_arg(new, other)) {
3316 Py_DECREF(new);
3317 return NULL;
3318 }
3319 return new;
3320}
3321
3322static PyObject *
3323dict_ior(PyObject *self, PyObject *other)
3324{
3325 if (dict_update_arg(self, other)) {
3326 return NULL;
3327 }
3328 Py_INCREF(self);
3329 return self;
3330}
3331
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00003332PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]");
3333
Martin v. Löwis00709aa2008-06-04 14:18:43 +00003334PyDoc_STRVAR(sizeof__doc__,
3335"D.__sizeof__() -> size of D in memory, in bytes");
3336
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003337PyDoc_STRVAR(update__doc__,
Brett Cannonf2754162013-05-11 14:46:48 -04003338"D.update([E, ]**F) -> None. Update D from dict/iterable E and F.\n\
3339If E is present and has a .keys() method, then does: for k in E: D[k] = E[k]\n\
3340If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v\n\
3341In either case, this is followed by: for k in F: D[k] = F[k]");
Tim Petersf7f88b12000-12-13 23:18:45 +00003342
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003343PyDoc_STRVAR(clear__doc__,
3344"D.clear() -> None. Remove all items from D.");
Tim Petersf7f88b12000-12-13 23:18:45 +00003345
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003346PyDoc_STRVAR(copy__doc__,
3347"D.copy() -> a shallow copy of D");
Tim Petersf7f88b12000-12-13 23:18:45 +00003348
Guido van Rossumb90c8482007-02-10 01:11:45 +00003349/* Forward */
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303350static PyObject *dictkeys_new(PyObject *, PyObject *);
3351static PyObject *dictitems_new(PyObject *, PyObject *);
3352static PyObject *dictvalues_new(PyObject *, PyObject *);
Guido van Rossumb90c8482007-02-10 01:11:45 +00003353
Guido van Rossum45c85d12007-07-27 16:31:40 +00003354PyDoc_STRVAR(keys__doc__,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003355 "D.keys() -> a set-like object providing a view on D's keys");
Guido van Rossum45c85d12007-07-27 16:31:40 +00003356PyDoc_STRVAR(items__doc__,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003357 "D.items() -> a set-like object providing a view on D's items");
Guido van Rossum45c85d12007-07-27 16:31:40 +00003358PyDoc_STRVAR(values__doc__,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003359 "D.values() -> an object providing a view on D's values");
Guido van Rossumb90c8482007-02-10 01:11:45 +00003360
Guido van Rossumc0b618a1997-05-02 03:12:38 +00003361static PyMethodDef mapp_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -07003362 DICT___CONTAINS___METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003363 {"__getitem__", (PyCFunction)(void(*)(void))dict_subscript, METH_O | METH_COEXIST,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003364 getitem__doc__},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003365 {"__sizeof__", (PyCFunction)(void(*)(void))dict_sizeof, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003366 sizeof__doc__},
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003367 DICT_GET_METHODDEF
3368 DICT_SETDEFAULT_METHODDEF
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003369 DICT_POP_METHODDEF
3370 DICT_POPITEM_METHODDEF
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303371 {"keys", dictkeys_new, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003372 keys__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303373 {"items", dictitems_new, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003374 items__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303375 {"values", dictvalues_new, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003376 values__doc__},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003377 {"update", (PyCFunction)(void(*)(void))dict_update, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003378 update__doc__},
Larry Hastings5c661892014-01-24 06:17:25 -08003379 DICT_FROMKEYS_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003380 {"clear", (PyCFunction)dict_clear, METH_NOARGS,
3381 clear__doc__},
3382 {"copy", (PyCFunction)dict_copy, METH_NOARGS,
3383 copy__doc__},
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003384 DICT___REVERSED___METHODDEF
Guido van Rossum48b069a2020-04-07 09:50:06 -07003385 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003386 {NULL, NULL} /* sentinel */
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003387};
3388
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00003389/* Return 1 if `key` is in dict `op`, 0 if not, and -1 on error. */
Raymond Hettingerbc0f2ab2003-11-25 21:12:14 +00003390int
3391PyDict_Contains(PyObject *op, PyObject *key)
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003392{
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003393 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07003394 Py_ssize_t ix;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003395 PyDictObject *mp = (PyDictObject *)op;
INADA Naokiba609772016-12-07 20:41:42 +09003396 PyObject *value;
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003398 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003399 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003400 hash = PyObject_Hash(key);
3401 if (hash == -1)
3402 return -1;
3403 }
INADA Naoki778928b2017-08-03 23:45:15 +09003404 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07003405 if (ix == DKIX_ERROR)
3406 return -1;
INADA Naokiba609772016-12-07 20:41:42 +09003407 return (ix != DKIX_EMPTY && value != NULL);
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003408}
3409
Thomas Wouterscf297e42007-02-23 15:07:44 +00003410/* Internal version of PyDict_Contains used when the hash value is already known */
3411int
Serhiy Storchakafb5db7e2020-10-26 08:43:39 +02003412_PyDict_Contains_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003413{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003414 PyDictObject *mp = (PyDictObject *)op;
INADA Naokiba609772016-12-07 20:41:42 +09003415 PyObject *value;
Victor Stinner742da042016-09-07 17:40:12 -07003416 Py_ssize_t ix;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003417
INADA Naoki778928b2017-08-03 23:45:15 +09003418 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07003419 if (ix == DKIX_ERROR)
3420 return -1;
INADA Naokiba609772016-12-07 20:41:42 +09003421 return (ix != DKIX_EMPTY && value != NULL);
Thomas Wouterscf297e42007-02-23 15:07:44 +00003422}
3423
Serhiy Storchakafb5db7e2020-10-26 08:43:39 +02003424int
3425_PyDict_ContainsId(PyObject *op, struct _Py_Identifier *key)
3426{
3427 PyObject *kv = _PyUnicode_FromId(key); /* borrowed */
3428 if (kv == NULL) {
3429 return -1;
3430 }
3431 return PyDict_Contains(op, kv);
3432}
3433
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003434/* Hack to implement "key in dict" */
3435static PySequenceMethods dict_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003436 0, /* sq_length */
3437 0, /* sq_concat */
3438 0, /* sq_repeat */
3439 0, /* sq_item */
3440 0, /* sq_slice */
3441 0, /* sq_ass_item */
3442 0, /* sq_ass_slice */
3443 PyDict_Contains, /* sq_contains */
3444 0, /* sq_inplace_concat */
3445 0, /* sq_inplace_repeat */
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003446};
3447
Brandt Buchereb8ac572020-02-24 19:47:34 -08003448static PyNumberMethods dict_as_number = {
3449 .nb_or = dict_or,
3450 .nb_inplace_or = dict_ior,
3451};
3452
Guido van Rossum09e563a2001-05-01 12:10:21 +00003453static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +00003454dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3455{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003456 PyObject *self;
Victor Stinnera9f61a52013-07-16 22:17:26 +02003457 PyDictObject *d;
Tim Peters6d6c1a32001-08-02 04:15:00 +00003458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003459 assert(type != NULL && type->tp_alloc != NULL);
3460 self = type->tp_alloc(type, 0);
Victor Stinnera9f61a52013-07-16 22:17:26 +02003461 if (self == NULL)
3462 return NULL;
Victor Stinnera9f61a52013-07-16 22:17:26 +02003463 d = (PyDictObject *)self;
Victor Stinnerac2a4fe2013-07-16 22:19:00 +02003464
Victor Stinnera9f61a52013-07-16 22:17:26 +02003465 /* The object has been implicitly tracked by tp_alloc */
Inada Naokidb6d9a52020-08-04 11:08:06 +09003466 if (type == &PyDict_Type) {
Victor Stinnera9f61a52013-07-16 22:17:26 +02003467 _PyObject_GC_UNTRACK(d);
Inada Naokidb6d9a52020-08-04 11:08:06 +09003468 }
Victor Stinnerac2a4fe2013-07-16 22:19:00 +02003469
3470 d->ma_used = 0;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07003471 d->ma_version_tag = DICT_NEXT_VERSION();
Inada Naokidb6d9a52020-08-04 11:08:06 +09003472 dictkeys_incref(Py_EMPTY_KEYS);
3473 d->ma_keys = Py_EMPTY_KEYS;
3474 d->ma_values = empty_values;
Victor Stinner0fc91ee2019-04-12 21:51:34 +02003475 ASSERT_CONSISTENT(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003476 return self;
Tim Peters6d6c1a32001-08-02 04:15:00 +00003477}
3478
Tim Peters25786c02001-09-02 08:22:48 +00003479static int
3480dict_init(PyObject *self, PyObject *args, PyObject *kwds)
3481{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003482 return dict_update_common(self, args, kwds, "dict");
Tim Peters25786c02001-09-02 08:22:48 +00003483}
3484
Tim Peters6d6c1a32001-08-02 04:15:00 +00003485static PyObject *
Dong-hee Nae27916b2020-04-02 09:55:43 +09003486dict_vectorcall(PyObject *type, PyObject * const*args,
3487 size_t nargsf, PyObject *kwnames)
3488{
3489 assert(PyType_Check(type));
3490 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
3491 if (!_PyArg_CheckPositional("dict", nargs, 0, 1)) {
3492 return NULL;
3493 }
3494
3495 PyObject *self = dict_new((PyTypeObject *)type, NULL, NULL);
3496 if (self == NULL) {
3497 return NULL;
3498 }
3499 if (nargs == 1) {
3500 if (dict_update_arg(self, args[0]) < 0) {
3501 Py_DECREF(self);
3502 return NULL;
3503 }
3504 args++;
3505 }
3506 if (kwnames != NULL) {
3507 for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(kwnames); i++) {
3508 if (PyDict_SetItem(self, PyTuple_GET_ITEM(kwnames, i), args[i]) < 0) {
3509 Py_DECREF(self);
3510 return NULL;
3511 }
3512 }
3513 }
3514 return self;
3515}
3516
3517static PyObject *
Guido van Rossum8ce8a782007-11-01 19:42:39 +00003518dict_iter(PyDictObject *dict)
Guido van Rossum09e563a2001-05-01 12:10:21 +00003519{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003520 return dictiter_new(dict, &PyDictIterKey_Type);
Guido van Rossum09e563a2001-05-01 12:10:21 +00003521}
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003522
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003523PyDoc_STRVAR(dictionary_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00003524"dict() -> new empty dictionary\n"
Tim Petersa427a2b2001-10-29 22:25:45 +00003525"dict(mapping) -> new dictionary initialized from a mapping object's\n"
Ezio Melotti7f807b72010-03-01 04:08:34 +00003526" (key, value) pairs\n"
3527"dict(iterable) -> new dictionary initialized as if via:\n"
Tim Peters4d859532001-10-27 18:27:48 +00003528" d = {}\n"
Ezio Melotti7f807b72010-03-01 04:08:34 +00003529" for k, v in iterable:\n"
Just van Rossuma797d812002-11-23 09:45:04 +00003530" d[k] = v\n"
3531"dict(**kwargs) -> new dictionary initialized with the name=value pairs\n"
3532" in the keyword argument list. For example: dict(one=1, two=2)");
Tim Peters25786c02001-09-02 08:22:48 +00003533
Guido van Rossumc0b618a1997-05-02 03:12:38 +00003534PyTypeObject PyDict_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003535 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3536 "dict",
3537 sizeof(PyDictObject),
3538 0,
3539 (destructor)dict_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003540 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003541 0, /* tp_getattr */
3542 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003543 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003544 (reprfunc)dict_repr, /* tp_repr */
Brandt Buchereb8ac572020-02-24 19:47:34 -08003545 &dict_as_number, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003546 &dict_as_sequence, /* tp_as_sequence */
3547 &dict_as_mapping, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00003548 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003549 0, /* tp_call */
3550 0, /* tp_str */
3551 PyObject_GenericGetAttr, /* tp_getattro */
3552 0, /* tp_setattro */
3553 0, /* tp_as_buffer */
3554 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Brandt Bucher145bf262021-02-26 14:51:55 -08003555 Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DICT_SUBCLASS |
3556 _Py_TPFLAGS_MATCH_SELF, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003557 dictionary_doc, /* tp_doc */
3558 dict_traverse, /* tp_traverse */
3559 dict_tp_clear, /* tp_clear */
3560 dict_richcompare, /* tp_richcompare */
3561 0, /* tp_weaklistoffset */
3562 (getiterfunc)dict_iter, /* tp_iter */
3563 0, /* tp_iternext */
3564 mapp_methods, /* tp_methods */
3565 0, /* tp_members */
3566 0, /* tp_getset */
3567 0, /* tp_base */
3568 0, /* tp_dict */
3569 0, /* tp_descr_get */
3570 0, /* tp_descr_set */
3571 0, /* tp_dictoffset */
3572 dict_init, /* tp_init */
3573 PyType_GenericAlloc, /* tp_alloc */
3574 dict_new, /* tp_new */
3575 PyObject_GC_Del, /* tp_free */
Dong-hee Nae27916b2020-04-02 09:55:43 +09003576 .tp_vectorcall = dict_vectorcall,
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003577};
3578
Guido van Rossum3cca2451997-05-16 14:23:33 +00003579/* For backward compatibility with old dictionary interface */
3580
Guido van Rossumc0b618a1997-05-02 03:12:38 +00003581PyObject *
Martin v. Löwis32b4a1b2002-12-11 13:21:12 +00003582PyDict_GetItemString(PyObject *v, const char *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003583{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003584 PyObject *kv, *rv;
3585 kv = PyUnicode_FromString(key);
Victor Stinnerfdcbab92013-07-16 22:16:05 +02003586 if (kv == NULL) {
3587 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003588 return NULL;
Victor Stinnerfdcbab92013-07-16 22:16:05 +02003589 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003590 rv = PyDict_GetItem(v, kv);
3591 Py_DECREF(kv);
3592 return rv;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003593}
3594
3595int
Victor Stinner3c1e4812012-03-26 22:10:51 +02003596_PyDict_SetItemId(PyObject *v, struct _Py_Identifier *key, PyObject *item)
3597{
3598 PyObject *kv;
3599 kv = _PyUnicode_FromId(key); /* borrowed */
3600 if (kv == NULL)
3601 return -1;
3602 return PyDict_SetItem(v, kv, item);
3603}
3604
3605int
Martin v. Löwis32b4a1b2002-12-11 13:21:12 +00003606PyDict_SetItemString(PyObject *v, const char *key, PyObject *item)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003607{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003608 PyObject *kv;
3609 int err;
3610 kv = PyUnicode_FromString(key);
3611 if (kv == NULL)
3612 return -1;
3613 PyUnicode_InternInPlace(&kv); /* XXX Should we really? */
3614 err = PyDict_SetItem(v, kv, item);
3615 Py_DECREF(kv);
3616 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003617}
3618
3619int
Victor Stinner5fd2e5a2013-11-06 18:58:22 +01003620_PyDict_DelItemId(PyObject *v, _Py_Identifier *key)
3621{
3622 PyObject *kv = _PyUnicode_FromId(key); /* borrowed */
3623 if (kv == NULL)
3624 return -1;
3625 return PyDict_DelItem(v, kv);
3626}
3627
3628int
Martin v. Löwis32b4a1b2002-12-11 13:21:12 +00003629PyDict_DelItemString(PyObject *v, const char *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003630{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003631 PyObject *kv;
3632 int err;
3633 kv = PyUnicode_FromString(key);
3634 if (kv == NULL)
3635 return -1;
3636 err = PyDict_DelItem(v, kv);
3637 Py_DECREF(kv);
3638 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003639}
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003640
Raymond Hettinger019a1482004-03-18 02:41:19 +00003641/* Dictionary iterator types */
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003642
3643typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003644 PyObject_HEAD
3645 PyDictObject *di_dict; /* Set to NULL when iterator is exhausted */
3646 Py_ssize_t di_used;
3647 Py_ssize_t di_pos;
3648 PyObject* di_result; /* reusable result tuple for iteritems */
3649 Py_ssize_t len;
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003650} dictiterobject;
3651
3652static PyObject *
Guido van Rossum8ce8a782007-11-01 19:42:39 +00003653dictiter_new(PyDictObject *dict, PyTypeObject *itertype)
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003654{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003655 dictiterobject *di;
3656 di = PyObject_GC_New(dictiterobject, itertype);
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003657 if (di == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003658 return NULL;
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003659 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003660 Py_INCREF(dict);
3661 di->di_dict = dict;
3662 di->di_used = dict->ma_used;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003663 di->len = dict->ma_used;
Dong-hee Na24dc2f82019-10-20 05:01:08 +09003664 if (itertype == &PyDictRevIterKey_Type ||
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003665 itertype == &PyDictRevIterItem_Type ||
Dong-hee Na24dc2f82019-10-20 05:01:08 +09003666 itertype == &PyDictRevIterValue_Type) {
3667 if (dict->ma_values) {
3668 di->di_pos = dict->ma_used - 1;
3669 }
3670 else {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003671 di->di_pos = dict->ma_keys->dk_nentries - 1;
Dong-hee Na24dc2f82019-10-20 05:01:08 +09003672 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003673 }
3674 else {
3675 di->di_pos = 0;
3676 }
3677 if (itertype == &PyDictIterItem_Type ||
3678 itertype == &PyDictRevIterItem_Type) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003679 di->di_result = PyTuple_Pack(2, Py_None, Py_None);
3680 if (di->di_result == NULL) {
3681 Py_DECREF(di);
3682 return NULL;
3683 }
3684 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003685 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003686 di->di_result = NULL;
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003687 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003688 _PyObject_GC_TRACK(di);
3689 return (PyObject *)di;
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003690}
3691
3692static void
3693dictiter_dealloc(dictiterobject *di)
3694{
INADA Naokia6296d32017-08-24 14:55:17 +09003695 /* bpo-31095: UnTrack is needed before calling any callbacks */
3696 _PyObject_GC_UNTRACK(di);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003697 Py_XDECREF(di->di_dict);
3698 Py_XDECREF(di->di_result);
3699 PyObject_GC_Del(di);
Antoine Pitrou7ddda782009-01-01 15:35:33 +00003700}
3701
3702static int
3703dictiter_traverse(dictiterobject *di, visitproc visit, void *arg)
3704{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003705 Py_VISIT(di->di_dict);
3706 Py_VISIT(di->di_result);
3707 return 0;
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003708}
3709
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00003710static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303711dictiter_len(dictiterobject *di, PyObject *Py_UNUSED(ignored))
Raymond Hettinger0ce6dc82004-03-18 08:38:00 +00003712{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003713 Py_ssize_t len = 0;
3714 if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used)
3715 len = di->len;
3716 return PyLong_FromSize_t(len);
Raymond Hettinger0ce6dc82004-03-18 08:38:00 +00003717}
3718
Guido van Rossumb90c8482007-02-10 01:11:45 +00003719PyDoc_STRVAR(length_hint_doc,
3720 "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00003721
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003722static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303723dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored));
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003724
3725PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
3726
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00003727static PyMethodDef dictiter_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003728 {"__length_hint__", (PyCFunction)(void(*)(void))dictiter_len, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003729 length_hint_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003730 {"__reduce__", (PyCFunction)(void(*)(void))dictiter_reduce, METH_NOARGS,
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003731 reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003732 {NULL, NULL} /* sentinel */
Raymond Hettinger0ce6dc82004-03-18 08:38:00 +00003733};
3734
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003735static PyObject*
3736dictiter_iternextkey(dictiterobject *di)
Guido van Rossum213c7a62001-04-23 14:08:49 +00003737{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003738 PyObject *key;
INADA Naokica2d8be2016-11-04 16:59:10 +09003739 Py_ssize_t i;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02003740 PyDictKeysObject *k;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003741 PyDictObject *d = di->di_dict;
Guido van Rossum213c7a62001-04-23 14:08:49 +00003742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003743 if (d == NULL)
3744 return NULL;
3745 assert (PyDict_Check(d));
Guido van Rossum2147df72002-07-16 20:30:22 +00003746
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003747 if (di->di_used != d->ma_used) {
3748 PyErr_SetString(PyExc_RuntimeError,
3749 "dictionary changed size during iteration");
3750 di->di_used = -1; /* Make this state sticky */
3751 return NULL;
3752 }
Guido van Rossum2147df72002-07-16 20:30:22 +00003753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003754 i = di->di_pos;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003755 k = d->ma_keys;
INADA Naokica2d8be2016-11-04 16:59:10 +09003756 assert(i >= 0);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003757 if (d->ma_values) {
INADA Naokica2d8be2016-11-04 16:59:10 +09003758 if (i >= d->ma_used)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003759 goto fail;
3760 key = DK_ENTRIES(k)[i].me_key;
INADA Naokica2d8be2016-11-04 16:59:10 +09003761 assert(d->ma_values[i] != NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003762 }
3763 else {
INADA Naokica2d8be2016-11-04 16:59:10 +09003764 Py_ssize_t n = k->dk_nentries;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003765 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i];
3766 while (i < n && entry_ptr->me_value == NULL) {
3767 entry_ptr++;
3768 i++;
3769 }
3770 if (i >= n)
3771 goto fail;
3772 key = entry_ptr->me_key;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003773 }
Thomas Perl796cc6e2019-03-28 07:03:25 +01003774 // We found an element (key), but did not expect it
3775 if (di->len == 0) {
3776 PyErr_SetString(PyExc_RuntimeError,
3777 "dictionary keys changed during iteration");
3778 goto fail;
3779 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003780 di->di_pos = i+1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003781 di->len--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003782 Py_INCREF(key);
3783 return key;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003784
3785fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003786 di->di_dict = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +03003787 Py_DECREF(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003788 return NULL;
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003789}
3790
Raymond Hettinger019a1482004-03-18 02:41:19 +00003791PyTypeObject PyDictIterKey_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003792 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3793 "dict_keyiterator", /* tp_name */
3794 sizeof(dictiterobject), /* tp_basicsize */
3795 0, /* tp_itemsize */
3796 /* methods */
3797 (destructor)dictiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003798 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003799 0, /* tp_getattr */
3800 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003801 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003802 0, /* tp_repr */
3803 0, /* tp_as_number */
3804 0, /* tp_as_sequence */
3805 0, /* tp_as_mapping */
3806 0, /* tp_hash */
3807 0, /* tp_call */
3808 0, /* tp_str */
3809 PyObject_GenericGetAttr, /* tp_getattro */
3810 0, /* tp_setattro */
3811 0, /* tp_as_buffer */
3812 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
3813 0, /* tp_doc */
3814 (traverseproc)dictiter_traverse, /* tp_traverse */
3815 0, /* tp_clear */
3816 0, /* tp_richcompare */
3817 0, /* tp_weaklistoffset */
3818 PyObject_SelfIter, /* tp_iter */
3819 (iternextfunc)dictiter_iternextkey, /* tp_iternext */
3820 dictiter_methods, /* tp_methods */
3821 0,
Raymond Hettinger019a1482004-03-18 02:41:19 +00003822};
3823
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003824static PyObject *
3825dictiter_iternextvalue(dictiterobject *di)
Raymond Hettinger019a1482004-03-18 02:41:19 +00003826{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003827 PyObject *value;
INADA Naokica2d8be2016-11-04 16:59:10 +09003828 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003829 PyDictObject *d = di->di_dict;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003831 if (d == NULL)
3832 return NULL;
3833 assert (PyDict_Check(d));
Raymond Hettinger019a1482004-03-18 02:41:19 +00003834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003835 if (di->di_used != d->ma_used) {
3836 PyErr_SetString(PyExc_RuntimeError,
3837 "dictionary changed size during iteration");
3838 di->di_used = -1; /* Make this state sticky */
3839 return NULL;
3840 }
Raymond Hettinger019a1482004-03-18 02:41:19 +00003841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003842 i = di->di_pos;
INADA Naokica2d8be2016-11-04 16:59:10 +09003843 assert(i >= 0);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003844 if (d->ma_values) {
INADA Naokica2d8be2016-11-04 16:59:10 +09003845 if (i >= d->ma_used)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003846 goto fail;
INADA Naokica2d8be2016-11-04 16:59:10 +09003847 value = d->ma_values[i];
3848 assert(value != NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003849 }
3850 else {
INADA Naokica2d8be2016-11-04 16:59:10 +09003851 Py_ssize_t n = d->ma_keys->dk_nentries;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003852 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i];
3853 while (i < n && entry_ptr->me_value == NULL) {
3854 entry_ptr++;
3855 i++;
3856 }
3857 if (i >= n)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003858 goto fail;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003859 value = entry_ptr->me_value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003860 }
Thomas Perlb8311cf2019-04-02 11:30:10 +02003861 // We found an element, but did not expect it
3862 if (di->len == 0) {
3863 PyErr_SetString(PyExc_RuntimeError,
3864 "dictionary keys changed during iteration");
3865 goto fail;
3866 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003867 di->di_pos = i+1;
3868 di->len--;
3869 Py_INCREF(value);
3870 return value;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003871
3872fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003873 di->di_dict = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +03003874 Py_DECREF(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003875 return NULL;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003876}
3877
3878PyTypeObject PyDictIterValue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003879 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3880 "dict_valueiterator", /* tp_name */
3881 sizeof(dictiterobject), /* tp_basicsize */
3882 0, /* tp_itemsize */
3883 /* methods */
3884 (destructor)dictiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003885 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003886 0, /* tp_getattr */
3887 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003888 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003889 0, /* tp_repr */
3890 0, /* tp_as_number */
3891 0, /* tp_as_sequence */
3892 0, /* tp_as_mapping */
3893 0, /* tp_hash */
3894 0, /* tp_call */
3895 0, /* tp_str */
3896 PyObject_GenericGetAttr, /* tp_getattro */
3897 0, /* tp_setattro */
3898 0, /* tp_as_buffer */
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003899 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003900 0, /* tp_doc */
3901 (traverseproc)dictiter_traverse, /* tp_traverse */
3902 0, /* tp_clear */
3903 0, /* tp_richcompare */
3904 0, /* tp_weaklistoffset */
3905 PyObject_SelfIter, /* tp_iter */
3906 (iternextfunc)dictiter_iternextvalue, /* tp_iternext */
3907 dictiter_methods, /* tp_methods */
3908 0,
Raymond Hettinger019a1482004-03-18 02:41:19 +00003909};
3910
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003911static PyObject *
3912dictiter_iternextitem(dictiterobject *di)
Raymond Hettinger019a1482004-03-18 02:41:19 +00003913{
Serhiy Storchaka753bca32017-05-20 12:30:02 +03003914 PyObject *key, *value, *result;
INADA Naokica2d8be2016-11-04 16:59:10 +09003915 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003916 PyDictObject *d = di->di_dict;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003917
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003918 if (d == NULL)
3919 return NULL;
3920 assert (PyDict_Check(d));
Raymond Hettinger019a1482004-03-18 02:41:19 +00003921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003922 if (di->di_used != d->ma_used) {
3923 PyErr_SetString(PyExc_RuntimeError,
3924 "dictionary changed size during iteration");
3925 di->di_used = -1; /* Make this state sticky */
3926 return NULL;
3927 }
Raymond Hettinger019a1482004-03-18 02:41:19 +00003928
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003929 i = di->di_pos;
INADA Naokica2d8be2016-11-04 16:59:10 +09003930 assert(i >= 0);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003931 if (d->ma_values) {
INADA Naokica2d8be2016-11-04 16:59:10 +09003932 if (i >= d->ma_used)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003933 goto fail;
3934 key = DK_ENTRIES(d->ma_keys)[i].me_key;
INADA Naokica2d8be2016-11-04 16:59:10 +09003935 value = d->ma_values[i];
3936 assert(value != NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003937 }
3938 else {
INADA Naokica2d8be2016-11-04 16:59:10 +09003939 Py_ssize_t n = d->ma_keys->dk_nentries;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003940 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i];
3941 while (i < n && entry_ptr->me_value == NULL) {
3942 entry_ptr++;
3943 i++;
3944 }
3945 if (i >= n)
3946 goto fail;
3947 key = entry_ptr->me_key;
3948 value = entry_ptr->me_value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003949 }
Thomas Perlb8311cf2019-04-02 11:30:10 +02003950 // We found an element, but did not expect it
3951 if (di->len == 0) {
3952 PyErr_SetString(PyExc_RuntimeError,
3953 "dictionary keys changed during iteration");
3954 goto fail;
3955 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003956 di->di_pos = i+1;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003957 di->len--;
Serhiy Storchaka753bca32017-05-20 12:30:02 +03003958 Py_INCREF(key);
3959 Py_INCREF(value);
3960 result = di->di_result;
3961 if (Py_REFCNT(result) == 1) {
3962 PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
3963 PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
3964 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
3965 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003966 Py_INCREF(result);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03003967 Py_DECREF(oldkey);
3968 Py_DECREF(oldvalue);
Brandt Bucher226a0122020-12-04 19:45:57 -08003969 // bpo-42536: The GC may have untracked this result tuple. Since we're
3970 // recycling it, make sure it's tracked again:
3971 if (!_PyObject_GC_IS_TRACKED(result)) {
3972 _PyObject_GC_TRACK(result);
3973 }
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003974 }
3975 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003976 result = PyTuple_New(2);
3977 if (result == NULL)
3978 return NULL;
Serhiy Storchaka753bca32017-05-20 12:30:02 +03003979 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
3980 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003981 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003982 return result;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003983
3984fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003985 di->di_dict = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +03003986 Py_DECREF(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003987 return NULL;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003988}
3989
3990PyTypeObject PyDictIterItem_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003991 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3992 "dict_itemiterator", /* tp_name */
3993 sizeof(dictiterobject), /* tp_basicsize */
3994 0, /* tp_itemsize */
3995 /* methods */
3996 (destructor)dictiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003997 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003998 0, /* tp_getattr */
3999 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004000 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004001 0, /* tp_repr */
4002 0, /* tp_as_number */
4003 0, /* tp_as_sequence */
4004 0, /* tp_as_mapping */
4005 0, /* tp_hash */
4006 0, /* tp_call */
4007 0, /* tp_str */
4008 PyObject_GenericGetAttr, /* tp_getattro */
4009 0, /* tp_setattro */
4010 0, /* tp_as_buffer */
4011 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
4012 0, /* tp_doc */
4013 (traverseproc)dictiter_traverse, /* tp_traverse */
4014 0, /* tp_clear */
4015 0, /* tp_richcompare */
4016 0, /* tp_weaklistoffset */
4017 PyObject_SelfIter, /* tp_iter */
4018 (iternextfunc)dictiter_iternextitem, /* tp_iternext */
4019 dictiter_methods, /* tp_methods */
4020 0,
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00004021};
Guido van Rossumb90c8482007-02-10 01:11:45 +00004022
4023
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004024/* dictreviter */
4025
4026static PyObject *
4027dictreviter_iternext(dictiterobject *di)
4028{
4029 PyDictObject *d = di->di_dict;
4030
4031 if (d == NULL) {
4032 return NULL;
4033 }
4034 assert (PyDict_Check(d));
4035
4036 if (di->di_used != d->ma_used) {
4037 PyErr_SetString(PyExc_RuntimeError,
4038 "dictionary changed size during iteration");
4039 di->di_used = -1; /* Make this state sticky */
4040 return NULL;
4041 }
4042
4043 Py_ssize_t i = di->di_pos;
4044 PyDictKeysObject *k = d->ma_keys;
4045 PyObject *key, *value, *result;
4046
Serhiy Storchaka2e3d8732019-10-23 14:48:08 +03004047 if (i < 0) {
4048 goto fail;
4049 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004050 if (d->ma_values) {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004051 key = DK_ENTRIES(k)[i].me_key;
4052 value = d->ma_values[i];
4053 assert (value != NULL);
4054 }
4055 else {
4056 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i];
Serhiy Storchaka2e3d8732019-10-23 14:48:08 +03004057 while (entry_ptr->me_value == NULL) {
4058 if (--i < 0) {
4059 goto fail;
4060 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004061 entry_ptr--;
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004062 }
4063 key = entry_ptr->me_key;
4064 value = entry_ptr->me_value;
4065 }
4066 di->di_pos = i-1;
4067 di->len--;
4068
Dong-hee Na1b55b652020-02-17 19:09:15 +09004069 if (Py_IS_TYPE(di, &PyDictRevIterKey_Type)) {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004070 Py_INCREF(key);
4071 return key;
4072 }
Dong-hee Na1b55b652020-02-17 19:09:15 +09004073 else if (Py_IS_TYPE(di, &PyDictRevIterValue_Type)) {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004074 Py_INCREF(value);
4075 return value;
4076 }
Dong-hee Na1b55b652020-02-17 19:09:15 +09004077 else if (Py_IS_TYPE(di, &PyDictRevIterItem_Type)) {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004078 Py_INCREF(key);
4079 Py_INCREF(value);
4080 result = di->di_result;
4081 if (Py_REFCNT(result) == 1) {
4082 PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
4083 PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
4084 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
4085 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
4086 Py_INCREF(result);
4087 Py_DECREF(oldkey);
4088 Py_DECREF(oldvalue);
Brandt Bucher226a0122020-12-04 19:45:57 -08004089 // bpo-42536: The GC may have untracked this result tuple. Since
4090 // we're recycling it, make sure it's tracked again:
4091 if (!_PyObject_GC_IS_TRACKED(result)) {
4092 _PyObject_GC_TRACK(result);
4093 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004094 }
4095 else {
4096 result = PyTuple_New(2);
4097 if (result == NULL) {
4098 return NULL;
4099 }
4100 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
4101 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
4102 }
4103 return result;
4104 }
4105 else {
4106 Py_UNREACHABLE();
4107 }
4108
4109fail:
4110 di->di_dict = NULL;
4111 Py_DECREF(d);
4112 return NULL;
4113}
4114
4115PyTypeObject PyDictRevIterKey_Type = {
4116 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4117 "dict_reversekeyiterator",
4118 sizeof(dictiterobject),
4119 .tp_dealloc = (destructor)dictiter_dealloc,
4120 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
4121 .tp_traverse = (traverseproc)dictiter_traverse,
4122 .tp_iter = PyObject_SelfIter,
4123 .tp_iternext = (iternextfunc)dictreviter_iternext,
4124 .tp_methods = dictiter_methods
4125};
4126
4127
4128/*[clinic input]
4129dict.__reversed__
4130
4131Return a reverse iterator over the dict keys.
4132[clinic start generated code]*/
4133
4134static PyObject *
4135dict___reversed___impl(PyDictObject *self)
4136/*[clinic end generated code: output=e674483336d1ed51 input=23210ef3477d8c4d]*/
4137{
4138 assert (PyDict_Check(self));
4139 return dictiter_new(self, &PyDictRevIterKey_Type);
4140}
4141
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004142static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304143dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004144{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02004145 _Py_IDENTIFIER(iter);
Sergey Fedoseev63958442018-10-20 05:43:33 +05004146 /* copy the iterator state */
4147 dictiterobject tmp = *di;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004148 Py_XINCREF(tmp.di_dict);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004149
Sergey Fedoseev63958442018-10-20 05:43:33 +05004150 PyObject *list = PySequence_List((PyObject*)&tmp);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004151 Py_XDECREF(tmp.di_dict);
Sergey Fedoseev63958442018-10-20 05:43:33 +05004152 if (list == NULL) {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004153 return NULL;
4154 }
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02004155 return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004156}
4157
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004158PyTypeObject PyDictRevIterItem_Type = {
4159 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4160 "dict_reverseitemiterator",
4161 sizeof(dictiterobject),
4162 .tp_dealloc = (destructor)dictiter_dealloc,
4163 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
4164 .tp_traverse = (traverseproc)dictiter_traverse,
4165 .tp_iter = PyObject_SelfIter,
4166 .tp_iternext = (iternextfunc)dictreviter_iternext,
4167 .tp_methods = dictiter_methods
4168};
4169
4170PyTypeObject PyDictRevIterValue_Type = {
4171 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4172 "dict_reversevalueiterator",
4173 sizeof(dictiterobject),
4174 .tp_dealloc = (destructor)dictiter_dealloc,
4175 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
4176 .tp_traverse = (traverseproc)dictiter_traverse,
4177 .tp_iter = PyObject_SelfIter,
4178 .tp_iternext = (iternextfunc)dictreviter_iternext,
4179 .tp_methods = dictiter_methods
4180};
4181
Guido van Rossum3ac67412007-02-10 18:55:06 +00004182/***********************************************/
Guido van Rossumb90c8482007-02-10 01:11:45 +00004183/* View objects for keys(), items(), values(). */
Guido van Rossum3ac67412007-02-10 18:55:06 +00004184/***********************************************/
4185
Guido van Rossumb90c8482007-02-10 01:11:45 +00004186/* The instance lay-out is the same for all three; but the type differs. */
4187
Guido van Rossumb90c8482007-02-10 01:11:45 +00004188static void
Eric Snow96c6af92015-05-29 22:21:39 -06004189dictview_dealloc(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004190{
INADA Naokia6296d32017-08-24 14:55:17 +09004191 /* bpo-31095: UnTrack is needed before calling any callbacks */
4192 _PyObject_GC_UNTRACK(dv);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004193 Py_XDECREF(dv->dv_dict);
4194 PyObject_GC_Del(dv);
Antoine Pitrou7ddda782009-01-01 15:35:33 +00004195}
4196
4197static int
Eric Snow96c6af92015-05-29 22:21:39 -06004198dictview_traverse(_PyDictViewObject *dv, visitproc visit, void *arg)
Antoine Pitrou7ddda782009-01-01 15:35:33 +00004199{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004200 Py_VISIT(dv->dv_dict);
4201 return 0;
Guido van Rossumb90c8482007-02-10 01:11:45 +00004202}
4203
Guido van Rossum83825ac2007-02-10 04:54:19 +00004204static Py_ssize_t
Eric Snow96c6af92015-05-29 22:21:39 -06004205dictview_len(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004207 Py_ssize_t len = 0;
4208 if (dv->dv_dict != NULL)
4209 len = dv->dv_dict->ma_used;
4210 return len;
Guido van Rossumb90c8482007-02-10 01:11:45 +00004211}
4212
Eric Snow96c6af92015-05-29 22:21:39 -06004213PyObject *
4214_PyDictView_New(PyObject *dict, PyTypeObject *type)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004215{
Eric Snow96c6af92015-05-29 22:21:39 -06004216 _PyDictViewObject *dv;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004217 if (dict == NULL) {
4218 PyErr_BadInternalCall();
4219 return NULL;
4220 }
4221 if (!PyDict_Check(dict)) {
4222 /* XXX Get rid of this restriction later */
4223 PyErr_Format(PyExc_TypeError,
4224 "%s() requires a dict argument, not '%s'",
Victor Stinner58ac7002020-02-07 03:04:21 +01004225 type->tp_name, Py_TYPE(dict)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004226 return NULL;
4227 }
Eric Snow96c6af92015-05-29 22:21:39 -06004228 dv = PyObject_GC_New(_PyDictViewObject, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004229 if (dv == NULL)
4230 return NULL;
4231 Py_INCREF(dict);
4232 dv->dv_dict = (PyDictObject *)dict;
4233 _PyObject_GC_TRACK(dv);
4234 return (PyObject *)dv;
Guido van Rossumb90c8482007-02-10 01:11:45 +00004235}
4236
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004237static PyObject *
Pablo Galindo10c3b212020-06-15 02:05:20 +01004238dictview_mapping(PyObject *view, void *Py_UNUSED(ignored)) {
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004239 assert(view != NULL);
4240 assert(PyDictKeys_Check(view)
4241 || PyDictValues_Check(view)
4242 || PyDictItems_Check(view));
4243 PyObject *mapping = (PyObject *)((_PyDictViewObject *)view)->dv_dict;
4244 return PyDictProxy_New(mapping);
4245}
4246
4247static PyGetSetDef dictview_getset[] = {
Pablo Galindo10c3b212020-06-15 02:05:20 +01004248 {"mapping", dictview_mapping, (setter)NULL,
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004249 "dictionary that this view refers to", NULL},
4250 {0}
4251};
4252
Neal Norwitze36f2ba2007-02-26 23:12:28 +00004253/* TODO(guido): The views objects are not complete:
4254
4255 * support more set operations
4256 * support arbitrary mappings?
4257 - either these should be static or exported in dictobject.h
4258 - if public then they should probably be in builtins
4259*/
4260
Guido van Rossumaac530c2007-08-24 22:33:45 +00004261/* Return 1 if self is a subset of other, iterating over self;
4262 0 if not; -1 if an error occurred. */
Guido van Rossumd9214d12007-02-12 02:23:40 +00004263static int
4264all_contained_in(PyObject *self, PyObject *other)
4265{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004266 PyObject *iter = PyObject_GetIter(self);
4267 int ok = 1;
Guido van Rossumd9214d12007-02-12 02:23:40 +00004268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004269 if (iter == NULL)
4270 return -1;
4271 for (;;) {
4272 PyObject *next = PyIter_Next(iter);
4273 if (next == NULL) {
4274 if (PyErr_Occurred())
4275 ok = -1;
4276 break;
4277 }
4278 ok = PySequence_Contains(other, next);
4279 Py_DECREF(next);
4280 if (ok <= 0)
4281 break;
4282 }
4283 Py_DECREF(iter);
4284 return ok;
Guido van Rossumd9214d12007-02-12 02:23:40 +00004285}
4286
4287static PyObject *
4288dictview_richcompare(PyObject *self, PyObject *other, int op)
4289{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004290 Py_ssize_t len_self, len_other;
4291 int ok;
4292 PyObject *result;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004294 assert(self != NULL);
4295 assert(PyDictViewSet_Check(self));
4296 assert(other != NULL);
Guido van Rossumd9214d12007-02-12 02:23:40 +00004297
Brian Curtindfc80e32011-08-10 20:28:54 -05004298 if (!PyAnySet_Check(other) && !PyDictViewSet_Check(other))
4299 Py_RETURN_NOTIMPLEMENTED;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004301 len_self = PyObject_Size(self);
4302 if (len_self < 0)
4303 return NULL;
4304 len_other = PyObject_Size(other);
4305 if (len_other < 0)
4306 return NULL;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004308 ok = 0;
4309 switch(op) {
Guido van Rossumaac530c2007-08-24 22:33:45 +00004310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004311 case Py_NE:
4312 case Py_EQ:
4313 if (len_self == len_other)
4314 ok = all_contained_in(self, other);
4315 if (op == Py_NE && ok >= 0)
4316 ok = !ok;
4317 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004319 case Py_LT:
4320 if (len_self < len_other)
4321 ok = all_contained_in(self, other);
4322 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004324 case Py_LE:
4325 if (len_self <= len_other)
4326 ok = all_contained_in(self, other);
4327 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004329 case Py_GT:
4330 if (len_self > len_other)
4331 ok = all_contained_in(other, self);
4332 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004334 case Py_GE:
4335 if (len_self >= len_other)
4336 ok = all_contained_in(other, self);
4337 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004339 }
4340 if (ok < 0)
4341 return NULL;
4342 result = ok ? Py_True : Py_False;
4343 Py_INCREF(result);
4344 return result;
Guido van Rossumd9214d12007-02-12 02:23:40 +00004345}
4346
Raymond Hettingerb0d56af2009-03-03 10:52:49 +00004347static PyObject *
Eric Snow96c6af92015-05-29 22:21:39 -06004348dictview_repr(_PyDictViewObject *dv)
Raymond Hettingerb0d56af2009-03-03 10:52:49 +00004349{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004350 PyObject *seq;
bennorthd7773d92018-01-26 15:46:01 +00004351 PyObject *result = NULL;
4352 Py_ssize_t rc;
Raymond Hettingerb0d56af2009-03-03 10:52:49 +00004353
bennorthd7773d92018-01-26 15:46:01 +00004354 rc = Py_ReprEnter((PyObject *)dv);
4355 if (rc != 0) {
4356 return rc > 0 ? PyUnicode_FromString("...") : NULL;
4357 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004358 seq = PySequence_List((PyObject *)dv);
bennorthd7773d92018-01-26 15:46:01 +00004359 if (seq == NULL) {
4360 goto Done;
4361 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004362 result = PyUnicode_FromFormat("%s(%R)", Py_TYPE(dv)->tp_name, seq);
4363 Py_DECREF(seq);
bennorthd7773d92018-01-26 15:46:01 +00004364
4365Done:
4366 Py_ReprLeave((PyObject *)dv);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004367 return result;
Raymond Hettingerb0d56af2009-03-03 10:52:49 +00004368}
4369
Guido van Rossum3ac67412007-02-10 18:55:06 +00004370/*** dict_keys ***/
Guido van Rossumb90c8482007-02-10 01:11:45 +00004371
4372static PyObject *
Eric Snow96c6af92015-05-29 22:21:39 -06004373dictkeys_iter(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004375 if (dv->dv_dict == NULL) {
4376 Py_RETURN_NONE;
4377 }
4378 return dictiter_new(dv->dv_dict, &PyDictIterKey_Type);
Guido van Rossum3ac67412007-02-10 18:55:06 +00004379}
4380
4381static int
Eric Snow96c6af92015-05-29 22:21:39 -06004382dictkeys_contains(_PyDictViewObject *dv, PyObject *obj)
Guido van Rossum3ac67412007-02-10 18:55:06 +00004383{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004384 if (dv->dv_dict == NULL)
4385 return 0;
4386 return PyDict_Contains((PyObject *)dv->dv_dict, obj);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004387}
4388
Guido van Rossum83825ac2007-02-10 04:54:19 +00004389static PySequenceMethods dictkeys_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004390 (lenfunc)dictview_len, /* sq_length */
4391 0, /* sq_concat */
4392 0, /* sq_repeat */
4393 0, /* sq_item */
4394 0, /* sq_slice */
4395 0, /* sq_ass_item */
4396 0, /* sq_ass_slice */
4397 (objobjproc)dictkeys_contains, /* sq_contains */
Guido van Rossum83825ac2007-02-10 04:54:19 +00004398};
4399
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004400// Create an set object from dictviews object.
4401// Returns a new reference.
4402// This utility function is used by set operations.
Guido van Rossum523259b2007-08-24 23:41:22 +00004403static PyObject*
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004404dictviews_to_set(PyObject *self)
Guido van Rossum523259b2007-08-24 23:41:22 +00004405{
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004406 PyObject *left = self;
4407 if (PyDictKeys_Check(self)) {
4408 // PySet_New() has fast path for the dict object.
4409 PyObject *dict = (PyObject *)((_PyDictViewObject *)self)->dv_dict;
4410 if (PyDict_CheckExact(dict)) {
4411 left = dict;
4412 }
4413 }
4414 return PySet_New(left);
4415}
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004416
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004417static PyObject*
4418dictviews_sub(PyObject *self, PyObject *other)
4419{
4420 PyObject *result = dictviews_to_set(self);
4421 if (result == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004422 return NULL;
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004423 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004424
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004425 _Py_IDENTIFIER(difference_update);
4426 PyObject *tmp = _PyObject_CallMethodIdOneArg(
4427 result, &PyId_difference_update, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004428 if (tmp == NULL) {
4429 Py_DECREF(result);
4430 return NULL;
4431 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004433 Py_DECREF(tmp);
4434 return result;
Guido van Rossum523259b2007-08-24 23:41:22 +00004435}
4436
Forest Gregg998cf1f2019-08-26 02:17:43 -05004437static int
4438dictitems_contains(_PyDictViewObject *dv, PyObject *obj);
4439
4440PyObject *
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04004441_PyDictView_Intersect(PyObject* self, PyObject *other)
Guido van Rossum523259b2007-08-24 23:41:22 +00004442{
Forest Gregg998cf1f2019-08-26 02:17:43 -05004443 PyObject *result;
4444 PyObject *it;
4445 PyObject *key;
4446 Py_ssize_t len_self;
4447 int rv;
4448 int (*dict_contains)(_PyDictViewObject *, PyObject *);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004449
Forest Gregg998cf1f2019-08-26 02:17:43 -05004450 /* Python interpreter swaps parameters when dict view
4451 is on right side of & */
4452 if (!PyDictViewSet_Check(self)) {
4453 PyObject *tmp = other;
4454 other = self;
4455 self = tmp;
4456 }
4457
4458 len_self = dictview_len((_PyDictViewObject *)self);
4459
4460 /* if other is a set and self is smaller than other,
4461 reuse set intersection logic */
Pablo Galindod439fb32021-02-20 18:03:08 +00004462 if (PySet_CheckExact(other) && len_self <= PyObject_Size(other)) {
Forest Gregg998cf1f2019-08-26 02:17:43 -05004463 _Py_IDENTIFIER(intersection);
4464 return _PyObject_CallMethodIdObjArgs(other, &PyId_intersection, self, NULL);
4465 }
4466
4467 /* if other is another dict view, and it is bigger than self,
4468 swap them */
4469 if (PyDictViewSet_Check(other)) {
4470 Py_ssize_t len_other = dictview_len((_PyDictViewObject *)other);
4471 if (len_other > len_self) {
4472 PyObject *tmp = other;
4473 other = self;
4474 self = tmp;
4475 }
4476 }
4477
4478 /* at this point, two things should be true
4479 1. self is a dictview
4480 2. if other is a dictview then it is smaller than self */
4481 result = PySet_New(NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004482 if (result == NULL)
4483 return NULL;
Guido van Rossum523259b2007-08-24 23:41:22 +00004484
Forest Gregg998cf1f2019-08-26 02:17:43 -05004485 it = PyObject_GetIter(other);
Zackery Spytzb16e3822019-10-13 05:49:05 -06004486 if (it == NULL) {
4487 Py_DECREF(result);
4488 return NULL;
4489 }
Forest Gregg998cf1f2019-08-26 02:17:43 -05004490
Forest Gregg998cf1f2019-08-26 02:17:43 -05004491 if (PyDictKeys_Check(self)) {
4492 dict_contains = dictkeys_contains;
4493 }
4494 /* else PyDictItems_Check(self) */
4495 else {
4496 dict_contains = dictitems_contains;
4497 }
4498
4499 while ((key = PyIter_Next(it)) != NULL) {
4500 rv = dict_contains((_PyDictViewObject *)self, key);
4501 if (rv < 0) {
4502 goto error;
4503 }
4504 if (rv) {
4505 if (PySet_Add(result, key)) {
4506 goto error;
4507 }
4508 }
4509 Py_DECREF(key);
4510 }
4511 Py_DECREF(it);
4512 if (PyErr_Occurred()) {
4513 Py_DECREF(result);
4514 return NULL;
4515 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004516 return result;
Forest Gregg998cf1f2019-08-26 02:17:43 -05004517
4518error:
4519 Py_DECREF(it);
4520 Py_DECREF(result);
4521 Py_DECREF(key);
4522 return NULL;
Guido van Rossum523259b2007-08-24 23:41:22 +00004523}
4524
4525static PyObject*
4526dictviews_or(PyObject* self, PyObject *other)
4527{
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004528 PyObject *result = dictviews_to_set(self);
4529 if (result == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004530 return NULL;
4531 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004532
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004533 if (_PySet_Update(result, other) < 0) {
4534 Py_DECREF(result);
4535 return NULL;
4536 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004537 return result;
Guido van Rossum523259b2007-08-24 23:41:22 +00004538}
4539
Dennis Sweeney07d81122020-06-10 01:56:56 -04004540static PyObject *
4541dictitems_xor(PyObject *self, PyObject *other)
4542{
4543 assert(PyDictItems_Check(self));
4544 assert(PyDictItems_Check(other));
4545 PyObject *d1 = (PyObject *)((_PyDictViewObject *)self)->dv_dict;
4546 PyObject *d2 = (PyObject *)((_PyDictViewObject *)other)->dv_dict;
4547
4548 PyObject *temp_dict = PyDict_Copy(d1);
4549 if (temp_dict == NULL) {
4550 return NULL;
4551 }
4552 PyObject *result_set = PySet_New(NULL);
4553 if (result_set == NULL) {
4554 Py_CLEAR(temp_dict);
4555 return NULL;
4556 }
4557
4558 PyObject *key = NULL, *val1 = NULL, *val2 = NULL;
4559 Py_ssize_t pos = 0;
4560 Py_hash_t hash;
4561
4562 while (_PyDict_Next(d2, &pos, &key, &val2, &hash)) {
4563 Py_INCREF(key);
4564 Py_INCREF(val2);
4565 val1 = _PyDict_GetItem_KnownHash(temp_dict, key, hash);
4566
4567 int to_delete;
4568 if (val1 == NULL) {
4569 if (PyErr_Occurred()) {
4570 goto error;
4571 }
4572 to_delete = 0;
4573 }
4574 else {
4575 Py_INCREF(val1);
4576 to_delete = PyObject_RichCompareBool(val1, val2, Py_EQ);
4577 if (to_delete < 0) {
4578 goto error;
4579 }
4580 }
4581
4582 if (to_delete) {
4583 if (_PyDict_DelItem_KnownHash(temp_dict, key, hash) < 0) {
4584 goto error;
4585 }
4586 }
4587 else {
4588 PyObject *pair = PyTuple_Pack(2, key, val2);
4589 if (pair == NULL) {
4590 goto error;
4591 }
4592 if (PySet_Add(result_set, pair) < 0) {
4593 Py_DECREF(pair);
4594 goto error;
4595 }
4596 Py_DECREF(pair);
4597 }
4598 Py_DECREF(key);
4599 Py_XDECREF(val1);
4600 Py_DECREF(val2);
4601 }
4602 key = val1 = val2 = NULL;
4603
4604 _Py_IDENTIFIER(items);
4605 PyObject *remaining_pairs = _PyObject_CallMethodIdNoArgs(temp_dict,
4606 &PyId_items);
4607 if (remaining_pairs == NULL) {
4608 goto error;
4609 }
4610 if (_PySet_Update(result_set, remaining_pairs) < 0) {
4611 Py_DECREF(remaining_pairs);
4612 goto error;
4613 }
4614 Py_DECREF(temp_dict);
4615 Py_DECREF(remaining_pairs);
4616 return result_set;
4617
4618error:
4619 Py_XDECREF(temp_dict);
4620 Py_XDECREF(result_set);
4621 Py_XDECREF(key);
4622 Py_XDECREF(val1);
4623 Py_XDECREF(val2);
4624 return NULL;
4625}
4626
Guido van Rossum523259b2007-08-24 23:41:22 +00004627static PyObject*
4628dictviews_xor(PyObject* self, PyObject *other)
4629{
Dennis Sweeney07d81122020-06-10 01:56:56 -04004630 if (PyDictItems_Check(self) && PyDictItems_Check(other)) {
4631 return dictitems_xor(self, other);
4632 }
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004633 PyObject *result = dictviews_to_set(self);
4634 if (result == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004635 return NULL;
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004636 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004637
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004638 _Py_IDENTIFIER(symmetric_difference_update);
4639 PyObject *tmp = _PyObject_CallMethodIdOneArg(
4640 result, &PyId_symmetric_difference_update, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004641 if (tmp == NULL) {
4642 Py_DECREF(result);
4643 return NULL;
4644 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004645
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004646 Py_DECREF(tmp);
4647 return result;
Guido van Rossum523259b2007-08-24 23:41:22 +00004648}
4649
4650static PyNumberMethods dictviews_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004651 0, /*nb_add*/
4652 (binaryfunc)dictviews_sub, /*nb_subtract*/
4653 0, /*nb_multiply*/
4654 0, /*nb_remainder*/
4655 0, /*nb_divmod*/
4656 0, /*nb_power*/
4657 0, /*nb_negative*/
4658 0, /*nb_positive*/
4659 0, /*nb_absolute*/
4660 0, /*nb_bool*/
4661 0, /*nb_invert*/
4662 0, /*nb_lshift*/
4663 0, /*nb_rshift*/
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04004664 (binaryfunc)_PyDictView_Intersect, /*nb_and*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004665 (binaryfunc)dictviews_xor, /*nb_xor*/
4666 (binaryfunc)dictviews_or, /*nb_or*/
Guido van Rossum523259b2007-08-24 23:41:22 +00004667};
4668
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004669static PyObject*
4670dictviews_isdisjoint(PyObject *self, PyObject *other)
4671{
4672 PyObject *it;
4673 PyObject *item = NULL;
4674
4675 if (self == other) {
Eric Snow96c6af92015-05-29 22:21:39 -06004676 if (dictview_len((_PyDictViewObject *)self) == 0)
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004677 Py_RETURN_TRUE;
4678 else
4679 Py_RETURN_FALSE;
4680 }
4681
4682 /* Iterate over the shorter object (only if other is a set,
4683 * because PySequence_Contains may be expensive otherwise): */
4684 if (PyAnySet_Check(other) || PyDictViewSet_Check(other)) {
Eric Snow96c6af92015-05-29 22:21:39 -06004685 Py_ssize_t len_self = dictview_len((_PyDictViewObject *)self);
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004686 Py_ssize_t len_other = PyObject_Size(other);
4687 if (len_other == -1)
4688 return NULL;
4689
4690 if ((len_other > len_self)) {
4691 PyObject *tmp = other;
4692 other = self;
4693 self = tmp;
4694 }
4695 }
4696
4697 it = PyObject_GetIter(other);
4698 if (it == NULL)
4699 return NULL;
4700
4701 while ((item = PyIter_Next(it)) != NULL) {
4702 int contains = PySequence_Contains(self, item);
4703 Py_DECREF(item);
4704 if (contains == -1) {
4705 Py_DECREF(it);
4706 return NULL;
4707 }
4708
4709 if (contains) {
4710 Py_DECREF(it);
4711 Py_RETURN_FALSE;
4712 }
4713 }
4714 Py_DECREF(it);
4715 if (PyErr_Occurred())
4716 return NULL; /* PyIter_Next raised an exception. */
4717 Py_RETURN_TRUE;
4718}
4719
4720PyDoc_STRVAR(isdisjoint_doc,
4721"Return True if the view and the given iterable have a null intersection.");
4722
Serhiy Storchaka81524022018-11-27 13:05:02 +02004723static PyObject* dictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored));
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004724
4725PyDoc_STRVAR(reversed_keys_doc,
4726"Return a reverse iterator over the dict keys.");
4727
Guido van Rossumb90c8482007-02-10 01:11:45 +00004728static PyMethodDef dictkeys_methods[] = {
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004729 {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O,
4730 isdisjoint_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004731 {"__reversed__", (PyCFunction)(void(*)(void))dictkeys_reversed, METH_NOARGS,
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004732 reversed_keys_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004733 {NULL, NULL} /* sentinel */
Guido van Rossumb90c8482007-02-10 01:11:45 +00004734};
4735
4736PyTypeObject PyDictKeys_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004737 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4738 "dict_keys", /* tp_name */
Eric Snow96c6af92015-05-29 22:21:39 -06004739 sizeof(_PyDictViewObject), /* tp_basicsize */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004740 0, /* tp_itemsize */
4741 /* methods */
4742 (destructor)dictview_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004743 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004744 0, /* tp_getattr */
4745 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004746 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004747 (reprfunc)dictview_repr, /* tp_repr */
4748 &dictviews_as_number, /* tp_as_number */
4749 &dictkeys_as_sequence, /* tp_as_sequence */
4750 0, /* tp_as_mapping */
4751 0, /* tp_hash */
4752 0, /* tp_call */
4753 0, /* tp_str */
4754 PyObject_GenericGetAttr, /* tp_getattro */
4755 0, /* tp_setattro */
4756 0, /* tp_as_buffer */
4757 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
4758 0, /* tp_doc */
4759 (traverseproc)dictview_traverse, /* tp_traverse */
4760 0, /* tp_clear */
4761 dictview_richcompare, /* tp_richcompare */
4762 0, /* tp_weaklistoffset */
4763 (getiterfunc)dictkeys_iter, /* tp_iter */
4764 0, /* tp_iternext */
4765 dictkeys_methods, /* tp_methods */
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004766 .tp_getset = dictview_getset,
Guido van Rossumb90c8482007-02-10 01:11:45 +00004767};
4768
4769static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304770dictkeys_new(PyObject *dict, PyObject *Py_UNUSED(ignored))
Guido van Rossumb90c8482007-02-10 01:11:45 +00004771{
Eric Snow96c6af92015-05-29 22:21:39 -06004772 return _PyDictView_New(dict, &PyDictKeys_Type);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004773}
4774
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004775static PyObject *
Serhiy Storchaka81524022018-11-27 13:05:02 +02004776dictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored))
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004777{
4778 if (dv->dv_dict == NULL) {
4779 Py_RETURN_NONE;
4780 }
4781 return dictiter_new(dv->dv_dict, &PyDictRevIterKey_Type);
4782}
4783
Guido van Rossum3ac67412007-02-10 18:55:06 +00004784/*** dict_items ***/
Guido van Rossumb90c8482007-02-10 01:11:45 +00004785
4786static PyObject *
Eric Snow96c6af92015-05-29 22:21:39 -06004787dictitems_iter(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004789 if (dv->dv_dict == NULL) {
4790 Py_RETURN_NONE;
4791 }
4792 return dictiter_new(dv->dv_dict, &PyDictIterItem_Type);
Guido van Rossum3ac67412007-02-10 18:55:06 +00004793}
4794
4795static int
Eric Snow96c6af92015-05-29 22:21:39 -06004796dictitems_contains(_PyDictViewObject *dv, PyObject *obj)
Guido van Rossum3ac67412007-02-10 18:55:06 +00004797{
Serhiy Storchaka753bca32017-05-20 12:30:02 +03004798 int result;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004799 PyObject *key, *value, *found;
4800 if (dv->dv_dict == NULL)
4801 return 0;
4802 if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 2)
4803 return 0;
4804 key = PyTuple_GET_ITEM(obj, 0);
4805 value = PyTuple_GET_ITEM(obj, 1);
Raymond Hettinger6692f012016-09-18 21:46:08 -07004806 found = PyDict_GetItemWithError((PyObject *)dv->dv_dict, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004807 if (found == NULL) {
4808 if (PyErr_Occurred())
4809 return -1;
4810 return 0;
4811 }
Serhiy Storchaka753bca32017-05-20 12:30:02 +03004812 Py_INCREF(found);
Serhiy Storchaka18b711c2019-08-04 14:12:48 +03004813 result = PyObject_RichCompareBool(found, value, Py_EQ);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03004814 Py_DECREF(found);
4815 return result;
Guido van Rossumb90c8482007-02-10 01:11:45 +00004816}
4817
Guido van Rossum83825ac2007-02-10 04:54:19 +00004818static PySequenceMethods dictitems_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004819 (lenfunc)dictview_len, /* sq_length */
4820 0, /* sq_concat */
4821 0, /* sq_repeat */
4822 0, /* sq_item */
4823 0, /* sq_slice */
4824 0, /* sq_ass_item */
4825 0, /* sq_ass_slice */
4826 (objobjproc)dictitems_contains, /* sq_contains */
Guido van Rossum83825ac2007-02-10 04:54:19 +00004827};
4828
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004829static PyObject* dictitems_reversed(_PyDictViewObject *dv);
4830
4831PyDoc_STRVAR(reversed_items_doc,
4832"Return a reverse iterator over the dict items.");
4833
Guido van Rossumb90c8482007-02-10 01:11:45 +00004834static PyMethodDef dictitems_methods[] = {
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004835 {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O,
4836 isdisjoint_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004837 {"__reversed__", (PyCFunction)(void(*)(void))dictitems_reversed, METH_NOARGS,
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004838 reversed_items_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004839 {NULL, NULL} /* sentinel */
Guido van Rossumb90c8482007-02-10 01:11:45 +00004840};
4841
4842PyTypeObject PyDictItems_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004843 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4844 "dict_items", /* tp_name */
Eric Snow96c6af92015-05-29 22:21:39 -06004845 sizeof(_PyDictViewObject), /* tp_basicsize */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004846 0, /* tp_itemsize */
4847 /* methods */
4848 (destructor)dictview_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004849 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004850 0, /* tp_getattr */
4851 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004852 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004853 (reprfunc)dictview_repr, /* tp_repr */
4854 &dictviews_as_number, /* tp_as_number */
4855 &dictitems_as_sequence, /* tp_as_sequence */
4856 0, /* tp_as_mapping */
4857 0, /* tp_hash */
4858 0, /* tp_call */
4859 0, /* tp_str */
4860 PyObject_GenericGetAttr, /* tp_getattro */
4861 0, /* tp_setattro */
4862 0, /* tp_as_buffer */
4863 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
4864 0, /* tp_doc */
4865 (traverseproc)dictview_traverse, /* tp_traverse */
4866 0, /* tp_clear */
4867 dictview_richcompare, /* tp_richcompare */
4868 0, /* tp_weaklistoffset */
4869 (getiterfunc)dictitems_iter, /* tp_iter */
4870 0, /* tp_iternext */
4871 dictitems_methods, /* tp_methods */
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004872 .tp_getset = dictview_getset,
Guido van Rossumb90c8482007-02-10 01:11:45 +00004873};
4874
4875static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304876dictitems_new(PyObject *dict, PyObject *Py_UNUSED(ignored))
Guido van Rossumb90c8482007-02-10 01:11:45 +00004877{
Eric Snow96c6af92015-05-29 22:21:39 -06004878 return _PyDictView_New(dict, &PyDictItems_Type);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004879}
4880
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004881static PyObject *
4882dictitems_reversed(_PyDictViewObject *dv)
4883{
4884 if (dv->dv_dict == NULL) {
4885 Py_RETURN_NONE;
4886 }
4887 return dictiter_new(dv->dv_dict, &PyDictRevIterItem_Type);
4888}
4889
Guido van Rossum3ac67412007-02-10 18:55:06 +00004890/*** dict_values ***/
Guido van Rossumb90c8482007-02-10 01:11:45 +00004891
4892static PyObject *
Eric Snow96c6af92015-05-29 22:21:39 -06004893dictvalues_iter(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004894{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004895 if (dv->dv_dict == NULL) {
4896 Py_RETURN_NONE;
4897 }
4898 return dictiter_new(dv->dv_dict, &PyDictIterValue_Type);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004899}
4900
Guido van Rossum83825ac2007-02-10 04:54:19 +00004901static PySequenceMethods dictvalues_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004902 (lenfunc)dictview_len, /* sq_length */
4903 0, /* sq_concat */
4904 0, /* sq_repeat */
4905 0, /* sq_item */
4906 0, /* sq_slice */
4907 0, /* sq_ass_item */
4908 0, /* sq_ass_slice */
4909 (objobjproc)0, /* sq_contains */
Guido van Rossum83825ac2007-02-10 04:54:19 +00004910};
4911
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004912static PyObject* dictvalues_reversed(_PyDictViewObject *dv);
4913
4914PyDoc_STRVAR(reversed_values_doc,
4915"Return a reverse iterator over the dict values.");
4916
Guido van Rossumb90c8482007-02-10 01:11:45 +00004917static PyMethodDef dictvalues_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004918 {"__reversed__", (PyCFunction)(void(*)(void))dictvalues_reversed, METH_NOARGS,
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004919 reversed_values_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004920 {NULL, NULL} /* sentinel */
Guido van Rossumb90c8482007-02-10 01:11:45 +00004921};
4922
4923PyTypeObject PyDictValues_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004924 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4925 "dict_values", /* tp_name */
Eric Snow96c6af92015-05-29 22:21:39 -06004926 sizeof(_PyDictViewObject), /* tp_basicsize */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004927 0, /* tp_itemsize */
4928 /* methods */
4929 (destructor)dictview_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004930 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004931 0, /* tp_getattr */
4932 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004933 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004934 (reprfunc)dictview_repr, /* tp_repr */
4935 0, /* tp_as_number */
4936 &dictvalues_as_sequence, /* tp_as_sequence */
4937 0, /* tp_as_mapping */
4938 0, /* tp_hash */
4939 0, /* tp_call */
4940 0, /* tp_str */
4941 PyObject_GenericGetAttr, /* tp_getattro */
4942 0, /* tp_setattro */
4943 0, /* tp_as_buffer */
4944 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
4945 0, /* tp_doc */
4946 (traverseproc)dictview_traverse, /* tp_traverse */
4947 0, /* tp_clear */
4948 0, /* tp_richcompare */
4949 0, /* tp_weaklistoffset */
4950 (getiterfunc)dictvalues_iter, /* tp_iter */
4951 0, /* tp_iternext */
4952 dictvalues_methods, /* tp_methods */
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004953 .tp_getset = dictview_getset,
Guido van Rossumb90c8482007-02-10 01:11:45 +00004954};
4955
4956static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304957dictvalues_new(PyObject *dict, PyObject *Py_UNUSED(ignored))
Guido van Rossumb90c8482007-02-10 01:11:45 +00004958{
Eric Snow96c6af92015-05-29 22:21:39 -06004959 return _PyDictView_New(dict, &PyDictValues_Type);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004960}
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004961
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004962static PyObject *
4963dictvalues_reversed(_PyDictViewObject *dv)
4964{
4965 if (dv->dv_dict == NULL) {
4966 Py_RETURN_NONE;
4967 }
4968 return dictiter_new(dv->dv_dict, &PyDictRevIterValue_Type);
4969}
4970
4971
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004972/* Returns NULL if cannot allocate a new PyDictKeysObject,
4973 but does not set an error */
4974PyDictKeysObject *
4975_PyDict_NewKeysForClass(void)
4976{
Victor Stinner742da042016-09-07 17:40:12 -07004977 PyDictKeysObject *keys = new_keys_object(PyDict_MINSIZE);
Victor Stinnerecf14e62021-04-10 23:15:32 +02004978 if (keys == NULL) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004979 PyErr_Clear();
Victor Stinnerecf14e62021-04-10 23:15:32 +02004980 }
4981 else {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004982 keys->dk_lookup = lookdict_split;
Victor Stinnerecf14e62021-04-10 23:15:32 +02004983 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004984 return keys;
4985}
4986
4987#define CACHED_KEYS(tp) (((PyHeapTypeObject*)tp)->ht_cached_keys)
4988
4989PyObject *
4990PyObject_GenericGetDict(PyObject *obj, void *context)
4991{
4992 PyObject *dict, **dictptr = _PyObject_GetDictPtr(obj);
4993 if (dictptr == NULL) {
4994 PyErr_SetString(PyExc_AttributeError,
4995 "This object has no __dict__");
4996 return NULL;
4997 }
4998 dict = *dictptr;
4999 if (dict == NULL) {
5000 PyTypeObject *tp = Py_TYPE(obj);
5001 if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && CACHED_KEYS(tp)) {
INADA Naokia7576492018-11-14 18:39:27 +09005002 dictkeys_incref(CACHED_KEYS(tp));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04005003 *dictptr = dict = new_dict_with_shared_keys(CACHED_KEYS(tp));
5004 }
5005 else {
5006 *dictptr = dict = PyDict_New();
5007 }
5008 }
5009 Py_XINCREF(dict);
5010 return dict;
5011}
5012
5013int
5014_PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
Victor Stinner742da042016-09-07 17:40:12 -07005015 PyObject *key, PyObject *value)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04005016{
5017 PyObject *dict;
5018 int res;
5019 PyDictKeysObject *cached;
5020
5021 assert(dictptr != NULL);
5022 if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && (cached = CACHED_KEYS(tp))) {
5023 assert(dictptr != NULL);
5024 dict = *dictptr;
5025 if (dict == NULL) {
INADA Naokia7576492018-11-14 18:39:27 +09005026 dictkeys_incref(cached);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04005027 dict = new_dict_with_shared_keys(cached);
5028 if (dict == NULL)
5029 return -1;
5030 *dictptr = dict;
5031 }
5032 if (value == NULL) {
5033 res = PyDict_DelItem(dict, key);
INADA Naoki2294f3a2017-02-12 13:51:30 +09005034 // Since key sharing dict doesn't allow deletion, PyDict_DelItem()
5035 // always converts dict to combined form.
5036 if ((cached = CACHED_KEYS(tp)) != NULL) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04005037 CACHED_KEYS(tp) = NULL;
INADA Naokia7576492018-11-14 18:39:27 +09005038 dictkeys_decref(cached);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04005039 }
Victor Stinner3d3f2642016-12-15 17:21:23 +01005040 }
5041 else {
INADA Naoki2294f3a2017-02-12 13:51:30 +09005042 int was_shared = (cached == ((PyDictObject *)dict)->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04005043 res = PyDict_SetItem(dict, key, value);
INADA Naoki2294f3a2017-02-12 13:51:30 +09005044 if (was_shared &&
5045 (cached = CACHED_KEYS(tp)) != NULL &&
5046 cached != ((PyDictObject *)dict)->ma_keys) {
Victor Stinner3d3f2642016-12-15 17:21:23 +01005047 /* PyDict_SetItem() may call dictresize and convert split table
5048 * into combined table. In such case, convert it to split
5049 * table again and update type's shared key only when this is
5050 * the only dict sharing key with the type.
5051 *
5052 * This is to allow using shared key in class like this:
5053 *
5054 * class C:
5055 * def __init__(self):
5056 * # one dict resize happens
5057 * self.a, self.b, self.c = 1, 2, 3
5058 * self.d, self.e, self.f = 4, 5, 6
5059 * a = C()
5060 */
Benjamin Peterson15ee8212012-04-24 14:44:18 -04005061 if (cached->dk_refcnt == 1) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04005062 CACHED_KEYS(tp) = make_keys_shared(dict);
Victor Stinner742da042016-09-07 17:40:12 -07005063 }
5064 else {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04005065 CACHED_KEYS(tp) = NULL;
5066 }
INADA Naokia7576492018-11-14 18:39:27 +09005067 dictkeys_decref(cached);
Benjamin Peterson15ee8212012-04-24 14:44:18 -04005068 if (CACHED_KEYS(tp) == NULL && PyErr_Occurred())
5069 return -1;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04005070 }
5071 }
5072 } else {
5073 dict = *dictptr;
5074 if (dict == NULL) {
5075 dict = PyDict_New();
5076 if (dict == NULL)
5077 return -1;
5078 *dictptr = dict;
5079 }
5080 if (value == NULL) {
5081 res = PyDict_DelItem(dict, key);
5082 } else {
5083 res = PyDict_SetItem(dict, key, value);
5084 }
5085 }
5086 return res;
5087}
5088
5089void
5090_PyDictKeys_DecRef(PyDictKeysObject *keys)
5091{
INADA Naokia7576492018-11-14 18:39:27 +09005092 dictkeys_decref(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04005093}