blob: a6963d7d53d4b51c87f7a9688b09453b7d4fee30 [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,
42mirroring the key order of dict's dk_enties with an array of node pointers.
43While 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;
539 PyDictKeyEntry *ep;
540 PyDictKeysObject *keys = ((PyDictObject *)od)->ma_keys;
541
542 ep = (keys->dk_lookup)((PyDictObject *)od, key, hash, &value_addr);
543 if (ep == NULL)
544 return -1;
545 /* We use pointer arithmetic to get the entry's index into the table. */
546 return ep - keys->dk_entries;
547}
548
549/* Replace od->od_fast_nodes with a new table matching the size of dict's. */
Eric Snow96c6af92015-05-29 22:21:39 -0600550static int
551_odict_resize(PyODictObject *od) {
Eric Snow4c729182015-06-03 10:50:37 -0600552 Py_ssize_t size, i;
Eric Snow96c6af92015-05-29 22:21:39 -0600553 _ODictNode **fast_nodes, *node;
554
555 /* Initialize a new "fast nodes" table. */
556 size = ((PyDictObject *)od)->ma_keys->dk_size;
557 fast_nodes = PyMem_NEW(_ODictNode *, size);
558 if (fast_nodes == NULL) {
559 PyErr_NoMemory();
560 return -1;
561 }
562 for (i = 0; i < size; i++)
563 fast_nodes[i] = NULL;
564
565 /* Copy the current nodes into the table. */
Eric Snow96c6af92015-05-29 22:21:39 -0600566 _odict_FOREACH(od, node) {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200567 i = _odict_get_index_raw(od, _odictnode_KEY(node),
Eric Snow4c729182015-06-03 10:50:37 -0600568 _odictnode_HASH(node));
Eric Snow96c6af92015-05-29 22:21:39 -0600569 if (i < 0) {
Eric Snow96c6af92015-05-29 22:21:39 -0600570 PyMem_FREE(fast_nodes);
571 return -1;
572 }
573 fast_nodes[i] = node;
574 }
Eric Snow96c6af92015-05-29 22:21:39 -0600575
576 /* Replace the old fast nodes table. */
577 _odict_free_fast_nodes(od);
578 od->od_fast_nodes = fast_nodes;
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200579 od->od_fast_nodes_size = size;
580 od->od_resize_sentinel = ((PyDictObject *)od)->ma_keys;
Eric Snow96c6af92015-05-29 22:21:39 -0600581 return 0;
582}
583
584/* Return the index into the hash table, regardless of a valid node. */
585static Py_ssize_t
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200586_odict_get_index(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600587{
Eric Snow4c729182015-06-03 10:50:37 -0600588 PyDictKeysObject *keys;
Eric Snow96c6af92015-05-29 22:21:39 -0600589
590 assert(key != NULL);
Eric Snow4c729182015-06-03 10:50:37 -0600591 keys = ((PyDictObject *)od)->ma_keys;
592
593 /* Ensure od_fast_nodes and dk_entries are in sync. */
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200594 if (od->od_resize_sentinel != keys ||
595 od->od_fast_nodes_size != keys->dk_size) {
Eric Snow4c729182015-06-03 10:50:37 -0600596 int resize_res = _odict_resize(od);
597 if (resize_res < 0)
598 return -1;
599 }
600
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200601 return _odict_get_index_raw(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600602}
603
Eric Snow96c6af92015-05-29 22:21:39 -0600604/* Returns NULL if there was some error or the key was not found. */
605static _ODictNode *
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200606_odict_find_node_hash(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600607{
608 Py_ssize_t index;
609
610 if (_odict_EMPTY(od))
611 return NULL;
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200612 index = _odict_get_index(od, key, hash);
613 if (index < 0)
614 return NULL;
615 return od->od_fast_nodes[index];
616}
617
618static _ODictNode *
619_odict_find_node(PyODictObject *od, PyObject *key)
620{
621 Py_ssize_t index;
622 Py_hash_t hash;
623
624 if (_odict_EMPTY(od))
625 return NULL;
626 hash = PyObject_Hash(key);
627 if (hash == -1)
628 return NULL;
629 index = _odict_get_index(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600630 if (index < 0)
631 return NULL;
632 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 }
676 else if (od->od_fast_nodes[i] != NULL) {
677 /* We already have a node for the key so there's no need to add one. */
678 Py_DECREF(key);
679 return 0;
680 }
681
682 /* must not be added yet */
683 node = (_ODictNode *)PyMem_MALLOC(sizeof(_ODictNode));
684 if (node == NULL) {
685 Py_DECREF(key);
686 PyErr_NoMemory();
687 return -1;
688 }
689
690 _odictnode_KEY(node) = key;
Eric Snow4c729182015-06-03 10:50:37 -0600691 _odictnode_HASH(node) = hash;
Eric Snow96c6af92015-05-29 22:21:39 -0600692 _odict_add_tail(od, node);
693 od->od_fast_nodes[i] = node;
694 return 0;
695}
696
697/* Putting the decref after the free causes problems. */
698#define _odictnode_DEALLOC(node) \
699 do { \
700 Py_DECREF(_odictnode_KEY(node)); \
701 PyMem_FREE((void *)node); \
702 } while (0)
703
704/* Repeated calls on the same node are no-ops. */
705static void
706_odict_remove_node(PyODictObject *od, _ODictNode *node)
707{
708 if (_odict_FIRST(od) == node)
709 _odict_FIRST(od) = _odictnode_NEXT(node);
710 else if (_odictnode_PREV(node) != NULL)
711 _odictnode_NEXT(_odictnode_PREV(node)) = _odictnode_NEXT(node);
712
713 if (_odict_LAST(od) == node)
714 _odict_LAST(od) = _odictnode_PREV(node);
715 else if (_odictnode_NEXT(node) != NULL)
716 _odictnode_PREV(_odictnode_NEXT(node)) = _odictnode_PREV(node);
717
718 _odictnode_PREV(node) = NULL;
719 _odictnode_NEXT(node) = NULL;
Eric Snow4fabf022015-06-04 00:09:56 -0600720 od->od_state++;
Eric Snow96c6af92015-05-29 22:21:39 -0600721}
722
Eric Snow96c6af92015-05-29 22:21:39 -0600723/* If someone calls PyDict_DelItem() directly on an OrderedDict, we'll
724 get all sorts of problems here. In PyODict_DelItem we make sure to
725 call _odict_clear_node first.
Victor Stinnerca30b022015-09-03 17:50:04 +0200726
Eric Snow96c6af92015-05-29 22:21:39 -0600727 This matters in the case of colliding keys. Suppose we add 3 keys:
728 [A, B, C], where the hash of C collides with A and the next possible
729 index in the hash table is occupied by B. If we remove B then for C
730 the dict's looknode func will give us the old index of B instead of
731 the index we got before deleting B. However, the node for C in
732 od_fast_nodes is still at the old dict index of C. Thus to be sure
733 things don't get out of sync, we clear the node in od_fast_nodes
734 *before* calling PyDict_DelItem.
735
736 The same must be done for any other OrderedDict operations where
737 we modify od_fast_nodes.
738*/
739static int
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200740_odict_clear_node(PyODictObject *od, _ODictNode *node, PyObject *key,
741 Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600742{
743 Py_ssize_t i;
744
745 assert(key != NULL);
746 if (_odict_EMPTY(od)) {
747 /* Let later code decide if this is a KeyError. */
748 return 0;
749 }
750
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200751 i = _odict_get_index(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600752 if (i < 0)
753 return PyErr_Occurred() ? -1 : 0;
754
755 if (node == NULL)
756 node = od->od_fast_nodes[i];
757 assert(node == od->od_fast_nodes[i]);
758 if (node == NULL) {
759 /* Let later code decide if this is a KeyError. */
760 return 0;
761 }
762
763 // Now clear the node.
764 od->od_fast_nodes[i] = NULL;
765 _odict_remove_node(od, node);
766 _odictnode_DEALLOC(node);
767 return 0;
768}
769
770static void
771_odict_clear_nodes(PyODictObject *od)
772{
773 _ODictNode *node, *next;
774
Eric Snow96c6af92015-05-29 22:21:39 -0600775 _odict_free_fast_nodes(od);
776 od->od_fast_nodes = NULL;
Serhiy Storchakad205d012016-01-19 14:46:25 +0200777
778 node = _odict_FIRST(od);
779 _odict_FIRST(od) = NULL;
780 _odict_LAST(od) = NULL;
781 while (node != NULL) {
782 next = _odictnode_NEXT(node);
783 _odictnode_DEALLOC(node);
784 node = next;
785 }
Eric Snow96c6af92015-05-29 22:21:39 -0600786}
787
788/* There isn't any memory management of nodes past this point. */
789#undef _odictnode_DEALLOC
790
791static int
792_odict_keys_equal(PyODictObject *a, PyODictObject *b)
793{
794 _ODictNode *node_a, *node_b;
795
796 node_a = _odict_FIRST(a);
797 node_b = _odict_FIRST(b);
798 while (1) {
799 if (node_a == NULL && node_b == NULL)
800 /* success: hit the end of each at the same time */
801 return 1;
802 else if (node_a == NULL || node_b == NULL)
803 /* unequal length */
804 return 0;
805 else {
806 int res = PyObject_RichCompareBool(
807 (PyObject *)_odictnode_KEY(node_a),
808 (PyObject *)_odictnode_KEY(node_b),
809 Py_EQ);
810 if (res < 0)
811 return res;
812 else if (res == 0)
813 return 0;
814
815 /* otherwise it must match, so move on to the next one */
816 node_a = _odictnode_NEXT(node_a);
817 node_b = _odictnode_NEXT(node_b);
818 }
819 }
820}
821
822
823/* ----------------------------------------------
824 * OrderedDict mapping methods
825 */
826
827/* mp_ass_subscript: __setitem__() and __delitem__() */
828
829static int
830odict_mp_ass_sub(PyODictObject *od, PyObject *v, PyObject *w)
831{
832 if (w == NULL)
833 return PyODict_DelItem((PyObject *)od, v);
834 else
835 return PyODict_SetItem((PyObject *)od, v, w);
836}
837
838/* tp_as_mapping */
839
840static PyMappingMethods odict_as_mapping = {
841 0, /*mp_length*/
842 0, /*mp_subscript*/
843 (objobjargproc)odict_mp_ass_sub, /*mp_ass_subscript*/
844};
845
846
847/* ----------------------------------------------
848 * OrderedDict methods
849 */
850
851/* __delitem__() */
852
853PyDoc_STRVAR(odict_delitem__doc__, "od.__delitem__(y) <==> del od[y]");
854
855/* __eq__() */
856
857PyDoc_STRVAR(odict_eq__doc__,
858"od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive \n\
859 while comparison to a regular mapping is order-insensitive.\n\
860 ");
861
862/* forward */
863static PyObject * odict_richcompare(PyObject *v, PyObject *w, int op);
864
865static PyObject *
866odict_eq(PyObject *a, PyObject *b)
867{
868 return odict_richcompare(a, b, Py_EQ);
869}
870
871/* __init__() */
872
873PyDoc_STRVAR(odict_init__doc__,
874"Initialize an ordered dictionary. The signature is the same as\n\
875 regular dictionaries, but keyword arguments are not recommended because\n\
876 their insertion order is arbitrary.\n\
877\n\
878 ");
879
880/* forward */
881static int odict_init(PyObject *self, PyObject *args, PyObject *kwds);
882
883/* __iter__() */
884
885PyDoc_STRVAR(odict_iter__doc__, "od.__iter__() <==> iter(od)");
886
887static PyObject * odict_iter(PyODictObject *self); /* forward */
888
889/* __ne__() */
890
891/* Mapping.__ne__() does not have a docstring. */
892PyDoc_STRVAR(odict_ne__doc__, "");
893
894static PyObject *
895odict_ne(PyObject *a, PyObject *b)
896{
897 return odict_richcompare(a, b, Py_NE);
898}
899
900/* __repr__() */
901
902PyDoc_STRVAR(odict_repr__doc__, "od.__repr__() <==> repr(od)");
903
904static PyObject * odict_repr(PyODictObject *self); /* forward */
905
906/* __setitem__() */
907
908PyDoc_STRVAR(odict_setitem__doc__, "od.__setitem__(i, y) <==> od[i]=y");
909
910/* fromkeys() */
911
912PyDoc_STRVAR(odict_fromkeys__doc__,
913"OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.\n\
914 If not specified, the value defaults to None.\n\
915\n\
916 ");
917
918static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -0600919odict_fromkeys(PyObject *cls, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -0600920{
Eric Snowac02ef32015-06-02 20:42:14 -0600921 static char *kwlist[] = {"iterable", "value", 0};
Eric Snow96c6af92015-05-29 22:21:39 -0600922 PyObject *seq;
923 PyObject *value = Py_None;
Eric Snowac02ef32015-06-02 20:42:14 -0600924
925 /* both borrowed */
926 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:fromkeys", kwlist,
927 &seq, &value)) {
Eric Snow96c6af92015-05-29 22:21:39 -0600928 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -0600929 }
Eric Snow96c6af92015-05-29 22:21:39 -0600930 return _PyDict_FromKeys(cls, seq, value);
931}
932
933/* __sizeof__() */
934
935/* OrderedDict.__sizeof__() does not have a docstring. */
936PyDoc_STRVAR(odict_sizeof__doc__, "");
937
938static PyObject *
939odict_sizeof(PyODictObject *od)
940{
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +0200941 Py_ssize_t res = _PyDict_SizeOf((PyDictObject *)od);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300942 res += sizeof(_ODictNode *) * _odict_FAST_SIZE(od); /* od_fast_nodes */
Eric Snow96c6af92015-05-29 22:21:39 -0600943 if (!_odict_EMPTY(od)) {
944 res += sizeof(_ODictNode) * PyODict_SIZE(od); /* linked-list */
945 }
946 return PyLong_FromSsize_t(res);
947}
948
949/* __reduce__() */
950
951PyDoc_STRVAR(odict_reduce__doc__, "Return state information for pickling");
952
953static PyObject *
954odict_reduce(register PyODictObject *od)
955{
956 _Py_IDENTIFIER(__dict__);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300957 _Py_IDENTIFIER(items);
Serhiy Storchaka4575beb2015-10-22 20:18:24 +0300958 PyObject *dict = NULL, *result = NULL;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300959 PyObject *items_iter, *items, *args = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -0600960
961 /* capture any instance state */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300962 dict = _PyObject_GetAttrId((PyObject *)od, &PyId___dict__);
963 if (dict == NULL)
Eric Snowc5e59602015-05-30 11:28:56 -0600964 goto Done;
965 else {
Eric Snow96c6af92015-05-29 22:21:39 -0600966 /* od.__dict__ isn't necessarily a dict... */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300967 Py_ssize_t dict_len = PyObject_Length(dict);
968 if (dict_len == -1)
Eric Snow96c6af92015-05-29 22:21:39 -0600969 goto Done;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300970 if (!dict_len) {
971 /* nothing to pickle in od.__dict__ */
972 Py_CLEAR(dict);
Eric Snow96c6af92015-05-29 22:21:39 -0600973 }
974 }
975
976 /* build the result */
Eric Snow96c6af92015-05-29 22:21:39 -0600977 args = PyTuple_New(0);
978 if (args == NULL)
979 goto Done;
980
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300981 items = _PyObject_CallMethodIdObjArgs((PyObject *)od, &PyId_items, NULL);
Eric Snow96c6af92015-05-29 22:21:39 -0600982 if (items == NULL)
983 goto Done;
984
985 items_iter = PyObject_GetIter(items);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300986 Py_DECREF(items);
Eric Snow96c6af92015-05-29 22:21:39 -0600987 if (items_iter == NULL)
988 goto Done;
989
Serhiy Storchaka4575beb2015-10-22 20:18:24 +0300990 result = PyTuple_Pack(5, Py_TYPE(od), args, dict ? dict : Py_None, Py_None, items_iter);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300991 Py_DECREF(items_iter);
Eric Snow96c6af92015-05-29 22:21:39 -0600992
993Done:
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300994 Py_XDECREF(dict);
Eric Snow96c6af92015-05-29 22:21:39 -0600995 Py_XDECREF(args);
Eric Snow96c6af92015-05-29 22:21:39 -0600996
997 return result;
998}
999
1000/* setdefault() */
1001
1002PyDoc_STRVAR(odict_setdefault__doc__,
1003 "od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od");
1004
1005/* Skips __missing__() calls. */
1006static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001007odict_setdefault(register PyODictObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001008{
Eric Snowac02ef32015-06-02 20:42:14 -06001009 static char *kwlist[] = {"key", "default", 0};
Eric Snow96c6af92015-05-29 22:21:39 -06001010 PyObject *key, *result = NULL;
1011 PyObject *failobj = Py_None;
1012
1013 /* both borrowed */
Eric Snowac02ef32015-06-02 20:42:14 -06001014 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:setdefault", kwlist,
1015 &key, &failobj)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001016 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001017 }
Eric Snow96c6af92015-05-29 22:21:39 -06001018
1019 if (PyODict_CheckExact(od)) {
Eric Snowd1719752015-06-01 23:12:13 -06001020 result = PyODict_GetItemWithError(od, key); /* borrowed */
1021 if (result == NULL) {
1022 if (PyErr_Occurred())
1023 return NULL;
1024 assert(_odict_find_node(od, key) == NULL);
1025 if (PyODict_SetItem((PyObject *)od, key, failobj) >= 0) {
Eric Snow96c6af92015-05-29 22:21:39 -06001026 result = failobj;
1027 Py_INCREF(failobj);
1028 }
1029 }
1030 else {
Eric Snowd1719752015-06-01 23:12:13 -06001031 Py_INCREF(result);
Eric Snow96c6af92015-05-29 22:21:39 -06001032 }
1033 }
1034 else {
1035 int exists = PySequence_Contains((PyObject *)od, key);
1036 if (exists < 0) {
Eric Snowd1719752015-06-01 23:12:13 -06001037 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001038 }
1039 else if (exists) {
1040 result = PyObject_GetItem((PyObject *)od, key);
1041 }
1042 else if (PyObject_SetItem((PyObject *)od, key, failobj) >= 0) {
1043 result = failobj;
1044 Py_INCREF(failobj);
1045 }
1046 }
1047
Eric Snow96c6af92015-05-29 22:21:39 -06001048 return result;
1049}
1050
1051/* pop() */
1052
1053PyDoc_STRVAR(odict_pop__doc__,
1054"od.pop(k[,d]) -> v, remove specified key and return the corresponding\n\
1055 value. If key is not found, d is returned if given, otherwise KeyError\n\
1056 is raised.\n\
1057\n\
1058 ");
1059
1060/* forward */
1061static PyObject * _odict_popkey(PyObject *, PyObject *, PyObject *);
1062
1063/* Skips __missing__() calls. */
1064static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001065odict_pop(PyObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001066{
Eric Snowac02ef32015-06-02 20:42:14 -06001067 static char *kwlist[] = {"key", "default", 0};
Eric Snow96c6af92015-05-29 22:21:39 -06001068 PyObject *key, *failobj = NULL;
1069
Eric Snowac02ef32015-06-02 20:42:14 -06001070 /* borrowed */
1071 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:pop", kwlist,
1072 &key, &failobj)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001073 return NULL;
1074 }
1075
1076 return _odict_popkey(od, key, failobj);
1077}
1078
1079static PyObject *
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001080_odict_popkey_hash(PyObject *od, PyObject *key, PyObject *failobj,
1081 Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -06001082{
1083 _ODictNode *node;
1084 PyObject *value = NULL;
1085
Eric Snow96c6af92015-05-29 22:21:39 -06001086 /* Pop the node first to avoid a possible dict resize (due to
1087 eval loop reentrancy) and complications due to hash collision
1088 resolution. */
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001089 node = _odict_find_node_hash((PyODictObject *)od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001090 if (node == NULL) {
1091 if (PyErr_Occurred())
Eric Snowd1719752015-06-01 23:12:13 -06001092 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001093 }
1094 else {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001095 int res = _odict_clear_node((PyODictObject *)od, node, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001096 if (res < 0) {
Eric Snowd1719752015-06-01 23:12:13 -06001097 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001098 }
1099 }
1100
1101 /* Now delete the value from the dict. */
1102 if (PyODict_CheckExact(od)) {
1103 if (node != NULL) {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001104 value = _PyDict_GetItem_KnownHash(od, key, hash); /* borrowed */
1105 if (value != NULL) {
1106 Py_INCREF(value);
1107 if (_PyDict_DelItem_KnownHash(od, key, hash) < 0) {
1108 Py_DECREF(value);
1109 return NULL;
1110 }
1111 }
Eric Snow96c6af92015-05-29 22:21:39 -06001112 }
1113 }
1114 else {
1115 int exists = PySequence_Contains(od, key);
1116 if (exists < 0)
Eric Snowd1719752015-06-01 23:12:13 -06001117 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001118 if (exists) {
1119 value = PyObject_GetItem(od, key);
1120 if (value != NULL) {
1121 if (PyObject_DelItem(od, key) == -1) {
Eric Snowe3dfa9e2015-05-30 12:51:15 -06001122 Py_CLEAR(value);
Eric Snow96c6af92015-05-29 22:21:39 -06001123 }
1124 }
1125 }
1126 }
1127
1128 /* Apply the fallback value, if necessary. */
1129 if (value == NULL && !PyErr_Occurred()) {
1130 if (failobj) {
1131 value = failobj;
1132 Py_INCREF(failobj);
1133 }
1134 else {
1135 PyErr_SetObject(PyExc_KeyError, key);
1136 }
1137 }
1138
Eric Snow96c6af92015-05-29 22:21:39 -06001139 return value;
1140}
1141
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001142static PyObject *
1143_odict_popkey(PyObject *od, PyObject *key, PyObject *failobj)
1144{
1145 Py_hash_t hash = PyObject_Hash(key);
1146 if (hash == -1)
1147 return NULL;
1148
1149 return _odict_popkey_hash(od, key, failobj, hash);
1150}
1151
Eric Snow96c6af92015-05-29 22:21:39 -06001152/* popitem() */
1153
1154PyDoc_STRVAR(odict_popitem__doc__,
1155"od.popitem() -> (k, v), return and remove a (key, value) pair.\n\
1156 Pairs are returned in LIFO order if last is true or FIFO order if false.\n\
1157\n\
1158 ");
1159
1160static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001161odict_popitem(PyObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001162{
Eric Snowac02ef32015-06-02 20:42:14 -06001163 static char *kwlist[] = {"last", 0};
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001164 PyObject *key, *value, *item = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001165 _ODictNode *node;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001166 int last = 1;
Eric Snow96c6af92015-05-29 22:21:39 -06001167
1168 /* pull the item */
1169
Eric Snowac02ef32015-06-02 20:42:14 -06001170 /* borrowed */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001171 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|p:popitem", kwlist,
Eric Snowac02ef32015-06-02 20:42:14 -06001172 &last)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001173 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001174 }
Eric Snow96c6af92015-05-29 22:21:39 -06001175
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001176 if (_odict_EMPTY(od)) {
1177 PyErr_SetString(PyExc_KeyError, "dictionary is empty");
1178 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001179 }
Eric Snow96c6af92015-05-29 22:21:39 -06001180
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001181 node = last ? _odict_LAST(od) : _odict_FIRST(od);
Eric Snow96c6af92015-05-29 22:21:39 -06001182 key = _odictnode_KEY(node);
Eric Snowd1719752015-06-01 23:12:13 -06001183 Py_INCREF(key);
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001184 value = _odict_popkey_hash(od, key, NULL, _odictnode_HASH(node));
Eric Snow96c6af92015-05-29 22:21:39 -06001185 if (value == NULL)
1186 return NULL;
1187 item = PyTuple_Pack(2, key, value);
Eric Snowd1719752015-06-01 23:12:13 -06001188 Py_DECREF(key);
Eric Snow96c6af92015-05-29 22:21:39 -06001189 Py_DECREF(value);
1190 return item;
1191}
1192
1193/* keys() */
1194
1195/* MutableMapping.keys() does not have a docstring. */
1196PyDoc_STRVAR(odict_keys__doc__, "");
1197
1198static PyObject * odictkeys_new(PyObject *od); /* forward */
1199
1200/* values() */
1201
1202/* MutableMapping.values() does not have a docstring. */
1203PyDoc_STRVAR(odict_values__doc__, "");
1204
1205static PyObject * odictvalues_new(PyObject *od); /* forward */
1206
1207/* items() */
1208
1209/* MutableMapping.items() does not have a docstring. */
1210PyDoc_STRVAR(odict_items__doc__, "");
1211
1212static PyObject * odictitems_new(PyObject *od); /* forward */
1213
1214/* update() */
1215
1216/* MutableMapping.update() does not have a docstring. */
1217PyDoc_STRVAR(odict_update__doc__, "");
1218
1219/* forward */
1220static PyObject * mutablemapping_update(PyObject *, PyObject *, PyObject *);
1221
1222#define odict_update mutablemapping_update
1223
1224/* clear() */
1225
1226PyDoc_STRVAR(odict_clear__doc__,
1227 "od.clear() -> None. Remove all items from od.");
1228
1229static PyObject *
1230odict_clear(register PyODictObject *od)
1231{
1232 PyDict_Clear((PyObject *)od);
1233 _odict_clear_nodes(od);
Eric Snow96c6af92015-05-29 22:21:39 -06001234 if (_odict_resize(od) < 0)
1235 return NULL;
1236 Py_RETURN_NONE;
1237}
1238
1239/* copy() */
1240
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001241/* forward */
1242static int _PyODict_SetItem_KnownHash(PyObject *, PyObject *, PyObject *,
1243 Py_hash_t);
1244
Eric Snow96c6af92015-05-29 22:21:39 -06001245PyDoc_STRVAR(odict_copy__doc__, "od.copy() -> a shallow copy of od");
1246
1247static PyObject *
1248odict_copy(register PyODictObject *od)
1249{
1250 _ODictNode *node;
1251 PyObject *od_copy;
1252
1253 if (PyODict_CheckExact(od))
1254 od_copy = PyODict_New();
1255 else
1256 od_copy = PyObject_CallFunctionObjArgs((PyObject *)Py_TYPE(od), NULL);
1257 if (od_copy == NULL)
1258 return NULL;
1259
1260 if (PyODict_CheckExact(od)) {
1261 _odict_FOREACH(od, node) {
Eric Snowa762af72015-06-01 22:59:08 -06001262 PyObject *key = _odictnode_KEY(node);
1263 PyObject *value = _odictnode_VALUE(node, od);
1264 if (value == NULL) {
1265 if (!PyErr_Occurred())
1266 PyErr_SetObject(PyExc_KeyError, key);
1267 goto fail;
1268 }
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001269 if (_PyODict_SetItem_KnownHash((PyObject *)od_copy, key, value,
1270 _odictnode_HASH(node)) != 0)
Eric Snow96c6af92015-05-29 22:21:39 -06001271 goto fail;
1272 }
1273 }
1274 else {
1275 _odict_FOREACH(od, node) {
1276 int res;
1277 PyObject *value = PyObject_GetItem((PyObject *)od,
1278 _odictnode_KEY(node));
1279 if (value == NULL)
1280 goto fail;
1281 res = PyObject_SetItem((PyObject *)od_copy,
1282 _odictnode_KEY(node), value);
1283 Py_DECREF(value);
1284 if (res != 0)
1285 goto fail;
1286 }
1287 }
1288 return od_copy;
1289
1290fail:
1291 Py_DECREF(od_copy);
1292 return NULL;
1293}
1294
1295/* __reversed__() */
1296
1297PyDoc_STRVAR(odict_reversed__doc__, "od.__reversed__() <==> reversed(od)");
1298
1299#define _odict_ITER_REVERSED 1
1300#define _odict_ITER_KEYS 2
1301#define _odict_ITER_VALUES 4
1302
1303/* forward */
1304static PyObject * odictiter_new(PyODictObject *, int);
1305
1306static PyObject *
1307odict_reversed(PyODictObject *od)
1308{
Eric Snow96c6af92015-05-29 22:21:39 -06001309 return odictiter_new(od, _odict_ITER_KEYS|_odict_ITER_REVERSED);
1310}
1311
1312/* move_to_end() */
1313
1314PyDoc_STRVAR(odict_move_to_end__doc__,
1315"Move an existing element to the end (or beginning if last==False).\n\
1316\n\
1317 Raises KeyError if the element does not exist.\n\
1318 When last=True, acts like a fast version of self[key]=self.pop(key).\n\
1319\n\
1320 ");
1321
1322static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001323odict_move_to_end(PyODictObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001324{
Eric Snowac02ef32015-06-02 20:42:14 -06001325 static char *kwlist[] = {"key", "last", 0};
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001326 PyObject *key;
1327 int last = 1;
1328 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001329
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001330 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|p:move_to_end", kwlist,
Eric Snowac02ef32015-06-02 20:42:14 -06001331 &key, &last)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001332 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001333 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001334
Eric Snow96c6af92015-05-29 22:21:39 -06001335 if (_odict_EMPTY(od)) {
1336 PyErr_SetObject(PyExc_KeyError, key);
Eric Snow96c6af92015-05-29 22:21:39 -06001337 return NULL;
1338 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001339 node = last ? _odict_LAST(od) : _odict_FIRST(od);
1340 if (key != _odictnode_KEY(node)) {
1341 node = _odict_find_node(od, key);
1342 if (node == NULL) {
1343 if (!PyErr_Occurred())
1344 PyErr_SetObject(PyExc_KeyError, key);
Eric Snowc5e59602015-05-30 11:28:56 -06001345 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001346 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001347 if (last) {
1348 /* Only move if not already the last one. */
1349 if (node != _odict_LAST(od)) {
1350 _odict_remove_node(od, node);
Eric Snow96c6af92015-05-29 22:21:39 -06001351 _odict_add_tail(od, node);
1352 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001353 }
1354 else {
1355 /* Only move if not already the first one. */
1356 if (node != _odict_FIRST(od)) {
1357 _odict_remove_node(od, node);
1358 _odict_add_head(od, node);
Eric Snow96c6af92015-05-29 22:21:39 -06001359 }
1360 }
1361 }
Eric Snow96c6af92015-05-29 22:21:39 -06001362 Py_RETURN_NONE;
1363}
1364
1365
1366/* tp_methods */
1367
1368static PyMethodDef odict_methods[] = {
1369
1370 /* explicitly defined so we can align docstrings with
1371 * collections.OrderedDict */
1372 {"__delitem__", (PyCFunction)odict_mp_ass_sub, METH_NOARGS,
1373 odict_delitem__doc__},
1374 {"__eq__", (PyCFunction)odict_eq, METH_NOARGS,
1375 odict_eq__doc__},
1376 {"__init__", (PyCFunction)odict_init, METH_NOARGS,
1377 odict_init__doc__},
1378 {"__iter__", (PyCFunction)odict_iter, METH_NOARGS,
1379 odict_iter__doc__},
1380 {"__ne__", (PyCFunction)odict_ne, METH_NOARGS,
1381 odict_ne__doc__},
1382 {"__repr__", (PyCFunction)odict_repr, METH_NOARGS,
1383 odict_repr__doc__},
1384 {"__setitem__", (PyCFunction)odict_mp_ass_sub, METH_NOARGS,
1385 odict_setitem__doc__},
Eric Snowac02ef32015-06-02 20:42:14 -06001386 {"fromkeys", (PyCFunction)odict_fromkeys,
1387 METH_VARARGS | METH_KEYWORDS | METH_CLASS, odict_fromkeys__doc__},
Eric Snow96c6af92015-05-29 22:21:39 -06001388
1389 /* overridden dict methods */
1390 {"__sizeof__", (PyCFunction)odict_sizeof, METH_NOARGS,
1391 odict_sizeof__doc__},
1392 {"__reduce__", (PyCFunction)odict_reduce, METH_NOARGS,
1393 odict_reduce__doc__},
Eric Snowac02ef32015-06-02 20:42:14 -06001394 {"setdefault", (PyCFunction)odict_setdefault,
1395 METH_VARARGS | METH_KEYWORDS, odict_setdefault__doc__},
1396 {"pop", (PyCFunction)odict_pop,
1397 METH_VARARGS | METH_KEYWORDS, odict_pop__doc__},
1398 {"popitem", (PyCFunction)odict_popitem,
1399 METH_VARARGS | METH_KEYWORDS, odict_popitem__doc__},
Eric Snow96c6af92015-05-29 22:21:39 -06001400 {"keys", (PyCFunction)odictkeys_new, METH_NOARGS,
1401 odict_keys__doc__},
1402 {"values", (PyCFunction)odictvalues_new, METH_NOARGS,
1403 odict_values__doc__},
1404 {"items", (PyCFunction)odictitems_new, METH_NOARGS,
1405 odict_items__doc__},
1406 {"update", (PyCFunction)odict_update, METH_VARARGS | METH_KEYWORDS,
1407 odict_update__doc__},
1408 {"clear", (PyCFunction)odict_clear, METH_NOARGS,
1409 odict_clear__doc__},
1410 {"copy", (PyCFunction)odict_copy, METH_NOARGS,
1411 odict_copy__doc__},
1412
1413 /* new methods */
1414 {"__reversed__", (PyCFunction)odict_reversed, METH_NOARGS,
1415 odict_reversed__doc__},
Eric Snowac02ef32015-06-02 20:42:14 -06001416 {"move_to_end", (PyCFunction)odict_move_to_end,
1417 METH_VARARGS | METH_KEYWORDS, odict_move_to_end__doc__},
Eric Snow96c6af92015-05-29 22:21:39 -06001418
1419 {NULL, NULL} /* sentinel */
1420};
1421
1422
1423/* ----------------------------------------------
1424 * OrderedDict members
1425 */
1426
1427/* tp_members */
1428
1429static PyMemberDef odict_members[] = {
1430 {"__dict__", T_OBJECT, offsetof(PyODictObject, od_inst_dict), READONLY},
1431 {0}
1432};
1433
1434
1435/* ----------------------------------------------
1436 * OrderedDict type slot methods
1437 */
1438
1439/* tp_dealloc */
1440
1441static void
1442odict_dealloc(PyODictObject *self)
1443{
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001444 PyThreadState *tstate = PyThreadState_GET();
1445
Eric Snow96c6af92015-05-29 22:21:39 -06001446 PyObject_GC_UnTrack(self);
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001447 Py_TRASHCAN_SAFE_BEGIN(self)
1448
Eric Snow96c6af92015-05-29 22:21:39 -06001449 Py_XDECREF(self->od_inst_dict);
1450 if (self->od_weakreflist != NULL)
1451 PyObject_ClearWeakRefs((PyObject *)self);
1452
1453 _odict_clear_nodes(self);
Eric Snow96c6af92015-05-29 22:21:39 -06001454
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001455 /* Call the base tp_dealloc(). Since it too uses the trashcan mechanism,
1456 * temporarily decrement trash_delete_nesting to prevent triggering it
1457 * and putting the partially deallocated object on the trashcan's
1458 * to-be-deleted-later list.
1459 */
1460 --tstate->trash_delete_nesting;
1461 assert(_tstate->trash_delete_nesting < PyTrash_UNWIND_LEVEL);
Eric Snow96c6af92015-05-29 22:21:39 -06001462 PyDict_Type.tp_dealloc((PyObject *)self);
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001463 ++tstate->trash_delete_nesting;
1464
1465 Py_TRASHCAN_SAFE_END(self)
Eric Snow96c6af92015-05-29 22:21:39 -06001466};
1467
1468/* tp_repr */
1469
1470static PyObject *
1471odict_repr(PyODictObject *self)
1472{
1473 int i;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001474 _Py_IDENTIFIER(items);
Serhiy Storchaka4575beb2015-10-22 20:18:24 +03001475 PyObject *pieces = NULL, *result = NULL;
1476 const char *classname;
1477
1478 classname = strrchr(Py_TYPE(self)->tp_name, '.');
1479 if (classname == NULL)
1480 classname = Py_TYPE(self)->tp_name;
1481 else
1482 classname++;
1483
1484 if (PyODict_SIZE(self) == 0)
1485 return PyUnicode_FromFormat("%s()", classname);
Eric Snow96c6af92015-05-29 22:21:39 -06001486
1487 i = Py_ReprEnter((PyObject *)self);
1488 if (i != 0) {
1489 return i > 0 ? PyUnicode_FromString("...") : NULL;
1490 }
1491
Eric Snow96c6af92015-05-29 22:21:39 -06001492 if (PyODict_CheckExact(self)) {
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001493 Py_ssize_t count = 0;
Eric Snowa762af72015-06-01 22:59:08 -06001494 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001495 pieces = PyList_New(PyODict_SIZE(self));
1496 if (pieces == NULL)
1497 goto Done;
1498
1499 _odict_FOREACH(self, node) {
Eric Snowa762af72015-06-01 22:59:08 -06001500 PyObject *pair;
1501 PyObject *key = _odictnode_KEY(node);
1502 PyObject *value = _odictnode_VALUE(node, self);
1503 if (value == NULL) {
1504 if (!PyErr_Occurred())
1505 PyErr_SetObject(PyExc_KeyError, key);
Eric Snowdb4061c2015-06-03 11:09:48 -06001506 goto Done;
Eric Snowa762af72015-06-01 22:59:08 -06001507 }
1508 pair = PyTuple_Pack(2, key, value);
Eric Snow96c6af92015-05-29 22:21:39 -06001509 if (pair == NULL)
1510 goto Done;
1511
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001512 if (count < PyList_GET_SIZE(pieces))
1513 PyList_SET_ITEM(pieces, count, pair); /* steals reference */
1514 else {
1515 if (PyList_Append(pieces, pair) < 0) {
1516 Py_DECREF(pair);
1517 goto Done;
1518 }
1519 Py_DECREF(pair);
1520 }
1521 count++;
Eric Snow96c6af92015-05-29 22:21:39 -06001522 }
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001523 if (count < PyList_GET_SIZE(pieces))
1524 PyList_GET_SIZE(pieces) = count;
Eric Snow96c6af92015-05-29 22:21:39 -06001525 }
1526 else {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001527 PyObject *items = _PyObject_CallMethodIdObjArgs((PyObject *)self,
1528 &PyId_items, NULL);
Eric Snow96c6af92015-05-29 22:21:39 -06001529 if (items == NULL)
1530 goto Done;
1531 pieces = PySequence_List(items);
1532 Py_DECREF(items);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001533 if (pieces == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -06001534 goto Done;
1535 }
1536
Serhiy Storchaka4575beb2015-10-22 20:18:24 +03001537 result = PyUnicode_FromFormat("%s(%R)", classname, pieces);
Eric Snow96c6af92015-05-29 22:21:39 -06001538
Eric Snow96c6af92015-05-29 22:21:39 -06001539Done:
1540 Py_XDECREF(pieces);
Eric Snow96c6af92015-05-29 22:21:39 -06001541 Py_ReprLeave((PyObject *)self);
1542 return result;
1543};
1544
1545/* tp_doc */
1546
1547PyDoc_STRVAR(odict_doc,
1548 "Dictionary that remembers insertion order");
1549
1550/* tp_traverse */
1551
1552static int
1553odict_traverse(PyODictObject *od, visitproc visit, void *arg)
1554{
Serhiy Storchakad205d012016-01-19 14:46:25 +02001555 _ODictNode *node;
1556
Eric Snow96c6af92015-05-29 22:21:39 -06001557 Py_VISIT(od->od_inst_dict);
1558 Py_VISIT(od->od_weakreflist);
Serhiy Storchakad205d012016-01-19 14:46:25 +02001559 _odict_FOREACH(od, node) {
1560 Py_VISIT(_odictnode_KEY(node));
1561 }
Eric Snow96c6af92015-05-29 22:21:39 -06001562 return PyDict_Type.tp_traverse((PyObject *)od, visit, arg);
1563}
1564
1565/* tp_clear */
1566
1567static int
1568odict_tp_clear(PyODictObject *od)
1569{
1570 PyObject *res;
1571 Py_CLEAR(od->od_inst_dict);
1572 Py_CLEAR(od->od_weakreflist);
1573 res = odict_clear(od);
1574 if (res == NULL)
1575 return -1;
1576 Py_DECREF(res);
1577 return 0;
1578}
1579
1580/* tp_richcompare */
1581
1582static PyObject *
1583odict_richcompare(PyObject *v, PyObject *w, int op)
1584{
1585 if (!PyODict_Check(v) || !PyDict_Check(w)) {
1586 Py_RETURN_NOTIMPLEMENTED;
1587 }
1588
1589 if (op == Py_EQ || op == Py_NE) {
1590 PyObject *res, *cmp;
1591 int eq;
1592
1593 cmp = PyDict_Type.tp_richcompare(v, w, op);
1594 if (cmp == NULL)
1595 return NULL;
1596 if (!PyODict_Check(w))
1597 return cmp;
1598 if (op == Py_EQ && cmp == Py_False)
1599 return cmp;
1600 if (op == Py_NE && cmp == Py_True)
1601 return cmp;
1602 Py_DECREF(cmp);
1603
1604 /* Try comparing odict keys. */
1605 eq = _odict_keys_equal((PyODictObject *)v, (PyODictObject *)w);
1606 if (eq < 0)
1607 return NULL;
1608
1609 res = (eq == (op == Py_EQ)) ? Py_True : Py_False;
1610 Py_INCREF(res);
1611 return res;
1612 } else {
1613 Py_RETURN_NOTIMPLEMENTED;
1614 }
1615};
1616
1617/* tp_iter */
1618
1619static PyObject *
1620odict_iter(PyODictObject *od)
1621{
1622 return odictiter_new(od, _odict_ITER_KEYS);
1623};
1624
1625/* tp_init */
1626
1627static int
1628odict_init(PyObject *self, PyObject *args, PyObject *kwds)
1629{
1630 PyObject *res;
1631 Py_ssize_t len = PyObject_Length(args);
1632
1633 if (len == -1)
1634 return -1;
1635 if (len > 1) {
1636 char *msg = "expected at most 1 arguments, got %d";
1637 PyErr_Format(PyExc_TypeError, msg, len);
1638 return -1;
1639 }
1640
1641 /* __init__() triggering update() is just the way things are! */
1642 res = odict_update(self, args, kwds);
1643 if (res == NULL) {
1644 return -1;
1645 } else {
1646 Py_DECREF(res);
1647 return 0;
1648 }
1649};
1650
1651/* tp_new */
1652
1653static PyObject *
1654odict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1655{
Victor Stinnerca30b022015-09-03 17:50:04 +02001656 PyObject *dict;
1657 PyODictObject *od;
1658
1659 dict = PyDict_New();
1660 if (dict == NULL)
1661 return NULL;
1662
1663 od = (PyODictObject *)PyDict_Type.tp_new(type, args, kwds);
1664 if (od == NULL) {
1665 Py_DECREF(dict);
1666 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001667 }
Victor Stinnerca30b022015-09-03 17:50:04 +02001668
1669 od->od_inst_dict = dict;
1670 /* type constructor fills the memory with zeros (see
1671 PyType_GenericAlloc()), there is no need to set them to zero again */
1672 if (_odict_resize(od) < 0) {
1673 Py_DECREF(od);
1674 return NULL;
1675 }
1676
1677 return (PyObject*)od;
Eric Snow96c6af92015-05-29 22:21:39 -06001678}
1679
1680/* PyODict_Type */
1681
1682PyTypeObject PyODict_Type = {
1683 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1684 "collections.OrderedDict", /* tp_name */
1685 sizeof(PyODictObject), /* tp_basicsize */
1686 0, /* tp_itemsize */
1687 (destructor)odict_dealloc, /* tp_dealloc */
1688 0, /* tp_print */
1689 0, /* tp_getattr */
1690 0, /* tp_setattr */
1691 0, /* tp_reserved */
1692 (reprfunc)odict_repr, /* tp_repr */
1693 0, /* tp_as_number */
1694 0, /* tp_as_sequence */
1695 &odict_as_mapping, /* tp_as_mapping */
1696 0, /* tp_hash */
1697 0, /* tp_call */
1698 0, /* tp_str */
1699 0, /* tp_getattro */
1700 0, /* tp_setattro */
1701 0, /* tp_as_buffer */
1702 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,/* tp_flags */
1703 odict_doc, /* tp_doc */
1704 (traverseproc)odict_traverse, /* tp_traverse */
1705 (inquiry)odict_tp_clear, /* tp_clear */
1706 (richcmpfunc)odict_richcompare, /* tp_richcompare */
1707 offsetof(PyODictObject, od_weakreflist), /* tp_weaklistoffset */
1708 (getiterfunc)odict_iter, /* tp_iter */
1709 0, /* tp_iternext */
1710 odict_methods, /* tp_methods */
1711 odict_members, /* tp_members */
1712 0, /* tp_getset */
1713 &PyDict_Type, /* tp_base */
1714 0, /* tp_dict */
1715 0, /* tp_descr_get */
1716 0, /* tp_descr_set */
1717 offsetof(PyODictObject, od_inst_dict), /* tp_dictoffset */
1718 (initproc)odict_init, /* tp_init */
1719 PyType_GenericAlloc, /* tp_alloc */
1720 (newfunc)odict_new, /* tp_new */
1721 0, /* tp_free */
1722};
1723
1724
1725/* ----------------------------------------------
1726 * the public OrderedDict API
1727 */
1728
1729PyObject *
1730PyODict_New(void) {
1731 return odict_new(&PyODict_Type, NULL, NULL);
1732};
1733
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001734static int
1735_PyODict_SetItem_KnownHash(PyObject *od, PyObject *key, PyObject *value,
1736 Py_hash_t hash)
1737{
1738 int res = _PyDict_SetItem_KnownHash(od, key, value, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001739 if (res == 0) {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001740 res = _odict_add_new_node((PyODictObject *)od, key, hash);
Serhiy Storchakad5f353e2015-11-06 11:07:11 +02001741 if (res < 0) {
1742 /* Revert setting the value on the dict */
1743 PyObject *exc, *val, *tb;
1744 PyErr_Fetch(&exc, &val, &tb);
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001745 (void) _PyDict_DelItem_KnownHash(od, key, hash);
Serhiy Storchakad5f353e2015-11-06 11:07:11 +02001746 _PyErr_ChainExceptions(exc, val, tb);
1747 }
Eric Snow96c6af92015-05-29 22:21:39 -06001748 }
1749 return res;
1750};
1751
1752int
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001753PyODict_SetItem(PyObject *od, PyObject *key, PyObject *value)
1754{
1755 Py_hash_t hash = PyObject_Hash(key);
1756 if (hash == -1)
1757 return -1;
1758 return _PyODict_SetItem_KnownHash(od, key, value, hash);
1759};
1760
1761int
1762PyODict_DelItem(PyObject *od, PyObject *key)
1763{
1764 int res;
1765 Py_hash_t hash = PyObject_Hash(key);
1766 if (hash == -1)
1767 return -1;
1768 res = _odict_clear_node((PyODictObject *)od, NULL, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001769 if (res < 0)
1770 return -1;
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001771 return _PyDict_DelItem_KnownHash(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001772};
1773
1774
1775/* -------------------------------------------
1776 * The OrderedDict views (keys/values/items)
1777 */
1778
1779typedef struct {
1780 PyObject_HEAD
1781 int kind;
1782 PyODictObject *di_odict;
Eric Snowb952ab42015-06-01 23:35:13 -06001783 Py_ssize_t di_size;
Eric Snow4fabf022015-06-04 00:09:56 -06001784 size_t di_state;
Eric Snow96c6af92015-05-29 22:21:39 -06001785 PyObject *di_current;
1786 PyObject *di_result; /* reusable result tuple for iteritems */
1787} odictiterobject;
1788
1789static void
1790odictiter_dealloc(odictiterobject *di)
1791{
1792 _PyObject_GC_UNTRACK(di);
Eric Snowa762af72015-06-01 22:59:08 -06001793 Py_XDECREF(di->di_odict);
Eric Snow96c6af92015-05-29 22:21:39 -06001794 Py_XDECREF(di->di_current);
1795 if (di->kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)) {
1796 Py_DECREF(di->di_result);
1797 }
1798 PyObject_GC_Del(di);
1799}
1800
1801static int
1802odictiter_traverse(odictiterobject *di, visitproc visit, void *arg)
1803{
1804 Py_VISIT(di->di_odict);
1805 Py_VISIT(di->di_current); /* A key could be any type, not just str. */
1806 Py_VISIT(di->di_result);
1807 return 0;
1808}
1809
Eric Snowa762af72015-06-01 22:59:08 -06001810/* In order to protect against modifications during iteration, we track
1811 * the current key instead of the current node. */
Eric Snow96c6af92015-05-29 22:21:39 -06001812static PyObject *
1813odictiter_nextkey(odictiterobject *di)
1814{
Eric Snowa762af72015-06-01 22:59:08 -06001815 PyObject *key = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001816 _ODictNode *node;
1817 int reversed = di->kind & _odict_ITER_REVERSED;
1818
Eric Snowa762af72015-06-01 22:59:08 -06001819 if (di->di_odict == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -06001820 return NULL;
Eric Snowa762af72015-06-01 22:59:08 -06001821 if (di->di_current == NULL)
1822 goto done; /* We're already done. */
1823
Eric Snowb952ab42015-06-01 23:35:13 -06001824 /* Check for unsupported changes. */
Eric Snow4fabf022015-06-04 00:09:56 -06001825 if (di->di_odict->od_state != di->di_state) {
1826 PyErr_SetString(PyExc_RuntimeError,
1827 "OrderedDict mutated during iteration");
1828 goto done;
1829 }
Eric Snowb952ab42015-06-01 23:35:13 -06001830 if (di->di_size != PyODict_SIZE(di->di_odict)) {
1831 PyErr_SetString(PyExc_RuntimeError,
1832 "OrderedDict changed size during iteration");
1833 di->di_size = -1; /* Make this state sticky */
1834 return NULL;
1835 }
1836
Eric Snowa762af72015-06-01 22:59:08 -06001837 /* Get the key. */
Eric Snow96c6af92015-05-29 22:21:39 -06001838 node = _odict_find_node(di->di_odict, di->di_current);
1839 if (node == NULL) {
Serhiy Storchakab45b7b22015-11-04 22:05:38 +02001840 if (!PyErr_Occurred())
1841 PyErr_SetObject(PyExc_KeyError, di->di_current);
Eric Snow96c6af92015-05-29 22:21:39 -06001842 /* Must have been deleted. */
Eric Snowe3dfa9e2015-05-30 12:51:15 -06001843 Py_CLEAR(di->di_current);
Eric Snow96c6af92015-05-29 22:21:39 -06001844 return NULL;
1845 }
1846 key = di->di_current;
1847
1848 /* Advance to the next key. */
1849 node = reversed ? _odictnode_PREV(node) : _odictnode_NEXT(node);
1850 if (node == NULL) {
1851 /* Reached the end. */
1852 di->di_current = NULL;
1853 }
1854 else {
1855 di->di_current = _odictnode_KEY(node);
1856 Py_INCREF(di->di_current);
1857 }
1858
1859 return key;
Eric Snowa762af72015-06-01 22:59:08 -06001860
1861done:
1862 Py_CLEAR(di->di_odict);
1863 return key;
Eric Snow96c6af92015-05-29 22:21:39 -06001864}
1865
1866static PyObject *
1867odictiter_iternext(odictiterobject *di)
1868{
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001869 PyObject *result, *value;
Eric Snow96c6af92015-05-29 22:21:39 -06001870 PyObject *key = odictiter_nextkey(di); /* new reference */
1871
1872 if (key == NULL)
1873 return NULL;
1874
1875 /* Handle the keys case. */
1876 if (! (di->kind & _odict_ITER_VALUES)) {
1877 return key;
1878 }
1879
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001880 value = PyODict_GetItem((PyObject *)di->di_odict, key); /* borrowed */
1881 if (value == NULL) {
1882 if (!PyErr_Occurred())
1883 PyErr_SetObject(PyExc_KeyError, key);
Eric Snow96c6af92015-05-29 22:21:39 -06001884 Py_DECREF(key);
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001885 goto done;
1886 }
1887 Py_INCREF(value);
1888
1889 /* Handle the values case. */
1890 if (!(di->kind & _odict_ITER_KEYS)) {
1891 Py_DECREF(key);
Eric Snow96c6af92015-05-29 22:21:39 -06001892 return value;
1893 }
Eric Snowa762af72015-06-01 22:59:08 -06001894
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001895 /* Handle the items case. */
1896 result = di->di_result;
1897
1898 if (Py_REFCNT(result) == 1) {
1899 /* not in use so we can reuse it
1900 * (the common case during iteration) */
1901 Py_INCREF(result);
1902 Py_DECREF(PyTuple_GET_ITEM(result, 0)); /* borrowed */
1903 Py_DECREF(PyTuple_GET_ITEM(result, 1)); /* borrowed */
1904 }
1905 else {
1906 result = PyTuple_New(2);
1907 if (result == NULL) {
1908 Py_DECREF(key);
1909 Py_DECREF(value);
1910 goto done;
1911 }
1912 }
1913
1914 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
1915 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
1916 return result;
1917
Eric Snowa762af72015-06-01 22:59:08 -06001918done:
1919 Py_CLEAR(di->di_current);
1920 Py_CLEAR(di->di_odict);
1921 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001922}
1923
1924/* No need for tp_clear because odictiterobject is not mutable. */
1925
1926PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
1927
1928static PyObject *
1929odictiter_reduce(odictiterobject *di)
1930{
Eric Snowc5e59602015-05-30 11:28:56 -06001931 PyObject *list, *iter;
Eric Snow96c6af92015-05-29 22:21:39 -06001932
1933 list = PyList_New(0);
1934 if (!list)
1935 return NULL;
1936
1937 /* iterate the temporary into a list */
1938 for(;;) {
1939 PyObject *element = odictiter_iternext(di);
1940 if (element) {
1941 if (PyList_Append(list, element)) {
1942 Py_DECREF(element);
1943 Py_DECREF(list);
1944 return NULL;
1945 }
1946 Py_DECREF(element);
1947 }
1948 else {
1949 /* done iterating? */
1950 break;
1951 }
1952 }
1953 if (PyErr_Occurred()) {
1954 Py_DECREF(list);
1955 return NULL;
1956 }
Eric Snowc5e59602015-05-30 11:28:56 -06001957 iter = _PyObject_GetBuiltin("iter");
1958 if (iter == NULL) {
1959 Py_DECREF(list);
1960 return NULL;
1961 }
1962 return Py_BuildValue("N(N)", iter, list);
Eric Snow96c6af92015-05-29 22:21:39 -06001963}
1964
1965static PyMethodDef odictiter_methods[] = {
1966 {"__reduce__", (PyCFunction)odictiter_reduce, METH_NOARGS, reduce_doc},
1967 {NULL, NULL} /* sentinel */
1968};
1969
1970PyTypeObject PyODictIter_Type = {
1971 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1972 "odict_iterator", /* tp_name */
1973 sizeof(odictiterobject), /* tp_basicsize */
1974 0, /* tp_itemsize */
1975 /* methods */
1976 (destructor)odictiter_dealloc, /* tp_dealloc */
1977 0, /* tp_print */
1978 0, /* tp_getattr */
1979 0, /* tp_setattr */
1980 0, /* tp_reserved */
1981 0, /* tp_repr */
1982 0, /* tp_as_number */
1983 0, /* tp_as_sequence */
1984 0, /* tp_as_mapping */
1985 0, /* tp_hash */
1986 0, /* tp_call */
1987 0, /* tp_str */
1988 PyObject_GenericGetAttr, /* tp_getattro */
1989 0, /* tp_setattro */
1990 0, /* tp_as_buffer */
1991 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1992 0, /* tp_doc */
1993 (traverseproc)odictiter_traverse, /* tp_traverse */
1994 0, /* tp_clear */
1995 0, /* tp_richcompare */
1996 0, /* tp_weaklistoffset */
1997 PyObject_SelfIter, /* tp_iter */
1998 (iternextfunc)odictiter_iternext, /* tp_iternext */
1999 odictiter_methods, /* tp_methods */
2000 0,
2001};
2002
2003static PyObject *
2004odictiter_new(PyODictObject *od, int kind)
2005{
2006 odictiterobject *di;
2007 _ODictNode *node;
2008 int reversed = kind & _odict_ITER_REVERSED;
2009
2010 di = PyObject_GC_New(odictiterobject, &PyODictIter_Type);
2011 if (di == NULL)
2012 return NULL;
2013
2014 if (kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)){
2015 di->di_result = PyTuple_Pack(2, Py_None, Py_None);
2016 if (di->di_result == NULL) {
2017 Py_DECREF(di);
2018 return NULL;
2019 }
2020 }
2021 else
2022 di->di_result = NULL;
2023
2024 di->kind = kind;
2025 node = reversed ? _odict_LAST(od) : _odict_FIRST(od);
2026 di->di_current = node ? _odictnode_KEY(node) : NULL;
2027 Py_XINCREF(di->di_current);
Eric Snowb952ab42015-06-01 23:35:13 -06002028 di->di_size = PyODict_SIZE(od);
Eric Snow4fabf022015-06-04 00:09:56 -06002029 di->di_state = od->od_state;
Eric Snow96c6af92015-05-29 22:21:39 -06002030 di->di_odict = od;
2031 Py_INCREF(od);
2032
2033 _PyObject_GC_TRACK(di);
2034 return (PyObject *)di;
2035}
2036
2037/* keys() */
2038
2039static PyObject *
2040odictkeys_iter(_PyDictViewObject *dv)
2041{
2042 if (dv->dv_dict == NULL) {
2043 Py_RETURN_NONE;
2044 }
2045 return odictiter_new((PyODictObject *)dv->dv_dict,
2046 _odict_ITER_KEYS);
2047}
2048
2049static PyObject *
2050odictkeys_reversed(_PyDictViewObject *dv)
2051{
2052 if (dv->dv_dict == NULL) {
2053 Py_RETURN_NONE;
2054 }
2055 return odictiter_new((PyODictObject *)dv->dv_dict,
2056 _odict_ITER_KEYS|_odict_ITER_REVERSED);
2057}
2058
2059static PyMethodDef odictkeys_methods[] = {
2060 {"__reversed__", (PyCFunction)odictkeys_reversed, METH_NOARGS, NULL},
2061 {NULL, NULL} /* sentinel */
2062};
2063
2064PyTypeObject PyODictKeys_Type = {
2065 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2066 "odict_keys", /* tp_name */
2067 0, /* tp_basicsize */
2068 0, /* tp_itemsize */
2069 0, /* tp_dealloc */
2070 0, /* tp_print */
2071 0, /* tp_getattr */
2072 0, /* tp_setattr */
2073 0, /* tp_reserved */
2074 0, /* tp_repr */
2075 0, /* tp_as_number */
2076 0, /* tp_as_sequence */
2077 0, /* tp_as_mapping */
2078 0, /* tp_hash */
2079 0, /* tp_call */
2080 0, /* tp_str */
2081 0, /* tp_getattro */
2082 0, /* tp_setattro */
2083 0, /* tp_as_buffer */
2084 0, /* tp_flags */
2085 0, /* tp_doc */
2086 0, /* tp_traverse */
2087 0, /* tp_clear */
2088 0, /* tp_richcompare */
2089 0, /* tp_weaklistoffset */
2090 (getiterfunc)odictkeys_iter, /* tp_iter */
2091 0, /* tp_iternext */
2092 odictkeys_methods, /* tp_methods */
2093 0, /* tp_members */
2094 0, /* tp_getset */
2095 &PyDictKeys_Type, /* tp_base */
2096};
2097
2098static PyObject *
2099odictkeys_new(PyObject *od)
2100{
2101 return _PyDictView_New(od, &PyODictKeys_Type);
2102}
2103
2104/* items() */
2105
2106static PyObject *
2107odictitems_iter(_PyDictViewObject *dv)
2108{
2109 if (dv->dv_dict == NULL) {
2110 Py_RETURN_NONE;
2111 }
2112 return odictiter_new((PyODictObject *)dv->dv_dict,
2113 _odict_ITER_KEYS|_odict_ITER_VALUES);
2114}
2115
2116static PyObject *
2117odictitems_reversed(_PyDictViewObject *dv)
2118{
2119 if (dv->dv_dict == NULL) {
2120 Py_RETURN_NONE;
2121 }
2122 return odictiter_new((PyODictObject *)dv->dv_dict,
2123 _odict_ITER_KEYS|_odict_ITER_VALUES|_odict_ITER_REVERSED);
2124}
2125
2126static PyMethodDef odictitems_methods[] = {
2127 {"__reversed__", (PyCFunction)odictitems_reversed, METH_NOARGS, NULL},
2128 {NULL, NULL} /* sentinel */
2129};
2130
2131PyTypeObject PyODictItems_Type = {
2132 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2133 "odict_items", /* tp_name */
2134 0, /* tp_basicsize */
2135 0, /* tp_itemsize */
2136 0, /* tp_dealloc */
2137 0, /* tp_print */
2138 0, /* tp_getattr */
2139 0, /* tp_setattr */
2140 0, /* tp_reserved */
2141 0, /* tp_repr */
2142 0, /* tp_as_number */
2143 0, /* tp_as_sequence */
2144 0, /* tp_as_mapping */
2145 0, /* tp_hash */
2146 0, /* tp_call */
2147 0, /* tp_str */
2148 0, /* tp_getattro */
2149 0, /* tp_setattro */
2150 0, /* tp_as_buffer */
2151 0, /* tp_flags */
2152 0, /* tp_doc */
2153 0, /* tp_traverse */
2154 0, /* tp_clear */
2155 0, /* tp_richcompare */
2156 0, /* tp_weaklistoffset */
2157 (getiterfunc)odictitems_iter, /* tp_iter */
2158 0, /* tp_iternext */
2159 odictitems_methods, /* tp_methods */
2160 0, /* tp_members */
2161 0, /* tp_getset */
2162 &PyDictItems_Type, /* tp_base */
2163};
2164
2165static PyObject *
2166odictitems_new(PyObject *od)
2167{
2168 return _PyDictView_New(od, &PyODictItems_Type);
2169}
2170
2171/* values() */
2172
2173static PyObject *
2174odictvalues_iter(_PyDictViewObject *dv)
2175{
2176 if (dv->dv_dict == NULL) {
2177 Py_RETURN_NONE;
2178 }
2179 return odictiter_new((PyODictObject *)dv->dv_dict,
2180 _odict_ITER_VALUES);
2181}
2182
2183static PyObject *
2184odictvalues_reversed(_PyDictViewObject *dv)
2185{
2186 if (dv->dv_dict == NULL) {
2187 Py_RETURN_NONE;
2188 }
2189 return odictiter_new((PyODictObject *)dv->dv_dict,
2190 _odict_ITER_VALUES|_odict_ITER_REVERSED);
2191}
2192
2193static PyMethodDef odictvalues_methods[] = {
2194 {"__reversed__", (PyCFunction)odictvalues_reversed, METH_NOARGS, NULL},
2195 {NULL, NULL} /* sentinel */
2196};
2197
2198PyTypeObject PyODictValues_Type = {
2199 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2200 "odict_values", /* tp_name */
2201 0, /* tp_basicsize */
2202 0, /* tp_itemsize */
2203 0, /* tp_dealloc */
2204 0, /* tp_print */
2205 0, /* tp_getattr */
2206 0, /* tp_setattr */
2207 0, /* tp_reserved */
2208 0, /* tp_repr */
2209 0, /* tp_as_number */
2210 0, /* tp_as_sequence */
2211 0, /* tp_as_mapping */
2212 0, /* tp_hash */
2213 0, /* tp_call */
2214 0, /* tp_str */
2215 0, /* tp_getattro */
2216 0, /* tp_setattro */
2217 0, /* tp_as_buffer */
2218 0, /* tp_flags */
2219 0, /* tp_doc */
2220 0, /* tp_traverse */
2221 0, /* tp_clear */
2222 0, /* tp_richcompare */
2223 0, /* tp_weaklistoffset */
2224 (getiterfunc)odictvalues_iter, /* tp_iter */
2225 0, /* tp_iternext */
2226 odictvalues_methods, /* tp_methods */
2227 0, /* tp_members */
2228 0, /* tp_getset */
2229 &PyDictValues_Type, /* tp_base */
2230};
2231
2232static PyObject *
2233odictvalues_new(PyObject *od)
2234{
2235 return _PyDictView_New(od, &PyODictValues_Type);
2236}
2237
2238
2239/* ----------------------------------------------
2240 MutableMappping implementations
2241
2242Mapping:
2243
2244============ ===========
2245method uses
2246============ ===========
2247__contains__ __getitem__
2248__eq__ items
2249__getitem__ +
2250__iter__ +
2251__len__ +
2252__ne__ __eq__
2253get __getitem__
2254items ItemsView
2255keys KeysView
2256values ValuesView
2257============ ===========
2258
2259ItemsView uses __len__, __iter__, and __getitem__.
2260KeysView uses __len__, __iter__, and __contains__.
2261ValuesView uses __len__, __iter__, and __getitem__.
2262
2263MutableMapping:
2264
2265============ ===========
2266method uses
2267============ ===========
2268__delitem__ +
2269__setitem__ +
2270clear popitem
2271pop __getitem__
2272 __delitem__
2273popitem __iter__
2274 _getitem__
2275 __delitem__
2276setdefault __getitem__
2277 __setitem__
2278update __setitem__
2279============ ===========
2280*/
2281
2282static int
2283mutablemapping_add_pairs(PyObject *self, PyObject *pairs)
2284{
2285 PyObject *pair, *iterator, *unexpected;
2286 int res = 0;
2287
2288 iterator = PyObject_GetIter(pairs);
2289 if (iterator == NULL)
2290 return -1;
2291 PyErr_Clear();
2292
2293 while ((pair = PyIter_Next(iterator)) != NULL) {
2294 /* could be more efficient (see UNPACK_SEQUENCE in ceval.c) */
Eric Snowc5e59602015-05-30 11:28:56 -06002295 PyObject *key = NULL, *value = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06002296 PyObject *pair_iterator = PyObject_GetIter(pair);
Eric Snowc5e59602015-05-30 11:28:56 -06002297 if (pair_iterator == NULL)
2298 goto Done;
Eric Snow96c6af92015-05-29 22:21:39 -06002299
2300 key = PyIter_Next(pair_iterator);
2301 if (key == NULL) {
2302 if (!PyErr_Occurred())
2303 PyErr_SetString(PyExc_ValueError,
2304 "need more than 0 values to unpack");
2305 goto Done;
2306 }
2307
2308 value = PyIter_Next(pair_iterator);
2309 if (value == NULL) {
2310 if (!PyErr_Occurred())
2311 PyErr_SetString(PyExc_ValueError,
2312 "need more than 1 value to unpack");
2313 goto Done;
2314 }
2315
2316 unexpected = PyIter_Next(pair_iterator);
2317 if (unexpected != NULL) {
2318 Py_DECREF(unexpected);
2319 PyErr_SetString(PyExc_ValueError,
2320 "too many values to unpack (expected 2)");
2321 goto Done;
2322 }
2323 else if (PyErr_Occurred())
2324 goto Done;
2325
2326 res = PyObject_SetItem(self, key, value);
2327
2328Done:
2329 Py_DECREF(pair);
Eric Snowc5e59602015-05-30 11:28:56 -06002330 Py_XDECREF(pair_iterator);
Eric Snow96c6af92015-05-29 22:21:39 -06002331 Py_XDECREF(key);
2332 Py_XDECREF(value);
2333 if (PyErr_Occurred())
2334 break;
2335 }
2336 Py_DECREF(iterator);
2337
2338 if (res < 0 || PyErr_Occurred() != NULL)
2339 return -1;
2340 else
2341 return 0;
2342}
2343
2344static PyObject *
2345mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
2346{
2347 int res = 0;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002348 Py_ssize_t len;
2349 _Py_IDENTIFIER(items);
2350 _Py_IDENTIFIER(keys);
Eric Snow96c6af92015-05-29 22:21:39 -06002351
2352 /* first handle args, if any */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002353 assert(args == NULL || PyTuple_Check(args));
2354 len = (args != NULL) ? PyTuple_GET_SIZE(args) : 0;
Benjamin Peterson99e96f22015-06-06 23:20:32 -05002355 if (len > 1) {
Eric Snow96c6af92015-05-29 22:21:39 -06002356 char *msg = "update() takes at most 1 positional argument (%d given)";
2357 PyErr_Format(PyExc_TypeError, msg, len);
2358 return NULL;
2359 }
Eric Snow96c6af92015-05-29 22:21:39 -06002360
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002361 if (len) {
Benjamin Peterson0718de92015-06-07 00:00:42 -05002362 PyObject *other = PyTuple_GET_ITEM(args, 0); /* borrowed reference */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002363 assert(other != NULL);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002364 Py_INCREF(other);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002365 if (PyDict_CheckExact(other) ||
2366 _PyObject_HasAttrId(other, &PyId_items)) { /* never fails */
2367 PyObject *items;
2368 if (PyDict_CheckExact(other))
2369 items = PyDict_Items(other);
2370 else
2371 items = _PyObject_CallMethodId(other, &PyId_items, NULL);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002372 Py_DECREF(other);
2373 if (items == NULL)
2374 return NULL;
2375 res = mutablemapping_add_pairs(self, items);
2376 Py_DECREF(items);
2377 if (res == -1)
2378 return NULL;
2379 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002380 else if (_PyObject_HasAttrId(other, &PyId_keys)) { /* never fails */
Benjamin Peterson0718de92015-06-07 00:00:42 -05002381 PyObject *keys, *iterator, *key;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002382 keys = _PyObject_CallMethodIdObjArgs(other, &PyId_keys, NULL);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002383 if (keys == NULL) {
2384 Py_DECREF(other);
2385 return NULL;
2386 }
2387 iterator = PyObject_GetIter(keys);
2388 Py_DECREF(keys);
2389 if (iterator == NULL) {
2390 Py_DECREF(other);
2391 return NULL;
2392 }
2393 while (res == 0 && (key = PyIter_Next(iterator))) {
2394 PyObject *value = PyObject_GetItem(other, key);
2395 if (value != NULL) {
2396 res = PyObject_SetItem(self, key, value);
2397 Py_DECREF(value);
2398 }
2399 else {
2400 res = -1;
2401 }
2402 Py_DECREF(key);
2403 }
2404 Py_DECREF(other);
2405 Py_DECREF(iterator);
2406 if (res != 0 || PyErr_Occurred())
2407 return NULL;
2408 }
2409 else {
2410 res = mutablemapping_add_pairs(self, other);
2411 Py_DECREF(other);
2412 if (res != 0)
2413 return NULL;
2414 }
2415 }
2416
2417 /* now handle kwargs */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002418 assert(kwargs == NULL || PyDict_Check(kwargs));
2419 len = (kwargs != NULL) ? PyDict_Size(kwargs) : 0;
Benjamin Peterson0718de92015-06-07 00:00:42 -05002420 if (len > 0) {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002421 PyObject *items = PyDict_Items(kwargs);
Eric Snow96c6af92015-05-29 22:21:39 -06002422 if (items == NULL)
2423 return NULL;
2424 res = mutablemapping_add_pairs(self, items);
2425 Py_DECREF(items);
2426 if (res == -1)
2427 return NULL;
2428 }
Eric Snow96c6af92015-05-29 22:21:39 -06002429
2430 Py_RETURN_NONE;
2431}