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