blob: 809a5ed778737003d590da8708c0331f4c6ad59c [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 Stinnerbcda8f12018-11-21 22:27:47 +0100115#include "pycore_object.h"
Victor Stinnere5014be2020-04-14 17:52:15 +0200116#include "pycore_pystate.h" // _PyThreadState_GET()
Eric Snow96c6af92015-05-29 22:21:39 -0600117#include "dict-common.h"
Victor Stinnere5014be2020-04-14 17:52:15 +0200118#include "stringlib/eq.h" // unicode_eq()
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000119
Larry Hastings61272b72014-01-07 12:41:53 -0800120/*[clinic input]
Larry Hastingsc2047262014-01-25 20:43:29 -0800121class dict "PyDictObject *" "&PyDict_Type"
Larry Hastings61272b72014-01-07 12:41:53 -0800122[clinic start generated code]*/
Larry Hastings581ee362014-01-28 05:00:08 -0800123/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f157a5a0ce9589d6]*/
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800124
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400125
126/*
127To ensure the lookup algorithm terminates, there must be at least one Unused
128slot (NULL key) in the table.
129To avoid slowing down lookups on a near-full table, we resize the table when
130it's USABLE_FRACTION (currently two-thirds) full.
131*/
Guido van Rossum16e93a81997-01-28 00:00:11 +0000132
Tim Peterseb28ef22001-06-02 05:27:19 +0000133#define PERTURB_SHIFT 5
134
Guido van Rossum16e93a81997-01-28 00:00:11 +0000135/*
Tim Peterseb28ef22001-06-02 05:27:19 +0000136Major subtleties ahead: Most hash schemes depend on having a "good" hash
137function, in the sense of simulating randomness. Python doesn't: its most
R David Murray537ad7a2016-07-10 12:33:18 -0400138important hash functions (for ints) are very regular in common
Tim Peterseb28ef22001-06-02 05:27:19 +0000139cases:
Tim Peters15d49292001-05-27 07:39:22 +0000140
R David Murray537ad7a2016-07-10 12:33:18 -0400141 >>>[hash(i) for i in range(4)]
Guido van Rossumdc5f6b22006-08-24 21:29:26 +0000142 [0, 1, 2, 3]
Tim Peters15d49292001-05-27 07:39:22 +0000143
Tim Peterseb28ef22001-06-02 05:27:19 +0000144This isn't necessarily bad! To the contrary, in a table of size 2**i, taking
145the low-order i bits as the initial table index is extremely fast, and there
R David Murray537ad7a2016-07-10 12:33:18 -0400146are no collisions at all for dicts indexed by a contiguous range of ints. So
147this gives better-than-random behavior in common cases, and that's very
148desirable.
Tim Peters15d49292001-05-27 07:39:22 +0000149
Tim Peterseb28ef22001-06-02 05:27:19 +0000150OTOH, when collisions occur, the tendency to fill contiguous slices of the
151hash table makes a good collision resolution strategy crucial. Taking only
152the last i bits of the hash code is also vulnerable: for example, consider
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153the list [i << 16 for i in range(20000)] as a set of keys. Since ints are
Guido van Rossumdc5f6b22006-08-24 21:29:26 +0000154their own hash codes, and this fits in a dict of size 2**15, the last 15 bits
155 of every hash code are all 0: they *all* map to the same table index.
Tim Peters15d49292001-05-27 07:39:22 +0000156
Tim Peterseb28ef22001-06-02 05:27:19 +0000157But catering to unusual cases should not slow the usual ones, so we just take
158the last i bits anyway. It's up to collision resolution to do the rest. If
159we *usually* find the key we're looking for on the first try (and, it turns
160out, we usually do -- the table load factor is kept under 2/3, so the odds
161are solidly in our favor), then it makes best sense to keep the initial index
162computation dirt cheap.
Tim Peters15d49292001-05-27 07:39:22 +0000163
Tim Peterseb28ef22001-06-02 05:27:19 +0000164The first half of collision resolution is to visit table indices via this
165recurrence:
Tim Peters15d49292001-05-27 07:39:22 +0000166
Tim Peterseb28ef22001-06-02 05:27:19 +0000167 j = ((5*j) + 1) mod 2**i
Tim Peters15d49292001-05-27 07:39:22 +0000168
Tim Peterseb28ef22001-06-02 05:27:19 +0000169For any initial j in range(2**i), repeating that 2**i times generates each
170int in range(2**i) exactly once (see any text on random-number generation for
171proof). By itself, this doesn't help much: like linear probing (setting
172j += 1, or j -= 1, on each loop trip), it scans the table entries in a fixed
173order. This would be bad, except that's not the only thing we do, and it's
174actually *good* in the common cases where hash keys are consecutive. In an
175example that's really too small to make this entirely clear, for a table of
176size 2**3 the order of indices is:
Tim Peters15d49292001-05-27 07:39:22 +0000177
Tim Peterseb28ef22001-06-02 05:27:19 +0000178 0 -> 1 -> 6 -> 7 -> 4 -> 5 -> 2 -> 3 -> 0 [and here it's repeating]
179
180If two things come in at index 5, the first place we look after is index 2,
181not 6, so if another comes in at index 6 the collision at 5 didn't hurt it.
182Linear probing is deadly in this case because there the fixed probe order
183is the *same* as the order consecutive keys are likely to arrive. But it's
184extremely unlikely hash codes will follow a 5*j+1 recurrence by accident,
185and certain that consecutive hash codes do not.
186
187The other half of the strategy is to get the other bits of the hash code
188into play. This is done by initializing a (unsigned) vrbl "perturb" to the
189full hash code, and changing the recurrence to:
190
Tim Peterseb28ef22001-06-02 05:27:19 +0000191 perturb >>= PERTURB_SHIFT;
INADA Naoki267941c2016-10-06 15:19:07 +0900192 j = (5*j) + 1 + perturb;
Tim Peterseb28ef22001-06-02 05:27:19 +0000193 use j % 2**i as the next table index;
194
195Now the probe sequence depends (eventually) on every bit in the hash code,
196and the pseudo-scrambling property of recurring on 5*j+1 is more valuable,
197because it quickly magnifies small differences in the bits that didn't affect
198the initial index. Note that because perturb is unsigned, if the recurrence
199is executed often enough perturb eventually becomes and remains 0. At that
200point (very rarely reached) the recurrence is on (just) 5*j+1 again, and
201that's certain to find an empty slot eventually (since it generates every int
202in range(2**i), and we make sure there's always at least one empty slot).
203
204Selecting a good value for PERTURB_SHIFT is a balancing act. You want it
205small so that the high bits of the hash code continue to affect the probe
206sequence across iterations; but you want it large so that in really bad cases
207the high-order hash bits have an effect on early iterations. 5 was "the
208best" in minimizing total collisions across experiments Tim Peters ran (on
209both normal and pathological cases), but 4 and 6 weren't significantly worse.
210
Guido van Rossumdc5f6b22006-08-24 21:29:26 +0000211Historical: Reimer Behrends contributed the idea of using a polynomial-based
Tim Peterseb28ef22001-06-02 05:27:19 +0000212approach, using repeated multiplication by x in GF(2**n) where an irreducible
213polynomial for each table size was chosen such that x was a primitive root.
214Christian Tismer later extended that to use division by x instead, as an
215efficient way to get the high bits of the hash code into play. This scheme
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000216also gave excellent collision statistics, but was more expensive: two
217if-tests were required inside the loop; computing "the next" index took about
218the same number of operations but without as much potential parallelism
219(e.g., computing 5*j can go on at the same time as computing 1+perturb in the
220above, and then shifting perturb can be done while the table index is being
221masked); and the PyDictObject struct required a member to hold the table's
222polynomial. In Tim's experiments the current scheme ran faster, produced
223equally good collision statistics, needed less code & used less memory.
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000224
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000225*/
Tim Petersdea48ec2001-05-22 20:40:22 +0000226
Fred Drake1bff34a2000-08-31 19:31:38 +0000227/* forward declarations */
Victor Stinner742da042016-09-07 17:40:12 -0700228static Py_ssize_t lookdict(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900229 Py_hash_t hash, PyObject **value_addr);
Victor Stinner742da042016-09-07 17:40:12 -0700230static Py_ssize_t lookdict_unicode(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900231 Py_hash_t hash, PyObject **value_addr);
Victor Stinner742da042016-09-07 17:40:12 -0700232static Py_ssize_t
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400233lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900234 Py_hash_t hash, PyObject **value_addr);
Victor Stinner742da042016-09-07 17:40:12 -0700235static Py_ssize_t lookdict_split(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900236 Py_hash_t hash, PyObject **value_addr);
Fred Drake1bff34a2000-08-31 19:31:38 +0000237
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400238static int dictresize(PyDictObject *mp, Py_ssize_t minused);
Tim Petersdea48ec2001-05-22 20:40:22 +0000239
INADA Naoki2aaf98c2018-09-26 12:59:00 +0900240static PyObject* dict_iter(PyDictObject *dict);
241
Benjamin Peterson3c569292016-09-08 13:16:41 -0700242/*Global counter used to set ma_version_tag field of dictionary.
Victor Stinner3b6a6b42016-09-08 12:51:24 -0700243 * It is incremented each time that a dictionary is created and each
244 * time that a dictionary is modified. */
245static uint64_t pydict_global_version = 0;
246
247#define DICT_NEXT_VERSION() (++pydict_global_version)
248
Victor Stinner742da042016-09-07 17:40:12 -0700249/* Dictionary reuse scheme to save calls to malloc and free */
Christian Heimes2202f872008-02-06 14:31:34 +0000250#ifndef PyDict_MAXFREELIST
251#define PyDict_MAXFREELIST 80
252#endif
Victor Stinnerb4b53862020-05-05 19:55:29 +0200253
254/* bpo-40521: dict free lists are shared by all interpreters. */
255#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
256# undef PyDict_MAXFREELIST
257# define PyDict_MAXFREELIST 0
258#endif
259
260#if PyDict_MAXFREELIST > 0
Christian Heimes2202f872008-02-06 14:31:34 +0000261static PyDictObject *free_list[PyDict_MAXFREELIST];
262static int numfree = 0;
Victor Stinner742da042016-09-07 17:40:12 -0700263static PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
264static int numfreekeys = 0;
Victor Stinnerb4b53862020-05-05 19:55:29 +0200265#endif
Raymond Hettinger43442782004-03-17 21:55:03 +0000266
Serhiy Storchaka1009bf12015-04-03 23:53:51 +0300267#include "clinic/dictobject.c.h"
268
Victor Stinnerae00a5a2020-04-29 02:29:20 +0200269void
270_PyDict_ClearFreeList(void)
Christian Heimes77c02eb2008-02-09 02:18:51 +0000271{
Victor Stinnerb4b53862020-05-05 19:55:29 +0200272#if PyDict_MAXFREELIST > 0
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 while (numfree) {
Victor Stinnerae00a5a2020-04-29 02:29:20 +0200274 PyDictObject *op = free_list[--numfree];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 assert(PyDict_CheckExact(op));
276 PyObject_GC_Del(op);
277 }
Victor Stinner742da042016-09-07 17:40:12 -0700278 while (numfreekeys) {
279 PyObject_FREE(keys_free_list[--numfreekeys]);
280 }
Victor Stinnerb4b53862020-05-05 19:55:29 +0200281#endif
Antoine Pitrou9a812cb2011-11-15 00:00:12 +0100282}
283
David Malcolm49526f42012-06-22 14:55:41 -0400284/* Print summary info about the state of the optimized allocator */
285void
286_PyDict_DebugMallocStats(FILE *out)
287{
Victor Stinnerb4b53862020-05-05 19:55:29 +0200288#if PyDict_MAXFREELIST > 0
David Malcolm49526f42012-06-22 14:55:41 -0400289 _PyDebugAllocatorStats(out,
290 "free PyDictObject", numfree, sizeof(PyDictObject));
Victor Stinnerb4b53862020-05-05 19:55:29 +0200291#endif
David Malcolm49526f42012-06-22 14:55:41 -0400292}
293
294
Antoine Pitrou9a812cb2011-11-15 00:00:12 +0100295void
Victor Stinnerbed48172019-08-27 00:12:32 +0200296_PyDict_Fini(void)
Antoine Pitrou9a812cb2011-11-15 00:00:12 +0100297{
Victor Stinnerae00a5a2020-04-29 02:29:20 +0200298 _PyDict_ClearFreeList();
Christian Heimes77c02eb2008-02-09 02:18:51 +0000299}
300
Victor Stinner742da042016-09-07 17:40:12 -0700301#define DK_SIZE(dk) ((dk)->dk_size)
302#if SIZEOF_VOID_P > 4
Victor Stinner58f7c5a2016-09-08 11:37:36 -0700303#define DK_IXSIZE(dk) \
304 (DK_SIZE(dk) <= 0xff ? \
305 1 : DK_SIZE(dk) <= 0xffff ? \
306 2 : DK_SIZE(dk) <= 0xffffffff ? \
Benjamin Peterson3c569292016-09-08 13:16:41 -0700307 4 : sizeof(int64_t))
Victor Stinner742da042016-09-07 17:40:12 -0700308#else
Victor Stinner58f7c5a2016-09-08 11:37:36 -0700309#define DK_IXSIZE(dk) \
310 (DK_SIZE(dk) <= 0xff ? \
311 1 : DK_SIZE(dk) <= 0xffff ? \
Benjamin Peterson3c569292016-09-08 13:16:41 -0700312 2 : sizeof(int32_t))
Victor Stinner742da042016-09-07 17:40:12 -0700313#endif
Victor Stinner58f7c5a2016-09-08 11:37:36 -0700314#define DK_ENTRIES(dk) \
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700315 ((PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[DK_SIZE(dk) * DK_IXSIZE(dk)]))
Victor Stinner742da042016-09-07 17:40:12 -0700316
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400317#define DK_MASK(dk) (((dk)->dk_size)-1)
318#define IS_POWER_OF_2(x) (((x) & (x-1)) == 0)
319
INADA Naokia7576492018-11-14 18:39:27 +0900320static void free_keys_object(PyDictKeysObject *keys);
321
322static inline void
323dictkeys_incref(PyDictKeysObject *dk)
324{
Victor Stinner49932fe2020-02-03 17:55:05 +0100325#ifdef Py_REF_DEBUG
326 _Py_RefTotal++;
327#endif
INADA Naokia7576492018-11-14 18:39:27 +0900328 dk->dk_refcnt++;
329}
330
331static inline void
332dictkeys_decref(PyDictKeysObject *dk)
333{
334 assert(dk->dk_refcnt > 0);
Victor Stinner49932fe2020-02-03 17:55:05 +0100335#ifdef Py_REF_DEBUG
336 _Py_RefTotal--;
337#endif
INADA Naokia7576492018-11-14 18:39:27 +0900338 if (--dk->dk_refcnt == 0) {
339 free_keys_object(dk);
340 }
341}
342
Victor Stinner742da042016-09-07 17:40:12 -0700343/* lookup indices. returns DKIX_EMPTY, DKIX_DUMMY, or ix >=0 */
Benjamin Peterson73222252016-09-08 09:58:47 -0700344static inline Py_ssize_t
Andy Lester62d21c92020-03-25 23:13:01 -0500345dictkeys_get_index(const PyDictKeysObject *keys, Py_ssize_t i)
Victor Stinner742da042016-09-07 17:40:12 -0700346{
347 Py_ssize_t s = DK_SIZE(keys);
Victor Stinner71211e32016-09-08 10:52:46 -0700348 Py_ssize_t ix;
349
Victor Stinner742da042016-09-07 17:40:12 -0700350 if (s <= 0xff) {
Andy Lester62d21c92020-03-25 23:13:01 -0500351 const int8_t *indices = (const int8_t*)(keys->dk_indices);
Victor Stinner208857e2016-09-08 11:35:46 -0700352 ix = indices[i];
Victor Stinner742da042016-09-07 17:40:12 -0700353 }
354 else if (s <= 0xffff) {
Andy Lester62d21c92020-03-25 23:13:01 -0500355 const int16_t *indices = (const int16_t*)(keys->dk_indices);
Victor Stinner208857e2016-09-08 11:35:46 -0700356 ix = indices[i];
Victor Stinner742da042016-09-07 17:40:12 -0700357 }
Benjamin Peterson3c569292016-09-08 13:16:41 -0700358#if SIZEOF_VOID_P > 4
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300359 else if (s > 0xffffffff) {
Andy Lester62d21c92020-03-25 23:13:01 -0500360 const int64_t *indices = (const int64_t*)(keys->dk_indices);
Victor Stinner208857e2016-09-08 11:35:46 -0700361 ix = indices[i];
Victor Stinner742da042016-09-07 17:40:12 -0700362 }
Benjamin Peterson3c569292016-09-08 13:16:41 -0700363#endif
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300364 else {
Andy Lester62d21c92020-03-25 23:13:01 -0500365 const int32_t *indices = (const int32_t*)(keys->dk_indices);
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300366 ix = indices[i];
367 }
Victor Stinner71211e32016-09-08 10:52:46 -0700368 assert(ix >= DKIX_DUMMY);
369 return ix;
Victor Stinner742da042016-09-07 17:40:12 -0700370}
371
372/* write to indices. */
Benjamin Peterson73222252016-09-08 09:58:47 -0700373static inline void
INADA Naokia7576492018-11-14 18:39:27 +0900374dictkeys_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix)
Victor Stinner742da042016-09-07 17:40:12 -0700375{
376 Py_ssize_t s = DK_SIZE(keys);
Victor Stinner71211e32016-09-08 10:52:46 -0700377
378 assert(ix >= DKIX_DUMMY);
379
Victor Stinner742da042016-09-07 17:40:12 -0700380 if (s <= 0xff) {
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700381 int8_t *indices = (int8_t*)(keys->dk_indices);
Victor Stinner71211e32016-09-08 10:52:46 -0700382 assert(ix <= 0x7f);
Victor Stinner208857e2016-09-08 11:35:46 -0700383 indices[i] = (char)ix;
Victor Stinner742da042016-09-07 17:40:12 -0700384 }
385 else if (s <= 0xffff) {
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700386 int16_t *indices = (int16_t*)(keys->dk_indices);
Victor Stinner71211e32016-09-08 10:52:46 -0700387 assert(ix <= 0x7fff);
Victor Stinner208857e2016-09-08 11:35:46 -0700388 indices[i] = (int16_t)ix;
Victor Stinner742da042016-09-07 17:40:12 -0700389 }
Benjamin Peterson3c569292016-09-08 13:16:41 -0700390#if SIZEOF_VOID_P > 4
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300391 else if (s > 0xffffffff) {
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700392 int64_t *indices = (int64_t*)(keys->dk_indices);
Victor Stinner208857e2016-09-08 11:35:46 -0700393 indices[i] = ix;
Victor Stinner742da042016-09-07 17:40:12 -0700394 }
Benjamin Peterson3c569292016-09-08 13:16:41 -0700395#endif
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300396 else {
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700397 int32_t *indices = (int32_t*)(keys->dk_indices);
Serhiy Storchaka473e0e42016-09-10 21:34:43 +0300398 assert(ix <= 0x7fffffff);
399 indices[i] = (int32_t)ix;
400 }
Victor Stinner742da042016-09-07 17:40:12 -0700401}
402
403
Antoine Pitroua504a7a2012-06-24 21:03:45 +0200404/* USABLE_FRACTION is the maximum dictionary load.
Victor Stinner742da042016-09-07 17:40:12 -0700405 * Increasing this ratio makes dictionaries more dense resulting in more
406 * collisions. Decreasing it improves sparseness at the expense of spreading
407 * indices over more cache lines and at the cost of total memory consumed.
Antoine Pitroua504a7a2012-06-24 21:03:45 +0200408 *
409 * USABLE_FRACTION must obey the following:
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400410 * (0 < USABLE_FRACTION(n) < n) for all n >= 2
411 *
Victor Stinner742da042016-09-07 17:40:12 -0700412 * USABLE_FRACTION should be quick to calculate.
413 * Fractions around 1/2 to 2/3 seem to work well in practice.
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400414 */
Victor Stinner742da042016-09-07 17:40:12 -0700415#define USABLE_FRACTION(n) (((n) << 1)/3)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400416
Victor Stinner742da042016-09-07 17:40:12 -0700417/* ESTIMATE_SIZE is reverse function of USABLE_FRACTION.
418 * This can be used to reserve enough size to insert n entries without
419 * resizing.
420 */
INADA Naoki92c50ee2016-11-22 00:57:02 +0900421#define ESTIMATE_SIZE(n) (((n)*3+1) >> 1)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400422
Victor Stinner742da042016-09-07 17:40:12 -0700423/* Alternative fraction that is otherwise close enough to 2n/3 to make
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400424 * little difference. 8 * 2/3 == 8 * 5/8 == 5. 16 * 2/3 == 16 * 5/8 == 10.
425 * 32 * 2/3 = 21, 32 * 5/8 = 20.
426 * Its advantage is that it is faster to compute on machines with slow division.
427 * #define USABLE_FRACTION(n) (((n) >> 1) + ((n) >> 2) - ((n) >> 3))
Victor Stinner742da042016-09-07 17:40:12 -0700428 */
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400429
Victor Stinnera9f61a52013-07-16 22:17:26 +0200430/* GROWTH_RATE. Growth rate upon hitting maximum load.
INADA Naoki5fbc5112018-04-17 15:53:34 +0900431 * Currently set to used*3.
Victor Stinnera9f61a52013-07-16 22:17:26 +0200432 * This means that dicts double in size when growing without deletions,
Raymond Hettinger36f74aa2013-05-17 03:01:13 -0700433 * but have more head room when the number of deletions is on a par with the
INADA Naoki5fbc5112018-04-17 15:53:34 +0900434 * number of insertions. See also bpo-17563 and bpo-33205.
435 *
Raymond Hettinger36f74aa2013-05-17 03:01:13 -0700436 * GROWTH_RATE was set to used*4 up to version 3.2.
437 * GROWTH_RATE was set to used*2 in version 3.3.0
INADA Naoki5fbc5112018-04-17 15:53:34 +0900438 * GROWTH_RATE was set to used*2 + capacity/2 in 3.4.0-3.6.0.
Antoine Pitroua504a7a2012-06-24 21:03:45 +0200439 */
INADA Naoki5fbc5112018-04-17 15:53:34 +0900440#define GROWTH_RATE(d) ((d)->ma_used*3)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400441
442#define ENSURE_ALLOWS_DELETIONS(d) \
443 if ((d)->ma_keys->dk_lookup == lookdict_unicode_nodummy) { \
444 (d)->ma_keys->dk_lookup = lookdict_unicode; \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400446
447/* This immutable, empty PyDictKeysObject is used for PyDict_Clear()
448 * (which cannot fail and thus can do no allocation).
449 */
450static PyDictKeysObject empty_keys_struct = {
Serhiy Storchaka97932e42016-09-26 23:01:23 +0300451 1, /* dk_refcnt */
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400452 1, /* dk_size */
453 lookdict_split, /* dk_lookup */
454 0, /* dk_usable (immutable) */
Victor Stinner742da042016-09-07 17:40:12 -0700455 0, /* dk_nentries */
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700456 {DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY,
457 DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY}, /* dk_indices */
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400458};
459
460static PyObject *empty_values[1] = { NULL };
461
462#define Py_EMPTY_KEYS &empty_keys_struct
463
Victor Stinner611b0fa2016-09-14 15:02:01 +0200464/* Uncomment to check the dict content in _PyDict_CheckConsistency() */
465/* #define DEBUG_PYDICT */
466
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200467#ifdef DEBUG_PYDICT
468# define ASSERT_CONSISTENT(op) assert(_PyDict_CheckConsistency((PyObject *)(op), 1))
469#else
470# define ASSERT_CONSISTENT(op) assert(_PyDict_CheckConsistency((PyObject *)(op), 0))
471#endif
Victor Stinner611b0fa2016-09-14 15:02:01 +0200472
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200473
474int
475_PyDict_CheckConsistency(PyObject *op, int check_content)
Victor Stinner611b0fa2016-09-14 15:02:01 +0200476{
Victor Stinner68762572019-10-07 18:42:01 +0200477#define CHECK(expr) \
478 do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0)
479
480 assert(op != NULL);
481 CHECK(PyDict_Check(op));
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200482 PyDictObject *mp = (PyDictObject *)op;
Victor Stinner50fe3f82018-10-26 18:47:15 +0200483
Victor Stinner611b0fa2016-09-14 15:02:01 +0200484 PyDictKeysObject *keys = mp->ma_keys;
485 int splitted = _PyDict_HasSplitTable(mp);
486 Py_ssize_t usable = USABLE_FRACTION(keys->dk_size);
Victor Stinner611b0fa2016-09-14 15:02:01 +0200487
Victor Stinner68762572019-10-07 18:42:01 +0200488 CHECK(0 <= mp->ma_used && mp->ma_used <= usable);
489 CHECK(IS_POWER_OF_2(keys->dk_size));
490 CHECK(0 <= keys->dk_usable && keys->dk_usable <= usable);
491 CHECK(0 <= keys->dk_nentries && keys->dk_nentries <= usable);
492 CHECK(keys->dk_usable + keys->dk_nentries <= usable);
Victor Stinner611b0fa2016-09-14 15:02:01 +0200493
494 if (!splitted) {
495 /* combined table */
Victor Stinner68762572019-10-07 18:42:01 +0200496 CHECK(keys->dk_refcnt == 1);
Victor Stinner611b0fa2016-09-14 15:02:01 +0200497 }
498
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200499 if (check_content) {
500 PyDictKeyEntry *entries = DK_ENTRIES(keys);
501 Py_ssize_t i;
Victor Stinner611b0fa2016-09-14 15:02:01 +0200502
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200503 for (i=0; i < keys->dk_size; i++) {
504 Py_ssize_t ix = dictkeys_get_index(keys, i);
Victor Stinner68762572019-10-07 18:42:01 +0200505 CHECK(DKIX_DUMMY <= ix && ix <= usable);
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200506 }
Victor Stinner611b0fa2016-09-14 15:02:01 +0200507
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200508 for (i=0; i < usable; i++) {
509 PyDictKeyEntry *entry = &entries[i];
510 PyObject *key = entry->me_key;
511
512 if (key != NULL) {
513 if (PyUnicode_CheckExact(key)) {
514 Py_hash_t hash = ((PyASCIIObject *)key)->hash;
Victor Stinner68762572019-10-07 18:42:01 +0200515 CHECK(hash != -1);
516 CHECK(entry->me_hash == hash);
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200517 }
518 else {
519 /* test_dict fails if PyObject_Hash() is called again */
Victor Stinner68762572019-10-07 18:42:01 +0200520 CHECK(entry->me_hash != -1);
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200521 }
522 if (!splitted) {
Victor Stinner68762572019-10-07 18:42:01 +0200523 CHECK(entry->me_value != NULL);
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200524 }
Victor Stinner611b0fa2016-09-14 15:02:01 +0200525 }
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200526
527 if (splitted) {
Victor Stinner68762572019-10-07 18:42:01 +0200528 CHECK(entry->me_value == NULL);
Victor Stinner611b0fa2016-09-14 15:02:01 +0200529 }
530 }
531
532 if (splitted) {
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200533 /* splitted table */
534 for (i=0; i < mp->ma_used; i++) {
Victor Stinner68762572019-10-07 18:42:01 +0200535 CHECK(mp->ma_values[i] != NULL);
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200536 }
Victor Stinner611b0fa2016-09-14 15:02:01 +0200537 }
538 }
Victor Stinner611b0fa2016-09-14 15:02:01 +0200539 return 1;
Victor Stinner68762572019-10-07 18:42:01 +0200540
541#undef CHECK
Victor Stinner611b0fa2016-09-14 15:02:01 +0200542}
Victor Stinner611b0fa2016-09-14 15:02:01 +0200543
544
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400545static PyDictKeysObject *new_keys_object(Py_ssize_t size)
546{
547 PyDictKeysObject *dk;
Victor Stinner742da042016-09-07 17:40:12 -0700548 Py_ssize_t es, usable;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400549
Victor Stinner742da042016-09-07 17:40:12 -0700550 assert(size >= PyDict_MINSIZE);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400551 assert(IS_POWER_OF_2(size));
Victor Stinner742da042016-09-07 17:40:12 -0700552
553 usable = USABLE_FRACTION(size);
554 if (size <= 0xff) {
555 es = 1;
556 }
557 else if (size <= 0xffff) {
558 es = 2;
559 }
560#if SIZEOF_VOID_P > 4
561 else if (size <= 0xffffffff) {
562 es = 4;
563 }
564#endif
565 else {
566 es = sizeof(Py_ssize_t);
567 }
568
Victor Stinnerb4b53862020-05-05 19:55:29 +0200569#if PyDict_MAXFREELIST > 0
Victor Stinner742da042016-09-07 17:40:12 -0700570 if (size == PyDict_MINSIZE && numfreekeys > 0) {
571 dk = keys_free_list[--numfreekeys];
572 }
Victor Stinnerb4b53862020-05-05 19:55:29 +0200573 else
574#endif
575 {
Victor Stinner98ee9d52016-09-08 09:33:56 -0700576 dk = PyObject_MALLOC(sizeof(PyDictKeysObject)
Victor Stinner98ee9d52016-09-08 09:33:56 -0700577 + es * size
578 + sizeof(PyDictKeyEntry) * usable);
Victor Stinner742da042016-09-07 17:40:12 -0700579 if (dk == NULL) {
580 PyErr_NoMemory();
581 return NULL;
582 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400583 }
Victor Stinner49932fe2020-02-03 17:55:05 +0100584#ifdef Py_REF_DEBUG
585 _Py_RefTotal++;
586#endif
INADA Naokia7576492018-11-14 18:39:27 +0900587 dk->dk_refcnt = 1;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400588 dk->dk_size = size;
Victor Stinner742da042016-09-07 17:40:12 -0700589 dk->dk_usable = usable;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400590 dk->dk_lookup = lookdict_unicode_nodummy;
Victor Stinner742da042016-09-07 17:40:12 -0700591 dk->dk_nentries = 0;
Gregory P. Smith397f1b22018-04-19 22:41:19 -0700592 memset(&dk->dk_indices[0], 0xff, es * size);
Victor Stinner742da042016-09-07 17:40:12 -0700593 memset(DK_ENTRIES(dk), 0, sizeof(PyDictKeyEntry) * usable);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400594 return dk;
595}
596
597static void
598free_keys_object(PyDictKeysObject *keys)
599{
Victor Stinner742da042016-09-07 17:40:12 -0700600 PyDictKeyEntry *entries = DK_ENTRIES(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400601 Py_ssize_t i, n;
Victor Stinner742da042016-09-07 17:40:12 -0700602 for (i = 0, n = keys->dk_nentries; i < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400603 Py_XDECREF(entries[i].me_key);
604 Py_XDECREF(entries[i].me_value);
605 }
Victor Stinnerb4b53862020-05-05 19:55:29 +0200606#if PyDict_MAXFREELIST > 0
Victor Stinner742da042016-09-07 17:40:12 -0700607 if (keys->dk_size == PyDict_MINSIZE && numfreekeys < PyDict_MAXFREELIST) {
608 keys_free_list[numfreekeys++] = keys;
609 return;
610 }
Victor Stinnerb4b53862020-05-05 19:55:29 +0200611#endif
Raymond Hettingerce5179f2016-01-31 08:56:21 -0800612 PyObject_FREE(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400613}
614
615#define new_values(size) PyMem_NEW(PyObject *, size)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400616#define free_values(values) PyMem_FREE(values)
617
618/* Consumes a reference to the keys object */
619static PyObject *
620new_dict(PyDictKeysObject *keys, PyObject **values)
621{
622 PyDictObject *mp;
Victor Stinnerc9b7f512013-07-08 22:19:20 +0200623 assert(keys != NULL);
Victor Stinnerb4b53862020-05-05 19:55:29 +0200624#if PyDict_MAXFREELIST > 0
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 if (numfree) {
626 mp = free_list[--numfree];
627 assert (mp != NULL);
Dong-hee Na1b55b652020-02-17 19:09:15 +0900628 assert (Py_IS_TYPE(mp, &PyDict_Type));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 _Py_NewReference((PyObject *)mp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 }
Victor Stinnerb4b53862020-05-05 19:55:29 +0200631 else
632#endif
633 {
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400634 mp = PyObject_GC_New(PyDictObject, &PyDict_Type);
635 if (mp == NULL) {
INADA Naokia7576492018-11-14 18:39:27 +0900636 dictkeys_decref(keys);
Zackery Spytz3d07c1e2019-03-23 20:23:29 -0600637 if (values != empty_values) {
638 free_values(values);
639 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400640 return NULL;
641 }
642 }
643 mp->ma_keys = keys;
644 mp->ma_values = values;
645 mp->ma_used = 0;
Victor Stinner3b6a6b42016-09-08 12:51:24 -0700646 mp->ma_version_tag = DICT_NEXT_VERSION();
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200647 ASSERT_CONSISTENT(mp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 return (PyObject *)mp;
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000649}
650
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400651/* Consumes a reference to the keys object */
652static PyObject *
653new_dict_with_shared_keys(PyDictKeysObject *keys)
654{
655 PyObject **values;
656 Py_ssize_t i, size;
657
Victor Stinner742da042016-09-07 17:40:12 -0700658 size = USABLE_FRACTION(DK_SIZE(keys));
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400659 values = new_values(size);
660 if (values == NULL) {
INADA Naokia7576492018-11-14 18:39:27 +0900661 dictkeys_decref(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400662 return PyErr_NoMemory();
663 }
664 for (i = 0; i < size; i++) {
665 values[i] = NULL;
666 }
667 return new_dict(keys, values);
668}
669
Yury Selivanovb0a7a032018-01-22 11:54:41 -0500670
671static PyObject *
672clone_combined_dict(PyDictObject *orig)
673{
674 assert(PyDict_CheckExact(orig));
675 assert(orig->ma_values == NULL);
676 assert(orig->ma_keys->dk_refcnt == 1);
677
678 Py_ssize_t keys_size = _PyDict_KeysSize(orig->ma_keys);
679 PyDictKeysObject *keys = PyObject_Malloc(keys_size);
680 if (keys == NULL) {
681 PyErr_NoMemory();
682 return NULL;
683 }
684
685 memcpy(keys, orig->ma_keys, keys_size);
686
687 /* After copying key/value pairs, we need to incref all
688 keys and values and they are about to be co-owned by a
689 new dict object. */
690 PyDictKeyEntry *ep0 = DK_ENTRIES(keys);
691 Py_ssize_t n = keys->dk_nentries;
692 for (Py_ssize_t i = 0; i < n; i++) {
693 PyDictKeyEntry *entry = &ep0[i];
694 PyObject *value = entry->me_value;
695 if (value != NULL) {
696 Py_INCREF(value);
697 Py_INCREF(entry->me_key);
698 }
699 }
700
701 PyDictObject *new = (PyDictObject *)new_dict(keys, NULL);
702 if (new == NULL) {
703 /* In case of an error, `new_dict()` takes care of
704 cleaning up `keys`. */
705 return NULL;
706 }
707 new->ma_used = orig->ma_used;
Victor Stinner0fc91ee2019-04-12 21:51:34 +0200708 ASSERT_CONSISTENT(new);
Yury Selivanovb0a7a032018-01-22 11:54:41 -0500709 if (_PyObject_GC_IS_TRACKED(orig)) {
710 /* Maintain tracking. */
711 _PyObject_GC_TRACK(new);
712 }
Yury Selivanov0b752282018-07-06 12:20:07 -0400713
714 /* Since we copied the keys table we now have an extra reference
Victor Stinner49932fe2020-02-03 17:55:05 +0100715 in the system. Manually call increment _Py_RefTotal to signal that
INADA Naokia7576492018-11-14 18:39:27 +0900716 we have it now; calling dictkeys_incref would be an error as
Yury Selivanov0b752282018-07-06 12:20:07 -0400717 keys->dk_refcnt is already set to 1 (after memcpy). */
Victor Stinner49932fe2020-02-03 17:55:05 +0100718#ifdef Py_REF_DEBUG
719 _Py_RefTotal++;
720#endif
Yury Selivanov0b752282018-07-06 12:20:07 -0400721
Yury Selivanovb0a7a032018-01-22 11:54:41 -0500722 return (PyObject *)new;
723}
724
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400725PyObject *
726PyDict_New(void)
727{
Inada Naokif2a18672019-03-12 17:25:44 +0900728 dictkeys_incref(Py_EMPTY_KEYS);
729 return new_dict(Py_EMPTY_KEYS, empty_values);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400730}
731
Victor Stinner742da042016-09-07 17:40:12 -0700732/* Search index of hash table from offset of entry table */
733static Py_ssize_t
734lookdict_index(PyDictKeysObject *k, Py_hash_t hash, Py_ssize_t index)
735{
Victor Stinner742da042016-09-07 17:40:12 -0700736 size_t mask = DK_MASK(k);
INADA Naoki073ae482017-06-23 15:22:50 +0900737 size_t perturb = (size_t)hash;
738 size_t i = (size_t)hash & mask;
Victor Stinner742da042016-09-07 17:40:12 -0700739
INADA Naoki073ae482017-06-23 15:22:50 +0900740 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900741 Py_ssize_t ix = dictkeys_get_index(k, i);
Victor Stinner742da042016-09-07 17:40:12 -0700742 if (ix == index) {
743 return i;
744 }
745 if (ix == DKIX_EMPTY) {
746 return DKIX_EMPTY;
747 }
INADA Naoki073ae482017-06-23 15:22:50 +0900748 perturb >>= PERTURB_SHIFT;
749 i = mask & (i*5 + perturb + 1);
Victor Stinner742da042016-09-07 17:40:12 -0700750 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700751 Py_UNREACHABLE();
Victor Stinner742da042016-09-07 17:40:12 -0700752}
753
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000754/*
755The basic lookup function used by all operations.
Guido van Rossum16e93a81997-01-28 00:00:11 +0000756This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000757Open addressing is preferred over chaining since the link overhead for
758chaining would be substantial (100% with typical malloc overhead).
759
Tim Peterseb28ef22001-06-02 05:27:19 +0000760The initial probe index is computed as hash mod the table size. Subsequent
761probe indices are computed as explained earlier.
Guido van Rossum2bc13791999-03-24 19:06:42 +0000762
763All arithmetic on hash should ignore overflow.
Guido van Rossum16e93a81997-01-28 00:00:11 +0000764
Guido van Rossumdc5f6b22006-08-24 21:29:26 +0000765The details in this version are due to Tim Peters, building on many past
Tim Peterseb28ef22001-06-02 05:27:19 +0000766contributions by Reimer Behrends, Jyrki Alakuijala, Vladimir Marangozov and
Guido van Rossumdc5f6b22006-08-24 21:29:26 +0000767Christian Tismer.
Fred Drake1bff34a2000-08-31 19:31:38 +0000768
Victor Stinner742da042016-09-07 17:40:12 -0700769lookdict() is general-purpose, and may return DKIX_ERROR if (and only if) a
Victor Stinnera4348cc2016-09-08 12:01:25 -0700770comparison raises an exception.
Guido van Rossum89d8c602007-09-18 17:26:56 +0000771lookdict_unicode() below is specialized to string keys, comparison of which can
INADA Naoki1b8df102017-02-20 22:48:10 +0900772never raise an exception; that function can never return DKIX_ERROR when key
773is string. Otherwise, it falls back to lookdict().
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400774lookdict_unicode_nodummy is further specialized for string keys that cannot be
775the <dummy> value.
INADA Naoki778928b2017-08-03 23:45:15 +0900776For both, when the key isn't found a DKIX_EMPTY is returned.
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000777*/
Victor Stinnerc7a8f672016-11-15 15:13:40 +0100778static Py_ssize_t _Py_HOT_FUNCTION
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400779lookdict(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900780 Py_hash_t hash, PyObject **value_addr)
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000781{
INADA Naoki778928b2017-08-03 23:45:15 +0900782 size_t i, mask, perturb;
Victor Stinner742da042016-09-07 17:40:12 -0700783 PyDictKeysObject *dk;
INADA Naoki778928b2017-08-03 23:45:15 +0900784 PyDictKeyEntry *ep0;
Tim Peterseb28ef22001-06-02 05:27:19 +0000785
Antoine Pitrou9a234902012-05-13 20:48:01 +0200786top:
Victor Stinner742da042016-09-07 17:40:12 -0700787 dk = mp->ma_keys;
Victor Stinner742da042016-09-07 17:40:12 -0700788 ep0 = DK_ENTRIES(dk);
INADA Naoki778928b2017-08-03 23:45:15 +0900789 mask = DK_MASK(dk);
790 perturb = hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000791 i = (size_t)hash & mask;
Victor Stinner742da042016-09-07 17:40:12 -0700792
INADA Naoki778928b2017-08-03 23:45:15 +0900793 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900794 Py_ssize_t ix = dictkeys_get_index(dk, i);
Victor Stinner742da042016-09-07 17:40:12 -0700795 if (ix == DKIX_EMPTY) {
Victor Stinner742da042016-09-07 17:40:12 -0700796 *value_addr = NULL;
797 return ix;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400798 }
INADA Naoki778928b2017-08-03 23:45:15 +0900799 if (ix >= 0) {
800 PyDictKeyEntry *ep = &ep0[ix];
801 assert(ep->me_key != NULL);
802 if (ep->me_key == key) {
803 *value_addr = ep->me_value;
804 return ix;
Victor Stinner742da042016-09-07 17:40:12 -0700805 }
INADA Naoki778928b2017-08-03 23:45:15 +0900806 if (ep->me_hash == hash) {
807 PyObject *startkey = ep->me_key;
808 Py_INCREF(startkey);
809 int cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
810 Py_DECREF(startkey);
811 if (cmp < 0) {
812 *value_addr = NULL;
813 return DKIX_ERROR;
814 }
815 if (dk == mp->ma_keys && ep->me_key == startkey) {
816 if (cmp > 0) {
817 *value_addr = ep->me_value;
818 return ix;
Victor Stinner742da042016-09-07 17:40:12 -0700819 }
INADA Naoki778928b2017-08-03 23:45:15 +0900820 }
821 else {
822 /* The dict was mutated, restart */
823 goto top;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400824 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000825 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826 }
INADA Naoki778928b2017-08-03 23:45:15 +0900827 perturb >>= PERTURB_SHIFT;
828 i = (i*5 + perturb + 1) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000829 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700830 Py_UNREACHABLE();
Guido van Rossum4b1302b1993-03-27 18:11:32 +0000831}
832
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400833/* Specialized version for string-only keys */
Victor Stinnerc7a8f672016-11-15 15:13:40 +0100834static Py_ssize_t _Py_HOT_FUNCTION
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400835lookdict_unicode(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900836 Py_hash_t hash, PyObject **value_addr)
Fred Drake1bff34a2000-08-31 19:31:38 +0000837{
Victor Stinner742da042016-09-07 17:40:12 -0700838 assert(mp->ma_values == NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000839 /* Make sure this function doesn't have to handle non-unicode keys,
840 including subclasses of str; e.g., one reason to subclass
841 unicodes is to override __eq__, and for speed we don't cater to
842 that here. */
843 if (!PyUnicode_CheckExact(key)) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400844 mp->ma_keys->dk_lookup = lookdict;
INADA Naoki778928b2017-08-03 23:45:15 +0900845 return lookdict(mp, key, hash, value_addr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000846 }
Tim Peters15d49292001-05-27 07:39:22 +0000847
INADA Naoki778928b2017-08-03 23:45:15 +0900848 PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
849 size_t mask = DK_MASK(mp->ma_keys);
850 size_t perturb = (size_t)hash;
851 size_t i = (size_t)hash & mask;
852
853 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900854 Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
Victor Stinner742da042016-09-07 17:40:12 -0700855 if (ix == DKIX_EMPTY) {
Victor Stinner742da042016-09-07 17:40:12 -0700856 *value_addr = NULL;
857 return DKIX_EMPTY;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400858 }
INADA Naoki778928b2017-08-03 23:45:15 +0900859 if (ix >= 0) {
860 PyDictKeyEntry *ep = &ep0[ix];
861 assert(ep->me_key != NULL);
862 assert(PyUnicode_CheckExact(ep->me_key));
863 if (ep->me_key == key ||
864 (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
865 *value_addr = ep->me_value;
866 return ix;
Victor Stinner742da042016-09-07 17:40:12 -0700867 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400868 }
INADA Naoki778928b2017-08-03 23:45:15 +0900869 perturb >>= PERTURB_SHIFT;
870 i = mask & (i*5 + perturb + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000871 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700872 Py_UNREACHABLE();
Fred Drake1bff34a2000-08-31 19:31:38 +0000873}
874
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400875/* Faster version of lookdict_unicode when it is known that no <dummy> keys
876 * will be present. */
Victor Stinnerc7a8f672016-11-15 15:13:40 +0100877static Py_ssize_t _Py_HOT_FUNCTION
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400878lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900879 Py_hash_t hash, PyObject **value_addr)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400880{
Victor Stinner742da042016-09-07 17:40:12 -0700881 assert(mp->ma_values == NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400882 /* Make sure this function doesn't have to handle non-unicode keys,
883 including subclasses of str; e.g., one reason to subclass
884 unicodes is to override __eq__, and for speed we don't cater to
885 that here. */
886 if (!PyUnicode_CheckExact(key)) {
887 mp->ma_keys->dk_lookup = lookdict;
INADA Naoki778928b2017-08-03 23:45:15 +0900888 return lookdict(mp, key, hash, value_addr);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400889 }
INADA Naoki778928b2017-08-03 23:45:15 +0900890
891 PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
892 size_t mask = DK_MASK(mp->ma_keys);
893 size_t perturb = (size_t)hash;
894 size_t i = (size_t)hash & mask;
895
896 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900897 Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
Victor Stinner742da042016-09-07 17:40:12 -0700898 assert (ix != DKIX_DUMMY);
899 if (ix == DKIX_EMPTY) {
Victor Stinner742da042016-09-07 17:40:12 -0700900 *value_addr = NULL;
901 return DKIX_EMPTY;
902 }
INADA Naoki778928b2017-08-03 23:45:15 +0900903 PyDictKeyEntry *ep = &ep0[ix];
904 assert(ep->me_key != NULL);
905 assert(PyUnicode_CheckExact(ep->me_key));
Victor Stinner742da042016-09-07 17:40:12 -0700906 if (ep->me_key == key ||
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400907 (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
INADA Naokiba609772016-12-07 20:41:42 +0900908 *value_addr = ep->me_value;
Victor Stinner742da042016-09-07 17:40:12 -0700909 return ix;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400910 }
INADA Naoki778928b2017-08-03 23:45:15 +0900911 perturb >>= PERTURB_SHIFT;
912 i = mask & (i*5 + perturb + 1);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400913 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700914 Py_UNREACHABLE();
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400915}
916
917/* Version of lookdict for split tables.
918 * All split tables and only split tables use this lookup function.
919 * Split tables only contain unicode keys and no dummy keys,
920 * so algorithm is the same as lookdict_unicode_nodummy.
921 */
Victor Stinnerc7a8f672016-11-15 15:13:40 +0100922static Py_ssize_t _Py_HOT_FUNCTION
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400923lookdict_split(PyDictObject *mp, PyObject *key,
INADA Naoki778928b2017-08-03 23:45:15 +0900924 Py_hash_t hash, PyObject **value_addr)
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400925{
Victor Stinner742da042016-09-07 17:40:12 -0700926 /* mp must split table */
927 assert(mp->ma_values != NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400928 if (!PyUnicode_CheckExact(key)) {
INADA Naoki778928b2017-08-03 23:45:15 +0900929 Py_ssize_t ix = lookdict(mp, key, hash, value_addr);
Victor Stinner742da042016-09-07 17:40:12 -0700930 if (ix >= 0) {
INADA Naokiba609772016-12-07 20:41:42 +0900931 *value_addr = mp->ma_values[ix];
Victor Stinner742da042016-09-07 17:40:12 -0700932 }
933 return ix;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400934 }
Victor Stinner742da042016-09-07 17:40:12 -0700935
INADA Naoki778928b2017-08-03 23:45:15 +0900936 PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
937 size_t mask = DK_MASK(mp->ma_keys);
938 size_t perturb = (size_t)hash;
939 size_t i = (size_t)hash & mask;
940
941 for (;;) {
INADA Naokia7576492018-11-14 18:39:27 +0900942 Py_ssize_t ix = dictkeys_get_index(mp->ma_keys, i);
INADA Naoki778928b2017-08-03 23:45:15 +0900943 assert (ix != DKIX_DUMMY);
Victor Stinner742da042016-09-07 17:40:12 -0700944 if (ix == DKIX_EMPTY) {
Victor Stinner742da042016-09-07 17:40:12 -0700945 *value_addr = NULL;
946 return DKIX_EMPTY;
947 }
INADA Naoki778928b2017-08-03 23:45:15 +0900948 PyDictKeyEntry *ep = &ep0[ix];
949 assert(ep->me_key != NULL);
950 assert(PyUnicode_CheckExact(ep->me_key));
Victor Stinner742da042016-09-07 17:40:12 -0700951 if (ep->me_key == key ||
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400952 (ep->me_hash == hash && unicode_eq(ep->me_key, key))) {
INADA Naokiba609772016-12-07 20:41:42 +0900953 *value_addr = mp->ma_values[ix];
Victor Stinner742da042016-09-07 17:40:12 -0700954 return ix;
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400955 }
INADA Naoki778928b2017-08-03 23:45:15 +0900956 perturb >>= PERTURB_SHIFT;
957 i = mask & (i*5 + perturb + 1);
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400958 }
Barry Warsawb2e57942017-09-14 18:13:16 -0700959 Py_UNREACHABLE();
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400960}
961
Benjamin Petersonfb886362010-04-24 18:21:17 +0000962int
963_PyDict_HasOnlyStringKeys(PyObject *dict)
964{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000965 Py_ssize_t pos = 0;
966 PyObject *key, *value;
Benjamin Petersonf6096542010-11-17 22:33:12 +0000967 assert(PyDict_Check(dict));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000968 /* Shortcut */
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400969 if (((PyDictObject *)dict)->ma_keys->dk_lookup != lookdict)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000970 return 1;
971 while (PyDict_Next(dict, &pos, &key, &value))
972 if (!PyUnicode_Check(key))
973 return 0;
974 return 1;
Benjamin Petersonfb886362010-04-24 18:21:17 +0000975}
976
Antoine Pitrou3a652b12009-03-23 18:52:06 +0000977#define MAINTAIN_TRACKING(mp, key, value) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 do { \
979 if (!_PyObject_GC_IS_TRACKED(mp)) { \
980 if (_PyObject_GC_MAY_BE_TRACKED(key) || \
981 _PyObject_GC_MAY_BE_TRACKED(value)) { \
982 _PyObject_GC_TRACK(mp); \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 } \
984 } \
985 } while(0)
Antoine Pitrou3a652b12009-03-23 18:52:06 +0000986
987void
988_PyDict_MaybeUntrack(PyObject *op)
989{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 PyDictObject *mp;
991 PyObject *value;
Victor Stinner742da042016-09-07 17:40:12 -0700992 Py_ssize_t i, numentries;
993 PyDictKeyEntry *ep0;
Antoine Pitrou3a652b12009-03-23 18:52:06 +0000994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 if (!PyDict_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op))
996 return;
997
998 mp = (PyDictObject *) op;
Victor Stinner742da042016-09-07 17:40:12 -0700999 ep0 = DK_ENTRIES(mp->ma_keys);
1000 numentries = mp->ma_keys->dk_nentries;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001001 if (_PyDict_HasSplitTable(mp)) {
Victor Stinner742da042016-09-07 17:40:12 -07001002 for (i = 0; i < numentries; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001003 if ((value = mp->ma_values[i]) == NULL)
1004 continue;
1005 if (_PyObject_GC_MAY_BE_TRACKED(value)) {
Victor Stinner742da042016-09-07 17:40:12 -07001006 assert(!_PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001007 return;
1008 }
1009 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001011 else {
Victor Stinner742da042016-09-07 17:40:12 -07001012 for (i = 0; i < numentries; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001013 if ((value = ep0[i].me_value) == NULL)
1014 continue;
1015 if (_PyObject_GC_MAY_BE_TRACKED(value) ||
1016 _PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key))
1017 return;
1018 }
1019 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 _PyObject_GC_UNTRACK(op);
Antoine Pitrou3a652b12009-03-23 18:52:06 +00001021}
1022
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001023/* Internal function to find slot for an item from its hash
Victor Stinner3c336c52016-09-12 14:17:40 +02001024 when it is known that the key is not present in the dict.
1025
1026 The dict must be combined. */
INADA Naokiba609772016-12-07 20:41:42 +09001027static Py_ssize_t
INADA Naoki778928b2017-08-03 23:45:15 +09001028find_empty_slot(PyDictKeysObject *keys, Py_hash_t hash)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001029{
INADA Naoki778928b2017-08-03 23:45:15 +09001030 assert(keys != NULL);
Tim Peters6d6c1a32001-08-02 04:15:00 +00001031
INADA Naoki778928b2017-08-03 23:45:15 +09001032 const size_t mask = DK_MASK(keys);
1033 size_t i = hash & mask;
INADA Naokia7576492018-11-14 18:39:27 +09001034 Py_ssize_t ix = dictkeys_get_index(keys, i);
INADA Naoki778928b2017-08-03 23:45:15 +09001035 for (size_t perturb = hash; ix >= 0;) {
INADA Naoki267941c2016-10-06 15:19:07 +09001036 perturb >>= PERTURB_SHIFT;
INADA Naoki778928b2017-08-03 23:45:15 +09001037 i = (i*5 + perturb + 1) & mask;
INADA Naokia7576492018-11-14 18:39:27 +09001038 ix = dictkeys_get_index(keys, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 }
INADA Naoki778928b2017-08-03 23:45:15 +09001040 return i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001041}
1042
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001043static int
1044insertion_resize(PyDictObject *mp)
1045{
Raymond Hettinger36f74aa2013-05-17 03:01:13 -07001046 return dictresize(mp, GROWTH_RATE(mp));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001047}
Antoine Pitroue965d972012-02-27 00:45:12 +01001048
1049/*
1050Internal routine to insert a new item into the table.
1051Used both by the internal resize routine and by the public insert routine.
Antoine Pitroue965d972012-02-27 00:45:12 +01001052Returns -1 if an error occurred, or 0 on success.
1053*/
1054static int
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001055insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
Antoine Pitroue965d972012-02-27 00:45:12 +01001056{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001057 PyObject *old_value;
INADA Naokiba609772016-12-07 20:41:42 +09001058 PyDictKeyEntry *ep;
Antoine Pitroue965d972012-02-27 00:45:12 +01001059
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001060 Py_INCREF(key);
1061 Py_INCREF(value);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001062 if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) {
1063 if (insertion_resize(mp) < 0)
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001064 goto Fail;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001065 }
1066
INADA Naoki778928b2017-08-03 23:45:15 +09001067 Py_ssize_t ix = mp->ma_keys->dk_lookup(mp, key, hash, &old_value);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001068 if (ix == DKIX_ERROR)
1069 goto Fail;
Victor Stinner742da042016-09-07 17:40:12 -07001070
Antoine Pitroud6967322014-10-18 00:35:00 +02001071 assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001072 MAINTAIN_TRACKING(mp, key, value);
Victor Stinner742da042016-09-07 17:40:12 -07001073
1074 /* When insertion order is different from shared key, we can't share
1075 * the key anymore. Convert this instance to combine table.
1076 */
1077 if (_PyDict_HasSplitTable(mp) &&
INADA Naokiba609772016-12-07 20:41:42 +09001078 ((ix >= 0 && old_value == NULL && mp->ma_used != ix) ||
Victor Stinner742da042016-09-07 17:40:12 -07001079 (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) {
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001080 if (insertion_resize(mp) < 0)
1081 goto Fail;
Victor Stinner742da042016-09-07 17:40:12 -07001082 ix = DKIX_EMPTY;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001083 }
Victor Stinner742da042016-09-07 17:40:12 -07001084
1085 if (ix == DKIX_EMPTY) {
1086 /* Insert into new slot. */
INADA Naokiba609772016-12-07 20:41:42 +09001087 assert(old_value == NULL);
Victor Stinner742da042016-09-07 17:40:12 -07001088 if (mp->ma_keys->dk_usable <= 0) {
1089 /* Need to resize. */
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001090 if (insertion_resize(mp) < 0)
1091 goto Fail;
Victor Stinner742da042016-09-07 17:40:12 -07001092 }
INADA Naoki778928b2017-08-03 23:45:15 +09001093 Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash);
INADA Naokiba609772016-12-07 20:41:42 +09001094 ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries];
INADA Naokia7576492018-11-14 18:39:27 +09001095 dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
Victor Stinner742da042016-09-07 17:40:12 -07001096 ep->me_key = key;
1097 ep->me_hash = hash;
1098 if (mp->ma_values) {
1099 assert (mp->ma_values[mp->ma_keys->dk_nentries] == NULL);
1100 mp->ma_values[mp->ma_keys->dk_nentries] = value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001101 }
1102 else {
Victor Stinner742da042016-09-07 17:40:12 -07001103 ep->me_value = value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001104 }
1105 mp->ma_used++;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07001106 mp->ma_version_tag = DICT_NEXT_VERSION();
Victor Stinner742da042016-09-07 17:40:12 -07001107 mp->ma_keys->dk_usable--;
1108 mp->ma_keys->dk_nentries++;
1109 assert(mp->ma_keys->dk_usable >= 0);
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001110 ASSERT_CONSISTENT(mp);
Victor Stinner742da042016-09-07 17:40:12 -07001111 return 0;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001112 }
Victor Stinner742da042016-09-07 17:40:12 -07001113
Inada Naoki91234a12019-06-03 21:30:58 +09001114 if (old_value != value) {
1115 if (_PyDict_HasSplitTable(mp)) {
1116 mp->ma_values[ix] = value;
1117 if (old_value == NULL) {
1118 /* pending state */
1119 assert(ix == mp->ma_used);
1120 mp->ma_used++;
1121 }
INADA Naokiba609772016-12-07 20:41:42 +09001122 }
Inada Naoki91234a12019-06-03 21:30:58 +09001123 else {
1124 assert(old_value != NULL);
1125 DK_ENTRIES(mp->ma_keys)[ix].me_value = value;
1126 }
1127 mp->ma_version_tag = DICT_NEXT_VERSION();
INADA Naokiba609772016-12-07 20:41:42 +09001128 }
INADA Naokiba609772016-12-07 20:41:42 +09001129 Py_XDECREF(old_value); /* which **CAN** re-enter (see issue #22653) */
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001130 ASSERT_CONSISTENT(mp);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001131 Py_DECREF(key);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001132 return 0;
Serhiy Storchaka753bca32017-05-20 12:30:02 +03001133
1134Fail:
1135 Py_DECREF(value);
1136 Py_DECREF(key);
1137 return -1;
Antoine Pitroue965d972012-02-27 00:45:12 +01001138}
1139
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001140// Same to insertdict but specialized for ma_keys = Py_EMPTY_KEYS.
1141static int
1142insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash,
1143 PyObject *value)
1144{
1145 assert(mp->ma_keys == Py_EMPTY_KEYS);
1146
1147 PyDictKeysObject *newkeys = new_keys_object(PyDict_MINSIZE);
1148 if (newkeys == NULL) {
1149 return -1;
1150 }
1151 if (!PyUnicode_CheckExact(key)) {
1152 newkeys->dk_lookup = lookdict;
1153 }
1154 dictkeys_decref(Py_EMPTY_KEYS);
1155 mp->ma_keys = newkeys;
1156 mp->ma_values = NULL;
1157
1158 Py_INCREF(key);
1159 Py_INCREF(value);
1160 MAINTAIN_TRACKING(mp, key, value);
1161
1162 size_t hashpos = (size_t)hash & (PyDict_MINSIZE-1);
Dong-hee Nac39d1dd2019-10-11 17:43:11 +09001163 PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys);
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001164 dictkeys_set_index(mp->ma_keys, hashpos, 0);
1165 ep->me_key = key;
1166 ep->me_hash = hash;
1167 ep->me_value = value;
1168 mp->ma_used++;
1169 mp->ma_version_tag = DICT_NEXT_VERSION();
1170 mp->ma_keys->dk_usable--;
1171 mp->ma_keys->dk_nentries++;
1172 return 0;
1173}
1174
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001175/*
luzpaza5293b42017-11-05 07:37:50 -06001176Internal routine used by dictresize() to build a hashtable of entries.
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001177*/
1178static void
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001179build_indices(PyDictKeysObject *keys, PyDictKeyEntry *ep, Py_ssize_t n)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001180{
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001181 size_t mask = (size_t)DK_SIZE(keys) - 1;
1182 for (Py_ssize_t ix = 0; ix != n; ix++, ep++) {
1183 Py_hash_t hash = ep->me_hash;
1184 size_t i = hash & mask;
INADA Naokia7576492018-11-14 18:39:27 +09001185 for (size_t perturb = hash; dictkeys_get_index(keys, i) != DKIX_EMPTY;) {
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001186 perturb >>= PERTURB_SHIFT;
INADA Naoki870c2862017-06-24 09:03:19 +09001187 i = mask & (i*5 + perturb + 1);
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001188 }
INADA Naokia7576492018-11-14 18:39:27 +09001189 dictkeys_set_index(keys, i, ix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 }
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001191}
1192
1193/*
1194Restructure the table by allocating a new table and reinserting all
1195items again. When entries have been deleted, the new table may
1196actually be smaller than the old one.
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001197If a table is split (its keys and hashes are shared, its values are not),
1198then the values are temporarily copied into the table, it is resized as
1199a combined table, then the me_value slots in the old table are NULLed out.
1200After resizing a table is always combined,
1201but can be resplit by make_keys_shared().
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001202*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001203static int
Victor Stinner3d3f2642016-12-15 17:21:23 +01001204dictresize(PyDictObject *mp, Py_ssize_t minsize)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001205{
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001206 Py_ssize_t newsize, numentries;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001207 PyDictKeysObject *oldkeys;
1208 PyObject **oldvalues;
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001209 PyDictKeyEntry *oldentries, *newentries;
Tim Peters91a364d2001-05-19 07:04:38 +00001210
Victor Stinner742da042016-09-07 17:40:12 -07001211 /* Find the smallest table size > minused. */
1212 for (newsize = PyDict_MINSIZE;
Victor Stinner3d3f2642016-12-15 17:21:23 +01001213 newsize < minsize && newsize > 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001214 newsize <<= 1)
1215 ;
1216 if (newsize <= 0) {
1217 PyErr_NoMemory();
1218 return -1;
1219 }
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001220
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001221 oldkeys = mp->ma_keys;
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001222
1223 /* NOTE: Current odict checks mp->ma_keys to detect resize happen.
1224 * So we can't reuse oldkeys even if oldkeys->dk_size == newsize.
1225 * TODO: Try reusing oldkeys when reimplement odict.
1226 */
1227
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001228 /* Allocate a new table. */
1229 mp->ma_keys = new_keys_object(newsize);
1230 if (mp->ma_keys == NULL) {
1231 mp->ma_keys = oldkeys;
1232 return -1;
1233 }
Victor Stinner3d3f2642016-12-15 17:21:23 +01001234 // New table must be large enough.
1235 assert(mp->ma_keys->dk_usable >= mp->ma_used);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001236 if (oldkeys->dk_lookup == lookdict)
1237 mp->ma_keys->dk_lookup = lookdict;
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001238
1239 numentries = mp->ma_used;
1240 oldentries = DK_ENTRIES(oldkeys);
1241 newentries = DK_ENTRIES(mp->ma_keys);
1242 oldvalues = mp->ma_values;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001243 if (oldvalues != NULL) {
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001244 /* Convert split table into new combined table.
1245 * We must incref keys; we can transfer values.
1246 * Note that values of split table is always dense.
1247 */
1248 for (Py_ssize_t i = 0; i < numentries; i++) {
1249 assert(oldvalues[i] != NULL);
1250 PyDictKeyEntry *ep = &oldentries[i];
1251 PyObject *key = ep->me_key;
1252 Py_INCREF(key);
1253 newentries[i].me_key = key;
1254 newentries[i].me_hash = ep->me_hash;
1255 newentries[i].me_value = oldvalues[i];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 }
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001257
INADA Naokia7576492018-11-14 18:39:27 +09001258 dictkeys_decref(oldkeys);
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001259 mp->ma_values = NULL;
Victor Stinner742da042016-09-07 17:40:12 -07001260 if (oldvalues != empty_values) {
1261 free_values(oldvalues);
1262 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001263 }
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001264 else { // combined table.
1265 if (oldkeys->dk_nentries == numentries) {
1266 memcpy(newentries, oldentries, numentries * sizeof(PyDictKeyEntry));
1267 }
1268 else {
1269 PyDictKeyEntry *ep = oldentries;
1270 for (Py_ssize_t i = 0; i < numentries; i++) {
1271 while (ep->me_value == NULL)
1272 ep++;
1273 newentries[i] = *ep++;
1274 }
1275 }
1276
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001277 assert(oldkeys->dk_lookup != lookdict_split);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001278 assert(oldkeys->dk_refcnt == 1);
Victor Stinner49932fe2020-02-03 17:55:05 +01001279#ifdef Py_REF_DEBUG
1280 _Py_RefTotal--;
1281#endif
Victor Stinnerb4b53862020-05-05 19:55:29 +02001282#if PyDict_MAXFREELIST > 0
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001283 if (oldkeys->dk_size == PyDict_MINSIZE &&
Victor Stinner49932fe2020-02-03 17:55:05 +01001284 numfreekeys < PyDict_MAXFREELIST)
1285 {
INADA Naokia7576492018-11-14 18:39:27 +09001286 keys_free_list[numfreekeys++] = oldkeys;
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001287 }
Victor Stinnerb4b53862020-05-05 19:55:29 +02001288 else
1289#endif
1290 {
INADA Naokia7576492018-11-14 18:39:27 +09001291 PyObject_FREE(oldkeys);
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001292 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001293 }
Serhiy Storchakae26e20d2016-10-29 10:50:00 +03001294
1295 build_indices(mp->ma_keys, newentries, numentries);
1296 mp->ma_keys->dk_usable -= numentries;
1297 mp->ma_keys->dk_nentries = numentries;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 return 0;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001299}
1300
Benjamin Peterson15ee8212012-04-24 14:44:18 -04001301/* Returns NULL if unable to split table.
1302 * A NULL return does not necessarily indicate an error */
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001303static PyDictKeysObject *
1304make_keys_shared(PyObject *op)
1305{
1306 Py_ssize_t i;
1307 Py_ssize_t size;
1308 PyDictObject *mp = (PyDictObject *)op;
1309
Benjamin Peterson15ee8212012-04-24 14:44:18 -04001310 if (!PyDict_CheckExact(op))
1311 return NULL;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001312 if (!_PyDict_HasSplitTable(mp)) {
1313 PyDictKeyEntry *ep0;
1314 PyObject **values;
1315 assert(mp->ma_keys->dk_refcnt == 1);
1316 if (mp->ma_keys->dk_lookup == lookdict) {
1317 return NULL;
1318 }
1319 else if (mp->ma_keys->dk_lookup == lookdict_unicode) {
1320 /* Remove dummy keys */
1321 if (dictresize(mp, DK_SIZE(mp->ma_keys)))
1322 return NULL;
1323 }
1324 assert(mp->ma_keys->dk_lookup == lookdict_unicode_nodummy);
1325 /* Copy values into a new array */
Victor Stinner742da042016-09-07 17:40:12 -07001326 ep0 = DK_ENTRIES(mp->ma_keys);
1327 size = USABLE_FRACTION(DK_SIZE(mp->ma_keys));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001328 values = new_values(size);
1329 if (values == NULL) {
1330 PyErr_SetString(PyExc_MemoryError,
1331 "Not enough memory to allocate new values array");
1332 return NULL;
1333 }
1334 for (i = 0; i < size; i++) {
1335 values[i] = ep0[i].me_value;
1336 ep0[i].me_value = NULL;
1337 }
1338 mp->ma_keys->dk_lookup = lookdict_split;
1339 mp->ma_values = values;
1340 }
INADA Naokia7576492018-11-14 18:39:27 +09001341 dictkeys_incref(mp->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001342 return mp->ma_keys;
1343}
Christian Heimes99170a52007-12-19 02:07:34 +00001344
1345PyObject *
1346_PyDict_NewPresized(Py_ssize_t minused)
1347{
INADA Naoki92c50ee2016-11-22 00:57:02 +09001348 const Py_ssize_t max_presize = 128 * 1024;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001349 Py_ssize_t newsize;
1350 PyDictKeysObject *new_keys;
INADA Naoki92c50ee2016-11-22 00:57:02 +09001351
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001352 if (minused <= USABLE_FRACTION(PyDict_MINSIZE)) {
Inada Naokif2a18672019-03-12 17:25:44 +09001353 return PyDict_New();
1354 }
INADA Naoki92c50ee2016-11-22 00:57:02 +09001355 /* There are no strict guarantee that returned dict can contain minused
1356 * items without resize. So we create medium size dict instead of very
1357 * large dict or MemoryError.
1358 */
1359 if (minused > USABLE_FRACTION(max_presize)) {
1360 newsize = max_presize;
1361 }
1362 else {
1363 Py_ssize_t minsize = ESTIMATE_SIZE(minused);
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001364 newsize = PyDict_MINSIZE*2;
INADA Naoki92c50ee2016-11-22 00:57:02 +09001365 while (newsize < minsize) {
1366 newsize <<= 1;
1367 }
1368 }
1369 assert(IS_POWER_OF_2(newsize));
1370
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001371 new_keys = new_keys_object(newsize);
1372 if (new_keys == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 return NULL;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001374 return new_dict(new_keys, NULL);
Christian Heimes99170a52007-12-19 02:07:34 +00001375}
1376
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001377/* Note that, for historical reasons, PyDict_GetItem() suppresses all errors
1378 * that may occur (originally dicts supported only string keys, and exceptions
1379 * weren't possible). So, while the original intent was that a NULL return
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001380 * meant the key wasn't present, in reality it can mean that, or that an error
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001381 * (suppressed) occurred while computing the key's hash, or that some error
1382 * (suppressed) occurred when comparing keys in the dict's internal probe
1383 * sequence. A nasty example of the latter is when a Python-coded comparison
1384 * function hits a stack-depth error, which can cause this to return NULL
1385 * even if the key is present.
1386 */
Guido van Rossumc0b618a1997-05-02 03:12:38 +00001387PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00001388PyDict_GetItem(PyObject *op, PyObject *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001389{
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001390 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07001391 Py_ssize_t ix;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 PyDictObject *mp = (PyDictObject *)op;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 PyThreadState *tstate;
INADA Naokiba609772016-12-07 20:41:42 +09001394 PyObject *value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 if (!PyDict_Check(op))
1397 return NULL;
1398 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001399 (hash = ((PyASCIIObject *) key)->hash) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001400 {
1401 hash = PyObject_Hash(key);
1402 if (hash == -1) {
1403 PyErr_Clear();
1404 return NULL;
1405 }
1406 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 /* We can arrive here with a NULL tstate during initialization: try
1409 running "python -Wi" for an example related to string interning.
1410 Let's just hope that no exception occurs then... This must be
Victor Stinner50b48572018-11-01 01:51:40 +01001411 _PyThreadState_GET() and not PyThreadState_Get() because the latter
Victor Stinner9204fb82018-10-30 15:13:17 +01001412 abort Python if tstate is NULL. */
Victor Stinner50b48572018-11-01 01:51:40 +01001413 tstate = _PyThreadState_GET();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 if (tstate != NULL && tstate->curexc_type != NULL) {
1415 /* preserve the existing exception */
1416 PyObject *err_type, *err_value, *err_tb;
1417 PyErr_Fetch(&err_type, &err_value, &err_tb);
INADA Naoki778928b2017-08-03 23:45:15 +09001418 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 /* ignore errors */
1420 PyErr_Restore(err_type, err_value, err_tb);
Victor Stinner742da042016-09-07 17:40:12 -07001421 if (ix < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 return NULL;
1423 }
1424 else {
INADA Naoki778928b2017-08-03 23:45:15 +09001425 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07001426 if (ix < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 PyErr_Clear();
1428 return NULL;
1429 }
1430 }
INADA Naokiba609772016-12-07 20:41:42 +09001431 return value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001432}
1433
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02001434/* Same as PyDict_GetItemWithError() but with hash supplied by caller.
1435 This returns NULL *with* an exception set if an exception occurred.
1436 It returns NULL *without* an exception set if the key wasn't present.
1437*/
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001438PyObject *
1439_PyDict_GetItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
1440{
Victor Stinner742da042016-09-07 17:40:12 -07001441 Py_ssize_t ix;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001442 PyDictObject *mp = (PyDictObject *)op;
INADA Naokiba609772016-12-07 20:41:42 +09001443 PyObject *value;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001444
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02001445 if (!PyDict_Check(op)) {
1446 PyErr_BadInternalCall();
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001447 return NULL;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001448 }
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02001449
INADA Naoki778928b2017-08-03 23:45:15 +09001450 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02001451 if (ix < 0) {
1452 return NULL;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001453 }
INADA Naokiba609772016-12-07 20:41:42 +09001454 return value;
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001455}
1456
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001457/* Variant of PyDict_GetItem() that doesn't suppress exceptions.
1458 This returns NULL *with* an exception set if an exception occurred.
1459 It returns NULL *without* an exception set if the key wasn't present.
1460*/
1461PyObject *
1462PyDict_GetItemWithError(PyObject *op, PyObject *key)
1463{
Victor Stinner742da042016-09-07 17:40:12 -07001464 Py_ssize_t ix;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001465 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 PyDictObject*mp = (PyDictObject *)op;
INADA Naokiba609772016-12-07 20:41:42 +09001467 PyObject *value;
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 if (!PyDict_Check(op)) {
1470 PyErr_BadInternalCall();
1471 return NULL;
1472 }
1473 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001474 (hash = ((PyASCIIObject *) key)->hash) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 {
1476 hash = PyObject_Hash(key);
1477 if (hash == -1) {
1478 return NULL;
1479 }
1480 }
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001481
INADA Naoki778928b2017-08-03 23:45:15 +09001482 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07001483 if (ix < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001485 return value;
Guido van Rossum47b9ff62006-08-24 00:41:19 +00001486}
1487
Brett Cannonfd074152012-04-14 14:10:13 -04001488PyObject *
1489_PyDict_GetItemIdWithError(PyObject *dp, struct _Py_Identifier *key)
1490{
1491 PyObject *kv;
1492 kv = _PyUnicode_FromId(key); /* borrowed */
1493 if (kv == NULL)
1494 return NULL;
scoder6067d4b2020-05-11 06:04:31 +02001495 Py_hash_t hash = ((PyASCIIObject *) kv)->hash;
1496 assert (hash != -1); /* interned strings have their hash value initialised */
1497 return _PyDict_GetItem_KnownHash(dp, kv, hash);
Brett Cannonfd074152012-04-14 14:10:13 -04001498}
1499
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02001500PyObject *
1501_PyDict_GetItemStringWithError(PyObject *v, const char *key)
1502{
1503 PyObject *kv, *rv;
1504 kv = PyUnicode_FromString(key);
1505 if (kv == NULL) {
1506 return NULL;
1507 }
1508 rv = PyDict_GetItemWithError(v, kv);
1509 Py_DECREF(kv);
1510 return rv;
1511}
1512
Victor Stinnerb4efc962015-11-20 09:24:02 +01001513/* Fast version of global value lookup (LOAD_GLOBAL).
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001514 * Lookup in globals, then builtins.
Victor Stinnerb4efc962015-11-20 09:24:02 +01001515 *
1516 * Raise an exception and return NULL if an error occurred (ex: computing the
1517 * key hash failed, key comparison failed, ...). Return NULL if the key doesn't
1518 * exist. Return the value if the key exists.
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001519 */
1520PyObject *
1521_PyDict_LoadGlobal(PyDictObject *globals, PyDictObject *builtins, PyObject *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001522{
Victor Stinner742da042016-09-07 17:40:12 -07001523 Py_ssize_t ix;
Victor Stinnerb4efc962015-11-20 09:24:02 +01001524 Py_hash_t hash;
INADA Naokiba609772016-12-07 20:41:42 +09001525 PyObject *value;
Victor Stinnerb4efc962015-11-20 09:24:02 +01001526
1527 if (!PyUnicode_CheckExact(key) ||
1528 (hash = ((PyASCIIObject *) key)->hash) == -1)
1529 {
1530 hash = PyObject_Hash(key);
1531 if (hash == -1)
1532 return NULL;
Antoine Pitroue965d972012-02-27 00:45:12 +01001533 }
Victor Stinnerb4efc962015-11-20 09:24:02 +01001534
1535 /* namespace 1: globals */
INADA Naoki778928b2017-08-03 23:45:15 +09001536 ix = globals->ma_keys->dk_lookup(globals, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07001537 if (ix == DKIX_ERROR)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001538 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001539 if (ix != DKIX_EMPTY && value != NULL)
1540 return value;
Victor Stinnerb4efc962015-11-20 09:24:02 +01001541
1542 /* namespace 2: builtins */
INADA Naoki778928b2017-08-03 23:45:15 +09001543 ix = builtins->ma_keys->dk_lookup(builtins, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07001544 if (ix < 0)
Victor Stinnerb4efc962015-11-20 09:24:02 +01001545 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001546 return value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001547}
1548
Antoine Pitroue965d972012-02-27 00:45:12 +01001549/* CAUTION: PyDict_SetItem() must guarantee that it won't resize the
1550 * dictionary if it's merely replacing the value for an existing key.
1551 * This means that it's safe to loop over a dictionary with PyDict_Next()
1552 * and occasionally replace a value -- but you can't insert new keys or
1553 * remove them.
1554 */
1555int
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001556PyDict_SetItem(PyObject *op, PyObject *key, PyObject *value)
Antoine Pitroue965d972012-02-27 00:45:12 +01001557{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001558 PyDictObject *mp;
1559 Py_hash_t hash;
Antoine Pitroue965d972012-02-27 00:45:12 +01001560 if (!PyDict_Check(op)) {
1561 PyErr_BadInternalCall();
1562 return -1;
1563 }
1564 assert(key);
1565 assert(value);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001566 mp = (PyDictObject *)op;
1567 if (!PyUnicode_CheckExact(key) ||
1568 (hash = ((PyASCIIObject *) key)->hash) == -1)
1569 {
Antoine Pitroue965d972012-02-27 00:45:12 +01001570 hash = PyObject_Hash(key);
1571 if (hash == -1)
1572 return -1;
1573 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001574
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001575 if (mp->ma_keys == Py_EMPTY_KEYS) {
1576 return insert_to_emptydict(mp, key, hash, value);
1577 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001578 /* insertdict() handles any resizing that might be necessary */
1579 return insertdict(mp, key, hash, value);
Antoine Pitroue965d972012-02-27 00:45:12 +01001580}
1581
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001582int
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001583_PyDict_SetItem_KnownHash(PyObject *op, PyObject *key, PyObject *value,
1584 Py_hash_t hash)
1585{
1586 PyDictObject *mp;
1587
1588 if (!PyDict_Check(op)) {
1589 PyErr_BadInternalCall();
1590 return -1;
1591 }
1592 assert(key);
1593 assert(value);
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001594 assert(hash != -1);
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001595 mp = (PyDictObject *)op;
1596
Inada Naoki2ddc7f62019-03-18 20:38:33 +09001597 if (mp->ma_keys == Py_EMPTY_KEYS) {
1598 return insert_to_emptydict(mp, key, hash, value);
1599 }
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001600 /* insertdict() handles any resizing that might be necessary */
1601 return insertdict(mp, key, hash, value);
1602}
1603
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001604static int
INADA Naoki778928b2017-08-03 23:45:15 +09001605delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix,
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001606 PyObject *old_value)
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001607{
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001608 PyObject *old_key;
Antoine Pitroud741ed42016-12-27 14:23:43 +01001609 PyDictKeyEntry *ep;
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001610
INADA Naoki778928b2017-08-03 23:45:15 +09001611 Py_ssize_t hashpos = lookdict_index(mp->ma_keys, hash, ix);
1612 assert(hashpos >= 0);
1613
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001614 mp->ma_used--;
Antoine Pitroud741ed42016-12-27 14:23:43 +01001615 mp->ma_version_tag = DICT_NEXT_VERSION();
1616 ep = &DK_ENTRIES(mp->ma_keys)[ix];
INADA Naokia7576492018-11-14 18:39:27 +09001617 dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
Antoine Pitroud741ed42016-12-27 14:23:43 +01001618 ENSURE_ALLOWS_DELETIONS(mp);
1619 old_key = ep->me_key;
1620 ep->me_key = NULL;
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001621 ep->me_value = NULL;
Antoine Pitroud741ed42016-12-27 14:23:43 +01001622 Py_DECREF(old_key);
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001623 Py_DECREF(old_value);
Antoine Pitroud741ed42016-12-27 14:23:43 +01001624
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001625 ASSERT_CONSISTENT(mp);
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001626 return 0;
1627}
1628
Raymond Hettinger4b74fba2014-05-03 16:32:11 -07001629int
Tim Peters1f5871e2000-07-04 17:44:48 +00001630PyDict_DelItem(PyObject *op, PyObject *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001631{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001632 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 assert(key);
1634 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001635 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001636 hash = PyObject_Hash(key);
1637 if (hash == -1)
1638 return -1;
1639 }
Victor Stinner742da042016-09-07 17:40:12 -07001640
1641 return _PyDict_DelItem_KnownHash(op, key, hash);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001642}
1643
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001644int
1645_PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
1646{
INADA Naoki778928b2017-08-03 23:45:15 +09001647 Py_ssize_t ix;
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001648 PyDictObject *mp;
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001649 PyObject *old_value;
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001650
1651 if (!PyDict_Check(op)) {
1652 PyErr_BadInternalCall();
1653 return -1;
1654 }
1655 assert(key);
1656 assert(hash != -1);
1657 mp = (PyDictObject *)op;
INADA Naoki778928b2017-08-03 23:45:15 +09001658 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Victor Stinner742da042016-09-07 17:40:12 -07001659 if (ix == DKIX_ERROR)
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001660 return -1;
INADA Naokiba609772016-12-07 20:41:42 +09001661 if (ix == DKIX_EMPTY || old_value == NULL) {
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001662 _PyErr_SetKeyError(key);
1663 return -1;
1664 }
Victor Stinner78601a32016-09-09 19:28:36 -07001665
1666 // Split table doesn't allow deletion. Combine it.
1667 if (_PyDict_HasSplitTable(mp)) {
1668 if (dictresize(mp, DK_SIZE(mp->ma_keys))) {
1669 return -1;
1670 }
INADA Naoki778928b2017-08-03 23:45:15 +09001671 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Victor Stinner78601a32016-09-09 19:28:36 -07001672 assert(ix >= 0);
1673 }
1674
INADA Naoki778928b2017-08-03 23:45:15 +09001675 return delitem_common(mp, hash, ix, old_value);
Serhiy Storchakab9d98d52015-10-02 12:47:11 +03001676}
1677
Antoine Pitroud741ed42016-12-27 14:23:43 +01001678/* This function promises that the predicate -> deletion sequence is atomic
1679 * (i.e. protected by the GIL), assuming the predicate itself doesn't
1680 * release the GIL.
1681 */
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001682int
1683_PyDict_DelItemIf(PyObject *op, PyObject *key,
1684 int (*predicate)(PyObject *value))
1685{
Antoine Pitroud741ed42016-12-27 14:23:43 +01001686 Py_ssize_t hashpos, ix;
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001687 PyDictObject *mp;
1688 Py_hash_t hash;
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001689 PyObject *old_value;
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001690 int res;
1691
1692 if (!PyDict_Check(op)) {
1693 PyErr_BadInternalCall();
1694 return -1;
1695 }
1696 assert(key);
1697 hash = PyObject_Hash(key);
1698 if (hash == -1)
1699 return -1;
1700 mp = (PyDictObject *)op;
INADA Naoki778928b2017-08-03 23:45:15 +09001701 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Antoine Pitroud741ed42016-12-27 14:23:43 +01001702 if (ix == DKIX_ERROR)
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001703 return -1;
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001704 if (ix == DKIX_EMPTY || old_value == NULL) {
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001705 _PyErr_SetKeyError(key);
1706 return -1;
1707 }
Antoine Pitroud741ed42016-12-27 14:23:43 +01001708
1709 // Split table doesn't allow deletion. Combine it.
1710 if (_PyDict_HasSplitTable(mp)) {
1711 if (dictresize(mp, DK_SIZE(mp->ma_keys))) {
1712 return -1;
1713 }
INADA Naoki778928b2017-08-03 23:45:15 +09001714 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Antoine Pitroud741ed42016-12-27 14:23:43 +01001715 assert(ix >= 0);
1716 }
1717
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001718 res = predicate(old_value);
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001719 if (res == -1)
1720 return -1;
INADA Naoki778928b2017-08-03 23:45:15 +09001721
1722 hashpos = lookdict_index(mp->ma_keys, hash, ix);
1723 assert(hashpos >= 0);
1724
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001725 if (res > 0)
Antoine Pitrouc06ae202016-12-27 14:34:54 +01001726 return delitem_common(mp, hashpos, ix, old_value);
Antoine Pitroue10ca3a2016-12-27 14:19:20 +01001727 else
1728 return 0;
1729}
1730
1731
Guido van Rossum25831651993-05-19 14:50:45 +00001732void
Tim Peters1f5871e2000-07-04 17:44:48 +00001733PyDict_Clear(PyObject *op)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001734{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001735 PyDictObject *mp;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001736 PyDictKeysObject *oldkeys;
1737 PyObject **oldvalues;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001738 Py_ssize_t i, n;
Tim Petersdea48ec2001-05-22 20:40:22 +00001739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 if (!PyDict_Check(op))
1741 return;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001742 mp = ((PyDictObject *)op);
1743 oldkeys = mp->ma_keys;
1744 oldvalues = mp->ma_values;
1745 if (oldvalues == empty_values)
1746 return;
1747 /* Empty the dict... */
INADA Naokia7576492018-11-14 18:39:27 +09001748 dictkeys_incref(Py_EMPTY_KEYS);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001749 mp->ma_keys = Py_EMPTY_KEYS;
1750 mp->ma_values = empty_values;
1751 mp->ma_used = 0;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07001752 mp->ma_version_tag = DICT_NEXT_VERSION();
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001753 /* ...then clear the keys and values */
1754 if (oldvalues != NULL) {
Victor Stinner742da042016-09-07 17:40:12 -07001755 n = oldkeys->dk_nentries;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001756 for (i = 0; i < n; i++)
1757 Py_CLEAR(oldvalues[i]);
1758 free_values(oldvalues);
INADA Naokia7576492018-11-14 18:39:27 +09001759 dictkeys_decref(oldkeys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001760 }
1761 else {
1762 assert(oldkeys->dk_refcnt == 1);
INADA Naokia7576492018-11-14 18:39:27 +09001763 dictkeys_decref(oldkeys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001764 }
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001765 ASSERT_CONSISTENT(mp);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001766}
1767
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001768/* Internal version of PyDict_Next that returns a hash value in addition
1769 * to the key and value.
1770 * Return 1 on success, return 0 when the reached the end of the dictionary
1771 * (or if op is not a dictionary)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001772 */
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001773int
1774_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
1775 PyObject **pvalue, Py_hash_t *phash)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001776{
INADA Naokica2d8be2016-11-04 16:59:10 +09001777 Py_ssize_t i;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001778 PyDictObject *mp;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001779 PyDictKeyEntry *entry_ptr;
1780 PyObject *value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001781
1782 if (!PyDict_Check(op))
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001783 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 mp = (PyDictObject *)op;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001785 i = *ppos;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001786 if (mp->ma_values) {
INADA Naokica2d8be2016-11-04 16:59:10 +09001787 if (i < 0 || i >= mp->ma_used)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001788 return 0;
INADA Naokica2d8be2016-11-04 16:59:10 +09001789 /* values of split table is always dense */
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001790 entry_ptr = &DK_ENTRIES(mp->ma_keys)[i];
INADA Naokica2d8be2016-11-04 16:59:10 +09001791 value = mp->ma_values[i];
1792 assert(value != NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001793 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001794 else {
INADA Naokica2d8be2016-11-04 16:59:10 +09001795 Py_ssize_t n = mp->ma_keys->dk_nentries;
1796 if (i < 0 || i >= n)
1797 return 0;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001798 entry_ptr = &DK_ENTRIES(mp->ma_keys)[i];
1799 while (i < n && entry_ptr->me_value == NULL) {
1800 entry_ptr++;
1801 i++;
Victor Stinner742da042016-09-07 17:40:12 -07001802 }
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001803 if (i >= n)
1804 return 0;
1805 value = entry_ptr->me_value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001806 }
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001807 *ppos = i+1;
1808 if (pkey)
1809 *pkey = entry_ptr->me_key;
1810 if (phash)
1811 *phash = entry_ptr->me_hash;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04001812 if (pvalue)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001813 *pvalue = value;
1814 return 1;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001815}
1816
Tim Peters080c88b2003-02-15 03:01:11 +00001817/*
1818 * Iterate over a dict. Use like so:
1819 *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001820 * Py_ssize_t i;
Tim Peters080c88b2003-02-15 03:01:11 +00001821 * PyObject *key, *value;
1822 * i = 0; # important! i should not otherwise be changed by you
Neal Norwitz07323012003-02-15 14:45:12 +00001823 * while (PyDict_Next(yourdict, &i, &key, &value)) {
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001824 * Refer to borrowed references in key and value.
Tim Peters080c88b2003-02-15 03:01:11 +00001825 * }
1826 *
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001827 * Return 1 on success, return 0 when the reached the end of the dictionary
1828 * (or if op is not a dictionary)
1829 *
Tim Peters080c88b2003-02-15 03:01:11 +00001830 * CAUTION: In general, it isn't safe to use PyDict_Next in a loop that
Tim Peters67830702001-03-21 19:23:56 +00001831 * mutates the dict. One exception: it is safe if the loop merely changes
1832 * the values associated with the keys (but doesn't insert new keys or
1833 * delete keys), via PyDict_SetItem().
1834 */
Guido van Rossum25831651993-05-19 14:50:45 +00001835int
Martin v. Löwis18e16552006-02-15 17:27:45 +00001836PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00001837{
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03001838 return _PyDict_Next(op, ppos, pkey, pvalue, NULL);
Thomas Wouterscf297e42007-02-23 15:07:44 +00001839}
1840
Eric Snow96c6af92015-05-29 22:21:39 -06001841/* Internal version of dict.pop(). */
1842PyObject *
Serhiy Storchaka42e1ea92017-01-12 19:12:21 +02001843_PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *deflt)
Eric Snow96c6af92015-05-29 22:21:39 -06001844{
Victor Stinner742da042016-09-07 17:40:12 -07001845 Py_ssize_t ix, hashpos;
Eric Snow96c6af92015-05-29 22:21:39 -06001846 PyObject *old_value, *old_key;
1847 PyDictKeyEntry *ep;
Yury Selivanov684ef2c2016-10-28 19:01:21 -04001848 PyDictObject *mp;
1849
1850 assert(PyDict_Check(dict));
1851 mp = (PyDictObject *)dict;
Eric Snow96c6af92015-05-29 22:21:39 -06001852
1853 if (mp->ma_used == 0) {
1854 if (deflt) {
1855 Py_INCREF(deflt);
1856 return deflt;
1857 }
1858 _PyErr_SetKeyError(key);
1859 return NULL;
1860 }
INADA Naoki778928b2017-08-03 23:45:15 +09001861 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Victor Stinner742da042016-09-07 17:40:12 -07001862 if (ix == DKIX_ERROR)
Eric Snow96c6af92015-05-29 22:21:39 -06001863 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001864 if (ix == DKIX_EMPTY || old_value == NULL) {
Eric Snow96c6af92015-05-29 22:21:39 -06001865 if (deflt) {
1866 Py_INCREF(deflt);
1867 return deflt;
1868 }
1869 _PyErr_SetKeyError(key);
1870 return NULL;
1871 }
Victor Stinner3b6a6b42016-09-08 12:51:24 -07001872
Victor Stinner78601a32016-09-09 19:28:36 -07001873 // Split table doesn't allow deletion. Combine it.
1874 if (_PyDict_HasSplitTable(mp)) {
1875 if (dictresize(mp, DK_SIZE(mp->ma_keys))) {
1876 return NULL;
1877 }
INADA Naoki778928b2017-08-03 23:45:15 +09001878 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value);
Victor Stinner78601a32016-09-09 19:28:36 -07001879 assert(ix >= 0);
1880 }
1881
INADA Naoki778928b2017-08-03 23:45:15 +09001882 hashpos = lookdict_index(mp->ma_keys, hash, ix);
1883 assert(hashpos >= 0);
Victor Stinner78601a32016-09-09 19:28:36 -07001884 assert(old_value != NULL);
Eric Snow96c6af92015-05-29 22:21:39 -06001885 mp->ma_used--;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07001886 mp->ma_version_tag = DICT_NEXT_VERSION();
INADA Naokia7576492018-11-14 18:39:27 +09001887 dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
Victor Stinner78601a32016-09-09 19:28:36 -07001888 ep = &DK_ENTRIES(mp->ma_keys)[ix];
1889 ENSURE_ALLOWS_DELETIONS(mp);
1890 old_key = ep->me_key;
1891 ep->me_key = NULL;
INADA Naokiba609772016-12-07 20:41:42 +09001892 ep->me_value = NULL;
Victor Stinner78601a32016-09-09 19:28:36 -07001893 Py_DECREF(old_key);
Victor Stinner611b0fa2016-09-14 15:02:01 +02001894
Victor Stinner0fc91ee2019-04-12 21:51:34 +02001895 ASSERT_CONSISTENT(mp);
Eric Snow96c6af92015-05-29 22:21:39 -06001896 return old_value;
1897}
1898
Serhiy Storchaka67796522017-01-12 18:34:33 +02001899PyObject *
Serhiy Storchaka42e1ea92017-01-12 19:12:21 +02001900_PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt)
Serhiy Storchaka67796522017-01-12 18:34:33 +02001901{
1902 Py_hash_t hash;
1903
Serhiy Storchaka42e1ea92017-01-12 19:12:21 +02001904 if (((PyDictObject *)dict)->ma_used == 0) {
Serhiy Storchaka67796522017-01-12 18:34:33 +02001905 if (deflt) {
1906 Py_INCREF(deflt);
1907 return deflt;
1908 }
1909 _PyErr_SetKeyError(key);
1910 return NULL;
1911 }
1912 if (!PyUnicode_CheckExact(key) ||
1913 (hash = ((PyASCIIObject *) key)->hash) == -1) {
1914 hash = PyObject_Hash(key);
1915 if (hash == -1)
1916 return NULL;
1917 }
Serhiy Storchaka42e1ea92017-01-12 19:12:21 +02001918 return _PyDict_Pop_KnownHash(dict, key, hash, deflt);
Serhiy Storchaka67796522017-01-12 18:34:33 +02001919}
1920
Eric Snow96c6af92015-05-29 22:21:39 -06001921/* Internal version of dict.from_keys(). It is subclass-friendly. */
1922PyObject *
1923_PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value)
1924{
1925 PyObject *it; /* iter(iterable) */
1926 PyObject *key;
1927 PyObject *d;
1928 int status;
1929
Victor Stinnera5ed5f02016-12-06 18:45:50 +01001930 d = _PyObject_CallNoArg(cls);
Eric Snow96c6af92015-05-29 22:21:39 -06001931 if (d == NULL)
1932 return NULL;
1933
1934 if (PyDict_CheckExact(d) && ((PyDictObject *)d)->ma_used == 0) {
1935 if (PyDict_CheckExact(iterable)) {
1936 PyDictObject *mp = (PyDictObject *)d;
1937 PyObject *oldvalue;
1938 Py_ssize_t pos = 0;
1939 PyObject *key;
1940 Py_hash_t hash;
1941
Serhiy Storchakac61ac162017-03-21 08:52:38 +02001942 if (dictresize(mp, ESTIMATE_SIZE(PyDict_GET_SIZE(iterable)))) {
Eric Snow96c6af92015-05-29 22:21:39 -06001943 Py_DECREF(d);
1944 return NULL;
1945 }
1946
1947 while (_PyDict_Next(iterable, &pos, &key, &oldvalue, &hash)) {
1948 if (insertdict(mp, key, hash, value)) {
1949 Py_DECREF(d);
1950 return NULL;
1951 }
1952 }
1953 return d;
1954 }
1955 if (PyAnySet_CheckExact(iterable)) {
1956 PyDictObject *mp = (PyDictObject *)d;
1957 Py_ssize_t pos = 0;
1958 PyObject *key;
1959 Py_hash_t hash;
1960
Victor Stinner742da042016-09-07 17:40:12 -07001961 if (dictresize(mp, ESTIMATE_SIZE(PySet_GET_SIZE(iterable)))) {
Eric Snow96c6af92015-05-29 22:21:39 -06001962 Py_DECREF(d);
1963 return NULL;
1964 }
1965
1966 while (_PySet_NextEntry(iterable, &pos, &key, &hash)) {
1967 if (insertdict(mp, key, hash, value)) {
1968 Py_DECREF(d);
1969 return NULL;
1970 }
1971 }
1972 return d;
1973 }
1974 }
1975
1976 it = PyObject_GetIter(iterable);
1977 if (it == NULL){
1978 Py_DECREF(d);
1979 return NULL;
1980 }
1981
1982 if (PyDict_CheckExact(d)) {
1983 while ((key = PyIter_Next(it)) != NULL) {
1984 status = PyDict_SetItem(d, key, value);
1985 Py_DECREF(key);
1986 if (status < 0)
1987 goto Fail;
1988 }
1989 } else {
1990 while ((key = PyIter_Next(it)) != NULL) {
1991 status = PyObject_SetItem(d, key, value);
1992 Py_DECREF(key);
1993 if (status < 0)
1994 goto Fail;
1995 }
1996 }
1997
1998 if (PyErr_Occurred())
1999 goto Fail;
2000 Py_DECREF(it);
2001 return d;
2002
2003Fail:
2004 Py_DECREF(it);
2005 Py_DECREF(d);
2006 return NULL;
2007}
2008
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002009/* Methods */
2010
2011static void
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002012dict_dealloc(PyDictObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002013{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002014 PyObject **values = mp->ma_values;
2015 PyDictKeysObject *keys = mp->ma_keys;
2016 Py_ssize_t i, n;
INADA Naokia6296d32017-08-24 14:55:17 +09002017
2018 /* bpo-31095: UnTrack is needed before calling any callbacks */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002019 PyObject_GC_UnTrack(mp);
Jeroen Demeyer351c6742019-05-10 19:21:11 +02002020 Py_TRASHCAN_BEGIN(mp, dict_dealloc)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002021 if (values != NULL) {
2022 if (values != empty_values) {
Victor Stinner742da042016-09-07 17:40:12 -07002023 for (i = 0, n = mp->ma_keys->dk_nentries; i < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002024 Py_XDECREF(values[i]);
2025 }
2026 free_values(values);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002027 }
INADA Naokia7576492018-11-14 18:39:27 +09002028 dictkeys_decref(keys);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002029 }
Victor Stinnerac2a4fe2013-07-16 22:19:00 +02002030 else if (keys != NULL) {
Antoine Pitrou2d169b22012-05-12 23:43:44 +02002031 assert(keys->dk_refcnt == 1);
INADA Naokia7576492018-11-14 18:39:27 +09002032 dictkeys_decref(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002033 }
Victor Stinnerb4b53862020-05-05 19:55:29 +02002034#if PyDict_MAXFREELIST > 0
2035 if (numfree < PyDict_MAXFREELIST && Py_IS_TYPE(mp, &PyDict_Type)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002036 free_list[numfree++] = mp;
Victor Stinnerb4b53862020-05-05 19:55:29 +02002037 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002038 else
Victor Stinnerb4b53862020-05-05 19:55:29 +02002039#endif
2040 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002041 Py_TYPE(mp)->tp_free((PyObject *)mp);
Victor Stinnerb4b53862020-05-05 19:55:29 +02002042 }
Jeroen Demeyer351c6742019-05-10 19:21:11 +02002043 Py_TRASHCAN_END
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002044}
2045
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002046
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002047static PyObject *
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002048dict_repr(PyDictObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002049{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002050 Py_ssize_t i;
Victor Stinnerf91929b2013-11-19 13:07:38 +01002051 PyObject *key = NULL, *value = NULL;
2052 _PyUnicodeWriter writer;
2053 int first;
Guido van Rossum255443b1998-04-10 22:47:14 +00002054
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002055 i = Py_ReprEnter((PyObject *)mp);
2056 if (i != 0) {
2057 return i > 0 ? PyUnicode_FromString("{...}") : NULL;
2058 }
Guido van Rossum255443b1998-04-10 22:47:14 +00002059
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002060 if (mp->ma_used == 0) {
Victor Stinnerf91929b2013-11-19 13:07:38 +01002061 Py_ReprLeave((PyObject *)mp);
2062 return PyUnicode_FromString("{}");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002063 }
Tim Petersa7259592001-06-16 05:11:17 +00002064
Victor Stinnerf91929b2013-11-19 13:07:38 +01002065 _PyUnicodeWriter_Init(&writer);
2066 writer.overallocate = 1;
2067 /* "{" + "1: 2" + ", 3: 4" * (len - 1) + "}" */
2068 writer.min_length = 1 + 4 + (2 + 4) * (mp->ma_used - 1) + 1;
Tim Petersa7259592001-06-16 05:11:17 +00002069
Victor Stinnerf91929b2013-11-19 13:07:38 +01002070 if (_PyUnicodeWriter_WriteChar(&writer, '{') < 0)
2071 goto error;
Tim Petersa7259592001-06-16 05:11:17 +00002072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 /* Do repr() on each key+value pair, and insert ": " between them.
2074 Note that repr may mutate the dict. */
2075 i = 0;
Victor Stinnerf91929b2013-11-19 13:07:38 +01002076 first = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002077 while (PyDict_Next((PyObject *)mp, &i, &key, &value)) {
Victor Stinnerf91929b2013-11-19 13:07:38 +01002078 PyObject *s;
2079 int res;
2080
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002081 /* Prevent repr from deleting key or value during key format. */
2082 Py_INCREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002083 Py_INCREF(value);
Victor Stinnerf97dfd72013-07-18 01:00:45 +02002084
Victor Stinnerf91929b2013-11-19 13:07:38 +01002085 if (!first) {
2086 if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0)
2087 goto error;
2088 }
2089 first = 0;
2090
2091 s = PyObject_Repr(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002092 if (s == NULL)
Victor Stinnerf91929b2013-11-19 13:07:38 +01002093 goto error;
2094 res = _PyUnicodeWriter_WriteStr(&writer, s);
2095 Py_DECREF(s);
2096 if (res < 0)
2097 goto error;
2098
2099 if (_PyUnicodeWriter_WriteASCIIString(&writer, ": ", 2) < 0)
2100 goto error;
2101
2102 s = PyObject_Repr(value);
2103 if (s == NULL)
2104 goto error;
2105 res = _PyUnicodeWriter_WriteStr(&writer, s);
2106 Py_DECREF(s);
2107 if (res < 0)
2108 goto error;
2109
2110 Py_CLEAR(key);
2111 Py_CLEAR(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002112 }
Tim Petersa7259592001-06-16 05:11:17 +00002113
Victor Stinnerf91929b2013-11-19 13:07:38 +01002114 writer.overallocate = 0;
2115 if (_PyUnicodeWriter_WriteChar(&writer, '}') < 0)
2116 goto error;
Tim Petersa7259592001-06-16 05:11:17 +00002117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002118 Py_ReprLeave((PyObject *)mp);
Victor Stinnerf91929b2013-11-19 13:07:38 +01002119
2120 return _PyUnicodeWriter_Finish(&writer);
2121
2122error:
2123 Py_ReprLeave((PyObject *)mp);
2124 _PyUnicodeWriter_Dealloc(&writer);
2125 Py_XDECREF(key);
2126 Py_XDECREF(value);
2127 return NULL;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002128}
2129
Martin v. Löwis18e16552006-02-15 17:27:45 +00002130static Py_ssize_t
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002131dict_length(PyDictObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002132{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002133 return mp->ma_used;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002134}
2135
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002136static PyObject *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002137dict_subscript(PyDictObject *mp, PyObject *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002138{
Victor Stinner742da042016-09-07 17:40:12 -07002139 Py_ssize_t ix;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002140 Py_hash_t hash;
INADA Naokiba609772016-12-07 20:41:42 +09002141 PyObject *value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002143 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002144 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002145 hash = PyObject_Hash(key);
2146 if (hash == -1)
2147 return NULL;
2148 }
INADA Naoki778928b2017-08-03 23:45:15 +09002149 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07002150 if (ix == DKIX_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002151 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09002152 if (ix == DKIX_EMPTY || value == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002153 if (!PyDict_CheckExact(mp)) {
2154 /* Look up __missing__ method if we're a subclass. */
2155 PyObject *missing, *res;
Benjamin Petersonce798522012-01-22 11:24:29 -05002156 _Py_IDENTIFIER(__missing__);
2157 missing = _PyObject_LookupSpecial((PyObject *)mp, &PyId___missing__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002158 if (missing != NULL) {
Petr Viktorinffd97532020-02-11 17:46:57 +01002159 res = PyObject_CallOneArg(missing, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 Py_DECREF(missing);
2161 return res;
2162 }
2163 else if (PyErr_Occurred())
2164 return NULL;
2165 }
Raymond Hettinger69492da2013-09-02 15:59:26 -07002166 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002167 return NULL;
2168 }
INADA Naokiba609772016-12-07 20:41:42 +09002169 Py_INCREF(value);
2170 return value;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002171}
2172
2173static int
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002174dict_ass_sub(PyDictObject *mp, PyObject *v, PyObject *w)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 if (w == NULL)
2177 return PyDict_DelItem((PyObject *)mp, v);
2178 else
2179 return PyDict_SetItem((PyObject *)mp, v, w);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002180}
2181
Guido van Rossuma9e7a811997-05-13 21:02:11 +00002182static PyMappingMethods dict_as_mapping = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002183 (lenfunc)dict_length, /*mp_length*/
2184 (binaryfunc)dict_subscript, /*mp_subscript*/
2185 (objobjargproc)dict_ass_sub, /*mp_ass_subscript*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002186};
2187
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002188static PyObject *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002189dict_keys(PyDictObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002190{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002191 PyObject *v;
2192 Py_ssize_t i, j;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002193 PyDictKeyEntry *ep;
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002194 Py_ssize_t n, offset;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002195 PyObject **value_ptr;
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002196
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002197 again:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002198 n = mp->ma_used;
2199 v = PyList_New(n);
2200 if (v == NULL)
2201 return NULL;
2202 if (n != mp->ma_used) {
2203 /* Durnit. The allocations caused the dict to resize.
2204 * Just start over, this shouldn't normally happen.
2205 */
2206 Py_DECREF(v);
2207 goto again;
2208 }
Victor Stinner742da042016-09-07 17:40:12 -07002209 ep = DK_ENTRIES(mp->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002210 if (mp->ma_values) {
2211 value_ptr = mp->ma_values;
2212 offset = sizeof(PyObject *);
2213 }
2214 else {
2215 value_ptr = &ep[0].me_value;
2216 offset = sizeof(PyDictKeyEntry);
2217 }
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002218 for (i = 0, j = 0; j < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002219 if (*value_ptr != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002220 PyObject *key = ep[i].me_key;
2221 Py_INCREF(key);
2222 PyList_SET_ITEM(v, j, key);
2223 j++;
2224 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002225 value_ptr = (PyObject **)(((char *)value_ptr) + offset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002226 }
2227 assert(j == n);
2228 return v;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002229}
2230
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002231static PyObject *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002232dict_values(PyDictObject *mp)
Guido van Rossum25831651993-05-19 14:50:45 +00002233{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002234 PyObject *v;
2235 Py_ssize_t i, j;
Benjamin Petersonf0acae22016-09-08 09:50:08 -07002236 PyDictKeyEntry *ep;
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002237 Py_ssize_t n, offset;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002238 PyObject **value_ptr;
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002239
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002240 again:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 n = mp->ma_used;
2242 v = PyList_New(n);
2243 if (v == NULL)
2244 return NULL;
2245 if (n != mp->ma_used) {
2246 /* Durnit. The allocations caused the dict to resize.
2247 * Just start over, this shouldn't normally happen.
2248 */
2249 Py_DECREF(v);
2250 goto again;
2251 }
Benjamin Petersonf0acae22016-09-08 09:50:08 -07002252 ep = DK_ENTRIES(mp->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002253 if (mp->ma_values) {
2254 value_ptr = mp->ma_values;
2255 offset = sizeof(PyObject *);
2256 }
2257 else {
Benjamin Petersonf0acae22016-09-08 09:50:08 -07002258 value_ptr = &ep[0].me_value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002259 offset = sizeof(PyDictKeyEntry);
2260 }
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002261 for (i = 0, j = 0; j < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002262 PyObject *value = *value_ptr;
2263 value_ptr = (PyObject **)(((char *)value_ptr) + offset);
2264 if (value != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002265 Py_INCREF(value);
2266 PyList_SET_ITEM(v, j, value);
2267 j++;
2268 }
2269 }
2270 assert(j == n);
2271 return v;
Guido van Rossum25831651993-05-19 14:50:45 +00002272}
2273
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002274static PyObject *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002275dict_items(PyDictObject *mp)
Guido van Rossum25831651993-05-19 14:50:45 +00002276{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002277 PyObject *v;
2278 Py_ssize_t i, j, n;
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002279 Py_ssize_t offset;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002280 PyObject *item, *key;
2281 PyDictKeyEntry *ep;
2282 PyObject **value_ptr;
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002284 /* Preallocate the list of tuples, to avoid allocations during
2285 * the loop over the items, which could trigger GC, which
2286 * could resize the dict. :-(
2287 */
Guido van Rossuma4dd0112001-04-15 22:16:26 +00002288 again:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002289 n = mp->ma_used;
2290 v = PyList_New(n);
2291 if (v == NULL)
2292 return NULL;
2293 for (i = 0; i < n; i++) {
2294 item = PyTuple_New(2);
2295 if (item == NULL) {
2296 Py_DECREF(v);
2297 return NULL;
2298 }
2299 PyList_SET_ITEM(v, i, item);
2300 }
2301 if (n != mp->ma_used) {
2302 /* Durnit. The allocations caused the dict to resize.
2303 * Just start over, this shouldn't normally happen.
2304 */
2305 Py_DECREF(v);
2306 goto again;
2307 }
2308 /* Nothing we do below makes any function calls. */
Victor Stinner742da042016-09-07 17:40:12 -07002309 ep = DK_ENTRIES(mp->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002310 if (mp->ma_values) {
2311 value_ptr = mp->ma_values;
2312 offset = sizeof(PyObject *);
2313 }
2314 else {
2315 value_ptr = &ep[0].me_value;
2316 offset = sizeof(PyDictKeyEntry);
2317 }
Cheryl Sabellaf66e3362019-04-05 06:08:43 -04002318 for (i = 0, j = 0; j < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002319 PyObject *value = *value_ptr;
2320 value_ptr = (PyObject **)(((char *)value_ptr) + offset);
2321 if (value != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002322 key = ep[i].me_key;
2323 item = PyList_GET_ITEM(v, j);
2324 Py_INCREF(key);
2325 PyTuple_SET_ITEM(item, 0, key);
2326 Py_INCREF(value);
2327 PyTuple_SET_ITEM(item, 1, value);
2328 j++;
2329 }
2330 }
2331 assert(j == n);
2332 return v;
Guido van Rossum25831651993-05-19 14:50:45 +00002333}
2334
Larry Hastings5c661892014-01-24 06:17:25 -08002335/*[clinic input]
2336@classmethod
2337dict.fromkeys
Larry Hastings5c661892014-01-24 06:17:25 -08002338 iterable: object
2339 value: object=None
2340 /
2341
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002342Create a new dictionary with keys from iterable and values set to value.
Larry Hastings5c661892014-01-24 06:17:25 -08002343[clinic start generated code]*/
2344
Larry Hastings5c661892014-01-24 06:17:25 -08002345static PyObject *
2346dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002347/*[clinic end generated code: output=8fb98e4b10384999 input=382ba4855d0f74c3]*/
Larry Hastings5c661892014-01-24 06:17:25 -08002348{
Eric Snow96c6af92015-05-29 22:21:39 -06002349 return _PyDict_FromKeys((PyObject *)type, iterable, value);
Raymond Hettingere33d3df2002-11-27 07:29:33 +00002350}
2351
Brandt Buchereb8ac572020-02-24 19:47:34 -08002352/* Single-arg dict update; used by dict_update_common and operators. */
2353static int
2354dict_update_arg(PyObject *self, PyObject *arg)
2355{
2356 if (PyDict_CheckExact(arg)) {
2357 return PyDict_Merge(self, arg, 1);
2358 }
2359 _Py_IDENTIFIER(keys);
2360 PyObject *func;
2361 if (_PyObject_LookupAttrId(arg, &PyId_keys, &func) < 0) {
2362 return -1;
2363 }
2364 if (func != NULL) {
2365 Py_DECREF(func);
2366 return PyDict_Merge(self, arg, 1);
2367 }
2368 return PyDict_MergeFromSeq2(self, arg, 1);
2369}
2370
Raymond Hettinger31017ae2004-03-04 08:25:44 +00002371static int
Victor Stinner742da042016-09-07 17:40:12 -07002372dict_update_common(PyObject *self, PyObject *args, PyObject *kwds,
2373 const char *methname)
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375 PyObject *arg = NULL;
2376 int result = 0;
Raymond Hettinger31017ae2004-03-04 08:25:44 +00002377
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002378 if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002379 result = -1;
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002380 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 else if (arg != NULL) {
Brandt Buchereb8ac572020-02-24 19:47:34 -08002382 result = dict_update_arg(self, arg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002383 }
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002385 if (result == 0 && kwds != NULL) {
2386 if (PyArg_ValidateKeywordArguments(kwds))
2387 result = PyDict_Merge(self, kwds, 1);
2388 else
2389 result = -1;
2390 }
2391 return result;
Raymond Hettinger31017ae2004-03-04 08:25:44 +00002392}
2393
Victor Stinner91f0d4a2017-01-19 12:45:06 +01002394/* Note: dict.update() uses the METH_VARARGS|METH_KEYWORDS calling convention.
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002395 Using METH_FASTCALL|METH_KEYWORDS would make dict.update(**dict2) calls
2396 slower, see the issue #29312. */
Raymond Hettinger31017ae2004-03-04 08:25:44 +00002397static PyObject *
2398dict_update(PyObject *self, PyObject *args, PyObject *kwds)
2399{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002400 if (dict_update_common(self, args, kwds, "update") != -1)
2401 Py_RETURN_NONE;
2402 return NULL;
Tim Peters6d6c1a32001-08-02 04:15:00 +00002403}
2404
Guido van Rossum05ac6de2001-08-10 20:28:28 +00002405/* Update unconditionally replaces existing items.
2406 Merge has a 3rd argument 'override'; if set, it acts like Update,
Tim Peters1fc240e2001-10-26 05:06:50 +00002407 otherwise it leaves existing items unchanged.
2408
2409 PyDict_{Update,Merge} update/merge from a mapping object.
2410
Tim Petersf582b822001-12-11 18:51:08 +00002411 PyDict_MergeFromSeq2 updates/merges from any iterable object
Tim Peters1fc240e2001-10-26 05:06:50 +00002412 producing iterable objects of length 2.
2413*/
2414
Tim Petersf582b822001-12-11 18:51:08 +00002415int
Tim Peters1fc240e2001-10-26 05:06:50 +00002416PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)
2417{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418 PyObject *it; /* iter(seq2) */
2419 Py_ssize_t i; /* index into seq2 of current element */
2420 PyObject *item; /* seq2[i] */
2421 PyObject *fast; /* item as a 2-tuple or 2-list */
Tim Peters1fc240e2001-10-26 05:06:50 +00002422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002423 assert(d != NULL);
2424 assert(PyDict_Check(d));
2425 assert(seq2 != NULL);
Tim Peters1fc240e2001-10-26 05:06:50 +00002426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002427 it = PyObject_GetIter(seq2);
2428 if (it == NULL)
2429 return -1;
Tim Peters1fc240e2001-10-26 05:06:50 +00002430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002431 for (i = 0; ; ++i) {
2432 PyObject *key, *value;
2433 Py_ssize_t n;
Tim Peters1fc240e2001-10-26 05:06:50 +00002434
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002435 fast = NULL;
2436 item = PyIter_Next(it);
2437 if (item == NULL) {
2438 if (PyErr_Occurred())
2439 goto Fail;
2440 break;
2441 }
Tim Peters1fc240e2001-10-26 05:06:50 +00002442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002443 /* Convert item to sequence, and verify length 2. */
2444 fast = PySequence_Fast(item, "");
2445 if (fast == NULL) {
2446 if (PyErr_ExceptionMatches(PyExc_TypeError))
2447 PyErr_Format(PyExc_TypeError,
2448 "cannot convert dictionary update "
2449 "sequence element #%zd to a sequence",
2450 i);
2451 goto Fail;
2452 }
2453 n = PySequence_Fast_GET_SIZE(fast);
2454 if (n != 2) {
2455 PyErr_Format(PyExc_ValueError,
2456 "dictionary update sequence element #%zd "
2457 "has length %zd; 2 is required",
2458 i, n);
2459 goto Fail;
2460 }
Tim Peters1fc240e2001-10-26 05:06:50 +00002461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002462 /* Update/merge with this (key, value) pair. */
2463 key = PySequence_Fast_GET_ITEM(fast, 0);
2464 value = PySequence_Fast_GET_ITEM(fast, 1);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002465 Py_INCREF(key);
2466 Py_INCREF(value);
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002467 if (override) {
2468 if (PyDict_SetItem(d, key, value) < 0) {
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002469 Py_DECREF(key);
2470 Py_DECREF(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002471 goto Fail;
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002472 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002473 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002474 else if (PyDict_GetItemWithError(d, key) == NULL) {
2475 if (PyErr_Occurred() || PyDict_SetItem(d, key, value) < 0) {
2476 Py_DECREF(key);
2477 Py_DECREF(value);
2478 goto Fail;
2479 }
2480 }
2481
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002482 Py_DECREF(key);
2483 Py_DECREF(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002484 Py_DECREF(fast);
2485 Py_DECREF(item);
2486 }
Tim Peters1fc240e2001-10-26 05:06:50 +00002487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002488 i = 0;
Victor Stinner0fc91ee2019-04-12 21:51:34 +02002489 ASSERT_CONSISTENT(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002490 goto Return;
Tim Peters1fc240e2001-10-26 05:06:50 +00002491Fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002492 Py_XDECREF(item);
2493 Py_XDECREF(fast);
2494 i = -1;
Tim Peters1fc240e2001-10-26 05:06:50 +00002495Return:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002496 Py_DECREF(it);
2497 return Py_SAFE_DOWNCAST(i, Py_ssize_t, int);
Tim Peters1fc240e2001-10-26 05:06:50 +00002498}
2499
doko@ubuntu.comc96df682016-10-11 08:04:02 +02002500static int
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002501dict_merge(PyObject *a, PyObject *b, int override)
Guido van Rossum05ac6de2001-08-10 20:28:28 +00002502{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02002503 PyDictObject *mp, *other;
2504 Py_ssize_t i, n;
Victor Stinner742da042016-09-07 17:40:12 -07002505 PyDictKeyEntry *entry, *ep0;
Tim Peters6d6c1a32001-08-02 04:15:00 +00002506
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002507 assert(0 <= override && override <= 2);
2508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002509 /* We accept for the argument either a concrete dictionary object,
2510 * or an abstract "mapping" object. For the former, we can do
2511 * things quite efficiently. For the latter, we only require that
2512 * PyMapping_Keys() and PyObject_GetItem() be supported.
2513 */
2514 if (a == NULL || !PyDict_Check(a) || b == NULL) {
2515 PyErr_BadInternalCall();
2516 return -1;
2517 }
2518 mp = (PyDictObject*)a;
INADA Naoki2aaf98c2018-09-26 12:59:00 +09002519 if (PyDict_Check(b) && (Py_TYPE(b)->tp_iter == (getiterfunc)dict_iter)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002520 other = (PyDictObject*)b;
2521 if (other == mp || other->ma_used == 0)
2522 /* a.update(a) or a.update({}); nothing to do */
2523 return 0;
2524 if (mp->ma_used == 0)
2525 /* Since the target dict is empty, PyDict_GetItem()
2526 * always returns NULL. Setting override to 1
2527 * skips the unnecessary test.
2528 */
2529 override = 1;
2530 /* Do one big resize at the start, rather than
2531 * incrementally resizing as we insert new items. Expect
2532 * that there will be no (or few) overlapping keys.
2533 */
INADA Naokib1152be2016-10-27 19:26:50 +09002534 if (USABLE_FRACTION(mp->ma_keys->dk_size) < other->ma_used) {
2535 if (dictresize(mp, ESTIMATE_SIZE(mp->ma_used + other->ma_used))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002536 return -1;
INADA Naokib1152be2016-10-27 19:26:50 +09002537 }
2538 }
Victor Stinner742da042016-09-07 17:40:12 -07002539 ep0 = DK_ENTRIES(other->ma_keys);
2540 for (i = 0, n = other->ma_keys->dk_nentries; i < n; i++) {
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002541 PyObject *key, *value;
2542 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07002543 entry = &ep0[i];
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002544 key = entry->me_key;
2545 hash = entry->me_hash;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002546 if (other->ma_values)
2547 value = other->ma_values[i];
2548 else
2549 value = entry->me_value;
2550
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002551 if (value != NULL) {
2552 int err = 0;
2553 Py_INCREF(key);
2554 Py_INCREF(value);
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02002555 if (override == 1)
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002556 err = insertdict(mp, key, hash, value);
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02002557 else if (_PyDict_GetItem_KnownHash(a, key, hash) == NULL) {
2558 if (PyErr_Occurred()) {
2559 Py_DECREF(value);
2560 Py_DECREF(key);
2561 return -1;
2562 }
2563 err = insertdict(mp, key, hash, value);
2564 }
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002565 else if (override != 0) {
2566 _PyErr_SetKeyError(key);
2567 Py_DECREF(value);
2568 Py_DECREF(key);
2569 return -1;
2570 }
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002571 Py_DECREF(value);
2572 Py_DECREF(key);
2573 if (err != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002574 return -1;
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002575
Victor Stinner742da042016-09-07 17:40:12 -07002576 if (n != other->ma_keys->dk_nentries) {
Benjamin Petersona82f77f2015-07-04 19:55:16 -05002577 PyErr_SetString(PyExc_RuntimeError,
2578 "dict mutated during update");
2579 return -1;
2580 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002581 }
2582 }
2583 }
2584 else {
2585 /* Do it the generic, slower way */
2586 PyObject *keys = PyMapping_Keys(b);
2587 PyObject *iter;
2588 PyObject *key, *value;
2589 int status;
Barry Warsaw66a0d1d2001-06-26 20:08:32 +00002590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002591 if (keys == NULL)
2592 /* Docstring says this is equivalent to E.keys() so
2593 * if E doesn't have a .keys() method we want
2594 * AttributeError to percolate up. Might as well
2595 * do the same for any other error.
2596 */
2597 return -1;
Barry Warsaw66a0d1d2001-06-26 20:08:32 +00002598
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002599 iter = PyObject_GetIter(keys);
2600 Py_DECREF(keys);
2601 if (iter == NULL)
2602 return -1;
Barry Warsaw66a0d1d2001-06-26 20:08:32 +00002603
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002604 for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002605 if (override != 1) {
2606 if (PyDict_GetItemWithError(a, key) != NULL) {
2607 if (override != 0) {
2608 _PyErr_SetKeyError(key);
2609 Py_DECREF(key);
2610 Py_DECREF(iter);
2611 return -1;
2612 }
2613 Py_DECREF(key);
2614 continue;
2615 }
2616 else if (PyErr_Occurred()) {
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002617 Py_DECREF(key);
2618 Py_DECREF(iter);
2619 return -1;
2620 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002621 }
2622 value = PyObject_GetItem(b, key);
2623 if (value == NULL) {
2624 Py_DECREF(iter);
2625 Py_DECREF(key);
2626 return -1;
2627 }
2628 status = PyDict_SetItem(a, key, value);
2629 Py_DECREF(key);
2630 Py_DECREF(value);
2631 if (status < 0) {
2632 Py_DECREF(iter);
2633 return -1;
2634 }
2635 }
2636 Py_DECREF(iter);
2637 if (PyErr_Occurred())
2638 /* Iterator completed, via error */
2639 return -1;
2640 }
Victor Stinner0fc91ee2019-04-12 21:51:34 +02002641 ASSERT_CONSISTENT(a);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002642 return 0;
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002643}
2644
Serhiy Storchakae036ef82016-10-02 11:06:43 +03002645int
2646PyDict_Update(PyObject *a, PyObject *b)
2647{
2648 return dict_merge(a, b, 1);
2649}
2650
2651int
2652PyDict_Merge(PyObject *a, PyObject *b, int override)
2653{
2654 /* XXX Deprecate override not in (0, 1). */
2655 return dict_merge(a, b, override != 0);
2656}
2657
2658int
2659_PyDict_MergeEx(PyObject *a, PyObject *b, int override)
2660{
2661 return dict_merge(a, b, override);
2662}
2663
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002664static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302665dict_copy(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002666{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002667 return PyDict_Copy((PyObject*)mp);
Jeremy Hyltona12c7a72000-03-30 22:27:31 +00002668}
2669
2670PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00002671PyDict_Copy(PyObject *o)
Jeremy Hyltona12c7a72000-03-30 22:27:31 +00002672{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002673 PyObject *copy;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002674 PyDictObject *mp;
2675 Py_ssize_t i, n;
Jeremy Hyltona12c7a72000-03-30 22:27:31 +00002676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002677 if (o == NULL || !PyDict_Check(o)) {
2678 PyErr_BadInternalCall();
2679 return NULL;
2680 }
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002681
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002682 mp = (PyDictObject *)o;
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002683 if (mp->ma_used == 0) {
2684 /* The dict is empty; just return a new dict. */
2685 return PyDict_New();
2686 }
2687
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002688 if (_PyDict_HasSplitTable(mp)) {
2689 PyDictObject *split_copy;
Victor Stinner742da042016-09-07 17:40:12 -07002690 Py_ssize_t size = USABLE_FRACTION(DK_SIZE(mp->ma_keys));
2691 PyObject **newvalues;
2692 newvalues = new_values(size);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002693 if (newvalues == NULL)
2694 return PyErr_NoMemory();
2695 split_copy = PyObject_GC_New(PyDictObject, &PyDict_Type);
2696 if (split_copy == NULL) {
2697 free_values(newvalues);
2698 return NULL;
2699 }
2700 split_copy->ma_values = newvalues;
2701 split_copy->ma_keys = mp->ma_keys;
2702 split_copy->ma_used = mp->ma_used;
INADA Naokid1c82c52018-04-03 11:43:53 +09002703 split_copy->ma_version_tag = DICT_NEXT_VERSION();
INADA Naokia7576492018-11-14 18:39:27 +09002704 dictkeys_incref(mp->ma_keys);
Victor Stinner742da042016-09-07 17:40:12 -07002705 for (i = 0, n = size; i < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002706 PyObject *value = mp->ma_values[i];
2707 Py_XINCREF(value);
2708 split_copy->ma_values[i] = value;
2709 }
Benjamin Peterson7ce67e42012-04-24 10:32:57 -04002710 if (_PyObject_GC_IS_TRACKED(mp))
2711 _PyObject_GC_TRACK(split_copy);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002712 return (PyObject *)split_copy;
2713 }
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002714
2715 if (PyDict_CheckExact(mp) && mp->ma_values == NULL &&
2716 (mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3))
2717 {
2718 /* Use fast-copy if:
2719
2720 (1) 'mp' is an instance of a subclassed dict; and
2721
2722 (2) 'mp' is not a split-dict; and
2723
2724 (3) if 'mp' is non-compact ('del' operation does not resize dicts),
2725 do fast-copy only if it has at most 1/3 non-used keys.
2726
Ville Skyttä61f82e02018-04-20 23:08:45 +03002727 The last condition (3) is important to guard against a pathological
Yury Selivanovb0a7a032018-01-22 11:54:41 -05002728 case when a large dict is almost emptied with multiple del/pop
2729 operations and copied after that. In cases like this, we defer to
2730 PyDict_Merge, which produces a compacted copy.
2731 */
2732 return clone_combined_dict(mp);
2733 }
2734
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002735 copy = PyDict_New();
2736 if (copy == NULL)
2737 return NULL;
2738 if (PyDict_Merge(copy, o, 1) == 0)
2739 return copy;
2740 Py_DECREF(copy);
2741 return NULL;
Guido van Rossume3f5b9c1997-05-28 19:15:28 +00002742}
2743
Martin v. Löwis18e16552006-02-15 17:27:45 +00002744Py_ssize_t
Tim Peters1f5871e2000-07-04 17:44:48 +00002745PyDict_Size(PyObject *mp)
Guido van Rossum4199fac1993-11-05 10:18:44 +00002746{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002747 if (mp == NULL || !PyDict_Check(mp)) {
2748 PyErr_BadInternalCall();
2749 return -1;
2750 }
2751 return ((PyDictObject *)mp)->ma_used;
Guido van Rossum4199fac1993-11-05 10:18:44 +00002752}
2753
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002754PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00002755PyDict_Keys(PyObject *mp)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002756{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002757 if (mp == NULL || !PyDict_Check(mp)) {
2758 PyErr_BadInternalCall();
2759 return NULL;
2760 }
2761 return dict_keys((PyDictObject *)mp);
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002762}
2763
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002764PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00002765PyDict_Values(PyObject *mp)
Guido van Rossum25831651993-05-19 14:50:45 +00002766{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002767 if (mp == NULL || !PyDict_Check(mp)) {
2768 PyErr_BadInternalCall();
2769 return NULL;
2770 }
2771 return dict_values((PyDictObject *)mp);
Guido van Rossum25831651993-05-19 14:50:45 +00002772}
2773
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002774PyObject *
Tim Peters1f5871e2000-07-04 17:44:48 +00002775PyDict_Items(PyObject *mp)
Guido van Rossum25831651993-05-19 14:50:45 +00002776{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002777 if (mp == NULL || !PyDict_Check(mp)) {
2778 PyErr_BadInternalCall();
2779 return NULL;
2780 }
2781 return dict_items((PyDictObject *)mp);
Guido van Rossum25831651993-05-19 14:50:45 +00002782}
2783
Tim Peterse63415e2001-05-08 04:38:29 +00002784/* Return 1 if dicts equal, 0 if not, -1 if error.
2785 * Gets out as soon as any difference is detected.
2786 * Uses only Py_EQ comparison.
2787 */
2788static int
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002789dict_equal(PyDictObject *a, PyDictObject *b)
Tim Peterse63415e2001-05-08 04:38:29 +00002790{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002791 Py_ssize_t i;
Tim Peterse63415e2001-05-08 04:38:29 +00002792
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002793 if (a->ma_used != b->ma_used)
2794 /* can't be equal if # of entries differ */
2795 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002796 /* Same # of entries -- check all of 'em. Exit early on any diff. */
Victor Stinner742da042016-09-07 17:40:12 -07002797 for (i = 0; i < a->ma_keys->dk_nentries; i++) {
2798 PyDictKeyEntry *ep = &DK_ENTRIES(a->ma_keys)[i];
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002799 PyObject *aval;
2800 if (a->ma_values)
2801 aval = a->ma_values[i];
2802 else
2803 aval = ep->me_value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002804 if (aval != NULL) {
2805 int cmp;
2806 PyObject *bval;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002807 PyObject *key = ep->me_key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002808 /* temporarily bump aval's refcount to ensure it stays
2809 alive until we're done with it */
2810 Py_INCREF(aval);
2811 /* ditto for key */
2812 Py_INCREF(key);
Antoine Pitrou0e9958b2012-12-02 19:10:07 +01002813 /* reuse the known hash value */
INADA Naoki778928b2017-08-03 23:45:15 +09002814 b->ma_keys->dk_lookup(b, key, ep->me_hash, &bval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002815 if (bval == NULL) {
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002816 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002817 Py_DECREF(aval);
2818 if (PyErr_Occurred())
2819 return -1;
2820 return 0;
2821 }
Dong-hee Na2d5bf562019-12-31 10:04:22 +09002822 Py_INCREF(bval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002823 cmp = PyObject_RichCompareBool(aval, bval, Py_EQ);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03002824 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002825 Py_DECREF(aval);
Dong-hee Na2d5bf562019-12-31 10:04:22 +09002826 Py_DECREF(bval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002827 if (cmp <= 0) /* error or not equal */
2828 return cmp;
2829 }
2830 }
2831 return 1;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002832}
Tim Peterse63415e2001-05-08 04:38:29 +00002833
2834static PyObject *
2835dict_richcompare(PyObject *v, PyObject *w, int op)
2836{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002837 int cmp;
2838 PyObject *res;
Tim Peterse63415e2001-05-08 04:38:29 +00002839
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002840 if (!PyDict_Check(v) || !PyDict_Check(w)) {
2841 res = Py_NotImplemented;
2842 }
2843 else if (op == Py_EQ || op == Py_NE) {
2844 cmp = dict_equal((PyDictObject *)v, (PyDictObject *)w);
2845 if (cmp < 0)
2846 return NULL;
2847 res = (cmp == (op == Py_EQ)) ? Py_True : Py_False;
2848 }
2849 else
2850 res = Py_NotImplemented;
2851 Py_INCREF(res);
2852 return res;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002853}
Tim Peterse63415e2001-05-08 04:38:29 +00002854
Larry Hastings61272b72014-01-07 12:41:53 -08002855/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002856
2857@coexist
2858dict.__contains__
2859
2860 key: object
2861 /
2862
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002863True if the dictionary has the specified key, else False.
Larry Hastings61272b72014-01-07 12:41:53 -08002864[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002865
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002866static PyObject *
Larry Hastingsc2047262014-01-25 20:43:29 -08002867dict___contains__(PyDictObject *self, PyObject *key)
Serhiy Storchaka19d25972017-02-04 08:05:07 +02002868/*[clinic end generated code: output=a3d03db709ed6e6b input=fe1cb42ad831e820]*/
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002869{
Larry Hastingsc2047262014-01-25 20:43:29 -08002870 register PyDictObject *mp = self;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002871 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07002872 Py_ssize_t ix;
INADA Naokiba609772016-12-07 20:41:42 +09002873 PyObject *value;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002875 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002876 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002877 hash = PyObject_Hash(key);
2878 if (hash == -1)
2879 return NULL;
2880 }
INADA Naoki778928b2017-08-03 23:45:15 +09002881 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07002882 if (ix == DKIX_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002883 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09002884 if (ix == DKIX_EMPTY || value == NULL)
Victor Stinner742da042016-09-07 17:40:12 -07002885 Py_RETURN_FALSE;
2886 Py_RETURN_TRUE;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00002887}
2888
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01002889/*[clinic input]
2890dict.get
2891
2892 key: object
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02002893 default: object = None
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01002894 /
2895
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002896Return the value for key if key is in the dictionary, else default.
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01002897[clinic start generated code]*/
2898
Guido van Rossumc0b618a1997-05-02 03:12:38 +00002899static PyObject *
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02002900dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02002901/*[clinic end generated code: output=bba707729dee05bf input=279ddb5790b6b107]*/
Barry Warsawc38c5da1997-10-06 17:49:20 +00002902{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002903 PyObject *val = NULL;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002904 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07002905 Py_ssize_t ix;
Barry Warsawc38c5da1997-10-06 17:49:20 +00002906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002907 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002908 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002909 hash = PyObject_Hash(key);
2910 if (hash == -1)
2911 return NULL;
2912 }
INADA Naoki778928b2017-08-03 23:45:15 +09002913 ix = (self->ma_keys->dk_lookup) (self, key, hash, &val);
Victor Stinner742da042016-09-07 17:40:12 -07002914 if (ix == DKIX_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002915 return NULL;
INADA Naokiba609772016-12-07 20:41:42 +09002916 if (ix == DKIX_EMPTY || val == NULL) {
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02002917 val = default_value;
INADA Naokiba609772016-12-07 20:41:42 +09002918 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002919 Py_INCREF(val);
2920 return val;
Barry Warsawc38c5da1997-10-06 17:49:20 +00002921}
2922
Benjamin Peterson00e98862013-03-07 22:16:29 -05002923PyObject *
2924PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj)
Guido van Rossum164452c2000-08-08 16:12:54 +00002925{
Benjamin Peterson00e98862013-03-07 22:16:29 -05002926 PyDictObject *mp = (PyDictObject *)d;
INADA Naoki93f26f72016-11-02 18:45:16 +09002927 PyObject *value;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002928 Py_hash_t hash;
Guido van Rossum164452c2000-08-08 16:12:54 +00002929
Benjamin Peterson00e98862013-03-07 22:16:29 -05002930 if (!PyDict_Check(d)) {
2931 PyErr_BadInternalCall();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002932 return NULL;
Benjamin Peterson00e98862013-03-07 22:16:29 -05002933 }
INADA Naoki93f26f72016-11-02 18:45:16 +09002934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002935 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002936 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002937 hash = PyObject_Hash(key);
2938 if (hash == -1)
2939 return NULL;
2940 }
Inada Naoki2ddc7f62019-03-18 20:38:33 +09002941 if (mp->ma_keys == Py_EMPTY_KEYS) {
2942 if (insert_to_emptydict(mp, key, hash, defaultobj) < 0) {
2943 return NULL;
2944 }
2945 return defaultobj;
2946 }
INADA Naoki93f26f72016-11-02 18:45:16 +09002947
2948 if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) {
2949 if (insertion_resize(mp) < 0)
2950 return NULL;
2951 }
2952
INADA Naoki778928b2017-08-03 23:45:15 +09002953 Py_ssize_t ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07002954 if (ix == DKIX_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002955 return NULL;
INADA Naoki93f26f72016-11-02 18:45:16 +09002956
2957 if (_PyDict_HasSplitTable(mp) &&
INADA Naokiba609772016-12-07 20:41:42 +09002958 ((ix >= 0 && value == NULL && mp->ma_used != ix) ||
INADA Naoki93f26f72016-11-02 18:45:16 +09002959 (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) {
2960 if (insertion_resize(mp) < 0) {
2961 return NULL;
2962 }
INADA Naoki93f26f72016-11-02 18:45:16 +09002963 ix = DKIX_EMPTY;
2964 }
2965
2966 if (ix == DKIX_EMPTY) {
2967 PyDictKeyEntry *ep, *ep0;
2968 value = defaultobj;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002969 if (mp->ma_keys->dk_usable <= 0) {
Victor Stinner3c336c52016-09-12 14:17:40 +02002970 if (insertion_resize(mp) < 0) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002971 return NULL;
Victor Stinner3c336c52016-09-12 14:17:40 +02002972 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002973 }
INADA Naoki778928b2017-08-03 23:45:15 +09002974 Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash);
INADA Naoki93f26f72016-11-02 18:45:16 +09002975 ep0 = DK_ENTRIES(mp->ma_keys);
2976 ep = &ep0[mp->ma_keys->dk_nentries];
INADA Naokia7576492018-11-14 18:39:27 +09002977 dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries);
Benjamin Petersonb1efa532013-03-04 09:47:50 -05002978 Py_INCREF(key);
INADA Naoki93f26f72016-11-02 18:45:16 +09002979 Py_INCREF(value);
2980 MAINTAIN_TRACKING(mp, key, value);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002981 ep->me_key = key;
2982 ep->me_hash = hash;
INADA Naokiba609772016-12-07 20:41:42 +09002983 if (_PyDict_HasSplitTable(mp)) {
INADA Naoki93f26f72016-11-02 18:45:16 +09002984 assert(mp->ma_values[mp->ma_keys->dk_nentries] == NULL);
2985 mp->ma_values[mp->ma_keys->dk_nentries] = value;
Victor Stinner742da042016-09-07 17:40:12 -07002986 }
2987 else {
INADA Naoki93f26f72016-11-02 18:45:16 +09002988 ep->me_value = value;
Victor Stinner742da042016-09-07 17:40:12 -07002989 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04002990 mp->ma_used++;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07002991 mp->ma_version_tag = DICT_NEXT_VERSION();
INADA Naoki93f26f72016-11-02 18:45:16 +09002992 mp->ma_keys->dk_usable--;
2993 mp->ma_keys->dk_nentries++;
2994 assert(mp->ma_keys->dk_usable >= 0);
2995 }
INADA Naokiba609772016-12-07 20:41:42 +09002996 else if (value == NULL) {
INADA Naoki93f26f72016-11-02 18:45:16 +09002997 value = defaultobj;
2998 assert(_PyDict_HasSplitTable(mp));
2999 assert(ix == mp->ma_used);
3000 Py_INCREF(value);
3001 MAINTAIN_TRACKING(mp, key, value);
INADA Naokiba609772016-12-07 20:41:42 +09003002 mp->ma_values[ix] = value;
INADA Naoki93f26f72016-11-02 18:45:16 +09003003 mp->ma_used++;
3004 mp->ma_version_tag = DICT_NEXT_VERSION();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003005 }
INADA Naoki93f26f72016-11-02 18:45:16 +09003006
Victor Stinner0fc91ee2019-04-12 21:51:34 +02003007 ASSERT_CONSISTENT(mp);
INADA Naoki93f26f72016-11-02 18:45:16 +09003008 return value;
Guido van Rossum164452c2000-08-08 16:12:54 +00003009}
3010
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003011/*[clinic input]
3012dict.setdefault
3013
3014 key: object
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02003015 default: object = None
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003016 /
3017
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02003018Insert key with a value of default if key is not in the dictionary.
3019
3020Return the value for key if key is in the dictionary, else default.
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003021[clinic start generated code]*/
3022
Benjamin Peterson00e98862013-03-07 22:16:29 -05003023static PyObject *
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02003024dict_setdefault_impl(PyDictObject *self, PyObject *key,
3025 PyObject *default_value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02003026/*[clinic end generated code: output=f8c1101ebf69e220 input=0f063756e815fd9d]*/
Benjamin Peterson00e98862013-03-07 22:16:29 -05003027{
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003028 PyObject *val;
Benjamin Peterson00e98862013-03-07 22:16:29 -05003029
Serhiy Storchaka48088ee2017-01-19 19:00:30 +02003030 val = PyDict_SetDefault((PyObject *)self, key, default_value);
Benjamin Peterson00e98862013-03-07 22:16:29 -05003031 Py_XINCREF(val);
3032 return val;
3033}
Guido van Rossum164452c2000-08-08 16:12:54 +00003034
3035static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303036dict_clear(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +00003037{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003038 PyDict_Clear((PyObject *)mp);
3039 Py_RETURN_NONE;
Guido van Rossumfb8f1ca1997-03-21 21:55:12 +00003040}
3041
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003042/*[clinic input]
3043dict.pop
3044
3045 key: object
3046 default: object = NULL
3047 /
3048
Serhiy Storchaka279f4462019-09-14 12:24:05 +03003049D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003050
3051If key is not found, default is returned if given, otherwise KeyError is raised
3052[clinic start generated code]*/
3053
Guido van Rossumba6ab842000-12-12 22:02:18 +00003054static PyObject *
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003055dict_pop_impl(PyDictObject *self, PyObject *key, PyObject *default_value)
Serhiy Storchaka279f4462019-09-14 12:24:05 +03003056/*[clinic end generated code: output=3abb47b89f24c21c input=eeebec7812190348]*/
Guido van Rossume027d982002-04-12 15:11:59 +00003057{
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003058 return _PyDict_Pop((PyObject*)self, key, default_value);
Guido van Rossume027d982002-04-12 15:11:59 +00003059}
3060
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003061/*[clinic input]
3062dict.popitem
3063
3064Remove and return a (key, value) pair as a 2-tuple.
3065
3066Pairs are returned in LIFO (last-in, first-out) order.
3067Raises KeyError if the dict is empty.
3068[clinic start generated code]*/
3069
Guido van Rossume027d982002-04-12 15:11:59 +00003070static PyObject *
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003071dict_popitem_impl(PyDictObject *self)
3072/*[clinic end generated code: output=e65fcb04420d230d input=1c38a49f21f64941]*/
Guido van Rossumba6ab842000-12-12 22:02:18 +00003073{
Victor Stinner742da042016-09-07 17:40:12 -07003074 Py_ssize_t i, j;
3075 PyDictKeyEntry *ep0, *ep;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003076 PyObject *res;
Guido van Rossumba6ab842000-12-12 22:02:18 +00003077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003078 /* Allocate the result tuple before checking the size. Believe it
3079 * or not, this allocation could trigger a garbage collection which
3080 * could empty the dict, so if we checked the size first and that
3081 * happened, the result would be an infinite loop (searching for an
3082 * entry that no longer exists). Note that the usual popitem()
3083 * idiom is "while d: k, v = d.popitem()". so needing to throw the
3084 * tuple away if the dict *is* empty isn't a significant
3085 * inefficiency -- possible, but unlikely in practice.
3086 */
3087 res = PyTuple_New(2);
3088 if (res == NULL)
3089 return NULL;
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003090 if (self->ma_used == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003091 Py_DECREF(res);
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003092 PyErr_SetString(PyExc_KeyError, "popitem(): dictionary is empty");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003093 return NULL;
3094 }
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003095 /* Convert split table to combined table */
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003096 if (self->ma_keys->dk_lookup == lookdict_split) {
3097 if (dictresize(self, DK_SIZE(self->ma_keys))) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003098 Py_DECREF(res);
3099 return NULL;
3100 }
3101 }
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003102 ENSURE_ALLOWS_DELETIONS(self);
Victor Stinner742da042016-09-07 17:40:12 -07003103
3104 /* Pop last item */
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003105 ep0 = DK_ENTRIES(self->ma_keys);
3106 i = self->ma_keys->dk_nentries - 1;
Victor Stinner742da042016-09-07 17:40:12 -07003107 while (i >= 0 && ep0[i].me_value == NULL) {
3108 i--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003109 }
Victor Stinner742da042016-09-07 17:40:12 -07003110 assert(i >= 0);
3111
3112 ep = &ep0[i];
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003113 j = lookdict_index(self->ma_keys, ep->me_hash, i);
Victor Stinner742da042016-09-07 17:40:12 -07003114 assert(j >= 0);
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003115 assert(dictkeys_get_index(self->ma_keys, j) == i);
3116 dictkeys_set_index(self->ma_keys, j, DKIX_DUMMY);
Victor Stinner742da042016-09-07 17:40:12 -07003117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003118 PyTuple_SET_ITEM(res, 0, ep->me_key);
3119 PyTuple_SET_ITEM(res, 1, ep->me_value);
Victor Stinner742da042016-09-07 17:40:12 -07003120 ep->me_key = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003121 ep->me_value = NULL;
Victor Stinner742da042016-09-07 17:40:12 -07003122 /* We can't dk_usable++ since there is DKIX_DUMMY in indices */
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003123 self->ma_keys->dk_nentries = i;
3124 self->ma_used--;
3125 self->ma_version_tag = DICT_NEXT_VERSION();
Victor Stinner0fc91ee2019-04-12 21:51:34 +02003126 ASSERT_CONSISTENT(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003127 return res;
Guido van Rossumba6ab842000-12-12 22:02:18 +00003128}
3129
Jeremy Hylton8caad492000-06-23 14:18:11 +00003130static int
3131dict_traverse(PyObject *op, visitproc visit, void *arg)
3132{
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003133 PyDictObject *mp = (PyDictObject *)op;
Benjamin Peterson55f44522016-09-05 12:12:59 -07003134 PyDictKeysObject *keys = mp->ma_keys;
Serhiy Storchaka46825d22016-09-26 21:29:34 +03003135 PyDictKeyEntry *entries = DK_ENTRIES(keys);
Victor Stinner742da042016-09-07 17:40:12 -07003136 Py_ssize_t i, n = keys->dk_nentries;
3137
Benjamin Peterson55f44522016-09-05 12:12:59 -07003138 if (keys->dk_lookup == lookdict) {
3139 for (i = 0; i < n; i++) {
3140 if (entries[i].me_value != NULL) {
3141 Py_VISIT(entries[i].me_value);
3142 Py_VISIT(entries[i].me_key);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003143 }
3144 }
Victor Stinner742da042016-09-07 17:40:12 -07003145 }
3146 else {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003147 if (mp->ma_values != NULL) {
Benjamin Peterson55f44522016-09-05 12:12:59 -07003148 for (i = 0; i < n; i++) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003149 Py_VISIT(mp->ma_values[i]);
3150 }
3151 }
3152 else {
Benjamin Peterson55f44522016-09-05 12:12:59 -07003153 for (i = 0; i < n; i++) {
3154 Py_VISIT(entries[i].me_value);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003155 }
3156 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003157 }
3158 return 0;
Jeremy Hylton8caad492000-06-23 14:18:11 +00003159}
3160
3161static int
3162dict_tp_clear(PyObject *op)
3163{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003164 PyDict_Clear(op);
3165 return 0;
Jeremy Hylton8caad492000-06-23 14:18:11 +00003166}
3167
Guido van Rossum8ce8a782007-11-01 19:42:39 +00003168static PyObject *dictiter_new(PyDictObject *, PyTypeObject *);
Guido van Rossum09e563a2001-05-01 12:10:21 +00003169
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +02003170Py_ssize_t
Eric Snow96c6af92015-05-29 22:21:39 -06003171_PyDict_SizeOf(PyDictObject *mp)
Martin v. Löwis00709aa2008-06-04 14:18:43 +00003172{
Victor Stinner742da042016-09-07 17:40:12 -07003173 Py_ssize_t size, usable, res;
Martin v. Löwis00709aa2008-06-04 14:18:43 +00003174
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003175 size = DK_SIZE(mp->ma_keys);
Victor Stinner742da042016-09-07 17:40:12 -07003176 usable = USABLE_FRACTION(size);
3177
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02003178 res = _PyObject_SIZE(Py_TYPE(mp));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003179 if (mp->ma_values)
Victor Stinner742da042016-09-07 17:40:12 -07003180 res += usable * sizeof(PyObject*);
Martin v. Loewis4f2f3b62012-04-24 19:13:57 +02003181 /* If the dictionary is split, the keys portion is accounted-for
3182 in the type object. */
3183 if (mp->ma_keys->dk_refcnt == 1)
Victor Stinner98ee9d52016-09-08 09:33:56 -07003184 res += (sizeof(PyDictKeysObject)
Victor Stinner98ee9d52016-09-08 09:33:56 -07003185 + DK_IXSIZE(mp->ma_keys) * size
3186 + sizeof(PyDictKeyEntry) * usable);
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +02003187 return res;
Martin v. Loewis4f2f3b62012-04-24 19:13:57 +02003188}
3189
3190Py_ssize_t
3191_PyDict_KeysSize(PyDictKeysObject *keys)
3192{
Victor Stinner98ee9d52016-09-08 09:33:56 -07003193 return (sizeof(PyDictKeysObject)
Victor Stinner98ee9d52016-09-08 09:33:56 -07003194 + DK_IXSIZE(keys) * DK_SIZE(keys)
3195 + USABLE_FRACTION(DK_SIZE(keys)) * sizeof(PyDictKeyEntry));
Martin v. Löwis00709aa2008-06-04 14:18:43 +00003196}
3197
doko@ubuntu.com17210f52016-01-14 14:04:59 +01003198static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303199dict_sizeof(PyDictObject *mp, PyObject *Py_UNUSED(ignored))
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +02003200{
3201 return PyLong_FromSsize_t(_PyDict_SizeOf(mp));
3202}
3203
Brandt Buchereb8ac572020-02-24 19:47:34 -08003204static PyObject *
3205dict_or(PyObject *self, PyObject *other)
3206{
3207 if (!PyDict_Check(self) || !PyDict_Check(other)) {
3208 Py_RETURN_NOTIMPLEMENTED;
3209 }
3210 PyObject *new = PyDict_Copy(self);
3211 if (new == NULL) {
3212 return NULL;
3213 }
3214 if (dict_update_arg(new, other)) {
3215 Py_DECREF(new);
3216 return NULL;
3217 }
3218 return new;
3219}
3220
3221static PyObject *
3222dict_ior(PyObject *self, PyObject *other)
3223{
3224 if (dict_update_arg(self, other)) {
3225 return NULL;
3226 }
3227 Py_INCREF(self);
3228 return self;
3229}
3230
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00003231PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]");
3232
Martin v. Löwis00709aa2008-06-04 14:18:43 +00003233PyDoc_STRVAR(sizeof__doc__,
3234"D.__sizeof__() -> size of D in memory, in bytes");
3235
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003236PyDoc_STRVAR(update__doc__,
Brett Cannonf2754162013-05-11 14:46:48 -04003237"D.update([E, ]**F) -> None. Update D from dict/iterable E and F.\n\
3238If E is present and has a .keys() method, then does: for k in E: D[k] = E[k]\n\
3239If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v\n\
3240In either case, this is followed by: for k in F: D[k] = F[k]");
Tim Petersf7f88b12000-12-13 23:18:45 +00003241
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003242PyDoc_STRVAR(clear__doc__,
3243"D.clear() -> None. Remove all items from D.");
Tim Petersf7f88b12000-12-13 23:18:45 +00003244
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003245PyDoc_STRVAR(copy__doc__,
3246"D.copy() -> a shallow copy of D");
Tim Petersf7f88b12000-12-13 23:18:45 +00003247
Guido van Rossumb90c8482007-02-10 01:11:45 +00003248/* Forward */
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303249static PyObject *dictkeys_new(PyObject *, PyObject *);
3250static PyObject *dictitems_new(PyObject *, PyObject *);
3251static PyObject *dictvalues_new(PyObject *, PyObject *);
Guido van Rossumb90c8482007-02-10 01:11:45 +00003252
Guido van Rossum45c85d12007-07-27 16:31:40 +00003253PyDoc_STRVAR(keys__doc__,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003254 "D.keys() -> a set-like object providing a view on D's keys");
Guido van Rossum45c85d12007-07-27 16:31:40 +00003255PyDoc_STRVAR(items__doc__,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003256 "D.items() -> a set-like object providing a view on D's items");
Guido van Rossum45c85d12007-07-27 16:31:40 +00003257PyDoc_STRVAR(values__doc__,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003258 "D.values() -> an object providing a view on D's values");
Guido van Rossumb90c8482007-02-10 01:11:45 +00003259
Guido van Rossumc0b618a1997-05-02 03:12:38 +00003260static PyMethodDef mapp_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -07003261 DICT___CONTAINS___METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003262 {"__getitem__", (PyCFunction)(void(*)(void))dict_subscript, METH_O | METH_COEXIST,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003263 getitem__doc__},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003264 {"__sizeof__", (PyCFunction)(void(*)(void))dict_sizeof, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003265 sizeof__doc__},
Victor Stinner7dc6a5f2017-01-19 12:37:13 +01003266 DICT_GET_METHODDEF
3267 DICT_SETDEFAULT_METHODDEF
Inada Naoki9e4f2f32019-04-12 16:11:28 +09003268 DICT_POP_METHODDEF
3269 DICT_POPITEM_METHODDEF
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303270 {"keys", dictkeys_new, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003271 keys__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303272 {"items", dictitems_new, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003273 items__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303274 {"values", dictvalues_new, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003275 values__doc__},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003276 {"update", (PyCFunction)(void(*)(void))dict_update, METH_VARARGS | METH_KEYWORDS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003277 update__doc__},
Larry Hastings5c661892014-01-24 06:17:25 -08003278 DICT_FROMKEYS_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003279 {"clear", (PyCFunction)dict_clear, METH_NOARGS,
3280 clear__doc__},
3281 {"copy", (PyCFunction)dict_copy, METH_NOARGS,
3282 copy__doc__},
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003283 DICT___REVERSED___METHODDEF
Guido van Rossum48b069a2020-04-07 09:50:06 -07003284 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003285 {NULL, NULL} /* sentinel */
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003286};
3287
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00003288/* Return 1 if `key` is in dict `op`, 0 if not, and -1 on error. */
Raymond Hettingerbc0f2ab2003-11-25 21:12:14 +00003289int
3290PyDict_Contains(PyObject *op, PyObject *key)
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003291{
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003292 Py_hash_t hash;
Victor Stinner742da042016-09-07 17:40:12 -07003293 Py_ssize_t ix;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003294 PyDictObject *mp = (PyDictObject *)op;
INADA Naokiba609772016-12-07 20:41:42 +09003295 PyObject *value;
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003297 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003298 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003299 hash = PyObject_Hash(key);
3300 if (hash == -1)
3301 return -1;
3302 }
INADA Naoki778928b2017-08-03 23:45:15 +09003303 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07003304 if (ix == DKIX_ERROR)
3305 return -1;
INADA Naokiba609772016-12-07 20:41:42 +09003306 return (ix != DKIX_EMPTY && value != NULL);
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003307}
3308
Thomas Wouterscf297e42007-02-23 15:07:44 +00003309/* Internal version of PyDict_Contains used when the hash value is already known */
3310int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00003311_PyDict_Contains(PyObject *op, PyObject *key, Py_hash_t hash)
Thomas Wouterscf297e42007-02-23 15:07:44 +00003312{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003313 PyDictObject *mp = (PyDictObject *)op;
INADA Naokiba609772016-12-07 20:41:42 +09003314 PyObject *value;
Victor Stinner742da042016-09-07 17:40:12 -07003315 Py_ssize_t ix;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003316
INADA Naoki778928b2017-08-03 23:45:15 +09003317 ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -07003318 if (ix == DKIX_ERROR)
3319 return -1;
INADA Naokiba609772016-12-07 20:41:42 +09003320 return (ix != DKIX_EMPTY && value != NULL);
Thomas Wouterscf297e42007-02-23 15:07:44 +00003321}
3322
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003323/* Hack to implement "key in dict" */
3324static PySequenceMethods dict_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003325 0, /* sq_length */
3326 0, /* sq_concat */
3327 0, /* sq_repeat */
3328 0, /* sq_item */
3329 0, /* sq_slice */
3330 0, /* sq_ass_item */
3331 0, /* sq_ass_slice */
3332 PyDict_Contains, /* sq_contains */
3333 0, /* sq_inplace_concat */
3334 0, /* sq_inplace_repeat */
Guido van Rossum0dbb4fb2001-04-20 16:50:40 +00003335};
3336
Brandt Buchereb8ac572020-02-24 19:47:34 -08003337static PyNumberMethods dict_as_number = {
3338 .nb_or = dict_or,
3339 .nb_inplace_or = dict_ior,
3340};
3341
Guido van Rossum09e563a2001-05-01 12:10:21 +00003342static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +00003343dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3344{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003345 PyObject *self;
Victor Stinnera9f61a52013-07-16 22:17:26 +02003346 PyDictObject *d;
Tim Peters6d6c1a32001-08-02 04:15:00 +00003347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003348 assert(type != NULL && type->tp_alloc != NULL);
3349 self = type->tp_alloc(type, 0);
Victor Stinnera9f61a52013-07-16 22:17:26 +02003350 if (self == NULL)
3351 return NULL;
Victor Stinnera9f61a52013-07-16 22:17:26 +02003352 d = (PyDictObject *)self;
Victor Stinnerac2a4fe2013-07-16 22:19:00 +02003353
Victor Stinnera9f61a52013-07-16 22:17:26 +02003354 /* The object has been implicitly tracked by tp_alloc */
3355 if (type == &PyDict_Type)
3356 _PyObject_GC_UNTRACK(d);
Victor Stinnerac2a4fe2013-07-16 22:19:00 +02003357
3358 d->ma_used = 0;
Victor Stinner3b6a6b42016-09-08 12:51:24 -07003359 d->ma_version_tag = DICT_NEXT_VERSION();
Victor Stinner742da042016-09-07 17:40:12 -07003360 d->ma_keys = new_keys_object(PyDict_MINSIZE);
Victor Stinnerac2a4fe2013-07-16 22:19:00 +02003361 if (d->ma_keys == NULL) {
3362 Py_DECREF(self);
3363 return NULL;
3364 }
Victor Stinner0fc91ee2019-04-12 21:51:34 +02003365 ASSERT_CONSISTENT(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003366 return self;
Tim Peters6d6c1a32001-08-02 04:15:00 +00003367}
3368
Tim Peters25786c02001-09-02 08:22:48 +00003369static int
3370dict_init(PyObject *self, PyObject *args, PyObject *kwds)
3371{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003372 return dict_update_common(self, args, kwds, "dict");
Tim Peters25786c02001-09-02 08:22:48 +00003373}
3374
Tim Peters6d6c1a32001-08-02 04:15:00 +00003375static PyObject *
Dong-hee Nae27916b2020-04-02 09:55:43 +09003376dict_vectorcall(PyObject *type, PyObject * const*args,
3377 size_t nargsf, PyObject *kwnames)
3378{
3379 assert(PyType_Check(type));
3380 Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
3381 if (!_PyArg_CheckPositional("dict", nargs, 0, 1)) {
3382 return NULL;
3383 }
3384
3385 PyObject *self = dict_new((PyTypeObject *)type, NULL, NULL);
3386 if (self == NULL) {
3387 return NULL;
3388 }
3389 if (nargs == 1) {
3390 if (dict_update_arg(self, args[0]) < 0) {
3391 Py_DECREF(self);
3392 return NULL;
3393 }
3394 args++;
3395 }
3396 if (kwnames != NULL) {
3397 for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(kwnames); i++) {
3398 if (PyDict_SetItem(self, PyTuple_GET_ITEM(kwnames, i), args[i]) < 0) {
3399 Py_DECREF(self);
3400 return NULL;
3401 }
3402 }
3403 }
3404 return self;
3405}
3406
3407static PyObject *
Guido van Rossum8ce8a782007-11-01 19:42:39 +00003408dict_iter(PyDictObject *dict)
Guido van Rossum09e563a2001-05-01 12:10:21 +00003409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003410 return dictiter_new(dict, &PyDictIterKey_Type);
Guido van Rossum09e563a2001-05-01 12:10:21 +00003411}
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003412
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003413PyDoc_STRVAR(dictionary_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00003414"dict() -> new empty dictionary\n"
Tim Petersa427a2b2001-10-29 22:25:45 +00003415"dict(mapping) -> new dictionary initialized from a mapping object's\n"
Ezio Melotti7f807b72010-03-01 04:08:34 +00003416" (key, value) pairs\n"
3417"dict(iterable) -> new dictionary initialized as if via:\n"
Tim Peters4d859532001-10-27 18:27:48 +00003418" d = {}\n"
Ezio Melotti7f807b72010-03-01 04:08:34 +00003419" for k, v in iterable:\n"
Just van Rossuma797d812002-11-23 09:45:04 +00003420" d[k] = v\n"
3421"dict(**kwargs) -> new dictionary initialized with the name=value pairs\n"
3422" in the keyword argument list. For example: dict(one=1, two=2)");
Tim Peters25786c02001-09-02 08:22:48 +00003423
Guido van Rossumc0b618a1997-05-02 03:12:38 +00003424PyTypeObject PyDict_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003425 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3426 "dict",
3427 sizeof(PyDictObject),
3428 0,
3429 (destructor)dict_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003430 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003431 0, /* tp_getattr */
3432 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003433 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003434 (reprfunc)dict_repr, /* tp_repr */
Brandt Buchereb8ac572020-02-24 19:47:34 -08003435 &dict_as_number, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003436 &dict_as_sequence, /* tp_as_sequence */
3437 &dict_as_mapping, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00003438 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003439 0, /* tp_call */
3440 0, /* tp_str */
3441 PyObject_GenericGetAttr, /* tp_getattro */
3442 0, /* tp_setattro */
3443 0, /* tp_as_buffer */
3444 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
3445 Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DICT_SUBCLASS, /* tp_flags */
3446 dictionary_doc, /* tp_doc */
3447 dict_traverse, /* tp_traverse */
3448 dict_tp_clear, /* tp_clear */
3449 dict_richcompare, /* tp_richcompare */
3450 0, /* tp_weaklistoffset */
3451 (getiterfunc)dict_iter, /* tp_iter */
3452 0, /* tp_iternext */
3453 mapp_methods, /* tp_methods */
3454 0, /* tp_members */
3455 0, /* tp_getset */
3456 0, /* tp_base */
3457 0, /* tp_dict */
3458 0, /* tp_descr_get */
3459 0, /* tp_descr_set */
3460 0, /* tp_dictoffset */
3461 dict_init, /* tp_init */
3462 PyType_GenericAlloc, /* tp_alloc */
3463 dict_new, /* tp_new */
3464 PyObject_GC_Del, /* tp_free */
Dong-hee Nae27916b2020-04-02 09:55:43 +09003465 .tp_vectorcall = dict_vectorcall,
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003466};
3467
Victor Stinner3c1e4812012-03-26 22:10:51 +02003468PyObject *
3469_PyDict_GetItemId(PyObject *dp, struct _Py_Identifier *key)
3470{
3471 PyObject *kv;
3472 kv = _PyUnicode_FromId(key); /* borrowed */
Victor Stinner5b3b1002013-07-22 23:50:57 +02003473 if (kv == NULL) {
3474 PyErr_Clear();
Victor Stinner3c1e4812012-03-26 22:10:51 +02003475 return NULL;
Victor Stinner5b3b1002013-07-22 23:50:57 +02003476 }
Victor Stinner3c1e4812012-03-26 22:10:51 +02003477 return PyDict_GetItem(dp, kv);
3478}
3479
Guido van Rossum3cca2451997-05-16 14:23:33 +00003480/* For backward compatibility with old dictionary interface */
3481
Guido van Rossumc0b618a1997-05-02 03:12:38 +00003482PyObject *
Martin v. Löwis32b4a1b2002-12-11 13:21:12 +00003483PyDict_GetItemString(PyObject *v, const char *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003484{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003485 PyObject *kv, *rv;
3486 kv = PyUnicode_FromString(key);
Victor Stinnerfdcbab92013-07-16 22:16:05 +02003487 if (kv == NULL) {
3488 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003489 return NULL;
Victor Stinnerfdcbab92013-07-16 22:16:05 +02003490 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003491 rv = PyDict_GetItem(v, kv);
3492 Py_DECREF(kv);
3493 return rv;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003494}
3495
3496int
Victor Stinner3c1e4812012-03-26 22:10:51 +02003497_PyDict_SetItemId(PyObject *v, struct _Py_Identifier *key, PyObject *item)
3498{
3499 PyObject *kv;
3500 kv = _PyUnicode_FromId(key); /* borrowed */
3501 if (kv == NULL)
3502 return -1;
3503 return PyDict_SetItem(v, kv, item);
3504}
3505
3506int
Martin v. Löwis32b4a1b2002-12-11 13:21:12 +00003507PyDict_SetItemString(PyObject *v, const char *key, PyObject *item)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003508{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003509 PyObject *kv;
3510 int err;
3511 kv = PyUnicode_FromString(key);
3512 if (kv == NULL)
3513 return -1;
3514 PyUnicode_InternInPlace(&kv); /* XXX Should we really? */
3515 err = PyDict_SetItem(v, kv, item);
3516 Py_DECREF(kv);
3517 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003518}
3519
3520int
Victor Stinner5fd2e5a2013-11-06 18:58:22 +01003521_PyDict_DelItemId(PyObject *v, _Py_Identifier *key)
3522{
3523 PyObject *kv = _PyUnicode_FromId(key); /* borrowed */
3524 if (kv == NULL)
3525 return -1;
3526 return PyDict_DelItem(v, kv);
3527}
3528
3529int
Martin v. Löwis32b4a1b2002-12-11 13:21:12 +00003530PyDict_DelItemString(PyObject *v, const char *key)
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003531{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003532 PyObject *kv;
3533 int err;
3534 kv = PyUnicode_FromString(key);
3535 if (kv == NULL)
3536 return -1;
3537 err = PyDict_DelItem(v, kv);
3538 Py_DECREF(kv);
3539 return err;
Guido van Rossum4b1302b1993-03-27 18:11:32 +00003540}
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003541
Raymond Hettinger019a1482004-03-18 02:41:19 +00003542/* Dictionary iterator types */
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003543
3544typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003545 PyObject_HEAD
3546 PyDictObject *di_dict; /* Set to NULL when iterator is exhausted */
3547 Py_ssize_t di_used;
3548 Py_ssize_t di_pos;
3549 PyObject* di_result; /* reusable result tuple for iteritems */
3550 Py_ssize_t len;
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003551} dictiterobject;
3552
3553static PyObject *
Guido van Rossum8ce8a782007-11-01 19:42:39 +00003554dictiter_new(PyDictObject *dict, PyTypeObject *itertype)
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003555{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003556 dictiterobject *di;
3557 di = PyObject_GC_New(dictiterobject, itertype);
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003558 if (di == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003559 return NULL;
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003560 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003561 Py_INCREF(dict);
3562 di->di_dict = dict;
3563 di->di_used = dict->ma_used;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003564 di->len = dict->ma_used;
Dong-hee Na24dc2f82019-10-20 05:01:08 +09003565 if (itertype == &PyDictRevIterKey_Type ||
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003566 itertype == &PyDictRevIterItem_Type ||
Dong-hee Na24dc2f82019-10-20 05:01:08 +09003567 itertype == &PyDictRevIterValue_Type) {
3568 if (dict->ma_values) {
3569 di->di_pos = dict->ma_used - 1;
3570 }
3571 else {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003572 di->di_pos = dict->ma_keys->dk_nentries - 1;
Dong-hee Na24dc2f82019-10-20 05:01:08 +09003573 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003574 }
3575 else {
3576 di->di_pos = 0;
3577 }
3578 if (itertype == &PyDictIterItem_Type ||
3579 itertype == &PyDictRevIterItem_Type) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003580 di->di_result = PyTuple_Pack(2, Py_None, Py_None);
3581 if (di->di_result == NULL) {
3582 Py_DECREF(di);
3583 return NULL;
3584 }
3585 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003586 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003587 di->di_result = NULL;
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003588 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003589 _PyObject_GC_TRACK(di);
3590 return (PyObject *)di;
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003591}
3592
3593static void
3594dictiter_dealloc(dictiterobject *di)
3595{
INADA Naokia6296d32017-08-24 14:55:17 +09003596 /* bpo-31095: UnTrack is needed before calling any callbacks */
3597 _PyObject_GC_UNTRACK(di);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003598 Py_XDECREF(di->di_dict);
3599 Py_XDECREF(di->di_result);
3600 PyObject_GC_Del(di);
Antoine Pitrou7ddda782009-01-01 15:35:33 +00003601}
3602
3603static int
3604dictiter_traverse(dictiterobject *di, visitproc visit, void *arg)
3605{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003606 Py_VISIT(di->di_dict);
3607 Py_VISIT(di->di_result);
3608 return 0;
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003609}
3610
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00003611static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303612dictiter_len(dictiterobject *di, PyObject *Py_UNUSED(ignored))
Raymond Hettinger0ce6dc82004-03-18 08:38:00 +00003613{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003614 Py_ssize_t len = 0;
3615 if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used)
3616 len = di->len;
3617 return PyLong_FromSize_t(len);
Raymond Hettinger0ce6dc82004-03-18 08:38:00 +00003618}
3619
Guido van Rossumb90c8482007-02-10 01:11:45 +00003620PyDoc_STRVAR(length_hint_doc,
3621 "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00003622
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003623static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05303624dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored));
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003625
3626PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
3627
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00003628static PyMethodDef dictiter_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003629 {"__length_hint__", (PyCFunction)(void(*)(void))dictiter_len, METH_NOARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003630 length_hint_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003631 {"__reduce__", (PyCFunction)(void(*)(void))dictiter_reduce, METH_NOARGS,
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003632 reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003633 {NULL, NULL} /* sentinel */
Raymond Hettinger0ce6dc82004-03-18 08:38:00 +00003634};
3635
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003636static PyObject*
3637dictiter_iternextkey(dictiterobject *di)
Guido van Rossum213c7a62001-04-23 14:08:49 +00003638{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003639 PyObject *key;
INADA Naokica2d8be2016-11-04 16:59:10 +09003640 Py_ssize_t i;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02003641 PyDictKeysObject *k;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003642 PyDictObject *d = di->di_dict;
Guido van Rossum213c7a62001-04-23 14:08:49 +00003643
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003644 if (d == NULL)
3645 return NULL;
3646 assert (PyDict_Check(d));
Guido van Rossum2147df72002-07-16 20:30:22 +00003647
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003648 if (di->di_used != d->ma_used) {
3649 PyErr_SetString(PyExc_RuntimeError,
3650 "dictionary changed size during iteration");
3651 di->di_used = -1; /* Make this state sticky */
3652 return NULL;
3653 }
Guido van Rossum2147df72002-07-16 20:30:22 +00003654
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003655 i = di->di_pos;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003656 k = d->ma_keys;
INADA Naokica2d8be2016-11-04 16:59:10 +09003657 assert(i >= 0);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003658 if (d->ma_values) {
INADA Naokica2d8be2016-11-04 16:59:10 +09003659 if (i >= d->ma_used)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003660 goto fail;
3661 key = DK_ENTRIES(k)[i].me_key;
INADA Naokica2d8be2016-11-04 16:59:10 +09003662 assert(d->ma_values[i] != NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003663 }
3664 else {
INADA Naokica2d8be2016-11-04 16:59:10 +09003665 Py_ssize_t n = k->dk_nentries;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003666 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i];
3667 while (i < n && entry_ptr->me_value == NULL) {
3668 entry_ptr++;
3669 i++;
3670 }
3671 if (i >= n)
3672 goto fail;
3673 key = entry_ptr->me_key;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003674 }
Thomas Perl796cc6e2019-03-28 07:03:25 +01003675 // We found an element (key), but did not expect it
3676 if (di->len == 0) {
3677 PyErr_SetString(PyExc_RuntimeError,
3678 "dictionary keys changed during iteration");
3679 goto fail;
3680 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003681 di->di_pos = i+1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003682 di->len--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003683 Py_INCREF(key);
3684 return key;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003685
3686fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003687 di->di_dict = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +03003688 Py_DECREF(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003689 return NULL;
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003690}
3691
Raymond Hettinger019a1482004-03-18 02:41:19 +00003692PyTypeObject PyDictIterKey_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003693 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3694 "dict_keyiterator", /* tp_name */
3695 sizeof(dictiterobject), /* tp_basicsize */
3696 0, /* tp_itemsize */
3697 /* methods */
3698 (destructor)dictiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003699 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003700 0, /* tp_getattr */
3701 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003702 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003703 0, /* tp_repr */
3704 0, /* tp_as_number */
3705 0, /* tp_as_sequence */
3706 0, /* tp_as_mapping */
3707 0, /* tp_hash */
3708 0, /* tp_call */
3709 0, /* tp_str */
3710 PyObject_GenericGetAttr, /* tp_getattro */
3711 0, /* tp_setattro */
3712 0, /* tp_as_buffer */
3713 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
3714 0, /* tp_doc */
3715 (traverseproc)dictiter_traverse, /* tp_traverse */
3716 0, /* tp_clear */
3717 0, /* tp_richcompare */
3718 0, /* tp_weaklistoffset */
3719 PyObject_SelfIter, /* tp_iter */
3720 (iternextfunc)dictiter_iternextkey, /* tp_iternext */
3721 dictiter_methods, /* tp_methods */
3722 0,
Raymond Hettinger019a1482004-03-18 02:41:19 +00003723};
3724
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003725static PyObject *
3726dictiter_iternextvalue(dictiterobject *di)
Raymond Hettinger019a1482004-03-18 02:41:19 +00003727{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003728 PyObject *value;
INADA Naokica2d8be2016-11-04 16:59:10 +09003729 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003730 PyDictObject *d = di->di_dict;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003731
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003732 if (d == NULL)
3733 return NULL;
3734 assert (PyDict_Check(d));
Raymond Hettinger019a1482004-03-18 02:41:19 +00003735
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003736 if (di->di_used != d->ma_used) {
3737 PyErr_SetString(PyExc_RuntimeError,
3738 "dictionary changed size during iteration");
3739 di->di_used = -1; /* Make this state sticky */
3740 return NULL;
3741 }
Raymond Hettinger019a1482004-03-18 02:41:19 +00003742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003743 i = di->di_pos;
INADA Naokica2d8be2016-11-04 16:59:10 +09003744 assert(i >= 0);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003745 if (d->ma_values) {
INADA Naokica2d8be2016-11-04 16:59:10 +09003746 if (i >= d->ma_used)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003747 goto fail;
INADA Naokica2d8be2016-11-04 16:59:10 +09003748 value = d->ma_values[i];
3749 assert(value != NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003750 }
3751 else {
INADA Naokica2d8be2016-11-04 16:59:10 +09003752 Py_ssize_t n = d->ma_keys->dk_nentries;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003753 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i];
3754 while (i < n && entry_ptr->me_value == NULL) {
3755 entry_ptr++;
3756 i++;
3757 }
3758 if (i >= n)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003759 goto fail;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003760 value = entry_ptr->me_value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003761 }
Thomas Perlb8311cf2019-04-02 11:30:10 +02003762 // We found an element, but did not expect it
3763 if (di->len == 0) {
3764 PyErr_SetString(PyExc_RuntimeError,
3765 "dictionary keys changed during iteration");
3766 goto fail;
3767 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003768 di->di_pos = i+1;
3769 di->len--;
3770 Py_INCREF(value);
3771 return value;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003772
3773fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003774 di->di_dict = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +03003775 Py_DECREF(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003776 return NULL;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003777}
3778
3779PyTypeObject PyDictIterValue_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003780 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3781 "dict_valueiterator", /* tp_name */
3782 sizeof(dictiterobject), /* tp_basicsize */
3783 0, /* tp_itemsize */
3784 /* methods */
3785 (destructor)dictiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003786 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003787 0, /* tp_getattr */
3788 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003789 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003790 0, /* tp_repr */
3791 0, /* tp_as_number */
3792 0, /* tp_as_sequence */
3793 0, /* tp_as_mapping */
3794 0, /* tp_hash */
3795 0, /* tp_call */
3796 0, /* tp_str */
3797 PyObject_GenericGetAttr, /* tp_getattro */
3798 0, /* tp_setattro */
3799 0, /* tp_as_buffer */
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003800 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003801 0, /* tp_doc */
3802 (traverseproc)dictiter_traverse, /* tp_traverse */
3803 0, /* tp_clear */
3804 0, /* tp_richcompare */
3805 0, /* tp_weaklistoffset */
3806 PyObject_SelfIter, /* tp_iter */
3807 (iternextfunc)dictiter_iternextvalue, /* tp_iternext */
3808 dictiter_methods, /* tp_methods */
3809 0,
Raymond Hettinger019a1482004-03-18 02:41:19 +00003810};
3811
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003812static PyObject *
3813dictiter_iternextitem(dictiterobject *di)
Raymond Hettinger019a1482004-03-18 02:41:19 +00003814{
Serhiy Storchaka753bca32017-05-20 12:30:02 +03003815 PyObject *key, *value, *result;
INADA Naokica2d8be2016-11-04 16:59:10 +09003816 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003817 PyDictObject *d = di->di_dict;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003818
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003819 if (d == NULL)
3820 return NULL;
3821 assert (PyDict_Check(d));
Raymond Hettinger019a1482004-03-18 02:41:19 +00003822
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003823 if (di->di_used != d->ma_used) {
3824 PyErr_SetString(PyExc_RuntimeError,
3825 "dictionary changed size during iteration");
3826 di->di_used = -1; /* Make this state sticky */
3827 return NULL;
3828 }
Raymond Hettinger019a1482004-03-18 02:41:19 +00003829
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003830 i = di->di_pos;
INADA Naokica2d8be2016-11-04 16:59:10 +09003831 assert(i >= 0);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003832 if (d->ma_values) {
INADA Naokica2d8be2016-11-04 16:59:10 +09003833 if (i >= d->ma_used)
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003834 goto fail;
3835 key = DK_ENTRIES(d->ma_keys)[i].me_key;
INADA Naokica2d8be2016-11-04 16:59:10 +09003836 value = d->ma_values[i];
3837 assert(value != NULL);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003838 }
3839 else {
INADA Naokica2d8be2016-11-04 16:59:10 +09003840 Py_ssize_t n = d->ma_keys->dk_nentries;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003841 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i];
3842 while (i < n && entry_ptr->me_value == NULL) {
3843 entry_ptr++;
3844 i++;
3845 }
3846 if (i >= n)
3847 goto fail;
3848 key = entry_ptr->me_key;
3849 value = entry_ptr->me_value;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04003850 }
Thomas Perlb8311cf2019-04-02 11:30:10 +02003851 // We found an element, but did not expect it
3852 if (di->len == 0) {
3853 PyErr_SetString(PyExc_RuntimeError,
3854 "dictionary keys changed during iteration");
3855 goto fail;
3856 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003857 di->di_pos = i+1;
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003858 di->len--;
Serhiy Storchaka753bca32017-05-20 12:30:02 +03003859 Py_INCREF(key);
3860 Py_INCREF(value);
3861 result = di->di_result;
3862 if (Py_REFCNT(result) == 1) {
3863 PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
3864 PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
3865 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
3866 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003867 Py_INCREF(result);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03003868 Py_DECREF(oldkey);
3869 Py_DECREF(oldvalue);
Serhiy Storchaka49f5cdd2016-10-09 23:08:05 +03003870 }
3871 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003872 result = PyTuple_New(2);
3873 if (result == NULL)
3874 return NULL;
Serhiy Storchaka753bca32017-05-20 12:30:02 +03003875 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
3876 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003877 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003878 return result;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003879
3880fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003881 di->di_dict = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +03003882 Py_DECREF(d);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003883 return NULL;
Raymond Hettinger019a1482004-03-18 02:41:19 +00003884}
3885
3886PyTypeObject PyDictIterItem_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003887 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3888 "dict_itemiterator", /* tp_name */
3889 sizeof(dictiterobject), /* tp_basicsize */
3890 0, /* tp_itemsize */
3891 /* methods */
3892 (destructor)dictiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003893 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003894 0, /* tp_getattr */
3895 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003896 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003897 0, /* tp_repr */
3898 0, /* tp_as_number */
3899 0, /* tp_as_sequence */
3900 0, /* tp_as_mapping */
3901 0, /* tp_hash */
3902 0, /* tp_call */
3903 0, /* tp_str */
3904 PyObject_GenericGetAttr, /* tp_getattro */
3905 0, /* tp_setattro */
3906 0, /* tp_as_buffer */
3907 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
3908 0, /* tp_doc */
3909 (traverseproc)dictiter_traverse, /* tp_traverse */
3910 0, /* tp_clear */
3911 0, /* tp_richcompare */
3912 0, /* tp_weaklistoffset */
3913 PyObject_SelfIter, /* tp_iter */
3914 (iternextfunc)dictiter_iternextitem, /* tp_iternext */
3915 dictiter_methods, /* tp_methods */
3916 0,
Guido van Rossum59d1d2b2001-04-20 19:13:02 +00003917};
Guido van Rossumb90c8482007-02-10 01:11:45 +00003918
3919
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003920/* dictreviter */
3921
3922static PyObject *
3923dictreviter_iternext(dictiterobject *di)
3924{
3925 PyDictObject *d = di->di_dict;
3926
3927 if (d == NULL) {
3928 return NULL;
3929 }
3930 assert (PyDict_Check(d));
3931
3932 if (di->di_used != d->ma_used) {
3933 PyErr_SetString(PyExc_RuntimeError,
3934 "dictionary changed size during iteration");
3935 di->di_used = -1; /* Make this state sticky */
3936 return NULL;
3937 }
3938
3939 Py_ssize_t i = di->di_pos;
3940 PyDictKeysObject *k = d->ma_keys;
3941 PyObject *key, *value, *result;
3942
Serhiy Storchaka2e3d8732019-10-23 14:48:08 +03003943 if (i < 0) {
3944 goto fail;
3945 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003946 if (d->ma_values) {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003947 key = DK_ENTRIES(k)[i].me_key;
3948 value = d->ma_values[i];
3949 assert (value != NULL);
3950 }
3951 else {
3952 PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i];
Serhiy Storchaka2e3d8732019-10-23 14:48:08 +03003953 while (entry_ptr->me_value == NULL) {
3954 if (--i < 0) {
3955 goto fail;
3956 }
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003957 entry_ptr--;
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003958 }
3959 key = entry_ptr->me_key;
3960 value = entry_ptr->me_value;
3961 }
3962 di->di_pos = i-1;
3963 di->len--;
3964
Dong-hee Na1b55b652020-02-17 19:09:15 +09003965 if (Py_IS_TYPE(di, &PyDictRevIterKey_Type)) {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003966 Py_INCREF(key);
3967 return key;
3968 }
Dong-hee Na1b55b652020-02-17 19:09:15 +09003969 else if (Py_IS_TYPE(di, &PyDictRevIterValue_Type)) {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003970 Py_INCREF(value);
3971 return value;
3972 }
Dong-hee Na1b55b652020-02-17 19:09:15 +09003973 else if (Py_IS_TYPE(di, &PyDictRevIterItem_Type)) {
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01003974 Py_INCREF(key);
3975 Py_INCREF(value);
3976 result = di->di_result;
3977 if (Py_REFCNT(result) == 1) {
3978 PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
3979 PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
3980 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
3981 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
3982 Py_INCREF(result);
3983 Py_DECREF(oldkey);
3984 Py_DECREF(oldvalue);
3985 }
3986 else {
3987 result = PyTuple_New(2);
3988 if (result == NULL) {
3989 return NULL;
3990 }
3991 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
3992 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
3993 }
3994 return result;
3995 }
3996 else {
3997 Py_UNREACHABLE();
3998 }
3999
4000fail:
4001 di->di_dict = NULL;
4002 Py_DECREF(d);
4003 return NULL;
4004}
4005
4006PyTypeObject PyDictRevIterKey_Type = {
4007 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4008 "dict_reversekeyiterator",
4009 sizeof(dictiterobject),
4010 .tp_dealloc = (destructor)dictiter_dealloc,
4011 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
4012 .tp_traverse = (traverseproc)dictiter_traverse,
4013 .tp_iter = PyObject_SelfIter,
4014 .tp_iternext = (iternextfunc)dictreviter_iternext,
4015 .tp_methods = dictiter_methods
4016};
4017
4018
4019/*[clinic input]
4020dict.__reversed__
4021
4022Return a reverse iterator over the dict keys.
4023[clinic start generated code]*/
4024
4025static PyObject *
4026dict___reversed___impl(PyDictObject *self)
4027/*[clinic end generated code: output=e674483336d1ed51 input=23210ef3477d8c4d]*/
4028{
4029 assert (PyDict_Check(self));
4030 return dictiter_new(self, &PyDictRevIterKey_Type);
4031}
4032
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004033static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304034dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004035{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02004036 _Py_IDENTIFIER(iter);
Sergey Fedoseev63958442018-10-20 05:43:33 +05004037 /* copy the iterator state */
4038 dictiterobject tmp = *di;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004039 Py_XINCREF(tmp.di_dict);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004040
Sergey Fedoseev63958442018-10-20 05:43:33 +05004041 PyObject *list = PySequence_List((PyObject*)&tmp);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004042 Py_XDECREF(tmp.di_dict);
Sergey Fedoseev63958442018-10-20 05:43:33 +05004043 if (list == NULL) {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004044 return NULL;
4045 }
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02004046 return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00004047}
4048
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004049PyTypeObject PyDictRevIterItem_Type = {
4050 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4051 "dict_reverseitemiterator",
4052 sizeof(dictiterobject),
4053 .tp_dealloc = (destructor)dictiter_dealloc,
4054 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
4055 .tp_traverse = (traverseproc)dictiter_traverse,
4056 .tp_iter = PyObject_SelfIter,
4057 .tp_iternext = (iternextfunc)dictreviter_iternext,
4058 .tp_methods = dictiter_methods
4059};
4060
4061PyTypeObject PyDictRevIterValue_Type = {
4062 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4063 "dict_reversevalueiterator",
4064 sizeof(dictiterobject),
4065 .tp_dealloc = (destructor)dictiter_dealloc,
4066 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
4067 .tp_traverse = (traverseproc)dictiter_traverse,
4068 .tp_iter = PyObject_SelfIter,
4069 .tp_iternext = (iternextfunc)dictreviter_iternext,
4070 .tp_methods = dictiter_methods
4071};
4072
Guido van Rossum3ac67412007-02-10 18:55:06 +00004073/***********************************************/
Guido van Rossumb90c8482007-02-10 01:11:45 +00004074/* View objects for keys(), items(), values(). */
Guido van Rossum3ac67412007-02-10 18:55:06 +00004075/***********************************************/
4076
Guido van Rossumb90c8482007-02-10 01:11:45 +00004077/* The instance lay-out is the same for all three; but the type differs. */
4078
Guido van Rossumb90c8482007-02-10 01:11:45 +00004079static void
Eric Snow96c6af92015-05-29 22:21:39 -06004080dictview_dealloc(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004081{
INADA Naokia6296d32017-08-24 14:55:17 +09004082 /* bpo-31095: UnTrack is needed before calling any callbacks */
4083 _PyObject_GC_UNTRACK(dv);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004084 Py_XDECREF(dv->dv_dict);
4085 PyObject_GC_Del(dv);
Antoine Pitrou7ddda782009-01-01 15:35:33 +00004086}
4087
4088static int
Eric Snow96c6af92015-05-29 22:21:39 -06004089dictview_traverse(_PyDictViewObject *dv, visitproc visit, void *arg)
Antoine Pitrou7ddda782009-01-01 15:35:33 +00004090{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004091 Py_VISIT(dv->dv_dict);
4092 return 0;
Guido van Rossumb90c8482007-02-10 01:11:45 +00004093}
4094
Guido van Rossum83825ac2007-02-10 04:54:19 +00004095static Py_ssize_t
Eric Snow96c6af92015-05-29 22:21:39 -06004096dictview_len(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004097{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004098 Py_ssize_t len = 0;
4099 if (dv->dv_dict != NULL)
4100 len = dv->dv_dict->ma_used;
4101 return len;
Guido van Rossumb90c8482007-02-10 01:11:45 +00004102}
4103
Eric Snow96c6af92015-05-29 22:21:39 -06004104PyObject *
4105_PyDictView_New(PyObject *dict, PyTypeObject *type)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004106{
Eric Snow96c6af92015-05-29 22:21:39 -06004107 _PyDictViewObject *dv;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004108 if (dict == NULL) {
4109 PyErr_BadInternalCall();
4110 return NULL;
4111 }
4112 if (!PyDict_Check(dict)) {
4113 /* XXX Get rid of this restriction later */
4114 PyErr_Format(PyExc_TypeError,
4115 "%s() requires a dict argument, not '%s'",
Victor Stinner58ac7002020-02-07 03:04:21 +01004116 type->tp_name, Py_TYPE(dict)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004117 return NULL;
4118 }
Eric Snow96c6af92015-05-29 22:21:39 -06004119 dv = PyObject_GC_New(_PyDictViewObject, type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004120 if (dv == NULL)
4121 return NULL;
4122 Py_INCREF(dict);
4123 dv->dv_dict = (PyDictObject *)dict;
4124 _PyObject_GC_TRACK(dv);
4125 return (PyObject *)dv;
Guido van Rossumb90c8482007-02-10 01:11:45 +00004126}
4127
Neal Norwitze36f2ba2007-02-26 23:12:28 +00004128/* TODO(guido): The views objects are not complete:
4129
4130 * support more set operations
4131 * support arbitrary mappings?
4132 - either these should be static or exported in dictobject.h
4133 - if public then they should probably be in builtins
4134*/
4135
Guido van Rossumaac530c2007-08-24 22:33:45 +00004136/* Return 1 if self is a subset of other, iterating over self;
4137 0 if not; -1 if an error occurred. */
Guido van Rossumd9214d12007-02-12 02:23:40 +00004138static int
4139all_contained_in(PyObject *self, PyObject *other)
4140{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004141 PyObject *iter = PyObject_GetIter(self);
4142 int ok = 1;
Guido van Rossumd9214d12007-02-12 02:23:40 +00004143
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004144 if (iter == NULL)
4145 return -1;
4146 for (;;) {
4147 PyObject *next = PyIter_Next(iter);
4148 if (next == NULL) {
4149 if (PyErr_Occurred())
4150 ok = -1;
4151 break;
4152 }
4153 ok = PySequence_Contains(other, next);
4154 Py_DECREF(next);
4155 if (ok <= 0)
4156 break;
4157 }
4158 Py_DECREF(iter);
4159 return ok;
Guido van Rossumd9214d12007-02-12 02:23:40 +00004160}
4161
4162static PyObject *
4163dictview_richcompare(PyObject *self, PyObject *other, int op)
4164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004165 Py_ssize_t len_self, len_other;
4166 int ok;
4167 PyObject *result;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004169 assert(self != NULL);
4170 assert(PyDictViewSet_Check(self));
4171 assert(other != NULL);
Guido van Rossumd9214d12007-02-12 02:23:40 +00004172
Brian Curtindfc80e32011-08-10 20:28:54 -05004173 if (!PyAnySet_Check(other) && !PyDictViewSet_Check(other))
4174 Py_RETURN_NOTIMPLEMENTED;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004176 len_self = PyObject_Size(self);
4177 if (len_self < 0)
4178 return NULL;
4179 len_other = PyObject_Size(other);
4180 if (len_other < 0)
4181 return NULL;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004182
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004183 ok = 0;
4184 switch(op) {
Guido van Rossumaac530c2007-08-24 22:33:45 +00004185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004186 case Py_NE:
4187 case Py_EQ:
4188 if (len_self == len_other)
4189 ok = all_contained_in(self, other);
4190 if (op == Py_NE && ok >= 0)
4191 ok = !ok;
4192 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004194 case Py_LT:
4195 if (len_self < len_other)
4196 ok = all_contained_in(self, other);
4197 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004199 case Py_LE:
4200 if (len_self <= len_other)
4201 ok = all_contained_in(self, other);
4202 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004204 case Py_GT:
4205 if (len_self > len_other)
4206 ok = all_contained_in(other, self);
4207 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004209 case Py_GE:
4210 if (len_self >= len_other)
4211 ok = all_contained_in(other, self);
4212 break;
Guido van Rossumaac530c2007-08-24 22:33:45 +00004213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004214 }
4215 if (ok < 0)
4216 return NULL;
4217 result = ok ? Py_True : Py_False;
4218 Py_INCREF(result);
4219 return result;
Guido van Rossumd9214d12007-02-12 02:23:40 +00004220}
4221
Raymond Hettingerb0d56af2009-03-03 10:52:49 +00004222static PyObject *
Eric Snow96c6af92015-05-29 22:21:39 -06004223dictview_repr(_PyDictViewObject *dv)
Raymond Hettingerb0d56af2009-03-03 10:52:49 +00004224{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004225 PyObject *seq;
bennorthd7773d92018-01-26 15:46:01 +00004226 PyObject *result = NULL;
4227 Py_ssize_t rc;
Raymond Hettingerb0d56af2009-03-03 10:52:49 +00004228
bennorthd7773d92018-01-26 15:46:01 +00004229 rc = Py_ReprEnter((PyObject *)dv);
4230 if (rc != 0) {
4231 return rc > 0 ? PyUnicode_FromString("...") : NULL;
4232 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004233 seq = PySequence_List((PyObject *)dv);
bennorthd7773d92018-01-26 15:46:01 +00004234 if (seq == NULL) {
4235 goto Done;
4236 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004237 result = PyUnicode_FromFormat("%s(%R)", Py_TYPE(dv)->tp_name, seq);
4238 Py_DECREF(seq);
bennorthd7773d92018-01-26 15:46:01 +00004239
4240Done:
4241 Py_ReprLeave((PyObject *)dv);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004242 return result;
Raymond Hettingerb0d56af2009-03-03 10:52:49 +00004243}
4244
Guido van Rossum3ac67412007-02-10 18:55:06 +00004245/*** dict_keys ***/
Guido van Rossumb90c8482007-02-10 01:11:45 +00004246
4247static PyObject *
Eric Snow96c6af92015-05-29 22:21:39 -06004248dictkeys_iter(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004249{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004250 if (dv->dv_dict == NULL) {
4251 Py_RETURN_NONE;
4252 }
4253 return dictiter_new(dv->dv_dict, &PyDictIterKey_Type);
Guido van Rossum3ac67412007-02-10 18:55:06 +00004254}
4255
4256static int
Eric Snow96c6af92015-05-29 22:21:39 -06004257dictkeys_contains(_PyDictViewObject *dv, PyObject *obj)
Guido van Rossum3ac67412007-02-10 18:55:06 +00004258{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004259 if (dv->dv_dict == NULL)
4260 return 0;
4261 return PyDict_Contains((PyObject *)dv->dv_dict, obj);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004262}
4263
Guido van Rossum83825ac2007-02-10 04:54:19 +00004264static PySequenceMethods dictkeys_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004265 (lenfunc)dictview_len, /* sq_length */
4266 0, /* sq_concat */
4267 0, /* sq_repeat */
4268 0, /* sq_item */
4269 0, /* sq_slice */
4270 0, /* sq_ass_item */
4271 0, /* sq_ass_slice */
4272 (objobjproc)dictkeys_contains, /* sq_contains */
Guido van Rossum83825ac2007-02-10 04:54:19 +00004273};
4274
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004275// Create an set object from dictviews object.
4276// Returns a new reference.
4277// This utility function is used by set operations.
Guido van Rossum523259b2007-08-24 23:41:22 +00004278static PyObject*
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004279dictviews_to_set(PyObject *self)
Guido van Rossum523259b2007-08-24 23:41:22 +00004280{
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004281 PyObject *left = self;
4282 if (PyDictKeys_Check(self)) {
4283 // PySet_New() has fast path for the dict object.
4284 PyObject *dict = (PyObject *)((_PyDictViewObject *)self)->dv_dict;
4285 if (PyDict_CheckExact(dict)) {
4286 left = dict;
4287 }
4288 }
4289 return PySet_New(left);
4290}
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004291
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004292static PyObject*
4293dictviews_sub(PyObject *self, PyObject *other)
4294{
4295 PyObject *result = dictviews_to_set(self);
4296 if (result == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004297 return NULL;
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004298 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004299
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004300 _Py_IDENTIFIER(difference_update);
4301 PyObject *tmp = _PyObject_CallMethodIdOneArg(
4302 result, &PyId_difference_update, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004303 if (tmp == NULL) {
4304 Py_DECREF(result);
4305 return NULL;
4306 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004308 Py_DECREF(tmp);
4309 return result;
Guido van Rossum523259b2007-08-24 23:41:22 +00004310}
4311
Forest Gregg998cf1f2019-08-26 02:17:43 -05004312static int
4313dictitems_contains(_PyDictViewObject *dv, PyObject *obj);
4314
4315PyObject *
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04004316_PyDictView_Intersect(PyObject* self, PyObject *other)
Guido van Rossum523259b2007-08-24 23:41:22 +00004317{
Forest Gregg998cf1f2019-08-26 02:17:43 -05004318 PyObject *result;
4319 PyObject *it;
4320 PyObject *key;
4321 Py_ssize_t len_self;
4322 int rv;
4323 int (*dict_contains)(_PyDictViewObject *, PyObject *);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02004324
Forest Gregg998cf1f2019-08-26 02:17:43 -05004325 /* Python interpreter swaps parameters when dict view
4326 is on right side of & */
4327 if (!PyDictViewSet_Check(self)) {
4328 PyObject *tmp = other;
4329 other = self;
4330 self = tmp;
4331 }
4332
4333 len_self = dictview_len((_PyDictViewObject *)self);
4334
4335 /* if other is a set and self is smaller than other,
4336 reuse set intersection logic */
Dong-hee Na1b55b652020-02-17 19:09:15 +09004337 if (Py_IS_TYPE(other, &PySet_Type) && len_self <= PyObject_Size(other)) {
Forest Gregg998cf1f2019-08-26 02:17:43 -05004338 _Py_IDENTIFIER(intersection);
4339 return _PyObject_CallMethodIdObjArgs(other, &PyId_intersection, self, NULL);
4340 }
4341
4342 /* if other is another dict view, and it is bigger than self,
4343 swap them */
4344 if (PyDictViewSet_Check(other)) {
4345 Py_ssize_t len_other = dictview_len((_PyDictViewObject *)other);
4346 if (len_other > len_self) {
4347 PyObject *tmp = other;
4348 other = self;
4349 self = tmp;
4350 }
4351 }
4352
4353 /* at this point, two things should be true
4354 1. self is a dictview
4355 2. if other is a dictview then it is smaller than self */
4356 result = PySet_New(NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004357 if (result == NULL)
4358 return NULL;
Guido van Rossum523259b2007-08-24 23:41:22 +00004359
Forest Gregg998cf1f2019-08-26 02:17:43 -05004360 it = PyObject_GetIter(other);
Zackery Spytzb16e3822019-10-13 05:49:05 -06004361 if (it == NULL) {
4362 Py_DECREF(result);
4363 return NULL;
4364 }
Forest Gregg998cf1f2019-08-26 02:17:43 -05004365
Forest Gregg998cf1f2019-08-26 02:17:43 -05004366 if (PyDictKeys_Check(self)) {
4367 dict_contains = dictkeys_contains;
4368 }
4369 /* else PyDictItems_Check(self) */
4370 else {
4371 dict_contains = dictitems_contains;
4372 }
4373
4374 while ((key = PyIter_Next(it)) != NULL) {
4375 rv = dict_contains((_PyDictViewObject *)self, key);
4376 if (rv < 0) {
4377 goto error;
4378 }
4379 if (rv) {
4380 if (PySet_Add(result, key)) {
4381 goto error;
4382 }
4383 }
4384 Py_DECREF(key);
4385 }
4386 Py_DECREF(it);
4387 if (PyErr_Occurred()) {
4388 Py_DECREF(result);
4389 return NULL;
4390 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004391 return result;
Forest Gregg998cf1f2019-08-26 02:17:43 -05004392
4393error:
4394 Py_DECREF(it);
4395 Py_DECREF(result);
4396 Py_DECREF(key);
4397 return NULL;
Guido van Rossum523259b2007-08-24 23:41:22 +00004398}
4399
4400static PyObject*
4401dictviews_or(PyObject* self, PyObject *other)
4402{
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004403 PyObject *result = dictviews_to_set(self);
4404 if (result == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004405 return NULL;
4406 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004407
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004408 if (_PySet_Update(result, other) < 0) {
4409 Py_DECREF(result);
4410 return NULL;
4411 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004412 return result;
Guido van Rossum523259b2007-08-24 23:41:22 +00004413}
4414
4415static PyObject*
4416dictviews_xor(PyObject* self, PyObject *other)
4417{
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004418 PyObject *result = dictviews_to_set(self);
4419 if (result == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004420 return NULL;
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004421 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004422
Inada Naoki6cbc84f2019-11-08 00:59:04 +09004423 _Py_IDENTIFIER(symmetric_difference_update);
4424 PyObject *tmp = _PyObject_CallMethodIdOneArg(
4425 result, &PyId_symmetric_difference_update, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004426 if (tmp == NULL) {
4427 Py_DECREF(result);
4428 return NULL;
4429 }
Guido van Rossum523259b2007-08-24 23:41:22 +00004430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004431 Py_DECREF(tmp);
4432 return result;
Guido van Rossum523259b2007-08-24 23:41:22 +00004433}
4434
4435static PyNumberMethods dictviews_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004436 0, /*nb_add*/
4437 (binaryfunc)dictviews_sub, /*nb_subtract*/
4438 0, /*nb_multiply*/
4439 0, /*nb_remainder*/
4440 0, /*nb_divmod*/
4441 0, /*nb_power*/
4442 0, /*nb_negative*/
4443 0, /*nb_positive*/
4444 0, /*nb_absolute*/
4445 0, /*nb_bool*/
4446 0, /*nb_invert*/
4447 0, /*nb_lshift*/
4448 0, /*nb_rshift*/
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04004449 (binaryfunc)_PyDictView_Intersect, /*nb_and*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004450 (binaryfunc)dictviews_xor, /*nb_xor*/
4451 (binaryfunc)dictviews_or, /*nb_or*/
Guido van Rossum523259b2007-08-24 23:41:22 +00004452};
4453
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004454static PyObject*
4455dictviews_isdisjoint(PyObject *self, PyObject *other)
4456{
4457 PyObject *it;
4458 PyObject *item = NULL;
4459
4460 if (self == other) {
Eric Snow96c6af92015-05-29 22:21:39 -06004461 if (dictview_len((_PyDictViewObject *)self) == 0)
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004462 Py_RETURN_TRUE;
4463 else
4464 Py_RETURN_FALSE;
4465 }
4466
4467 /* Iterate over the shorter object (only if other is a set,
4468 * because PySequence_Contains may be expensive otherwise): */
4469 if (PyAnySet_Check(other) || PyDictViewSet_Check(other)) {
Eric Snow96c6af92015-05-29 22:21:39 -06004470 Py_ssize_t len_self = dictview_len((_PyDictViewObject *)self);
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004471 Py_ssize_t len_other = PyObject_Size(other);
4472 if (len_other == -1)
4473 return NULL;
4474
4475 if ((len_other > len_self)) {
4476 PyObject *tmp = other;
4477 other = self;
4478 self = tmp;
4479 }
4480 }
4481
4482 it = PyObject_GetIter(other);
4483 if (it == NULL)
4484 return NULL;
4485
4486 while ((item = PyIter_Next(it)) != NULL) {
4487 int contains = PySequence_Contains(self, item);
4488 Py_DECREF(item);
4489 if (contains == -1) {
4490 Py_DECREF(it);
4491 return NULL;
4492 }
4493
4494 if (contains) {
4495 Py_DECREF(it);
4496 Py_RETURN_FALSE;
4497 }
4498 }
4499 Py_DECREF(it);
4500 if (PyErr_Occurred())
4501 return NULL; /* PyIter_Next raised an exception. */
4502 Py_RETURN_TRUE;
4503}
4504
4505PyDoc_STRVAR(isdisjoint_doc,
4506"Return True if the view and the given iterable have a null intersection.");
4507
Serhiy Storchaka81524022018-11-27 13:05:02 +02004508static PyObject* dictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored));
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004509
4510PyDoc_STRVAR(reversed_keys_doc,
4511"Return a reverse iterator over the dict keys.");
4512
Guido van Rossumb90c8482007-02-10 01:11:45 +00004513static PyMethodDef dictkeys_methods[] = {
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004514 {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O,
4515 isdisjoint_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004516 {"__reversed__", (PyCFunction)(void(*)(void))dictkeys_reversed, METH_NOARGS,
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004517 reversed_keys_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004518 {NULL, NULL} /* sentinel */
Guido van Rossumb90c8482007-02-10 01:11:45 +00004519};
4520
4521PyTypeObject PyDictKeys_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004522 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4523 "dict_keys", /* tp_name */
Eric Snow96c6af92015-05-29 22:21:39 -06004524 sizeof(_PyDictViewObject), /* tp_basicsize */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004525 0, /* tp_itemsize */
4526 /* methods */
4527 (destructor)dictview_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004528 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004529 0, /* tp_getattr */
4530 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004531 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004532 (reprfunc)dictview_repr, /* tp_repr */
4533 &dictviews_as_number, /* tp_as_number */
4534 &dictkeys_as_sequence, /* tp_as_sequence */
4535 0, /* tp_as_mapping */
4536 0, /* tp_hash */
4537 0, /* tp_call */
4538 0, /* tp_str */
4539 PyObject_GenericGetAttr, /* tp_getattro */
4540 0, /* tp_setattro */
4541 0, /* tp_as_buffer */
4542 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
4543 0, /* tp_doc */
4544 (traverseproc)dictview_traverse, /* tp_traverse */
4545 0, /* tp_clear */
4546 dictview_richcompare, /* tp_richcompare */
4547 0, /* tp_weaklistoffset */
4548 (getiterfunc)dictkeys_iter, /* tp_iter */
4549 0, /* tp_iternext */
4550 dictkeys_methods, /* tp_methods */
4551 0,
Guido van Rossumb90c8482007-02-10 01:11:45 +00004552};
4553
4554static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304555dictkeys_new(PyObject *dict, PyObject *Py_UNUSED(ignored))
Guido van Rossumb90c8482007-02-10 01:11:45 +00004556{
Eric Snow96c6af92015-05-29 22:21:39 -06004557 return _PyDictView_New(dict, &PyDictKeys_Type);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004558}
4559
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004560static PyObject *
Serhiy Storchaka81524022018-11-27 13:05:02 +02004561dictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored))
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004562{
4563 if (dv->dv_dict == NULL) {
4564 Py_RETURN_NONE;
4565 }
4566 return dictiter_new(dv->dv_dict, &PyDictRevIterKey_Type);
4567}
4568
Guido van Rossum3ac67412007-02-10 18:55:06 +00004569/*** dict_items ***/
Guido van Rossumb90c8482007-02-10 01:11:45 +00004570
4571static PyObject *
Eric Snow96c6af92015-05-29 22:21:39 -06004572dictitems_iter(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004573{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004574 if (dv->dv_dict == NULL) {
4575 Py_RETURN_NONE;
4576 }
4577 return dictiter_new(dv->dv_dict, &PyDictIterItem_Type);
Guido van Rossum3ac67412007-02-10 18:55:06 +00004578}
4579
4580static int
Eric Snow96c6af92015-05-29 22:21:39 -06004581dictitems_contains(_PyDictViewObject *dv, PyObject *obj)
Guido van Rossum3ac67412007-02-10 18:55:06 +00004582{
Serhiy Storchaka753bca32017-05-20 12:30:02 +03004583 int result;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004584 PyObject *key, *value, *found;
4585 if (dv->dv_dict == NULL)
4586 return 0;
4587 if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 2)
4588 return 0;
4589 key = PyTuple_GET_ITEM(obj, 0);
4590 value = PyTuple_GET_ITEM(obj, 1);
Raymond Hettinger6692f012016-09-18 21:46:08 -07004591 found = PyDict_GetItemWithError((PyObject *)dv->dv_dict, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004592 if (found == NULL) {
4593 if (PyErr_Occurred())
4594 return -1;
4595 return 0;
4596 }
Serhiy Storchaka753bca32017-05-20 12:30:02 +03004597 Py_INCREF(found);
Serhiy Storchaka18b711c2019-08-04 14:12:48 +03004598 result = PyObject_RichCompareBool(found, value, Py_EQ);
Serhiy Storchaka753bca32017-05-20 12:30:02 +03004599 Py_DECREF(found);
4600 return result;
Guido van Rossumb90c8482007-02-10 01:11:45 +00004601}
4602
Guido van Rossum83825ac2007-02-10 04:54:19 +00004603static PySequenceMethods dictitems_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004604 (lenfunc)dictview_len, /* sq_length */
4605 0, /* sq_concat */
4606 0, /* sq_repeat */
4607 0, /* sq_item */
4608 0, /* sq_slice */
4609 0, /* sq_ass_item */
4610 0, /* sq_ass_slice */
4611 (objobjproc)dictitems_contains, /* sq_contains */
Guido van Rossum83825ac2007-02-10 04:54:19 +00004612};
4613
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004614static PyObject* dictitems_reversed(_PyDictViewObject *dv);
4615
4616PyDoc_STRVAR(reversed_items_doc,
4617"Return a reverse iterator over the dict items.");
4618
Guido van Rossumb90c8482007-02-10 01:11:45 +00004619static PyMethodDef dictitems_methods[] = {
Daniel Stutzbach045b3ba2010-09-02 15:06:06 +00004620 {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O,
4621 isdisjoint_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004622 {"__reversed__", (PyCFunction)(void(*)(void))dictitems_reversed, METH_NOARGS,
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004623 reversed_items_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004624 {NULL, NULL} /* sentinel */
Guido van Rossumb90c8482007-02-10 01:11:45 +00004625};
4626
4627PyTypeObject PyDictItems_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004628 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4629 "dict_items", /* tp_name */
Eric Snow96c6af92015-05-29 22:21:39 -06004630 sizeof(_PyDictViewObject), /* tp_basicsize */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004631 0, /* tp_itemsize */
4632 /* methods */
4633 (destructor)dictview_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004634 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004635 0, /* tp_getattr */
4636 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004637 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004638 (reprfunc)dictview_repr, /* tp_repr */
4639 &dictviews_as_number, /* tp_as_number */
4640 &dictitems_as_sequence, /* tp_as_sequence */
4641 0, /* tp_as_mapping */
4642 0, /* tp_hash */
4643 0, /* tp_call */
4644 0, /* tp_str */
4645 PyObject_GenericGetAttr, /* tp_getattro */
4646 0, /* tp_setattro */
4647 0, /* tp_as_buffer */
4648 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
4649 0, /* tp_doc */
4650 (traverseproc)dictview_traverse, /* tp_traverse */
4651 0, /* tp_clear */
4652 dictview_richcompare, /* tp_richcompare */
4653 0, /* tp_weaklistoffset */
4654 (getiterfunc)dictitems_iter, /* tp_iter */
4655 0, /* tp_iternext */
4656 dictitems_methods, /* tp_methods */
4657 0,
Guido van Rossumb90c8482007-02-10 01:11:45 +00004658};
4659
4660static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304661dictitems_new(PyObject *dict, PyObject *Py_UNUSED(ignored))
Guido van Rossumb90c8482007-02-10 01:11:45 +00004662{
Eric Snow96c6af92015-05-29 22:21:39 -06004663 return _PyDictView_New(dict, &PyDictItems_Type);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004664}
4665
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004666static PyObject *
4667dictitems_reversed(_PyDictViewObject *dv)
4668{
4669 if (dv->dv_dict == NULL) {
4670 Py_RETURN_NONE;
4671 }
4672 return dictiter_new(dv->dv_dict, &PyDictRevIterItem_Type);
4673}
4674
Guido van Rossum3ac67412007-02-10 18:55:06 +00004675/*** dict_values ***/
Guido van Rossumb90c8482007-02-10 01:11:45 +00004676
4677static PyObject *
Eric Snow96c6af92015-05-29 22:21:39 -06004678dictvalues_iter(_PyDictViewObject *dv)
Guido van Rossumb90c8482007-02-10 01:11:45 +00004679{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004680 if (dv->dv_dict == NULL) {
4681 Py_RETURN_NONE;
4682 }
4683 return dictiter_new(dv->dv_dict, &PyDictIterValue_Type);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004684}
4685
Guido van Rossum83825ac2007-02-10 04:54:19 +00004686static PySequenceMethods dictvalues_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004687 (lenfunc)dictview_len, /* sq_length */
4688 0, /* sq_concat */
4689 0, /* sq_repeat */
4690 0, /* sq_item */
4691 0, /* sq_slice */
4692 0, /* sq_ass_item */
4693 0, /* sq_ass_slice */
4694 (objobjproc)0, /* sq_contains */
Guido van Rossum83825ac2007-02-10 04:54:19 +00004695};
4696
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004697static PyObject* dictvalues_reversed(_PyDictViewObject *dv);
4698
4699PyDoc_STRVAR(reversed_values_doc,
4700"Return a reverse iterator over the dict values.");
4701
Guido van Rossumb90c8482007-02-10 01:11:45 +00004702static PyMethodDef dictvalues_methods[] = {
Serhiy Storchaka62be7422018-11-27 13:27:31 +02004703 {"__reversed__", (PyCFunction)(void(*)(void))dictvalues_reversed, METH_NOARGS,
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004704 reversed_values_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004705 {NULL, NULL} /* sentinel */
Guido van Rossumb90c8482007-02-10 01:11:45 +00004706};
4707
4708PyTypeObject PyDictValues_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004709 PyVarObject_HEAD_INIT(&PyType_Type, 0)
4710 "dict_values", /* tp_name */
Eric Snow96c6af92015-05-29 22:21:39 -06004711 sizeof(_PyDictViewObject), /* tp_basicsize */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004712 0, /* tp_itemsize */
4713 /* methods */
4714 (destructor)dictview_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004715 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004716 0, /* tp_getattr */
4717 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02004718 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004719 (reprfunc)dictview_repr, /* tp_repr */
4720 0, /* tp_as_number */
4721 &dictvalues_as_sequence, /* tp_as_sequence */
4722 0, /* tp_as_mapping */
4723 0, /* tp_hash */
4724 0, /* tp_call */
4725 0, /* tp_str */
4726 PyObject_GenericGetAttr, /* tp_getattro */
4727 0, /* tp_setattro */
4728 0, /* tp_as_buffer */
4729 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
4730 0, /* tp_doc */
4731 (traverseproc)dictview_traverse, /* tp_traverse */
4732 0, /* tp_clear */
4733 0, /* tp_richcompare */
4734 0, /* tp_weaklistoffset */
4735 (getiterfunc)dictvalues_iter, /* tp_iter */
4736 0, /* tp_iternext */
4737 dictvalues_methods, /* tp_methods */
4738 0,
Guido van Rossumb90c8482007-02-10 01:11:45 +00004739};
4740
4741static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05304742dictvalues_new(PyObject *dict, PyObject *Py_UNUSED(ignored))
Guido van Rossumb90c8482007-02-10 01:11:45 +00004743{
Eric Snow96c6af92015-05-29 22:21:39 -06004744 return _PyDictView_New(dict, &PyDictValues_Type);
Guido van Rossumb90c8482007-02-10 01:11:45 +00004745}
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004746
Rémi Lapeyre6531bf62018-11-06 01:38:54 +01004747static PyObject *
4748dictvalues_reversed(_PyDictViewObject *dv)
4749{
4750 if (dv->dv_dict == NULL) {
4751 Py_RETURN_NONE;
4752 }
4753 return dictiter_new(dv->dv_dict, &PyDictRevIterValue_Type);
4754}
4755
4756
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004757/* Returns NULL if cannot allocate a new PyDictKeysObject,
4758 but does not set an error */
4759PyDictKeysObject *
4760_PyDict_NewKeysForClass(void)
4761{
Victor Stinner742da042016-09-07 17:40:12 -07004762 PyDictKeysObject *keys = new_keys_object(PyDict_MINSIZE);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004763 if (keys == NULL)
4764 PyErr_Clear();
4765 else
4766 keys->dk_lookup = lookdict_split;
4767 return keys;
4768}
4769
4770#define CACHED_KEYS(tp) (((PyHeapTypeObject*)tp)->ht_cached_keys)
4771
4772PyObject *
4773PyObject_GenericGetDict(PyObject *obj, void *context)
4774{
4775 PyObject *dict, **dictptr = _PyObject_GetDictPtr(obj);
4776 if (dictptr == NULL) {
4777 PyErr_SetString(PyExc_AttributeError,
4778 "This object has no __dict__");
4779 return NULL;
4780 }
4781 dict = *dictptr;
4782 if (dict == NULL) {
4783 PyTypeObject *tp = Py_TYPE(obj);
4784 if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && CACHED_KEYS(tp)) {
INADA Naokia7576492018-11-14 18:39:27 +09004785 dictkeys_incref(CACHED_KEYS(tp));
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004786 *dictptr = dict = new_dict_with_shared_keys(CACHED_KEYS(tp));
4787 }
4788 else {
4789 *dictptr = dict = PyDict_New();
4790 }
4791 }
4792 Py_XINCREF(dict);
4793 return dict;
4794}
4795
4796int
4797_PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
Victor Stinner742da042016-09-07 17:40:12 -07004798 PyObject *key, PyObject *value)
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004799{
4800 PyObject *dict;
4801 int res;
4802 PyDictKeysObject *cached;
4803
4804 assert(dictptr != NULL);
4805 if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && (cached = CACHED_KEYS(tp))) {
4806 assert(dictptr != NULL);
4807 dict = *dictptr;
4808 if (dict == NULL) {
INADA Naokia7576492018-11-14 18:39:27 +09004809 dictkeys_incref(cached);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004810 dict = new_dict_with_shared_keys(cached);
4811 if (dict == NULL)
4812 return -1;
4813 *dictptr = dict;
4814 }
4815 if (value == NULL) {
4816 res = PyDict_DelItem(dict, key);
INADA Naoki2294f3a2017-02-12 13:51:30 +09004817 // Since key sharing dict doesn't allow deletion, PyDict_DelItem()
4818 // always converts dict to combined form.
4819 if ((cached = CACHED_KEYS(tp)) != NULL) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004820 CACHED_KEYS(tp) = NULL;
INADA Naokia7576492018-11-14 18:39:27 +09004821 dictkeys_decref(cached);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004822 }
Victor Stinner3d3f2642016-12-15 17:21:23 +01004823 }
4824 else {
INADA Naoki2294f3a2017-02-12 13:51:30 +09004825 int was_shared = (cached == ((PyDictObject *)dict)->ma_keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004826 res = PyDict_SetItem(dict, key, value);
INADA Naoki2294f3a2017-02-12 13:51:30 +09004827 if (was_shared &&
4828 (cached = CACHED_KEYS(tp)) != NULL &&
4829 cached != ((PyDictObject *)dict)->ma_keys) {
Victor Stinner3d3f2642016-12-15 17:21:23 +01004830 /* PyDict_SetItem() may call dictresize and convert split table
4831 * into combined table. In such case, convert it to split
4832 * table again and update type's shared key only when this is
4833 * the only dict sharing key with the type.
4834 *
4835 * This is to allow using shared key in class like this:
4836 *
4837 * class C:
4838 * def __init__(self):
4839 * # one dict resize happens
4840 * self.a, self.b, self.c = 1, 2, 3
4841 * self.d, self.e, self.f = 4, 5, 6
4842 * a = C()
4843 */
Benjamin Peterson15ee8212012-04-24 14:44:18 -04004844 if (cached->dk_refcnt == 1) {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004845 CACHED_KEYS(tp) = make_keys_shared(dict);
Victor Stinner742da042016-09-07 17:40:12 -07004846 }
4847 else {
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004848 CACHED_KEYS(tp) = NULL;
4849 }
INADA Naokia7576492018-11-14 18:39:27 +09004850 dictkeys_decref(cached);
Benjamin Peterson15ee8212012-04-24 14:44:18 -04004851 if (CACHED_KEYS(tp) == NULL && PyErr_Occurred())
4852 return -1;
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004853 }
4854 }
4855 } else {
4856 dict = *dictptr;
4857 if (dict == NULL) {
4858 dict = PyDict_New();
4859 if (dict == NULL)
4860 return -1;
4861 *dictptr = dict;
4862 }
4863 if (value == NULL) {
4864 res = PyDict_DelItem(dict, key);
4865 } else {
4866 res = PyDict_SetItem(dict, key, value);
4867 }
4868 }
4869 return res;
4870}
4871
4872void
4873_PyDictKeys_DecRef(PyDictKeysObject *keys)
4874{
INADA Naokia7576492018-11-14 18:39:27 +09004875 dictkeys_decref(keys);
Benjamin Peterson7d95e402012-04-23 11:24:50 -04004876}