blob: 1b7ae06d822710272b27cfa161f8fa6c73fcd2bc [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"
Victor Stinnere5014be2020-04-14 17:52:15 +0200114#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
Victor Stinner59d3dce2020-06-02 14:03:25 +0200115#include "pycore_object.h" // _PyObject_GC_TRACK()
116#include "pycore_pyerrors.h" // _PyErr_Fetch()
Victor Stinnere5014be2020-04-14 17:52:15 +0200117#include "pycore_pystate.h" // _PyThreadState_GET()
Eric Snow96c6af92015-05-29 22:21:39 -0600118#include "dict-common.h"
Victor Stinnere5014be2020-04-14 17:52:15 +0200119#include "stringlib/eq.h" // unicode_eq()
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000120
Larry Hastings61272b72014-01-07 12:41:53 -0800121/*[clinic input]
Larry Hastingsc2047262014-01-25 20:43:29 -0800122class dict "PyDictObject *" "&PyDict_Type"
Larry Hastings61272b72014-01-07 12:41:53 -0800123[clinic start generated code]*/
Larry Hastings581ee362014-01-28 05:00:08 -0800124/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f157a5a0ce9589d6]*/
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800125
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400126
127/*
128To ensure the lookup algorithm terminates, there must be at least one Unused
129slot (NULL key) in the table.
130To avoid slowing down lookups on a near-full table, we resize the table when
131it's USABLE_FRACTION (currently two-thirds) full.
132*/
Guido van Rossum16e93a81997-01-28 00:00:11 +0000133
Tim Peterseb28ef22001-06-02 05:27:19 +0000134#define PERTURB_SHIFT 5
135
Guido van Rossum16e93a81997-01-28 00:00:11 +0000136/*
Tim Peterseb28ef22001-06-02 05:27:19 +0000137Major subtleties ahead: Most hash schemes depend on having a "good" hash
138function, in the sense of simulating randomness. Python doesn't: its most
R David Murray537ad7a2016-07-10 12:33:18 -0400139important hash functions (for ints) are very regular in common
Tim Peterseb28ef22001-06-02 05:27:19 +0000140cases:
Tim Peters15d49292001-05-27 07:39:22 +0000141
R David Murray537ad7a2016-07-10 12:33:18 -0400142 >>>[hash(i) for i in range(4)]
Guido van Rossumdc5f6b22006-08-24 21:29:26 +0000143 [0, 1, 2, 3]
Tim Peters15d49292001-05-27 07:39:22 +0000144
Tim Peterseb28ef22001-06-02 05:27:19 +0000145This isn't necessarily bad! To the contrary, in a table of size 2**i, taking
146the low-order i bits as the initial table index is extremely fast, and there
R David Murray537ad7a2016-07-10 12:33:18 -0400147are no collisions at all for dicts indexed by a contiguous range of ints. So
148this gives better-than-random behavior in common cases, and that's very
149desirable.
Tim Peters15d49292001-05-27 07:39:22 +0000150
Tim Peterseb28ef22001-06-02 05:27:19 +0000151OTOH, when collisions occur, the tendency to fill contiguous slices of the
152hash table makes a good collision resolution strategy crucial. Taking only
153the last i bits of the hash code is also vulnerable: for example, consider
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154the list [i << 16 for i in range(20000)] as a set of keys. Since ints are
Guido van Rossumdc5f6b22006-08-24 21:29:26 +0000155their own hash codes, and this fits in a dict of size 2**15, the last 15 bits
156 of every hash code are all 0: they *all* map to the same table index.
Tim Peters15d49292001-05-27 07:39:22 +0000157
Tim Peterseb28ef22001-06-02 05:27:19 +0000158But catering to unusual cases should not slow the usual ones, so we just take
159the last i bits anyway. It's up to collision resolution to do the rest. If
160we *usually* find the key we're looking for on the first try (and, it turns
161out, we usually do -- the table load factor is kept under 2/3, so the odds
162are solidly in our favor), then it makes best sense to keep the initial index
163computation dirt cheap.
Tim Peters15d49292001-05-27 07:39:22 +0000164
Tim Peterseb28ef22001-06-02 05:27:19 +0000165The first half of collision resolution is to visit table indices via this
166recurrence:
Tim Peters15d49292001-05-27 07:39:22 +0000167
Tim Peterseb28ef22001-06-02 05:27:19 +0000168 j = ((5*j) + 1) mod 2**i
Tim Peters15d49292001-05-27 07:39:22 +0000169
Tim Peterseb28ef22001-06-02 05:27:19 +0000170For any initial j in range(2**i), repeating that 2**i times generates each
171int in range(2**i) exactly once (see any text on random-number generation for
172proof). By itself, this doesn't help much: like linear probing (setting
173j += 1, or j -= 1, on each loop trip), it scans the table entries in a fixed
174order. This would be bad, except that's not the only thing we do, and it's
175actually *good* in the common cases where hash keys are consecutive. In an
176example that's really too small to make this entirely clear, for a table of
177size 2**3 the order of indices is:
Tim Peters15d49292001-05-27 07:39:22 +0000178
Tim Peterseb28ef22001-06-02 05:27:19 +0000179 0 -> 1 -> 6 -> 7 -> 4 -> 5 -> 2 -> 3 -> 0 [and here it's repeating]
180
181If two things come in at index 5, the first place we look after is index 2,
182not 6, so if another comes in at index 6 the collision at 5 didn't hurt it.
183Linear probing is deadly in this case because there the fixed probe order
184is the *same* as the order consecutive keys are likely to arrive. But it's
185extremely unlikely hash codes will follow a 5*j+1 recurrence by accident,
186and certain that consecutive hash codes do not.
187
188The other half of the strategy is to get the other bits of the hash code
189into play. This is done by initializing a (unsigned) vrbl "perturb" to the
190full hash code, and changing the recurrence to:
191
Tim Peterseb28ef22001-06-02 05:27:19 +0000192 perturb >>= PERTURB_SHIFT;
INADA Naoki267941c2016-10-06 15:19:07 +0900193 j = (5*j) + 1 + perturb;
Tim Peterseb28ef22001-06-02 05:27:19 +0000194 use j % 2**i as the next table index;
195
196Now the probe sequence depends (eventually) on every bit in the hash code,
197and the pseudo-scrambling property of recurring on 5*j+1 is more valuable,
198because it quickly magnifies small differences in the bits that didn't affect
199the initial index. Note that because perturb is unsigned, if the recurrence
200is executed often enough perturb eventually becomes and remains 0. At that
201point (very rarely reached) the recurrence is on (just) 5*j+1 again, and
202that's certain to find an empty slot eventually (since it generates every int
203in range(2**i), and we make sure there's always at least one empty slot).
204
205Selecting a good value for PERTURB_SHIFT is a balancing act. You want it
206small so that the high bits of the hash code continue to affect the probe
207sequence across iterations; but you want it large so that in really bad cases
208the high-order hash bits have an effect on early iterations. 5 was "the
209best" in minimizing total collisions across experiments Tim Peters ran (on
210both normal and pathological cases), but 4 and 6 weren't significantly worse.
211
Guido van Rossumdc5f6b22006-08-24 21:29:26 +0000212Historical: Reimer Behrends contributed the idea of using a polynomial-based
Tim Peterseb28ef22001-06-02 05:27:19 +0000213approach, using repeated multiplication by x in GF(2**n) where an irreducible
214polynomial for each table size was chosen such that x was a primitive root.
215Christian Tismer later extended that to use division by x instead, as an
216efficient way to get the high bits of the hash code into play. This scheme
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000217also gave excellent collision statistics, but was more expensive: two
218if-tests were required inside the loop; computing "the next" index took about
219the same number of operations but without as much potential parallelism
220(e.g., computing 5*j can go on at the same time as computing 1+perturb in the
221above, and then shifting perturb can be done while the table index is being
222masked); and the PyDictObject struct required a member to hold the table's
223polynomial. In Tim's experiments the current scheme ran faster, produced
224equally good collision statistics, needed less code & used less memory.
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000225
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000226*/
Tim Petersdea48ec2001-05-22 20:40:22 +0000227
Fred Drake1bff34a2000-08-31 19:31:38 +0000228/* forward declarations */
Victor Stinner742da042016-09-07 17:40:12 -0700229static Py_ssize_t lookdict(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900230 Py_hash_t hash, PyObject **value_addr);
Victor Stinner742da042016-09-07 17:40:12 -0700231static Py_ssize_t lookdict_unicode(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900232 Py_hash_t hash, PyObject **value_addr);
Victor Stinner742da042016-09-07 17:40:12 -0700233static Py_ssize_t
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400234lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900235 Py_hash_t hash, PyObject **value_addr);
Victor Stinner742da042016-09-07 17:40:12 -0700236static Py_ssize_t lookdict_split(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900237 Py_hash_t hash, PyObject **value_addr);
Fred Drake1bff34a2000-08-31 19:31:38 +0000238
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400239static int dictresize(PyDictObject *mp, Py_ssize_t minused);
Tim Petersdea48ec2001-05-22 20:40:22 +0000240
INADA Naoki2aaf98c2018-09-26 12:59:00 +0900241static PyObject* dict_iter(PyDictObject *dict);
242
Benjamin Peterson3c569292016-09-08 13:16:41 -0700243/*Global counter used to set ma_version_tag field of dictionary.
Victor Stinner3b6a6b42016-09-08 12:51:24 -0700244 * It is incremented each time that a dictionary is created and each
245 * time that a dictionary is modified. */
246static uint64_t pydict_global_version = 0;
247
248#define DICT_NEXT_VERSION() (++pydict_global_version)
249
Serhiy Storchaka1009bf12015-04-03 23:53:51 +0300250#include "clinic/dictobject.c.h"
251
Victor Stinner522691c2020-06-23 16:40:40 +0200252
253static struct _Py_dict_state *
254get_dict_state(void)
255{
256 PyInterpreterState *interp = _PyInterpreterState_GET();
257 return &interp->dict_state;
258}
259
260
Victor Stinnerae00a5a2020-04-29 02:29:20 +0200261void
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200262_PyDict_ClearFreeList(PyThreadState *tstate)
Christian Heimes77c02eb2008-02-09 02:18:51 +0000263{
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200264 struct _Py_dict_state *state = &tstate->interp->dict_state;
265 while (state->numfree) {
266 PyDictObject *op = state->free_list[--state->numfree];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 assert(PyDict_CheckExact(op));
268 PyObject_GC_Del(op);
269 }
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200270 while (state->keys_numfree) {
271 PyObject_FREE(state->keys_free_list[--state->keys_numfree]);
Victor Stinner742da042016-09-07 17:40:12 -0700272 }
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200273}
274
275
276void
277_PyDict_Fini(PyThreadState *tstate)
278{
279 _PyDict_ClearFreeList(tstate);
280#ifdef Py_DEBUG
Victor Stinner522691c2020-06-23 16:40:40 +0200281 struct _Py_dict_state *state = get_dict_state();
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200282 state->numfree = -1;
283 state->keys_numfree = -1;
Victor Stinnerb4b53862020-05-05 19:55:29 +0200284#endif
Antoine Pitrou9a812cb2011-11-15 00:00:12 +0100285}
286
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200287
David Malcolm49526f42012-06-22 14:55:41 -0400288/* Print summary info about the state of the optimized allocator */
289void
290_PyDict_DebugMallocStats(FILE *out)
291{
Victor Stinner522691c2020-06-23 16:40:40 +0200292 struct _Py_dict_state *state = get_dict_state();
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200293 _PyDebugAllocatorStats(out, "free PyDictObject",
294 state->numfree, sizeof(PyDictObject));
David Malcolm49526f42012-06-22 14:55:41 -0400295}
296
297
Victor Stinner742da042016-09-07 17:40:12 -0700298#define DK_SIZE(dk) ((dk)->dk_size)
299#if SIZEOF_VOID_P > 4
Victor Stinner58f7c5a2016-09-08 11:37:36 -0700300#define DK_IXSIZE(dk) \
301 (DK_SIZE(dk) <= 0xff ? \
302 1 : DK_SIZE(dk) <= 0xffff ? \
303 2 : DK_SIZE(dk) <= 0xffffffff ? \
Benjamin Peterson3c569292016-09-08 13:16:41 -0700304 4 : sizeof(int64_t))
Victor Stinner742da042016-09-07 17:40:12 -0700305#else
Victor Stinner58f7c5a2016-09-08 11:37:36 -0700306#define DK_IXSIZE(dk) \
307 (DK_SIZE(dk) <= 0xff ? \
308 1 : DK_SIZE(dk) <= 0xffff ? \
Benjamin Peterson3c569292016-09-08 13:16:41 -0700309 2 : sizeof(int32_t))
Victor Stinner742da042016-09-07 17:40:12 -0700310#endif
Victor Stinner58f7c5a2016-09-08 11:37:36 -0700311#define DK_ENTRIES(dk) \
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700312 ((PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[DK_SIZE(dk) * DK_IXSIZE(dk)]))
Victor Stinner742da042016-09-07 17:40:12 -0700313
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400314#define DK_MASK(dk) (((dk)->dk_size)-1)
315#define IS_POWER_OF_2(x) (((x) & (x-1)) == 0)
316
INADA Naokia7576492018-11-14 18:39:27 +0900317static void free_keys_object(PyDictKeysObject *keys);
318
319static inline void
320dictkeys_incref(PyDictKeysObject *dk)
321{
Victor Stinner49932fe2020-02-03 17:55:05 +0100322#ifdef Py_REF_DEBUG
323 _Py_RefTotal++;
324#endif
INADA Naokia7576492018-11-14 18:39:27 +0900325 dk->dk_refcnt++;
326}
327
328static inline void
329dictkeys_decref(PyDictKeysObject *dk)
330{
331 assert(dk->dk_refcnt > 0);
Victor Stinner49932fe2020-02-03 17:55:05 +0100332#ifdef Py_REF_DEBUG
333 _Py_RefTotal--;
334#endif
INADA Naokia7576492018-11-14 18:39:27 +0900335 if (--dk->dk_refcnt == 0) {
336 free_keys_object(dk);
337 }
338}
339
Victor Stinner742da042016-09-07 17:40:12 -0700340/* lookup indices. returns DKIX_EMPTY, DKIX_DUMMY, or ix >=0 */
Benjamin Peterson73222252016-09-08 09:58:47 -0700341static inline Py_ssize_t
Andy Lester62d21c92020-03-25 23:13:01 -0500342dictkeys_get_index(const PyDictKeysObject *keys, Py_ssize_t i)
Victor Stinner742da042016-09-07 17:40:12 -0700343{
344 Py_ssize_t s = DK_SIZE(keys);
Victor Stinner71211e32016-09-08 10:52:46 -0700345 Py_ssize_t ix;
346
Victor Stinner742da042016-09-07 17:40:12 -0700347 if (s <= 0xff) {
Andy Lester62d21c92020-03-25 23:13:01 -0500348 const int8_t *indices = (const int8_t*)(keys->dk_indices);
Victor Stinner208857e2016-09-08 11:35:46 -0700349 ix = indices[i];
Victor Stinner742da042016-09-07 17:40:12 -0700350 }
351 else if (s <= 0xffff) {
Andy Lester62d21c92020-03-25 23:13:01 -0500352 const int16_t *indices = (const int16_t*)(keys->dk_indices);
Victor Stinner208857e2016-09-08 11:35:46 -0700353 ix = indices[i];
Victor Stinner742da042016-09-07 17:40:12 -0700354 }
Benjamin Peterson3c569292016-09-08 13:16:41 -0700355#if SIZEOF_VOID_P > 4
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300356 else if (s > 0xffffffff) {
Andy Lester62d21c92020-03-25 23:13:01 -0500357 const int64_t *indices = (const int64_t*)(keys->dk_indices);
Victor Stinner208857e2016-09-08 11:35:46 -0700358 ix = indices[i];
Victor Stinner742da042016-09-07 17:40:12 -0700359 }
Benjamin Peterson3c569292016-09-08 13:16:41 -0700360#endif
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300361 else {
Andy Lester62d21c92020-03-25 23:13:01 -0500362 const int32_t *indices = (const int32_t*)(keys->dk_indices);
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300363 ix = indices[i];
364 }
Victor Stinner71211e32016-09-08 10:52:46 -0700365 assert(ix >= DKIX_DUMMY);
366 return ix;
Victor Stinner742da042016-09-07 17:40:12 -0700367}
368
369/* write to indices. */
Benjamin Peterson73222252016-09-08 09:58:47 -0700370static inline void
INADA Naokia7576492018-11-14 18:39:27 +0900371dictkeys_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix)
Victor Stinner742da042016-09-07 17:40:12 -0700372{
373 Py_ssize_t s = DK_SIZE(keys);
Victor Stinner71211e32016-09-08 10:52:46 -0700374
375 assert(ix >= DKIX_DUMMY);
376
Victor Stinner742da042016-09-07 17:40:12 -0700377 if (s <= 0xff) {
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700378 int8_t *indices = (int8_t*)(keys->dk_indices);
Victor Stinner71211e32016-09-08 10:52:46 -0700379 assert(ix <= 0x7f);
Victor Stinner208857e2016-09-08 11:35:46 -0700380 indices[i] = (char)ix;
Victor Stinner742da042016-09-07 17:40:12 -0700381 }
382 else if (s <= 0xffff) {
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700383 int16_t *indices = (int16_t*)(keys->dk_indices);
Victor Stinner71211e32016-09-08 10:52:46 -0700384 assert(ix <= 0x7fff);
Victor Stinner208857e2016-09-08 11:35:46 -0700385 indices[i] = (int16_t)ix;
Victor Stinner742da042016-09-07 17:40:12 -0700386 }
Benjamin Peterson3c569292016-09-08 13:16:41 -0700387#if SIZEOF_VOID_P > 4
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300388 else if (s > 0xffffffff) {
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700389 int64_t *indices = (int64_t*)(keys->dk_indices);
Victor Stinner208857e2016-09-08 11:35:46 -0700390 indices[i] = ix;
Victor Stinner742da042016-09-07 17:40:12 -0700391 }
Benjamin Peterson3c569292016-09-08 13:16:41 -0700392#endif
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300393 else {
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700394 int32_t *indices = (int32_t*)(keys->dk_indices);
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300395 assert(ix <= 0x7fffffff);
396 indices[i] = (int32_t)ix;
397 }
Victor Stinner742da042016-09-07 17:40:12 -0700398}
399
400
Antoine Pitroua504a7a2012-06-24 21:03:45 +0200401/* USABLE_FRACTION is the maximum dictionary load.
Victor Stinner742da042016-09-07 17:40:12 -0700402 * Increasing this ratio makes dictionaries more dense resulting in more
403 * collisions. Decreasing it improves sparseness at the expense of spreading
404 * indices over more cache lines and at the cost of total memory consumed.
Antoine Pitroua504a7a2012-06-24 21:03:45 +0200405 *
406 * USABLE_FRACTION must obey the following:
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400407 * (0 < USABLE_FRACTION(n) < n) for all n >= 2
408 *
Victor Stinner742da042016-09-07 17:40:12 -0700409 * USABLE_FRACTION should be quick to calculate.
410 * Fractions around 1/2 to 2/3 seem to work well in practice.
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400411 */
Victor Stinner742da042016-09-07 17:40:12 -0700412#define USABLE_FRACTION(n) (((n) << 1)/3)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400413
Victor Stinner742da042016-09-07 17:40:12 -0700414/* ESTIMATE_SIZE is reverse function of USABLE_FRACTION.
415 * This can be used to reserve enough size to insert n entries without
416 * resizing.
417 */
INADA Naoki92c50ee2016-11-22 00:57:02 +0900418#define ESTIMATE_SIZE(n) (((n)*3+1) >> 1)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400419
Victor Stinner742da042016-09-07 17:40:12 -0700420/* Alternative fraction that is otherwise close enough to 2n/3 to make
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400421 * little difference. 8 * 2/3 == 8 * 5/8 == 5. 16 * 2/3 == 16 * 5/8 == 10.
422 * 32 * 2/3 = 21, 32 * 5/8 = 20.
423 * Its advantage is that it is faster to compute on machines with slow division.
424 * #define USABLE_FRACTION(n) (((n) >> 1) + ((n) >> 2) - ((n) >> 3))
Victor Stinner742da042016-09-07 17:40:12 -0700425 */
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400426
Victor Stinnera9f61a52013-07-16 22:17:26 +0200427/* GROWTH_RATE. Growth rate upon hitting maximum load.
INADA Naoki5fbc5112018-04-17 15:53:34 +0900428 * Currently set to used*3.
Victor Stinnera9f61a52013-07-16 22:17:26 +0200429 * This means that dicts double in size when growing without deletions,
Raymond Hettinger36f74aa2013-05-17 03:01:13 -0700430 * but have more head room when the number of deletions is on a par with the
INADA Naoki5fbc5112018-04-17 15:53:34 +0900431 * number of insertions. See also bpo-17563 and bpo-33205.
432 *
Raymond Hettinger36f74aa2013-05-17 03:01:13 -0700433 * GROWTH_RATE was set to used*4 up to version 3.2.
434 * GROWTH_RATE was set to used*2 in version 3.3.0
INADA Naoki5fbc5112018-04-17 15:53:34 +0900435 * GROWTH_RATE was set to used*2 + capacity/2 in 3.4.0-3.6.0.
Antoine Pitroua504a7a2012-06-24 21:03:45 +0200436 */
INADA Naoki5fbc5112018-04-17 15:53:34 +0900437#define GROWTH_RATE(d) ((d)->ma_used*3)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400438
439#define ENSURE_ALLOWS_DELETIONS(d) \
440 if ((d)->ma_keys->dk_lookup == lookdict_unicode_nodummy) { \
441 (d)->ma_keys->dk_lookup = lookdict_unicode; \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400443
444/* This immutable, empty PyDictKeysObject is used for PyDict_Clear()
445 * (which cannot fail and thus can do no allocation).
446 */
447static PyDictKeysObject empty_keys_struct = {
Serhiy Storchaka97932e42016-09-26 23:01:23 +0300448 1, /* dk_refcnt */
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400449 1, /* dk_size */
450 lookdict_split, /* dk_lookup */
451 0, /* dk_usable (immutable) */
Victor Stinner742da042016-09-07 17:40:12 -0700452 0, /* dk_nentries */
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700453 {DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY,
454 DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY}, /* dk_indices */
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400455};
456
457static PyObject *empty_values[1] = { NULL };
458
459#define Py_EMPTY_KEYS &empty_keys_struct
460
Victor Stinner611b0fa2016-09-14 15:02:01 +0200461/* Uncomment to check the dict content in _PyDict_CheckConsistency() */
462/* #define DEBUG_PYDICT */
463
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200464#ifdef DEBUG_PYDICT
465# define ASSERT_CONSISTENT(op) assert(_PyDict_CheckConsistency((PyObject *)(op), 1))
466#else
467# define ASSERT_CONSISTENT(op) assert(_PyDict_CheckConsistency((PyObject *)(op), 0))
468#endif
Victor Stinner611b0fa2016-09-14 15:02:01 +0200469
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200470
471int
472_PyDict_CheckConsistency(PyObject *op, int check_content)
Victor Stinner611b0fa2016-09-14 15:02:01 +0200473{
Victor Stinner68762572019-10-07 18:42:01 +0200474#define CHECK(expr) \
475 do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0)
476
477 assert(op != NULL);
478 CHECK(PyDict_Check(op));
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200479 PyDictObject *mp = (PyDictObject *)op;
Victor Stinner50fe3f82018-10-26 18:47:15 +0200480
Victor Stinner611b0fa2016-09-14 15:02:01 +0200481 PyDictKeysObject *keys = mp->ma_keys;
482 int splitted = _PyDict_HasSplitTable(mp);
483 Py_ssize_t usable = USABLE_FRACTION(keys->dk_size);
Victor Stinner611b0fa2016-09-14 15:02:01 +0200484
Victor Stinner68762572019-10-07 18:42:01 +0200485 CHECK(0 <= mp->ma_used && mp->ma_used <= usable);
486 CHECK(IS_POWER_OF_2(keys->dk_size));
487 CHECK(0 <= keys->dk_usable && keys->dk_usable <= usable);
488 CHECK(0 <= keys->dk_nentries && keys->dk_nentries <= usable);
489 CHECK(keys->dk_usable + keys->dk_nentries <= usable);
Victor Stinner611b0fa2016-09-14 15:02:01 +0200490
491 if (!splitted) {
492 /* combined table */
Victor Stinner68762572019-10-07 18:42:01 +0200493 CHECK(keys->dk_refcnt == 1);
Victor Stinner611b0fa2016-09-14 15:02:01 +0200494 }
495
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200496 if (check_content) {
497 PyDictKeyEntry *entries = DK_ENTRIES(keys);
498 Py_ssize_t i;
Victor Stinner611b0fa2016-09-14 15:02:01 +0200499
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200500 for (i=0; i < keys->dk_size; i++) {
501 Py_ssize_t ix = dictkeys_get_index(keys, i);
Victor Stinner68762572019-10-07 18:42:01 +0200502 CHECK(DKIX_DUMMY <= ix && ix <= usable);
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200503 }
Victor Stinner611b0fa2016-09-14 15:02:01 +0200504
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200505 for (i=0; i < usable; i++) {
506 PyDictKeyEntry *entry = &entries[i];
507 PyObject *key = entry->me_key;
508
509 if (key != NULL) {
510 if (PyUnicode_CheckExact(key)) {
511 Py_hash_t hash = ((PyASCIIObject *)key)->hash;
Victor Stinner68762572019-10-07 18:42:01 +0200512 CHECK(hash != -1);
513 CHECK(entry->me_hash == hash);
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200514 }
515 else {
516 /* test_dict fails if PyObject_Hash() is called again */
Victor Stinner68762572019-10-07 18:42:01 +0200517 CHECK(entry->me_hash != -1);
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200518 }
519 if (!splitted) {
Victor Stinner68762572019-10-07 18:42:01 +0200520 CHECK(entry->me_value != NULL);
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200521 }
Victor Stinner611b0fa2016-09-14 15:02:01 +0200522 }
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200523
524 if (splitted) {
Victor Stinner68762572019-10-07 18:42:01 +0200525 CHECK(entry->me_value == NULL);
Victor Stinner611b0fa2016-09-14 15:02:01 +0200526 }
527 }
528
529 if (splitted) {
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200530 /* splitted table */
531 for (i=0; i < mp->ma_used; i++) {
Victor Stinner68762572019-10-07 18:42:01 +0200532 CHECK(mp->ma_values[i] != NULL);
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200533 }
Victor Stinner611b0fa2016-09-14 15:02:01 +0200534 }
535 }
Victor Stinner611b0fa2016-09-14 15:02:01 +0200536 return 1;
Victor Stinner68762572019-10-07 18:42:01 +0200537
538#undef CHECK
Victor Stinner611b0fa2016-09-14 15:02:01 +0200539}
Victor Stinner611b0fa2016-09-14 15:02:01 +0200540
541
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200542static PyDictKeysObject*
543new_keys_object(Py_ssize_t size)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400544{
545 PyDictKeysObject *dk;
Victor Stinner742da042016-09-07 17:40:12 -0700546 Py_ssize_t es, usable;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400547
Victor Stinner742da042016-09-07 17:40:12 -0700548 assert(size >= PyDict_MINSIZE);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400549 assert(IS_POWER_OF_2(size));
Victor Stinner742da042016-09-07 17:40:12 -0700550
551 usable = USABLE_FRACTION(size);
552 if (size <= 0xff) {
553 es = 1;
554 }
555 else if (size <= 0xffff) {
556 es = 2;
557 }
558#if SIZEOF_VOID_P > 4
559 else if (size <= 0xffffffff) {
560 es = 4;
561 }
562#endif
563 else {
564 es = sizeof(Py_ssize_t);
565 }
566
Victor Stinner522691c2020-06-23 16:40:40 +0200567 struct _Py_dict_state *state = get_dict_state();
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200568#ifdef Py_DEBUG
569 // new_keys_object() must not be called after _PyDict_Fini()
570 assert(state->keys_numfree != -1);
571#endif
572 if (size == PyDict_MINSIZE && state->keys_numfree > 0) {
573 dk = state->keys_free_list[--state->keys_numfree];
Victor Stinner742da042016-09-07 17:40:12 -0700574 }
Victor Stinnerb4b53862020-05-05 19:55:29 +0200575 else
Victor Stinnerb4b53862020-05-05 19:55:29 +0200576 {
Victor Stinner98ee9d52016-09-08 09:33:56 -0700577 dk = PyObject_MALLOC(sizeof(PyDictKeysObject)
Victor Stinner98ee9d52016-09-08 09:33:56 -0700578 + es * size
579 + sizeof(PyDictKeyEntry) * usable);
Victor Stinner742da042016-09-07 17:40:12 -0700580 if (dk == NULL) {
581 PyErr_NoMemory();
582 return NULL;
583 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400584 }
Victor Stinner49932fe2020-02-03 17:55:05 +0100585#ifdef Py_REF_DEBUG
586 _Py_RefTotal++;
587#endif
INADA Naokia7576492018-11-14 18:39:27 +0900588 dk->dk_refcnt = 1;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400589 dk->dk_size = size;
Victor Stinner742da042016-09-07 17:40:12 -0700590 dk->dk_usable = usable;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400591 dk->dk_lookup = lookdict_unicode_nodummy;
Victor Stinner742da042016-09-07 17:40:12 -0700592 dk->dk_nentries = 0;
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700593 memset(&dk->dk_indices[0], 0xff, es * size);
Victor Stinner742da042016-09-07 17:40:12 -0700594 memset(DK_ENTRIES(dk), 0, sizeof(PyDictKeyEntry) * usable);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400595 return dk;
596}
597
598static void
599free_keys_object(PyDictKeysObject *keys)
600{
Victor Stinner742da042016-09-07 17:40:12 -0700601 PyDictKeyEntry *entries = DK_ENTRIES(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400602 Py_ssize_t i, n;
Victor Stinner742da042016-09-07 17:40:12 -0700603 for (i = 0, n = keys->dk_nentries; i < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400604 Py_XDECREF(entries[i].me_key);
605 Py_XDECREF(entries[i].me_value);
606 }
Victor Stinner522691c2020-06-23 16:40:40 +0200607 struct _Py_dict_state *state = get_dict_state();
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200608#ifdef Py_DEBUG
609 // free_keys_object() must not be called after _PyDict_Fini()
610 assert(state->keys_numfree != -1);
611#endif
612 if (keys->dk_size == PyDict_MINSIZE && state->keys_numfree < PyDict_MAXFREELIST) {
613 state->keys_free_list[state->keys_numfree++] = keys;
Victor Stinner742da042016-09-07 17:40:12 -0700614 return;
615 }
Raymond Hettingerce5179f2016-01-31 08:56:21 -0800616 PyObject_FREE(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400617}
618
619#define new_values(size) PyMem_NEW(PyObject *, size)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400620#define free_values(values) PyMem_FREE(values)
621
622/* Consumes a reference to the keys object */
623static PyObject *
624new_dict(PyDictKeysObject *keys, PyObject **values)
625{
626 PyDictObject *mp;
Victor Stinnerc9b7f512013-07-08 22:19:20 +0200627 assert(keys != NULL);
Victor Stinner522691c2020-06-23 16:40:40 +0200628 struct _Py_dict_state *state = get_dict_state();
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200629#ifdef Py_DEBUG
630 // new_dict() must not be called after _PyDict_Fini()
631 assert(state->numfree != -1);
632#endif
633 if (state->numfree) {
634 mp = state->free_list[--state->numfree];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 assert (mp != NULL);
Dong-hee Na1b55b652020-02-17 19:09:15 +0900636 assert (Py_IS_TYPE(mp, &PyDict_Type));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 _Py_NewReference((PyObject *)mp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 }
Victor Stinnerb4e85ca2020-06-23 11:33:18 +0200639 else {
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400640 mp = PyObject_GC_New(PyDictObject, &PyDict_Type);
641 if (mp == NULL) {
INADA Naokia7576492018-11-14 18:39:27 +0900642 dictkeys_decref(keys);
Zackery Spytz3d07c1e2019-03-23 20:23:29 -0600643 if (values != empty_values) {
644 free_values(values);
645 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400646 return NULL;
647 }
648 }
649 mp->ma_keys = keys;
650 mp->ma_values = values;
651 mp->ma_used = 0;
Victor Stinner3b6a6b42016-09-08 12:51:24 -0700652 mp->ma_version_tag = DICT_NEXT_VERSION();
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200653 ASSERT_CONSISTENT(mp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 return (PyObject *)mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000655}
656
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400657/* Consumes a reference to the keys object */
658static PyObject *
659new_dict_with_shared_keys(PyDictKeysObject *keys)
660{
661 PyObject **values;
662 Py_ssize_t i, size;
663
Victor Stinner742da042016-09-07 17:40:12 -0700664 size = USABLE_FRACTION(DK_SIZE(keys));
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400665 values = new_values(size);
666 if (values == NULL) {
INADA Naokia7576492018-11-14 18:39:27 +0900667 dictkeys_decref(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400668 return PyErr_NoMemory();
669 }
670 for (i = 0; i < size; i++) {
671 values[i] = NULL;
672 }
673 return new_dict(keys, values);
674}
675
Yury Selivanovb0a7a032018-01-22 11:54:41 -0500676
Inada Naokidb6d9a52020-08-04 11:08:06 +0900677static PyDictKeysObject *
678clone_combined_dict_keys(PyDictObject *orig)
Yury Selivanovb0a7a032018-01-22 11:54:41 -0500679{
Inada Naokidb6d9a52020-08-04 11:08:06 +0900680 assert(PyDict_Check(orig));
681 assert(Py_TYPE(orig)->tp_iter == (getiterfunc)dict_iter);
Yury Selivanovb0a7a032018-01-22 11:54:41 -0500682 assert(orig->ma_values == NULL);
683 assert(orig->ma_keys->dk_refcnt == 1);
684
685 Py_ssize_t keys_size = _PyDict_KeysSize(orig->ma_keys);
686 PyDictKeysObject *keys = PyObject_Malloc(keys_size);
687 if (keys == NULL) {
688 PyErr_NoMemory();
689 return NULL;
690 }
691
692 memcpy(keys, orig->ma_keys, keys_size);
693
694 /* After copying key/value pairs, we need to incref all
695 keys and values and they are about to be co-owned by a
696 new dict object. */
697 PyDictKeyEntry *ep0 = DK_ENTRIES(keys);
698 Py_ssize_t n = keys->dk_nentries;
699 for (Py_ssize_t i = 0; i < n; i++) {
700 PyDictKeyEntry *entry = &ep0[i];
701 PyObject *value = entry->me_value;
702 if (value != NULL) {
703 Py_INCREF(value);
704 Py_INCREF(entry->me_key);
705 }
706 }
707
Yury Selivanov0b752282018-07-06 12:20:07 -0400708 /* Since we copied the keys table we now have an extra reference
Victor Stinner49932fe2020-02-03 17:55:05 +0100709 in the system. Manually call increment _Py_RefTotal to signal that
INADA Naokia7576492018-11-14 18:39:27 +0900710 we have it now; calling dictkeys_incref would be an error as
Yury Selivanov0b752282018-07-06 12:20:07 -0400711 keys->dk_refcnt is already set to 1 (after memcpy). */
Victor Stinner49932fe2020-02-03 17:55:05 +0100712#ifdef Py_REF_DEBUG
713 _Py_RefTotal++;
714#endif
Inada Naokidb6d9a52020-08-04 11:08:06 +0900715 return keys;
Yury Selivanovb0a7a032018-01-22 11:54:41 -0500716}
717
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400718PyObject *
719PyDict_New(void)
720{
Inada Naokif2a18672019-03-12 17:25:44 +0900721 dictkeys_incref(Py_EMPTY_KEYS);
722 return new_dict(Py_EMPTY_KEYS, empty_values);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400723}
724
Victor Stinner742da042016-09-07 17:40:12 -0700725/* Search index of hash table from offset of entry table */
726static Py_ssize_t
727lookdict_index(PyDictKeysObject *k, Py_hash_t hash, Py_ssize_t index)
728{
Victor Stinner742da042016-09-07 17:40:12 -0700729 size_t mask = DK_MASK(k);
INADA Naoki073ae482017-06-23 15:22:50 +0900730 size_t perturb = (size_t)hash;
731 size_t i = (size_t)hash & mask;
Victor Stinner742da042016-09-07 17:40:12 -0700732
INADA Naoki073ae482017-06-23 15:22:50 +0900733 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900734 Py_ssize_t ix = dictkeys_get_index(k, i);
Victor Stinner742da042016-09-07 17:40:12 -0700735 if (ix == index) {
736 return i;
737 }
738 if (ix == DKIX_EMPTY) {
739 return DKIX_EMPTY;
740 }
INADA Naoki073ae482017-06-23 15:22:50 +0900741 perturb >>= PERTURB_SHIFT;
742 i = mask & (i*5 + perturb + 1);
Victor Stinner742da042016-09-07 17:40:12 -0700743 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700744 Py_UNREACHABLE();
Victor Stinner742da042016-09-07 17:40:12 -0700745}
746
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000747/*
748The basic lookup function used by all operations.
Guido van Rossum16e93a81997-01-28 00:00:11 +0000749This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000750Open addressing is preferred over chaining since the link overhead for
751chaining would be substantial (100% with typical malloc overhead).
752
Tim Peterseb28ef22001-06-02 05:27:19 +0000753The initial probe index is computed as hash mod the table size. Subsequent
754probe indices are computed as explained earlier.
Guido van Rossum2bc13791999-03-24 19:06:42 +0000755
756All arithmetic on hash should ignore overflow.
Guido van Rossum16e93a81997-01-28 00:00:11 +0000757
Guido van Rossumdc5f6b22006-08-24 21:29:26 +0000758The details in this version are due to Tim Peters, building on many past
Tim Peterseb28ef22001-06-02 05:27:19 +0000759contributions by Reimer Behrends, Jyrki Alakuijala, Vladimir Marangozov and
Guido van Rossumdc5f6b22006-08-24 21:29:26 +0000760Christian Tismer.
Fred Drake1bff34a2000-08-31 19:31:38 +0000761
Victor Stinner742da042016-09-07 17:40:12 -0700762lookdict() is general-purpose, and may return DKIX_ERROR if (and only if) a
Victor Stinnera4348cc2016-09-08 12:01:25 -0700763comparison raises an exception.
Guido van Rossum89d8c602007-09-18 17:26:56 +0000764lookdict_unicode() below is specialized to string keys, comparison of which can
INADA Naoki1b8df102017-02-20 22:48:10 +0900765never raise an exception; that function can never return DKIX_ERROR when key
766is string. Otherwise, it falls back to lookdict().
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400767lookdict_unicode_nodummy is further specialized for string keys that cannot be
768the <dummy> value.
INADA Naoki778928b2017-08-03 23:45:15 +0900769For both, when the key isn't found a DKIX_EMPTY is returned.
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000770*/
Victor Stinnerc7a8f672016-11-15 15:13:40 +0100771static Py_ssize_t _Py_HOT_FUNCTION
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400772lookdict(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900773 Py_hash_t hash, PyObject **value_addr)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000774{
INADA Naoki778928b2017-08-03 23:45:15 +0900775 size_t i, mask, perturb;
Victor Stinner742da042016-09-07 17:40:12 -0700776 PyDictKeysObject *dk;
INADA Naoki778928b2017-08-03 23:45:15 +0900777 PyDictKeyEntry *ep0;
Tim Peterseb28ef22001-06-02 05:27:19 +0000778
Antoine Pitrou9a234902012-05-13 20:48:01 +0200779top:
Victor Stinner742da042016-09-07 17:40:12 -0700780 dk = mp->ma_keys;
Victor Stinner742da042016-09-07 17:40:12 -0700781 ep0 = DK_ENTRIES(dk);
INADA Naoki778928b2017-08-03 23:45:15 +0900782 mask = DK_MASK(dk);
783 perturb = hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000784 i = (size_t)hash & mask;
Victor Stinner742da042016-09-07 17:40:12 -0700785
INADA Naoki778928b2017-08-03 23:45:15 +0900786 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900787 Py_ssize_t ix = dictkeys_get_index(dk, i);
Victor Stinner742da042016-09-07 17:40:12 -0700788 if (ix == DKIX_EMPTY) {
Victor Stinner742da042016-09-07 17:40:12 -0700789 *value_addr = NULL;
790 return ix;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400791 }
INADA Naoki778928b2017-08-03 23:45:15 +0900792 if (ix >= 0) {
793 PyDictKeyEntry *ep = &ep0[ix];
794 assert(ep->me_key != NULL);
795 if (ep->me_key == key) {
796 *value_addr = ep->me_value;
797 return ix;
Victor Stinner742da042016-09-07 17:40:12 -0700798 }
INADA Naoki778928b2017-08-03 23:45:15 +0900799 if (ep->me_hash == hash) {
800 PyObject *startkey = ep->me_key;
801 Py_INCREF(startkey);
802 int cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
803 Py_DECREF(startkey);
804 if (cmp < 0) {
805 *value_addr = NULL;
806 return DKIX_ERROR;
807 }
808 if (dk == mp->ma_keys && ep->me_key == startkey) {
809 if (cmp > 0) {
810 *value_addr = ep->me_value;
811 return ix;
Victor Stinner742da042016-09-07 17:40:12 -0700812 }
INADA Naoki778928b2017-08-03 23:45:15 +0900813 }
814 else {
815 /* The dict was mutated, restart */
816 goto top;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400817 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000818 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000819 }
INADA Naoki778928b2017-08-03 23:45:15 +0900820 perturb >>= PERTURB_SHIFT;
821 i = (i*5 + perturb + 1) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000822 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700823 Py_UNREACHABLE();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000824}
825
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400826/* Specialized version for string-only keys */
Victor Stinnerc7a8f672016-11-15 15:13:40 +0100827static Py_ssize_t _Py_HOT_FUNCTION
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400828lookdict_unicode(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900829 Py_hash_t hash, PyObject **value_addr)
Fred Drake1bff34a2000-08-31 19:31:38 +0000830{
Victor Stinner742da042016-09-07 17:40:12 -0700831 assert(mp->ma_values == NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000832 /* Make sure this function doesn't have to handle non-unicode keys,
833 including subclasses of str; e.g., one reason to subclass
834 unicodes is to override __eq__, and for speed we don't cater to
835 that here. */
836 if (!PyUnicode_CheckExact(key)) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400837 mp->ma_keys->dk_lookup = lookdict;
INADA Naoki778928b2017-08-03 23:45:15 +0900838 return lookdict(mp, key, hash, value_addr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000839 }
Tim Peters15d49292001-05-27 07:39:22 +0000840
INADA Naoki778928b2017-08-03 23:45:15 +0900841 PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
842 size_t mask = DK_MASK(mp->ma_keys);
843 size_t perturb = (size_t)hash;
844 size_t i = (size_t)hash & mask;
845
846 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900847 Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
Victor Stinner742da042016-09-07 17:40:12 -0700848 if (ix == DKIX_EMPTY) {
Victor Stinner742da042016-09-07 17:40:12 -0700849 *value_addr = NULL;
850 return DKIX_EMPTY;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400851 }
INADA Naoki778928b2017-08-03 23:45:15 +0900852 if (ix >= 0) {
853 PyDictKeyEntry *ep = &ep0[ix];
854 assert(ep->me_key != NULL);
855 assert(PyUnicode_CheckExact(ep->me_key));
856 if (ep->me_key == key ||
857 (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
858 *value_addr = ep->me_value;
859 return ix;
Victor Stinner742da042016-09-07 17:40:12 -0700860 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400861 }
INADA Naoki778928b2017-08-03 23:45:15 +0900862 perturb >>= PERTURB_SHIFT;
863 i = mask & (i*5 + perturb + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000864 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700865 Py_UNREACHABLE();
Fred Drake1bff34a2000-08-31 19:31:38 +0000866}
867
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400868/* Faster version of lookdict_unicode when it is known that no <dummy> keys
869 * will be present. */
Victor Stinnerc7a8f672016-11-15 15:13:40 +0100870static Py_ssize_t _Py_HOT_FUNCTION
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400871lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900872 Py_hash_t hash, PyObject **value_addr)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400873{
Victor Stinner742da042016-09-07 17:40:12 -0700874 assert(mp->ma_values == NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400875 /* Make sure this function doesn't have to handle non-unicode keys,
876 including subclasses of str; e.g., one reason to subclass
877 unicodes is to override __eq__, and for speed we don't cater to
878 that here. */
879 if (!PyUnicode_CheckExact(key)) {
880 mp->ma_keys->dk_lookup = lookdict;
INADA Naoki778928b2017-08-03 23:45:15 +0900881 return lookdict(mp, key, hash, value_addr);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400882 }
INADA Naoki778928b2017-08-03 23:45:15 +0900883
884 PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
885 size_t mask = DK_MASK(mp->ma_keys);
886 size_t perturb = (size_t)hash;
887 size_t i = (size_t)hash & mask;
888
889 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900890 Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
Victor Stinner742da042016-09-07 17:40:12 -0700891 assert (ix != DKIX_DUMMY);
892 if (ix == DKIX_EMPTY) {
Victor Stinner742da042016-09-07 17:40:12 -0700893 *value_addr = NULL;
894 return DKIX_EMPTY;
895 }
INADA Naoki778928b2017-08-03 23:45:15 +0900896 PyDictKeyEntry *ep = &ep0[ix];
897 assert(ep->me_key != NULL);
898 assert(PyUnicode_CheckExact(ep->me_key));
Victor Stinner742da042016-09-07 17:40:12 -0700899 if (ep->me_key == key ||
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400900 (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
INADA Naokiba609772016-12-07 20:41:42 +0900901 *value_addr = ep->me_value;
Victor Stinner742da042016-09-07 17:40:12 -0700902 return ix;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400903 }
INADA Naoki778928b2017-08-03 23:45:15 +0900904 perturb >>= PERTURB_SHIFT;
905 i = mask & (i*5 + perturb + 1);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400906 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700907 Py_UNREACHABLE();
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400908}
909
910/* Version of lookdict for split tables.
911 * All split tables and only split tables use this lookup function.
912 * Split tables only contain unicode keys and no dummy keys,
913 * so algorithm is the same as lookdict_unicode_nodummy.
914 */
Victor Stinnerc7a8f672016-11-15 15:13:40 +0100915static Py_ssize_t _Py_HOT_FUNCTION
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400916lookdict_split(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900917 Py_hash_t hash, PyObject **value_addr)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400918{
Victor Stinner742da042016-09-07 17:40:12 -0700919 /* mp must split table */
920 assert(mp->ma_values != NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400921 if (!PyUnicode_CheckExact(key)) {
INADA Naoki778928b2017-08-03 23:45:15 +0900922 Py_ssize_t ix = lookdict(mp, key, hash, value_addr);
Victor Stinner742da042016-09-07 17:40:12 -0700923 if (ix >= 0) {
INADA Naokiba609772016-12-07 20:41:42 +0900924 *value_addr = mp->ma_values[ix];
Victor Stinner742da042016-09-07 17:40:12 -0700925 }
926 return ix;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400927 }
Victor Stinner742da042016-09-07 17:40:12 -0700928
INADA Naoki778928b2017-08-03 23:45:15 +0900929 PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
930 size_t mask = DK_MASK(mp->ma_keys);
931 size_t perturb = (size_t)hash;
932 size_t i = (size_t)hash & mask;
933
934 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900935 Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
INADA Naoki778928b2017-08-03 23:45:15 +0900936 assert (ix != DKIX_DUMMY);
Victor Stinner742da042016-09-07 17:40:12 -0700937 if (ix == DKIX_EMPTY) {
Victor Stinner742da042016-09-07 17:40:12 -0700938 *value_addr = NULL;
939 return DKIX_EMPTY;
940 }
INADA Naoki778928b2017-08-03 23:45:15 +0900941 PyDictKeyEntry *ep = &ep0[ix];
942 assert(ep->me_key != NULL);
943 assert(PyUnicode_CheckExact(ep->me_key));
Victor Stinner742da042016-09-07 17:40:12 -0700944 if (ep->me_key == key ||
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400945 (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
INADA Naokiba609772016-12-07 20:41:42 +0900946 *value_addr = mp->ma_values[ix];
Victor Stinner742da042016-09-07 17:40:12 -0700947 return ix;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400948 }
INADA Naoki778928b2017-08-03 23:45:15 +0900949 perturb >>= PERTURB_SHIFT;
950 i = mask & (i*5 + perturb + 1);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400951 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700952 Py_UNREACHABLE();
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400953}
954
Benjamin Petersonfb886362010-04-24 18:21:17 +0000955int
956_PyDict_HasOnlyStringKeys(PyObject *dict)
957{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 Py_ssize_t pos = 0;
959 PyObject *key, *value;
Benjamin Petersonf6096542010-11-17 22:33:12 +0000960 assert(PyDict_Check(dict));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 /* Shortcut */
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400962 if (((PyDictObject *)dict)->ma_keys->dk_lookup != lookdict)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 return 1;
964 while (PyDict_Next(dict, &pos, &key, &value))
965 if (!PyUnicode_Check(key))
966 return 0;
967 return 1;
Benjamin Petersonfb886362010-04-24 18:21:17 +0000968}
969
Antoine Pitrou3a652b12009-03-23 18:52:06 +0000970#define MAINTAIN_TRACKING(mp, key, value) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 do { \
972 if (!_PyObject_GC_IS_TRACKED(mp)) { \
973 if (_PyObject_GC_MAY_BE_TRACKED(key) || \
974 _PyObject_GC_MAY_BE_TRACKED(value)) { \
975 _PyObject_GC_TRACK(mp); \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000976 } \
977 } \
978 } while(0)
Antoine Pitrou3a652b12009-03-23 18:52:06 +0000979
980void
981_PyDict_MaybeUntrack(PyObject *op)
982{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 PyDictObject *mp;
984 PyObject *value;
Victor Stinner742da042016-09-07 17:40:12 -0700985 Py_ssize_t i, numentries;
986 PyDictKeyEntry *ep0;
Antoine Pitrou3a652b12009-03-23 18:52:06 +0000987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 if (!PyDict_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op))
989 return;
990
991 mp = (PyDictObject *) op;
Victor Stinner742da042016-09-07 17:40:12 -0700992 ep0 = DK_ENTRIES(mp->ma_keys);
993 numentries = mp->ma_keys->dk_nentries;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400994 if (_PyDict_HasSplitTable(mp)) {
Victor Stinner742da042016-09-07 17:40:12 -0700995 for (i = 0; i < numentries; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400996 if ((value = mp->ma_values[i]) == NULL)
997 continue;
998 if (_PyObject_GC_MAY_BE_TRACKED(value)) {
Victor Stinner742da042016-09-07 17:40:12 -0700999 assert(!_PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001000 return;
1001 }
1002 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001004 else {
Victor Stinner742da042016-09-07 17:40:12 -07001005 for (i = 0; i < numentries; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001006 if ((value = ep0[i].me_value) == NULL)
1007 continue;
1008 if (_PyObject_GC_MAY_BE_TRACKED(value) ||
1009 _PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key))
1010 return;
1011 }
1012 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001013 _PyObject_GC_UNTRACK(op);
Antoine Pitrou3a652b12009-03-23 18:52:06 +00001014}
1015
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001016/* Internal function to find slot for an item from its hash
Victor Stinner3c336c52016-09-12 14:17:40 +02001017 when it is known that the key is not present in the dict.
1018
1019 The dict must be combined. */
INADA Naokiba609772016-12-07 20:41:42 +09001020static Py_ssize_t
INADA Naoki778928b2017-08-03 23:45:15 +09001021find_empty_slot(PyDictKeysObject *keys, Py_hash_t hash)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001022{
INADA Naoki778928b2017-08-03 23:45:15 +09001023 assert(keys != NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001024
INADA Naoki778928b2017-08-03 23:45:15 +09001025 const size_t mask = DK_MASK(keys);
1026 size_t i = hash & mask;
INADA Naokia7576492018-11-14 18:39:27 +09001027 Py_ssize_t ix = dictkeys_get_index(keys, i);
INADA Naoki778928b2017-08-03 23:45:15 +09001028 for (size_t perturb = hash; ix >= 0;) {
INADA Naoki267941c2016-10-06 15:19:07 +09001029 perturb >>= PERTURB_SHIFT;
INADA Naoki778928b2017-08-03 23:45:15 +09001030 i = (i*5 + perturb + 1) & mask;
INADA Naokia7576492018-11-14 18:39:27 +09001031 ix = dictkeys_get_index(keys, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 }
INADA Naoki778928b2017-08-03 23:45:15 +09001033 return i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001034}
1035
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001036static int
1037insertion_resize(PyDictObject *mp)
1038{
Raymond Hettinger36f74aa2013-05-17 03:01:13 -07001039 return dictresize(mp, GROWTH_RATE(mp));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001040}
Antoine Pitroue965d972012-02-27 00:45:12 +01001041
1042/*
1043Internal routine to insert a new item into the table.
1044Used both by the internal resize routine and by the public insert routine.
Antoine Pitroue965d972012-02-27 00:45:12 +01001045Returns -1 if an error occurred, or 0 on success.
1046*/
1047static int
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001048insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
Antoine Pitroue965d972012-02-27 00:45:12 +01001049{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001050 PyObject *old_value;
INADA Naokiba609772016-12-07 20:41:42 +09001051 PyDictKeyEntry *ep;
Antoine Pitroue965d972012-02-27 00:45:12 +01001052
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001053 Py_INCREF(key);
1054 Py_INCREF(value);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001055 if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) {
1056 if (insertion_resize(mp) < 0)
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001057 goto Fail;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001058 }
1059
INADA Naoki778928b2017-08-03 23:45:15 +09001060 Py_ssize_t ix = mp->ma_keys->dk_lookup(mp, key, hash, &old_value);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001061 if (ix == DKIX_ERROR)
1062 goto Fail;
Victor Stinner742da042016-09-07 17:40:12 -07001063
Antoine Pitroud6967322014-10-18 00:35:00 +02001064 assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001065 MAINTAIN_TRACKING(mp, key, value);
Victor Stinner742da042016-09-07 17:40:12 -07001066
1067 /* When insertion order is different from shared key, we can't share
1068 * the key anymore. Convert this instance to combine table.
1069 */
1070 if (_PyDict_HasSplitTable(mp) &&
INADA Naokiba609772016-12-07 20:41:42 +09001071 ((ix >= 0 && old_value == NULL && mp->ma_used != ix) ||
Victor Stinner742da042016-09-07 17:40:12 -07001072 (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) {
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001073 if (insertion_resize(mp) < 0)
1074 goto Fail;
Victor Stinner742da042016-09-07 17:40:12 -07001075 ix = DKIX_EMPTY;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001076 }
Victor Stinner742da042016-09-07 17:40:12 -07001077
1078 if (ix == DKIX_EMPTY) {
1079 /* Insert into new slot. */
INADA Naokiba609772016-12-07 20:41:42 +09001080 assert(old_value == NULL);
Victor Stinner742da042016-09-07 17:40:12 -07001081 if (mp->ma_keys->dk_usable <= 0) {
1082 /* Need to resize. */
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001083 if (insertion_resize(mp) < 0)
1084 goto Fail;
Victor Stinner742da042016-09-07 17:40:12 -07001085 }
INADA Naoki778928b2017-08-03 23:45:15 +09001086 Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash);
INADA Naokiba609772016-12-07 20:41:42 +09001087 ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries];
INADA Naokia7576492018-11-14 18:39:27 +09001088 dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
Victor Stinner742da042016-09-07 17:40:12 -07001089 ep->me_key = key;
1090 ep->me_hash = hash;
1091 if (mp->ma_values) {
1092 assert (mp->ma_values[mp->ma_keys->dk_nentries] == NULL);
1093 mp->ma_values[mp->ma_keys->dk_nentries] = value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001094 }
1095 else {
Victor Stinner742da042016-09-07 17:40:12 -07001096 ep->me_value = value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001097 }
1098 mp->ma_used++;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07001099 mp->ma_version_tag = DICT_NEXT_VERSION();
Victor Stinner742da042016-09-07 17:40:12 -07001100 mp->ma_keys->dk_usable--;
1101 mp->ma_keys->dk_nentries++;
1102 assert(mp->ma_keys->dk_usable >= 0);
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001103 ASSERT_CONSISTENT(mp);
Victor Stinner742da042016-09-07 17:40:12 -07001104 return 0;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001105 }
Victor Stinner742da042016-09-07 17:40:12 -07001106
Inada Naoki91234a12019-06-03 21:30:58 +09001107 if (old_value != value) {
1108 if (_PyDict_HasSplitTable(mp)) {
1109 mp->ma_values[ix] = value;
1110 if (old_value == NULL) {
1111 /* pending state */
1112 assert(ix == mp->ma_used);
1113 mp->ma_used++;
1114 }
INADA Naokiba609772016-12-07 20:41:42 +09001115 }
Inada Naoki91234a12019-06-03 21:30:58 +09001116 else {
1117 assert(old_value != NULL);
1118 DK_ENTRIES(mp->ma_keys)[ix].me_value = value;
1119 }
1120 mp->ma_version_tag = DICT_NEXT_VERSION();
INADA Naokiba609772016-12-07 20:41:42 +09001121 }
INADA Naokiba609772016-12-07 20:41:42 +09001122 Py_XDECREF(old_value); /* which **CAN** re-enter (see issue #22653) */
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001123 ASSERT_CONSISTENT(mp);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001124 Py_DECREF(key);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001125 return 0;
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001126
1127Fail:
1128 Py_DECREF(value);
1129 Py_DECREF(key);
1130 return -1;
Antoine Pitroue965d972012-02-27 00:45:12 +01001131}
1132
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001133// Same to insertdict but specialized for ma_keys = Py_EMPTY_KEYS.
1134static int
1135insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash,
1136 PyObject *value)
1137{
1138 assert(mp->ma_keys == Py_EMPTY_KEYS);
1139
1140 PyDictKeysObject *newkeys = new_keys_object(PyDict_MINSIZE);
1141 if (newkeys == NULL) {
1142 return -1;
1143 }
1144 if (!PyUnicode_CheckExact(key)) {
1145 newkeys->dk_lookup = lookdict;
1146 }
1147 dictkeys_decref(Py_EMPTY_KEYS);
1148 mp->ma_keys = newkeys;
1149 mp->ma_values = NULL;
1150
1151 Py_INCREF(key);
1152 Py_INCREF(value);
1153 MAINTAIN_TRACKING(mp, key, value);
1154
1155 size_t hashpos = (size_t)hash & (PyDict_MINSIZE-1);
Dong-hee Nac39d1dd2019-10-11 17:43:11 +09001156 PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys);
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001157 dictkeys_set_index(mp->ma_keys, hashpos, 0);
1158 ep->me_key = key;
1159 ep->me_hash = hash;
1160 ep->me_value = value;
1161 mp->ma_used++;
1162 mp->ma_version_tag = DICT_NEXT_VERSION();
1163 mp->ma_keys->dk_usable--;
1164 mp->ma_keys->dk_nentries++;
1165 return 0;
1166}
1167
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001168/*
luzpaza5293b42017-11-05 07:37:50 -06001169Internal routine used by dictresize() to build a hashtable of entries.
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001170*/
1171static void
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001172build_indices(PyDictKeysObject *keys, PyDictKeyEntry *ep, Py_ssize_t n)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001173{
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001174 size_t mask = (size_t)DK_SIZE(keys) - 1;
1175 for (Py_ssize_t ix = 0; ix != n; ix++, ep++) {
1176 Py_hash_t hash = ep->me_hash;
1177 size_t i = hash & mask;
INADA Naokia7576492018-11-14 18:39:27 +09001178 for (size_t perturb = hash; dictkeys_get_index(keys, i) != DKIX_EMPTY;) {
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001179 perturb >>= PERTURB_SHIFT;
INADA Naoki870c2862017-06-24 09:03:19 +09001180 i = mask & (i*5 + perturb + 1);
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001181 }
INADA Naokia7576492018-11-14 18:39:27 +09001182 dictkeys_set_index(keys, i, ix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001184}
1185
1186/*
1187Restructure the table by allocating a new table and reinserting all
1188items again. When entries have been deleted, the new table may
1189actually be smaller than the old one.
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001190If a table is split (its keys and hashes are shared, its values are not),
1191then the values are temporarily copied into the table, it is resized as
1192a combined table, then the me_value slots in the old table are NULLed out.
1193After resizing a table is always combined,
1194but can be resplit by make_keys_shared().
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001195*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001196static int
Victor Stinner3d3f2642016-12-15 17:21:23 +01001197dictresize(PyDictObject *mp, Py_ssize_t minsize)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001198{
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001199 Py_ssize_t newsize, numentries;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001200 PyDictKeysObject *oldkeys;
1201 PyObject **oldvalues;
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001202 PyDictKeyEntry *oldentries, *newentries;
Tim Peters91a364d2001-05-19 07:04:38 +00001203
Victor Stinner742da042016-09-07 17:40:12 -07001204 /* Find the smallest table size > minused. */
1205 for (newsize = PyDict_MINSIZE;
Victor Stinner3d3f2642016-12-15 17:21:23 +01001206 newsize < minsize && newsize > 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 newsize <<= 1)
1208 ;
1209 if (newsize <= 0) {
1210 PyErr_NoMemory();
1211 return -1;
1212 }
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001213
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001214 oldkeys = mp->ma_keys;
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001215
1216 /* NOTE: Current odict checks mp->ma_keys to detect resize happen.
1217 * So we can't reuse oldkeys even if oldkeys->dk_size == newsize.
1218 * TODO: Try reusing oldkeys when reimplement odict.
1219 */
1220
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001221 /* Allocate a new table. */
1222 mp->ma_keys = new_keys_object(newsize);
1223 if (mp->ma_keys == NULL) {
1224 mp->ma_keys = oldkeys;
1225 return -1;
1226 }
Victor Stinner3d3f2642016-12-15 17:21:23 +01001227 // New table must be large enough.
1228 assert(mp->ma_keys->dk_usable >= mp->ma_used);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001229 if (oldkeys->dk_lookup == lookdict)
1230 mp->ma_keys->dk_lookup = lookdict;
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001231
1232 numentries = mp->ma_used;
1233 oldentries = DK_ENTRIES(oldkeys);
1234 newentries = DK_ENTRIES(mp->ma_keys);
1235 oldvalues = mp->ma_values;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001236 if (oldvalues != NULL) {
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001237 /* Convert split table into new combined table.
1238 * We must incref keys; we can transfer values.
1239 * Note that values of split table is always dense.
1240 */
1241 for (Py_ssize_t i = 0; i < numentries; i++) {
1242 assert(oldvalues[i] != NULL);
1243 PyDictKeyEntry *ep = &oldentries[i];
1244 PyObject *key = ep->me_key;
1245 Py_INCREF(key);
1246 newentries[i].me_key = key;
1247 newentries[i].me_hash = ep->me_hash;
1248 newentries[i].me_value = oldvalues[i];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 }
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001250
INADA Naokia7576492018-11-14 18:39:27 +09001251 dictkeys_decref(oldkeys);
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001252 mp->ma_values = NULL;
Victor Stinner742da042016-09-07 17:40:12 -07001253 if (oldvalues != empty_values) {
1254 free_values(oldvalues);
1255 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001256 }
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001257 else { // combined table.
1258 if (oldkeys->dk_nentries == numentries) {
1259 memcpy(newentries, oldentries, numentries * sizeof(PyDictKeyEntry));
1260 }
1261 else {
1262 PyDictKeyEntry *ep = oldentries;
1263 for (Py_ssize_t i = 0; i < numentries; i++) {
1264 while (ep->me_value == NULL)
1265 ep++;
1266 newentries[i] = *ep++;
1267 }
1268 }
1269
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001270 assert(oldkeys->dk_lookup != lookdict_split);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001271 assert(oldkeys->dk_refcnt == 1);
Victor Stinner49932fe2020-02-03 17:55:05 +01001272#ifdef Py_REF_DEBUG
1273 _Py_RefTotal--;
1274#endif
Victor Stinner522691c2020-06-23 16:40:40 +02001275 struct _Py_dict_state *state = get_dict_state();
Victor Stinnerb4e85ca2020-06-23 11:33:18 +02001276#ifdef Py_DEBUG
1277 // dictresize() must not be called after _PyDict_Fini()
1278 assert(state->keys_numfree != -1);
Victor Stinnerb4b53862020-05-05 19:55:29 +02001279#endif
Victor Stinnerb4e85ca2020-06-23 11:33:18 +02001280 if (oldkeys->dk_size == PyDict_MINSIZE &&
1281 state->keys_numfree < PyDict_MAXFREELIST)
Victor Stinnerb4b53862020-05-05 19:55:29 +02001282 {
Victor Stinnerb4e85ca2020-06-23 11:33:18 +02001283 state->keys_free_list[state->keys_numfree++] = oldkeys;
1284 }
1285 else {
INADA Naokia7576492018-11-14 18:39:27 +09001286 PyObject_FREE(oldkeys);
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001287 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001288 }
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001289
1290 build_indices(mp->ma_keys, newentries, numentries);
1291 mp->ma_keys->dk_usable -= numentries;
1292 mp->ma_keys->dk_nentries = numentries;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 return 0;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001294}
1295
Benjamin Peterson15ee8212012-04-24 14:44:18 -04001296/* Returns NULL if unable to split table.
1297 * A NULL return does not necessarily indicate an error */
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001298static PyDictKeysObject *
1299make_keys_shared(PyObject *op)
1300{
1301 Py_ssize_t i;
1302 Py_ssize_t size;
1303 PyDictObject *mp = (PyDictObject *)op;
1304
Benjamin Peterson15ee8212012-04-24 14:44:18 -04001305 if (!PyDict_CheckExact(op))
1306 return NULL;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001307 if (!_PyDict_HasSplitTable(mp)) {
1308 PyDictKeyEntry *ep0;
1309 PyObject **values;
1310 assert(mp->ma_keys->dk_refcnt == 1);
1311 if (mp->ma_keys->dk_lookup == lookdict) {
1312 return NULL;
1313 }
1314 else if (mp->ma_keys->dk_lookup == lookdict_unicode) {
1315 /* Remove dummy keys */
1316 if (dictresize(mp, DK_SIZE(mp->ma_keys)))
1317 return NULL;
1318 }
1319 assert(mp->ma_keys->dk_lookup == lookdict_unicode_nodummy);
1320 /* Copy values into a new array */
Victor Stinner742da042016-09-07 17:40:12 -07001321 ep0 = DK_ENTRIES(mp->ma_keys);
1322 size = USABLE_FRACTION(DK_SIZE(mp->ma_keys));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001323 values = new_values(size);
1324 if (values == NULL) {
1325 PyErr_SetString(PyExc_MemoryError,
1326 "Not enough memory to allocate new values array");
1327 return NULL;
1328 }
1329 for (i = 0; i < size; i++) {
1330 values[i] = ep0[i].me_value;
1331 ep0[i].me_value = NULL;
1332 }
1333 mp->ma_keys->dk_lookup = lookdict_split;
1334 mp->ma_values = values;
1335 }
INADA Naokia7576492018-11-14 18:39:27 +09001336 dictkeys_incref(mp->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001337 return mp->ma_keys;
1338}
Christian Heimes99170a52007-12-19 02:07:34 +00001339
1340PyObject *
1341_PyDict_NewPresized(Py_ssize_t minused)
1342{
INADA Naoki92c50ee2016-11-22 00:57:02 +09001343 const Py_ssize_t max_presize = 128 * 1024;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001344 Py_ssize_t newsize;
1345 PyDictKeysObject *new_keys;
INADA Naoki92c50ee2016-11-22 00:57:02 +09001346
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001347 if (minused <= USABLE_FRACTION(PyDict_MINSIZE)) {
Inada Naokif2a18672019-03-12 17:25:44 +09001348 return PyDict_New();
1349 }
INADA Naoki92c50ee2016-11-22 00:57:02 +09001350 /* There are no strict guarantee that returned dict can contain minused
1351 * items without resize. So we create medium size dict instead of very
1352 * large dict or MemoryError.
1353 */
1354 if (minused > USABLE_FRACTION(max_presize)) {
1355 newsize = max_presize;
1356 }
1357 else {
1358 Py_ssize_t minsize = ESTIMATE_SIZE(minused);
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001359 newsize = PyDict_MINSIZE*2;
INADA Naoki92c50ee2016-11-22 00:57:02 +09001360 while (newsize < minsize) {
1361 newsize <<= 1;
1362 }
1363 }
1364 assert(IS_POWER_OF_2(newsize));
1365
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001366 new_keys = new_keys_object(newsize);
1367 if (new_keys == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 return NULL;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001369 return new_dict(new_keys, NULL);
Christian Heimes99170a52007-12-19 02:07:34 +00001370}
1371
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001372/* Note that, for historical reasons, PyDict_GetItem() suppresses all errors
1373 * that may occur (originally dicts supported only string keys, and exceptions
1374 * weren't possible). So, while the original intent was that a NULL return
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001375 * meant the key wasn't present, in reality it can mean that, or that an error
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001376 * (suppressed) occurred while computing the key's hash, or that some error
1377 * (suppressed) occurred when comparing keys in the dict's internal probe
1378 * sequence. A nasty example of the latter is when a Python-coded comparison
1379 * function hits a stack-depth error, which can cause this to return NULL
1380 * even if the key is present.
1381 */
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001382PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00001383PyDict_GetItem(PyObject *op, PyObject *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001384{
Victor Stinner59d3dce2020-06-02 14:03:25 +02001385 if (!PyDict_Check(op)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 return NULL;
Victor Stinner59d3dce2020-06-02 14:03:25 +02001387 }
1388 PyDictObject *mp = (PyDictObject *)op;
1389
1390 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001392 (hash = ((PyASCIIObject *) key)->hash) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 {
1394 hash = PyObject_Hash(key);
1395 if (hash == -1) {
1396 PyErr_Clear();
1397 return NULL;
1398 }
1399 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001400
Victor Stinner59d3dce2020-06-02 14:03:25 +02001401 PyThreadState *tstate = _PyThreadState_GET();
1402#ifdef Py_DEBUG
1403 // bpo-40839: Before Python 3.10, it was possible to call PyDict_GetItem()
1404 // with the GIL released.
1405 _Py_EnsureTstateNotNULL(tstate);
1406#endif
1407
1408 /* Preserve the existing exception */
1409 PyObject *exc_type, *exc_value, *exc_tb;
1410 PyObject *value;
1411 Py_ssize_t ix;
1412
1413 _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
1414 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
1415
1416 /* Ignore any exception raised by the lookup */
1417 _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
1418
1419 if (ix < 0) {
1420 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 }
INADA Naokiba609772016-12-07 20:41:42 +09001422 return value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001423}
1424
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02001425/* Same as PyDict_GetItemWithError() but with hash supplied by caller.
1426 This returns NULL *with* an exception set if an exception occurred.
1427 It returns NULL *without* an exception set if the key wasn't present.
1428*/
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001429PyObject *
1430_PyDict_GetItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
1431{
Victor Stinner742da042016-09-07 17:40:12 -07001432 Py_ssize_t ix;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001433 PyDictObject *mp = (PyDictObject *)op;
INADA Naokiba609772016-12-07 20:41:42 +09001434 PyObject *value;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001435
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02001436 if (!PyDict_Check(op)) {
1437 PyErr_BadInternalCall();
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001438 return NULL;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001439 }
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02001440
INADA Naoki778928b2017-08-03 23:45:15 +09001441 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02001442 if (ix < 0) {
1443 return NULL;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001444 }
INADA Naokiba609772016-12-07 20:41:42 +09001445 return value;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001446}
1447
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001448/* Variant of PyDict_GetItem() that doesn't suppress exceptions.
1449 This returns NULL *with* an exception set if an exception occurred.
1450 It returns NULL *without* an exception set if the key wasn't present.
1451*/
1452PyObject *
1453PyDict_GetItemWithError(PyObject *op, PyObject *key)
1454{
Victor Stinner742da042016-09-07 17:40:12 -07001455 Py_ssize_t ix;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001456 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 PyDictObject*mp = (PyDictObject *)op;
INADA Naokiba609772016-12-07 20:41:42 +09001458 PyObject *value;
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 if (!PyDict_Check(op)) {
1461 PyErr_BadInternalCall();
1462 return NULL;
1463 }
1464 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001465 (hash = ((PyASCIIObject *) key)->hash) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 {
1467 hash = PyObject_Hash(key);
1468 if (hash == -1) {
1469 return NULL;
1470 }
1471 }
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001472
INADA Naoki778928b2017-08-03 23:45:15 +09001473 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07001474 if (ix < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001476 return value;
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001477}
1478
Brett Cannonfd074152012-04-14 14:10:13 -04001479PyObject *
1480_PyDict_GetItemIdWithError(PyObject *dp, struct _Py_Identifier *key)
1481{
1482 PyObject *kv;
1483 kv = _PyUnicode_FromId(key); /* borrowed */
1484 if (kv == NULL)
1485 return NULL;
scoder6067d4b2020-05-11 06:04:31 +02001486 Py_hash_t hash = ((PyASCIIObject *) kv)->hash;
1487 assert (hash != -1); /* interned strings have their hash value initialised */
1488 return _PyDict_GetItem_KnownHash(dp, kv, hash);
Brett Cannonfd074152012-04-14 14:10:13 -04001489}
1490
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001491PyObject *
1492_PyDict_GetItemStringWithError(PyObject *v, const char *key)
1493{
1494 PyObject *kv, *rv;
1495 kv = PyUnicode_FromString(key);
1496 if (kv == NULL) {
1497 return NULL;
1498 }
1499 rv = PyDict_GetItemWithError(v, kv);
1500 Py_DECREF(kv);
1501 return rv;
1502}
1503
Victor Stinnerb4efc962015-11-20 09:24:02 +01001504/* Fast version of global value lookup (LOAD_GLOBAL).
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001505 * Lookup in globals, then builtins.
Victor Stinnerb4efc962015-11-20 09:24:02 +01001506 *
1507 * Raise an exception and return NULL if an error occurred (ex: computing the
1508 * key hash failed, key comparison failed, ...). Return NULL if the key doesn't
1509 * exist. Return the value if the key exists.
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001510 */
1511PyObject *
1512_PyDict_LoadGlobal(PyDictObject *globals, PyDictObject *builtins, PyObject *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001513{
Victor Stinner742da042016-09-07 17:40:12 -07001514 Py_ssize_t ix;
Victor Stinnerb4efc962015-11-20 09:24:02 +01001515 Py_hash_t hash;
INADA Naokiba609772016-12-07 20:41:42 +09001516 PyObject *value;
Victor Stinnerb4efc962015-11-20 09:24:02 +01001517
1518 if (!PyUnicode_CheckExact(key) ||
1519 (hash = ((PyASCIIObject *) key)->hash) == -1)
1520 {
1521 hash = PyObject_Hash(key);
1522 if (hash == -1)
1523 return NULL;
Antoine Pitroue965d972012-02-27 00:45:12 +01001524 }
Victor Stinnerb4efc962015-11-20 09:24:02 +01001525
1526 /* namespace 1: globals */
INADA Naoki778928b2017-08-03 23:45:15 +09001527 ix = globals->ma_keys->dk_lookup(globals, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07001528 if (ix == DKIX_ERROR)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001529 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001530 if (ix != DKIX_EMPTY && value != NULL)
1531 return value;
Victor Stinnerb4efc962015-11-20 09:24:02 +01001532
1533 /* namespace 2: builtins */
INADA Naoki778928b2017-08-03 23:45:15 +09001534 ix = builtins->ma_keys->dk_lookup(builtins, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07001535 if (ix < 0)
Victor Stinnerb4efc962015-11-20 09:24:02 +01001536 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001537 return value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001538}
1539
Antoine Pitroue965d972012-02-27 00:45:12 +01001540/* CAUTION: PyDict_SetItem() must guarantee that it won't resize the
1541 * dictionary if it's merely replacing the value for an existing key.
1542 * This means that it's safe to loop over a dictionary with PyDict_Next()
1543 * and occasionally replace a value -- but you can't insert new keys or
1544 * remove them.
1545 */
1546int
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001547PyDict_SetItem(PyObject *op, PyObject *key, PyObject *value)
Antoine Pitroue965d972012-02-27 00:45:12 +01001548{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001549 PyDictObject *mp;
1550 Py_hash_t hash;
Antoine Pitroue965d972012-02-27 00:45:12 +01001551 if (!PyDict_Check(op)) {
1552 PyErr_BadInternalCall();
1553 return -1;
1554 }
1555 assert(key);
1556 assert(value);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001557 mp = (PyDictObject *)op;
1558 if (!PyUnicode_CheckExact(key) ||
1559 (hash = ((PyASCIIObject *) key)->hash) == -1)
1560 {
Antoine Pitroue965d972012-02-27 00:45:12 +01001561 hash = PyObject_Hash(key);
1562 if (hash == -1)
1563 return -1;
1564 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001565
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001566 if (mp->ma_keys == Py_EMPTY_KEYS) {
1567 return insert_to_emptydict(mp, key, hash, value);
1568 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001569 /* insertdict() handles any resizing that might be necessary */
1570 return insertdict(mp, key, hash, value);
Antoine Pitroue965d972012-02-27 00:45:12 +01001571}
1572
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001573int
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001574_PyDict_SetItem_KnownHash(PyObject *op, PyObject *key, PyObject *value,
1575 Py_hash_t hash)
1576{
1577 PyDictObject *mp;
1578
1579 if (!PyDict_Check(op)) {
1580 PyErr_BadInternalCall();
1581 return -1;
1582 }
1583 assert(key);
1584 assert(value);
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001585 assert(hash != -1);
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001586 mp = (PyDictObject *)op;
1587
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001588 if (mp->ma_keys == Py_EMPTY_KEYS) {
1589 return insert_to_emptydict(mp, key, hash, value);
1590 }
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001591 /* insertdict() handles any resizing that might be necessary */
1592 return insertdict(mp, key, hash, value);
1593}
1594
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001595static int
INADA Naoki778928b2017-08-03 23:45:15 +09001596delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix,
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001597 PyObject *old_value)
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001598{
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001599 PyObject *old_key;
Antoine Pitroud741ed42016-12-27 14:23:43 +01001600 PyDictKeyEntry *ep;
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001601
INADA Naoki778928b2017-08-03 23:45:15 +09001602 Py_ssize_t hashpos = lookdict_index(mp->ma_keys, hash, ix);
1603 assert(hashpos >= 0);
1604
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001605 mp->ma_used--;
Antoine Pitroud741ed42016-12-27 14:23:43 +01001606 mp->ma_version_tag = DICT_NEXT_VERSION();
1607 ep = &DK_ENTRIES(mp->ma_keys)[ix];
INADA Naokia7576492018-11-14 18:39:27 +09001608 dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
Antoine Pitroud741ed42016-12-27 14:23:43 +01001609 ENSURE_ALLOWS_DELETIONS(mp);
1610 old_key = ep->me_key;
1611 ep->me_key = NULL;
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001612 ep->me_value = NULL;
Antoine Pitroud741ed42016-12-27 14:23:43 +01001613 Py_DECREF(old_key);
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001614 Py_DECREF(old_value);
Antoine Pitroud741ed42016-12-27 14:23:43 +01001615
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001616 ASSERT_CONSISTENT(mp);
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001617 return 0;
1618}
1619
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001620int
Tim Peters1f5871e2000-07-04 17:44:48 +00001621PyDict_DelItem(PyObject *op, PyObject *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001622{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001623 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 assert(key);
1625 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001626 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 hash = PyObject_Hash(key);
1628 if (hash == -1)
1629 return -1;
1630 }
Victor Stinner742da042016-09-07 17:40:12 -07001631
1632 return _PyDict_DelItem_KnownHash(op, key, hash);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001633}
1634
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001635int
1636_PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
1637{
INADA Naoki778928b2017-08-03 23:45:15 +09001638 Py_ssize_t ix;
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001639 PyDictObject *mp;
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001640 PyObject *old_value;
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001641
1642 if (!PyDict_Check(op)) {
1643 PyErr_BadInternalCall();
1644 return -1;
1645 }
1646 assert(key);
1647 assert(hash != -1);
1648 mp = (PyDictObject *)op;
INADA Naoki778928b2017-08-03 23:45:15 +09001649 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Victor Stinner742da042016-09-07 17:40:12 -07001650 if (ix == DKIX_ERROR)
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001651 return -1;
INADA Naokiba609772016-12-07 20:41:42 +09001652 if (ix == DKIX_EMPTY || old_value == NULL) {
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001653 _PyErr_SetKeyError(key);
1654 return -1;
1655 }
Victor Stinner78601a32016-09-09 19:28:36 -07001656
1657 // Split table doesn't allow deletion. Combine it.
1658 if (_PyDict_HasSplitTable(mp)) {
1659 if (dictresize(mp, DK_SIZE(mp->ma_keys))) {
1660 return -1;
1661 }
INADA Naoki778928b2017-08-03 23:45:15 +09001662 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Victor Stinner78601a32016-09-09 19:28:36 -07001663 assert(ix >= 0);
1664 }
1665
INADA Naoki778928b2017-08-03 23:45:15 +09001666 return delitem_common(mp, hash, ix, old_value);
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001667}
1668
Antoine Pitroud741ed42016-12-27 14:23:43 +01001669/* This function promises that the predicate -> deletion sequence is atomic
1670 * (i.e. protected by the GIL), assuming the predicate itself doesn't
1671 * release the GIL.
1672 */
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001673int
1674_PyDict_DelItemIf(PyObject *op, PyObject *key,
1675 int (*predicate)(PyObject *value))
1676{
Antoine Pitroud741ed42016-12-27 14:23:43 +01001677 Py_ssize_t hashpos, ix;
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001678 PyDictObject *mp;
1679 Py_hash_t hash;
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001680 PyObject *old_value;
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001681 int res;
1682
1683 if (!PyDict_Check(op)) {
1684 PyErr_BadInternalCall();
1685 return -1;
1686 }
1687 assert(key);
1688 hash = PyObject_Hash(key);
1689 if (hash == -1)
1690 return -1;
1691 mp = (PyDictObject *)op;
INADA Naoki778928b2017-08-03 23:45:15 +09001692 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Antoine Pitroud741ed42016-12-27 14:23:43 +01001693 if (ix == DKIX_ERROR)
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001694 return -1;
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001695 if (ix == DKIX_EMPTY || old_value == NULL) {
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001696 _PyErr_SetKeyError(key);
1697 return -1;
1698 }
Antoine Pitroud741ed42016-12-27 14:23:43 +01001699
1700 // Split table doesn't allow deletion. Combine it.
1701 if (_PyDict_HasSplitTable(mp)) {
1702 if (dictresize(mp, DK_SIZE(mp->ma_keys))) {
1703 return -1;
1704 }
INADA Naoki778928b2017-08-03 23:45:15 +09001705 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Antoine Pitroud741ed42016-12-27 14:23:43 +01001706 assert(ix >= 0);
1707 }
1708
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001709 res = predicate(old_value);
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001710 if (res == -1)
1711 return -1;
INADA Naoki778928b2017-08-03 23:45:15 +09001712
1713 hashpos = lookdict_index(mp->ma_keys, hash, ix);
1714 assert(hashpos >= 0);
1715
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001716 if (res > 0)
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001717 return delitem_common(mp, hashpos, ix, old_value);
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001718 else
1719 return 0;
1720}
1721
1722
Guido van Rossum25831651993-05-19 14:50:45 +00001723void
Tim Peters1f5871e2000-07-04 17:44:48 +00001724PyDict_Clear(PyObject *op)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001725{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001726 PyDictObject *mp;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001727 PyDictKeysObject *oldkeys;
1728 PyObject **oldvalues;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001729 Py_ssize_t i, n;
Tim Petersdea48ec2001-05-22 20:40:22 +00001730
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001731 if (!PyDict_Check(op))
1732 return;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001733 mp = ((PyDictObject *)op);
1734 oldkeys = mp->ma_keys;
1735 oldvalues = mp->ma_values;
1736 if (oldvalues == empty_values)
1737 return;
1738 /* Empty the dict... */
INADA Naokia7576492018-11-14 18:39:27 +09001739 dictkeys_incref(Py_EMPTY_KEYS);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001740 mp->ma_keys = Py_EMPTY_KEYS;
1741 mp->ma_values = empty_values;
1742 mp->ma_used = 0;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07001743 mp->ma_version_tag = DICT_NEXT_VERSION();
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001744 /* ...then clear the keys and values */
1745 if (oldvalues != NULL) {
Victor Stinner742da042016-09-07 17:40:12 -07001746 n = oldkeys->dk_nentries;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001747 for (i = 0; i < n; i++)
1748 Py_CLEAR(oldvalues[i]);
1749 free_values(oldvalues);
INADA Naokia7576492018-11-14 18:39:27 +09001750 dictkeys_decref(oldkeys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001751 }
1752 else {
1753 assert(oldkeys->dk_refcnt == 1);
INADA Naokia7576492018-11-14 18:39:27 +09001754 dictkeys_decref(oldkeys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001755 }
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001756 ASSERT_CONSISTENT(mp);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001757}
1758
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001759/* Internal version of PyDict_Next that returns a hash value in addition
1760 * to the key and value.
1761 * Return 1 on success, return 0 when the reached the end of the dictionary
1762 * (or if op is not a dictionary)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001763 */
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001764int
1765_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
1766 PyObject **pvalue, Py_hash_t *phash)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001767{
INADA Naokica2d8be2016-11-04 16:59:10 +09001768 Py_ssize_t i;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001769 PyDictObject *mp;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001770 PyDictKeyEntry *entry_ptr;
1771 PyObject *value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001772
1773 if (!PyDict_Check(op))
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001774 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 mp = (PyDictObject *)op;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001776 i = *ppos;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001777 if (mp->ma_values) {
INADA Naokica2d8be2016-11-04 16:59:10 +09001778 if (i < 0 || i >= mp->ma_used)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001779 return 0;
INADA Naokica2d8be2016-11-04 16:59:10 +09001780 /* values of split table is always dense */
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001781 entry_ptr = &DK_ENTRIES(mp->ma_keys)[i];
INADA Naokica2d8be2016-11-04 16:59:10 +09001782 value = mp->ma_values[i];
1783 assert(value != NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001785 else {
INADA Naokica2d8be2016-11-04 16:59:10 +09001786 Py_ssize_t n = mp->ma_keys->dk_nentries;
1787 if (i < 0 || i >= n)
1788 return 0;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001789 entry_ptr = &DK_ENTRIES(mp->ma_keys)[i];
1790 while (i < n && entry_ptr->me_value == NULL) {
1791 entry_ptr++;
1792 i++;
Victor Stinner742da042016-09-07 17:40:12 -07001793 }
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001794 if (i >= n)
1795 return 0;
1796 value = entry_ptr->me_value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 }
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001798 *ppos = i+1;
1799 if (pkey)
1800 *pkey = entry_ptr->me_key;
1801 if (phash)
1802 *phash = entry_ptr->me_hash;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001803 if (pvalue)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001804 *pvalue = value;
1805 return 1;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001806}
1807
Tim Peters080c88b2003-02-15 03:01:11 +00001808/*
1809 * Iterate over a dict. Use like so:
1810 *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001811 * Py_ssize_t i;
Tim Peters080c88b2003-02-15 03:01:11 +00001812 * PyObject *key, *value;
1813 * i = 0; # important! i should not otherwise be changed by you
Neal Norwitz07323012003-02-15 14:45:12 +00001814 * while (PyDict_Next(yourdict, &i, &key, &value)) {
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001815 * Refer to borrowed references in key and value.
Tim Peters080c88b2003-02-15 03:01:11 +00001816 * }
1817 *
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001818 * Return 1 on success, return 0 when the reached the end of the dictionary
1819 * (or if op is not a dictionary)
1820 *
Tim Peters080c88b2003-02-15 03:01:11 +00001821 * CAUTION: In general, it isn't safe to use PyDict_Next in a loop that
Tim Peters67830702001-03-21 19:23:56 +00001822 * mutates the dict. One exception: it is safe if the loop merely changes
1823 * the values associated with the keys (but doesn't insert new keys or
1824 * delete keys), via PyDict_SetItem().
1825 */
Guido van Rossum25831651993-05-19 14:50:45 +00001826int
Martin v. Löwis18e16552006-02-15 17:27:45 +00001827PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001828{
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001829 return _PyDict_Next(op, ppos, pkey, pvalue, NULL);
Thomas Wouterscf297e42007-02-23 15:07:44 +00001830}
1831
Eric Snow96c6af92015-05-29 22:21:39 -06001832/* Internal version of dict.pop(). */
1833PyObject *
Serhiy Storchaka42e1ea92017-01-12 19:12:21 +02001834_PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *deflt)
Eric Snow96c6af92015-05-29 22:21:39 -06001835{
Victor Stinner742da042016-09-07 17:40:12 -07001836 Py_ssize_t ix, hashpos;
Eric Snow96c6af92015-05-29 22:21:39 -06001837 PyObject *old_value, *old_key;
1838 PyDictKeyEntry *ep;
Yury Selivanov684ef2c2016-10-28 19:01:21 -04001839 PyDictObject *mp;
1840
1841 assert(PyDict_Check(dict));
1842 mp = (PyDictObject *)dict;
Eric Snow96c6af92015-05-29 22:21:39 -06001843
1844 if (mp->ma_used == 0) {
1845 if (deflt) {
1846 Py_INCREF(deflt);
1847 return deflt;
1848 }
1849 _PyErr_SetKeyError(key);
1850 return NULL;
1851 }
INADA Naoki778928b2017-08-03 23:45:15 +09001852 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Victor Stinner742da042016-09-07 17:40:12 -07001853 if (ix == DKIX_ERROR)
Eric Snow96c6af92015-05-29 22:21:39 -06001854 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001855 if (ix == DKIX_EMPTY || old_value == NULL) {
Eric Snow96c6af92015-05-29 22:21:39 -06001856 if (deflt) {
1857 Py_INCREF(deflt);
1858 return deflt;
1859 }
1860 _PyErr_SetKeyError(key);
1861 return NULL;
1862 }
Victor Stinner3b6a6b42016-09-08 12:51:24 -07001863
Victor Stinner78601a32016-09-09 19:28:36 -07001864 // Split table doesn't allow deletion. Combine it.
1865 if (_PyDict_HasSplitTable(mp)) {
1866 if (dictresize(mp, DK_SIZE(mp->ma_keys))) {
1867 return NULL;
1868 }
INADA Naoki778928b2017-08-03 23:45:15 +09001869 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Victor Stinner78601a32016-09-09 19:28:36 -07001870 assert(ix >= 0);
1871 }
1872
INADA Naoki778928b2017-08-03 23:45:15 +09001873 hashpos = lookdict_index(mp->ma_keys, hash, ix);
1874 assert(hashpos >= 0);
Victor Stinner78601a32016-09-09 19:28:36 -07001875 assert(old_value != NULL);
Eric Snow96c6af92015-05-29 22:21:39 -06001876 mp->ma_used--;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07001877 mp->ma_version_tag = DICT_NEXT_VERSION();
INADA Naokia7576492018-11-14 18:39:27 +09001878 dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
Victor Stinner78601a32016-09-09 19:28:36 -07001879 ep = &DK_ENTRIES(mp->ma_keys)[ix];
1880 ENSURE_ALLOWS_DELETIONS(mp);
1881 old_key = ep->me_key;
1882 ep->me_key = NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001883 ep->me_value = NULL;
Victor Stinner78601a32016-09-09 19:28:36 -07001884 Py_DECREF(old_key);
Victor Stinner611b0fa2016-09-14 15:02:01 +02001885
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001886 ASSERT_CONSISTENT(mp);
Eric Snow96c6af92015-05-29 22:21:39 -06001887 return old_value;
1888}
1889
Serhiy Storchaka67796522017-01-12 18:34:33 +02001890PyObject *
Serhiy Storchaka42e1ea92017-01-12 19:12:21 +02001891_PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt)
Serhiy Storchaka67796522017-01-12 18:34:33 +02001892{
1893 Py_hash_t hash;
1894
Serhiy Storchaka42e1ea92017-01-12 19:12:21 +02001895 if (((PyDictObject *)dict)->ma_used == 0) {
Serhiy Storchaka67796522017-01-12 18:34:33 +02001896 if (deflt) {
1897 Py_INCREF(deflt);
1898 return deflt;
1899 }
1900 _PyErr_SetKeyError(key);
1901 return NULL;
1902 }
1903 if (!PyUnicode_CheckExact(key) ||
1904 (hash = ((PyASCIIObject *) key)->hash) == -1) {
1905 hash = PyObject_Hash(key);
1906 if (hash == -1)
1907 return NULL;
1908 }
Serhiy Storchaka42e1ea92017-01-12 19:12:21 +02001909 return _PyDict_Pop_KnownHash(dict, key, hash, deflt);
Serhiy Storchaka67796522017-01-12 18:34:33 +02001910}
1911
Eric Snow96c6af92015-05-29 22:21:39 -06001912/* Internal version of dict.from_keys(). It is subclass-friendly. */
1913PyObject *
1914_PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)
1915{
1916 PyObject *it; /* iter(iterable) */
1917 PyObject *key;
1918 PyObject *d;
1919 int status;
1920
Victor Stinnera5ed5f02016-12-06 18:45:50 +01001921 d = _PyObject_CallNoArg(cls);
Eric Snow96c6af92015-05-29 22:21:39 -06001922 if (d == NULL)
1923 return NULL;
1924
1925 if (PyDict_CheckExact(d) && ((PyDictObject *)d)->ma_used == 0) {
1926 if (PyDict_CheckExact(iterable)) {
1927 PyDictObject *mp = (PyDictObject *)d;
1928 PyObject *oldvalue;
1929 Py_ssize_t pos = 0;
1930 PyObject *key;
1931 Py_hash_t hash;
1932
Serhiy Storchakac61ac162017-03-21 08:52:38 +02001933 if (dictresize(mp, ESTIMATE_SIZE(PyDict_GET_SIZE(iterable)))) {
Eric Snow96c6af92015-05-29 22:21:39 -06001934 Py_DECREF(d);
1935 return NULL;
1936 }
1937
1938 while (_PyDict_Next(iterable, &pos, &key, &oldvalue, &hash)) {
1939 if (insertdict(mp, key, hash, value)) {
1940 Py_DECREF(d);
1941 return NULL;
1942 }
1943 }
1944 return d;
1945 }
1946 if (PyAnySet_CheckExact(iterable)) {
1947 PyDictObject *mp = (PyDictObject *)d;
1948 Py_ssize_t pos = 0;
1949 PyObject *key;
1950 Py_hash_t hash;
1951
Victor Stinner742da042016-09-07 17:40:12 -07001952 if (dictresize(mp, ESTIMATE_SIZE(PySet_GET_SIZE(iterable)))) {
Eric Snow96c6af92015-05-29 22:21:39 -06001953 Py_DECREF(d);
1954 return NULL;
1955 }
1956
1957 while (_PySet_NextEntry(iterable, &pos, &key, &hash)) {
1958 if (insertdict(mp, key, hash, value)) {
1959 Py_DECREF(d);
1960 return NULL;
1961 }
1962 }
1963 return d;
1964 }
1965 }
1966
1967 it = PyObject_GetIter(iterable);
1968 if (it == NULL){
1969 Py_DECREF(d);
1970 return NULL;
1971 }
1972
1973 if (PyDict_CheckExact(d)) {
1974 while ((key = PyIter_Next(it)) != NULL) {
1975 status = PyDict_SetItem(d, key, value);
1976 Py_DECREF(key);
1977 if (status < 0)
1978 goto Fail;
1979 }
1980 } else {
1981 while ((key = PyIter_Next(it)) != NULL) {
1982 status = PyObject_SetItem(d, key, value);
1983 Py_DECREF(key);
1984 if (status < 0)
1985 goto Fail;
1986 }
1987 }
1988
1989 if (PyErr_Occurred())
1990 goto Fail;
1991 Py_DECREF(it);
1992 return d;
1993
1994Fail:
1995 Py_DECREF(it);
1996 Py_DECREF(d);
1997 return NULL;
1998}
1999
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002000/* Methods */
2001
2002static void
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002003dict_dealloc(PyDictObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002004{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002005 PyObject **values = mp->ma_values;
2006 PyDictKeysObject *keys = mp->ma_keys;
2007 Py_ssize_t i, n;
INADA Naokia6296d32017-08-24 14:55:17 +09002008
2009 /* bpo-31095: UnTrack is needed before calling any callbacks */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002010 PyObject_GC_UnTrack(mp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02002011 Py_TRASHCAN_BEGIN(mp, dict_dealloc)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002012 if (values != NULL) {
2013 if (values != empty_values) {
Victor Stinner742da042016-09-07 17:40:12 -07002014 for (i = 0, n = mp->ma_keys->dk_nentries; i < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002015 Py_XDECREF(values[i]);
2016 }
2017 free_values(values);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002018 }
INADA Naokia7576492018-11-14 18:39:27 +09002019 dictkeys_decref(keys);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002020 }
Victor Stinnerac2a4fe2013-07-16 22:19:00 +02002021 else if (keys != NULL) {
Antoine Pitrou2d169b22012-05-12 23:43:44 +02002022 assert(keys->dk_refcnt == 1);
INADA Naokia7576492018-11-14 18:39:27 +09002023 dictkeys_decref(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002024 }
Victor Stinner522691c2020-06-23 16:40:40 +02002025 struct _Py_dict_state *state = get_dict_state();
Victor Stinnerb4e85ca2020-06-23 11:33:18 +02002026#ifdef Py_DEBUG
2027 // new_dict() must not be called after _PyDict_Fini()
2028 assert(state->numfree != -1);
Victor Stinnerb4b53862020-05-05 19:55:29 +02002029#endif
Victor Stinnerb4e85ca2020-06-23 11:33:18 +02002030 if (state->numfree < PyDict_MAXFREELIST && Py_IS_TYPE(mp, &PyDict_Type)) {
2031 state->free_list[state->numfree++] = mp;
2032 }
2033 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002034 Py_TYPE(mp)->tp_free((PyObject *)mp);
Victor Stinnerb4b53862020-05-05 19:55:29 +02002035 }
Jeroen Demeyer351c6742019-05-10 19:21:11 +02002036 Py_TRASHCAN_END
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002037}
2038
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002039
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002040static PyObject *
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002041dict_repr(PyDictObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002042{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002043 Py_ssize_t i;
Victor Stinnerf91929b2013-11-19 13:07:38 +01002044 PyObject *key = NULL, *value = NULL;
2045 _PyUnicodeWriter writer;
2046 int first;
Guido van Rossum255443b1998-04-10 22:47:14 +00002047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002048 i = Py_ReprEnter((PyObject *)mp);
2049 if (i != 0) {
2050 return i > 0 ? PyUnicode_FromString("{...}") : NULL;
2051 }
Guido van Rossum255443b1998-04-10 22:47:14 +00002052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002053 if (mp->ma_used == 0) {
Victor Stinnerf91929b2013-11-19 13:07:38 +01002054 Py_ReprLeave((PyObject *)mp);
2055 return PyUnicode_FromString("{}");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002056 }
Tim Petersa7259592001-06-16 05:11:17 +00002057
Victor Stinnerf91929b2013-11-19 13:07:38 +01002058 _PyUnicodeWriter_Init(&writer);
2059 writer.overallocate = 1;
2060 /* "{" + "1: 2" + ", 3: 4" * (len - 1) + "}" */
2061 writer.min_length = 1 + 4 + (2 + 4) * (mp->ma_used - 1) + 1;
Tim Petersa7259592001-06-16 05:11:17 +00002062
Victor Stinnerf91929b2013-11-19 13:07:38 +01002063 if (_PyUnicodeWriter_WriteChar(&writer, '{') < 0)
2064 goto error;
Tim Petersa7259592001-06-16 05:11:17 +00002065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002066 /* Do repr() on each key+value pair, and insert ": " between them.
2067 Note that repr may mutate the dict. */
2068 i = 0;
Victor Stinnerf91929b2013-11-19 13:07:38 +01002069 first = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002070 while (PyDict_Next((PyObject *)mp, &i, &key, &value)) {
Victor Stinnerf91929b2013-11-19 13:07:38 +01002071 PyObject *s;
2072 int res;
2073
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002074 /* Prevent repr from deleting key or value during key format. */
2075 Py_INCREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002076 Py_INCREF(value);
Victor Stinnerf97dfd72013-07-18 01:00:45 +02002077
Victor Stinnerf91929b2013-11-19 13:07:38 +01002078 if (!first) {
2079 if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0)
2080 goto error;
2081 }
2082 first = 0;
2083
2084 s = PyObject_Repr(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 if (s == NULL)
Victor Stinnerf91929b2013-11-19 13:07:38 +01002086 goto error;
2087 res = _PyUnicodeWriter_WriteStr(&writer, s);
2088 Py_DECREF(s);
2089 if (res < 0)
2090 goto error;
2091
2092 if (_PyUnicodeWriter_WriteASCIIString(&writer, ": ", 2) < 0)
2093 goto error;
2094
2095 s = PyObject_Repr(value);
2096 if (s == NULL)
2097 goto error;
2098 res = _PyUnicodeWriter_WriteStr(&writer, s);
2099 Py_DECREF(s);
2100 if (res < 0)
2101 goto error;
2102
2103 Py_CLEAR(key);
2104 Py_CLEAR(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002105 }
Tim Petersa7259592001-06-16 05:11:17 +00002106
Victor Stinnerf91929b2013-11-19 13:07:38 +01002107 writer.overallocate = 0;
2108 if (_PyUnicodeWriter_WriteChar(&writer, '}') < 0)
2109 goto error;
Tim Petersa7259592001-06-16 05:11:17 +00002110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 Py_ReprLeave((PyObject *)mp);
Victor Stinnerf91929b2013-11-19 13:07:38 +01002112
2113 return _PyUnicodeWriter_Finish(&writer);
2114
2115error:
2116 Py_ReprLeave((PyObject *)mp);
2117 _PyUnicodeWriter_Dealloc(&writer);
2118 Py_XDECREF(key);
2119 Py_XDECREF(value);
2120 return NULL;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002121}
2122
Martin v. Löwis18e16552006-02-15 17:27:45 +00002123static Py_ssize_t
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002124dict_length(PyDictObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002125{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002126 return mp->ma_used;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002127}
2128
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002129static PyObject *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002130dict_subscript(PyDictObject *mp, PyObject *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002131{
Victor Stinner742da042016-09-07 17:40:12 -07002132 Py_ssize_t ix;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002133 Py_hash_t hash;
INADA Naokiba609772016-12-07 20:41:42 +09002134 PyObject *value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002137 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002138 hash = PyObject_Hash(key);
2139 if (hash == -1)
2140 return NULL;
2141 }
INADA Naoki778928b2017-08-03 23:45:15 +09002142 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07002143 if (ix == DKIX_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002144 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09002145 if (ix == DKIX_EMPTY || value == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002146 if (!PyDict_CheckExact(mp)) {
2147 /* Look up __missing__ method if we're a subclass. */
2148 PyObject *missing, *res;
Benjamin Petersonce798522012-01-22 11:24:29 -05002149 _Py_IDENTIFIER(__missing__);
2150 missing = _PyObject_LookupSpecial((PyObject *)mp, &PyId___missing__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 if (missing != NULL) {
Petr Viktorinffd97532020-02-11 17:46:57 +01002152 res = PyObject_CallOneArg(missing, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002153 Py_DECREF(missing);
2154 return res;
2155 }
2156 else if (PyErr_Occurred())
2157 return NULL;
2158 }
Raymond Hettinger69492da2013-09-02 15:59:26 -07002159 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 return NULL;
2161 }
INADA Naokiba609772016-12-07 20:41:42 +09002162 Py_INCREF(value);
2163 return value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002164}
2165
2166static int
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002167dict_ass_sub(PyDictObject *mp, PyObject *v, PyObject *w)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002168{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 if (w == NULL)
2170 return PyDict_DelItem((PyObject *)mp, v);
2171 else
2172 return PyDict_SetItem((PyObject *)mp, v, w);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002173}
2174
Guido van Rossuma9e7a811997-05-13 21:02:11 +00002175static PyMappingMethods dict_as_mapping = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 (lenfunc)dict_length, /*mp_length*/
2177 (binaryfunc)dict_subscript, /*mp_subscript*/
2178 (objobjargproc)dict_ass_sub, /*mp_ass_subscript*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002179};
2180
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002181static PyObject *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002182dict_keys(PyDictObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002183{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002184 PyObject *v;
2185 Py_ssize_t i, j;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002186 PyDictKeyEntry *ep;
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002187 Py_ssize_t n, offset;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002188 PyObject **value_ptr;
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002189
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002190 again:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 n = mp->ma_used;
2192 v = PyList_New(n);
2193 if (v == NULL)
2194 return NULL;
2195 if (n != mp->ma_used) {
2196 /* Durnit. The allocations caused the dict to resize.
2197 * Just start over, this shouldn't normally happen.
2198 */
2199 Py_DECREF(v);
2200 goto again;
2201 }
Victor Stinner742da042016-09-07 17:40:12 -07002202 ep = DK_ENTRIES(mp->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002203 if (mp->ma_values) {
2204 value_ptr = mp->ma_values;
2205 offset = sizeof(PyObject *);
2206 }
2207 else {
2208 value_ptr = &ep[0].me_value;
2209 offset = sizeof(PyDictKeyEntry);
2210 }
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002211 for (i = 0, j = 0; j < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002212 if (*value_ptr != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002213 PyObject *key = ep[i].me_key;
2214 Py_INCREF(key);
2215 PyList_SET_ITEM(v, j, key);
2216 j++;
2217 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002218 value_ptr = (PyObject **)(((char *)value_ptr) + offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002219 }
2220 assert(j == n);
2221 return v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002222}
2223
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002224static PyObject *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002225dict_values(PyDictObject *mp)
Guido van Rossum25831651993-05-19 14:50:45 +00002226{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002227 PyObject *v;
2228 Py_ssize_t i, j;
Benjamin Petersonf0acae22016-09-08 09:50:08 -07002229 PyDictKeyEntry *ep;
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002230 Py_ssize_t n, offset;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002231 PyObject **value_ptr;
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002232
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002233 again:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002234 n = mp->ma_used;
2235 v = PyList_New(n);
2236 if (v == NULL)
2237 return NULL;
2238 if (n != mp->ma_used) {
2239 /* Durnit. The allocations caused the dict to resize.
2240 * Just start over, this shouldn't normally happen.
2241 */
2242 Py_DECREF(v);
2243 goto again;
2244 }
Benjamin Petersonf0acae22016-09-08 09:50:08 -07002245 ep = DK_ENTRIES(mp->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002246 if (mp->ma_values) {
2247 value_ptr = mp->ma_values;
2248 offset = sizeof(PyObject *);
2249 }
2250 else {
Benjamin Petersonf0acae22016-09-08 09:50:08 -07002251 value_ptr = &ep[0].me_value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002252 offset = sizeof(PyDictKeyEntry);
2253 }
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002254 for (i = 0, j = 0; j < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002255 PyObject *value = *value_ptr;
2256 value_ptr = (PyObject **)(((char *)value_ptr) + offset);
2257 if (value != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002258 Py_INCREF(value);
2259 PyList_SET_ITEM(v, j, value);
2260 j++;
2261 }
2262 }
2263 assert(j == n);
2264 return v;
Guido van Rossum25831651993-05-19 14:50:45 +00002265}
2266
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002267static PyObject *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002268dict_items(PyDictObject *mp)
Guido van Rossum25831651993-05-19 14:50:45 +00002269{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002270 PyObject *v;
2271 Py_ssize_t i, j, n;
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002272 Py_ssize_t offset;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002273 PyObject *item, *key;
2274 PyDictKeyEntry *ep;
2275 PyObject **value_ptr;
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 /* Preallocate the list of tuples, to avoid allocations during
2278 * the loop over the items, which could trigger GC, which
2279 * could resize the dict. :-(
2280 */
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002281 again:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002282 n = mp->ma_used;
2283 v = PyList_New(n);
2284 if (v == NULL)
2285 return NULL;
2286 for (i = 0; i < n; i++) {
2287 item = PyTuple_New(2);
2288 if (item == NULL) {
2289 Py_DECREF(v);
2290 return NULL;
2291 }
2292 PyList_SET_ITEM(v, i, item);
2293 }
2294 if (n != mp->ma_used) {
2295 /* Durnit. The allocations caused the dict to resize.
2296 * Just start over, this shouldn't normally happen.
2297 */
2298 Py_DECREF(v);
2299 goto again;
2300 }
2301 /* Nothing we do below makes any function calls. */
Victor Stinner742da042016-09-07 17:40:12 -07002302 ep = DK_ENTRIES(mp->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002303 if (mp->ma_values) {
2304 value_ptr = mp->ma_values;
2305 offset = sizeof(PyObject *);
2306 }
2307 else {
2308 value_ptr = &ep[0].me_value;
2309 offset = sizeof(PyDictKeyEntry);
2310 }
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002311 for (i = 0, j = 0; j < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002312 PyObject *value = *value_ptr;
2313 value_ptr = (PyObject **)(((char *)value_ptr) + offset);
2314 if (value != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 key = ep[i].me_key;
2316 item = PyList_GET_ITEM(v, j);
2317 Py_INCREF(key);
2318 PyTuple_SET_ITEM(item, 0, key);
2319 Py_INCREF(value);
2320 PyTuple_SET_ITEM(item, 1, value);
2321 j++;
2322 }
2323 }
2324 assert(j == n);
2325 return v;
Guido van Rossum25831651993-05-19 14:50:45 +00002326}
2327
Larry Hastings5c661892014-01-24 06:17:25 -08002328/*[clinic input]
2329@classmethod
2330dict.fromkeys
Larry Hastings5c661892014-01-24 06:17:25 -08002331 iterable: object
2332 value: object=None
2333 /
2334
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002335Create a new dictionary with keys from iterable and values set to value.
Larry Hastings5c661892014-01-24 06:17:25 -08002336[clinic start generated code]*/
2337
Larry Hastings5c661892014-01-24 06:17:25 -08002338static PyObject *
2339dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002340/*[clinic end generated code: output=8fb98e4b10384999 input=382ba4855d0f74c3]*/
Larry Hastings5c661892014-01-24 06:17:25 -08002341{
Eric Snow96c6af92015-05-29 22:21:39 -06002342 return _PyDict_FromKeys((PyObject *)type, iterable, value);
Raymond Hettingere33d3df2002-11-27 07:29:33 +00002343}
2344
Brandt Buchereb8ac572020-02-24 19:47:34 -08002345/* Single-arg dict update; used by dict_update_common and operators. */
2346static int
2347dict_update_arg(PyObject *self, PyObject *arg)
2348{
2349 if (PyDict_CheckExact(arg)) {
2350 return PyDict_Merge(self, arg, 1);
2351 }
2352 _Py_IDENTIFIER(keys);
2353 PyObject *func;
2354 if (_PyObject_LookupAttrId(arg, &PyId_keys, &func) < 0) {
2355 return -1;
2356 }
2357 if (func != NULL) {
2358 Py_DECREF(func);
2359 return PyDict_Merge(self, arg, 1);
2360 }
2361 return PyDict_MergeFromSeq2(self, arg, 1);
2362}
2363
Raymond Hettinger31017ae2004-03-04 08:25:44 +00002364static int
Victor Stinner742da042016-09-07 17:40:12 -07002365dict_update_common(PyObject *self, PyObject *args, PyObject *kwds,
2366 const char *methname)
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002367{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002368 PyObject *arg = NULL;
2369 int result = 0;
Raymond Hettinger31017ae2004-03-04 08:25:44 +00002370
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002371 if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002372 result = -1;
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002373 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002374 else if (arg != NULL) {
Brandt Buchereb8ac572020-02-24 19:47:34 -08002375 result = dict_update_arg(self, arg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376 }
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002378 if (result == 0 && kwds != NULL) {
2379 if (PyArg_ValidateKeywordArguments(kwds))
2380 result = PyDict_Merge(self, kwds, 1);
2381 else
2382 result = -1;
2383 }
2384 return result;
Raymond Hettinger31017ae2004-03-04 08:25:44 +00002385}
2386
Victor Stinner91f0d4a2017-01-19 12:45:06 +01002387/* Note: dict.update() uses the METH_VARARGS|METH_KEYWORDS calling convention.
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002388 Using METH_FASTCALL|METH_KEYWORDS would make dict.update(**dict2) calls
2389 slower, see the issue #29312. */
Raymond Hettinger31017ae2004-03-04 08:25:44 +00002390static PyObject *
2391dict_update(PyObject *self, PyObject *args, PyObject *kwds)
2392{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 if (dict_update_common(self, args, kwds, "update") != -1)
2394 Py_RETURN_NONE;
2395 return NULL;
Tim Peters6d6c1a32001-08-02 04:15:00 +00002396}
2397
Guido van Rossum05ac6de2001-08-10 20:28:28 +00002398/* Update unconditionally replaces existing items.
2399 Merge has a 3rd argument 'override'; if set, it acts like Update,
Tim Peters1fc240e2001-10-26 05:06:50 +00002400 otherwise it leaves existing items unchanged.
2401
2402 PyDict_{Update,Merge} update/merge from a mapping object.
2403
Tim Petersf582b822001-12-11 18:51:08 +00002404 PyDict_MergeFromSeq2 updates/merges from any iterable object
Tim Peters1fc240e2001-10-26 05:06:50 +00002405 producing iterable objects of length 2.
2406*/
2407
Tim Petersf582b822001-12-11 18:51:08 +00002408int
Tim Peters1fc240e2001-10-26 05:06:50 +00002409PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)
2410{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002411 PyObject *it; /* iter(seq2) */
2412 Py_ssize_t i; /* index into seq2 of current element */
2413 PyObject *item; /* seq2[i] */
2414 PyObject *fast; /* item as a 2-tuple or 2-list */
Tim Peters1fc240e2001-10-26 05:06:50 +00002415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002416 assert(d != NULL);
2417 assert(PyDict_Check(d));
2418 assert(seq2 != NULL);
Tim Peters1fc240e2001-10-26 05:06:50 +00002419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002420 it = PyObject_GetIter(seq2);
2421 if (it == NULL)
2422 return -1;
Tim Peters1fc240e2001-10-26 05:06:50 +00002423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 for (i = 0; ; ++i) {
2425 PyObject *key, *value;
2426 Py_ssize_t n;
Tim Peters1fc240e2001-10-26 05:06:50 +00002427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002428 fast = NULL;
2429 item = PyIter_Next(it);
2430 if (item == NULL) {
2431 if (PyErr_Occurred())
2432 goto Fail;
2433 break;
2434 }
Tim Peters1fc240e2001-10-26 05:06:50 +00002435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002436 /* Convert item to sequence, and verify length 2. */
2437 fast = PySequence_Fast(item, "");
2438 if (fast == NULL) {
2439 if (PyErr_ExceptionMatches(PyExc_TypeError))
2440 PyErr_Format(PyExc_TypeError,
2441 "cannot convert dictionary update "
2442 "sequence element #%zd to a sequence",
2443 i);
2444 goto Fail;
2445 }
2446 n = PySequence_Fast_GET_SIZE(fast);
2447 if (n != 2) {
2448 PyErr_Format(PyExc_ValueError,
2449 "dictionary update sequence element #%zd "
2450 "has length %zd; 2 is required",
2451 i, n);
2452 goto Fail;
2453 }
Tim Peters1fc240e2001-10-26 05:06:50 +00002454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002455 /* Update/merge with this (key, value) pair. */
2456 key = PySequence_Fast_GET_ITEM(fast, 0);
2457 value = PySequence_Fast_GET_ITEM(fast, 1);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002458 Py_INCREF(key);
2459 Py_INCREF(value);
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002460 if (override) {
2461 if (PyDict_SetItem(d, key, value) < 0) {
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002462 Py_DECREF(key);
2463 Py_DECREF(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002464 goto Fail;
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002465 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002466 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002467 else if (PyDict_GetItemWithError(d, key) == NULL) {
2468 if (PyErr_Occurred() || PyDict_SetItem(d, key, value) < 0) {
2469 Py_DECREF(key);
2470 Py_DECREF(value);
2471 goto Fail;
2472 }
2473 }
2474
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002475 Py_DECREF(key);
2476 Py_DECREF(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002477 Py_DECREF(fast);
2478 Py_DECREF(item);
2479 }
Tim Peters1fc240e2001-10-26 05:06:50 +00002480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002481 i = 0;
Victor Stinner0fc91ee2019-04-12 21:51:34 +02002482 ASSERT_CONSISTENT(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002483 goto Return;
Tim Peters1fc240e2001-10-26 05:06:50 +00002484Fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002485 Py_XDECREF(item);
2486 Py_XDECREF(fast);
2487 i = -1;
Tim Peters1fc240e2001-10-26 05:06:50 +00002488Return:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002489 Py_DECREF(it);
2490 return Py_SAFE_DOWNCAST(i, Py_ssize_t, int);
Tim Peters1fc240e2001-10-26 05:06:50 +00002491}
2492
doko@ubuntu.comc96df682016-10-11 08:04:02 +02002493static int
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002494dict_merge(PyObject *a, PyObject *b, int override)
Guido van Rossum05ac6de2001-08-10 20:28:28 +00002495{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002496 PyDictObject *mp, *other;
2497 Py_ssize_t i, n;
Victor Stinner742da042016-09-07 17:40:12 -07002498 PyDictKeyEntry *entry, *ep0;
Tim Peters6d6c1a32001-08-02 04:15:00 +00002499
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002500 assert(0 <= override && override <= 2);
2501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002502 /* We accept for the argument either a concrete dictionary object,
2503 * or an abstract "mapping" object. For the former, we can do
2504 * things quite efficiently. For the latter, we only require that
2505 * PyMapping_Keys() and PyObject_GetItem() be supported.
2506 */
2507 if (a == NULL || !PyDict_Check(a) || b == NULL) {
2508 PyErr_BadInternalCall();
2509 return -1;
2510 }
2511 mp = (PyDictObject*)a;
INADA Naoki2aaf98c2018-09-26 12:59:00 +09002512 if (PyDict_Check(b) && (Py_TYPE(b)->tp_iter == (getiterfunc)dict_iter)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002513 other = (PyDictObject*)b;
2514 if (other == mp || other->ma_used == 0)
2515 /* a.update(a) or a.update({}); nothing to do */
2516 return 0;
Inada Naokidb6d9a52020-08-04 11:08:06 +09002517 if (mp->ma_used == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002518 /* Since the target dict is empty, PyDict_GetItem()
2519 * always returns NULL. Setting override to 1
2520 * skips the unnecessary test.
2521 */
2522 override = 1;
Inada Naokidb6d9a52020-08-04 11:08:06 +09002523 PyDictKeysObject *okeys = other->ma_keys;
2524
2525 // If other is clean, combined, and just allocated, just clone it.
2526 if (other->ma_values == NULL &&
2527 other->ma_used == okeys->dk_nentries &&
2528 (okeys->dk_size == PyDict_MINSIZE ||
2529 USABLE_FRACTION(okeys->dk_size/2) < other->ma_used)) {
2530 PyDictKeysObject *keys = clone_combined_dict_keys(other);
2531 if (keys == NULL) {
2532 return -1;
2533 }
2534
2535 dictkeys_decref(mp->ma_keys);
2536 mp->ma_keys = keys;
2537 if (mp->ma_values != NULL) {
2538 if (mp->ma_values != empty_values) {
2539 free_values(mp->ma_values);
2540 }
2541 mp->ma_values = NULL;
2542 }
2543
2544 mp->ma_used = other->ma_used;
2545 mp->ma_version_tag = DICT_NEXT_VERSION();
2546 ASSERT_CONSISTENT(mp);
2547
2548 if (_PyObject_GC_IS_TRACKED(other) && !_PyObject_GC_IS_TRACKED(mp)) {
2549 /* Maintain tracking. */
2550 _PyObject_GC_TRACK(mp);
2551 }
2552
2553 return 0;
2554 }
2555 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002556 /* Do one big resize at the start, rather than
2557 * incrementally resizing as we insert new items. Expect
2558 * that there will be no (or few) overlapping keys.
2559 */
INADA Naokib1152be2016-10-27 19:26:50 +09002560 if (USABLE_FRACTION(mp->ma_keys->dk_size) < other->ma_used) {
2561 if (dictresize(mp, ESTIMATE_SIZE(mp->ma_used + other->ma_used))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002562 return -1;
INADA Naokib1152be2016-10-27 19:26:50 +09002563 }
2564 }
Victor Stinner742da042016-09-07 17:40:12 -07002565 ep0 = DK_ENTRIES(other->ma_keys);
2566 for (i = 0, n = other->ma_keys->dk_nentries; i < n; i++) {
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002567 PyObject *key, *value;
2568 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07002569 entry = &ep0[i];
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002570 key = entry->me_key;
2571 hash = entry->me_hash;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002572 if (other->ma_values)
2573 value = other->ma_values[i];
2574 else
2575 value = entry->me_value;
2576
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002577 if (value != NULL) {
2578 int err = 0;
2579 Py_INCREF(key);
2580 Py_INCREF(value);
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02002581 if (override == 1)
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002582 err = insertdict(mp, key, hash, value);
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02002583 else if (_PyDict_GetItem_KnownHash(a, key, hash) == NULL) {
2584 if (PyErr_Occurred()) {
2585 Py_DECREF(value);
2586 Py_DECREF(key);
2587 return -1;
2588 }
2589 err = insertdict(mp, key, hash, value);
2590 }
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002591 else if (override != 0) {
2592 _PyErr_SetKeyError(key);
2593 Py_DECREF(value);
2594 Py_DECREF(key);
2595 return -1;
2596 }
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002597 Py_DECREF(value);
2598 Py_DECREF(key);
2599 if (err != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002600 return -1;
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002601
Victor Stinner742da042016-09-07 17:40:12 -07002602 if (n != other->ma_keys->dk_nentries) {
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002603 PyErr_SetString(PyExc_RuntimeError,
2604 "dict mutated during update");
2605 return -1;
2606 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002607 }
2608 }
2609 }
2610 else {
2611 /* Do it the generic, slower way */
2612 PyObject *keys = PyMapping_Keys(b);
2613 PyObject *iter;
2614 PyObject *key, *value;
2615 int status;
Barry Warsaw66a0d1d2001-06-26 20:08:32 +00002616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002617 if (keys == NULL)
2618 /* Docstring says this is equivalent to E.keys() so
2619 * if E doesn't have a .keys() method we want
2620 * AttributeError to percolate up. Might as well
2621 * do the same for any other error.
2622 */
2623 return -1;
Barry Warsaw66a0d1d2001-06-26 20:08:32 +00002624
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002625 iter = PyObject_GetIter(keys);
2626 Py_DECREF(keys);
2627 if (iter == NULL)
2628 return -1;
Barry Warsaw66a0d1d2001-06-26 20:08:32 +00002629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002630 for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002631 if (override != 1) {
2632 if (PyDict_GetItemWithError(a, key) != NULL) {
2633 if (override != 0) {
2634 _PyErr_SetKeyError(key);
2635 Py_DECREF(key);
2636 Py_DECREF(iter);
2637 return -1;
2638 }
2639 Py_DECREF(key);
2640 continue;
2641 }
2642 else if (PyErr_Occurred()) {
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002643 Py_DECREF(key);
2644 Py_DECREF(iter);
2645 return -1;
2646 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002647 }
2648 value = PyObject_GetItem(b, key);
2649 if (value == NULL) {
2650 Py_DECREF(iter);
2651 Py_DECREF(key);
2652 return -1;
2653 }
2654 status = PyDict_SetItem(a, key, value);
2655 Py_DECREF(key);
2656 Py_DECREF(value);
2657 if (status < 0) {
2658 Py_DECREF(iter);
2659 return -1;
2660 }
2661 }
2662 Py_DECREF(iter);
2663 if (PyErr_Occurred())
2664 /* Iterator completed, via error */
2665 return -1;
2666 }
Victor Stinner0fc91ee2019-04-12 21:51:34 +02002667 ASSERT_CONSISTENT(a);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002668 return 0;
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002669}
2670
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002671int
2672PyDict_Update(PyObject *a, PyObject *b)
2673{
2674 return dict_merge(a, b, 1);
2675}
2676
2677int
2678PyDict_Merge(PyObject *a, PyObject *b, int override)
2679{
2680 /* XXX Deprecate override not in (0, 1). */
2681 return dict_merge(a, b, override != 0);
2682}
2683
2684int
2685_PyDict_MergeEx(PyObject *a, PyObject *b, int override)
2686{
2687 return dict_merge(a, b, override);
2688}
2689
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002690static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302691dict_copy(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002692{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002693 return PyDict_Copy((PyObject*)mp);
Jeremy Hyltona12c7a72000-03-30 22:27:31 +00002694}
2695
2696PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00002697PyDict_Copy(PyObject *o)
Jeremy Hyltona12c7a72000-03-30 22:27:31 +00002698{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002699 PyObject *copy;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002700 PyDictObject *mp;
2701 Py_ssize_t i, n;
Jeremy Hyltona12c7a72000-03-30 22:27:31 +00002702
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002703 if (o == NULL || !PyDict_Check(o)) {
2704 PyErr_BadInternalCall();
2705 return NULL;
2706 }
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002707
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002708 mp = (PyDictObject *)o;
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002709 if (mp->ma_used == 0) {
2710 /* The dict is empty; just return a new dict. */
2711 return PyDict_New();
2712 }
2713
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002714 if (_PyDict_HasSplitTable(mp)) {
2715 PyDictObject *split_copy;
Victor Stinner742da042016-09-07 17:40:12 -07002716 Py_ssize_t size = USABLE_FRACTION(DK_SIZE(mp->ma_keys));
2717 PyObject **newvalues;
2718 newvalues = new_values(size);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002719 if (newvalues == NULL)
2720 return PyErr_NoMemory();
2721 split_copy = PyObject_GC_New(PyDictObject, &PyDict_Type);
2722 if (split_copy == NULL) {
2723 free_values(newvalues);
2724 return NULL;
2725 }
2726 split_copy->ma_values = newvalues;
2727 split_copy->ma_keys = mp->ma_keys;
2728 split_copy->ma_used = mp->ma_used;
INADA Naokid1c82c52018-04-03 11:43:53 +09002729 split_copy->ma_version_tag = DICT_NEXT_VERSION();
INADA Naokia7576492018-11-14 18:39:27 +09002730 dictkeys_incref(mp->ma_keys);
Victor Stinner742da042016-09-07 17:40:12 -07002731 for (i = 0, n = size; i < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002732 PyObject *value = mp->ma_values[i];
2733 Py_XINCREF(value);
2734 split_copy->ma_values[i] = value;
2735 }
Benjamin Peterson7ce67e42012-04-24 10:32:57 -04002736 if (_PyObject_GC_IS_TRACKED(mp))
2737 _PyObject_GC_TRACK(split_copy);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002738 return (PyObject *)split_copy;
2739 }
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002740
Inada Naokidb6d9a52020-08-04 11:08:06 +09002741 if (Py_TYPE(mp)->tp_iter == (getiterfunc)dict_iter &&
2742 mp->ma_values == NULL &&
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002743 (mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3))
2744 {
2745 /* Use fast-copy if:
2746
Inada Naokidb6d9a52020-08-04 11:08:06 +09002747 (1) type(mp) doesn't override tp_iter; and
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002748
2749 (2) 'mp' is not a split-dict; and
2750
2751 (3) if 'mp' is non-compact ('del' operation does not resize dicts),
2752 do fast-copy only if it has at most 1/3 non-used keys.
2753
Ville Skyttä61f82e02018-04-20 23:08:45 +03002754 The last condition (3) is important to guard against a pathological
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002755 case when a large dict is almost emptied with multiple del/pop
2756 operations and copied after that. In cases like this, we defer to
2757 PyDict_Merge, which produces a compacted copy.
2758 */
Inada Naokidb6d9a52020-08-04 11:08:06 +09002759 PyDictKeysObject *keys = clone_combined_dict_keys(mp);
2760 if (keys == NULL) {
2761 return NULL;
2762 }
2763 PyDictObject *new = (PyDictObject *)new_dict(keys, NULL);
2764 if (new == NULL) {
2765 /* In case of an error, `new_dict()` takes care of
2766 cleaning up `keys`. */
2767 return NULL;
2768 }
2769
2770 new->ma_used = mp->ma_used;
2771 ASSERT_CONSISTENT(new);
2772 if (_PyObject_GC_IS_TRACKED(mp)) {
2773 /* Maintain tracking. */
2774 _PyObject_GC_TRACK(new);
2775 }
2776
2777 return (PyObject *)new;
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002778 }
2779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002780 copy = PyDict_New();
2781 if (copy == NULL)
2782 return NULL;
Inada Naokidb6d9a52020-08-04 11:08:06 +09002783 if (dict_merge(copy, o, 1) == 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002784 return copy;
2785 Py_DECREF(copy);
2786 return NULL;
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002787}
2788
Martin v. Löwis18e16552006-02-15 17:27:45 +00002789Py_ssize_t
Tim Peters1f5871e2000-07-04 17:44:48 +00002790PyDict_Size(PyObject *mp)
Guido van Rossum4199fac1993-11-05 10:18:44 +00002791{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002792 if (mp == NULL || !PyDict_Check(mp)) {
2793 PyErr_BadInternalCall();
2794 return -1;
2795 }
2796 return ((PyDictObject *)mp)->ma_used;
Guido van Rossum4199fac1993-11-05 10:18:44 +00002797}
2798
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002799PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00002800PyDict_Keys(PyObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002801{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002802 if (mp == NULL || !PyDict_Check(mp)) {
2803 PyErr_BadInternalCall();
2804 return NULL;
2805 }
2806 return dict_keys((PyDictObject *)mp);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002807}
2808
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002809PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00002810PyDict_Values(PyObject *mp)
Guido van Rossum25831651993-05-19 14:50:45 +00002811{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002812 if (mp == NULL || !PyDict_Check(mp)) {
2813 PyErr_BadInternalCall();
2814 return NULL;
2815 }
2816 return dict_values((PyDictObject *)mp);
Guido van Rossum25831651993-05-19 14:50:45 +00002817}
2818
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002819PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00002820PyDict_Items(PyObject *mp)
Guido van Rossum25831651993-05-19 14:50:45 +00002821{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002822 if (mp == NULL || !PyDict_Check(mp)) {
2823 PyErr_BadInternalCall();
2824 return NULL;
2825 }
2826 return dict_items((PyDictObject *)mp);
Guido van Rossum25831651993-05-19 14:50:45 +00002827}
2828
Tim Peterse63415e2001-05-08 04:38:29 +00002829/* Return 1 if dicts equal, 0 if not, -1 if error.
2830 * Gets out as soon as any difference is detected.
2831 * Uses only Py_EQ comparison.
2832 */
2833static int
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002834dict_equal(PyDictObject *a, PyDictObject *b)
Tim Peterse63415e2001-05-08 04:38:29 +00002835{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002836 Py_ssize_t i;
Tim Peterse63415e2001-05-08 04:38:29 +00002837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002838 if (a->ma_used != b->ma_used)
2839 /* can't be equal if # of entries differ */
2840 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002841 /* Same # of entries -- check all of 'em. Exit early on any diff. */
Victor Stinner742da042016-09-07 17:40:12 -07002842 for (i = 0; i < a->ma_keys->dk_nentries; i++) {
2843 PyDictKeyEntry *ep = &DK_ENTRIES(a->ma_keys)[i];
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002844 PyObject *aval;
2845 if (a->ma_values)
2846 aval = a->ma_values[i];
2847 else
2848 aval = ep->me_value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002849 if (aval != NULL) {
2850 int cmp;
2851 PyObject *bval;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002852 PyObject *key = ep->me_key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002853 /* temporarily bump aval's refcount to ensure it stays
2854 alive until we're done with it */
2855 Py_INCREF(aval);
2856 /* ditto for key */
2857 Py_INCREF(key);
Antoine Pitrou0e9958b2012-12-02 19:10:07 +01002858 /* reuse the known hash value */
INADA Naoki778928b2017-08-03 23:45:15 +09002859 b->ma_keys->dk_lookup(b, key, ep->me_hash, &bval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002860 if (bval == NULL) {
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002861 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002862 Py_DECREF(aval);
2863 if (PyErr_Occurred())
2864 return -1;
2865 return 0;
2866 }
Dong-hee Na2d5bf562019-12-31 10:04:22 +09002867 Py_INCREF(bval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002868 cmp = PyObject_RichCompareBool(aval, bval, Py_EQ);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002869 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002870 Py_DECREF(aval);
Dong-hee Na2d5bf562019-12-31 10:04:22 +09002871 Py_DECREF(bval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002872 if (cmp <= 0) /* error or not equal */
2873 return cmp;
2874 }
2875 }
2876 return 1;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002877}
Tim Peterse63415e2001-05-08 04:38:29 +00002878
2879static PyObject *
2880dict_richcompare(PyObject *v, PyObject *w, int op)
2881{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002882 int cmp;
2883 PyObject *res;
Tim Peterse63415e2001-05-08 04:38:29 +00002884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002885 if (!PyDict_Check(v) || !PyDict_Check(w)) {
2886 res = Py_NotImplemented;
2887 }
2888 else if (op == Py_EQ || op == Py_NE) {
2889 cmp = dict_equal((PyDictObject *)v, (PyDictObject *)w);
2890 if (cmp < 0)
2891 return NULL;
2892 res = (cmp == (op == Py_EQ)) ? Py_True : Py_False;
2893 }
2894 else
2895 res = Py_NotImplemented;
2896 Py_INCREF(res);
2897 return res;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002898}
Tim Peterse63415e2001-05-08 04:38:29 +00002899
Larry Hastings61272b72014-01-07 12:41:53 -08002900/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002901
2902@coexist
2903dict.__contains__
2904
2905 key: object
2906 /
2907
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002908True if the dictionary has the specified key, else False.
Larry Hastings61272b72014-01-07 12:41:53 -08002909[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002910
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002911static PyObject *
Larry Hastingsc2047262014-01-25 20:43:29 -08002912dict___contains__(PyDictObject *self, PyObject *key)
Serhiy Storchaka19d25972017-02-04 08:05:07 +02002913/*[clinic end generated code: output=a3d03db709ed6e6b input=fe1cb42ad831e820]*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002914{
Larry Hastingsc2047262014-01-25 20:43:29 -08002915 register PyDictObject *mp = self;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002916 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07002917 Py_ssize_t ix;
INADA Naokiba609772016-12-07 20:41:42 +09002918 PyObject *value;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002919
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002920 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002921 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002922 hash = PyObject_Hash(key);
2923 if (hash == -1)
2924 return NULL;
2925 }
INADA Naoki778928b2017-08-03 23:45:15 +09002926 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07002927 if (ix == DKIX_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002928 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09002929 if (ix == DKIX_EMPTY || value == NULL)
Victor Stinner742da042016-09-07 17:40:12 -07002930 Py_RETURN_FALSE;
2931 Py_RETURN_TRUE;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002932}
2933
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01002934/*[clinic input]
2935dict.get
2936
2937 key: object
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02002938 default: object = None
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01002939 /
2940
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002941Return the value for key if key is in the dictionary, else default.
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01002942[clinic start generated code]*/
2943
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002944static PyObject *
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02002945dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002946/*[clinic end generated code: output=bba707729dee05bf input=279ddb5790b6b107]*/
Barry Warsawc38c5da1997-10-06 17:49:20 +00002947{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002948 PyObject *val = NULL;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002949 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07002950 Py_ssize_t ix;
Barry Warsawc38c5da1997-10-06 17:49:20 +00002951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002952 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002953 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002954 hash = PyObject_Hash(key);
2955 if (hash == -1)
2956 return NULL;
2957 }
INADA Naoki778928b2017-08-03 23:45:15 +09002958 ix = (self->ma_keys->dk_lookup) (self, key, hash, &val);
Victor Stinner742da042016-09-07 17:40:12 -07002959 if (ix == DKIX_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002960 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09002961 if (ix == DKIX_EMPTY || val == NULL) {
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02002962 val = default_value;
INADA Naokiba609772016-12-07 20:41:42 +09002963 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002964 Py_INCREF(val);
2965 return val;
Barry Warsawc38c5da1997-10-06 17:49:20 +00002966}
2967
Benjamin Peterson00e98862013-03-07 22:16:29 -05002968PyObject *
2969PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj)
Guido van Rossum164452c2000-08-08 16:12:54 +00002970{
Benjamin Peterson00e98862013-03-07 22:16:29 -05002971 PyDictObject *mp = (PyDictObject *)d;
INADA Naoki93f26f72016-11-02 18:45:16 +09002972 PyObject *value;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002973 Py_hash_t hash;
Guido van Rossum164452c2000-08-08 16:12:54 +00002974
Benjamin Peterson00e98862013-03-07 22:16:29 -05002975 if (!PyDict_Check(d)) {
2976 PyErr_BadInternalCall();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002977 return NULL;
Benjamin Peterson00e98862013-03-07 22:16:29 -05002978 }
INADA Naoki93f26f72016-11-02 18:45:16 +09002979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002980 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002981 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002982 hash = PyObject_Hash(key);
2983 if (hash == -1)
2984 return NULL;
2985 }
Inada Naoki2ddc7f62019-03-18 20:38:33 +09002986 if (mp->ma_keys == Py_EMPTY_KEYS) {
2987 if (insert_to_emptydict(mp, key, hash, defaultobj) < 0) {
2988 return NULL;
2989 }
2990 return defaultobj;
2991 }
INADA Naoki93f26f72016-11-02 18:45:16 +09002992
2993 if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) {
2994 if (insertion_resize(mp) < 0)
2995 return NULL;
2996 }
2997
INADA Naoki778928b2017-08-03 23:45:15 +09002998 Py_ssize_t ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07002999 if (ix == DKIX_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003000 return NULL;
INADA Naoki93f26f72016-11-02 18:45:16 +09003001
3002 if (_PyDict_HasSplitTable(mp) &&
INADA Naokiba609772016-12-07 20:41:42 +09003003 ((ix >= 0 && value == NULL && mp->ma_used != ix) ||
INADA Naoki93f26f72016-11-02 18:45:16 +09003004 (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) {
3005 if (insertion_resize(mp) < 0) {
3006 return NULL;
3007 }
INADA Naoki93f26f72016-11-02 18:45:16 +09003008 ix = DKIX_EMPTY;
3009 }
3010
3011 if (ix == DKIX_EMPTY) {
3012 PyDictKeyEntry *ep, *ep0;
3013 value = defaultobj;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003014 if (mp->ma_keys->dk_usable <= 0) {
Victor Stinner3c336c52016-09-12 14:17:40 +02003015 if (insertion_resize(mp) < 0) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003016 return NULL;
Victor Stinner3c336c52016-09-12 14:17:40 +02003017 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003018 }
INADA Naoki778928b2017-08-03 23:45:15 +09003019 Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash);
INADA Naoki93f26f72016-11-02 18:45:16 +09003020 ep0 = DK_ENTRIES(mp->ma_keys);
3021 ep = &ep0[mp->ma_keys->dk_nentries];
INADA Naokia7576492018-11-14 18:39:27 +09003022 dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
Benjamin Petersonb1efa532013-03-04 09:47:50 -05003023 Py_INCREF(key);
INADA Naoki93f26f72016-11-02 18:45:16 +09003024 Py_INCREF(value);
3025 MAINTAIN_TRACKING(mp, key, value);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003026 ep->me_key = key;
3027 ep->me_hash = hash;
INADA Naokiba609772016-12-07 20:41:42 +09003028 if (_PyDict_HasSplitTable(mp)) {
INADA Naoki93f26f72016-11-02 18:45:16 +09003029 assert(mp->ma_values[mp->ma_keys->dk_nentries] == NULL);
3030 mp->ma_values[mp->ma_keys->dk_nentries] = value;
Victor Stinner742da042016-09-07 17:40:12 -07003031 }
3032 else {
INADA Naoki93f26f72016-11-02 18:45:16 +09003033 ep->me_value = value;
Victor Stinner742da042016-09-07 17:40:12 -07003034 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003035 mp->ma_used++;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07003036 mp->ma_version_tag = DICT_NEXT_VERSION();
INADA Naoki93f26f72016-11-02 18:45:16 +09003037 mp->ma_keys->dk_usable--;
3038 mp->ma_keys->dk_nentries++;
3039 assert(mp->ma_keys->dk_usable >= 0);
3040 }
INADA Naokiba609772016-12-07 20:41:42 +09003041 else if (value == NULL) {
INADA Naoki93f26f72016-11-02 18:45:16 +09003042 value = defaultobj;
3043 assert(_PyDict_HasSplitTable(mp));
3044 assert(ix == mp->ma_used);
3045 Py_INCREF(value);
3046 MAINTAIN_TRACKING(mp, key, value);
INADA Naokiba609772016-12-07 20:41:42 +09003047 mp->ma_values[ix] = value;
INADA Naoki93f26f72016-11-02 18:45:16 +09003048 mp->ma_used++;
3049 mp->ma_version_tag = DICT_NEXT_VERSION();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003050 }
INADA Naoki93f26f72016-11-02 18:45:16 +09003051
Victor Stinner0fc91ee2019-04-12 21:51:34 +02003052 ASSERT_CONSISTENT(mp);
INADA Naoki93f26f72016-11-02 18:45:16 +09003053 return value;
Guido van Rossum164452c2000-08-08 16:12:54 +00003054}
3055
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003056/*[clinic input]
3057dict.setdefault
3058
3059 key: object
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02003060 default: object = None
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003061 /
3062
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02003063Insert key with a value of default if key is not in the dictionary.
3064
3065Return the value for key if key is in the dictionary, else default.
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003066[clinic start generated code]*/
3067
Benjamin Peterson00e98862013-03-07 22:16:29 -05003068static PyObject *
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02003069dict_setdefault_impl(PyDictObject *self, PyObject *key,
3070 PyObject *default_value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02003071/*[clinic end generated code: output=f8c1101ebf69e220 input=0f063756e815fd9d]*/
Benjamin Peterson00e98862013-03-07 22:16:29 -05003072{
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003073 PyObject *val;
Benjamin Peterson00e98862013-03-07 22:16:29 -05003074
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02003075 val = PyDict_SetDefault((PyObject *)self, key, default_value);
Benjamin Peterson00e98862013-03-07 22:16:29 -05003076 Py_XINCREF(val);
3077 return val;
3078}
Guido van Rossum164452c2000-08-08 16:12:54 +00003079
3080static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303081dict_clear(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +00003082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003083 PyDict_Clear((PyObject *)mp);
3084 Py_RETURN_NONE;
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +00003085}
3086
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003087/*[clinic input]
3088dict.pop
3089
3090 key: object
3091 default: object = NULL
3092 /
3093
Serhiy Storchaka279f4462019-09-14 12:24:05 +03003094D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003095
Serhiy Storchaka6bf323732020-07-19 09:18:55 +03003096If the key is not found, return the default if given; otherwise,
3097raise a KeyError.
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003098[clinic start generated code]*/
3099
Guido van Rossumba6ab842000-12-12 22:02:18 +00003100static PyObject *
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003101dict_pop_impl(PyDictObject *self, PyObject *key, PyObject *default_value)
Serhiy Storchaka6bf323732020-07-19 09:18:55 +03003102/*[clinic end generated code: output=3abb47b89f24c21c input=e221baa01044c44c]*/
Guido van Rossume027d982002-04-12 15:11:59 +00003103{
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003104 return _PyDict_Pop((PyObject*)self, key, default_value);
Guido van Rossume027d982002-04-12 15:11:59 +00003105}
3106
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003107/*[clinic input]
3108dict.popitem
3109
3110Remove and return a (key, value) pair as a 2-tuple.
3111
3112Pairs are returned in LIFO (last-in, first-out) order.
3113Raises KeyError if the dict is empty.
3114[clinic start generated code]*/
3115
Guido van Rossume027d982002-04-12 15:11:59 +00003116static PyObject *
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003117dict_popitem_impl(PyDictObject *self)
3118/*[clinic end generated code: output=e65fcb04420d230d input=1c38a49f21f64941]*/
Guido van Rossumba6ab842000-12-12 22:02:18 +00003119{
Victor Stinner742da042016-09-07 17:40:12 -07003120 Py_ssize_t i, j;
3121 PyDictKeyEntry *ep0, *ep;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003122 PyObject *res;
Guido van Rossumba6ab842000-12-12 22:02:18 +00003123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003124 /* Allocate the result tuple before checking the size. Believe it
3125 * or not, this allocation could trigger a garbage collection which
3126 * could empty the dict, so if we checked the size first and that
3127 * happened, the result would be an infinite loop (searching for an
3128 * entry that no longer exists). Note that the usual popitem()
3129 * idiom is "while d: k, v = d.popitem()". so needing to throw the
3130 * tuple away if the dict *is* empty isn't a significant
3131 * inefficiency -- possible, but unlikely in practice.
3132 */
3133 res = PyTuple_New(2);
3134 if (res == NULL)
3135 return NULL;
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003136 if (self->ma_used == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003137 Py_DECREF(res);
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003138 PyErr_SetString(PyExc_KeyError, "popitem(): dictionary is empty");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003139 return NULL;
3140 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003141 /* Convert split table to combined table */
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003142 if (self->ma_keys->dk_lookup == lookdict_split) {
3143 if (dictresize(self, DK_SIZE(self->ma_keys))) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003144 Py_DECREF(res);
3145 return NULL;
3146 }
3147 }
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003148 ENSURE_ALLOWS_DELETIONS(self);
Victor Stinner742da042016-09-07 17:40:12 -07003149
3150 /* Pop last item */
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003151 ep0 = DK_ENTRIES(self->ma_keys);
3152 i = self->ma_keys->dk_nentries - 1;
Victor Stinner742da042016-09-07 17:40:12 -07003153 while (i >= 0 && ep0[i].me_value == NULL) {
3154 i--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003155 }
Victor Stinner742da042016-09-07 17:40:12 -07003156 assert(i >= 0);
3157
3158 ep = &ep0[i];
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003159 j = lookdict_index(self->ma_keys, ep->me_hash, i);
Victor Stinner742da042016-09-07 17:40:12 -07003160 assert(j >= 0);
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003161 assert(dictkeys_get_index(self->ma_keys, j) == i);
3162 dictkeys_set_index(self->ma_keys, j, DKIX_DUMMY);
Victor Stinner742da042016-09-07 17:40:12 -07003163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003164 PyTuple_SET_ITEM(res, 0, ep->me_key);
3165 PyTuple_SET_ITEM(res, 1, ep->me_value);
Victor Stinner742da042016-09-07 17:40:12 -07003166 ep->me_key = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003167 ep->me_value = NULL;
Victor Stinner742da042016-09-07 17:40:12 -07003168 /* We can't dk_usable++ since there is DKIX_DUMMY in indices */
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003169 self->ma_keys->dk_nentries = i;
3170 self->ma_used--;
3171 self->ma_version_tag = DICT_NEXT_VERSION();
Victor Stinner0fc91ee2019-04-12 21:51:34 +02003172 ASSERT_CONSISTENT(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003173 return res;
Guido van Rossumba6ab842000-12-12 22:02:18 +00003174}
3175
Jeremy Hylton8caad492000-06-23 14:18:11 +00003176static int
3177dict_traverse(PyObject *op, visitproc visit, void *arg)
3178{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003179 PyDictObject *mp = (PyDictObject *)op;
Benjamin Peterson55f44522016-09-05 12:12:59 -07003180 PyDictKeysObject *keys = mp->ma_keys;
Serhiy Storchaka46825d22016-09-26 21:29:34 +03003181 PyDictKeyEntry *entries = DK_ENTRIES(keys);
Victor Stinner742da042016-09-07 17:40:12 -07003182 Py_ssize_t i, n = keys->dk_nentries;
3183
Benjamin Peterson55f44522016-09-05 12:12:59 -07003184 if (keys->dk_lookup == lookdict) {
3185 for (i = 0; i < n; i++) {
3186 if (entries[i].me_value != NULL) {
3187 Py_VISIT(entries[i].me_value);
3188 Py_VISIT(entries[i].me_key);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003189 }
3190 }
Victor Stinner742da042016-09-07 17:40:12 -07003191 }
3192 else {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003193 if (mp->ma_values != NULL) {
Benjamin Peterson55f44522016-09-05 12:12:59 -07003194 for (i = 0; i < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003195 Py_VISIT(mp->ma_values[i]);
3196 }
3197 }
3198 else {
Benjamin Peterson55f44522016-09-05 12:12:59 -07003199 for (i = 0; i < n; i++) {
3200 Py_VISIT(entries[i].me_value);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003201 }
3202 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003203 }
3204 return 0;
Jeremy Hylton8caad492000-06-23 14:18:11 +00003205}
3206
3207static int
3208dict_tp_clear(PyObject *op)
3209{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003210 PyDict_Clear(op);
3211 return 0;
Jeremy Hylton8caad492000-06-23 14:18:11 +00003212}
3213
Guido van Rossum8ce8a782007-11-01 19:42:39 +00003214static PyObject *dictiter_new(PyDictObject *, PyTypeObject *);
Guido van Rossum09e563a2001-05-01 12:10:21 +00003215
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +02003216Py_ssize_t
Eric Snow96c6af92015-05-29 22:21:39 -06003217_PyDict_SizeOf(PyDictObject *mp)
Martin v. Löwis00709aa2008-06-04 14:18:43 +00003218{
Victor Stinner742da042016-09-07 17:40:12 -07003219 Py_ssize_t size, usable, res;
Martin v. Löwis00709aa2008-06-04 14:18:43 +00003220
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003221 size = DK_SIZE(mp->ma_keys);
Victor Stinner742da042016-09-07 17:40:12 -07003222 usable = USABLE_FRACTION(size);
3223
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02003224 res = _PyObject_SIZE(Py_TYPE(mp));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003225 if (mp->ma_values)
Victor Stinner742da042016-09-07 17:40:12 -07003226 res += usable * sizeof(PyObject*);
Martin v. Loewis4f2f3b62012-04-24 19:13:57 +02003227 /* If the dictionary is split, the keys portion is accounted-for
3228 in the type object. */
3229 if (mp->ma_keys->dk_refcnt == 1)
Victor Stinner98ee9d52016-09-08 09:33:56 -07003230 res += (sizeof(PyDictKeysObject)
Victor Stinner98ee9d52016-09-08 09:33:56 -07003231 + DK_IXSIZE(mp->ma_keys) * size
3232 + sizeof(PyDictKeyEntry) * usable);
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +02003233 return res;
Martin v. Loewis4f2f3b62012-04-24 19:13:57 +02003234}
3235
3236Py_ssize_t
3237_PyDict_KeysSize(PyDictKeysObject *keys)
3238{
Victor Stinner98ee9d52016-09-08 09:33:56 -07003239 return (sizeof(PyDictKeysObject)
Victor Stinner98ee9d52016-09-08 09:33:56 -07003240 + DK_IXSIZE(keys) * DK_SIZE(keys)
3241 + USABLE_FRACTION(DK_SIZE(keys)) * sizeof(PyDictKeyEntry));
Martin v. Löwis00709aa2008-06-04 14:18:43 +00003242}
3243
doko@ubuntu.com17210f52016-01-14 14:04:59 +01003244static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303245dict_sizeof(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +02003246{
3247 return PyLong_FromSsize_t(_PyDict_SizeOf(mp));
3248}
3249
Brandt Buchereb8ac572020-02-24 19:47:34 -08003250static PyObject *
3251dict_or(PyObject *self, PyObject *other)
3252{
3253 if (!PyDict_Check(self) || !PyDict_Check(other)) {
3254 Py_RETURN_NOTIMPLEMENTED;
3255 }
3256 PyObject *new = PyDict_Copy(self);
3257 if (new == NULL) {
3258 return NULL;
3259 }
3260 if (dict_update_arg(new, other)) {
3261 Py_DECREF(new);
3262 return NULL;
3263 }
3264 return new;
3265}
3266
3267static PyObject *
3268dict_ior(PyObject *self, PyObject *other)
3269{
3270 if (dict_update_arg(self, other)) {
3271 return NULL;
3272 }
3273 Py_INCREF(self);
3274 return self;
3275}
3276
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00003277PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]");
3278
Martin v. Löwis00709aa2008-06-04 14:18:43 +00003279PyDoc_STRVAR(sizeof__doc__,
3280"D.__sizeof__() -> size of D in memory, in bytes");
3281
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003282PyDoc_STRVAR(update__doc__,
Brett Cannonf2754162013-05-11 14:46:48 -04003283"D.update([E, ]**F) -> None. Update D from dict/iterable E and F.\n\
3284If E is present and has a .keys() method, then does: for k in E: D[k] = E[k]\n\
3285If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v\n\
3286In either case, this is followed by: for k in F: D[k] = F[k]");
Tim Petersf7f88b12000-12-13 23:18:45 +00003287
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003288PyDoc_STRVAR(clear__doc__,
3289"D.clear() -> None. Remove all items from D.");
Tim Petersf7f88b12000-12-13 23:18:45 +00003290
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003291PyDoc_STRVAR(copy__doc__,
3292"D.copy() -> a shallow copy of D");
Tim Petersf7f88b12000-12-13 23:18:45 +00003293
Guido van Rossumb90c8482007-02-10 01:11:45 +00003294/* Forward */
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303295static PyObject *dictkeys_new(PyObject *, PyObject *);
3296static PyObject *dictitems_new(PyObject *, PyObject *);
3297static PyObject *dictvalues_new(PyObject *, PyObject *);
Guido van Rossumb90c8482007-02-10 01:11:45 +00003298
Guido van Rossum45c85d12007-07-27 16:31:40 +00003299PyDoc_STRVAR(keys__doc__,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003300 "D.keys() -> a set-like object providing a view on D's keys");
Guido van Rossum45c85d12007-07-27 16:31:40 +00003301PyDoc_STRVAR(items__doc__,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003302 "D.items() -> a set-like object providing a view on D's items");
Guido van Rossum45c85d12007-07-27 16:31:40 +00003303PyDoc_STRVAR(values__doc__,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003304 "D.values() -> an object providing a view on D's values");
Guido van Rossumb90c8482007-02-10 01:11:45 +00003305
Guido van Rossumc0b618a1997-05-02 03:12:38 +00003306static PyMethodDef mapp_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -07003307 DICT___CONTAINS___METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003308 {"__getitem__", (PyCFunction)(void(*)(void))dict_subscript, METH_O | METH_COEXIST,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003309 getitem__doc__},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003310 {"__sizeof__", (PyCFunction)(void(*)(void))dict_sizeof, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003311 sizeof__doc__},
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003312 DICT_GET_METHODDEF
3313 DICT_SETDEFAULT_METHODDEF
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003314 DICT_POP_METHODDEF
3315 DICT_POPITEM_METHODDEF
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303316 {"keys", dictkeys_new, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003317 keys__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303318 {"items", dictitems_new, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003319 items__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303320 {"values", dictvalues_new, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003321 values__doc__},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003322 {"update", (PyCFunction)(void(*)(void))dict_update, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003323 update__doc__},
Larry Hastings5c661892014-01-24 06:17:25 -08003324 DICT_FROMKEYS_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003325 {"clear", (PyCFunction)dict_clear, METH_NOARGS,
3326 clear__doc__},
3327 {"copy", (PyCFunction)dict_copy, METH_NOARGS,
3328 copy__doc__},
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003329 DICT___REVERSED___METHODDEF
Guido van Rossum48b069a2020-04-07 09:50:06 -07003330 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003331 {NULL, NULL} /* sentinel */
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003332};
3333
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00003334/* Return 1 if `key` is in dict `op`, 0 if not, and -1 on error. */
Raymond Hettingerbc0f2ab2003-11-25 21:12:14 +00003335int
3336PyDict_Contains(PyObject *op, PyObject *key)
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003337{
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003338 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07003339 Py_ssize_t ix;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003340 PyDictObject *mp = (PyDictObject *)op;
INADA Naokiba609772016-12-07 20:41:42 +09003341 PyObject *value;
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003343 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003344 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003345 hash = PyObject_Hash(key);
3346 if (hash == -1)
3347 return -1;
3348 }
INADA Naoki778928b2017-08-03 23:45:15 +09003349 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07003350 if (ix == DKIX_ERROR)
3351 return -1;
INADA Naokiba609772016-12-07 20:41:42 +09003352 return (ix != DKIX_EMPTY && value != NULL);
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003353}
3354
Thomas Wouterscf297e42007-02-23 15:07:44 +00003355/* Internal version of PyDict_Contains used when the hash value is already known */
3356int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003357_PyDict_Contains(PyObject *op, PyObject *key, Py_hash_t hash)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003358{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003359 PyDictObject *mp = (PyDictObject *)op;
INADA Naokiba609772016-12-07 20:41:42 +09003360 PyObject *value;
Victor Stinner742da042016-09-07 17:40:12 -07003361 Py_ssize_t ix;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003362
INADA Naoki778928b2017-08-03 23:45:15 +09003363 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07003364 if (ix == DKIX_ERROR)
3365 return -1;
INADA Naokiba609772016-12-07 20:41:42 +09003366 return (ix != DKIX_EMPTY && value != NULL);
Thomas Wouterscf297e42007-02-23 15:07:44 +00003367}
3368
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003369/* Hack to implement "key in dict" */
3370static PySequenceMethods dict_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003371 0, /* sq_length */
3372 0, /* sq_concat */
3373 0, /* sq_repeat */
3374 0, /* sq_item */
3375 0, /* sq_slice */
3376 0, /* sq_ass_item */
3377 0, /* sq_ass_slice */
3378 PyDict_Contains, /* sq_contains */
3379 0, /* sq_inplace_concat */
3380 0, /* sq_inplace_repeat */
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003381};
3382
Brandt Buchereb8ac572020-02-24 19:47:34 -08003383static PyNumberMethods dict_as_number = {
3384 .nb_or = dict_or,
3385 .nb_inplace_or = dict_ior,
3386};
3387
Guido van Rossum09e563a2001-05-01 12:10:21 +00003388static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +00003389dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3390{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003391 PyObject *self;
Victor Stinnera9f61a52013-07-16 22:17:26 +02003392 PyDictObject *d;
Tim Peters6d6c1a32001-08-02 04:15:00 +00003393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003394 assert(type != NULL && type->tp_alloc != NULL);
3395 self = type->tp_alloc(type, 0);
Victor Stinnera9f61a52013-07-16 22:17:26 +02003396 if (self == NULL)
3397 return NULL;
Victor Stinnera9f61a52013-07-16 22:17:26 +02003398 d = (PyDictObject *)self;
Victor Stinnerac2a4fe2013-07-16 22:19:00 +02003399
Victor Stinnera9f61a52013-07-16 22:17:26 +02003400 /* The object has been implicitly tracked by tp_alloc */
Inada Naokidb6d9a52020-08-04 11:08:06 +09003401 if (type == &PyDict_Type) {
Victor Stinnera9f61a52013-07-16 22:17:26 +02003402 _PyObject_GC_UNTRACK(d);
Inada Naokidb6d9a52020-08-04 11:08:06 +09003403 }
Victor Stinnerac2a4fe2013-07-16 22:19:00 +02003404
3405 d->ma_used = 0;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07003406 d->ma_version_tag = DICT_NEXT_VERSION();
Inada Naokidb6d9a52020-08-04 11:08:06 +09003407 dictkeys_incref(Py_EMPTY_KEYS);
3408 d->ma_keys = Py_EMPTY_KEYS;
3409 d->ma_values = empty_values;
Victor Stinner0fc91ee2019-04-12 21:51:34 +02003410 ASSERT_CONSISTENT(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003411 return self;
Tim Peters6d6c1a32001-08-02 04:15:00 +00003412}
3413
Tim Peters25786c02001-09-02 08:22:48 +00003414static int
3415dict_init(PyObject *self, PyObject *args, PyObject *kwds)
3416{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003417 return dict_update_common(self, args, kwds, "dict");
Tim Peters25786c02001-09-02 08:22:48 +00003418}
3419
Tim Peters6d6c1a32001-08-02 04:15:00 +00003420static PyObject *
Dong-hee Nae27916b2020-04-02 09:55:43 +09003421dict_vectorcall(PyObject *type, PyObject * const*args,
3422 size_t nargsf, PyObject *kwnames)
3423{
3424 assert(PyType_Check(type));
3425 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
3426 if (!_PyArg_CheckPositional("dict", nargs, 0, 1)) {
3427 return NULL;
3428 }
3429
3430 PyObject *self = dict_new((PyTypeObject *)type, NULL, NULL);
3431 if (self == NULL) {
3432 return NULL;
3433 }
3434 if (nargs == 1) {
3435 if (dict_update_arg(self, args[0]) < 0) {
3436 Py_DECREF(self);
3437 return NULL;
3438 }
3439 args++;
3440 }
3441 if (kwnames != NULL) {
3442 for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(kwnames); i++) {
3443 if (PyDict_SetItem(self, PyTuple_GET_ITEM(kwnames, i), args[i]) < 0) {
3444 Py_DECREF(self);
3445 return NULL;
3446 }
3447 }
3448 }
3449 return self;
3450}
3451
3452static PyObject *
Guido van Rossum8ce8a782007-11-01 19:42:39 +00003453dict_iter(PyDictObject *dict)
Guido van Rossum09e563a2001-05-01 12:10:21 +00003454{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003455 return dictiter_new(dict, &PyDictIterKey_Type);
Guido van Rossum09e563a2001-05-01 12:10:21 +00003456}
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003457
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003458PyDoc_STRVAR(dictionary_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00003459"dict() -> new empty dictionary\n"
Tim Petersa427a2b2001-10-29 22:25:45 +00003460"dict(mapping) -> new dictionary initialized from a mapping object's\n"
Ezio Melotti7f807b72010-03-01 04:08:34 +00003461" (key, value) pairs\n"
3462"dict(iterable) -> new dictionary initialized as if via:\n"
Tim Peters4d859532001-10-27 18:27:48 +00003463" d = {}\n"
Ezio Melotti7f807b72010-03-01 04:08:34 +00003464" for k, v in iterable:\n"
Just van Rossuma797d812002-11-23 09:45:04 +00003465" d[k] = v\n"
3466"dict(**kwargs) -> new dictionary initialized with the name=value pairs\n"
3467" in the keyword argument list. For example: dict(one=1, two=2)");
Tim Peters25786c02001-09-02 08:22:48 +00003468
Guido van Rossumc0b618a1997-05-02 03:12:38 +00003469PyTypeObject PyDict_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003470 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3471 "dict",
3472 sizeof(PyDictObject),
3473 0,
3474 (destructor)dict_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003475 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003476 0, /* tp_getattr */
3477 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003478 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003479 (reprfunc)dict_repr, /* tp_repr */
Brandt Buchereb8ac572020-02-24 19:47:34 -08003480 &dict_as_number, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003481 &dict_as_sequence, /* tp_as_sequence */
3482 &dict_as_mapping, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00003483 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003484 0, /* tp_call */
3485 0, /* tp_str */
3486 PyObject_GenericGetAttr, /* tp_getattro */
3487 0, /* tp_setattro */
3488 0, /* tp_as_buffer */
3489 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
3490 Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DICT_SUBCLASS, /* tp_flags */
3491 dictionary_doc, /* tp_doc */
3492 dict_traverse, /* tp_traverse */
3493 dict_tp_clear, /* tp_clear */
3494 dict_richcompare, /* tp_richcompare */
3495 0, /* tp_weaklistoffset */
3496 (getiterfunc)dict_iter, /* tp_iter */
3497 0, /* tp_iternext */
3498 mapp_methods, /* tp_methods */
3499 0, /* tp_members */
3500 0, /* tp_getset */
3501 0, /* tp_base */
3502 0, /* tp_dict */
3503 0, /* tp_descr_get */
3504 0, /* tp_descr_set */
3505 0, /* tp_dictoffset */
3506 dict_init, /* tp_init */
3507 PyType_GenericAlloc, /* tp_alloc */
3508 dict_new, /* tp_new */
3509 PyObject_GC_Del, /* tp_free */
Dong-hee Nae27916b2020-04-02 09:55:43 +09003510 .tp_vectorcall = dict_vectorcall,
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003511};
3512
Victor Stinner3c1e4812012-03-26 22:10:51 +02003513PyObject *
3514_PyDict_GetItemId(PyObject *dp, struct _Py_Identifier *key)
3515{
3516 PyObject *kv;
3517 kv = _PyUnicode_FromId(key); /* borrowed */
Victor Stinner5b3b1002013-07-22 23:50:57 +02003518 if (kv == NULL) {
3519 PyErr_Clear();
Victor Stinner3c1e4812012-03-26 22:10:51 +02003520 return NULL;
Victor Stinner5b3b1002013-07-22 23:50:57 +02003521 }
Victor Stinner3c1e4812012-03-26 22:10:51 +02003522 return PyDict_GetItem(dp, kv);
3523}
3524
Guido van Rossum3cca2451997-05-16 14:23:33 +00003525/* For backward compatibility with old dictionary interface */
3526
Guido van Rossumc0b618a1997-05-02 03:12:38 +00003527PyObject *
Martin v. Löwis32b4a1b2002-12-11 13:21:12 +00003528PyDict_GetItemString(PyObject *v, const char *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003529{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003530 PyObject *kv, *rv;
3531 kv = PyUnicode_FromString(key);
Victor Stinnerfdcbab92013-07-16 22:16:05 +02003532 if (kv == NULL) {
3533 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003534 return NULL;
Victor Stinnerfdcbab92013-07-16 22:16:05 +02003535 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003536 rv = PyDict_GetItem(v, kv);
3537 Py_DECREF(kv);
3538 return rv;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003539}
3540
3541int
Victor Stinner3c1e4812012-03-26 22:10:51 +02003542_PyDict_SetItemId(PyObject *v, struct _Py_Identifier *key, PyObject *item)
3543{
3544 PyObject *kv;
3545 kv = _PyUnicode_FromId(key); /* borrowed */
3546 if (kv == NULL)
3547 return -1;
3548 return PyDict_SetItem(v, kv, item);
3549}
3550
3551int
Martin v. Löwis32b4a1b2002-12-11 13:21:12 +00003552PyDict_SetItemString(PyObject *v, const char *key, PyObject *item)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003553{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003554 PyObject *kv;
3555 int err;
3556 kv = PyUnicode_FromString(key);
3557 if (kv == NULL)
3558 return -1;
3559 PyUnicode_InternInPlace(&kv); /* XXX Should we really? */
3560 err = PyDict_SetItem(v, kv, item);
3561 Py_DECREF(kv);
3562 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003563}
3564
3565int
Victor Stinner5fd2e5a2013-11-06 18:58:22 +01003566_PyDict_DelItemId(PyObject *v, _Py_Identifier *key)
3567{
3568 PyObject *kv = _PyUnicode_FromId(key); /* borrowed */
3569 if (kv == NULL)
3570 return -1;
3571 return PyDict_DelItem(v, kv);
3572}
3573
3574int
Martin v. Löwis32b4a1b2002-12-11 13:21:12 +00003575PyDict_DelItemString(PyObject *v, const char *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003576{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003577 PyObject *kv;
3578 int err;
3579 kv = PyUnicode_FromString(key);
3580 if (kv == NULL)
3581 return -1;
3582 err = PyDict_DelItem(v, kv);
3583 Py_DECREF(kv);
3584 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003585}
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003586
Raymond Hettinger019a1482004-03-18 02:41:19 +00003587/* Dictionary iterator types */
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003588
3589typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003590 PyObject_HEAD
3591 PyDictObject *di_dict; /* Set to NULL when iterator is exhausted */
3592 Py_ssize_t di_used;
3593 Py_ssize_t di_pos;
3594 PyObject* di_result; /* reusable result tuple for iteritems */
3595 Py_ssize_t len;
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003596} dictiterobject;
3597
3598static PyObject *
Guido van Rossum8ce8a782007-11-01 19:42:39 +00003599dictiter_new(PyDictObject *dict, PyTypeObject *itertype)
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003600{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003601 dictiterobject *di;
3602 di = PyObject_GC_New(dictiterobject, itertype);
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003603 if (di == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003604 return NULL;
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003605 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003606 Py_INCREF(dict);
3607 di->di_dict = dict;
3608 di->di_used = dict->ma_used;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003609 di->len = dict->ma_used;
Dong-hee Na24dc2f82019-10-20 05:01:08 +09003610 if (itertype == &PyDictRevIterKey_Type ||
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003611 itertype == &PyDictRevIterItem_Type ||
Dong-hee Na24dc2f82019-10-20 05:01:08 +09003612 itertype == &PyDictRevIterValue_Type) {
3613 if (dict->ma_values) {
3614 di->di_pos = dict->ma_used - 1;
3615 }
3616 else {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003617 di->di_pos = dict->ma_keys->dk_nentries - 1;
Dong-hee Na24dc2f82019-10-20 05:01:08 +09003618 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003619 }
3620 else {
3621 di->di_pos = 0;
3622 }
3623 if (itertype == &PyDictIterItem_Type ||
3624 itertype == &PyDictRevIterItem_Type) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003625 di->di_result = PyTuple_Pack(2, Py_None, Py_None);
3626 if (di->di_result == NULL) {
3627 Py_DECREF(di);
3628 return NULL;
3629 }
3630 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003631 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003632 di->di_result = NULL;
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003633 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003634 _PyObject_GC_TRACK(di);
3635 return (PyObject *)di;
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003636}
3637
3638static void
3639dictiter_dealloc(dictiterobject *di)
3640{
INADA Naokia6296d32017-08-24 14:55:17 +09003641 /* bpo-31095: UnTrack is needed before calling any callbacks */
3642 _PyObject_GC_UNTRACK(di);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003643 Py_XDECREF(di->di_dict);
3644 Py_XDECREF(di->di_result);
3645 PyObject_GC_Del(di);
Antoine Pitrou7ddda782009-01-01 15:35:33 +00003646}
3647
3648static int
3649dictiter_traverse(dictiterobject *di, visitproc visit, void *arg)
3650{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003651 Py_VISIT(di->di_dict);
3652 Py_VISIT(di->di_result);
3653 return 0;
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003654}
3655
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00003656static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303657dictiter_len(dictiterobject *di, PyObject *Py_UNUSED(ignored))
Raymond Hettinger0ce6dc82004-03-18 08:38:00 +00003658{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003659 Py_ssize_t len = 0;
3660 if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used)
3661 len = di->len;
3662 return PyLong_FromSize_t(len);
Raymond Hettinger0ce6dc82004-03-18 08:38:00 +00003663}
3664
Guido van Rossumb90c8482007-02-10 01:11:45 +00003665PyDoc_STRVAR(length_hint_doc,
3666 "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00003667
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003668static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303669dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored));
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003670
3671PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
3672
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00003673static PyMethodDef dictiter_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003674 {"__length_hint__", (PyCFunction)(void(*)(void))dictiter_len, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003675 length_hint_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003676 {"__reduce__", (PyCFunction)(void(*)(void))dictiter_reduce, METH_NOARGS,
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003677 reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003678 {NULL, NULL} /* sentinel */
Raymond Hettinger0ce6dc82004-03-18 08:38:00 +00003679};
3680
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003681static PyObject*
3682dictiter_iternextkey(dictiterobject *di)
Guido van Rossum213c7a62001-04-23 14:08:49 +00003683{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003684 PyObject *key;
INADA Naokica2d8be2016-11-04 16:59:10 +09003685 Py_ssize_t i;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02003686 PyDictKeysObject *k;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003687 PyDictObject *d = di->di_dict;
Guido van Rossum213c7a62001-04-23 14:08:49 +00003688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003689 if (d == NULL)
3690 return NULL;
3691 assert (PyDict_Check(d));
Guido van Rossum2147df72002-07-16 20:30:22 +00003692
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003693 if (di->di_used != d->ma_used) {
3694 PyErr_SetString(PyExc_RuntimeError,
3695 "dictionary changed size during iteration");
3696 di->di_used = -1; /* Make this state sticky */
3697 return NULL;
3698 }
Guido van Rossum2147df72002-07-16 20:30:22 +00003699
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003700 i = di->di_pos;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003701 k = d->ma_keys;
INADA Naokica2d8be2016-11-04 16:59:10 +09003702 assert(i >= 0);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003703 if (d->ma_values) {
INADA Naokica2d8be2016-11-04 16:59:10 +09003704 if (i >= d->ma_used)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003705 goto fail;
3706 key = DK_ENTRIES(k)[i].me_key;
INADA Naokica2d8be2016-11-04 16:59:10 +09003707 assert(d->ma_values[i] != NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003708 }
3709 else {
INADA Naokica2d8be2016-11-04 16:59:10 +09003710 Py_ssize_t n = k->dk_nentries;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003711 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i];
3712 while (i < n && entry_ptr->me_value == NULL) {
3713 entry_ptr++;
3714 i++;
3715 }
3716 if (i >= n)
3717 goto fail;
3718 key = entry_ptr->me_key;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003719 }
Thomas Perl796cc6e2019-03-28 07:03:25 +01003720 // We found an element (key), but did not expect it
3721 if (di->len == 0) {
3722 PyErr_SetString(PyExc_RuntimeError,
3723 "dictionary keys changed during iteration");
3724 goto fail;
3725 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003726 di->di_pos = i+1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003727 di->len--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003728 Py_INCREF(key);
3729 return key;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003730
3731fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003732 di->di_dict = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +03003733 Py_DECREF(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003734 return NULL;
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003735}
3736
Raymond Hettinger019a1482004-03-18 02:41:19 +00003737PyTypeObject PyDictIterKey_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003738 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3739 "dict_keyiterator", /* tp_name */
3740 sizeof(dictiterobject), /* tp_basicsize */
3741 0, /* tp_itemsize */
3742 /* methods */
3743 (destructor)dictiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003744 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003745 0, /* tp_getattr */
3746 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003747 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003748 0, /* tp_repr */
3749 0, /* tp_as_number */
3750 0, /* tp_as_sequence */
3751 0, /* tp_as_mapping */
3752 0, /* tp_hash */
3753 0, /* tp_call */
3754 0, /* tp_str */
3755 PyObject_GenericGetAttr, /* tp_getattro */
3756 0, /* tp_setattro */
3757 0, /* tp_as_buffer */
3758 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
3759 0, /* tp_doc */
3760 (traverseproc)dictiter_traverse, /* tp_traverse */
3761 0, /* tp_clear */
3762 0, /* tp_richcompare */
3763 0, /* tp_weaklistoffset */
3764 PyObject_SelfIter, /* tp_iter */
3765 (iternextfunc)dictiter_iternextkey, /* tp_iternext */
3766 dictiter_methods, /* tp_methods */
3767 0,
Raymond Hettinger019a1482004-03-18 02:41:19 +00003768};
3769
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003770static PyObject *
3771dictiter_iternextvalue(dictiterobject *di)
Raymond Hettinger019a1482004-03-18 02:41:19 +00003772{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003773 PyObject *value;
INADA Naokica2d8be2016-11-04 16:59:10 +09003774 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003775 PyDictObject *d = di->di_dict;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003777 if (d == NULL)
3778 return NULL;
3779 assert (PyDict_Check(d));
Raymond Hettinger019a1482004-03-18 02:41:19 +00003780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003781 if (di->di_used != d->ma_used) {
3782 PyErr_SetString(PyExc_RuntimeError,
3783 "dictionary changed size during iteration");
3784 di->di_used = -1; /* Make this state sticky */
3785 return NULL;
3786 }
Raymond Hettinger019a1482004-03-18 02:41:19 +00003787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003788 i = di->di_pos;
INADA Naokica2d8be2016-11-04 16:59:10 +09003789 assert(i >= 0);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003790 if (d->ma_values) {
INADA Naokica2d8be2016-11-04 16:59:10 +09003791 if (i >= d->ma_used)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003792 goto fail;
INADA Naokica2d8be2016-11-04 16:59:10 +09003793 value = d->ma_values[i];
3794 assert(value != NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003795 }
3796 else {
INADA Naokica2d8be2016-11-04 16:59:10 +09003797 Py_ssize_t n = d->ma_keys->dk_nentries;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003798 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i];
3799 while (i < n && entry_ptr->me_value == NULL) {
3800 entry_ptr++;
3801 i++;
3802 }
3803 if (i >= n)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003804 goto fail;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003805 value = entry_ptr->me_value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003806 }
Thomas Perlb8311cf2019-04-02 11:30:10 +02003807 // We found an element, but did not expect it
3808 if (di->len == 0) {
3809 PyErr_SetString(PyExc_RuntimeError,
3810 "dictionary keys changed during iteration");
3811 goto fail;
3812 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003813 di->di_pos = i+1;
3814 di->len--;
3815 Py_INCREF(value);
3816 return value;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003817
3818fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003819 di->di_dict = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +03003820 Py_DECREF(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003821 return NULL;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003822}
3823
3824PyTypeObject PyDictIterValue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003825 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3826 "dict_valueiterator", /* tp_name */
3827 sizeof(dictiterobject), /* tp_basicsize */
3828 0, /* tp_itemsize */
3829 /* methods */
3830 (destructor)dictiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003831 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003832 0, /* tp_getattr */
3833 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003834 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003835 0, /* tp_repr */
3836 0, /* tp_as_number */
3837 0, /* tp_as_sequence */
3838 0, /* tp_as_mapping */
3839 0, /* tp_hash */
3840 0, /* tp_call */
3841 0, /* tp_str */
3842 PyObject_GenericGetAttr, /* tp_getattro */
3843 0, /* tp_setattro */
3844 0, /* tp_as_buffer */
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003845 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003846 0, /* tp_doc */
3847 (traverseproc)dictiter_traverse, /* tp_traverse */
3848 0, /* tp_clear */
3849 0, /* tp_richcompare */
3850 0, /* tp_weaklistoffset */
3851 PyObject_SelfIter, /* tp_iter */
3852 (iternextfunc)dictiter_iternextvalue, /* tp_iternext */
3853 dictiter_methods, /* tp_methods */
3854 0,
Raymond Hettinger019a1482004-03-18 02:41:19 +00003855};
3856
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003857static PyObject *
3858dictiter_iternextitem(dictiterobject *di)
Raymond Hettinger019a1482004-03-18 02:41:19 +00003859{
Serhiy Storchaka753bca32017-05-20 12:30:02 +03003860 PyObject *key, *value, *result;
INADA Naokica2d8be2016-11-04 16:59:10 +09003861 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003862 PyDictObject *d = di->di_dict;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003864 if (d == NULL)
3865 return NULL;
3866 assert (PyDict_Check(d));
Raymond Hettinger019a1482004-03-18 02:41:19 +00003867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003868 if (di->di_used != d->ma_used) {
3869 PyErr_SetString(PyExc_RuntimeError,
3870 "dictionary changed size during iteration");
3871 di->di_used = -1; /* Make this state sticky */
3872 return NULL;
3873 }
Raymond Hettinger019a1482004-03-18 02:41:19 +00003874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003875 i = di->di_pos;
INADA Naokica2d8be2016-11-04 16:59:10 +09003876 assert(i >= 0);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003877 if (d->ma_values) {
INADA Naokica2d8be2016-11-04 16:59:10 +09003878 if (i >= d->ma_used)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003879 goto fail;
3880 key = DK_ENTRIES(d->ma_keys)[i].me_key;
INADA Naokica2d8be2016-11-04 16:59:10 +09003881 value = d->ma_values[i];
3882 assert(value != NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003883 }
3884 else {
INADA Naokica2d8be2016-11-04 16:59:10 +09003885 Py_ssize_t n = d->ma_keys->dk_nentries;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003886 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i];
3887 while (i < n && entry_ptr->me_value == NULL) {
3888 entry_ptr++;
3889 i++;
3890 }
3891 if (i >= n)
3892 goto fail;
3893 key = entry_ptr->me_key;
3894 value = entry_ptr->me_value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003895 }
Thomas Perlb8311cf2019-04-02 11:30:10 +02003896 // We found an element, but did not expect it
3897 if (di->len == 0) {
3898 PyErr_SetString(PyExc_RuntimeError,
3899 "dictionary keys changed during iteration");
3900 goto fail;
3901 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003902 di->di_pos = i+1;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003903 di->len--;
Serhiy Storchaka753bca32017-05-20 12:30:02 +03003904 Py_INCREF(key);
3905 Py_INCREF(value);
3906 result = di->di_result;
3907 if (Py_REFCNT(result) == 1) {
3908 PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
3909 PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
3910 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
3911 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003912 Py_INCREF(result);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03003913 Py_DECREF(oldkey);
3914 Py_DECREF(oldvalue);
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003915 }
3916 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003917 result = PyTuple_New(2);
3918 if (result == NULL)
3919 return NULL;
Serhiy Storchaka753bca32017-05-20 12:30:02 +03003920 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
3921 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003922 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003923 return result;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003924
3925fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003926 di->di_dict = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +03003927 Py_DECREF(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003928 return NULL;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003929}
3930
3931PyTypeObject PyDictIterItem_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003932 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3933 "dict_itemiterator", /* tp_name */
3934 sizeof(dictiterobject), /* tp_basicsize */
3935 0, /* tp_itemsize */
3936 /* methods */
3937 (destructor)dictiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003938 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003939 0, /* tp_getattr */
3940 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003941 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003942 0, /* tp_repr */
3943 0, /* tp_as_number */
3944 0, /* tp_as_sequence */
3945 0, /* tp_as_mapping */
3946 0, /* tp_hash */
3947 0, /* tp_call */
3948 0, /* tp_str */
3949 PyObject_GenericGetAttr, /* tp_getattro */
3950 0, /* tp_setattro */
3951 0, /* tp_as_buffer */
3952 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
3953 0, /* tp_doc */
3954 (traverseproc)dictiter_traverse, /* tp_traverse */
3955 0, /* tp_clear */
3956 0, /* tp_richcompare */
3957 0, /* tp_weaklistoffset */
3958 PyObject_SelfIter, /* tp_iter */
3959 (iternextfunc)dictiter_iternextitem, /* tp_iternext */
3960 dictiter_methods, /* tp_methods */
3961 0,
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003962};
Guido van Rossumb90c8482007-02-10 01:11:45 +00003963
3964
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003965/* dictreviter */
3966
3967static PyObject *
3968dictreviter_iternext(dictiterobject *di)
3969{
3970 PyDictObject *d = di->di_dict;
3971
3972 if (d == NULL) {
3973 return NULL;
3974 }
3975 assert (PyDict_Check(d));
3976
3977 if (di->di_used != d->ma_used) {
3978 PyErr_SetString(PyExc_RuntimeError,
3979 "dictionary changed size during iteration");
3980 di->di_used = -1; /* Make this state sticky */
3981 return NULL;
3982 }
3983
3984 Py_ssize_t i = di->di_pos;
3985 PyDictKeysObject *k = d->ma_keys;
3986 PyObject *key, *value, *result;
3987
Serhiy Storchaka2e3d8732019-10-23 14:48:08 +03003988 if (i < 0) {
3989 goto fail;
3990 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003991 if (d->ma_values) {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003992 key = DK_ENTRIES(k)[i].me_key;
3993 value = d->ma_values[i];
3994 assert (value != NULL);
3995 }
3996 else {
3997 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i];
Serhiy Storchaka2e3d8732019-10-23 14:48:08 +03003998 while (entry_ptr->me_value == NULL) {
3999 if (--i < 0) {
4000 goto fail;
4001 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004002 entry_ptr--;
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004003 }
4004 key = entry_ptr->me_key;
4005 value = entry_ptr->me_value;
4006 }
4007 di->di_pos = i-1;
4008 di->len--;
4009
Dong-hee Na1b55b652020-02-17 19:09:15 +09004010 if (Py_IS_TYPE(di, &PyDictRevIterKey_Type)) {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004011 Py_INCREF(key);
4012 return key;
4013 }
Dong-hee Na1b55b652020-02-17 19:09:15 +09004014 else if (Py_IS_TYPE(di, &PyDictRevIterValue_Type)) {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004015 Py_INCREF(value);
4016 return value;
4017 }
Dong-hee Na1b55b652020-02-17 19:09:15 +09004018 else if (Py_IS_TYPE(di, &PyDictRevIterItem_Type)) {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004019 Py_INCREF(key);
4020 Py_INCREF(value);
4021 result = di->di_result;
4022 if (Py_REFCNT(result) == 1) {
4023 PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
4024 PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
4025 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
4026 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
4027 Py_INCREF(result);
4028 Py_DECREF(oldkey);
4029 Py_DECREF(oldvalue);
4030 }
4031 else {
4032 result = PyTuple_New(2);
4033 if (result == NULL) {
4034 return NULL;
4035 }
4036 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
4037 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
4038 }
4039 return result;
4040 }
4041 else {
4042 Py_UNREACHABLE();
4043 }
4044
4045fail:
4046 di->di_dict = NULL;
4047 Py_DECREF(d);
4048 return NULL;
4049}
4050
4051PyTypeObject PyDictRevIterKey_Type = {
4052 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4053 "dict_reversekeyiterator",
4054 sizeof(dictiterobject),
4055 .tp_dealloc = (destructor)dictiter_dealloc,
4056 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
4057 .tp_traverse = (traverseproc)dictiter_traverse,
4058 .tp_iter = PyObject_SelfIter,
4059 .tp_iternext = (iternextfunc)dictreviter_iternext,
4060 .tp_methods = dictiter_methods
4061};
4062
4063
4064/*[clinic input]
4065dict.__reversed__
4066
4067Return a reverse iterator over the dict keys.
4068[clinic start generated code]*/
4069
4070static PyObject *
4071dict___reversed___impl(PyDictObject *self)
4072/*[clinic end generated code: output=e674483336d1ed51 input=23210ef3477d8c4d]*/
4073{
4074 assert (PyDict_Check(self));
4075 return dictiter_new(self, &PyDictRevIterKey_Type);
4076}
4077
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004078static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304079dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004080{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02004081 _Py_IDENTIFIER(iter);
Sergey Fedoseev63958442018-10-20 05:43:33 +05004082 /* copy the iterator state */
4083 dictiterobject tmp = *di;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004084 Py_XINCREF(tmp.di_dict);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004085
Sergey Fedoseev63958442018-10-20 05:43:33 +05004086 PyObject *list = PySequence_List((PyObject*)&tmp);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004087 Py_XDECREF(tmp.di_dict);
Sergey Fedoseev63958442018-10-20 05:43:33 +05004088 if (list == NULL) {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004089 return NULL;
4090 }
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02004091 return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004092}
4093
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004094PyTypeObject PyDictRevIterItem_Type = {
4095 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4096 "dict_reverseitemiterator",
4097 sizeof(dictiterobject),
4098 .tp_dealloc = (destructor)dictiter_dealloc,
4099 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
4100 .tp_traverse = (traverseproc)dictiter_traverse,
4101 .tp_iter = PyObject_SelfIter,
4102 .tp_iternext = (iternextfunc)dictreviter_iternext,
4103 .tp_methods = dictiter_methods
4104};
4105
4106PyTypeObject PyDictRevIterValue_Type = {
4107 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4108 "dict_reversevalueiterator",
4109 sizeof(dictiterobject),
4110 .tp_dealloc = (destructor)dictiter_dealloc,
4111 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
4112 .tp_traverse = (traverseproc)dictiter_traverse,
4113 .tp_iter = PyObject_SelfIter,
4114 .tp_iternext = (iternextfunc)dictreviter_iternext,
4115 .tp_methods = dictiter_methods
4116};
4117
Guido van Rossum3ac67412007-02-10 18:55:06 +00004118/***********************************************/
Guido van Rossumb90c8482007-02-10 01:11:45 +00004119/* View objects for keys(), items(), values(). */
Guido van Rossum3ac67412007-02-10 18:55:06 +00004120/***********************************************/
4121
Guido van Rossumb90c8482007-02-10 01:11:45 +00004122/* The instance lay-out is the same for all three; but the type differs. */
4123
Guido van Rossumb90c8482007-02-10 01:11:45 +00004124static void
Eric Snow96c6af92015-05-29 22:21:39 -06004125dictview_dealloc(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004126{
INADA Naokia6296d32017-08-24 14:55:17 +09004127 /* bpo-31095: UnTrack is needed before calling any callbacks */
4128 _PyObject_GC_UNTRACK(dv);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004129 Py_XDECREF(dv->dv_dict);
4130 PyObject_GC_Del(dv);
Antoine Pitrou7ddda782009-01-01 15:35:33 +00004131}
4132
4133static int
Eric Snow96c6af92015-05-29 22:21:39 -06004134dictview_traverse(_PyDictViewObject *dv, visitproc visit, void *arg)
Antoine Pitrou7ddda782009-01-01 15:35:33 +00004135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004136 Py_VISIT(dv->dv_dict);
4137 return 0;
Guido van Rossumb90c8482007-02-10 01:11:45 +00004138}
4139
Guido van Rossum83825ac2007-02-10 04:54:19 +00004140static Py_ssize_t
Eric Snow96c6af92015-05-29 22:21:39 -06004141dictview_len(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004142{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004143 Py_ssize_t len = 0;
4144 if (dv->dv_dict != NULL)
4145 len = dv->dv_dict->ma_used;
4146 return len;
Guido van Rossumb90c8482007-02-10 01:11:45 +00004147}
4148
Eric Snow96c6af92015-05-29 22:21:39 -06004149PyObject *
4150_PyDictView_New(PyObject *dict, PyTypeObject *type)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004151{
Eric Snow96c6af92015-05-29 22:21:39 -06004152 _PyDictViewObject *dv;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004153 if (dict == NULL) {
4154 PyErr_BadInternalCall();
4155 return NULL;
4156 }
4157 if (!PyDict_Check(dict)) {
4158 /* XXX Get rid of this restriction later */
4159 PyErr_Format(PyExc_TypeError,
4160 "%s() requires a dict argument, not '%s'",
Victor Stinner58ac7002020-02-07 03:04:21 +01004161 type->tp_name, Py_TYPE(dict)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004162 return NULL;
4163 }
Eric Snow96c6af92015-05-29 22:21:39 -06004164 dv = PyObject_GC_New(_PyDictViewObject, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004165 if (dv == NULL)
4166 return NULL;
4167 Py_INCREF(dict);
4168 dv->dv_dict = (PyDictObject *)dict;
4169 _PyObject_GC_TRACK(dv);
4170 return (PyObject *)dv;
Guido van Rossumb90c8482007-02-10 01:11:45 +00004171}
4172
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004173static PyObject *
Pablo Galindo10c3b212020-06-15 02:05:20 +01004174dictview_mapping(PyObject *view, void *Py_UNUSED(ignored)) {
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004175 assert(view != NULL);
4176 assert(PyDictKeys_Check(view)
4177 || PyDictValues_Check(view)
4178 || PyDictItems_Check(view));
4179 PyObject *mapping = (PyObject *)((_PyDictViewObject *)view)->dv_dict;
4180 return PyDictProxy_New(mapping);
4181}
4182
4183static PyGetSetDef dictview_getset[] = {
Pablo Galindo10c3b212020-06-15 02:05:20 +01004184 {"mapping", dictview_mapping, (setter)NULL,
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004185 "dictionary that this view refers to", NULL},
4186 {0}
4187};
4188
Neal Norwitze36f2ba2007-02-26 23:12:28 +00004189/* TODO(guido): The views objects are not complete:
4190
4191 * support more set operations
4192 * support arbitrary mappings?
4193 - either these should be static or exported in dictobject.h
4194 - if public then they should probably be in builtins
4195*/
4196
Guido van Rossumaac530c2007-08-24 22:33:45 +00004197/* Return 1 if self is a subset of other, iterating over self;
4198 0 if not; -1 if an error occurred. */
Guido van Rossumd9214d12007-02-12 02:23:40 +00004199static int
4200all_contained_in(PyObject *self, PyObject *other)
4201{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004202 PyObject *iter = PyObject_GetIter(self);
4203 int ok = 1;
Guido van Rossumd9214d12007-02-12 02:23:40 +00004204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004205 if (iter == NULL)
4206 return -1;
4207 for (;;) {
4208 PyObject *next = PyIter_Next(iter);
4209 if (next == NULL) {
4210 if (PyErr_Occurred())
4211 ok = -1;
4212 break;
4213 }
4214 ok = PySequence_Contains(other, next);
4215 Py_DECREF(next);
4216 if (ok <= 0)
4217 break;
4218 }
4219 Py_DECREF(iter);
4220 return ok;
Guido van Rossumd9214d12007-02-12 02:23:40 +00004221}
4222
4223static PyObject *
4224dictview_richcompare(PyObject *self, PyObject *other, int op)
4225{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004226 Py_ssize_t len_self, len_other;
4227 int ok;
4228 PyObject *result;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004230 assert(self != NULL);
4231 assert(PyDictViewSet_Check(self));
4232 assert(other != NULL);
Guido van Rossumd9214d12007-02-12 02:23:40 +00004233
Brian Curtindfc80e32011-08-10 20:28:54 -05004234 if (!PyAnySet_Check(other) && !PyDictViewSet_Check(other))
4235 Py_RETURN_NOTIMPLEMENTED;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004237 len_self = PyObject_Size(self);
4238 if (len_self < 0)
4239 return NULL;
4240 len_other = PyObject_Size(other);
4241 if (len_other < 0)
4242 return NULL;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004244 ok = 0;
4245 switch(op) {
Guido van Rossumaac530c2007-08-24 22:33:45 +00004246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004247 case Py_NE:
4248 case Py_EQ:
4249 if (len_self == len_other)
4250 ok = all_contained_in(self, other);
4251 if (op == Py_NE && ok >= 0)
4252 ok = !ok;
4253 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004255 case Py_LT:
4256 if (len_self < len_other)
4257 ok = all_contained_in(self, other);
4258 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004260 case Py_LE:
4261 if (len_self <= len_other)
4262 ok = all_contained_in(self, other);
4263 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004265 case Py_GT:
4266 if (len_self > len_other)
4267 ok = all_contained_in(other, self);
4268 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004270 case Py_GE:
4271 if (len_self >= len_other)
4272 ok = all_contained_in(other, self);
4273 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004275 }
4276 if (ok < 0)
4277 return NULL;
4278 result = ok ? Py_True : Py_False;
4279 Py_INCREF(result);
4280 return result;
Guido van Rossumd9214d12007-02-12 02:23:40 +00004281}
4282
Raymond Hettingerb0d56af2009-03-03 10:52:49 +00004283static PyObject *
Eric Snow96c6af92015-05-29 22:21:39 -06004284dictview_repr(_PyDictViewObject *dv)
Raymond Hettingerb0d56af2009-03-03 10:52:49 +00004285{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004286 PyObject *seq;
bennorthd7773d92018-01-26 15:46:01 +00004287 PyObject *result = NULL;
4288 Py_ssize_t rc;
Raymond Hettingerb0d56af2009-03-03 10:52:49 +00004289
bennorthd7773d92018-01-26 15:46:01 +00004290 rc = Py_ReprEnter((PyObject *)dv);
4291 if (rc != 0) {
4292 return rc > 0 ? PyUnicode_FromString("...") : NULL;
4293 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004294 seq = PySequence_List((PyObject *)dv);
bennorthd7773d92018-01-26 15:46:01 +00004295 if (seq == NULL) {
4296 goto Done;
4297 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004298 result = PyUnicode_FromFormat("%s(%R)", Py_TYPE(dv)->tp_name, seq);
4299 Py_DECREF(seq);
bennorthd7773d92018-01-26 15:46:01 +00004300
4301Done:
4302 Py_ReprLeave((PyObject *)dv);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004303 return result;
Raymond Hettingerb0d56af2009-03-03 10:52:49 +00004304}
4305
Guido van Rossum3ac67412007-02-10 18:55:06 +00004306/*** dict_keys ***/
Guido van Rossumb90c8482007-02-10 01:11:45 +00004307
4308static PyObject *
Eric Snow96c6af92015-05-29 22:21:39 -06004309dictkeys_iter(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004310{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004311 if (dv->dv_dict == NULL) {
4312 Py_RETURN_NONE;
4313 }
4314 return dictiter_new(dv->dv_dict, &PyDictIterKey_Type);
Guido van Rossum3ac67412007-02-10 18:55:06 +00004315}
4316
4317static int
Eric Snow96c6af92015-05-29 22:21:39 -06004318dictkeys_contains(_PyDictViewObject *dv, PyObject *obj)
Guido van Rossum3ac67412007-02-10 18:55:06 +00004319{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004320 if (dv->dv_dict == NULL)
4321 return 0;
4322 return PyDict_Contains((PyObject *)dv->dv_dict, obj);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004323}
4324
Guido van Rossum83825ac2007-02-10 04:54:19 +00004325static PySequenceMethods dictkeys_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004326 (lenfunc)dictview_len, /* sq_length */
4327 0, /* sq_concat */
4328 0, /* sq_repeat */
4329 0, /* sq_item */
4330 0, /* sq_slice */
4331 0, /* sq_ass_item */
4332 0, /* sq_ass_slice */
4333 (objobjproc)dictkeys_contains, /* sq_contains */
Guido van Rossum83825ac2007-02-10 04:54:19 +00004334};
4335
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004336// Create an set object from dictviews object.
4337// Returns a new reference.
4338// This utility function is used by set operations.
Guido van Rossum523259b2007-08-24 23:41:22 +00004339static PyObject*
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004340dictviews_to_set(PyObject *self)
Guido van Rossum523259b2007-08-24 23:41:22 +00004341{
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004342 PyObject *left = self;
4343 if (PyDictKeys_Check(self)) {
4344 // PySet_New() has fast path for the dict object.
4345 PyObject *dict = (PyObject *)((_PyDictViewObject *)self)->dv_dict;
4346 if (PyDict_CheckExact(dict)) {
4347 left = dict;
4348 }
4349 }
4350 return PySet_New(left);
4351}
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004352
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004353static PyObject*
4354dictviews_sub(PyObject *self, PyObject *other)
4355{
4356 PyObject *result = dictviews_to_set(self);
4357 if (result == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004358 return NULL;
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004359 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004360
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004361 _Py_IDENTIFIER(difference_update);
4362 PyObject *tmp = _PyObject_CallMethodIdOneArg(
4363 result, &PyId_difference_update, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004364 if (tmp == NULL) {
4365 Py_DECREF(result);
4366 return NULL;
4367 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004369 Py_DECREF(tmp);
4370 return result;
Guido van Rossum523259b2007-08-24 23:41:22 +00004371}
4372
Forest Gregg998cf1f2019-08-26 02:17:43 -05004373static int
4374dictitems_contains(_PyDictViewObject *dv, PyObject *obj);
4375
4376PyObject *
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04004377_PyDictView_Intersect(PyObject* self, PyObject *other)
Guido van Rossum523259b2007-08-24 23:41:22 +00004378{
Forest Gregg998cf1f2019-08-26 02:17:43 -05004379 PyObject *result;
4380 PyObject *it;
4381 PyObject *key;
4382 Py_ssize_t len_self;
4383 int rv;
4384 int (*dict_contains)(_PyDictViewObject *, PyObject *);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004385
Forest Gregg998cf1f2019-08-26 02:17:43 -05004386 /* Python interpreter swaps parameters when dict view
4387 is on right side of & */
4388 if (!PyDictViewSet_Check(self)) {
4389 PyObject *tmp = other;
4390 other = self;
4391 self = tmp;
4392 }
4393
4394 len_self = dictview_len((_PyDictViewObject *)self);
4395
4396 /* if other is a set and self is smaller than other,
4397 reuse set intersection logic */
Dong-hee Na1b55b652020-02-17 19:09:15 +09004398 if (Py_IS_TYPE(other, &PySet_Type) && len_self <= PyObject_Size(other)) {
Forest Gregg998cf1f2019-08-26 02:17:43 -05004399 _Py_IDENTIFIER(intersection);
4400 return _PyObject_CallMethodIdObjArgs(other, &PyId_intersection, self, NULL);
4401 }
4402
4403 /* if other is another dict view, and it is bigger than self,
4404 swap them */
4405 if (PyDictViewSet_Check(other)) {
4406 Py_ssize_t len_other = dictview_len((_PyDictViewObject *)other);
4407 if (len_other > len_self) {
4408 PyObject *tmp = other;
4409 other = self;
4410 self = tmp;
4411 }
4412 }
4413
4414 /* at this point, two things should be true
4415 1. self is a dictview
4416 2. if other is a dictview then it is smaller than self */
4417 result = PySet_New(NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004418 if (result == NULL)
4419 return NULL;
Guido van Rossum523259b2007-08-24 23:41:22 +00004420
Forest Gregg998cf1f2019-08-26 02:17:43 -05004421 it = PyObject_GetIter(other);
Zackery Spytzb16e3822019-10-13 05:49:05 -06004422 if (it == NULL) {
4423 Py_DECREF(result);
4424 return NULL;
4425 }
Forest Gregg998cf1f2019-08-26 02:17:43 -05004426
Forest Gregg998cf1f2019-08-26 02:17:43 -05004427 if (PyDictKeys_Check(self)) {
4428 dict_contains = dictkeys_contains;
4429 }
4430 /* else PyDictItems_Check(self) */
4431 else {
4432 dict_contains = dictitems_contains;
4433 }
4434
4435 while ((key = PyIter_Next(it)) != NULL) {
4436 rv = dict_contains((_PyDictViewObject *)self, key);
4437 if (rv < 0) {
4438 goto error;
4439 }
4440 if (rv) {
4441 if (PySet_Add(result, key)) {
4442 goto error;
4443 }
4444 }
4445 Py_DECREF(key);
4446 }
4447 Py_DECREF(it);
4448 if (PyErr_Occurred()) {
4449 Py_DECREF(result);
4450 return NULL;
4451 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004452 return result;
Forest Gregg998cf1f2019-08-26 02:17:43 -05004453
4454error:
4455 Py_DECREF(it);
4456 Py_DECREF(result);
4457 Py_DECREF(key);
4458 return NULL;
Guido van Rossum523259b2007-08-24 23:41:22 +00004459}
4460
4461static PyObject*
4462dictviews_or(PyObject* self, PyObject *other)
4463{
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004464 PyObject *result = dictviews_to_set(self);
4465 if (result == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004466 return NULL;
4467 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004468
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004469 if (_PySet_Update(result, other) < 0) {
4470 Py_DECREF(result);
4471 return NULL;
4472 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004473 return result;
Guido van Rossum523259b2007-08-24 23:41:22 +00004474}
4475
Dennis Sweeney07d81122020-06-10 01:56:56 -04004476static PyObject *
4477dictitems_xor(PyObject *self, PyObject *other)
4478{
4479 assert(PyDictItems_Check(self));
4480 assert(PyDictItems_Check(other));
4481 PyObject *d1 = (PyObject *)((_PyDictViewObject *)self)->dv_dict;
4482 PyObject *d2 = (PyObject *)((_PyDictViewObject *)other)->dv_dict;
4483
4484 PyObject *temp_dict = PyDict_Copy(d1);
4485 if (temp_dict == NULL) {
4486 return NULL;
4487 }
4488 PyObject *result_set = PySet_New(NULL);
4489 if (result_set == NULL) {
4490 Py_CLEAR(temp_dict);
4491 return NULL;
4492 }
4493
4494 PyObject *key = NULL, *val1 = NULL, *val2 = NULL;
4495 Py_ssize_t pos = 0;
4496 Py_hash_t hash;
4497
4498 while (_PyDict_Next(d2, &pos, &key, &val2, &hash)) {
4499 Py_INCREF(key);
4500 Py_INCREF(val2);
4501 val1 = _PyDict_GetItem_KnownHash(temp_dict, key, hash);
4502
4503 int to_delete;
4504 if (val1 == NULL) {
4505 if (PyErr_Occurred()) {
4506 goto error;
4507 }
4508 to_delete = 0;
4509 }
4510 else {
4511 Py_INCREF(val1);
4512 to_delete = PyObject_RichCompareBool(val1, val2, Py_EQ);
4513 if (to_delete < 0) {
4514 goto error;
4515 }
4516 }
4517
4518 if (to_delete) {
4519 if (_PyDict_DelItem_KnownHash(temp_dict, key, hash) < 0) {
4520 goto error;
4521 }
4522 }
4523 else {
4524 PyObject *pair = PyTuple_Pack(2, key, val2);
4525 if (pair == NULL) {
4526 goto error;
4527 }
4528 if (PySet_Add(result_set, pair) < 0) {
4529 Py_DECREF(pair);
4530 goto error;
4531 }
4532 Py_DECREF(pair);
4533 }
4534 Py_DECREF(key);
4535 Py_XDECREF(val1);
4536 Py_DECREF(val2);
4537 }
4538 key = val1 = val2 = NULL;
4539
4540 _Py_IDENTIFIER(items);
4541 PyObject *remaining_pairs = _PyObject_CallMethodIdNoArgs(temp_dict,
4542 &PyId_items);
4543 if (remaining_pairs == NULL) {
4544 goto error;
4545 }
4546 if (_PySet_Update(result_set, remaining_pairs) < 0) {
4547 Py_DECREF(remaining_pairs);
4548 goto error;
4549 }
4550 Py_DECREF(temp_dict);
4551 Py_DECREF(remaining_pairs);
4552 return result_set;
4553
4554error:
4555 Py_XDECREF(temp_dict);
4556 Py_XDECREF(result_set);
4557 Py_XDECREF(key);
4558 Py_XDECREF(val1);
4559 Py_XDECREF(val2);
4560 return NULL;
4561}
4562
Guido van Rossum523259b2007-08-24 23:41:22 +00004563static PyObject*
4564dictviews_xor(PyObject* self, PyObject *other)
4565{
Dennis Sweeney07d81122020-06-10 01:56:56 -04004566 if (PyDictItems_Check(self) && PyDictItems_Check(other)) {
4567 return dictitems_xor(self, other);
4568 }
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004569 PyObject *result = dictviews_to_set(self);
4570 if (result == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004571 return NULL;
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004572 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004573
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004574 _Py_IDENTIFIER(symmetric_difference_update);
4575 PyObject *tmp = _PyObject_CallMethodIdOneArg(
4576 result, &PyId_symmetric_difference_update, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004577 if (tmp == NULL) {
4578 Py_DECREF(result);
4579 return NULL;
4580 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004581
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004582 Py_DECREF(tmp);
4583 return result;
Guido van Rossum523259b2007-08-24 23:41:22 +00004584}
4585
4586static PyNumberMethods dictviews_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004587 0, /*nb_add*/
4588 (binaryfunc)dictviews_sub, /*nb_subtract*/
4589 0, /*nb_multiply*/
4590 0, /*nb_remainder*/
4591 0, /*nb_divmod*/
4592 0, /*nb_power*/
4593 0, /*nb_negative*/
4594 0, /*nb_positive*/
4595 0, /*nb_absolute*/
4596 0, /*nb_bool*/
4597 0, /*nb_invert*/
4598 0, /*nb_lshift*/
4599 0, /*nb_rshift*/
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04004600 (binaryfunc)_PyDictView_Intersect, /*nb_and*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004601 (binaryfunc)dictviews_xor, /*nb_xor*/
4602 (binaryfunc)dictviews_or, /*nb_or*/
Guido van Rossum523259b2007-08-24 23:41:22 +00004603};
4604
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004605static PyObject*
4606dictviews_isdisjoint(PyObject *self, PyObject *other)
4607{
4608 PyObject *it;
4609 PyObject *item = NULL;
4610
4611 if (self == other) {
Eric Snow96c6af92015-05-29 22:21:39 -06004612 if (dictview_len((_PyDictViewObject *)self) == 0)
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004613 Py_RETURN_TRUE;
4614 else
4615 Py_RETURN_FALSE;
4616 }
4617
4618 /* Iterate over the shorter object (only if other is a set,
4619 * because PySequence_Contains may be expensive otherwise): */
4620 if (PyAnySet_Check(other) || PyDictViewSet_Check(other)) {
Eric Snow96c6af92015-05-29 22:21:39 -06004621 Py_ssize_t len_self = dictview_len((_PyDictViewObject *)self);
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004622 Py_ssize_t len_other = PyObject_Size(other);
4623 if (len_other == -1)
4624 return NULL;
4625
4626 if ((len_other > len_self)) {
4627 PyObject *tmp = other;
4628 other = self;
4629 self = tmp;
4630 }
4631 }
4632
4633 it = PyObject_GetIter(other);
4634 if (it == NULL)
4635 return NULL;
4636
4637 while ((item = PyIter_Next(it)) != NULL) {
4638 int contains = PySequence_Contains(self, item);
4639 Py_DECREF(item);
4640 if (contains == -1) {
4641 Py_DECREF(it);
4642 return NULL;
4643 }
4644
4645 if (contains) {
4646 Py_DECREF(it);
4647 Py_RETURN_FALSE;
4648 }
4649 }
4650 Py_DECREF(it);
4651 if (PyErr_Occurred())
4652 return NULL; /* PyIter_Next raised an exception. */
4653 Py_RETURN_TRUE;
4654}
4655
4656PyDoc_STRVAR(isdisjoint_doc,
4657"Return True if the view and the given iterable have a null intersection.");
4658
Serhiy Storchaka81524022018-11-27 13:05:02 +02004659static PyObject* dictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored));
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004660
4661PyDoc_STRVAR(reversed_keys_doc,
4662"Return a reverse iterator over the dict keys.");
4663
Guido van Rossumb90c8482007-02-10 01:11:45 +00004664static PyMethodDef dictkeys_methods[] = {
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004665 {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O,
4666 isdisjoint_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004667 {"__reversed__", (PyCFunction)(void(*)(void))dictkeys_reversed, METH_NOARGS,
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004668 reversed_keys_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004669 {NULL, NULL} /* sentinel */
Guido van Rossumb90c8482007-02-10 01:11:45 +00004670};
4671
4672PyTypeObject PyDictKeys_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004673 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4674 "dict_keys", /* tp_name */
Eric Snow96c6af92015-05-29 22:21:39 -06004675 sizeof(_PyDictViewObject), /* tp_basicsize */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004676 0, /* tp_itemsize */
4677 /* methods */
4678 (destructor)dictview_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004679 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004680 0, /* tp_getattr */
4681 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004682 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004683 (reprfunc)dictview_repr, /* tp_repr */
4684 &dictviews_as_number, /* tp_as_number */
4685 &dictkeys_as_sequence, /* tp_as_sequence */
4686 0, /* tp_as_mapping */
4687 0, /* tp_hash */
4688 0, /* tp_call */
4689 0, /* tp_str */
4690 PyObject_GenericGetAttr, /* tp_getattro */
4691 0, /* tp_setattro */
4692 0, /* tp_as_buffer */
4693 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
4694 0, /* tp_doc */
4695 (traverseproc)dictview_traverse, /* tp_traverse */
4696 0, /* tp_clear */
4697 dictview_richcompare, /* tp_richcompare */
4698 0, /* tp_weaklistoffset */
4699 (getiterfunc)dictkeys_iter, /* tp_iter */
4700 0, /* tp_iternext */
4701 dictkeys_methods, /* tp_methods */
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004702 .tp_getset = dictview_getset,
Guido van Rossumb90c8482007-02-10 01:11:45 +00004703};
4704
4705static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304706dictkeys_new(PyObject *dict, PyObject *Py_UNUSED(ignored))
Guido van Rossumb90c8482007-02-10 01:11:45 +00004707{
Eric Snow96c6af92015-05-29 22:21:39 -06004708 return _PyDictView_New(dict, &PyDictKeys_Type);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004709}
4710
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004711static PyObject *
Serhiy Storchaka81524022018-11-27 13:05:02 +02004712dictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored))
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004713{
4714 if (dv->dv_dict == NULL) {
4715 Py_RETURN_NONE;
4716 }
4717 return dictiter_new(dv->dv_dict, &PyDictRevIterKey_Type);
4718}
4719
Guido van Rossum3ac67412007-02-10 18:55:06 +00004720/*** dict_items ***/
Guido van Rossumb90c8482007-02-10 01:11:45 +00004721
4722static PyObject *
Eric Snow96c6af92015-05-29 22:21:39 -06004723dictitems_iter(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004724{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004725 if (dv->dv_dict == NULL) {
4726 Py_RETURN_NONE;
4727 }
4728 return dictiter_new(dv->dv_dict, &PyDictIterItem_Type);
Guido van Rossum3ac67412007-02-10 18:55:06 +00004729}
4730
4731static int
Eric Snow96c6af92015-05-29 22:21:39 -06004732dictitems_contains(_PyDictViewObject *dv, PyObject *obj)
Guido van Rossum3ac67412007-02-10 18:55:06 +00004733{
Serhiy Storchaka753bca32017-05-20 12:30:02 +03004734 int result;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004735 PyObject *key, *value, *found;
4736 if (dv->dv_dict == NULL)
4737 return 0;
4738 if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 2)
4739 return 0;
4740 key = PyTuple_GET_ITEM(obj, 0);
4741 value = PyTuple_GET_ITEM(obj, 1);
Raymond Hettinger6692f012016-09-18 21:46:08 -07004742 found = PyDict_GetItemWithError((PyObject *)dv->dv_dict, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004743 if (found == NULL) {
4744 if (PyErr_Occurred())
4745 return -1;
4746 return 0;
4747 }
Serhiy Storchaka753bca32017-05-20 12:30:02 +03004748 Py_INCREF(found);
Serhiy Storchaka18b711c2019-08-04 14:12:48 +03004749 result = PyObject_RichCompareBool(found, value, Py_EQ);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03004750 Py_DECREF(found);
4751 return result;
Guido van Rossumb90c8482007-02-10 01:11:45 +00004752}
4753
Guido van Rossum83825ac2007-02-10 04:54:19 +00004754static PySequenceMethods dictitems_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004755 (lenfunc)dictview_len, /* sq_length */
4756 0, /* sq_concat */
4757 0, /* sq_repeat */
4758 0, /* sq_item */
4759 0, /* sq_slice */
4760 0, /* sq_ass_item */
4761 0, /* sq_ass_slice */
4762 (objobjproc)dictitems_contains, /* sq_contains */
Guido van Rossum83825ac2007-02-10 04:54:19 +00004763};
4764
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004765static PyObject* dictitems_reversed(_PyDictViewObject *dv);
4766
4767PyDoc_STRVAR(reversed_items_doc,
4768"Return a reverse iterator over the dict items.");
4769
Guido van Rossumb90c8482007-02-10 01:11:45 +00004770static PyMethodDef dictitems_methods[] = {
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004771 {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O,
4772 isdisjoint_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004773 {"__reversed__", (PyCFunction)(void(*)(void))dictitems_reversed, METH_NOARGS,
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004774 reversed_items_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004775 {NULL, NULL} /* sentinel */
Guido van Rossumb90c8482007-02-10 01:11:45 +00004776};
4777
4778PyTypeObject PyDictItems_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004779 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4780 "dict_items", /* tp_name */
Eric Snow96c6af92015-05-29 22:21:39 -06004781 sizeof(_PyDictViewObject), /* tp_basicsize */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004782 0, /* tp_itemsize */
4783 /* methods */
4784 (destructor)dictview_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004785 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004786 0, /* tp_getattr */
4787 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004788 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004789 (reprfunc)dictview_repr, /* tp_repr */
4790 &dictviews_as_number, /* tp_as_number */
4791 &dictitems_as_sequence, /* tp_as_sequence */
4792 0, /* tp_as_mapping */
4793 0, /* tp_hash */
4794 0, /* tp_call */
4795 0, /* tp_str */
4796 PyObject_GenericGetAttr, /* tp_getattro */
4797 0, /* tp_setattro */
4798 0, /* tp_as_buffer */
4799 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
4800 0, /* tp_doc */
4801 (traverseproc)dictview_traverse, /* tp_traverse */
4802 0, /* tp_clear */
4803 dictview_richcompare, /* tp_richcompare */
4804 0, /* tp_weaklistoffset */
4805 (getiterfunc)dictitems_iter, /* tp_iter */
4806 0, /* tp_iternext */
4807 dictitems_methods, /* tp_methods */
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004808 .tp_getset = dictview_getset,
Guido van Rossumb90c8482007-02-10 01:11:45 +00004809};
4810
4811static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304812dictitems_new(PyObject *dict, PyObject *Py_UNUSED(ignored))
Guido van Rossumb90c8482007-02-10 01:11:45 +00004813{
Eric Snow96c6af92015-05-29 22:21:39 -06004814 return _PyDictView_New(dict, &PyDictItems_Type);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004815}
4816
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004817static PyObject *
4818dictitems_reversed(_PyDictViewObject *dv)
4819{
4820 if (dv->dv_dict == NULL) {
4821 Py_RETURN_NONE;
4822 }
4823 return dictiter_new(dv->dv_dict, &PyDictRevIterItem_Type);
4824}
4825
Guido van Rossum3ac67412007-02-10 18:55:06 +00004826/*** dict_values ***/
Guido van Rossumb90c8482007-02-10 01:11:45 +00004827
4828static PyObject *
Eric Snow96c6af92015-05-29 22:21:39 -06004829dictvalues_iter(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004830{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004831 if (dv->dv_dict == NULL) {
4832 Py_RETURN_NONE;
4833 }
4834 return dictiter_new(dv->dv_dict, &PyDictIterValue_Type);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004835}
4836
Guido van Rossum83825ac2007-02-10 04:54:19 +00004837static PySequenceMethods dictvalues_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004838 (lenfunc)dictview_len, /* sq_length */
4839 0, /* sq_concat */
4840 0, /* sq_repeat */
4841 0, /* sq_item */
4842 0, /* sq_slice */
4843 0, /* sq_ass_item */
4844 0, /* sq_ass_slice */
4845 (objobjproc)0, /* sq_contains */
Guido van Rossum83825ac2007-02-10 04:54:19 +00004846};
4847
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004848static PyObject* dictvalues_reversed(_PyDictViewObject *dv);
4849
4850PyDoc_STRVAR(reversed_values_doc,
4851"Return a reverse iterator over the dict values.");
4852
Guido van Rossumb90c8482007-02-10 01:11:45 +00004853static PyMethodDef dictvalues_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004854 {"__reversed__", (PyCFunction)(void(*)(void))dictvalues_reversed, METH_NOARGS,
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004855 reversed_values_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004856 {NULL, NULL} /* sentinel */
Guido van Rossumb90c8482007-02-10 01:11:45 +00004857};
4858
4859PyTypeObject PyDictValues_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004860 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4861 "dict_values", /* tp_name */
Eric Snow96c6af92015-05-29 22:21:39 -06004862 sizeof(_PyDictViewObject), /* tp_basicsize */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004863 0, /* tp_itemsize */
4864 /* methods */
4865 (destructor)dictview_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004866 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004867 0, /* tp_getattr */
4868 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004869 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004870 (reprfunc)dictview_repr, /* tp_repr */
4871 0, /* tp_as_number */
4872 &dictvalues_as_sequence, /* tp_as_sequence */
4873 0, /* tp_as_mapping */
4874 0, /* tp_hash */
4875 0, /* tp_call */
4876 0, /* tp_str */
4877 PyObject_GenericGetAttr, /* tp_getattro */
4878 0, /* tp_setattro */
4879 0, /* tp_as_buffer */
4880 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
4881 0, /* tp_doc */
4882 (traverseproc)dictview_traverse, /* tp_traverse */
4883 0, /* tp_clear */
4884 0, /* tp_richcompare */
4885 0, /* tp_weaklistoffset */
4886 (getiterfunc)dictvalues_iter, /* tp_iter */
4887 0, /* tp_iternext */
4888 dictvalues_methods, /* tp_methods */
Dennis Sweeney3ee0e482020-06-12 13:19:25 -04004889 .tp_getset = dictview_getset,
Guido van Rossumb90c8482007-02-10 01:11:45 +00004890};
4891
4892static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304893dictvalues_new(PyObject *dict, PyObject *Py_UNUSED(ignored))
Guido van Rossumb90c8482007-02-10 01:11:45 +00004894{
Eric Snow96c6af92015-05-29 22:21:39 -06004895 return _PyDictView_New(dict, &PyDictValues_Type);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004896}
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004897
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004898static PyObject *
4899dictvalues_reversed(_PyDictViewObject *dv)
4900{
4901 if (dv->dv_dict == NULL) {
4902 Py_RETURN_NONE;
4903 }
4904 return dictiter_new(dv->dv_dict, &PyDictRevIterValue_Type);
4905}
4906
4907
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004908/* Returns NULL if cannot allocate a new PyDictKeysObject,
4909 but does not set an error */
4910PyDictKeysObject *
4911_PyDict_NewKeysForClass(void)
4912{
Victor Stinner742da042016-09-07 17:40:12 -07004913 PyDictKeysObject *keys = new_keys_object(PyDict_MINSIZE);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004914 if (keys == NULL)
4915 PyErr_Clear();
4916 else
4917 keys->dk_lookup = lookdict_split;
4918 return keys;
4919}
4920
4921#define CACHED_KEYS(tp) (((PyHeapTypeObject*)tp)->ht_cached_keys)
4922
4923PyObject *
4924PyObject_GenericGetDict(PyObject *obj, void *context)
4925{
4926 PyObject *dict, **dictptr = _PyObject_GetDictPtr(obj);
4927 if (dictptr == NULL) {
4928 PyErr_SetString(PyExc_AttributeError,
4929 "This object has no __dict__");
4930 return NULL;
4931 }
4932 dict = *dictptr;
4933 if (dict == NULL) {
4934 PyTypeObject *tp = Py_TYPE(obj);
4935 if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && CACHED_KEYS(tp)) {
INADA Naokia7576492018-11-14 18:39:27 +09004936 dictkeys_incref(CACHED_KEYS(tp));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004937 *dictptr = dict = new_dict_with_shared_keys(CACHED_KEYS(tp));
4938 }
4939 else {
4940 *dictptr = dict = PyDict_New();
4941 }
4942 }
4943 Py_XINCREF(dict);
4944 return dict;
4945}
4946
4947int
4948_PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
Victor Stinner742da042016-09-07 17:40:12 -07004949 PyObject *key, PyObject *value)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004950{
4951 PyObject *dict;
4952 int res;
4953 PyDictKeysObject *cached;
4954
4955 assert(dictptr != NULL);
4956 if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && (cached = CACHED_KEYS(tp))) {
4957 assert(dictptr != NULL);
4958 dict = *dictptr;
4959 if (dict == NULL) {
INADA Naokia7576492018-11-14 18:39:27 +09004960 dictkeys_incref(cached);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004961 dict = new_dict_with_shared_keys(cached);
4962 if (dict == NULL)
4963 return -1;
4964 *dictptr = dict;
4965 }
4966 if (value == NULL) {
4967 res = PyDict_DelItem(dict, key);
INADA Naoki2294f3a2017-02-12 13:51:30 +09004968 // Since key sharing dict doesn't allow deletion, PyDict_DelItem()
4969 // always converts dict to combined form.
4970 if ((cached = CACHED_KEYS(tp)) != NULL) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004971 CACHED_KEYS(tp) = NULL;
INADA Naokia7576492018-11-14 18:39:27 +09004972 dictkeys_decref(cached);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004973 }
Victor Stinner3d3f2642016-12-15 17:21:23 +01004974 }
4975 else {
INADA Naoki2294f3a2017-02-12 13:51:30 +09004976 int was_shared = (cached == ((PyDictObject *)dict)->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004977 res = PyDict_SetItem(dict, key, value);
INADA Naoki2294f3a2017-02-12 13:51:30 +09004978 if (was_shared &&
4979 (cached = CACHED_KEYS(tp)) != NULL &&
4980 cached != ((PyDictObject *)dict)->ma_keys) {
Victor Stinner3d3f2642016-12-15 17:21:23 +01004981 /* PyDict_SetItem() may call dictresize and convert split table
4982 * into combined table. In such case, convert it to split
4983 * table again and update type's shared key only when this is
4984 * the only dict sharing key with the type.
4985 *
4986 * This is to allow using shared key in class like this:
4987 *
4988 * class C:
4989 * def __init__(self):
4990 * # one dict resize happens
4991 * self.a, self.b, self.c = 1, 2, 3
4992 * self.d, self.e, self.f = 4, 5, 6
4993 * a = C()
4994 */
Benjamin Peterson15ee8212012-04-24 14:44:18 -04004995 if (cached->dk_refcnt == 1) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004996 CACHED_KEYS(tp) = make_keys_shared(dict);
Victor Stinner742da042016-09-07 17:40:12 -07004997 }
4998 else {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004999 CACHED_KEYS(tp) = NULL;
5000 }
INADA Naokia7576492018-11-14 18:39:27 +09005001 dictkeys_decref(cached);
Benjamin Peterson15ee8212012-04-24 14:44:18 -04005002 if (CACHED_KEYS(tp) == NULL && PyErr_Occurred())
5003 return -1;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04005004 }
5005 }
5006 } else {
5007 dict = *dictptr;
5008 if (dict == NULL) {
5009 dict = PyDict_New();
5010 if (dict == NULL)
5011 return -1;
5012 *dictptr = dict;
5013 }
5014 if (value == NULL) {
5015 res = PyDict_DelItem(dict, key);
5016 } else {
5017 res = PyDict_SetItem(dict, key, value);
5018 }
5019 }
5020 return res;
5021}
5022
5023void
5024_PyDictKeys_DecRef(PyDictKeysObject *keys)
5025{
INADA Naokia7576492018-11-14 18:39:27 +09005026 dictkeys_decref(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04005027}