blob: 676ed99078cea38e11255047a2d2597b98e49e88 [file] [log] [blame]
Eric Snow96c6af92015-05-29 22:21:39 -06001/* Ordered Dictionary object implementation.
2
3This implementation is necessarily explicitly equivalent to the pure Python
4OrderedDict class in Lib/collections/__init__.py. The strategy there
5involves using a doubly-linked-list to capture the order. We keep to that
6strategy, using a lower-level linked-list.
7
8About the Linked-List
9=====================
10
11For the linked list we use a basic doubly-linked-list. Using a circularly-
12linked-list does have some benefits, but they don't apply so much here
13since OrderedDict is focused on the ends of the list (for the most part).
14Furthermore, there are some features of generic linked-lists that we simply
15don't need for OrderedDict. Thus a simple custom implementation meets our
16needs. Alternatives to our simple approach include the QCIRCLE_*
17macros from BSD's queue.h, and the linux's list.h.
18
19Getting O(1) Node Lookup
20------------------------
21
22One invariant of Python's OrderedDict is that it preserves time complexity
23of dict's methods, particularly the O(1) operations. Simply adding a
24linked-list on top of dict is not sufficient here; operations for nodes in
25the middle of the linked-list implicitly require finding the node first.
26With a simple linked-list like we're using, that is an O(n) operation.
27Consequently, methods like __delitem__() would change from O(1) to O(n),
28which is unacceptable.
29
30In order to preserve O(1) performance for node removal (finding nodes), we
31must do better than just looping through the linked-list. Here are options
32we've considered:
33
341. use a second dict to map keys to nodes (a la the pure Python version).
352. keep a simple hash table mirroring the order of dict's, mapping each key
36 to the corresponding node in the linked-list.
373. use a version of shared keys (split dict) that allows non-unicode keys.
384. have the value stored for each key be a (value, node) pair, and adjust
39 __getitem__(), get(), etc. accordingly.
40
41The approach with the least performance impact (time and space) is #2,
Benjamin Petersonee178e62016-09-08 11:08:30 -070042mirroring the key order of dict's dk_entries with an array of node pointers.
Eric Snow96c6af92015-05-29 22:21:39 -060043While lookdict() and friends (dk_lookup) don't give us the index into the
44array, we make use of pointer arithmetic to get that index. An alternative
45would be to refactor lookdict() to provide the index, explicitly exposing
46the implementation detail. We could even just use a custom lookup function
47for OrderedDict that facilitates our need. However, both approaches are
48significantly more complicated than just using pointer arithmetic.
49
50The catch with mirroring the hash table ordering is that we have to keep
51the ordering in sync through any dict resizes. However, that order only
52matters during node lookup. We can simply defer any potential resizing
53until we need to do a lookup.
54
55Linked-List Nodes
56-----------------
57
58The current implementation stores a pointer to the associated key only.
59One alternative would be to store a pointer to the PyDictKeyEntry instead.
60This would save one pointer de-reference per item, which is nice during
61calls to values() and items(). However, it adds unnecessary overhead
62otherwise, so we stick with just the key.
63
64Linked-List API
65---------------
66
67As noted, the linked-list implemented here does not have all the bells and
68whistles. However, we recognize that the implementation may need to
69change to accommodate performance improvements or extra functionality. To
Miss Islington (bot)4e9d9b32018-07-06 05:08:51 -070070that end, we use a simple API to interact with the linked-list. Here's a
Eric Snow96c6af92015-05-29 22:21:39 -060071summary of the methods/macros:
72
73Node info:
74
75* _odictnode_KEY(node)
76* _odictnode_VALUE(od, node)
77* _odictnode_PREV(node)
78* _odictnode_NEXT(node)
79
80Linked-List info:
81
82* _odict_FIRST(od)
83* _odict_LAST(od)
84* _odict_EMPTY(od)
85* _odict_FOREACH(od, node) - used in place of `for (node=...)`
86
87For adding nodes:
88
89* _odict_add_head(od, node)
90* _odict_add_tail(od, node)
Serhiy Storchaka19a70e72015-11-13 14:48:36 +020091* _odict_add_new_node(od, key, hash)
Eric Snow96c6af92015-05-29 22:21:39 -060092
93For removing nodes:
94
Serhiy Storchaka19a70e72015-11-13 14:48:36 +020095* _odict_clear_node(od, node, key, hash)
Eric Snow96c6af92015-05-29 22:21:39 -060096* _odict_clear_nodes(od, clear_each)
97
98Others:
99
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200100* _odict_find_node_hash(od, key, hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600101* _odict_find_node(od, key)
102* _odict_keys_equal(od1, od2)
103
Eric Snow96c6af92015-05-29 22:21:39 -0600104And here's a look at how the linked-list relates to the OrderedDict API:
105
106============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
107method key val prev next mem 1st last empty iter find add rmv clr keq
108============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
109__del__ ~ X
110__delitem__ free ~ node
111__eq__ ~ X
112__iter__ X X
113__new__ X X
114__reduce__ X ~ X
115__repr__ X X X
116__reversed__ X X
117__setitem__ key
118__sizeof__ size X
119clear ~ ~ X
120copy X X X
121items X X X
122keys X X
123move_to_end X X X ~ h/t key
124pop free key
125popitem X X free X X node
126setdefault ~ ? ~
127values X X
128============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
129
130__delitem__ is the only method that directly relies on finding an arbitrary
131node in the linked-list. Everything else is iteration or relates to the
132ends of the linked-list.
133
134Situation that Endangers Consistency
135------------------------------------
136Using a raw linked-list for OrderedDict exposes a key situation that can
137cause problems. If a node is stored in a variable, there is a chance that
138the node may have been deallocated before the variable gets used, thus
139potentially leading to a segmentation fault. A key place where this shows
140up is during iteration through the linked list (via _odict_FOREACH or
141otherwise).
142
143A number of solutions are available to resolve this situation:
144
145* defer looking up the node until as late as possible and certainly after
146 any code that could possibly result in a deletion;
147* if the node is needed both before and after a point where the node might
148 be removed, do a check before using the node at the "after" location to
149 see if the node is still valid;
150* like the last one, but simply pull the node again to ensure it's right;
151* keep the key in the variable instead of the node and then look up the
152 node using the key at the point where the node is needed (this is what
153 we do for the iterators).
154
155Another related problem, preserving consistent ordering during iteration,
156is described below. That one is not exclusive to using linked-lists.
157
158
159Challenges from Subclassing dict
160================================
161
162OrderedDict subclasses dict, which is an unusual relationship between two
163builtin types (other than the base object type). Doing so results in
164some complication and deserves further explanation. There are two things
165to consider here. First, in what circumstances or with what adjustments
166can OrderedDict be used as a drop-in replacement for dict (at the C level)?
167Second, how can the OrderedDict implementation leverage the dict
168implementation effectively without introducing unnecessary coupling or
169inefficiencies?
170
171This second point is reflected here and in the implementation, so the
172further focus is on the first point. It is worth noting that for
173overridden methods, the dict implementation is deferred to as much as
174possible. Furthermore, coupling is limited to as little as is reasonable.
175
176Concrete API Compatibility
177--------------------------
178
179Use of the concrete C-API for dict (PyDict_*) with OrderedDict is
180problematic. (See http://bugs.python.org/issue10977.) The concrete API
181has a number of hard-coded assumptions tied to the dict implementation.
182This is, in part, due to performance reasons, which is understandable
183given the part dict plays in Python.
184
185Any attempt to replace dict with OrderedDict for any role in the
186interpreter (e.g. **kwds) faces a challenge. Such any effort must
187recognize that the instances in affected locations currently interact with
188the concrete API.
189
190Here are some ways to address this challenge:
191
1921. Change the relevant usage of the concrete API in CPython and add
Martin Panter69332c12016-08-04 13:07:31 +0000193 PyDict_CheckExact() calls to each of the concrete API functions.
Eric Snow96c6af92015-05-29 22:21:39 -06001942. Adjust the relevant concrete API functions to explicitly accommodate
195 OrderedDict.
1963. As with #1, add the checks, but improve the abstract API with smart fast
197 paths for dict and OrderedDict, and refactor CPython to use the abstract
198 API. Improvements to the abstract API would be valuable regardless.
199
200Adding the checks to the concrete API would help make any interpreter
201switch to OrderedDict less painful for extension modules. However, this
202won't work. The equivalent C API call to `dict.__setitem__(obj, k, v)`
203is 'PyDict_SetItem(obj, k, v)`. This illustrates how subclasses in C call
204the base class's methods, since there is no equivalent of super() in the
205C API. Calling into Python for parent class API would work, but some
206extension modules already rely on this feature of the concrete API.
207
208For reference, here is a breakdown of some of the dict concrete API:
209
210========================== ============= =======================
211concrete API uses abstract API
212========================== ============= =======================
213PyDict_Check PyMapping_Check
214(PyDict_CheckExact) -
215(PyDict_New) -
216(PyDictProxy_New) -
217PyDict_Clear -
218PyDict_Contains PySequence_Contains
219PyDict_Copy -
220PyDict_SetItem PyObject_SetItem
221PyDict_SetItemString PyMapping_SetItemString
222PyDict_DelItem PyMapping_DelItem
223PyDict_DelItemString PyMapping_DelItemString
224PyDict_GetItem -
225PyDict_GetItemWithError PyObject_GetItem
226_PyDict_GetItemIdWithError -
227PyDict_GetItemString PyMapping_GetItemString
228PyDict_Items PyMapping_Items
229PyDict_Keys PyMapping_Keys
230PyDict_Values PyMapping_Values
231PyDict_Size PyMapping_Size
232 PyMapping_Length
233PyDict_Next PyIter_Next
234_PyDict_Next -
235PyDict_Merge -
236PyDict_Update -
237PyDict_MergeFromSeq2 -
238PyDict_ClearFreeList -
239- PyMapping_HasKeyString
240- PyMapping_HasKey
241========================== ============= =======================
242
243
244The dict Interface Relative to OrderedDict
245==========================================
246
247Since OrderedDict subclasses dict, understanding the various methods and
248attributes of dict is important for implementing OrderedDict.
249
250Relevant Type Slots
251-------------------
252
253================= ================ =================== ================
254slot attribute object dict
255================= ================ =================== ================
256tp_dealloc - object_dealloc dict_dealloc
257tp_repr __repr__ object_repr dict_repr
258sq_contains __contains__ - dict_contains
259mp_length __len__ - dict_length
260mp_subscript __getitem__ - dict_subscript
261mp_ass_subscript __setitem__ - dict_ass_sub
262 __delitem__
263tp_hash __hash__ _Py_HashPointer ..._HashNotImpl
264tp_str __str__ object_str -
265tp_getattro __getattribute__ ..._GenericGetAttr (repeated)
266 __getattr__
267tp_setattro __setattr__ ..._GenericSetAttr (disabled)
268tp_doc __doc__ (literal) dictionary_doc
269tp_traverse - - dict_traverse
270tp_clear - - dict_tp_clear
271tp_richcompare __eq__ object_richcompare dict_richcompare
272 __ne__
273tp_weaklistoffset (__weakref__) - -
274tp_iter __iter__ - dict_iter
275tp_dictoffset (__dict__) - -
276tp_init __init__ object_init dict_init
277tp_alloc - PyType_GenericAlloc (repeated)
278tp_new __new__ object_new dict_new
279tp_free - PyObject_Del PyObject_GC_Del
280================= ================ =================== ================
281
282Relevant Methods
283----------------
284
285================ =================== ===============
286method object dict
287================ =================== ===============
288__reduce__ object_reduce -
289__sizeof__ object_sizeof dict_sizeof
290clear - dict_clear
291copy - dict_copy
292fromkeys - dict_fromkeys
293get - dict_get
294items - dictitems_new
295keys - dictkeys_new
296pop - dict_pop
297popitem - dict_popitem
298setdefault - dict_setdefault
299update - dict_update
300values - dictvalues_new
301================ =================== ===============
302
303
304Pure Python OrderedDict
305=======================
306
307As already noted, compatibility with the pure Python OrderedDict
308implementation is a key goal of this C implementation. To further that
309goal, here's a summary of how OrderedDict-specific methods are implemented
310in collections/__init__.py. Also provided is an indication of which
311methods directly mutate or iterate the object, as well as any relationship
312with the underlying linked-list.
313
314============= ============== == ================ === === ====
315method impl used ll uses inq mut iter
316============= ============== == ================ === === ====
317__contains__ dict - - X
318__delitem__ OrderedDict Y dict.__delitem__ X
319__eq__ OrderedDict N OrderedDict ~
320 dict.__eq__
321 __iter__
322__getitem__ dict - - X
323__iter__ OrderedDict Y - X
324__init__ OrderedDict N update
325__len__ dict - - X
326__ne__ MutableMapping - __eq__ ~
327__reduce__ OrderedDict N OrderedDict ~
328 __iter__
329 __getitem__
330__repr__ OrderedDict N __class__ ~
331 items
332__reversed__ OrderedDict Y - X
333__setitem__ OrderedDict Y __contains__ X
334 dict.__setitem__
335__sizeof__ OrderedDict Y __len__ ~
336 __dict__
337clear OrderedDict Y dict.clear X
338copy OrderedDict N __class__
339 __init__
340fromkeys OrderedDict N __setitem__
341get dict - - ~
342items MutableMapping - ItemsView X
343keys MutableMapping - KeysView X
344move_to_end OrderedDict Y - X
345pop OrderedDict N __contains__ X
346 __getitem__
347 __delitem__
348popitem OrderedDict Y dict.pop X
349setdefault OrderedDict N __contains__ ~
350 __getitem__
351 __setitem__
352update MutableMapping - __setitem__ ~
353values MutableMapping - ValuesView X
354============= ============== == ================ === === ====
355
356__reversed__ and move_to_end are both exclusive to OrderedDict.
357
358
359C OrderedDict Implementation
360============================
361
362================= ================
363slot impl
364================= ================
365tp_dealloc odict_dealloc
366tp_repr odict_repr
367mp_ass_subscript odict_ass_sub
368tp_doc odict_doc
369tp_traverse odict_traverse
370tp_clear odict_tp_clear
371tp_richcompare odict_richcompare
372tp_weaklistoffset (offset)
373tp_iter odict_iter
374tp_dictoffset (offset)
375tp_init odict_init
376tp_alloc (repeated)
Eric Snow96c6af92015-05-29 22:21:39 -0600377================= ================
378
379================= ================
380method impl
381================= ================
382__reduce__ odict_reduce
383__sizeof__ odict_sizeof
384clear odict_clear
385copy odict_copy
386fromkeys odict_fromkeys
387items odictitems_new
388keys odictkeys_new
389pop odict_pop
390popitem odict_popitem
391setdefault odict_setdefault
392update odict_update
393values odictvalues_new
394================= ================
395
396Inherited unchanged from object/dict:
397
398================ ==========================
399method type field
400================ ==========================
401- tp_free
402__contains__ tp_as_sequence.sq_contains
403__getattr__ tp_getattro
404__getattribute__ tp_getattro
405__getitem__ tp_as_mapping.mp_subscript
406__hash__ tp_hash
407__len__ tp_as_mapping.mp_length
408__setattr__ tp_setattro
409__str__ tp_str
410get -
411================ ==========================
412
413
414Other Challenges
415================
416
417Preserving Ordering During Iteration
418------------------------------------
419During iteration through an OrderedDict, it is possible that items could
420get added, removed, or reordered. For a linked-list implementation, as
421with some other implementations, that situation may lead to undefined
422behavior. The documentation for dict mentions this in the `iter()` section
423of http://docs.python.org/3.4/library/stdtypes.html#dictionary-view-objects.
424In this implementation we follow dict's lead (as does the pure Python
425implementation) for __iter__(), keys(), values(), and items().
426
427For internal iteration (using _odict_FOREACH or not), there is still the
428risk that not all nodes that we expect to be seen in the loop actually get
429seen. Thus, we are careful in each of those places to ensure that they
430are. This comes, of course, at a small price at each location. The
431solutions are much the same as those detailed in the `Situation that
432Endangers Consistency` section above.
433
434
435Potential Optimizations
436=======================
437
438* Allocate the nodes as a block via od_fast_nodes instead of individually.
439 - Set node->key to NULL to indicate the node is not-in-use.
440 - Add _odict_EXISTS()?
441 - How to maintain consistency across resizes? Existing node pointers
Miss Islington (bot)4e9d9b32018-07-06 05:08:51 -0700442 would be invalidated after a resize, which is particularly problematic
Eric Snow96c6af92015-05-29 22:21:39 -0600443 for the iterators.
444* Use a more stream-lined implementation of update() and, likely indirectly,
445 __init__().
446
447*/
448
449/* TODO
450
451sooner:
452- reentrancy (make sure everything is at a thread-safe state when calling
453 into Python). I've already checked this multiple times, but want to
454 make one more pass.
455- add unit tests for reentrancy?
456
457later:
458- make the dict views support the full set API (the pure Python impl does)
459- implement a fuller MutableMapping API in C?
460- move the MutableMapping implementation to abstract.c?
461- optimize mutablemapping_update
462- use PyObject_MALLOC (small object allocator) for odict nodes?
463- support subclasses better (e.g. in odict_richcompare)
464
465*/
466
467#include "Python.h"
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600468#include "internal/pystate.h"
Eric Snow96c6af92015-05-29 22:21:39 -0600469#include "structmember.h"
470#include "dict-common.h"
471#include <stddef.h>
472
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100473#include "clinic/odictobject.c.h"
474
475/*[clinic input]
476class OrderedDict "PyODictObject *" "&PyODict_Type"
477[clinic start generated code]*/
478/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ca0641cf6143d4af]*/
479
Eric Snow96c6af92015-05-29 22:21:39 -0600480
481typedef struct _odictnode _ODictNode;
482
483/* PyODictObject */
484struct _odictobject {
Eric Snow4fabf022015-06-04 00:09:56 -0600485 PyDictObject od_dict; /* the underlying dict */
486 _ODictNode *od_first; /* first node in the linked list, if any */
487 _ODictNode *od_last; /* last node in the linked list, if any */
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200488 /* od_fast_nodes, od_fast_nodes_size and od_resize_sentinel are managed
489 * by _odict_resize().
Eric Snow8c7f9552015-08-07 17:45:12 -0600490 * Note that we rely on implementation details of dict for both. */
491 _ODictNode **od_fast_nodes; /* hash table that mirrors the dict table */
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200492 Py_ssize_t od_fast_nodes_size;
493 void *od_resize_sentinel; /* changes if odict should be resized */
Eric Snow8c7f9552015-08-07 17:45:12 -0600494
Eric Snow4fabf022015-06-04 00:09:56 -0600495 size_t od_state; /* incremented whenever the LL changes */
496 PyObject *od_inst_dict; /* OrderedDict().__dict__ */
497 PyObject *od_weakreflist; /* holds weakrefs to the odict */
Eric Snow96c6af92015-05-29 22:21:39 -0600498};
499
500
501/* ----------------------------------------------
502 * odict keys (a simple doubly-linked list)
503 */
504
505struct _odictnode {
506 PyObject *key;
Eric Snow4c729182015-06-03 10:50:37 -0600507 Py_hash_t hash;
Eric Snow96c6af92015-05-29 22:21:39 -0600508 _ODictNode *next;
509 _ODictNode *prev;
510};
511
512#define _odictnode_KEY(node) \
513 (node->key)
Eric Snow4c729182015-06-03 10:50:37 -0600514#define _odictnode_HASH(node) \
515 (node->hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600516/* borrowed reference */
517#define _odictnode_VALUE(node, od) \
Eric Snowa762af72015-06-01 22:59:08 -0600518 PyODict_GetItemWithError((PyObject *)od, _odictnode_KEY(node))
Eric Snow96c6af92015-05-29 22:21:39 -0600519#define _odictnode_PREV(node) (node->prev)
520#define _odictnode_NEXT(node) (node->next)
521
522#define _odict_FIRST(od) (((PyODictObject *)od)->od_first)
523#define _odict_LAST(od) (((PyODictObject *)od)->od_last)
524#define _odict_EMPTY(od) (_odict_FIRST(od) == NULL)
525#define _odict_FOREACH(od, node) \
526 for (node = _odict_FIRST(od); node != NULL; node = _odictnode_NEXT(node))
527
Eric Snow4c729182015-06-03 10:50:37 -0600528/* Return the index into the hash table, regardless of a valid node. */
529static Py_ssize_t
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200530_odict_get_index_raw(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow4c729182015-06-03 10:50:37 -0600531{
INADA Naokiba609772016-12-07 20:41:42 +0900532 PyObject *value = NULL;
Eric Snow4c729182015-06-03 10:50:37 -0600533 PyDictKeysObject *keys = ((PyDictObject *)od)->ma_keys;
Victor Stinner742da042016-09-07 17:40:12 -0700534 Py_ssize_t ix;
Eric Snow4c729182015-06-03 10:50:37 -0600535
INADA Naoki778928b2017-08-03 23:45:15 +0900536 ix = (keys->dk_lookup)((PyDictObject *)od, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -0700537 if (ix == DKIX_EMPTY) {
538 return keys->dk_nentries; /* index of new entry */
539 }
540 if (ix < 0)
Eric Snow4c729182015-06-03 10:50:37 -0600541 return -1;
542 /* We use pointer arithmetic to get the entry's index into the table. */
Victor Stinner742da042016-09-07 17:40:12 -0700543 return ix;
Eric Snow4c729182015-06-03 10:50:37 -0600544}
545
546/* Replace od->od_fast_nodes with a new table matching the size of dict's. */
Eric Snow96c6af92015-05-29 22:21:39 -0600547static int
Serhiy Storchaka861d34e2018-10-20 11:24:05 +0300548_odict_resize(PyODictObject *od)
549{
Eric Snow4c729182015-06-03 10:50:37 -0600550 Py_ssize_t size, i;
Eric Snow96c6af92015-05-29 22:21:39 -0600551 _ODictNode **fast_nodes, *node;
552
553 /* Initialize a new "fast nodes" table. */
554 size = ((PyDictObject *)od)->ma_keys->dk_size;
555 fast_nodes = PyMem_NEW(_ODictNode *, size);
556 if (fast_nodes == NULL) {
557 PyErr_NoMemory();
558 return -1;
559 }
560 for (i = 0; i < size; i++)
561 fast_nodes[i] = NULL;
562
563 /* Copy the current nodes into the table. */
Eric Snow96c6af92015-05-29 22:21:39 -0600564 _odict_FOREACH(od, node) {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200565 i = _odict_get_index_raw(od, _odictnode_KEY(node),
Victor Stinner742da042016-09-07 17:40:12 -0700566 _odictnode_HASH(node));
Eric Snow96c6af92015-05-29 22:21:39 -0600567 if (i < 0) {
Eric Snow96c6af92015-05-29 22:21:39 -0600568 PyMem_FREE(fast_nodes);
569 return -1;
570 }
571 fast_nodes[i] = node;
572 }
Eric Snow96c6af92015-05-29 22:21:39 -0600573
574 /* Replace the old fast nodes table. */
Serhiy Storchaka861d34e2018-10-20 11:24:05 +0300575 PyMem_FREE(od->od_fast_nodes);
Eric Snow96c6af92015-05-29 22:21:39 -0600576 od->od_fast_nodes = fast_nodes;
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200577 od->od_fast_nodes_size = size;
578 od->od_resize_sentinel = ((PyDictObject *)od)->ma_keys;
Eric Snow96c6af92015-05-29 22:21:39 -0600579 return 0;
580}
581
582/* Return the index into the hash table, regardless of a valid node. */
583static Py_ssize_t
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200584_odict_get_index(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600585{
Eric Snow4c729182015-06-03 10:50:37 -0600586 PyDictKeysObject *keys;
Eric Snow96c6af92015-05-29 22:21:39 -0600587
588 assert(key != NULL);
Eric Snow4c729182015-06-03 10:50:37 -0600589 keys = ((PyDictObject *)od)->ma_keys;
590
591 /* Ensure od_fast_nodes and dk_entries are in sync. */
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200592 if (od->od_resize_sentinel != keys ||
593 od->od_fast_nodes_size != keys->dk_size) {
Eric Snow4c729182015-06-03 10:50:37 -0600594 int resize_res = _odict_resize(od);
595 if (resize_res < 0)
596 return -1;
597 }
598
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200599 return _odict_get_index_raw(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600600}
601
Eric Snow96c6af92015-05-29 22:21:39 -0600602/* Returns NULL if there was some error or the key was not found. */
603static _ODictNode *
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200604_odict_find_node_hash(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600605{
606 Py_ssize_t index;
607
608 if (_odict_EMPTY(od))
609 return NULL;
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200610 index = _odict_get_index(od, key, hash);
611 if (index < 0)
612 return NULL;
Serhiy Storchaka861d34e2018-10-20 11:24:05 +0300613 assert(od->od_fast_nodes != NULL);
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200614 return od->od_fast_nodes[index];
615}
616
617static _ODictNode *
618_odict_find_node(PyODictObject *od, PyObject *key)
619{
620 Py_ssize_t index;
621 Py_hash_t hash;
622
623 if (_odict_EMPTY(od))
624 return NULL;
625 hash = PyObject_Hash(key);
626 if (hash == -1)
627 return NULL;
628 index = _odict_get_index(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600629 if (index < 0)
630 return NULL;
Serhiy Storchaka861d34e2018-10-20 11:24:05 +0300631 assert(od->od_fast_nodes != NULL);
Eric Snow96c6af92015-05-29 22:21:39 -0600632 return od->od_fast_nodes[index];
633}
634
635static void
636_odict_add_head(PyODictObject *od, _ODictNode *node)
637{
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300638 _odictnode_PREV(node) = NULL;
639 _odictnode_NEXT(node) = _odict_FIRST(od);
640 if (_odict_FIRST(od) == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -0600641 _odict_LAST(od) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300642 else
Eric Snow96c6af92015-05-29 22:21:39 -0600643 _odictnode_PREV(_odict_FIRST(od)) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300644 _odict_FIRST(od) = node;
Eric Snow4fabf022015-06-04 00:09:56 -0600645 od->od_state++;
Eric Snow96c6af92015-05-29 22:21:39 -0600646}
647
648static void
649_odict_add_tail(PyODictObject *od, _ODictNode *node)
650{
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300651 _odictnode_PREV(node) = _odict_LAST(od);
652 _odictnode_NEXT(node) = NULL;
653 if (_odict_LAST(od) == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -0600654 _odict_FIRST(od) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300655 else
Eric Snow96c6af92015-05-29 22:21:39 -0600656 _odictnode_NEXT(_odict_LAST(od)) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300657 _odict_LAST(od) = node;
Eric Snow4fabf022015-06-04 00:09:56 -0600658 od->od_state++;
Eric Snow96c6af92015-05-29 22:21:39 -0600659}
660
661/* adds the node to the end of the list */
662static int
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200663_odict_add_new_node(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600664{
665 Py_ssize_t i;
666 _ODictNode *node;
667
Serhiy Storchakad17427b2015-10-20 18:21:48 +0300668 Py_INCREF(key);
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200669 i = _odict_get_index(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600670 if (i < 0) {
671 if (!PyErr_Occurred())
672 PyErr_SetObject(PyExc_KeyError, key);
673 Py_DECREF(key);
674 return -1;
675 }
Serhiy Storchaka861d34e2018-10-20 11:24:05 +0300676 assert(od->od_fast_nodes != NULL);
677 if (od->od_fast_nodes[i] != NULL) {
Eric Snow96c6af92015-05-29 22:21:39 -0600678 /* We already have a node for the key so there's no need to add one. */
679 Py_DECREF(key);
680 return 0;
681 }
682
683 /* must not be added yet */
684 node = (_ODictNode *)PyMem_MALLOC(sizeof(_ODictNode));
685 if (node == NULL) {
686 Py_DECREF(key);
687 PyErr_NoMemory();
688 return -1;
689 }
690
691 _odictnode_KEY(node) = key;
Eric Snow4c729182015-06-03 10:50:37 -0600692 _odictnode_HASH(node) = hash;
Eric Snow96c6af92015-05-29 22:21:39 -0600693 _odict_add_tail(od, node);
694 od->od_fast_nodes[i] = node;
695 return 0;
696}
697
698/* Putting the decref after the free causes problems. */
699#define _odictnode_DEALLOC(node) \
700 do { \
701 Py_DECREF(_odictnode_KEY(node)); \
702 PyMem_FREE((void *)node); \
703 } while (0)
704
705/* Repeated calls on the same node are no-ops. */
706static void
707_odict_remove_node(PyODictObject *od, _ODictNode *node)
708{
709 if (_odict_FIRST(od) == node)
710 _odict_FIRST(od) = _odictnode_NEXT(node);
711 else if (_odictnode_PREV(node) != NULL)
712 _odictnode_NEXT(_odictnode_PREV(node)) = _odictnode_NEXT(node);
713
714 if (_odict_LAST(od) == node)
715 _odict_LAST(od) = _odictnode_PREV(node);
716 else if (_odictnode_NEXT(node) != NULL)
717 _odictnode_PREV(_odictnode_NEXT(node)) = _odictnode_PREV(node);
718
719 _odictnode_PREV(node) = NULL;
720 _odictnode_NEXT(node) = NULL;
Eric Snow4fabf022015-06-04 00:09:56 -0600721 od->od_state++;
Eric Snow96c6af92015-05-29 22:21:39 -0600722}
723
Eric Snow96c6af92015-05-29 22:21:39 -0600724/* If someone calls PyDict_DelItem() directly on an OrderedDict, we'll
725 get all sorts of problems here. In PyODict_DelItem we make sure to
726 call _odict_clear_node first.
Victor Stinnerca30b022015-09-03 17:50:04 +0200727
Eric Snow96c6af92015-05-29 22:21:39 -0600728 This matters in the case of colliding keys. Suppose we add 3 keys:
729 [A, B, C], where the hash of C collides with A and the next possible
730 index in the hash table is occupied by B. If we remove B then for C
731 the dict's looknode func will give us the old index of B instead of
732 the index we got before deleting B. However, the node for C in
733 od_fast_nodes is still at the old dict index of C. Thus to be sure
734 things don't get out of sync, we clear the node in od_fast_nodes
735 *before* calling PyDict_DelItem.
736
737 The same must be done for any other OrderedDict operations where
738 we modify od_fast_nodes.
739*/
740static int
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200741_odict_clear_node(PyODictObject *od, _ODictNode *node, PyObject *key,
742 Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600743{
744 Py_ssize_t i;
745
746 assert(key != NULL);
747 if (_odict_EMPTY(od)) {
748 /* Let later code decide if this is a KeyError. */
749 return 0;
750 }
751
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200752 i = _odict_get_index(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600753 if (i < 0)
754 return PyErr_Occurred() ? -1 : 0;
755
Serhiy Storchaka861d34e2018-10-20 11:24:05 +0300756 assert(od->od_fast_nodes != NULL);
Eric Snow96c6af92015-05-29 22:21:39 -0600757 if (node == NULL)
758 node = od->od_fast_nodes[i];
759 assert(node == od->od_fast_nodes[i]);
760 if (node == NULL) {
761 /* Let later code decide if this is a KeyError. */
762 return 0;
763 }
764
765 // Now clear the node.
766 od->od_fast_nodes[i] = NULL;
767 _odict_remove_node(od, node);
768 _odictnode_DEALLOC(node);
769 return 0;
770}
771
772static void
773_odict_clear_nodes(PyODictObject *od)
774{
775 _ODictNode *node, *next;
776
Serhiy Storchaka861d34e2018-10-20 11:24:05 +0300777 PyMem_FREE(od->od_fast_nodes);
Eric Snow96c6af92015-05-29 22:21:39 -0600778 od->od_fast_nodes = NULL;
Serhiy Storchaka861d34e2018-10-20 11:24:05 +0300779 od->od_fast_nodes_size = 0;
780 od->od_resize_sentinel = NULL;
Serhiy Storchakad205d012016-01-19 14:46:25 +0200781
782 node = _odict_FIRST(od);
783 _odict_FIRST(od) = NULL;
784 _odict_LAST(od) = NULL;
785 while (node != NULL) {
786 next = _odictnode_NEXT(node);
787 _odictnode_DEALLOC(node);
788 node = next;
789 }
Eric Snow96c6af92015-05-29 22:21:39 -0600790}
791
792/* There isn't any memory management of nodes past this point. */
793#undef _odictnode_DEALLOC
794
795static int
796_odict_keys_equal(PyODictObject *a, PyODictObject *b)
797{
798 _ODictNode *node_a, *node_b;
799
800 node_a = _odict_FIRST(a);
801 node_b = _odict_FIRST(b);
802 while (1) {
803 if (node_a == NULL && node_b == NULL)
804 /* success: hit the end of each at the same time */
805 return 1;
806 else if (node_a == NULL || node_b == NULL)
807 /* unequal length */
808 return 0;
809 else {
810 int res = PyObject_RichCompareBool(
811 (PyObject *)_odictnode_KEY(node_a),
812 (PyObject *)_odictnode_KEY(node_b),
813 Py_EQ);
814 if (res < 0)
815 return res;
816 else if (res == 0)
817 return 0;
818
819 /* otherwise it must match, so move on to the next one */
820 node_a = _odictnode_NEXT(node_a);
821 node_b = _odictnode_NEXT(node_b);
822 }
823 }
824}
825
826
827/* ----------------------------------------------
828 * OrderedDict mapping methods
829 */
830
831/* mp_ass_subscript: __setitem__() and __delitem__() */
832
833static int
834odict_mp_ass_sub(PyODictObject *od, PyObject *v, PyObject *w)
835{
836 if (w == NULL)
837 return PyODict_DelItem((PyObject *)od, v);
838 else
839 return PyODict_SetItem((PyObject *)od, v, w);
840}
841
842/* tp_as_mapping */
843
844static PyMappingMethods odict_as_mapping = {
845 0, /*mp_length*/
846 0, /*mp_subscript*/
847 (objobjargproc)odict_mp_ass_sub, /*mp_ass_subscript*/
848};
849
850
851/* ----------------------------------------------
852 * OrderedDict methods
853 */
854
Eric Snow96c6af92015-05-29 22:21:39 -0600855/* fromkeys() */
856
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100857/*[clinic input]
858@classmethod
859OrderedDict.fromkeys
860
861 iterable as seq: object
862 value: object = None
863
Serhiy Storchaka78d9e582017-01-25 00:30:04 +0200864Create a new ordered dictionary with keys from iterable and values set to value.
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100865[clinic start generated code]*/
Eric Snow96c6af92015-05-29 22:21:39 -0600866
867static PyObject *
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100868OrderedDict_fromkeys_impl(PyTypeObject *type, PyObject *seq, PyObject *value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +0200869/*[clinic end generated code: output=c10390d452d78d6d input=1a0476c229c597b3]*/
Eric Snow96c6af92015-05-29 22:21:39 -0600870{
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100871 return _PyDict_FromKeys((PyObject *)type, seq, value);
Eric Snow96c6af92015-05-29 22:21:39 -0600872}
873
874/* __sizeof__() */
875
876/* OrderedDict.__sizeof__() does not have a docstring. */
877PyDoc_STRVAR(odict_sizeof__doc__, "");
878
879static PyObject *
880odict_sizeof(PyODictObject *od)
881{
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +0200882 Py_ssize_t res = _PyDict_SizeOf((PyDictObject *)od);
Serhiy Storchaka861d34e2018-10-20 11:24:05 +0300883 res += sizeof(_ODictNode *) * od->od_fast_nodes_size; /* od_fast_nodes */
Eric Snow96c6af92015-05-29 22:21:39 -0600884 if (!_odict_EMPTY(od)) {
885 res += sizeof(_ODictNode) * PyODict_SIZE(od); /* linked-list */
886 }
887 return PyLong_FromSsize_t(res);
888}
889
890/* __reduce__() */
891
892PyDoc_STRVAR(odict_reduce__doc__, "Return state information for pickling");
893
894static PyObject *
895odict_reduce(register PyODictObject *od)
896{
897 _Py_IDENTIFIER(__dict__);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300898 _Py_IDENTIFIER(items);
Serhiy Storchaka4575beb2015-10-22 20:18:24 +0300899 PyObject *dict = NULL, *result = NULL;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300900 PyObject *items_iter, *items, *args = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -0600901
902 /* capture any instance state */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300903 dict = _PyObject_GetAttrId((PyObject *)od, &PyId___dict__);
904 if (dict == NULL)
Eric Snowc5e59602015-05-30 11:28:56 -0600905 goto Done;
906 else {
Eric Snow96c6af92015-05-29 22:21:39 -0600907 /* od.__dict__ isn't necessarily a dict... */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300908 Py_ssize_t dict_len = PyObject_Length(dict);
909 if (dict_len == -1)
Eric Snow96c6af92015-05-29 22:21:39 -0600910 goto Done;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300911 if (!dict_len) {
912 /* nothing to pickle in od.__dict__ */
913 Py_CLEAR(dict);
Eric Snow96c6af92015-05-29 22:21:39 -0600914 }
915 }
916
917 /* build the result */
Eric Snow96c6af92015-05-29 22:21:39 -0600918 args = PyTuple_New(0);
919 if (args == NULL)
920 goto Done;
921
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300922 items = _PyObject_CallMethodIdObjArgs((PyObject *)od, &PyId_items, NULL);
Eric Snow96c6af92015-05-29 22:21:39 -0600923 if (items == NULL)
924 goto Done;
925
926 items_iter = PyObject_GetIter(items);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300927 Py_DECREF(items);
Eric Snow96c6af92015-05-29 22:21:39 -0600928 if (items_iter == NULL)
929 goto Done;
930
Serhiy Storchaka4575beb2015-10-22 20:18:24 +0300931 result = PyTuple_Pack(5, Py_TYPE(od), args, dict ? dict : Py_None, Py_None, items_iter);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300932 Py_DECREF(items_iter);
Eric Snow96c6af92015-05-29 22:21:39 -0600933
934Done:
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300935 Py_XDECREF(dict);
Eric Snow96c6af92015-05-29 22:21:39 -0600936 Py_XDECREF(args);
Eric Snow96c6af92015-05-29 22:21:39 -0600937
938 return result;
939}
940
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100941/* setdefault(): Skips __missing__() calls. */
Eric Snow96c6af92015-05-29 22:21:39 -0600942
Eric Snow96c6af92015-05-29 22:21:39 -0600943
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100944/*[clinic input]
945OrderedDict.setdefault
946
947 key: object
Serhiy Storchakaa70eaf22017-01-19 19:38:13 +0200948 default: object = None
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100949
Serhiy Storchaka78d9e582017-01-25 00:30:04 +0200950Insert key with a value of default if key is not in the dictionary.
951
952Return the value for key if key is in the dictionary, else default.
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100953[clinic start generated code]*/
954
Eric Snow96c6af92015-05-29 22:21:39 -0600955static PyObject *
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100956OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key,
Serhiy Storchakaa70eaf22017-01-19 19:38:13 +0200957 PyObject *default_value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +0200958/*[clinic end generated code: output=97537cb7c28464b6 input=38e098381c1efbc6]*/
Eric Snow96c6af92015-05-29 22:21:39 -0600959{
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100960 PyObject *result = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -0600961
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100962 if (PyODict_CheckExact(self)) {
963 result = PyODict_GetItemWithError(self, key); /* borrowed */
Eric Snowd1719752015-06-01 23:12:13 -0600964 if (result == NULL) {
965 if (PyErr_Occurred())
966 return NULL;
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100967 assert(_odict_find_node(self, key) == NULL);
Serhiy Storchakaa70eaf22017-01-19 19:38:13 +0200968 if (PyODict_SetItem((PyObject *)self, key, default_value) >= 0) {
969 result = default_value;
970 Py_INCREF(result);
Eric Snow96c6af92015-05-29 22:21:39 -0600971 }
972 }
973 else {
Eric Snowd1719752015-06-01 23:12:13 -0600974 Py_INCREF(result);
Eric Snow96c6af92015-05-29 22:21:39 -0600975 }
976 }
977 else {
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100978 int exists = PySequence_Contains((PyObject *)self, key);
Eric Snow96c6af92015-05-29 22:21:39 -0600979 if (exists < 0) {
Eric Snowd1719752015-06-01 23:12:13 -0600980 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -0600981 }
982 else if (exists) {
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100983 result = PyObject_GetItem((PyObject *)self, key);
Eric Snow96c6af92015-05-29 22:21:39 -0600984 }
Serhiy Storchakaa70eaf22017-01-19 19:38:13 +0200985 else if (PyObject_SetItem((PyObject *)self, key, default_value) >= 0) {
986 result = default_value;
987 Py_INCREF(result);
Eric Snow96c6af92015-05-29 22:21:39 -0600988 }
989 }
990
Eric Snow96c6af92015-05-29 22:21:39 -0600991 return result;
992}
993
994/* pop() */
995
996PyDoc_STRVAR(odict_pop__doc__,
997"od.pop(k[,d]) -> v, remove specified key and return the corresponding\n\
998 value. If key is not found, d is returned if given, otherwise KeyError\n\
999 is raised.\n\
1000\n\
1001 ");
1002
1003/* forward */
1004static PyObject * _odict_popkey(PyObject *, PyObject *, PyObject *);
1005
1006/* Skips __missing__() calls. */
1007static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001008odict_pop(PyObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001009{
Eric Snowac02ef32015-06-02 20:42:14 -06001010 static char *kwlist[] = {"key", "default", 0};
Eric Snow96c6af92015-05-29 22:21:39 -06001011 PyObject *key, *failobj = NULL;
1012
Eric Snowac02ef32015-06-02 20:42:14 -06001013 /* borrowed */
1014 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:pop", kwlist,
1015 &key, &failobj)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001016 return NULL;
1017 }
1018
1019 return _odict_popkey(od, key, failobj);
1020}
1021
1022static PyObject *
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001023_odict_popkey_hash(PyObject *od, PyObject *key, PyObject *failobj,
1024 Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -06001025{
1026 _ODictNode *node;
1027 PyObject *value = NULL;
1028
Eric Snow96c6af92015-05-29 22:21:39 -06001029 /* Pop the node first to avoid a possible dict resize (due to
1030 eval loop reentrancy) and complications due to hash collision
1031 resolution. */
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001032 node = _odict_find_node_hash((PyODictObject *)od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001033 if (node == NULL) {
1034 if (PyErr_Occurred())
Eric Snowd1719752015-06-01 23:12:13 -06001035 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001036 }
1037 else {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001038 int res = _odict_clear_node((PyODictObject *)od, node, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001039 if (res < 0) {
Eric Snowd1719752015-06-01 23:12:13 -06001040 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001041 }
1042 }
1043
1044 /* Now delete the value from the dict. */
Serhiy Storchaka04386832016-10-30 17:17:24 +02001045 if (PyODict_CheckExact(od)) {
1046 if (node != NULL) {
1047 value = _PyDict_GetItem_KnownHash(od, key, hash); /* borrowed */
1048 if (value != NULL) {
1049 Py_INCREF(value);
1050 if (_PyDict_DelItem_KnownHash(od, key, hash) < 0) {
1051 Py_DECREF(value);
1052 return NULL;
1053 }
1054 }
1055 }
1056 }
1057 else {
1058 int exists = PySequence_Contains(od, key);
1059 if (exists < 0)
1060 return NULL;
1061 if (exists) {
1062 value = PyObject_GetItem(od, key);
1063 if (value != NULL) {
1064 if (PyObject_DelItem(od, key) == -1) {
1065 Py_CLEAR(value);
1066 }
Eric Snow96c6af92015-05-29 22:21:39 -06001067 }
1068 }
1069 }
1070
1071 /* Apply the fallback value, if necessary. */
1072 if (value == NULL && !PyErr_Occurred()) {
1073 if (failobj) {
1074 value = failobj;
1075 Py_INCREF(failobj);
1076 }
1077 else {
1078 PyErr_SetObject(PyExc_KeyError, key);
1079 }
1080 }
1081
Eric Snow96c6af92015-05-29 22:21:39 -06001082 return value;
1083}
1084
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001085static PyObject *
1086_odict_popkey(PyObject *od, PyObject *key, PyObject *failobj)
1087{
1088 Py_hash_t hash = PyObject_Hash(key);
1089 if (hash == -1)
1090 return NULL;
1091
1092 return _odict_popkey_hash(od, key, failobj, hash);
1093}
1094
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001095
Eric Snow96c6af92015-05-29 22:21:39 -06001096/* popitem() */
1097
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001098/*[clinic input]
1099OrderedDict.popitem
1100
1101 last: bool = True
1102
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001103Remove and return a (key, value) pair from the dictionary.
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001104
1105Pairs are returned in LIFO order if last is true or FIFO order if false.
1106[clinic start generated code]*/
Eric Snow96c6af92015-05-29 22:21:39 -06001107
1108static PyObject *
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001109OrderedDict_popitem_impl(PyODictObject *self, int last)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001110/*[clinic end generated code: output=98e7d986690d49eb input=d992ac5ee8305e1a]*/
Eric Snow96c6af92015-05-29 22:21:39 -06001111{
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001112 PyObject *key, *value, *item = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001113 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001114
1115 /* pull the item */
1116
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001117 if (_odict_EMPTY(self)) {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001118 PyErr_SetString(PyExc_KeyError, "dictionary is empty");
1119 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001120 }
Eric Snow96c6af92015-05-29 22:21:39 -06001121
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001122 node = last ? _odict_LAST(self) : _odict_FIRST(self);
Eric Snow96c6af92015-05-29 22:21:39 -06001123 key = _odictnode_KEY(node);
Eric Snowd1719752015-06-01 23:12:13 -06001124 Py_INCREF(key);
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001125 value = _odict_popkey_hash((PyObject *)self, key, NULL, _odictnode_HASH(node));
Eric Snow96c6af92015-05-29 22:21:39 -06001126 if (value == NULL)
1127 return NULL;
1128 item = PyTuple_Pack(2, key, value);
Eric Snowd1719752015-06-01 23:12:13 -06001129 Py_DECREF(key);
Eric Snow96c6af92015-05-29 22:21:39 -06001130 Py_DECREF(value);
1131 return item;
1132}
1133
1134/* keys() */
1135
1136/* MutableMapping.keys() does not have a docstring. */
1137PyDoc_STRVAR(odict_keys__doc__, "");
1138
1139static PyObject * odictkeys_new(PyObject *od); /* forward */
1140
1141/* values() */
1142
1143/* MutableMapping.values() does not have a docstring. */
1144PyDoc_STRVAR(odict_values__doc__, "");
1145
1146static PyObject * odictvalues_new(PyObject *od); /* forward */
1147
1148/* items() */
1149
1150/* MutableMapping.items() does not have a docstring. */
1151PyDoc_STRVAR(odict_items__doc__, "");
1152
1153static PyObject * odictitems_new(PyObject *od); /* forward */
1154
1155/* update() */
1156
1157/* MutableMapping.update() does not have a docstring. */
1158PyDoc_STRVAR(odict_update__doc__, "");
1159
1160/* forward */
1161static PyObject * mutablemapping_update(PyObject *, PyObject *, PyObject *);
1162
1163#define odict_update mutablemapping_update
1164
1165/* clear() */
1166
1167PyDoc_STRVAR(odict_clear__doc__,
1168 "od.clear() -> None. Remove all items from od.");
1169
1170static PyObject *
Serhiy Storchaka861d34e2018-10-20 11:24:05 +03001171odict_clear(register PyODictObject *od, PyObject *Py_UNUSED(ignored))
Eric Snow96c6af92015-05-29 22:21:39 -06001172{
1173 PyDict_Clear((PyObject *)od);
1174 _odict_clear_nodes(od);
Eric Snow96c6af92015-05-29 22:21:39 -06001175 Py_RETURN_NONE;
1176}
1177
1178/* copy() */
1179
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001180/* forward */
1181static int _PyODict_SetItem_KnownHash(PyObject *, PyObject *, PyObject *,
1182 Py_hash_t);
1183
Eric Snow96c6af92015-05-29 22:21:39 -06001184PyDoc_STRVAR(odict_copy__doc__, "od.copy() -> a shallow copy of od");
1185
1186static PyObject *
1187odict_copy(register PyODictObject *od)
1188{
1189 _ODictNode *node;
1190 PyObject *od_copy;
1191
1192 if (PyODict_CheckExact(od))
1193 od_copy = PyODict_New();
1194 else
Victor Stinnerf17c3de2016-12-06 18:46:19 +01001195 od_copy = _PyObject_CallNoArg((PyObject *)Py_TYPE(od));
Eric Snow96c6af92015-05-29 22:21:39 -06001196 if (od_copy == NULL)
1197 return NULL;
1198
1199 if (PyODict_CheckExact(od)) {
1200 _odict_FOREACH(od, node) {
Eric Snowa762af72015-06-01 22:59:08 -06001201 PyObject *key = _odictnode_KEY(node);
1202 PyObject *value = _odictnode_VALUE(node, od);
1203 if (value == NULL) {
1204 if (!PyErr_Occurred())
1205 PyErr_SetObject(PyExc_KeyError, key);
1206 goto fail;
1207 }
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001208 if (_PyODict_SetItem_KnownHash((PyObject *)od_copy, key, value,
1209 _odictnode_HASH(node)) != 0)
Eric Snow96c6af92015-05-29 22:21:39 -06001210 goto fail;
1211 }
1212 }
1213 else {
1214 _odict_FOREACH(od, node) {
1215 int res;
1216 PyObject *value = PyObject_GetItem((PyObject *)od,
1217 _odictnode_KEY(node));
1218 if (value == NULL)
1219 goto fail;
1220 res = PyObject_SetItem((PyObject *)od_copy,
1221 _odictnode_KEY(node), value);
1222 Py_DECREF(value);
1223 if (res != 0)
1224 goto fail;
1225 }
1226 }
1227 return od_copy;
1228
1229fail:
1230 Py_DECREF(od_copy);
1231 return NULL;
1232}
1233
1234/* __reversed__() */
1235
1236PyDoc_STRVAR(odict_reversed__doc__, "od.__reversed__() <==> reversed(od)");
1237
1238#define _odict_ITER_REVERSED 1
1239#define _odict_ITER_KEYS 2
1240#define _odict_ITER_VALUES 4
1241
1242/* forward */
1243static PyObject * odictiter_new(PyODictObject *, int);
1244
1245static PyObject *
1246odict_reversed(PyODictObject *od)
1247{
Eric Snow96c6af92015-05-29 22:21:39 -06001248 return odictiter_new(od, _odict_ITER_KEYS|_odict_ITER_REVERSED);
1249}
1250
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001251
Eric Snow96c6af92015-05-29 22:21:39 -06001252/* move_to_end() */
1253
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001254/*[clinic input]
1255OrderedDict.move_to_end
1256
1257 key: object
1258 last: bool = True
1259
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001260Move an existing element to the end (or beginning if last is false).
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001261
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001262Raise KeyError if the element does not exist.
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001263[clinic start generated code]*/
Eric Snow96c6af92015-05-29 22:21:39 -06001264
1265static PyObject *
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001266OrderedDict_move_to_end_impl(PyODictObject *self, PyObject *key, int last)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001267/*[clinic end generated code: output=fafa4c5cc9b92f20 input=d6ceff7132a2fcd7]*/
Eric Snow96c6af92015-05-29 22:21:39 -06001268{
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001269 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001270
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001271 if (_odict_EMPTY(self)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001272 PyErr_SetObject(PyExc_KeyError, key);
Eric Snow96c6af92015-05-29 22:21:39 -06001273 return NULL;
1274 }
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001275 node = last ? _odict_LAST(self) : _odict_FIRST(self);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001276 if (key != _odictnode_KEY(node)) {
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001277 node = _odict_find_node(self, key);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001278 if (node == NULL) {
1279 if (!PyErr_Occurred())
1280 PyErr_SetObject(PyExc_KeyError, key);
Eric Snowc5e59602015-05-30 11:28:56 -06001281 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001282 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001283 if (last) {
1284 /* Only move if not already the last one. */
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001285 if (node != _odict_LAST(self)) {
1286 _odict_remove_node(self, node);
1287 _odict_add_tail(self, node);
Eric Snow96c6af92015-05-29 22:21:39 -06001288 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001289 }
1290 else {
1291 /* Only move if not already the first one. */
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001292 if (node != _odict_FIRST(self)) {
1293 _odict_remove_node(self, node);
1294 _odict_add_head(self, node);
Eric Snow96c6af92015-05-29 22:21:39 -06001295 }
1296 }
1297 }
Eric Snow96c6af92015-05-29 22:21:39 -06001298 Py_RETURN_NONE;
1299}
1300
1301
1302/* tp_methods */
1303
1304static PyMethodDef odict_methods[] = {
1305
Eric Snow96c6af92015-05-29 22:21:39 -06001306 /* overridden dict methods */
Serhiy Storchakab0f387d2018-04-09 21:46:41 +03001307 ORDEREDDICT_FROMKEYS_METHODDEF
Eric Snow96c6af92015-05-29 22:21:39 -06001308 {"__sizeof__", (PyCFunction)odict_sizeof, METH_NOARGS,
1309 odict_sizeof__doc__},
1310 {"__reduce__", (PyCFunction)odict_reduce, METH_NOARGS,
1311 odict_reduce__doc__},
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001312 ORDEREDDICT_SETDEFAULT_METHODDEF
Eric Snowac02ef32015-06-02 20:42:14 -06001313 {"pop", (PyCFunction)odict_pop,
1314 METH_VARARGS | METH_KEYWORDS, odict_pop__doc__},
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001315 ORDEREDDICT_POPITEM_METHODDEF
Eric Snow96c6af92015-05-29 22:21:39 -06001316 {"keys", (PyCFunction)odictkeys_new, METH_NOARGS,
1317 odict_keys__doc__},
1318 {"values", (PyCFunction)odictvalues_new, METH_NOARGS,
1319 odict_values__doc__},
1320 {"items", (PyCFunction)odictitems_new, METH_NOARGS,
1321 odict_items__doc__},
1322 {"update", (PyCFunction)odict_update, METH_VARARGS | METH_KEYWORDS,
1323 odict_update__doc__},
1324 {"clear", (PyCFunction)odict_clear, METH_NOARGS,
1325 odict_clear__doc__},
1326 {"copy", (PyCFunction)odict_copy, METH_NOARGS,
1327 odict_copy__doc__},
1328
1329 /* new methods */
1330 {"__reversed__", (PyCFunction)odict_reversed, METH_NOARGS,
1331 odict_reversed__doc__},
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001332 ORDEREDDICT_MOVE_TO_END_METHODDEF
Eric Snow96c6af92015-05-29 22:21:39 -06001333
1334 {NULL, NULL} /* sentinel */
1335};
1336
1337
1338/* ----------------------------------------------
1339 * OrderedDict members
1340 */
1341
Serhiy Storchakad2962f12016-02-08 16:39:05 +02001342/* tp_getset */
Eric Snow96c6af92015-05-29 22:21:39 -06001343
Serhiy Storchakad2962f12016-02-08 16:39:05 +02001344static PyGetSetDef odict_getset[] = {
1345 {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
1346 {NULL}
Eric Snow96c6af92015-05-29 22:21:39 -06001347};
1348
Eric Snow96c6af92015-05-29 22:21:39 -06001349/* ----------------------------------------------
1350 * OrderedDict type slot methods
1351 */
1352
1353/* tp_dealloc */
1354
1355static void
1356odict_dealloc(PyODictObject *self)
1357{
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001358 PyThreadState *tstate = PyThreadState_GET();
1359
Eric Snow96c6af92015-05-29 22:21:39 -06001360 PyObject_GC_UnTrack(self);
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001361 Py_TRASHCAN_SAFE_BEGIN(self)
1362
Eric Snow96c6af92015-05-29 22:21:39 -06001363 Py_XDECREF(self->od_inst_dict);
1364 if (self->od_weakreflist != NULL)
1365 PyObject_ClearWeakRefs((PyObject *)self);
1366
1367 _odict_clear_nodes(self);
Eric Snow96c6af92015-05-29 22:21:39 -06001368
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001369 /* Call the base tp_dealloc(). Since it too uses the trashcan mechanism,
1370 * temporarily decrement trash_delete_nesting to prevent triggering it
1371 * and putting the partially deallocated object on the trashcan's
1372 * to-be-deleted-later list.
1373 */
1374 --tstate->trash_delete_nesting;
1375 assert(_tstate->trash_delete_nesting < PyTrash_UNWIND_LEVEL);
Eric Snow96c6af92015-05-29 22:21:39 -06001376 PyDict_Type.tp_dealloc((PyObject *)self);
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001377 ++tstate->trash_delete_nesting;
1378
1379 Py_TRASHCAN_SAFE_END(self)
Victor Stinnere1871952016-06-08 10:18:18 +02001380}
Eric Snow96c6af92015-05-29 22:21:39 -06001381
1382/* tp_repr */
1383
1384static PyObject *
1385odict_repr(PyODictObject *self)
1386{
1387 int i;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001388 _Py_IDENTIFIER(items);
Serhiy Storchaka4575beb2015-10-22 20:18:24 +03001389 PyObject *pieces = NULL, *result = NULL;
Serhiy Storchaka4575beb2015-10-22 20:18:24 +03001390
1391 if (PyODict_SIZE(self) == 0)
Serhiy Storchaka4ab46d72017-09-17 21:11:04 +03001392 return PyUnicode_FromFormat("%s()", _PyType_Name(Py_TYPE(self)));
Eric Snow96c6af92015-05-29 22:21:39 -06001393
1394 i = Py_ReprEnter((PyObject *)self);
1395 if (i != 0) {
1396 return i > 0 ? PyUnicode_FromString("...") : NULL;
1397 }
1398
Eric Snow96c6af92015-05-29 22:21:39 -06001399 if (PyODict_CheckExact(self)) {
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001400 Py_ssize_t count = 0;
Eric Snowa762af72015-06-01 22:59:08 -06001401 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001402 pieces = PyList_New(PyODict_SIZE(self));
1403 if (pieces == NULL)
1404 goto Done;
1405
1406 _odict_FOREACH(self, node) {
Eric Snowa762af72015-06-01 22:59:08 -06001407 PyObject *pair;
1408 PyObject *key = _odictnode_KEY(node);
1409 PyObject *value = _odictnode_VALUE(node, self);
1410 if (value == NULL) {
1411 if (!PyErr_Occurred())
1412 PyErr_SetObject(PyExc_KeyError, key);
Eric Snowdb4061c2015-06-03 11:09:48 -06001413 goto Done;
Eric Snowa762af72015-06-01 22:59:08 -06001414 }
1415 pair = PyTuple_Pack(2, key, value);
Eric Snow96c6af92015-05-29 22:21:39 -06001416 if (pair == NULL)
1417 goto Done;
1418
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001419 if (count < PyList_GET_SIZE(pieces))
1420 PyList_SET_ITEM(pieces, count, pair); /* steals reference */
1421 else {
1422 if (PyList_Append(pieces, pair) < 0) {
1423 Py_DECREF(pair);
1424 goto Done;
1425 }
1426 Py_DECREF(pair);
1427 }
1428 count++;
Eric Snow96c6af92015-05-29 22:21:39 -06001429 }
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001430 if (count < PyList_GET_SIZE(pieces))
Serhiy Storchaka1a5856b2017-04-22 02:48:11 +03001431 Py_SIZE(pieces) = count;
Eric Snow96c6af92015-05-29 22:21:39 -06001432 }
1433 else {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001434 PyObject *items = _PyObject_CallMethodIdObjArgs((PyObject *)self,
1435 &PyId_items, NULL);
Eric Snow96c6af92015-05-29 22:21:39 -06001436 if (items == NULL)
1437 goto Done;
1438 pieces = PySequence_List(items);
1439 Py_DECREF(items);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001440 if (pieces == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -06001441 goto Done;
1442 }
1443
Serhiy Storchaka4ab46d72017-09-17 21:11:04 +03001444 result = PyUnicode_FromFormat("%s(%R)",
1445 _PyType_Name(Py_TYPE(self)), pieces);
Eric Snow96c6af92015-05-29 22:21:39 -06001446
Eric Snow96c6af92015-05-29 22:21:39 -06001447Done:
1448 Py_XDECREF(pieces);
Eric Snow96c6af92015-05-29 22:21:39 -06001449 Py_ReprLeave((PyObject *)self);
1450 return result;
Victor Stinnere1871952016-06-08 10:18:18 +02001451}
Eric Snow96c6af92015-05-29 22:21:39 -06001452
1453/* tp_doc */
1454
1455PyDoc_STRVAR(odict_doc,
1456 "Dictionary that remembers insertion order");
1457
1458/* tp_traverse */
1459
1460static int
1461odict_traverse(PyODictObject *od, visitproc visit, void *arg)
1462{
Serhiy Storchakad205d012016-01-19 14:46:25 +02001463 _ODictNode *node;
1464
Eric Snow96c6af92015-05-29 22:21:39 -06001465 Py_VISIT(od->od_inst_dict);
1466 Py_VISIT(od->od_weakreflist);
Serhiy Storchakad205d012016-01-19 14:46:25 +02001467 _odict_FOREACH(od, node) {
1468 Py_VISIT(_odictnode_KEY(node));
1469 }
Eric Snow96c6af92015-05-29 22:21:39 -06001470 return PyDict_Type.tp_traverse((PyObject *)od, visit, arg);
1471}
1472
1473/* tp_clear */
1474
1475static int
1476odict_tp_clear(PyODictObject *od)
1477{
Eric Snow96c6af92015-05-29 22:21:39 -06001478 Py_CLEAR(od->od_inst_dict);
1479 Py_CLEAR(od->od_weakreflist);
Serhiy Storchaka861d34e2018-10-20 11:24:05 +03001480 PyDict_Clear((PyObject *)od);
1481 _odict_clear_nodes(od);
Eric Snow96c6af92015-05-29 22:21:39 -06001482 return 0;
1483}
1484
1485/* tp_richcompare */
1486
1487static PyObject *
1488odict_richcompare(PyObject *v, PyObject *w, int op)
1489{
1490 if (!PyODict_Check(v) || !PyDict_Check(w)) {
1491 Py_RETURN_NOTIMPLEMENTED;
1492 }
1493
1494 if (op == Py_EQ || op == Py_NE) {
1495 PyObject *res, *cmp;
1496 int eq;
1497
1498 cmp = PyDict_Type.tp_richcompare(v, w, op);
1499 if (cmp == NULL)
1500 return NULL;
1501 if (!PyODict_Check(w))
1502 return cmp;
1503 if (op == Py_EQ && cmp == Py_False)
1504 return cmp;
1505 if (op == Py_NE && cmp == Py_True)
1506 return cmp;
1507 Py_DECREF(cmp);
1508
1509 /* Try comparing odict keys. */
1510 eq = _odict_keys_equal((PyODictObject *)v, (PyODictObject *)w);
1511 if (eq < 0)
1512 return NULL;
1513
1514 res = (eq == (op == Py_EQ)) ? Py_True : Py_False;
1515 Py_INCREF(res);
1516 return res;
1517 } else {
1518 Py_RETURN_NOTIMPLEMENTED;
1519 }
Victor Stinnere1871952016-06-08 10:18:18 +02001520}
Eric Snow96c6af92015-05-29 22:21:39 -06001521
1522/* tp_iter */
1523
1524static PyObject *
1525odict_iter(PyODictObject *od)
1526{
1527 return odictiter_new(od, _odict_ITER_KEYS);
Victor Stinnere1871952016-06-08 10:18:18 +02001528}
Eric Snow96c6af92015-05-29 22:21:39 -06001529
1530/* tp_init */
1531
1532static int
1533odict_init(PyObject *self, PyObject *args, PyObject *kwds)
1534{
1535 PyObject *res;
1536 Py_ssize_t len = PyObject_Length(args);
1537
1538 if (len == -1)
1539 return -1;
1540 if (len > 1) {
Serhiy Storchakae2f92de2017-11-11 13:06:26 +02001541 const char *msg = "expected at most 1 arguments, got %d";
Eric Snow96c6af92015-05-29 22:21:39 -06001542 PyErr_Format(PyExc_TypeError, msg, len);
1543 return -1;
1544 }
1545
1546 /* __init__() triggering update() is just the way things are! */
1547 res = odict_update(self, args, kwds);
1548 if (res == NULL) {
1549 return -1;
1550 } else {
1551 Py_DECREF(res);
1552 return 0;
1553 }
Victor Stinnere1871952016-06-08 10:18:18 +02001554}
Eric Snow96c6af92015-05-29 22:21:39 -06001555
Eric Snow96c6af92015-05-29 22:21:39 -06001556/* PyODict_Type */
1557
1558PyTypeObject PyODict_Type = {
1559 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1560 "collections.OrderedDict", /* tp_name */
1561 sizeof(PyODictObject), /* tp_basicsize */
1562 0, /* tp_itemsize */
1563 (destructor)odict_dealloc, /* tp_dealloc */
1564 0, /* tp_print */
1565 0, /* tp_getattr */
1566 0, /* tp_setattr */
1567 0, /* tp_reserved */
1568 (reprfunc)odict_repr, /* tp_repr */
1569 0, /* tp_as_number */
1570 0, /* tp_as_sequence */
1571 &odict_as_mapping, /* tp_as_mapping */
1572 0, /* tp_hash */
1573 0, /* tp_call */
1574 0, /* tp_str */
1575 0, /* tp_getattro */
1576 0, /* tp_setattro */
1577 0, /* tp_as_buffer */
1578 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,/* tp_flags */
1579 odict_doc, /* tp_doc */
1580 (traverseproc)odict_traverse, /* tp_traverse */
1581 (inquiry)odict_tp_clear, /* tp_clear */
1582 (richcmpfunc)odict_richcompare, /* tp_richcompare */
1583 offsetof(PyODictObject, od_weakreflist), /* tp_weaklistoffset */
1584 (getiterfunc)odict_iter, /* tp_iter */
1585 0, /* tp_iternext */
1586 odict_methods, /* tp_methods */
Serhiy Storchakad2962f12016-02-08 16:39:05 +02001587 0, /* tp_members */
1588 odict_getset, /* tp_getset */
Eric Snow96c6af92015-05-29 22:21:39 -06001589 &PyDict_Type, /* tp_base */
1590 0, /* tp_dict */
1591 0, /* tp_descr_get */
1592 0, /* tp_descr_set */
1593 offsetof(PyODictObject, od_inst_dict), /* tp_dictoffset */
1594 (initproc)odict_init, /* tp_init */
1595 PyType_GenericAlloc, /* tp_alloc */
Serhiy Storchaka861d34e2018-10-20 11:24:05 +03001596 0, /* tp_new */
Eric Snow96c6af92015-05-29 22:21:39 -06001597 0, /* tp_free */
1598};
1599
1600
1601/* ----------------------------------------------
1602 * the public OrderedDict API
1603 */
1604
1605PyObject *
Serhiy Storchaka861d34e2018-10-20 11:24:05 +03001606PyODict_New(void)
1607{
1608 return PyDict_Type.tp_new(&PyODict_Type, NULL, NULL);
Victor Stinnere1871952016-06-08 10:18:18 +02001609}
Eric Snow96c6af92015-05-29 22:21:39 -06001610
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001611static int
1612_PyODict_SetItem_KnownHash(PyObject *od, PyObject *key, PyObject *value,
1613 Py_hash_t hash)
1614{
1615 int res = _PyDict_SetItem_KnownHash(od, key, value, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001616 if (res == 0) {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001617 res = _odict_add_new_node((PyODictObject *)od, key, hash);
Serhiy Storchakad5f353e2015-11-06 11:07:11 +02001618 if (res < 0) {
1619 /* Revert setting the value on the dict */
1620 PyObject *exc, *val, *tb;
1621 PyErr_Fetch(&exc, &val, &tb);
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001622 (void) _PyDict_DelItem_KnownHash(od, key, hash);
Serhiy Storchakad5f353e2015-11-06 11:07:11 +02001623 _PyErr_ChainExceptions(exc, val, tb);
1624 }
Eric Snow96c6af92015-05-29 22:21:39 -06001625 }
1626 return res;
Victor Stinnere1871952016-06-08 10:18:18 +02001627}
Eric Snow96c6af92015-05-29 22:21:39 -06001628
1629int
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001630PyODict_SetItem(PyObject *od, PyObject *key, PyObject *value)
1631{
1632 Py_hash_t hash = PyObject_Hash(key);
1633 if (hash == -1)
1634 return -1;
1635 return _PyODict_SetItem_KnownHash(od, key, value, hash);
Victor Stinnere1871952016-06-08 10:18:18 +02001636}
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001637
1638int
1639PyODict_DelItem(PyObject *od, PyObject *key)
1640{
1641 int res;
1642 Py_hash_t hash = PyObject_Hash(key);
1643 if (hash == -1)
1644 return -1;
1645 res = _odict_clear_node((PyODictObject *)od, NULL, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001646 if (res < 0)
1647 return -1;
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001648 return _PyDict_DelItem_KnownHash(od, key, hash);
Victor Stinnere1871952016-06-08 10:18:18 +02001649}
Eric Snow96c6af92015-05-29 22:21:39 -06001650
1651
1652/* -------------------------------------------
1653 * The OrderedDict views (keys/values/items)
1654 */
1655
1656typedef struct {
1657 PyObject_HEAD
1658 int kind;
1659 PyODictObject *di_odict;
Eric Snowb952ab42015-06-01 23:35:13 -06001660 Py_ssize_t di_size;
Eric Snow4fabf022015-06-04 00:09:56 -06001661 size_t di_state;
Eric Snow96c6af92015-05-29 22:21:39 -06001662 PyObject *di_current;
1663 PyObject *di_result; /* reusable result tuple for iteritems */
1664} odictiterobject;
1665
1666static void
1667odictiter_dealloc(odictiterobject *di)
1668{
1669 _PyObject_GC_UNTRACK(di);
Eric Snowa762af72015-06-01 22:59:08 -06001670 Py_XDECREF(di->di_odict);
Eric Snow96c6af92015-05-29 22:21:39 -06001671 Py_XDECREF(di->di_current);
1672 if (di->kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)) {
1673 Py_DECREF(di->di_result);
1674 }
1675 PyObject_GC_Del(di);
1676}
1677
1678static int
1679odictiter_traverse(odictiterobject *di, visitproc visit, void *arg)
1680{
1681 Py_VISIT(di->di_odict);
1682 Py_VISIT(di->di_current); /* A key could be any type, not just str. */
1683 Py_VISIT(di->di_result);
1684 return 0;
1685}
1686
Eric Snowa762af72015-06-01 22:59:08 -06001687/* In order to protect against modifications during iteration, we track
1688 * the current key instead of the current node. */
Eric Snow96c6af92015-05-29 22:21:39 -06001689static PyObject *
1690odictiter_nextkey(odictiterobject *di)
1691{
Eric Snowa762af72015-06-01 22:59:08 -06001692 PyObject *key = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001693 _ODictNode *node;
1694 int reversed = di->kind & _odict_ITER_REVERSED;
1695
Eric Snowa762af72015-06-01 22:59:08 -06001696 if (di->di_odict == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -06001697 return NULL;
Eric Snowa762af72015-06-01 22:59:08 -06001698 if (di->di_current == NULL)
1699 goto done; /* We're already done. */
1700
Eric Snowb952ab42015-06-01 23:35:13 -06001701 /* Check for unsupported changes. */
Eric Snow4fabf022015-06-04 00:09:56 -06001702 if (di->di_odict->od_state != di->di_state) {
1703 PyErr_SetString(PyExc_RuntimeError,
1704 "OrderedDict mutated during iteration");
1705 goto done;
1706 }
Eric Snowb952ab42015-06-01 23:35:13 -06001707 if (di->di_size != PyODict_SIZE(di->di_odict)) {
1708 PyErr_SetString(PyExc_RuntimeError,
1709 "OrderedDict changed size during iteration");
1710 di->di_size = -1; /* Make this state sticky */
1711 return NULL;
1712 }
1713
Eric Snowa762af72015-06-01 22:59:08 -06001714 /* Get the key. */
Eric Snow96c6af92015-05-29 22:21:39 -06001715 node = _odict_find_node(di->di_odict, di->di_current);
1716 if (node == NULL) {
Serhiy Storchakab45b7b22015-11-04 22:05:38 +02001717 if (!PyErr_Occurred())
1718 PyErr_SetObject(PyExc_KeyError, di->di_current);
Eric Snow96c6af92015-05-29 22:21:39 -06001719 /* Must have been deleted. */
Eric Snowe3dfa9e2015-05-30 12:51:15 -06001720 Py_CLEAR(di->di_current);
Eric Snow96c6af92015-05-29 22:21:39 -06001721 return NULL;
1722 }
1723 key = di->di_current;
1724
1725 /* Advance to the next key. */
1726 node = reversed ? _odictnode_PREV(node) : _odictnode_NEXT(node);
1727 if (node == NULL) {
1728 /* Reached the end. */
1729 di->di_current = NULL;
1730 }
1731 else {
1732 di->di_current = _odictnode_KEY(node);
1733 Py_INCREF(di->di_current);
1734 }
1735
1736 return key;
Eric Snowa762af72015-06-01 22:59:08 -06001737
1738done:
1739 Py_CLEAR(di->di_odict);
1740 return key;
Eric Snow96c6af92015-05-29 22:21:39 -06001741}
1742
1743static PyObject *
1744odictiter_iternext(odictiterobject *di)
1745{
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001746 PyObject *result, *value;
Eric Snow96c6af92015-05-29 22:21:39 -06001747 PyObject *key = odictiter_nextkey(di); /* new reference */
1748
1749 if (key == NULL)
1750 return NULL;
1751
1752 /* Handle the keys case. */
1753 if (! (di->kind & _odict_ITER_VALUES)) {
1754 return key;
1755 }
1756
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001757 value = PyODict_GetItem((PyObject *)di->di_odict, key); /* borrowed */
1758 if (value == NULL) {
1759 if (!PyErr_Occurred())
1760 PyErr_SetObject(PyExc_KeyError, key);
Eric Snow96c6af92015-05-29 22:21:39 -06001761 Py_DECREF(key);
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001762 goto done;
1763 }
1764 Py_INCREF(value);
1765
1766 /* Handle the values case. */
1767 if (!(di->kind & _odict_ITER_KEYS)) {
1768 Py_DECREF(key);
Eric Snow96c6af92015-05-29 22:21:39 -06001769 return value;
1770 }
Eric Snowa762af72015-06-01 22:59:08 -06001771
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001772 /* Handle the items case. */
1773 result = di->di_result;
1774
1775 if (Py_REFCNT(result) == 1) {
1776 /* not in use so we can reuse it
1777 * (the common case during iteration) */
1778 Py_INCREF(result);
1779 Py_DECREF(PyTuple_GET_ITEM(result, 0)); /* borrowed */
1780 Py_DECREF(PyTuple_GET_ITEM(result, 1)); /* borrowed */
1781 }
1782 else {
1783 result = PyTuple_New(2);
1784 if (result == NULL) {
1785 Py_DECREF(key);
1786 Py_DECREF(value);
1787 goto done;
1788 }
1789 }
1790
1791 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
1792 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
1793 return result;
1794
Eric Snowa762af72015-06-01 22:59:08 -06001795done:
1796 Py_CLEAR(di->di_current);
1797 Py_CLEAR(di->di_odict);
1798 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001799}
1800
1801/* No need for tp_clear because odictiterobject is not mutable. */
1802
1803PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
1804
1805static PyObject *
1806odictiter_reduce(odictiterobject *di)
1807{
Miss Islington (bot)dcd56f62018-10-19 22:54:09 -07001808 /* copy the iterator state */
1809 odictiterobject tmp = *di;
1810 Py_XINCREF(tmp.di_odict);
1811 Py_XINCREF(tmp.di_current);
Eric Snow96c6af92015-05-29 22:21:39 -06001812
1813 /* iterate the temporary into a list */
Miss Islington (bot)dcd56f62018-10-19 22:54:09 -07001814 PyObject *list = PySequence_List((PyObject*)&tmp);
1815 Py_XDECREF(tmp.di_odict);
1816 Py_XDECREF(tmp.di_current);
1817 if (list == NULL) {
Eric Snow96c6af92015-05-29 22:21:39 -06001818 return NULL;
1819 }
Miss Islington (bot)dcd56f62018-10-19 22:54:09 -07001820 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Eric Snow96c6af92015-05-29 22:21:39 -06001821}
1822
1823static PyMethodDef odictiter_methods[] = {
1824 {"__reduce__", (PyCFunction)odictiter_reduce, METH_NOARGS, reduce_doc},
1825 {NULL, NULL} /* sentinel */
1826};
1827
1828PyTypeObject PyODictIter_Type = {
1829 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1830 "odict_iterator", /* tp_name */
1831 sizeof(odictiterobject), /* tp_basicsize */
1832 0, /* tp_itemsize */
1833 /* methods */
1834 (destructor)odictiter_dealloc, /* tp_dealloc */
1835 0, /* tp_print */
1836 0, /* tp_getattr */
1837 0, /* tp_setattr */
1838 0, /* tp_reserved */
1839 0, /* tp_repr */
1840 0, /* tp_as_number */
1841 0, /* tp_as_sequence */
1842 0, /* tp_as_mapping */
1843 0, /* tp_hash */
1844 0, /* tp_call */
1845 0, /* tp_str */
1846 PyObject_GenericGetAttr, /* tp_getattro */
1847 0, /* tp_setattro */
1848 0, /* tp_as_buffer */
1849 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1850 0, /* tp_doc */
1851 (traverseproc)odictiter_traverse, /* tp_traverse */
1852 0, /* tp_clear */
1853 0, /* tp_richcompare */
1854 0, /* tp_weaklistoffset */
1855 PyObject_SelfIter, /* tp_iter */
1856 (iternextfunc)odictiter_iternext, /* tp_iternext */
1857 odictiter_methods, /* tp_methods */
1858 0,
1859};
1860
1861static PyObject *
1862odictiter_new(PyODictObject *od, int kind)
1863{
1864 odictiterobject *di;
1865 _ODictNode *node;
1866 int reversed = kind & _odict_ITER_REVERSED;
1867
1868 di = PyObject_GC_New(odictiterobject, &PyODictIter_Type);
1869 if (di == NULL)
1870 return NULL;
1871
1872 if (kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)){
1873 di->di_result = PyTuple_Pack(2, Py_None, Py_None);
1874 if (di->di_result == NULL) {
1875 Py_DECREF(di);
1876 return NULL;
1877 }
1878 }
1879 else
1880 di->di_result = NULL;
1881
1882 di->kind = kind;
1883 node = reversed ? _odict_LAST(od) : _odict_FIRST(od);
1884 di->di_current = node ? _odictnode_KEY(node) : NULL;
1885 Py_XINCREF(di->di_current);
Eric Snowb952ab42015-06-01 23:35:13 -06001886 di->di_size = PyODict_SIZE(od);
Eric Snow4fabf022015-06-04 00:09:56 -06001887 di->di_state = od->od_state;
Eric Snow96c6af92015-05-29 22:21:39 -06001888 di->di_odict = od;
1889 Py_INCREF(od);
1890
1891 _PyObject_GC_TRACK(di);
1892 return (PyObject *)di;
1893}
1894
1895/* keys() */
1896
1897static PyObject *
1898odictkeys_iter(_PyDictViewObject *dv)
1899{
1900 if (dv->dv_dict == NULL) {
1901 Py_RETURN_NONE;
1902 }
1903 return odictiter_new((PyODictObject *)dv->dv_dict,
1904 _odict_ITER_KEYS);
1905}
1906
1907static PyObject *
1908odictkeys_reversed(_PyDictViewObject *dv)
1909{
1910 if (dv->dv_dict == NULL) {
1911 Py_RETURN_NONE;
1912 }
1913 return odictiter_new((PyODictObject *)dv->dv_dict,
1914 _odict_ITER_KEYS|_odict_ITER_REVERSED);
1915}
1916
1917static PyMethodDef odictkeys_methods[] = {
1918 {"__reversed__", (PyCFunction)odictkeys_reversed, METH_NOARGS, NULL},
1919 {NULL, NULL} /* sentinel */
1920};
1921
1922PyTypeObject PyODictKeys_Type = {
1923 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1924 "odict_keys", /* tp_name */
1925 0, /* tp_basicsize */
1926 0, /* tp_itemsize */
1927 0, /* tp_dealloc */
1928 0, /* tp_print */
1929 0, /* tp_getattr */
1930 0, /* tp_setattr */
1931 0, /* tp_reserved */
1932 0, /* tp_repr */
1933 0, /* tp_as_number */
1934 0, /* tp_as_sequence */
1935 0, /* tp_as_mapping */
1936 0, /* tp_hash */
1937 0, /* tp_call */
1938 0, /* tp_str */
1939 0, /* tp_getattro */
1940 0, /* tp_setattro */
1941 0, /* tp_as_buffer */
1942 0, /* tp_flags */
1943 0, /* tp_doc */
1944 0, /* tp_traverse */
1945 0, /* tp_clear */
1946 0, /* tp_richcompare */
1947 0, /* tp_weaklistoffset */
1948 (getiterfunc)odictkeys_iter, /* tp_iter */
1949 0, /* tp_iternext */
1950 odictkeys_methods, /* tp_methods */
1951 0, /* tp_members */
1952 0, /* tp_getset */
1953 &PyDictKeys_Type, /* tp_base */
1954};
1955
1956static PyObject *
1957odictkeys_new(PyObject *od)
1958{
1959 return _PyDictView_New(od, &PyODictKeys_Type);
1960}
1961
1962/* items() */
1963
1964static PyObject *
1965odictitems_iter(_PyDictViewObject *dv)
1966{
1967 if (dv->dv_dict == NULL) {
1968 Py_RETURN_NONE;
1969 }
1970 return odictiter_new((PyODictObject *)dv->dv_dict,
1971 _odict_ITER_KEYS|_odict_ITER_VALUES);
1972}
1973
1974static PyObject *
1975odictitems_reversed(_PyDictViewObject *dv)
1976{
1977 if (dv->dv_dict == NULL) {
1978 Py_RETURN_NONE;
1979 }
1980 return odictiter_new((PyODictObject *)dv->dv_dict,
1981 _odict_ITER_KEYS|_odict_ITER_VALUES|_odict_ITER_REVERSED);
1982}
1983
1984static PyMethodDef odictitems_methods[] = {
1985 {"__reversed__", (PyCFunction)odictitems_reversed, METH_NOARGS, NULL},
1986 {NULL, NULL} /* sentinel */
1987};
1988
1989PyTypeObject PyODictItems_Type = {
1990 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1991 "odict_items", /* tp_name */
1992 0, /* tp_basicsize */
1993 0, /* tp_itemsize */
1994 0, /* tp_dealloc */
1995 0, /* tp_print */
1996 0, /* tp_getattr */
1997 0, /* tp_setattr */
1998 0, /* tp_reserved */
1999 0, /* tp_repr */
2000 0, /* tp_as_number */
2001 0, /* tp_as_sequence */
2002 0, /* tp_as_mapping */
2003 0, /* tp_hash */
2004 0, /* tp_call */
2005 0, /* tp_str */
2006 0, /* tp_getattro */
2007 0, /* tp_setattro */
2008 0, /* tp_as_buffer */
2009 0, /* tp_flags */
2010 0, /* tp_doc */
2011 0, /* tp_traverse */
2012 0, /* tp_clear */
2013 0, /* tp_richcompare */
2014 0, /* tp_weaklistoffset */
2015 (getiterfunc)odictitems_iter, /* tp_iter */
2016 0, /* tp_iternext */
2017 odictitems_methods, /* tp_methods */
2018 0, /* tp_members */
2019 0, /* tp_getset */
2020 &PyDictItems_Type, /* tp_base */
2021};
2022
2023static PyObject *
2024odictitems_new(PyObject *od)
2025{
2026 return _PyDictView_New(od, &PyODictItems_Type);
2027}
2028
2029/* values() */
2030
2031static PyObject *
2032odictvalues_iter(_PyDictViewObject *dv)
2033{
2034 if (dv->dv_dict == NULL) {
2035 Py_RETURN_NONE;
2036 }
2037 return odictiter_new((PyODictObject *)dv->dv_dict,
2038 _odict_ITER_VALUES);
2039}
2040
2041static PyObject *
2042odictvalues_reversed(_PyDictViewObject *dv)
2043{
2044 if (dv->dv_dict == NULL) {
2045 Py_RETURN_NONE;
2046 }
2047 return odictiter_new((PyODictObject *)dv->dv_dict,
2048 _odict_ITER_VALUES|_odict_ITER_REVERSED);
2049}
2050
2051static PyMethodDef odictvalues_methods[] = {
2052 {"__reversed__", (PyCFunction)odictvalues_reversed, METH_NOARGS, NULL},
2053 {NULL, NULL} /* sentinel */
2054};
2055
2056PyTypeObject PyODictValues_Type = {
2057 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2058 "odict_values", /* tp_name */
2059 0, /* tp_basicsize */
2060 0, /* tp_itemsize */
2061 0, /* tp_dealloc */
2062 0, /* tp_print */
2063 0, /* tp_getattr */
2064 0, /* tp_setattr */
2065 0, /* tp_reserved */
2066 0, /* tp_repr */
2067 0, /* tp_as_number */
2068 0, /* tp_as_sequence */
2069 0, /* tp_as_mapping */
2070 0, /* tp_hash */
2071 0, /* tp_call */
2072 0, /* tp_str */
2073 0, /* tp_getattro */
2074 0, /* tp_setattro */
2075 0, /* tp_as_buffer */
2076 0, /* tp_flags */
2077 0, /* tp_doc */
2078 0, /* tp_traverse */
2079 0, /* tp_clear */
2080 0, /* tp_richcompare */
2081 0, /* tp_weaklistoffset */
2082 (getiterfunc)odictvalues_iter, /* tp_iter */
2083 0, /* tp_iternext */
2084 odictvalues_methods, /* tp_methods */
2085 0, /* tp_members */
2086 0, /* tp_getset */
2087 &PyDictValues_Type, /* tp_base */
2088};
2089
2090static PyObject *
2091odictvalues_new(PyObject *od)
2092{
2093 return _PyDictView_New(od, &PyODictValues_Type);
2094}
2095
2096
2097/* ----------------------------------------------
Martin Panter536d70e2017-01-14 08:23:08 +00002098 MutableMapping implementations
Eric Snow96c6af92015-05-29 22:21:39 -06002099
2100Mapping:
2101
2102============ ===========
2103method uses
2104============ ===========
2105__contains__ __getitem__
2106__eq__ items
2107__getitem__ +
2108__iter__ +
2109__len__ +
2110__ne__ __eq__
2111get __getitem__
2112items ItemsView
2113keys KeysView
2114values ValuesView
2115============ ===========
2116
2117ItemsView uses __len__, __iter__, and __getitem__.
2118KeysView uses __len__, __iter__, and __contains__.
2119ValuesView uses __len__, __iter__, and __getitem__.
2120
2121MutableMapping:
2122
2123============ ===========
2124method uses
2125============ ===========
2126__delitem__ +
2127__setitem__ +
2128clear popitem
2129pop __getitem__
2130 __delitem__
2131popitem __iter__
2132 _getitem__
2133 __delitem__
2134setdefault __getitem__
2135 __setitem__
2136update __setitem__
2137============ ===========
2138*/
2139
2140static int
2141mutablemapping_add_pairs(PyObject *self, PyObject *pairs)
2142{
2143 PyObject *pair, *iterator, *unexpected;
2144 int res = 0;
2145
2146 iterator = PyObject_GetIter(pairs);
2147 if (iterator == NULL)
2148 return -1;
2149 PyErr_Clear();
2150
2151 while ((pair = PyIter_Next(iterator)) != NULL) {
2152 /* could be more efficient (see UNPACK_SEQUENCE in ceval.c) */
Eric Snowc5e59602015-05-30 11:28:56 -06002153 PyObject *key = NULL, *value = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06002154 PyObject *pair_iterator = PyObject_GetIter(pair);
Eric Snowc5e59602015-05-30 11:28:56 -06002155 if (pair_iterator == NULL)
2156 goto Done;
Eric Snow96c6af92015-05-29 22:21:39 -06002157
2158 key = PyIter_Next(pair_iterator);
2159 if (key == NULL) {
2160 if (!PyErr_Occurred())
2161 PyErr_SetString(PyExc_ValueError,
2162 "need more than 0 values to unpack");
2163 goto Done;
2164 }
2165
2166 value = PyIter_Next(pair_iterator);
2167 if (value == NULL) {
2168 if (!PyErr_Occurred())
2169 PyErr_SetString(PyExc_ValueError,
2170 "need more than 1 value to unpack");
2171 goto Done;
2172 }
2173
2174 unexpected = PyIter_Next(pair_iterator);
2175 if (unexpected != NULL) {
2176 Py_DECREF(unexpected);
2177 PyErr_SetString(PyExc_ValueError,
2178 "too many values to unpack (expected 2)");
2179 goto Done;
2180 }
2181 else if (PyErr_Occurred())
2182 goto Done;
2183
2184 res = PyObject_SetItem(self, key, value);
2185
2186Done:
2187 Py_DECREF(pair);
Eric Snowc5e59602015-05-30 11:28:56 -06002188 Py_XDECREF(pair_iterator);
Eric Snow96c6af92015-05-29 22:21:39 -06002189 Py_XDECREF(key);
2190 Py_XDECREF(value);
2191 if (PyErr_Occurred())
2192 break;
2193 }
2194 Py_DECREF(iterator);
2195
2196 if (res < 0 || PyErr_Occurred() != NULL)
2197 return -1;
2198 else
2199 return 0;
2200}
2201
2202static PyObject *
2203mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
2204{
2205 int res = 0;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002206 Py_ssize_t len;
2207 _Py_IDENTIFIER(items);
2208 _Py_IDENTIFIER(keys);
Eric Snow96c6af92015-05-29 22:21:39 -06002209
2210 /* first handle args, if any */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002211 assert(args == NULL || PyTuple_Check(args));
2212 len = (args != NULL) ? PyTuple_GET_SIZE(args) : 0;
Benjamin Peterson99e96f22015-06-06 23:20:32 -05002213 if (len > 1) {
Serhiy Storchakae2f92de2017-11-11 13:06:26 +02002214 const char *msg = "update() takes at most 1 positional argument (%d given)";
Eric Snow96c6af92015-05-29 22:21:39 -06002215 PyErr_Format(PyExc_TypeError, msg, len);
2216 return NULL;
2217 }
Eric Snow96c6af92015-05-29 22:21:39 -06002218
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002219 if (len) {
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002220 PyObject *func;
Benjamin Peterson0718de92015-06-07 00:00:42 -05002221 PyObject *other = PyTuple_GET_ITEM(args, 0); /* borrowed reference */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002222 assert(other != NULL);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002223 Py_INCREF(other);
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002224 if (PyDict_CheckExact(other)) {
2225 PyObject *items = PyDict_Items(other);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002226 Py_DECREF(other);
2227 if (items == NULL)
2228 return NULL;
2229 res = mutablemapping_add_pairs(self, items);
2230 Py_DECREF(items);
2231 if (res == -1)
2232 return NULL;
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002233 goto handle_kwargs;
Benjamin Peterson0718de92015-06-07 00:00:42 -05002234 }
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002235
Serhiy Storchakaf320be72018-01-25 10:49:40 +02002236 if (_PyObject_LookupAttrId(other, &PyId_keys, &func) < 0) {
2237 Py_DECREF(other);
2238 return NULL;
2239 }
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002240 if (func != NULL) {
Benjamin Peterson0718de92015-06-07 00:00:42 -05002241 PyObject *keys, *iterator, *key;
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002242 keys = _PyObject_CallNoArg(func);
2243 Py_DECREF(func);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002244 if (keys == NULL) {
2245 Py_DECREF(other);
2246 return NULL;
2247 }
2248 iterator = PyObject_GetIter(keys);
2249 Py_DECREF(keys);
2250 if (iterator == NULL) {
2251 Py_DECREF(other);
2252 return NULL;
2253 }
2254 while (res == 0 && (key = PyIter_Next(iterator))) {
2255 PyObject *value = PyObject_GetItem(other, key);
2256 if (value != NULL) {
2257 res = PyObject_SetItem(self, key, value);
2258 Py_DECREF(value);
2259 }
2260 else {
2261 res = -1;
2262 }
2263 Py_DECREF(key);
2264 }
2265 Py_DECREF(other);
2266 Py_DECREF(iterator);
2267 if (res != 0 || PyErr_Occurred())
2268 return NULL;
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002269 goto handle_kwargs;
Benjamin Peterson0718de92015-06-07 00:00:42 -05002270 }
Serhiy Storchakaf320be72018-01-25 10:49:40 +02002271
2272 if (_PyObject_LookupAttrId(other, &PyId_items, &func) < 0) {
Eric Snow06aed902016-09-09 11:59:08 -07002273 Py_DECREF(other);
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002274 return NULL;
2275 }
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002276 if (func != NULL) {
2277 PyObject *items;
2278 Py_DECREF(other);
2279 items = _PyObject_CallNoArg(func);
2280 Py_DECREF(func);
Eric Snow06aed902016-09-09 11:59:08 -07002281 if (items == NULL)
2282 return NULL;
2283 res = mutablemapping_add_pairs(self, items);
2284 Py_DECREF(items);
2285 if (res == -1)
2286 return NULL;
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002287 goto handle_kwargs;
2288 }
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002289
2290 res = mutablemapping_add_pairs(self, other);
2291 Py_DECREF(other);
2292 if (res != 0)
2293 return NULL;
Benjamin Peterson0718de92015-06-07 00:00:42 -05002294 }
2295
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002296 handle_kwargs:
Benjamin Peterson0718de92015-06-07 00:00:42 -05002297 /* now handle kwargs */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002298 assert(kwargs == NULL || PyDict_Check(kwargs));
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02002299 if (kwargs != NULL && PyDict_GET_SIZE(kwargs)) {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002300 PyObject *items = PyDict_Items(kwargs);
Eric Snow96c6af92015-05-29 22:21:39 -06002301 if (items == NULL)
2302 return NULL;
2303 res = mutablemapping_add_pairs(self, items);
2304 Py_DECREF(items);
2305 if (res == -1)
2306 return NULL;
2307 }
Eric Snow96c6af92015-05-29 22:21:39 -06002308
2309 Py_RETURN_NONE;
2310}