blob: be61d4eadb2665813643d2b667158c379f55833f [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
70that end, We use a simple API to interact with the linked-list. Here's a
71summary 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
104Used, but specific to the linked-list implementation:
105
106* _odict_free_fast_nodes(od)
107
108And here's a look at how the linked-list relates to the OrderedDict API:
109
110============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
111method key val prev next mem 1st last empty iter find add rmv clr keq
112============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
113__del__ ~ X
114__delitem__ free ~ node
115__eq__ ~ X
116__iter__ X X
117__new__ X X
118__reduce__ X ~ X
119__repr__ X X X
120__reversed__ X X
121__setitem__ key
122__sizeof__ size X
123clear ~ ~ X
124copy X X X
125items X X X
126keys X X
127move_to_end X X X ~ h/t key
128pop free key
129popitem X X free X X node
130setdefault ~ ? ~
131values X X
132============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
133
134__delitem__ is the only method that directly relies on finding an arbitrary
135node in the linked-list. Everything else is iteration or relates to the
136ends of the linked-list.
137
138Situation that Endangers Consistency
139------------------------------------
140Using a raw linked-list for OrderedDict exposes a key situation that can
141cause problems. If a node is stored in a variable, there is a chance that
142the node may have been deallocated before the variable gets used, thus
143potentially leading to a segmentation fault. A key place where this shows
144up is during iteration through the linked list (via _odict_FOREACH or
145otherwise).
146
147A number of solutions are available to resolve this situation:
148
149* defer looking up the node until as late as possible and certainly after
150 any code that could possibly result in a deletion;
151* if the node is needed both before and after a point where the node might
152 be removed, do a check before using the node at the "after" location to
153 see if the node is still valid;
154* like the last one, but simply pull the node again to ensure it's right;
155* keep the key in the variable instead of the node and then look up the
156 node using the key at the point where the node is needed (this is what
157 we do for the iterators).
158
159Another related problem, preserving consistent ordering during iteration,
160is described below. That one is not exclusive to using linked-lists.
161
162
163Challenges from Subclassing dict
164================================
165
166OrderedDict subclasses dict, which is an unusual relationship between two
167builtin types (other than the base object type). Doing so results in
168some complication and deserves further explanation. There are two things
169to consider here. First, in what circumstances or with what adjustments
170can OrderedDict be used as a drop-in replacement for dict (at the C level)?
171Second, how can the OrderedDict implementation leverage the dict
172implementation effectively without introducing unnecessary coupling or
173inefficiencies?
174
175This second point is reflected here and in the implementation, so the
176further focus is on the first point. It is worth noting that for
177overridden methods, the dict implementation is deferred to as much as
178possible. Furthermore, coupling is limited to as little as is reasonable.
179
180Concrete API Compatibility
181--------------------------
182
183Use of the concrete C-API for dict (PyDict_*) with OrderedDict is
184problematic. (See http://bugs.python.org/issue10977.) The concrete API
185has a number of hard-coded assumptions tied to the dict implementation.
186This is, in part, due to performance reasons, which is understandable
187given the part dict plays in Python.
188
189Any attempt to replace dict with OrderedDict for any role in the
190interpreter (e.g. **kwds) faces a challenge. Such any effort must
191recognize that the instances in affected locations currently interact with
192the concrete API.
193
194Here are some ways to address this challenge:
195
1961. Change the relevant usage of the concrete API in CPython and add
Martin Panter69332c12016-08-04 13:07:31 +0000197 PyDict_CheckExact() calls to each of the concrete API functions.
Eric Snow96c6af92015-05-29 22:21:39 -06001982. Adjust the relevant concrete API functions to explicitly accommodate
199 OrderedDict.
2003. As with #1, add the checks, but improve the abstract API with smart fast
201 paths for dict and OrderedDict, and refactor CPython to use the abstract
202 API. Improvements to the abstract API would be valuable regardless.
203
204Adding the checks to the concrete API would help make any interpreter
205switch to OrderedDict less painful for extension modules. However, this
206won't work. The equivalent C API call to `dict.__setitem__(obj, k, v)`
207is 'PyDict_SetItem(obj, k, v)`. This illustrates how subclasses in C call
208the base class's methods, since there is no equivalent of super() in the
209C API. Calling into Python for parent class API would work, but some
210extension modules already rely on this feature of the concrete API.
211
212For reference, here is a breakdown of some of the dict concrete API:
213
214========================== ============= =======================
215concrete API uses abstract API
216========================== ============= =======================
217PyDict_Check PyMapping_Check
218(PyDict_CheckExact) -
219(PyDict_New) -
220(PyDictProxy_New) -
221PyDict_Clear -
222PyDict_Contains PySequence_Contains
223PyDict_Copy -
224PyDict_SetItem PyObject_SetItem
225PyDict_SetItemString PyMapping_SetItemString
226PyDict_DelItem PyMapping_DelItem
227PyDict_DelItemString PyMapping_DelItemString
228PyDict_GetItem -
229PyDict_GetItemWithError PyObject_GetItem
230_PyDict_GetItemIdWithError -
231PyDict_GetItemString PyMapping_GetItemString
232PyDict_Items PyMapping_Items
233PyDict_Keys PyMapping_Keys
234PyDict_Values PyMapping_Values
235PyDict_Size PyMapping_Size
236 PyMapping_Length
237PyDict_Next PyIter_Next
238_PyDict_Next -
239PyDict_Merge -
240PyDict_Update -
241PyDict_MergeFromSeq2 -
242PyDict_ClearFreeList -
243- PyMapping_HasKeyString
244- PyMapping_HasKey
245========================== ============= =======================
246
247
248The dict Interface Relative to OrderedDict
249==========================================
250
251Since OrderedDict subclasses dict, understanding the various methods and
252attributes of dict is important for implementing OrderedDict.
253
254Relevant Type Slots
255-------------------
256
257================= ================ =================== ================
258slot attribute object dict
259================= ================ =================== ================
260tp_dealloc - object_dealloc dict_dealloc
261tp_repr __repr__ object_repr dict_repr
262sq_contains __contains__ - dict_contains
263mp_length __len__ - dict_length
264mp_subscript __getitem__ - dict_subscript
265mp_ass_subscript __setitem__ - dict_ass_sub
266 __delitem__
267tp_hash __hash__ _Py_HashPointer ..._HashNotImpl
268tp_str __str__ object_str -
269tp_getattro __getattribute__ ..._GenericGetAttr (repeated)
270 __getattr__
271tp_setattro __setattr__ ..._GenericSetAttr (disabled)
272tp_doc __doc__ (literal) dictionary_doc
273tp_traverse - - dict_traverse
274tp_clear - - dict_tp_clear
275tp_richcompare __eq__ object_richcompare dict_richcompare
276 __ne__
277tp_weaklistoffset (__weakref__) - -
278tp_iter __iter__ - dict_iter
279tp_dictoffset (__dict__) - -
280tp_init __init__ object_init dict_init
281tp_alloc - PyType_GenericAlloc (repeated)
282tp_new __new__ object_new dict_new
283tp_free - PyObject_Del PyObject_GC_Del
284================= ================ =================== ================
285
286Relevant Methods
287----------------
288
289================ =================== ===============
290method object dict
291================ =================== ===============
292__reduce__ object_reduce -
293__sizeof__ object_sizeof dict_sizeof
294clear - dict_clear
295copy - dict_copy
296fromkeys - dict_fromkeys
297get - dict_get
298items - dictitems_new
299keys - dictkeys_new
300pop - dict_pop
301popitem - dict_popitem
302setdefault - dict_setdefault
303update - dict_update
304values - dictvalues_new
305================ =================== ===============
306
307
308Pure Python OrderedDict
309=======================
310
311As already noted, compatibility with the pure Python OrderedDict
312implementation is a key goal of this C implementation. To further that
313goal, here's a summary of how OrderedDict-specific methods are implemented
314in collections/__init__.py. Also provided is an indication of which
315methods directly mutate or iterate the object, as well as any relationship
316with the underlying linked-list.
317
318============= ============== == ================ === === ====
319method impl used ll uses inq mut iter
320============= ============== == ================ === === ====
321__contains__ dict - - X
322__delitem__ OrderedDict Y dict.__delitem__ X
323__eq__ OrderedDict N OrderedDict ~
324 dict.__eq__
325 __iter__
326__getitem__ dict - - X
327__iter__ OrderedDict Y - X
328__init__ OrderedDict N update
329__len__ dict - - X
330__ne__ MutableMapping - __eq__ ~
331__reduce__ OrderedDict N OrderedDict ~
332 __iter__
333 __getitem__
334__repr__ OrderedDict N __class__ ~
335 items
336__reversed__ OrderedDict Y - X
337__setitem__ OrderedDict Y __contains__ X
338 dict.__setitem__
339__sizeof__ OrderedDict Y __len__ ~
340 __dict__
341clear OrderedDict Y dict.clear X
342copy OrderedDict N __class__
343 __init__
344fromkeys OrderedDict N __setitem__
345get dict - - ~
346items MutableMapping - ItemsView X
347keys MutableMapping - KeysView X
348move_to_end OrderedDict Y - X
349pop OrderedDict N __contains__ X
350 __getitem__
351 __delitem__
352popitem OrderedDict Y dict.pop X
353setdefault OrderedDict N __contains__ ~
354 __getitem__
355 __setitem__
356update MutableMapping - __setitem__ ~
357values MutableMapping - ValuesView X
358============= ============== == ================ === === ====
359
360__reversed__ and move_to_end are both exclusive to OrderedDict.
361
362
363C OrderedDict Implementation
364============================
365
366================= ================
367slot impl
368================= ================
369tp_dealloc odict_dealloc
370tp_repr odict_repr
371mp_ass_subscript odict_ass_sub
372tp_doc odict_doc
373tp_traverse odict_traverse
374tp_clear odict_tp_clear
375tp_richcompare odict_richcompare
376tp_weaklistoffset (offset)
377tp_iter odict_iter
378tp_dictoffset (offset)
379tp_init odict_init
380tp_alloc (repeated)
381tp_new odict_new
382================= ================
383
384================= ================
385method impl
386================= ================
387__reduce__ odict_reduce
388__sizeof__ odict_sizeof
389clear odict_clear
390copy odict_copy
391fromkeys odict_fromkeys
392items odictitems_new
393keys odictkeys_new
394pop odict_pop
395popitem odict_popitem
396setdefault odict_setdefault
397update odict_update
398values odictvalues_new
399================= ================
400
401Inherited unchanged from object/dict:
402
403================ ==========================
404method type field
405================ ==========================
406- tp_free
407__contains__ tp_as_sequence.sq_contains
408__getattr__ tp_getattro
409__getattribute__ tp_getattro
410__getitem__ tp_as_mapping.mp_subscript
411__hash__ tp_hash
412__len__ tp_as_mapping.mp_length
413__setattr__ tp_setattro
414__str__ tp_str
415get -
416================ ==========================
417
418
419Other Challenges
420================
421
422Preserving Ordering During Iteration
423------------------------------------
424During iteration through an OrderedDict, it is possible that items could
425get added, removed, or reordered. For a linked-list implementation, as
426with some other implementations, that situation may lead to undefined
427behavior. The documentation for dict mentions this in the `iter()` section
428of http://docs.python.org/3.4/library/stdtypes.html#dictionary-view-objects.
429In this implementation we follow dict's lead (as does the pure Python
430implementation) for __iter__(), keys(), values(), and items().
431
432For internal iteration (using _odict_FOREACH or not), there is still the
433risk that not all nodes that we expect to be seen in the loop actually get
434seen. Thus, we are careful in each of those places to ensure that they
435are. This comes, of course, at a small price at each location. The
436solutions are much the same as those detailed in the `Situation that
437Endangers Consistency` section above.
438
439
440Potential Optimizations
441=======================
442
443* Allocate the nodes as a block via od_fast_nodes instead of individually.
444 - Set node->key to NULL to indicate the node is not-in-use.
445 - Add _odict_EXISTS()?
446 - How to maintain consistency across resizes? Existing node pointers
447 would be invalidate after a resize, which is particularly problematic
448 for the iterators.
449* Use a more stream-lined implementation of update() and, likely indirectly,
450 __init__().
451
452*/
453
454/* TODO
455
456sooner:
457- reentrancy (make sure everything is at a thread-safe state when calling
458 into Python). I've already checked this multiple times, but want to
459 make one more pass.
460- add unit tests for reentrancy?
461
462later:
463- make the dict views support the full set API (the pure Python impl does)
464- implement a fuller MutableMapping API in C?
465- move the MutableMapping implementation to abstract.c?
466- optimize mutablemapping_update
467- use PyObject_MALLOC (small object allocator) for odict nodes?
468- support subclasses better (e.g. in odict_richcompare)
469
470*/
471
472#include "Python.h"
473#include "structmember.h"
474#include "dict-common.h"
475#include <stddef.h>
476
477
478typedef struct _odictnode _ODictNode;
479
480/* PyODictObject */
481struct _odictobject {
Eric Snow4fabf022015-06-04 00:09:56 -0600482 PyDictObject od_dict; /* the underlying dict */
483 _ODictNode *od_first; /* first node in the linked list, if any */
484 _ODictNode *od_last; /* last node in the linked list, if any */
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200485 /* od_fast_nodes, od_fast_nodes_size and od_resize_sentinel are managed
486 * by _odict_resize().
Eric Snow8c7f9552015-08-07 17:45:12 -0600487 * Note that we rely on implementation details of dict for both. */
488 _ODictNode **od_fast_nodes; /* hash table that mirrors the dict table */
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200489 Py_ssize_t od_fast_nodes_size;
490 void *od_resize_sentinel; /* changes if odict should be resized */
Eric Snow8c7f9552015-08-07 17:45:12 -0600491
Eric Snow4fabf022015-06-04 00:09:56 -0600492 size_t od_state; /* incremented whenever the LL changes */
493 PyObject *od_inst_dict; /* OrderedDict().__dict__ */
494 PyObject *od_weakreflist; /* holds weakrefs to the odict */
Eric Snow96c6af92015-05-29 22:21:39 -0600495};
496
497
498/* ----------------------------------------------
499 * odict keys (a simple doubly-linked list)
500 */
501
502struct _odictnode {
503 PyObject *key;
Eric Snow4c729182015-06-03 10:50:37 -0600504 Py_hash_t hash;
Eric Snow96c6af92015-05-29 22:21:39 -0600505 _ODictNode *next;
506 _ODictNode *prev;
507};
508
509#define _odictnode_KEY(node) \
510 (node->key)
Eric Snow4c729182015-06-03 10:50:37 -0600511#define _odictnode_HASH(node) \
512 (node->hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600513/* borrowed reference */
514#define _odictnode_VALUE(node, od) \
Eric Snowa762af72015-06-01 22:59:08 -0600515 PyODict_GetItemWithError((PyObject *)od, _odictnode_KEY(node))
Eric Snow96c6af92015-05-29 22:21:39 -0600516#define _odictnode_PREV(node) (node->prev)
517#define _odictnode_NEXT(node) (node->next)
518
519#define _odict_FIRST(od) (((PyODictObject *)od)->od_first)
520#define _odict_LAST(od) (((PyODictObject *)od)->od_last)
521#define _odict_EMPTY(od) (_odict_FIRST(od) == NULL)
522#define _odict_FOREACH(od, node) \
523 for (node = _odict_FIRST(od); node != NULL; node = _odictnode_NEXT(node))
524
Eric Snow8c7f9552015-08-07 17:45:12 -0600525#define _odict_FAST_SIZE(od) ((PyDictObject *)od)->ma_keys->dk_size
Eric Snow96c6af92015-05-29 22:21:39 -0600526
Eric Snow96c6af92015-05-29 22:21:39 -0600527static void
528_odict_free_fast_nodes(PyODictObject *od) {
529 if (od->od_fast_nodes) {
530 PyMem_FREE(od->od_fast_nodes);
531 }
532}
533
Eric Snow4c729182015-06-03 10:50:37 -0600534/* Return the index into the hash table, regardless of a valid node. */
535static Py_ssize_t
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200536_odict_get_index_raw(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow4c729182015-06-03 10:50:37 -0600537{
538 PyObject **value_addr = NULL;
Eric Snow4c729182015-06-03 10:50:37 -0600539 PyDictKeysObject *keys = ((PyDictObject *)od)->ma_keys;
Victor Stinner742da042016-09-07 17:40:12 -0700540 Py_ssize_t ix;
Eric Snow4c729182015-06-03 10:50:37 -0600541
Victor Stinner742da042016-09-07 17:40:12 -0700542 ix = (keys->dk_lookup)((PyDictObject *)od, key, hash, &value_addr, NULL);
543 if (ix == DKIX_EMPTY) {
544 return keys->dk_nentries; /* index of new entry */
545 }
546 if (ix < 0)
Eric Snow4c729182015-06-03 10:50:37 -0600547 return -1;
548 /* We use pointer arithmetic to get the entry's index into the table. */
Victor Stinner742da042016-09-07 17:40:12 -0700549 return ix;
Eric Snow4c729182015-06-03 10:50:37 -0600550}
551
552/* Replace od->od_fast_nodes with a new table matching the size of dict's. */
Eric Snow96c6af92015-05-29 22:21:39 -0600553static int
554_odict_resize(PyODictObject *od) {
Eric Snow4c729182015-06-03 10:50:37 -0600555 Py_ssize_t size, i;
Eric Snow96c6af92015-05-29 22:21:39 -0600556 _ODictNode **fast_nodes, *node;
557
558 /* Initialize a new "fast nodes" table. */
559 size = ((PyDictObject *)od)->ma_keys->dk_size;
560 fast_nodes = PyMem_NEW(_ODictNode *, size);
561 if (fast_nodes == NULL) {
562 PyErr_NoMemory();
563 return -1;
564 }
565 for (i = 0; i < size; i++)
566 fast_nodes[i] = NULL;
567
568 /* Copy the current nodes into the table. */
Eric Snow96c6af92015-05-29 22:21:39 -0600569 _odict_FOREACH(od, node) {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200570 i = _odict_get_index_raw(od, _odictnode_KEY(node),
Victor Stinner742da042016-09-07 17:40:12 -0700571 _odictnode_HASH(node));
Eric Snow96c6af92015-05-29 22:21:39 -0600572 if (i < 0) {
Eric Snow96c6af92015-05-29 22:21:39 -0600573 PyMem_FREE(fast_nodes);
574 return -1;
575 }
576 fast_nodes[i] = node;
577 }
Eric Snow96c6af92015-05-29 22:21:39 -0600578
579 /* Replace the old fast nodes table. */
580 _odict_free_fast_nodes(od);
581 od->od_fast_nodes = fast_nodes;
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200582 od->od_fast_nodes_size = size;
583 od->od_resize_sentinel = ((PyDictObject *)od)->ma_keys;
Eric Snow96c6af92015-05-29 22:21:39 -0600584 return 0;
585}
586
587/* Return the index into the hash table, regardless of a valid node. */
588static Py_ssize_t
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200589_odict_get_index(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600590{
Eric Snow4c729182015-06-03 10:50:37 -0600591 PyDictKeysObject *keys;
Eric Snow96c6af92015-05-29 22:21:39 -0600592
593 assert(key != NULL);
Eric Snow4c729182015-06-03 10:50:37 -0600594 keys = ((PyDictObject *)od)->ma_keys;
595
596 /* Ensure od_fast_nodes and dk_entries are in sync. */
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200597 if (od->od_resize_sentinel != keys ||
598 od->od_fast_nodes_size != keys->dk_size) {
Eric Snow4c729182015-06-03 10:50:37 -0600599 int resize_res = _odict_resize(od);
600 if (resize_res < 0)
601 return -1;
602 }
603
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200604 return _odict_get_index_raw(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600605}
606
Eric Snow96c6af92015-05-29 22:21:39 -0600607/* Returns NULL if there was some error or the key was not found. */
608static _ODictNode *
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200609_odict_find_node_hash(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600610{
611 Py_ssize_t index;
612
613 if (_odict_EMPTY(od))
614 return NULL;
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200615 index = _odict_get_index(od, key, hash);
616 if (index < 0)
617 return NULL;
618 return od->od_fast_nodes[index];
619}
620
621static _ODictNode *
622_odict_find_node(PyODictObject *od, PyObject *key)
623{
624 Py_ssize_t index;
625 Py_hash_t hash;
626
627 if (_odict_EMPTY(od))
628 return NULL;
629 hash = PyObject_Hash(key);
630 if (hash == -1)
631 return NULL;
632 index = _odict_get_index(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600633 if (index < 0)
634 return NULL;
635 return od->od_fast_nodes[index];
636}
637
638static void
639_odict_add_head(PyODictObject *od, _ODictNode *node)
640{
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300641 _odictnode_PREV(node) = NULL;
642 _odictnode_NEXT(node) = _odict_FIRST(od);
643 if (_odict_FIRST(od) == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -0600644 _odict_LAST(od) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300645 else
Eric Snow96c6af92015-05-29 22:21:39 -0600646 _odictnode_PREV(_odict_FIRST(od)) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300647 _odict_FIRST(od) = node;
Eric Snow4fabf022015-06-04 00:09:56 -0600648 od->od_state++;
Eric Snow96c6af92015-05-29 22:21:39 -0600649}
650
651static void
652_odict_add_tail(PyODictObject *od, _ODictNode *node)
653{
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300654 _odictnode_PREV(node) = _odict_LAST(od);
655 _odictnode_NEXT(node) = NULL;
656 if (_odict_LAST(od) == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -0600657 _odict_FIRST(od) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300658 else
Eric Snow96c6af92015-05-29 22:21:39 -0600659 _odictnode_NEXT(_odict_LAST(od)) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300660 _odict_LAST(od) = node;
Eric Snow4fabf022015-06-04 00:09:56 -0600661 od->od_state++;
Eric Snow96c6af92015-05-29 22:21:39 -0600662}
663
664/* adds the node to the end of the list */
665static int
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200666_odict_add_new_node(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600667{
668 Py_ssize_t i;
669 _ODictNode *node;
670
Serhiy Storchakad17427b2015-10-20 18:21:48 +0300671 Py_INCREF(key);
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200672 i = _odict_get_index(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600673 if (i < 0) {
674 if (!PyErr_Occurred())
675 PyErr_SetObject(PyExc_KeyError, key);
676 Py_DECREF(key);
677 return -1;
678 }
679 else if (od->od_fast_nodes[i] != NULL) {
680 /* We already have a node for the key so there's no need to add one. */
681 Py_DECREF(key);
682 return 0;
683 }
684
685 /* must not be added yet */
686 node = (_ODictNode *)PyMem_MALLOC(sizeof(_ODictNode));
687 if (node == NULL) {
688 Py_DECREF(key);
689 PyErr_NoMemory();
690 return -1;
691 }
692
693 _odictnode_KEY(node) = key;
Eric Snow4c729182015-06-03 10:50:37 -0600694 _odictnode_HASH(node) = hash;
Eric Snow96c6af92015-05-29 22:21:39 -0600695 _odict_add_tail(od, node);
696 od->od_fast_nodes[i] = node;
697 return 0;
698}
699
700/* Putting the decref after the free causes problems. */
701#define _odictnode_DEALLOC(node) \
702 do { \
703 Py_DECREF(_odictnode_KEY(node)); \
704 PyMem_FREE((void *)node); \
705 } while (0)
706
707/* Repeated calls on the same node are no-ops. */
708static void
709_odict_remove_node(PyODictObject *od, _ODictNode *node)
710{
711 if (_odict_FIRST(od) == node)
712 _odict_FIRST(od) = _odictnode_NEXT(node);
713 else if (_odictnode_PREV(node) != NULL)
714 _odictnode_NEXT(_odictnode_PREV(node)) = _odictnode_NEXT(node);
715
716 if (_odict_LAST(od) == node)
717 _odict_LAST(od) = _odictnode_PREV(node);
718 else if (_odictnode_NEXT(node) != NULL)
719 _odictnode_PREV(_odictnode_NEXT(node)) = _odictnode_PREV(node);
720
721 _odictnode_PREV(node) = NULL;
722 _odictnode_NEXT(node) = NULL;
Eric Snow4fabf022015-06-04 00:09:56 -0600723 od->od_state++;
Eric Snow96c6af92015-05-29 22:21:39 -0600724}
725
Eric Snow96c6af92015-05-29 22:21:39 -0600726/* If someone calls PyDict_DelItem() directly on an OrderedDict, we'll
727 get all sorts of problems here. In PyODict_DelItem we make sure to
728 call _odict_clear_node first.
Victor Stinnerca30b022015-09-03 17:50:04 +0200729
Eric Snow96c6af92015-05-29 22:21:39 -0600730 This matters in the case of colliding keys. Suppose we add 3 keys:
731 [A, B, C], where the hash of C collides with A and the next possible
732 index in the hash table is occupied by B. If we remove B then for C
733 the dict's looknode func will give us the old index of B instead of
734 the index we got before deleting B. However, the node for C in
735 od_fast_nodes is still at the old dict index of C. Thus to be sure
736 things don't get out of sync, we clear the node in od_fast_nodes
737 *before* calling PyDict_DelItem.
738
739 The same must be done for any other OrderedDict operations where
740 we modify od_fast_nodes.
741*/
742static int
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200743_odict_clear_node(PyODictObject *od, _ODictNode *node, PyObject *key,
744 Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600745{
746 Py_ssize_t i;
747
748 assert(key != NULL);
749 if (_odict_EMPTY(od)) {
750 /* Let later code decide if this is a KeyError. */
751 return 0;
752 }
753
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200754 i = _odict_get_index(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600755 if (i < 0)
756 return PyErr_Occurred() ? -1 : 0;
757
758 if (node == NULL)
759 node = od->od_fast_nodes[i];
760 assert(node == od->od_fast_nodes[i]);
761 if (node == NULL) {
762 /* Let later code decide if this is a KeyError. */
763 return 0;
764 }
765
766 // Now clear the node.
767 od->od_fast_nodes[i] = NULL;
768 _odict_remove_node(od, node);
769 _odictnode_DEALLOC(node);
770 return 0;
771}
772
773static void
774_odict_clear_nodes(PyODictObject *od)
775{
776 _ODictNode *node, *next;
777
Eric Snow96c6af92015-05-29 22:21:39 -0600778 _odict_free_fast_nodes(od);
779 od->od_fast_nodes = NULL;
Serhiy Storchakad205d012016-01-19 14:46:25 +0200780
781 node = _odict_FIRST(od);
782 _odict_FIRST(od) = NULL;
783 _odict_LAST(od) = NULL;
784 while (node != NULL) {
785 next = _odictnode_NEXT(node);
786 _odictnode_DEALLOC(node);
787 node = next;
788 }
Eric Snow96c6af92015-05-29 22:21:39 -0600789}
790
791/* There isn't any memory management of nodes past this point. */
792#undef _odictnode_DEALLOC
793
794static int
795_odict_keys_equal(PyODictObject *a, PyODictObject *b)
796{
797 _ODictNode *node_a, *node_b;
798
799 node_a = _odict_FIRST(a);
800 node_b = _odict_FIRST(b);
801 while (1) {
802 if (node_a == NULL && node_b == NULL)
803 /* success: hit the end of each at the same time */
804 return 1;
805 else if (node_a == NULL || node_b == NULL)
806 /* unequal length */
807 return 0;
808 else {
809 int res = PyObject_RichCompareBool(
810 (PyObject *)_odictnode_KEY(node_a),
811 (PyObject *)_odictnode_KEY(node_b),
812 Py_EQ);
813 if (res < 0)
814 return res;
815 else if (res == 0)
816 return 0;
817
818 /* otherwise it must match, so move on to the next one */
819 node_a = _odictnode_NEXT(node_a);
820 node_b = _odictnode_NEXT(node_b);
821 }
822 }
823}
824
825
826/* ----------------------------------------------
827 * OrderedDict mapping methods
828 */
829
830/* mp_ass_subscript: __setitem__() and __delitem__() */
831
832static int
833odict_mp_ass_sub(PyODictObject *od, PyObject *v, PyObject *w)
834{
835 if (w == NULL)
836 return PyODict_DelItem((PyObject *)od, v);
837 else
838 return PyODict_SetItem((PyObject *)od, v, w);
839}
840
841/* tp_as_mapping */
842
843static PyMappingMethods odict_as_mapping = {
844 0, /*mp_length*/
845 0, /*mp_subscript*/
846 (objobjargproc)odict_mp_ass_sub, /*mp_ass_subscript*/
847};
848
849
850/* ----------------------------------------------
851 * OrderedDict methods
852 */
853
854/* __delitem__() */
855
856PyDoc_STRVAR(odict_delitem__doc__, "od.__delitem__(y) <==> del od[y]");
857
858/* __eq__() */
859
860PyDoc_STRVAR(odict_eq__doc__,
861"od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive \n\
862 while comparison to a regular mapping is order-insensitive.\n\
863 ");
864
865/* forward */
866static PyObject * odict_richcompare(PyObject *v, PyObject *w, int op);
867
868static PyObject *
869odict_eq(PyObject *a, PyObject *b)
870{
871 return odict_richcompare(a, b, Py_EQ);
872}
873
874/* __init__() */
875
876PyDoc_STRVAR(odict_init__doc__,
877"Initialize an ordered dictionary. The signature is the same as\n\
878 regular dictionaries, but keyword arguments are not recommended because\n\
879 their insertion order is arbitrary.\n\
880\n\
881 ");
882
883/* forward */
884static int odict_init(PyObject *self, PyObject *args, PyObject *kwds);
885
886/* __iter__() */
887
888PyDoc_STRVAR(odict_iter__doc__, "od.__iter__() <==> iter(od)");
889
890static PyObject * odict_iter(PyODictObject *self); /* forward */
891
892/* __ne__() */
893
894/* Mapping.__ne__() does not have a docstring. */
895PyDoc_STRVAR(odict_ne__doc__, "");
896
897static PyObject *
898odict_ne(PyObject *a, PyObject *b)
899{
900 return odict_richcompare(a, b, Py_NE);
901}
902
903/* __repr__() */
904
905PyDoc_STRVAR(odict_repr__doc__, "od.__repr__() <==> repr(od)");
906
907static PyObject * odict_repr(PyODictObject *self); /* forward */
908
909/* __setitem__() */
910
911PyDoc_STRVAR(odict_setitem__doc__, "od.__setitem__(i, y) <==> od[i]=y");
912
913/* fromkeys() */
914
915PyDoc_STRVAR(odict_fromkeys__doc__,
916"OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.\n\
917 If not specified, the value defaults to None.\n\
918\n\
919 ");
920
921static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -0600922odict_fromkeys(PyObject *cls, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -0600923{
Eric Snowac02ef32015-06-02 20:42:14 -0600924 static char *kwlist[] = {"iterable", "value", 0};
Eric Snow96c6af92015-05-29 22:21:39 -0600925 PyObject *seq;
926 PyObject *value = Py_None;
Eric Snowac02ef32015-06-02 20:42:14 -0600927
928 /* both borrowed */
929 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:fromkeys", kwlist,
930 &seq, &value)) {
Eric Snow96c6af92015-05-29 22:21:39 -0600931 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -0600932 }
Eric Snow96c6af92015-05-29 22:21:39 -0600933 return _PyDict_FromKeys(cls, seq, value);
934}
935
936/* __sizeof__() */
937
938/* OrderedDict.__sizeof__() does not have a docstring. */
939PyDoc_STRVAR(odict_sizeof__doc__, "");
940
941static PyObject *
942odict_sizeof(PyODictObject *od)
943{
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +0200944 Py_ssize_t res = _PyDict_SizeOf((PyDictObject *)od);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300945 res += sizeof(_ODictNode *) * _odict_FAST_SIZE(od); /* od_fast_nodes */
Eric Snow96c6af92015-05-29 22:21:39 -0600946 if (!_odict_EMPTY(od)) {
947 res += sizeof(_ODictNode) * PyODict_SIZE(od); /* linked-list */
948 }
949 return PyLong_FromSsize_t(res);
950}
951
952/* __reduce__() */
953
954PyDoc_STRVAR(odict_reduce__doc__, "Return state information for pickling");
955
956static PyObject *
957odict_reduce(register PyODictObject *od)
958{
959 _Py_IDENTIFIER(__dict__);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300960 _Py_IDENTIFIER(items);
Serhiy Storchaka4575beb2015-10-22 20:18:24 +0300961 PyObject *dict = NULL, *result = NULL;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300962 PyObject *items_iter, *items, *args = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -0600963
964 /* capture any instance state */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300965 dict = _PyObject_GetAttrId((PyObject *)od, &PyId___dict__);
966 if (dict == NULL)
Eric Snowc5e59602015-05-30 11:28:56 -0600967 goto Done;
968 else {
Eric Snow96c6af92015-05-29 22:21:39 -0600969 /* od.__dict__ isn't necessarily a dict... */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300970 Py_ssize_t dict_len = PyObject_Length(dict);
971 if (dict_len == -1)
Eric Snow96c6af92015-05-29 22:21:39 -0600972 goto Done;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300973 if (!dict_len) {
974 /* nothing to pickle in od.__dict__ */
975 Py_CLEAR(dict);
Eric Snow96c6af92015-05-29 22:21:39 -0600976 }
977 }
978
979 /* build the result */
Eric Snow96c6af92015-05-29 22:21:39 -0600980 args = PyTuple_New(0);
981 if (args == NULL)
982 goto Done;
983
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300984 items = _PyObject_CallMethodIdObjArgs((PyObject *)od, &PyId_items, NULL);
Eric Snow96c6af92015-05-29 22:21:39 -0600985 if (items == NULL)
986 goto Done;
987
988 items_iter = PyObject_GetIter(items);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300989 Py_DECREF(items);
Eric Snow96c6af92015-05-29 22:21:39 -0600990 if (items_iter == NULL)
991 goto Done;
992
Serhiy Storchaka4575beb2015-10-22 20:18:24 +0300993 result = PyTuple_Pack(5, Py_TYPE(od), args, dict ? dict : Py_None, Py_None, items_iter);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300994 Py_DECREF(items_iter);
Eric Snow96c6af92015-05-29 22:21:39 -0600995
996Done:
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300997 Py_XDECREF(dict);
Eric Snow96c6af92015-05-29 22:21:39 -0600998 Py_XDECREF(args);
Eric Snow96c6af92015-05-29 22:21:39 -0600999
1000 return result;
1001}
1002
1003/* setdefault() */
1004
1005PyDoc_STRVAR(odict_setdefault__doc__,
1006 "od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od");
1007
1008/* Skips __missing__() calls. */
1009static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001010odict_setdefault(register PyODictObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001011{
Eric Snowac02ef32015-06-02 20:42:14 -06001012 static char *kwlist[] = {"key", "default", 0};
Eric Snow96c6af92015-05-29 22:21:39 -06001013 PyObject *key, *result = NULL;
1014 PyObject *failobj = Py_None;
1015
1016 /* both borrowed */
Eric Snowac02ef32015-06-02 20:42:14 -06001017 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:setdefault", kwlist,
1018 &key, &failobj)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001019 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001020 }
Eric Snow96c6af92015-05-29 22:21:39 -06001021
1022 if (PyODict_CheckExact(od)) {
Eric Snowd1719752015-06-01 23:12:13 -06001023 result = PyODict_GetItemWithError(od, key); /* borrowed */
1024 if (result == NULL) {
1025 if (PyErr_Occurred())
1026 return NULL;
1027 assert(_odict_find_node(od, key) == NULL);
1028 if (PyODict_SetItem((PyObject *)od, key, failobj) >= 0) {
Eric Snow96c6af92015-05-29 22:21:39 -06001029 result = failobj;
1030 Py_INCREF(failobj);
1031 }
1032 }
1033 else {
Eric Snowd1719752015-06-01 23:12:13 -06001034 Py_INCREF(result);
Eric Snow96c6af92015-05-29 22:21:39 -06001035 }
1036 }
1037 else {
1038 int exists = PySequence_Contains((PyObject *)od, key);
1039 if (exists < 0) {
Eric Snowd1719752015-06-01 23:12:13 -06001040 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001041 }
1042 else if (exists) {
1043 result = PyObject_GetItem((PyObject *)od, key);
1044 }
1045 else if (PyObject_SetItem((PyObject *)od, key, failobj) >= 0) {
1046 result = failobj;
1047 Py_INCREF(failobj);
1048 }
1049 }
1050
Eric Snow96c6af92015-05-29 22:21:39 -06001051 return result;
1052}
1053
1054/* pop() */
1055
1056PyDoc_STRVAR(odict_pop__doc__,
1057"od.pop(k[,d]) -> v, remove specified key and return the corresponding\n\
1058 value. If key is not found, d is returned if given, otherwise KeyError\n\
1059 is raised.\n\
1060\n\
1061 ");
1062
1063/* forward */
1064static PyObject * _odict_popkey(PyObject *, PyObject *, PyObject *);
1065
1066/* Skips __missing__() calls. */
1067static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001068odict_pop(PyObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001069{
Eric Snowac02ef32015-06-02 20:42:14 -06001070 static char *kwlist[] = {"key", "default", 0};
Eric Snow96c6af92015-05-29 22:21:39 -06001071 PyObject *key, *failobj = NULL;
1072
Eric Snowac02ef32015-06-02 20:42:14 -06001073 /* borrowed */
1074 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:pop", kwlist,
1075 &key, &failobj)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001076 return NULL;
1077 }
1078
1079 return _odict_popkey(od, key, failobj);
1080}
1081
1082static PyObject *
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001083_odict_popkey_hash(PyObject *od, PyObject *key, PyObject *failobj,
1084 Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -06001085{
1086 _ODictNode *node;
1087 PyObject *value = NULL;
1088
Eric Snow96c6af92015-05-29 22:21:39 -06001089 /* Pop the node first to avoid a possible dict resize (due to
1090 eval loop reentrancy) and complications due to hash collision
1091 resolution. */
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001092 node = _odict_find_node_hash((PyODictObject *)od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001093 if (node == NULL) {
1094 if (PyErr_Occurred())
Eric Snowd1719752015-06-01 23:12:13 -06001095 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001096 }
1097 else {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001098 int res = _odict_clear_node((PyODictObject *)od, node, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001099 if (res < 0) {
Eric Snowd1719752015-06-01 23:12:13 -06001100 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001101 }
1102 }
1103
1104 /* Now delete the value from the dict. */
Serhiy Storchaka48325802016-10-25 15:33:23 +03001105 if (node != NULL) {
1106 value = _PyDict_GetItem_KnownHash(od, key, hash); /* borrowed */
1107 if (value != NULL) {
1108 Py_INCREF(value);
1109 if (_PyDict_DelItem_KnownHash(od, key, hash) < 0) {
1110 Py_DECREF(value);
1111 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001112 }
1113 }
1114 }
1115
1116 /* Apply the fallback value, if necessary. */
1117 if (value == NULL && !PyErr_Occurred()) {
1118 if (failobj) {
1119 value = failobj;
1120 Py_INCREF(failobj);
1121 }
1122 else {
1123 PyErr_SetObject(PyExc_KeyError, key);
1124 }
1125 }
1126
Eric Snow96c6af92015-05-29 22:21:39 -06001127 return value;
1128}
1129
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001130static PyObject *
1131_odict_popkey(PyObject *od, PyObject *key, PyObject *failobj)
1132{
1133 Py_hash_t hash = PyObject_Hash(key);
1134 if (hash == -1)
1135 return NULL;
1136
1137 return _odict_popkey_hash(od, key, failobj, hash);
1138}
1139
Eric Snow96c6af92015-05-29 22:21:39 -06001140/* popitem() */
1141
1142PyDoc_STRVAR(odict_popitem__doc__,
1143"od.popitem() -> (k, v), return and remove a (key, value) pair.\n\
1144 Pairs are returned in LIFO order if last is true or FIFO order if false.\n\
1145\n\
1146 ");
1147
1148static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001149odict_popitem(PyObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001150{
Eric Snowac02ef32015-06-02 20:42:14 -06001151 static char *kwlist[] = {"last", 0};
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001152 PyObject *key, *value, *item = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001153 _ODictNode *node;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001154 int last = 1;
Eric Snow96c6af92015-05-29 22:21:39 -06001155
1156 /* pull the item */
1157
Eric Snowac02ef32015-06-02 20:42:14 -06001158 /* borrowed */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001159 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|p:popitem", kwlist,
Eric Snowac02ef32015-06-02 20:42:14 -06001160 &last)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001161 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001162 }
Eric Snow96c6af92015-05-29 22:21:39 -06001163
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001164 if (_odict_EMPTY(od)) {
1165 PyErr_SetString(PyExc_KeyError, "dictionary is empty");
1166 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001167 }
Eric Snow96c6af92015-05-29 22:21:39 -06001168
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001169 node = last ? _odict_LAST(od) : _odict_FIRST(od);
Eric Snow96c6af92015-05-29 22:21:39 -06001170 key = _odictnode_KEY(node);
Eric Snowd1719752015-06-01 23:12:13 -06001171 Py_INCREF(key);
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001172 value = _odict_popkey_hash(od, key, NULL, _odictnode_HASH(node));
Eric Snow96c6af92015-05-29 22:21:39 -06001173 if (value == NULL)
1174 return NULL;
1175 item = PyTuple_Pack(2, key, value);
Eric Snowd1719752015-06-01 23:12:13 -06001176 Py_DECREF(key);
Eric Snow96c6af92015-05-29 22:21:39 -06001177 Py_DECREF(value);
1178 return item;
1179}
1180
1181/* keys() */
1182
1183/* MutableMapping.keys() does not have a docstring. */
1184PyDoc_STRVAR(odict_keys__doc__, "");
1185
1186static PyObject * odictkeys_new(PyObject *od); /* forward */
1187
1188/* values() */
1189
1190/* MutableMapping.values() does not have a docstring. */
1191PyDoc_STRVAR(odict_values__doc__, "");
1192
1193static PyObject * odictvalues_new(PyObject *od); /* forward */
1194
1195/* items() */
1196
1197/* MutableMapping.items() does not have a docstring. */
1198PyDoc_STRVAR(odict_items__doc__, "");
1199
1200static PyObject * odictitems_new(PyObject *od); /* forward */
1201
1202/* update() */
1203
1204/* MutableMapping.update() does not have a docstring. */
1205PyDoc_STRVAR(odict_update__doc__, "");
1206
1207/* forward */
1208static PyObject * mutablemapping_update(PyObject *, PyObject *, PyObject *);
1209
1210#define odict_update mutablemapping_update
1211
1212/* clear() */
1213
1214PyDoc_STRVAR(odict_clear__doc__,
1215 "od.clear() -> None. Remove all items from od.");
1216
1217static PyObject *
1218odict_clear(register PyODictObject *od)
1219{
1220 PyDict_Clear((PyObject *)od);
1221 _odict_clear_nodes(od);
Eric Snow96c6af92015-05-29 22:21:39 -06001222 if (_odict_resize(od) < 0)
1223 return NULL;
1224 Py_RETURN_NONE;
1225}
1226
1227/* copy() */
1228
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001229/* forward */
1230static int _PyODict_SetItem_KnownHash(PyObject *, PyObject *, PyObject *,
1231 Py_hash_t);
1232
Eric Snow96c6af92015-05-29 22:21:39 -06001233PyDoc_STRVAR(odict_copy__doc__, "od.copy() -> a shallow copy of od");
1234
1235static PyObject *
1236odict_copy(register PyODictObject *od)
1237{
1238 _ODictNode *node;
1239 PyObject *od_copy;
1240
1241 if (PyODict_CheckExact(od))
1242 od_copy = PyODict_New();
1243 else
1244 od_copy = PyObject_CallFunctionObjArgs((PyObject *)Py_TYPE(od), NULL);
1245 if (od_copy == NULL)
1246 return NULL;
1247
1248 if (PyODict_CheckExact(od)) {
1249 _odict_FOREACH(od, node) {
Eric Snowa762af72015-06-01 22:59:08 -06001250 PyObject *key = _odictnode_KEY(node);
1251 PyObject *value = _odictnode_VALUE(node, od);
1252 if (value == NULL) {
1253 if (!PyErr_Occurred())
1254 PyErr_SetObject(PyExc_KeyError, key);
1255 goto fail;
1256 }
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001257 if (_PyODict_SetItem_KnownHash((PyObject *)od_copy, key, value,
1258 _odictnode_HASH(node)) != 0)
Eric Snow96c6af92015-05-29 22:21:39 -06001259 goto fail;
1260 }
1261 }
1262 else {
1263 _odict_FOREACH(od, node) {
1264 int res;
1265 PyObject *value = PyObject_GetItem((PyObject *)od,
1266 _odictnode_KEY(node));
1267 if (value == NULL)
1268 goto fail;
1269 res = PyObject_SetItem((PyObject *)od_copy,
1270 _odictnode_KEY(node), value);
1271 Py_DECREF(value);
1272 if (res != 0)
1273 goto fail;
1274 }
1275 }
1276 return od_copy;
1277
1278fail:
1279 Py_DECREF(od_copy);
1280 return NULL;
1281}
1282
1283/* __reversed__() */
1284
1285PyDoc_STRVAR(odict_reversed__doc__, "od.__reversed__() <==> reversed(od)");
1286
1287#define _odict_ITER_REVERSED 1
1288#define _odict_ITER_KEYS 2
1289#define _odict_ITER_VALUES 4
1290
1291/* forward */
1292static PyObject * odictiter_new(PyODictObject *, int);
1293
1294static PyObject *
1295odict_reversed(PyODictObject *od)
1296{
Eric Snow96c6af92015-05-29 22:21:39 -06001297 return odictiter_new(od, _odict_ITER_KEYS|_odict_ITER_REVERSED);
1298}
1299
1300/* move_to_end() */
1301
1302PyDoc_STRVAR(odict_move_to_end__doc__,
1303"Move an existing element to the end (or beginning if last==False).\n\
1304\n\
1305 Raises KeyError if the element does not exist.\n\
1306 When last=True, acts like a fast version of self[key]=self.pop(key).\n\
1307\n\
1308 ");
1309
1310static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001311odict_move_to_end(PyODictObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001312{
Eric Snowac02ef32015-06-02 20:42:14 -06001313 static char *kwlist[] = {"key", "last", 0};
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001314 PyObject *key;
1315 int last = 1;
1316 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001317
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001318 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|p:move_to_end", kwlist,
Eric Snowac02ef32015-06-02 20:42:14 -06001319 &key, &last)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001320 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001321 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001322
Eric Snow96c6af92015-05-29 22:21:39 -06001323 if (_odict_EMPTY(od)) {
1324 PyErr_SetObject(PyExc_KeyError, key);
Eric Snow96c6af92015-05-29 22:21:39 -06001325 return NULL;
1326 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001327 node = last ? _odict_LAST(od) : _odict_FIRST(od);
1328 if (key != _odictnode_KEY(node)) {
1329 node = _odict_find_node(od, key);
1330 if (node == NULL) {
1331 if (!PyErr_Occurred())
1332 PyErr_SetObject(PyExc_KeyError, key);
Eric Snowc5e59602015-05-30 11:28:56 -06001333 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001334 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001335 if (last) {
1336 /* Only move if not already the last one. */
1337 if (node != _odict_LAST(od)) {
1338 _odict_remove_node(od, node);
Eric Snow96c6af92015-05-29 22:21:39 -06001339 _odict_add_tail(od, node);
1340 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001341 }
1342 else {
1343 /* Only move if not already the first one. */
1344 if (node != _odict_FIRST(od)) {
1345 _odict_remove_node(od, node);
1346 _odict_add_head(od, node);
Eric Snow96c6af92015-05-29 22:21:39 -06001347 }
1348 }
1349 }
Eric Snow96c6af92015-05-29 22:21:39 -06001350 Py_RETURN_NONE;
1351}
1352
1353
1354/* tp_methods */
1355
1356static PyMethodDef odict_methods[] = {
1357
1358 /* explicitly defined so we can align docstrings with
1359 * collections.OrderedDict */
1360 {"__delitem__", (PyCFunction)odict_mp_ass_sub, METH_NOARGS,
1361 odict_delitem__doc__},
1362 {"__eq__", (PyCFunction)odict_eq, METH_NOARGS,
1363 odict_eq__doc__},
1364 {"__init__", (PyCFunction)odict_init, METH_NOARGS,
1365 odict_init__doc__},
1366 {"__iter__", (PyCFunction)odict_iter, METH_NOARGS,
1367 odict_iter__doc__},
1368 {"__ne__", (PyCFunction)odict_ne, METH_NOARGS,
1369 odict_ne__doc__},
1370 {"__repr__", (PyCFunction)odict_repr, METH_NOARGS,
1371 odict_repr__doc__},
1372 {"__setitem__", (PyCFunction)odict_mp_ass_sub, METH_NOARGS,
1373 odict_setitem__doc__},
Eric Snowac02ef32015-06-02 20:42:14 -06001374 {"fromkeys", (PyCFunction)odict_fromkeys,
1375 METH_VARARGS | METH_KEYWORDS | METH_CLASS, odict_fromkeys__doc__},
Eric Snow96c6af92015-05-29 22:21:39 -06001376
1377 /* overridden dict methods */
1378 {"__sizeof__", (PyCFunction)odict_sizeof, METH_NOARGS,
1379 odict_sizeof__doc__},
1380 {"__reduce__", (PyCFunction)odict_reduce, METH_NOARGS,
1381 odict_reduce__doc__},
Eric Snowac02ef32015-06-02 20:42:14 -06001382 {"setdefault", (PyCFunction)odict_setdefault,
1383 METH_VARARGS | METH_KEYWORDS, odict_setdefault__doc__},
1384 {"pop", (PyCFunction)odict_pop,
1385 METH_VARARGS | METH_KEYWORDS, odict_pop__doc__},
1386 {"popitem", (PyCFunction)odict_popitem,
1387 METH_VARARGS | METH_KEYWORDS, odict_popitem__doc__},
Eric Snow96c6af92015-05-29 22:21:39 -06001388 {"keys", (PyCFunction)odictkeys_new, METH_NOARGS,
1389 odict_keys__doc__},
1390 {"values", (PyCFunction)odictvalues_new, METH_NOARGS,
1391 odict_values__doc__},
1392 {"items", (PyCFunction)odictitems_new, METH_NOARGS,
1393 odict_items__doc__},
1394 {"update", (PyCFunction)odict_update, METH_VARARGS | METH_KEYWORDS,
1395 odict_update__doc__},
1396 {"clear", (PyCFunction)odict_clear, METH_NOARGS,
1397 odict_clear__doc__},
1398 {"copy", (PyCFunction)odict_copy, METH_NOARGS,
1399 odict_copy__doc__},
1400
1401 /* new methods */
1402 {"__reversed__", (PyCFunction)odict_reversed, METH_NOARGS,
1403 odict_reversed__doc__},
Eric Snowac02ef32015-06-02 20:42:14 -06001404 {"move_to_end", (PyCFunction)odict_move_to_end,
1405 METH_VARARGS | METH_KEYWORDS, odict_move_to_end__doc__},
Eric Snow96c6af92015-05-29 22:21:39 -06001406
1407 {NULL, NULL} /* sentinel */
1408};
1409
1410
1411/* ----------------------------------------------
1412 * OrderedDict members
1413 */
1414
Serhiy Storchakad2962f12016-02-08 16:39:05 +02001415/* tp_getset */
Eric Snow96c6af92015-05-29 22:21:39 -06001416
Serhiy Storchakad2962f12016-02-08 16:39:05 +02001417static PyGetSetDef odict_getset[] = {
1418 {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
1419 {NULL}
Eric Snow96c6af92015-05-29 22:21:39 -06001420};
1421
Eric Snow96c6af92015-05-29 22:21:39 -06001422/* ----------------------------------------------
1423 * OrderedDict type slot methods
1424 */
1425
1426/* tp_dealloc */
1427
1428static void
1429odict_dealloc(PyODictObject *self)
1430{
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001431 PyThreadState *tstate = PyThreadState_GET();
1432
Eric Snow96c6af92015-05-29 22:21:39 -06001433 PyObject_GC_UnTrack(self);
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001434 Py_TRASHCAN_SAFE_BEGIN(self)
1435
Eric Snow96c6af92015-05-29 22:21:39 -06001436 Py_XDECREF(self->od_inst_dict);
1437 if (self->od_weakreflist != NULL)
1438 PyObject_ClearWeakRefs((PyObject *)self);
1439
1440 _odict_clear_nodes(self);
Eric Snow96c6af92015-05-29 22:21:39 -06001441
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001442 /* Call the base tp_dealloc(). Since it too uses the trashcan mechanism,
1443 * temporarily decrement trash_delete_nesting to prevent triggering it
1444 * and putting the partially deallocated object on the trashcan's
1445 * to-be-deleted-later list.
1446 */
1447 --tstate->trash_delete_nesting;
1448 assert(_tstate->trash_delete_nesting < PyTrash_UNWIND_LEVEL);
Eric Snow96c6af92015-05-29 22:21:39 -06001449 PyDict_Type.tp_dealloc((PyObject *)self);
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001450 ++tstate->trash_delete_nesting;
1451
1452 Py_TRASHCAN_SAFE_END(self)
Victor Stinnere1871952016-06-08 10:18:18 +02001453}
Eric Snow96c6af92015-05-29 22:21:39 -06001454
1455/* tp_repr */
1456
1457static PyObject *
1458odict_repr(PyODictObject *self)
1459{
1460 int i;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001461 _Py_IDENTIFIER(items);
Serhiy Storchaka4575beb2015-10-22 20:18:24 +03001462 PyObject *pieces = NULL, *result = NULL;
1463 const char *classname;
1464
1465 classname = strrchr(Py_TYPE(self)->tp_name, '.');
1466 if (classname == NULL)
1467 classname = Py_TYPE(self)->tp_name;
1468 else
1469 classname++;
1470
1471 if (PyODict_SIZE(self) == 0)
1472 return PyUnicode_FromFormat("%s()", classname);
Eric Snow96c6af92015-05-29 22:21:39 -06001473
1474 i = Py_ReprEnter((PyObject *)self);
1475 if (i != 0) {
1476 return i > 0 ? PyUnicode_FromString("...") : NULL;
1477 }
1478
Eric Snow96c6af92015-05-29 22:21:39 -06001479 if (PyODict_CheckExact(self)) {
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001480 Py_ssize_t count = 0;
Eric Snowa762af72015-06-01 22:59:08 -06001481 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001482 pieces = PyList_New(PyODict_SIZE(self));
1483 if (pieces == NULL)
1484 goto Done;
1485
1486 _odict_FOREACH(self, node) {
Eric Snowa762af72015-06-01 22:59:08 -06001487 PyObject *pair;
1488 PyObject *key = _odictnode_KEY(node);
1489 PyObject *value = _odictnode_VALUE(node, self);
1490 if (value == NULL) {
1491 if (!PyErr_Occurred())
1492 PyErr_SetObject(PyExc_KeyError, key);
Eric Snowdb4061c2015-06-03 11:09:48 -06001493 goto Done;
Eric Snowa762af72015-06-01 22:59:08 -06001494 }
1495 pair = PyTuple_Pack(2, key, value);
Eric Snow96c6af92015-05-29 22:21:39 -06001496 if (pair == NULL)
1497 goto Done;
1498
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001499 if (count < PyList_GET_SIZE(pieces))
1500 PyList_SET_ITEM(pieces, count, pair); /* steals reference */
1501 else {
1502 if (PyList_Append(pieces, pair) < 0) {
1503 Py_DECREF(pair);
1504 goto Done;
1505 }
1506 Py_DECREF(pair);
1507 }
1508 count++;
Eric Snow96c6af92015-05-29 22:21:39 -06001509 }
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001510 if (count < PyList_GET_SIZE(pieces))
1511 PyList_GET_SIZE(pieces) = count;
Eric Snow96c6af92015-05-29 22:21:39 -06001512 }
1513 else {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001514 PyObject *items = _PyObject_CallMethodIdObjArgs((PyObject *)self,
1515 &PyId_items, NULL);
Eric Snow96c6af92015-05-29 22:21:39 -06001516 if (items == NULL)
1517 goto Done;
1518 pieces = PySequence_List(items);
1519 Py_DECREF(items);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001520 if (pieces == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -06001521 goto Done;
1522 }
1523
Serhiy Storchaka4575beb2015-10-22 20:18:24 +03001524 result = PyUnicode_FromFormat("%s(%R)", classname, pieces);
Eric Snow96c6af92015-05-29 22:21:39 -06001525
Eric Snow96c6af92015-05-29 22:21:39 -06001526Done:
1527 Py_XDECREF(pieces);
Eric Snow96c6af92015-05-29 22:21:39 -06001528 Py_ReprLeave((PyObject *)self);
1529 return result;
Victor Stinnere1871952016-06-08 10:18:18 +02001530}
Eric Snow96c6af92015-05-29 22:21:39 -06001531
1532/* tp_doc */
1533
1534PyDoc_STRVAR(odict_doc,
1535 "Dictionary that remembers insertion order");
1536
1537/* tp_traverse */
1538
1539static int
1540odict_traverse(PyODictObject *od, visitproc visit, void *arg)
1541{
Serhiy Storchakad205d012016-01-19 14:46:25 +02001542 _ODictNode *node;
1543
Eric Snow96c6af92015-05-29 22:21:39 -06001544 Py_VISIT(od->od_inst_dict);
1545 Py_VISIT(od->od_weakreflist);
Serhiy Storchakad205d012016-01-19 14:46:25 +02001546 _odict_FOREACH(od, node) {
1547 Py_VISIT(_odictnode_KEY(node));
1548 }
Eric Snow96c6af92015-05-29 22:21:39 -06001549 return PyDict_Type.tp_traverse((PyObject *)od, visit, arg);
1550}
1551
1552/* tp_clear */
1553
1554static int
1555odict_tp_clear(PyODictObject *od)
1556{
1557 PyObject *res;
1558 Py_CLEAR(od->od_inst_dict);
1559 Py_CLEAR(od->od_weakreflist);
1560 res = odict_clear(od);
1561 if (res == NULL)
1562 return -1;
1563 Py_DECREF(res);
1564 return 0;
1565}
1566
1567/* tp_richcompare */
1568
1569static PyObject *
1570odict_richcompare(PyObject *v, PyObject *w, int op)
1571{
1572 if (!PyODict_Check(v) || !PyDict_Check(w)) {
1573 Py_RETURN_NOTIMPLEMENTED;
1574 }
1575
1576 if (op == Py_EQ || op == Py_NE) {
1577 PyObject *res, *cmp;
1578 int eq;
1579
1580 cmp = PyDict_Type.tp_richcompare(v, w, op);
1581 if (cmp == NULL)
1582 return NULL;
1583 if (!PyODict_Check(w))
1584 return cmp;
1585 if (op == Py_EQ && cmp == Py_False)
1586 return cmp;
1587 if (op == Py_NE && cmp == Py_True)
1588 return cmp;
1589 Py_DECREF(cmp);
1590
1591 /* Try comparing odict keys. */
1592 eq = _odict_keys_equal((PyODictObject *)v, (PyODictObject *)w);
1593 if (eq < 0)
1594 return NULL;
1595
1596 res = (eq == (op == Py_EQ)) ? Py_True : Py_False;
1597 Py_INCREF(res);
1598 return res;
1599 } else {
1600 Py_RETURN_NOTIMPLEMENTED;
1601 }
Victor Stinnere1871952016-06-08 10:18:18 +02001602}
Eric Snow96c6af92015-05-29 22:21:39 -06001603
1604/* tp_iter */
1605
1606static PyObject *
1607odict_iter(PyODictObject *od)
1608{
1609 return odictiter_new(od, _odict_ITER_KEYS);
Victor Stinnere1871952016-06-08 10:18:18 +02001610}
Eric Snow96c6af92015-05-29 22:21:39 -06001611
1612/* tp_init */
1613
1614static int
1615odict_init(PyObject *self, PyObject *args, PyObject *kwds)
1616{
1617 PyObject *res;
1618 Py_ssize_t len = PyObject_Length(args);
1619
1620 if (len == -1)
1621 return -1;
1622 if (len > 1) {
1623 char *msg = "expected at most 1 arguments, got %d";
1624 PyErr_Format(PyExc_TypeError, msg, len);
1625 return -1;
1626 }
1627
1628 /* __init__() triggering update() is just the way things are! */
1629 res = odict_update(self, args, kwds);
1630 if (res == NULL) {
1631 return -1;
1632 } else {
1633 Py_DECREF(res);
1634 return 0;
1635 }
Victor Stinnere1871952016-06-08 10:18:18 +02001636}
Eric Snow96c6af92015-05-29 22:21:39 -06001637
1638/* tp_new */
1639
1640static PyObject *
1641odict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1642{
Victor Stinnerca30b022015-09-03 17:50:04 +02001643 PyODictObject *od;
1644
Victor Stinnerca30b022015-09-03 17:50:04 +02001645 od = (PyODictObject *)PyDict_Type.tp_new(type, args, kwds);
Serhiy Storchakad2962f12016-02-08 16:39:05 +02001646 if (od == NULL)
Victor Stinnerca30b022015-09-03 17:50:04 +02001647 return NULL;
Victor Stinnerca30b022015-09-03 17:50:04 +02001648
Victor Stinnerca30b022015-09-03 17:50:04 +02001649 /* type constructor fills the memory with zeros (see
1650 PyType_GenericAlloc()), there is no need to set them to zero again */
1651 if (_odict_resize(od) < 0) {
1652 Py_DECREF(od);
1653 return NULL;
1654 }
1655
1656 return (PyObject*)od;
Eric Snow96c6af92015-05-29 22:21:39 -06001657}
1658
1659/* PyODict_Type */
1660
1661PyTypeObject PyODict_Type = {
1662 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1663 "collections.OrderedDict", /* tp_name */
1664 sizeof(PyODictObject), /* tp_basicsize */
1665 0, /* tp_itemsize */
1666 (destructor)odict_dealloc, /* tp_dealloc */
1667 0, /* tp_print */
1668 0, /* tp_getattr */
1669 0, /* tp_setattr */
1670 0, /* tp_reserved */
1671 (reprfunc)odict_repr, /* tp_repr */
1672 0, /* tp_as_number */
1673 0, /* tp_as_sequence */
1674 &odict_as_mapping, /* tp_as_mapping */
1675 0, /* tp_hash */
1676 0, /* tp_call */
1677 0, /* tp_str */
1678 0, /* tp_getattro */
1679 0, /* tp_setattro */
1680 0, /* tp_as_buffer */
1681 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,/* tp_flags */
1682 odict_doc, /* tp_doc */
1683 (traverseproc)odict_traverse, /* tp_traverse */
1684 (inquiry)odict_tp_clear, /* tp_clear */
1685 (richcmpfunc)odict_richcompare, /* tp_richcompare */
1686 offsetof(PyODictObject, od_weakreflist), /* tp_weaklistoffset */
1687 (getiterfunc)odict_iter, /* tp_iter */
1688 0, /* tp_iternext */
1689 odict_methods, /* tp_methods */
Serhiy Storchakad2962f12016-02-08 16:39:05 +02001690 0, /* tp_members */
1691 odict_getset, /* tp_getset */
Eric Snow96c6af92015-05-29 22:21:39 -06001692 &PyDict_Type, /* tp_base */
1693 0, /* tp_dict */
1694 0, /* tp_descr_get */
1695 0, /* tp_descr_set */
1696 offsetof(PyODictObject, od_inst_dict), /* tp_dictoffset */
1697 (initproc)odict_init, /* tp_init */
1698 PyType_GenericAlloc, /* tp_alloc */
1699 (newfunc)odict_new, /* tp_new */
1700 0, /* tp_free */
1701};
1702
1703
1704/* ----------------------------------------------
1705 * the public OrderedDict API
1706 */
1707
1708PyObject *
1709PyODict_New(void) {
1710 return odict_new(&PyODict_Type, NULL, NULL);
Victor Stinnere1871952016-06-08 10:18:18 +02001711}
Eric Snow96c6af92015-05-29 22:21:39 -06001712
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001713static int
1714_PyODict_SetItem_KnownHash(PyObject *od, PyObject *key, PyObject *value,
1715 Py_hash_t hash)
1716{
1717 int res = _PyDict_SetItem_KnownHash(od, key, value, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001718 if (res == 0) {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001719 res = _odict_add_new_node((PyODictObject *)od, key, hash);
Serhiy Storchakad5f353e2015-11-06 11:07:11 +02001720 if (res < 0) {
1721 /* Revert setting the value on the dict */
1722 PyObject *exc, *val, *tb;
1723 PyErr_Fetch(&exc, &val, &tb);
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001724 (void) _PyDict_DelItem_KnownHash(od, key, hash);
Serhiy Storchakad5f353e2015-11-06 11:07:11 +02001725 _PyErr_ChainExceptions(exc, val, tb);
1726 }
Eric Snow96c6af92015-05-29 22:21:39 -06001727 }
1728 return res;
Victor Stinnere1871952016-06-08 10:18:18 +02001729}
Eric Snow96c6af92015-05-29 22:21:39 -06001730
1731int
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001732PyODict_SetItem(PyObject *od, PyObject *key, PyObject *value)
1733{
1734 Py_hash_t hash = PyObject_Hash(key);
1735 if (hash == -1)
1736 return -1;
1737 return _PyODict_SetItem_KnownHash(od, key, value, hash);
Victor Stinnere1871952016-06-08 10:18:18 +02001738}
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001739
1740int
1741PyODict_DelItem(PyObject *od, PyObject *key)
1742{
1743 int res;
1744 Py_hash_t hash = PyObject_Hash(key);
1745 if (hash == -1)
1746 return -1;
1747 res = _odict_clear_node((PyODictObject *)od, NULL, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001748 if (res < 0)
1749 return -1;
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001750 return _PyDict_DelItem_KnownHash(od, key, hash);
Victor Stinnere1871952016-06-08 10:18:18 +02001751}
Eric Snow96c6af92015-05-29 22:21:39 -06001752
1753
1754/* -------------------------------------------
1755 * The OrderedDict views (keys/values/items)
1756 */
1757
1758typedef struct {
1759 PyObject_HEAD
1760 int kind;
1761 PyODictObject *di_odict;
Eric Snowb952ab42015-06-01 23:35:13 -06001762 Py_ssize_t di_size;
Eric Snow4fabf022015-06-04 00:09:56 -06001763 size_t di_state;
Eric Snow96c6af92015-05-29 22:21:39 -06001764 PyObject *di_current;
1765 PyObject *di_result; /* reusable result tuple for iteritems */
1766} odictiterobject;
1767
1768static void
1769odictiter_dealloc(odictiterobject *di)
1770{
1771 _PyObject_GC_UNTRACK(di);
Eric Snowa762af72015-06-01 22:59:08 -06001772 Py_XDECREF(di->di_odict);
Eric Snow96c6af92015-05-29 22:21:39 -06001773 Py_XDECREF(di->di_current);
1774 if (di->kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)) {
1775 Py_DECREF(di->di_result);
1776 }
1777 PyObject_GC_Del(di);
1778}
1779
1780static int
1781odictiter_traverse(odictiterobject *di, visitproc visit, void *arg)
1782{
1783 Py_VISIT(di->di_odict);
1784 Py_VISIT(di->di_current); /* A key could be any type, not just str. */
1785 Py_VISIT(di->di_result);
1786 return 0;
1787}
1788
Eric Snowa762af72015-06-01 22:59:08 -06001789/* In order to protect against modifications during iteration, we track
1790 * the current key instead of the current node. */
Eric Snow96c6af92015-05-29 22:21:39 -06001791static PyObject *
1792odictiter_nextkey(odictiterobject *di)
1793{
Eric Snowa762af72015-06-01 22:59:08 -06001794 PyObject *key = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001795 _ODictNode *node;
1796 int reversed = di->kind & _odict_ITER_REVERSED;
1797
Eric Snowa762af72015-06-01 22:59:08 -06001798 if (di->di_odict == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -06001799 return NULL;
Eric Snowa762af72015-06-01 22:59:08 -06001800 if (di->di_current == NULL)
1801 goto done; /* We're already done. */
1802
Eric Snowb952ab42015-06-01 23:35:13 -06001803 /* Check for unsupported changes. */
Eric Snow4fabf022015-06-04 00:09:56 -06001804 if (di->di_odict->od_state != di->di_state) {
1805 PyErr_SetString(PyExc_RuntimeError,
1806 "OrderedDict mutated during iteration");
1807 goto done;
1808 }
Eric Snowb952ab42015-06-01 23:35:13 -06001809 if (di->di_size != PyODict_SIZE(di->di_odict)) {
1810 PyErr_SetString(PyExc_RuntimeError,
1811 "OrderedDict changed size during iteration");
1812 di->di_size = -1; /* Make this state sticky */
1813 return NULL;
1814 }
1815
Eric Snowa762af72015-06-01 22:59:08 -06001816 /* Get the key. */
Eric Snow96c6af92015-05-29 22:21:39 -06001817 node = _odict_find_node(di->di_odict, di->di_current);
1818 if (node == NULL) {
Serhiy Storchakab45b7b22015-11-04 22:05:38 +02001819 if (!PyErr_Occurred())
1820 PyErr_SetObject(PyExc_KeyError, di->di_current);
Eric Snow96c6af92015-05-29 22:21:39 -06001821 /* Must have been deleted. */
Eric Snowe3dfa9e2015-05-30 12:51:15 -06001822 Py_CLEAR(di->di_current);
Eric Snow96c6af92015-05-29 22:21:39 -06001823 return NULL;
1824 }
1825 key = di->di_current;
1826
1827 /* Advance to the next key. */
1828 node = reversed ? _odictnode_PREV(node) : _odictnode_NEXT(node);
1829 if (node == NULL) {
1830 /* Reached the end. */
1831 di->di_current = NULL;
1832 }
1833 else {
1834 di->di_current = _odictnode_KEY(node);
1835 Py_INCREF(di->di_current);
1836 }
1837
1838 return key;
Eric Snowa762af72015-06-01 22:59:08 -06001839
1840done:
1841 Py_CLEAR(di->di_odict);
1842 return key;
Eric Snow96c6af92015-05-29 22:21:39 -06001843}
1844
1845static PyObject *
1846odictiter_iternext(odictiterobject *di)
1847{
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001848 PyObject *result, *value;
Eric Snow96c6af92015-05-29 22:21:39 -06001849 PyObject *key = odictiter_nextkey(di); /* new reference */
1850
1851 if (key == NULL)
1852 return NULL;
1853
1854 /* Handle the keys case. */
1855 if (! (di->kind & _odict_ITER_VALUES)) {
1856 return key;
1857 }
1858
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001859 value = PyODict_GetItem((PyObject *)di->di_odict, key); /* borrowed */
1860 if (value == NULL) {
1861 if (!PyErr_Occurred())
1862 PyErr_SetObject(PyExc_KeyError, key);
Eric Snow96c6af92015-05-29 22:21:39 -06001863 Py_DECREF(key);
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001864 goto done;
1865 }
1866 Py_INCREF(value);
1867
1868 /* Handle the values case. */
1869 if (!(di->kind & _odict_ITER_KEYS)) {
1870 Py_DECREF(key);
Eric Snow96c6af92015-05-29 22:21:39 -06001871 return value;
1872 }
Eric Snowa762af72015-06-01 22:59:08 -06001873
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001874 /* Handle the items case. */
1875 result = di->di_result;
1876
1877 if (Py_REFCNT(result) == 1) {
1878 /* not in use so we can reuse it
1879 * (the common case during iteration) */
1880 Py_INCREF(result);
1881 Py_DECREF(PyTuple_GET_ITEM(result, 0)); /* borrowed */
1882 Py_DECREF(PyTuple_GET_ITEM(result, 1)); /* borrowed */
1883 }
1884 else {
1885 result = PyTuple_New(2);
1886 if (result == NULL) {
1887 Py_DECREF(key);
1888 Py_DECREF(value);
1889 goto done;
1890 }
1891 }
1892
1893 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
1894 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
1895 return result;
1896
Eric Snowa762af72015-06-01 22:59:08 -06001897done:
1898 Py_CLEAR(di->di_current);
1899 Py_CLEAR(di->di_odict);
1900 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001901}
1902
1903/* No need for tp_clear because odictiterobject is not mutable. */
1904
1905PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
1906
1907static PyObject *
1908odictiter_reduce(odictiterobject *di)
1909{
Eric Snowc5e59602015-05-30 11:28:56 -06001910 PyObject *list, *iter;
Eric Snow96c6af92015-05-29 22:21:39 -06001911
1912 list = PyList_New(0);
1913 if (!list)
1914 return NULL;
1915
1916 /* iterate the temporary into a list */
1917 for(;;) {
1918 PyObject *element = odictiter_iternext(di);
1919 if (element) {
1920 if (PyList_Append(list, element)) {
1921 Py_DECREF(element);
1922 Py_DECREF(list);
1923 return NULL;
1924 }
1925 Py_DECREF(element);
1926 }
1927 else {
1928 /* done iterating? */
1929 break;
1930 }
1931 }
1932 if (PyErr_Occurred()) {
1933 Py_DECREF(list);
1934 return NULL;
1935 }
Eric Snowc5e59602015-05-30 11:28:56 -06001936 iter = _PyObject_GetBuiltin("iter");
1937 if (iter == NULL) {
1938 Py_DECREF(list);
1939 return NULL;
1940 }
1941 return Py_BuildValue("N(N)", iter, list);
Eric Snow96c6af92015-05-29 22:21:39 -06001942}
1943
1944static PyMethodDef odictiter_methods[] = {
1945 {"__reduce__", (PyCFunction)odictiter_reduce, METH_NOARGS, reduce_doc},
1946 {NULL, NULL} /* sentinel */
1947};
1948
1949PyTypeObject PyODictIter_Type = {
1950 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1951 "odict_iterator", /* tp_name */
1952 sizeof(odictiterobject), /* tp_basicsize */
1953 0, /* tp_itemsize */
1954 /* methods */
1955 (destructor)odictiter_dealloc, /* tp_dealloc */
1956 0, /* tp_print */
1957 0, /* tp_getattr */
1958 0, /* tp_setattr */
1959 0, /* tp_reserved */
1960 0, /* tp_repr */
1961 0, /* tp_as_number */
1962 0, /* tp_as_sequence */
1963 0, /* tp_as_mapping */
1964 0, /* tp_hash */
1965 0, /* tp_call */
1966 0, /* tp_str */
1967 PyObject_GenericGetAttr, /* tp_getattro */
1968 0, /* tp_setattro */
1969 0, /* tp_as_buffer */
1970 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1971 0, /* tp_doc */
1972 (traverseproc)odictiter_traverse, /* tp_traverse */
1973 0, /* tp_clear */
1974 0, /* tp_richcompare */
1975 0, /* tp_weaklistoffset */
1976 PyObject_SelfIter, /* tp_iter */
1977 (iternextfunc)odictiter_iternext, /* tp_iternext */
1978 odictiter_methods, /* tp_methods */
1979 0,
1980};
1981
1982static PyObject *
1983odictiter_new(PyODictObject *od, int kind)
1984{
1985 odictiterobject *di;
1986 _ODictNode *node;
1987 int reversed = kind & _odict_ITER_REVERSED;
1988
1989 di = PyObject_GC_New(odictiterobject, &PyODictIter_Type);
1990 if (di == NULL)
1991 return NULL;
1992
1993 if (kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)){
1994 di->di_result = PyTuple_Pack(2, Py_None, Py_None);
1995 if (di->di_result == NULL) {
1996 Py_DECREF(di);
1997 return NULL;
1998 }
1999 }
2000 else
2001 di->di_result = NULL;
2002
2003 di->kind = kind;
2004 node = reversed ? _odict_LAST(od) : _odict_FIRST(od);
2005 di->di_current = node ? _odictnode_KEY(node) : NULL;
2006 Py_XINCREF(di->di_current);
Eric Snowb952ab42015-06-01 23:35:13 -06002007 di->di_size = PyODict_SIZE(od);
Eric Snow4fabf022015-06-04 00:09:56 -06002008 di->di_state = od->od_state;
Eric Snow96c6af92015-05-29 22:21:39 -06002009 di->di_odict = od;
2010 Py_INCREF(od);
2011
2012 _PyObject_GC_TRACK(di);
2013 return (PyObject *)di;
2014}
2015
2016/* keys() */
2017
2018static PyObject *
2019odictkeys_iter(_PyDictViewObject *dv)
2020{
2021 if (dv->dv_dict == NULL) {
2022 Py_RETURN_NONE;
2023 }
2024 return odictiter_new((PyODictObject *)dv->dv_dict,
2025 _odict_ITER_KEYS);
2026}
2027
2028static PyObject *
2029odictkeys_reversed(_PyDictViewObject *dv)
2030{
2031 if (dv->dv_dict == NULL) {
2032 Py_RETURN_NONE;
2033 }
2034 return odictiter_new((PyODictObject *)dv->dv_dict,
2035 _odict_ITER_KEYS|_odict_ITER_REVERSED);
2036}
2037
2038static PyMethodDef odictkeys_methods[] = {
2039 {"__reversed__", (PyCFunction)odictkeys_reversed, METH_NOARGS, NULL},
2040 {NULL, NULL} /* sentinel */
2041};
2042
2043PyTypeObject PyODictKeys_Type = {
2044 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2045 "odict_keys", /* tp_name */
2046 0, /* tp_basicsize */
2047 0, /* tp_itemsize */
2048 0, /* tp_dealloc */
2049 0, /* tp_print */
2050 0, /* tp_getattr */
2051 0, /* tp_setattr */
2052 0, /* tp_reserved */
2053 0, /* tp_repr */
2054 0, /* tp_as_number */
2055 0, /* tp_as_sequence */
2056 0, /* tp_as_mapping */
2057 0, /* tp_hash */
2058 0, /* tp_call */
2059 0, /* tp_str */
2060 0, /* tp_getattro */
2061 0, /* tp_setattro */
2062 0, /* tp_as_buffer */
2063 0, /* tp_flags */
2064 0, /* tp_doc */
2065 0, /* tp_traverse */
2066 0, /* tp_clear */
2067 0, /* tp_richcompare */
2068 0, /* tp_weaklistoffset */
2069 (getiterfunc)odictkeys_iter, /* tp_iter */
2070 0, /* tp_iternext */
2071 odictkeys_methods, /* tp_methods */
2072 0, /* tp_members */
2073 0, /* tp_getset */
2074 &PyDictKeys_Type, /* tp_base */
2075};
2076
2077static PyObject *
2078odictkeys_new(PyObject *od)
2079{
2080 return _PyDictView_New(od, &PyODictKeys_Type);
2081}
2082
2083/* items() */
2084
2085static PyObject *
2086odictitems_iter(_PyDictViewObject *dv)
2087{
2088 if (dv->dv_dict == NULL) {
2089 Py_RETURN_NONE;
2090 }
2091 return odictiter_new((PyODictObject *)dv->dv_dict,
2092 _odict_ITER_KEYS|_odict_ITER_VALUES);
2093}
2094
2095static PyObject *
2096odictitems_reversed(_PyDictViewObject *dv)
2097{
2098 if (dv->dv_dict == NULL) {
2099 Py_RETURN_NONE;
2100 }
2101 return odictiter_new((PyODictObject *)dv->dv_dict,
2102 _odict_ITER_KEYS|_odict_ITER_VALUES|_odict_ITER_REVERSED);
2103}
2104
2105static PyMethodDef odictitems_methods[] = {
2106 {"__reversed__", (PyCFunction)odictitems_reversed, METH_NOARGS, NULL},
2107 {NULL, NULL} /* sentinel */
2108};
2109
2110PyTypeObject PyODictItems_Type = {
2111 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2112 "odict_items", /* tp_name */
2113 0, /* tp_basicsize */
2114 0, /* tp_itemsize */
2115 0, /* tp_dealloc */
2116 0, /* tp_print */
2117 0, /* tp_getattr */
2118 0, /* tp_setattr */
2119 0, /* tp_reserved */
2120 0, /* tp_repr */
2121 0, /* tp_as_number */
2122 0, /* tp_as_sequence */
2123 0, /* tp_as_mapping */
2124 0, /* tp_hash */
2125 0, /* tp_call */
2126 0, /* tp_str */
2127 0, /* tp_getattro */
2128 0, /* tp_setattro */
2129 0, /* tp_as_buffer */
2130 0, /* tp_flags */
2131 0, /* tp_doc */
2132 0, /* tp_traverse */
2133 0, /* tp_clear */
2134 0, /* tp_richcompare */
2135 0, /* tp_weaklistoffset */
2136 (getiterfunc)odictitems_iter, /* tp_iter */
2137 0, /* tp_iternext */
2138 odictitems_methods, /* tp_methods */
2139 0, /* tp_members */
2140 0, /* tp_getset */
2141 &PyDictItems_Type, /* tp_base */
2142};
2143
2144static PyObject *
2145odictitems_new(PyObject *od)
2146{
2147 return _PyDictView_New(od, &PyODictItems_Type);
2148}
2149
2150/* values() */
2151
2152static PyObject *
2153odictvalues_iter(_PyDictViewObject *dv)
2154{
2155 if (dv->dv_dict == NULL) {
2156 Py_RETURN_NONE;
2157 }
2158 return odictiter_new((PyODictObject *)dv->dv_dict,
2159 _odict_ITER_VALUES);
2160}
2161
2162static PyObject *
2163odictvalues_reversed(_PyDictViewObject *dv)
2164{
2165 if (dv->dv_dict == NULL) {
2166 Py_RETURN_NONE;
2167 }
2168 return odictiter_new((PyODictObject *)dv->dv_dict,
2169 _odict_ITER_VALUES|_odict_ITER_REVERSED);
2170}
2171
2172static PyMethodDef odictvalues_methods[] = {
2173 {"__reversed__", (PyCFunction)odictvalues_reversed, METH_NOARGS, NULL},
2174 {NULL, NULL} /* sentinel */
2175};
2176
2177PyTypeObject PyODictValues_Type = {
2178 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2179 "odict_values", /* tp_name */
2180 0, /* tp_basicsize */
2181 0, /* tp_itemsize */
2182 0, /* tp_dealloc */
2183 0, /* tp_print */
2184 0, /* tp_getattr */
2185 0, /* tp_setattr */
2186 0, /* tp_reserved */
2187 0, /* tp_repr */
2188 0, /* tp_as_number */
2189 0, /* tp_as_sequence */
2190 0, /* tp_as_mapping */
2191 0, /* tp_hash */
2192 0, /* tp_call */
2193 0, /* tp_str */
2194 0, /* tp_getattro */
2195 0, /* tp_setattro */
2196 0, /* tp_as_buffer */
2197 0, /* tp_flags */
2198 0, /* tp_doc */
2199 0, /* tp_traverse */
2200 0, /* tp_clear */
2201 0, /* tp_richcompare */
2202 0, /* tp_weaklistoffset */
2203 (getiterfunc)odictvalues_iter, /* tp_iter */
2204 0, /* tp_iternext */
2205 odictvalues_methods, /* tp_methods */
2206 0, /* tp_members */
2207 0, /* tp_getset */
2208 &PyDictValues_Type, /* tp_base */
2209};
2210
2211static PyObject *
2212odictvalues_new(PyObject *od)
2213{
2214 return _PyDictView_New(od, &PyODictValues_Type);
2215}
2216
2217
2218/* ----------------------------------------------
2219 MutableMappping implementations
2220
2221Mapping:
2222
2223============ ===========
2224method uses
2225============ ===========
2226__contains__ __getitem__
2227__eq__ items
2228__getitem__ +
2229__iter__ +
2230__len__ +
2231__ne__ __eq__
2232get __getitem__
2233items ItemsView
2234keys KeysView
2235values ValuesView
2236============ ===========
2237
2238ItemsView uses __len__, __iter__, and __getitem__.
2239KeysView uses __len__, __iter__, and __contains__.
2240ValuesView uses __len__, __iter__, and __getitem__.
2241
2242MutableMapping:
2243
2244============ ===========
2245method uses
2246============ ===========
2247__delitem__ +
2248__setitem__ +
2249clear popitem
2250pop __getitem__
2251 __delitem__
2252popitem __iter__
2253 _getitem__
2254 __delitem__
2255setdefault __getitem__
2256 __setitem__
2257update __setitem__
2258============ ===========
2259*/
2260
2261static int
2262mutablemapping_add_pairs(PyObject *self, PyObject *pairs)
2263{
2264 PyObject *pair, *iterator, *unexpected;
2265 int res = 0;
2266
2267 iterator = PyObject_GetIter(pairs);
2268 if (iterator == NULL)
2269 return -1;
2270 PyErr_Clear();
2271
2272 while ((pair = PyIter_Next(iterator)) != NULL) {
2273 /* could be more efficient (see UNPACK_SEQUENCE in ceval.c) */
Eric Snowc5e59602015-05-30 11:28:56 -06002274 PyObject *key = NULL, *value = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06002275 PyObject *pair_iterator = PyObject_GetIter(pair);
Eric Snowc5e59602015-05-30 11:28:56 -06002276 if (pair_iterator == NULL)
2277 goto Done;
Eric Snow96c6af92015-05-29 22:21:39 -06002278
2279 key = PyIter_Next(pair_iterator);
2280 if (key == NULL) {
2281 if (!PyErr_Occurred())
2282 PyErr_SetString(PyExc_ValueError,
2283 "need more than 0 values to unpack");
2284 goto Done;
2285 }
2286
2287 value = PyIter_Next(pair_iterator);
2288 if (value == NULL) {
2289 if (!PyErr_Occurred())
2290 PyErr_SetString(PyExc_ValueError,
2291 "need more than 1 value to unpack");
2292 goto Done;
2293 }
2294
2295 unexpected = PyIter_Next(pair_iterator);
2296 if (unexpected != NULL) {
2297 Py_DECREF(unexpected);
2298 PyErr_SetString(PyExc_ValueError,
2299 "too many values to unpack (expected 2)");
2300 goto Done;
2301 }
2302 else if (PyErr_Occurred())
2303 goto Done;
2304
2305 res = PyObject_SetItem(self, key, value);
2306
2307Done:
2308 Py_DECREF(pair);
Eric Snowc5e59602015-05-30 11:28:56 -06002309 Py_XDECREF(pair_iterator);
Eric Snow96c6af92015-05-29 22:21:39 -06002310 Py_XDECREF(key);
2311 Py_XDECREF(value);
2312 if (PyErr_Occurred())
2313 break;
2314 }
2315 Py_DECREF(iterator);
2316
2317 if (res < 0 || PyErr_Occurred() != NULL)
2318 return -1;
2319 else
2320 return 0;
2321}
2322
2323static PyObject *
2324mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
2325{
2326 int res = 0;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002327 Py_ssize_t len;
2328 _Py_IDENTIFIER(items);
2329 _Py_IDENTIFIER(keys);
Eric Snow96c6af92015-05-29 22:21:39 -06002330
2331 /* first handle args, if any */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002332 assert(args == NULL || PyTuple_Check(args));
2333 len = (args != NULL) ? PyTuple_GET_SIZE(args) : 0;
Benjamin Peterson99e96f22015-06-06 23:20:32 -05002334 if (len > 1) {
Eric Snow96c6af92015-05-29 22:21:39 -06002335 char *msg = "update() takes at most 1 positional argument (%d given)";
2336 PyErr_Format(PyExc_TypeError, msg, len);
2337 return NULL;
2338 }
Eric Snow96c6af92015-05-29 22:21:39 -06002339
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002340 if (len) {
Benjamin Peterson0718de92015-06-07 00:00:42 -05002341 PyObject *other = PyTuple_GET_ITEM(args, 0); /* borrowed reference */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002342 assert(other != NULL);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002343 Py_INCREF(other);
Eric Snow06aed902016-09-09 11:59:08 -07002344 if PyDict_CheckExact(other) {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002345 PyObject *items;
2346 if (PyDict_CheckExact(other))
2347 items = PyDict_Items(other);
2348 else
2349 items = _PyObject_CallMethodId(other, &PyId_items, NULL);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002350 Py_DECREF(other);
2351 if (items == NULL)
2352 return NULL;
2353 res = mutablemapping_add_pairs(self, items);
2354 Py_DECREF(items);
2355 if (res == -1)
2356 return NULL;
2357 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002358 else if (_PyObject_HasAttrId(other, &PyId_keys)) { /* never fails */
Benjamin Peterson0718de92015-06-07 00:00:42 -05002359 PyObject *keys, *iterator, *key;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002360 keys = _PyObject_CallMethodIdObjArgs(other, &PyId_keys, NULL);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002361 if (keys == NULL) {
2362 Py_DECREF(other);
2363 return NULL;
2364 }
2365 iterator = PyObject_GetIter(keys);
2366 Py_DECREF(keys);
2367 if (iterator == NULL) {
2368 Py_DECREF(other);
2369 return NULL;
2370 }
2371 while (res == 0 && (key = PyIter_Next(iterator))) {
2372 PyObject *value = PyObject_GetItem(other, key);
2373 if (value != NULL) {
2374 res = PyObject_SetItem(self, key, value);
2375 Py_DECREF(value);
2376 }
2377 else {
2378 res = -1;
2379 }
2380 Py_DECREF(key);
2381 }
2382 Py_DECREF(other);
2383 Py_DECREF(iterator);
2384 if (res != 0 || PyErr_Occurred())
2385 return NULL;
2386 }
Eric Snow06aed902016-09-09 11:59:08 -07002387 else if (_PyObject_HasAttrId(other, &PyId_items)) { /* never fails */
2388 PyObject *items;
2389 if (PyDict_CheckExact(other))
2390 items = PyDict_Items(other);
2391 else
2392 items = _PyObject_CallMethodId(other, &PyId_items, NULL);
2393 Py_DECREF(other);
2394 if (items == NULL)
2395 return NULL;
2396 res = mutablemapping_add_pairs(self, items);
2397 Py_DECREF(items);
2398 if (res == -1)
2399 return NULL;
2400 }
Benjamin Peterson0718de92015-06-07 00:00:42 -05002401 else {
2402 res = mutablemapping_add_pairs(self, other);
2403 Py_DECREF(other);
2404 if (res != 0)
2405 return NULL;
2406 }
2407 }
2408
2409 /* now handle kwargs */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002410 assert(kwargs == NULL || PyDict_Check(kwargs));
2411 len = (kwargs != NULL) ? PyDict_Size(kwargs) : 0;
Benjamin Peterson0718de92015-06-07 00:00:42 -05002412 if (len > 0) {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002413 PyObject *items = PyDict_Items(kwargs);
Eric Snow96c6af92015-05-29 22:21:39 -06002414 if (items == NULL)
2415 return NULL;
2416 res = mutablemapping_add_pairs(self, items);
2417 Py_DECREF(items);
2418 if (res == -1)
2419 return NULL;
2420 }
Eric Snow96c6af92015-05-29 22:21:39 -06002421
2422 Py_RETURN_NONE;
2423}