blob: 5ad88bcacc5cb5958ac4e99874bdf6c46e059fe2 [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
197 PyDict_CheckExact() calls to each of the concrete API funcions.
1982. 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
775 if (!_odict_EMPTY(od)) {
776 node = _odict_FIRST(od);
777 while (node != NULL) {
778 next = _odictnode_NEXT(node);
779 _odictnode_DEALLOC(node);
780 node = next;
781 }
782 _odict_FIRST(od) = NULL;
783 _odict_LAST(od) = NULL;
784 }
785
786 _odict_free_fast_nodes(od);
787 od->od_fast_nodes = NULL;
788}
789
790/* There isn't any memory management of nodes past this point. */
791#undef _odictnode_DEALLOC
792
793static int
794_odict_keys_equal(PyODictObject *a, PyODictObject *b)
795{
796 _ODictNode *node_a, *node_b;
797
798 node_a = _odict_FIRST(a);
799 node_b = _odict_FIRST(b);
800 while (1) {
801 if (node_a == NULL && node_b == NULL)
802 /* success: hit the end of each at the same time */
803 return 1;
804 else if (node_a == NULL || node_b == NULL)
805 /* unequal length */
806 return 0;
807 else {
808 int res = PyObject_RichCompareBool(
809 (PyObject *)_odictnode_KEY(node_a),
810 (PyObject *)_odictnode_KEY(node_b),
811 Py_EQ);
812 if (res < 0)
813 return res;
814 else if (res == 0)
815 return 0;
816
817 /* otherwise it must match, so move on to the next one */
818 node_a = _odictnode_NEXT(node_a);
819 node_b = _odictnode_NEXT(node_b);
820 }
821 }
822}
823
824
825/* ----------------------------------------------
826 * OrderedDict mapping methods
827 */
828
829/* mp_ass_subscript: __setitem__() and __delitem__() */
830
831static int
832odict_mp_ass_sub(PyODictObject *od, PyObject *v, PyObject *w)
833{
834 if (w == NULL)
835 return PyODict_DelItem((PyObject *)od, v);
836 else
837 return PyODict_SetItem((PyObject *)od, v, w);
838}
839
840/* tp_as_mapping */
841
842static PyMappingMethods odict_as_mapping = {
843 0, /*mp_length*/
844 0, /*mp_subscript*/
845 (objobjargproc)odict_mp_ass_sub, /*mp_ass_subscript*/
846};
847
848
849/* ----------------------------------------------
850 * OrderedDict methods
851 */
852
853/* __delitem__() */
854
855PyDoc_STRVAR(odict_delitem__doc__, "od.__delitem__(y) <==> del od[y]");
856
857/* __eq__() */
858
859PyDoc_STRVAR(odict_eq__doc__,
860"od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive \n\
861 while comparison to a regular mapping is order-insensitive.\n\
862 ");
863
864/* forward */
865static PyObject * odict_richcompare(PyObject *v, PyObject *w, int op);
866
867static PyObject *
868odict_eq(PyObject *a, PyObject *b)
869{
870 return odict_richcompare(a, b, Py_EQ);
871}
872
873/* __init__() */
874
875PyDoc_STRVAR(odict_init__doc__,
876"Initialize an ordered dictionary. The signature is the same as\n\
877 regular dictionaries, but keyword arguments are not recommended because\n\
878 their insertion order is arbitrary.\n\
879\n\
880 ");
881
882/* forward */
883static int odict_init(PyObject *self, PyObject *args, PyObject *kwds);
884
885/* __iter__() */
886
887PyDoc_STRVAR(odict_iter__doc__, "od.__iter__() <==> iter(od)");
888
889static PyObject * odict_iter(PyODictObject *self); /* forward */
890
891/* __ne__() */
892
893/* Mapping.__ne__() does not have a docstring. */
894PyDoc_STRVAR(odict_ne__doc__, "");
895
896static PyObject *
897odict_ne(PyObject *a, PyObject *b)
898{
899 return odict_richcompare(a, b, Py_NE);
900}
901
902/* __repr__() */
903
904PyDoc_STRVAR(odict_repr__doc__, "od.__repr__() <==> repr(od)");
905
906static PyObject * odict_repr(PyODictObject *self); /* forward */
907
908/* __setitem__() */
909
910PyDoc_STRVAR(odict_setitem__doc__, "od.__setitem__(i, y) <==> od[i]=y");
911
912/* fromkeys() */
913
914PyDoc_STRVAR(odict_fromkeys__doc__,
915"OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.\n\
916 If not specified, the value defaults to None.\n\
917\n\
918 ");
919
920static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -0600921odict_fromkeys(PyObject *cls, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -0600922{
Eric Snowac02ef32015-06-02 20:42:14 -0600923 static char *kwlist[] = {"iterable", "value", 0};
Eric Snow96c6af92015-05-29 22:21:39 -0600924 PyObject *seq;
925 PyObject *value = Py_None;
Eric Snowac02ef32015-06-02 20:42:14 -0600926
927 /* both borrowed */
928 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:fromkeys", kwlist,
929 &seq, &value)) {
Eric Snow96c6af92015-05-29 22:21:39 -0600930 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -0600931 }
Eric Snow96c6af92015-05-29 22:21:39 -0600932 return _PyDict_FromKeys(cls, seq, value);
933}
934
935/* __sizeof__() */
936
937/* OrderedDict.__sizeof__() does not have a docstring. */
938PyDoc_STRVAR(odict_sizeof__doc__, "");
939
940static PyObject *
941odict_sizeof(PyODictObject *od)
942{
943 PyObject *pylong;
Eric Snowc5e59602015-05-30 11:28:56 -0600944 Py_ssize_t res, temp;
Eric Snow96c6af92015-05-29 22:21:39 -0600945
946 pylong = _PyDict_SizeOf((PyDictObject *)od);
947 if (pylong == NULL)
948 return NULL;
949 res = PyLong_AsSsize_t(pylong);
950 Py_DECREF(pylong);
951 if (res == -1 && PyErr_Occurred())
952 return NULL;
953
954 res += sizeof(PyODictObject) - sizeof(PyDictObject);
955
956 /* instance dict */
957 pylong = _PyDict_SizeOf((PyDictObject *)od->od_inst_dict);
958 if (pylong == NULL)
959 return NULL;
Eric Snowc5e59602015-05-30 11:28:56 -0600960 temp = PyLong_AsSsize_t(pylong);
Eric Snow96c6af92015-05-29 22:21:39 -0600961 Py_DECREF(pylong);
Eric Snowc5e59602015-05-30 11:28:56 -0600962 if (temp == -1 && PyErr_Occurred())
Eric Snow96c6af92015-05-29 22:21:39 -0600963 return NULL;
Eric Snowc5e59602015-05-30 11:28:56 -0600964 res += temp;
Eric Snow96c6af92015-05-29 22:21:39 -0600965
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300966 res += sizeof(_ODictNode *) * _odict_FAST_SIZE(od); /* od_fast_nodes */
Eric Snow96c6af92015-05-29 22:21:39 -0600967 if (!_odict_EMPTY(od)) {
968 res += sizeof(_ODictNode) * PyODict_SIZE(od); /* linked-list */
969 }
970 return PyLong_FromSsize_t(res);
971}
972
973/* __reduce__() */
974
975PyDoc_STRVAR(odict_reduce__doc__, "Return state information for pickling");
976
977static PyObject *
978odict_reduce(register PyODictObject *od)
979{
980 _Py_IDENTIFIER(__dict__);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300981 _Py_IDENTIFIER(items);
Serhiy Storchaka4575beb2015-10-22 20:18:24 +0300982 PyObject *dict = NULL, *result = NULL;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300983 PyObject *items_iter, *items, *args = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -0600984
985 /* capture any instance state */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300986 dict = _PyObject_GetAttrId((PyObject *)od, &PyId___dict__);
987 if (dict == NULL)
Eric Snowc5e59602015-05-30 11:28:56 -0600988 goto Done;
989 else {
Eric Snow96c6af92015-05-29 22:21:39 -0600990 /* od.__dict__ isn't necessarily a dict... */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300991 Py_ssize_t dict_len = PyObject_Length(dict);
992 if (dict_len == -1)
Eric Snow96c6af92015-05-29 22:21:39 -0600993 goto Done;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300994 if (!dict_len) {
995 /* nothing to pickle in od.__dict__ */
996 Py_CLEAR(dict);
Eric Snow96c6af92015-05-29 22:21:39 -0600997 }
998 }
999
1000 /* build the result */
Eric Snow96c6af92015-05-29 22:21:39 -06001001 args = PyTuple_New(0);
1002 if (args == NULL)
1003 goto Done;
1004
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001005 items = _PyObject_CallMethodIdObjArgs((PyObject *)od, &PyId_items, NULL);
Eric Snow96c6af92015-05-29 22:21:39 -06001006 if (items == NULL)
1007 goto Done;
1008
1009 items_iter = PyObject_GetIter(items);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001010 Py_DECREF(items);
Eric Snow96c6af92015-05-29 22:21:39 -06001011 if (items_iter == NULL)
1012 goto Done;
1013
Serhiy Storchaka4575beb2015-10-22 20:18:24 +03001014 result = PyTuple_Pack(5, Py_TYPE(od), args, dict ? dict : Py_None, Py_None, items_iter);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001015 Py_DECREF(items_iter);
Eric Snow96c6af92015-05-29 22:21:39 -06001016
1017Done:
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001018 Py_XDECREF(dict);
Eric Snow96c6af92015-05-29 22:21:39 -06001019 Py_XDECREF(args);
Eric Snow96c6af92015-05-29 22:21:39 -06001020
1021 return result;
1022}
1023
1024/* setdefault() */
1025
1026PyDoc_STRVAR(odict_setdefault__doc__,
1027 "od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od");
1028
1029/* Skips __missing__() calls. */
1030static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001031odict_setdefault(register PyODictObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001032{
Eric Snowac02ef32015-06-02 20:42:14 -06001033 static char *kwlist[] = {"key", "default", 0};
Eric Snow96c6af92015-05-29 22:21:39 -06001034 PyObject *key, *result = NULL;
1035 PyObject *failobj = Py_None;
1036
1037 /* both borrowed */
Eric Snowac02ef32015-06-02 20:42:14 -06001038 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:setdefault", kwlist,
1039 &key, &failobj)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001040 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001041 }
Eric Snow96c6af92015-05-29 22:21:39 -06001042
1043 if (PyODict_CheckExact(od)) {
Eric Snowd1719752015-06-01 23:12:13 -06001044 result = PyODict_GetItemWithError(od, key); /* borrowed */
1045 if (result == NULL) {
1046 if (PyErr_Occurred())
1047 return NULL;
1048 assert(_odict_find_node(od, key) == NULL);
1049 if (PyODict_SetItem((PyObject *)od, key, failobj) >= 0) {
Eric Snow96c6af92015-05-29 22:21:39 -06001050 result = failobj;
1051 Py_INCREF(failobj);
1052 }
1053 }
1054 else {
Eric Snowd1719752015-06-01 23:12:13 -06001055 Py_INCREF(result);
Eric Snow96c6af92015-05-29 22:21:39 -06001056 }
1057 }
1058 else {
1059 int exists = PySequence_Contains((PyObject *)od, key);
1060 if (exists < 0) {
Eric Snowd1719752015-06-01 23:12:13 -06001061 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001062 }
1063 else if (exists) {
1064 result = PyObject_GetItem((PyObject *)od, key);
1065 }
1066 else if (PyObject_SetItem((PyObject *)od, key, failobj) >= 0) {
1067 result = failobj;
1068 Py_INCREF(failobj);
1069 }
1070 }
1071
Eric Snow96c6af92015-05-29 22:21:39 -06001072 return result;
1073}
1074
1075/* pop() */
1076
1077PyDoc_STRVAR(odict_pop__doc__,
1078"od.pop(k[,d]) -> v, remove specified key and return the corresponding\n\
1079 value. If key is not found, d is returned if given, otherwise KeyError\n\
1080 is raised.\n\
1081\n\
1082 ");
1083
1084/* forward */
1085static PyObject * _odict_popkey(PyObject *, PyObject *, PyObject *);
1086
1087/* Skips __missing__() calls. */
1088static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001089odict_pop(PyObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001090{
Eric Snowac02ef32015-06-02 20:42:14 -06001091 static char *kwlist[] = {"key", "default", 0};
Eric Snow96c6af92015-05-29 22:21:39 -06001092 PyObject *key, *failobj = NULL;
1093
Eric Snowac02ef32015-06-02 20:42:14 -06001094 /* borrowed */
1095 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:pop", kwlist,
1096 &key, &failobj)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001097 return NULL;
1098 }
1099
1100 return _odict_popkey(od, key, failobj);
1101}
1102
1103static PyObject *
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001104_odict_popkey_hash(PyObject *od, PyObject *key, PyObject *failobj,
1105 Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -06001106{
1107 _ODictNode *node;
1108 PyObject *value = NULL;
1109
Eric Snow96c6af92015-05-29 22:21:39 -06001110 /* Pop the node first to avoid a possible dict resize (due to
1111 eval loop reentrancy) and complications due to hash collision
1112 resolution. */
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001113 node = _odict_find_node_hash((PyODictObject *)od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001114 if (node == NULL) {
1115 if (PyErr_Occurred())
Eric Snowd1719752015-06-01 23:12:13 -06001116 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001117 }
1118 else {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001119 int res = _odict_clear_node((PyODictObject *)od, node, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001120 if (res < 0) {
Eric Snowd1719752015-06-01 23:12:13 -06001121 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001122 }
1123 }
1124
1125 /* Now delete the value from the dict. */
1126 if (PyODict_CheckExact(od)) {
1127 if (node != NULL) {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001128 value = _PyDict_GetItem_KnownHash(od, key, hash); /* borrowed */
1129 if (value != NULL) {
1130 Py_INCREF(value);
1131 if (_PyDict_DelItem_KnownHash(od, key, hash) < 0) {
1132 Py_DECREF(value);
1133 return NULL;
1134 }
1135 }
Eric Snow96c6af92015-05-29 22:21:39 -06001136 }
1137 }
1138 else {
1139 int exists = PySequence_Contains(od, key);
1140 if (exists < 0)
Eric Snowd1719752015-06-01 23:12:13 -06001141 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001142 if (exists) {
1143 value = PyObject_GetItem(od, key);
1144 if (value != NULL) {
1145 if (PyObject_DelItem(od, key) == -1) {
Eric Snowe3dfa9e2015-05-30 12:51:15 -06001146 Py_CLEAR(value);
Eric Snow96c6af92015-05-29 22:21:39 -06001147 }
1148 }
1149 }
1150 }
1151
1152 /* Apply the fallback value, if necessary. */
1153 if (value == NULL && !PyErr_Occurred()) {
1154 if (failobj) {
1155 value = failobj;
1156 Py_INCREF(failobj);
1157 }
1158 else {
1159 PyErr_SetObject(PyExc_KeyError, key);
1160 }
1161 }
1162
Eric Snow96c6af92015-05-29 22:21:39 -06001163 return value;
1164}
1165
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001166static PyObject *
1167_odict_popkey(PyObject *od, PyObject *key, PyObject *failobj)
1168{
1169 Py_hash_t hash = PyObject_Hash(key);
1170 if (hash == -1)
1171 return NULL;
1172
1173 return _odict_popkey_hash(od, key, failobj, hash);
1174}
1175
Eric Snow96c6af92015-05-29 22:21:39 -06001176/* popitem() */
1177
1178PyDoc_STRVAR(odict_popitem__doc__,
1179"od.popitem() -> (k, v), return and remove a (key, value) pair.\n\
1180 Pairs are returned in LIFO order if last is true or FIFO order if false.\n\
1181\n\
1182 ");
1183
1184static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001185odict_popitem(PyObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001186{
Eric Snowac02ef32015-06-02 20:42:14 -06001187 static char *kwlist[] = {"last", 0};
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001188 PyObject *key, *value, *item = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001189 _ODictNode *node;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001190 int last = 1;
Eric Snow96c6af92015-05-29 22:21:39 -06001191
1192 /* pull the item */
1193
Eric Snowac02ef32015-06-02 20:42:14 -06001194 /* borrowed */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001195 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|p:popitem", kwlist,
Eric Snowac02ef32015-06-02 20:42:14 -06001196 &last)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001197 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001198 }
Eric Snow96c6af92015-05-29 22:21:39 -06001199
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001200 if (_odict_EMPTY(od)) {
1201 PyErr_SetString(PyExc_KeyError, "dictionary is empty");
1202 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001203 }
Eric Snow96c6af92015-05-29 22:21:39 -06001204
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001205 node = last ? _odict_LAST(od) : _odict_FIRST(od);
Eric Snow96c6af92015-05-29 22:21:39 -06001206 key = _odictnode_KEY(node);
Eric Snowd1719752015-06-01 23:12:13 -06001207 Py_INCREF(key);
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001208 value = _odict_popkey_hash(od, key, NULL, _odictnode_HASH(node));
Eric Snow96c6af92015-05-29 22:21:39 -06001209 if (value == NULL)
1210 return NULL;
1211 item = PyTuple_Pack(2, key, value);
Eric Snowd1719752015-06-01 23:12:13 -06001212 Py_DECREF(key);
Eric Snow96c6af92015-05-29 22:21:39 -06001213 Py_DECREF(value);
1214 return item;
1215}
1216
1217/* keys() */
1218
1219/* MutableMapping.keys() does not have a docstring. */
1220PyDoc_STRVAR(odict_keys__doc__, "");
1221
1222static PyObject * odictkeys_new(PyObject *od); /* forward */
1223
1224/* values() */
1225
1226/* MutableMapping.values() does not have a docstring. */
1227PyDoc_STRVAR(odict_values__doc__, "");
1228
1229static PyObject * odictvalues_new(PyObject *od); /* forward */
1230
1231/* items() */
1232
1233/* MutableMapping.items() does not have a docstring. */
1234PyDoc_STRVAR(odict_items__doc__, "");
1235
1236static PyObject * odictitems_new(PyObject *od); /* forward */
1237
1238/* update() */
1239
1240/* MutableMapping.update() does not have a docstring. */
1241PyDoc_STRVAR(odict_update__doc__, "");
1242
1243/* forward */
1244static PyObject * mutablemapping_update(PyObject *, PyObject *, PyObject *);
1245
1246#define odict_update mutablemapping_update
1247
1248/* clear() */
1249
1250PyDoc_STRVAR(odict_clear__doc__,
1251 "od.clear() -> None. Remove all items from od.");
1252
1253static PyObject *
1254odict_clear(register PyODictObject *od)
1255{
1256 PyDict_Clear((PyObject *)od);
1257 _odict_clear_nodes(od);
1258 _odict_FIRST(od) = NULL;
1259 _odict_LAST(od) = NULL;
1260 if (_odict_resize(od) < 0)
1261 return NULL;
1262 Py_RETURN_NONE;
1263}
1264
1265/* copy() */
1266
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001267/* forward */
1268static int _PyODict_SetItem_KnownHash(PyObject *, PyObject *, PyObject *,
1269 Py_hash_t);
1270
Eric Snow96c6af92015-05-29 22:21:39 -06001271PyDoc_STRVAR(odict_copy__doc__, "od.copy() -> a shallow copy of od");
1272
1273static PyObject *
1274odict_copy(register PyODictObject *od)
1275{
1276 _ODictNode *node;
1277 PyObject *od_copy;
1278
1279 if (PyODict_CheckExact(od))
1280 od_copy = PyODict_New();
1281 else
1282 od_copy = PyObject_CallFunctionObjArgs((PyObject *)Py_TYPE(od), NULL);
1283 if (od_copy == NULL)
1284 return NULL;
1285
1286 if (PyODict_CheckExact(od)) {
1287 _odict_FOREACH(od, node) {
Eric Snowa762af72015-06-01 22:59:08 -06001288 PyObject *key = _odictnode_KEY(node);
1289 PyObject *value = _odictnode_VALUE(node, od);
1290 if (value == NULL) {
1291 if (!PyErr_Occurred())
1292 PyErr_SetObject(PyExc_KeyError, key);
1293 goto fail;
1294 }
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001295 if (_PyODict_SetItem_KnownHash((PyObject *)od_copy, key, value,
1296 _odictnode_HASH(node)) != 0)
Eric Snow96c6af92015-05-29 22:21:39 -06001297 goto fail;
1298 }
1299 }
1300 else {
1301 _odict_FOREACH(od, node) {
1302 int res;
1303 PyObject *value = PyObject_GetItem((PyObject *)od,
1304 _odictnode_KEY(node));
1305 if (value == NULL)
1306 goto fail;
1307 res = PyObject_SetItem((PyObject *)od_copy,
1308 _odictnode_KEY(node), value);
1309 Py_DECREF(value);
1310 if (res != 0)
1311 goto fail;
1312 }
1313 }
1314 return od_copy;
1315
1316fail:
1317 Py_DECREF(od_copy);
1318 return NULL;
1319}
1320
1321/* __reversed__() */
1322
1323PyDoc_STRVAR(odict_reversed__doc__, "od.__reversed__() <==> reversed(od)");
1324
1325#define _odict_ITER_REVERSED 1
1326#define _odict_ITER_KEYS 2
1327#define _odict_ITER_VALUES 4
1328
1329/* forward */
1330static PyObject * odictiter_new(PyODictObject *, int);
1331
1332static PyObject *
1333odict_reversed(PyODictObject *od)
1334{
Eric Snow96c6af92015-05-29 22:21:39 -06001335 return odictiter_new(od, _odict_ITER_KEYS|_odict_ITER_REVERSED);
1336}
1337
1338/* move_to_end() */
1339
1340PyDoc_STRVAR(odict_move_to_end__doc__,
1341"Move an existing element to the end (or beginning if last==False).\n\
1342\n\
1343 Raises KeyError if the element does not exist.\n\
1344 When last=True, acts like a fast version of self[key]=self.pop(key).\n\
1345\n\
1346 ");
1347
1348static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001349odict_move_to_end(PyODictObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001350{
Eric Snowac02ef32015-06-02 20:42:14 -06001351 static char *kwlist[] = {"key", "last", 0};
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001352 PyObject *key;
1353 int last = 1;
1354 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001355
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001356 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|p:move_to_end", kwlist,
Eric Snowac02ef32015-06-02 20:42:14 -06001357 &key, &last)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001358 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001359 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001360
Eric Snow96c6af92015-05-29 22:21:39 -06001361 if (_odict_EMPTY(od)) {
1362 PyErr_SetObject(PyExc_KeyError, key);
Eric Snow96c6af92015-05-29 22:21:39 -06001363 return NULL;
1364 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001365 node = last ? _odict_LAST(od) : _odict_FIRST(od);
1366 if (key != _odictnode_KEY(node)) {
1367 node = _odict_find_node(od, key);
1368 if (node == NULL) {
1369 if (!PyErr_Occurred())
1370 PyErr_SetObject(PyExc_KeyError, key);
Eric Snowc5e59602015-05-30 11:28:56 -06001371 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001372 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001373 if (last) {
1374 /* Only move if not already the last one. */
1375 if (node != _odict_LAST(od)) {
1376 _odict_remove_node(od, node);
Eric Snow96c6af92015-05-29 22:21:39 -06001377 _odict_add_tail(od, node);
1378 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001379 }
1380 else {
1381 /* Only move if not already the first one. */
1382 if (node != _odict_FIRST(od)) {
1383 _odict_remove_node(od, node);
1384 _odict_add_head(od, node);
Eric Snow96c6af92015-05-29 22:21:39 -06001385 }
1386 }
1387 }
Eric Snow96c6af92015-05-29 22:21:39 -06001388 Py_RETURN_NONE;
1389}
1390
1391
1392/* tp_methods */
1393
1394static PyMethodDef odict_methods[] = {
1395
1396 /* explicitly defined so we can align docstrings with
1397 * collections.OrderedDict */
1398 {"__delitem__", (PyCFunction)odict_mp_ass_sub, METH_NOARGS,
1399 odict_delitem__doc__},
1400 {"__eq__", (PyCFunction)odict_eq, METH_NOARGS,
1401 odict_eq__doc__},
1402 {"__init__", (PyCFunction)odict_init, METH_NOARGS,
1403 odict_init__doc__},
1404 {"__iter__", (PyCFunction)odict_iter, METH_NOARGS,
1405 odict_iter__doc__},
1406 {"__ne__", (PyCFunction)odict_ne, METH_NOARGS,
1407 odict_ne__doc__},
1408 {"__repr__", (PyCFunction)odict_repr, METH_NOARGS,
1409 odict_repr__doc__},
1410 {"__setitem__", (PyCFunction)odict_mp_ass_sub, METH_NOARGS,
1411 odict_setitem__doc__},
Eric Snowac02ef32015-06-02 20:42:14 -06001412 {"fromkeys", (PyCFunction)odict_fromkeys,
1413 METH_VARARGS | METH_KEYWORDS | METH_CLASS, odict_fromkeys__doc__},
Eric Snow96c6af92015-05-29 22:21:39 -06001414
1415 /* overridden dict methods */
1416 {"__sizeof__", (PyCFunction)odict_sizeof, METH_NOARGS,
1417 odict_sizeof__doc__},
1418 {"__reduce__", (PyCFunction)odict_reduce, METH_NOARGS,
1419 odict_reduce__doc__},
Eric Snowac02ef32015-06-02 20:42:14 -06001420 {"setdefault", (PyCFunction)odict_setdefault,
1421 METH_VARARGS | METH_KEYWORDS, odict_setdefault__doc__},
1422 {"pop", (PyCFunction)odict_pop,
1423 METH_VARARGS | METH_KEYWORDS, odict_pop__doc__},
1424 {"popitem", (PyCFunction)odict_popitem,
1425 METH_VARARGS | METH_KEYWORDS, odict_popitem__doc__},
Eric Snow96c6af92015-05-29 22:21:39 -06001426 {"keys", (PyCFunction)odictkeys_new, METH_NOARGS,
1427 odict_keys__doc__},
1428 {"values", (PyCFunction)odictvalues_new, METH_NOARGS,
1429 odict_values__doc__},
1430 {"items", (PyCFunction)odictitems_new, METH_NOARGS,
1431 odict_items__doc__},
1432 {"update", (PyCFunction)odict_update, METH_VARARGS | METH_KEYWORDS,
1433 odict_update__doc__},
1434 {"clear", (PyCFunction)odict_clear, METH_NOARGS,
1435 odict_clear__doc__},
1436 {"copy", (PyCFunction)odict_copy, METH_NOARGS,
1437 odict_copy__doc__},
1438
1439 /* new methods */
1440 {"__reversed__", (PyCFunction)odict_reversed, METH_NOARGS,
1441 odict_reversed__doc__},
Eric Snowac02ef32015-06-02 20:42:14 -06001442 {"move_to_end", (PyCFunction)odict_move_to_end,
1443 METH_VARARGS | METH_KEYWORDS, odict_move_to_end__doc__},
Eric Snow96c6af92015-05-29 22:21:39 -06001444
1445 {NULL, NULL} /* sentinel */
1446};
1447
1448
1449/* ----------------------------------------------
1450 * OrderedDict members
1451 */
1452
1453/* tp_members */
1454
1455static PyMemberDef odict_members[] = {
1456 {"__dict__", T_OBJECT, offsetof(PyODictObject, od_inst_dict), READONLY},
1457 {0}
1458};
1459
1460
1461/* ----------------------------------------------
1462 * OrderedDict type slot methods
1463 */
1464
1465/* tp_dealloc */
1466
1467static void
1468odict_dealloc(PyODictObject *self)
1469{
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001470 PyThreadState *tstate = PyThreadState_GET();
1471
Eric Snow96c6af92015-05-29 22:21:39 -06001472 PyObject_GC_UnTrack(self);
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001473 Py_TRASHCAN_SAFE_BEGIN(self)
1474
Eric Snow96c6af92015-05-29 22:21:39 -06001475 Py_XDECREF(self->od_inst_dict);
1476 if (self->od_weakreflist != NULL)
1477 PyObject_ClearWeakRefs((PyObject *)self);
1478
1479 _odict_clear_nodes(self);
Eric Snow96c6af92015-05-29 22:21:39 -06001480
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001481 /* Call the base tp_dealloc(). Since it too uses the trashcan mechanism,
1482 * temporarily decrement trash_delete_nesting to prevent triggering it
1483 * and putting the partially deallocated object on the trashcan's
1484 * to-be-deleted-later list.
1485 */
1486 --tstate->trash_delete_nesting;
1487 assert(_tstate->trash_delete_nesting < PyTrash_UNWIND_LEVEL);
Eric Snow96c6af92015-05-29 22:21:39 -06001488 PyDict_Type.tp_dealloc((PyObject *)self);
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001489 ++tstate->trash_delete_nesting;
1490
1491 Py_TRASHCAN_SAFE_END(self)
Eric Snow96c6af92015-05-29 22:21:39 -06001492};
1493
1494/* tp_repr */
1495
1496static PyObject *
1497odict_repr(PyODictObject *self)
1498{
1499 int i;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001500 _Py_IDENTIFIER(items);
Serhiy Storchaka4575beb2015-10-22 20:18:24 +03001501 PyObject *pieces = NULL, *result = NULL;
1502 const char *classname;
1503
1504 classname = strrchr(Py_TYPE(self)->tp_name, '.');
1505 if (classname == NULL)
1506 classname = Py_TYPE(self)->tp_name;
1507 else
1508 classname++;
1509
1510 if (PyODict_SIZE(self) == 0)
1511 return PyUnicode_FromFormat("%s()", classname);
Eric Snow96c6af92015-05-29 22:21:39 -06001512
1513 i = Py_ReprEnter((PyObject *)self);
1514 if (i != 0) {
1515 return i > 0 ? PyUnicode_FromString("...") : NULL;
1516 }
1517
Eric Snow96c6af92015-05-29 22:21:39 -06001518 if (PyODict_CheckExact(self)) {
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001519 Py_ssize_t count = 0;
Eric Snowa762af72015-06-01 22:59:08 -06001520 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001521 pieces = PyList_New(PyODict_SIZE(self));
1522 if (pieces == NULL)
1523 goto Done;
1524
1525 _odict_FOREACH(self, node) {
Eric Snowa762af72015-06-01 22:59:08 -06001526 PyObject *pair;
1527 PyObject *key = _odictnode_KEY(node);
1528 PyObject *value = _odictnode_VALUE(node, self);
1529 if (value == NULL) {
1530 if (!PyErr_Occurred())
1531 PyErr_SetObject(PyExc_KeyError, key);
Eric Snowdb4061c2015-06-03 11:09:48 -06001532 goto Done;
Eric Snowa762af72015-06-01 22:59:08 -06001533 }
1534 pair = PyTuple_Pack(2, key, value);
Eric Snow96c6af92015-05-29 22:21:39 -06001535 if (pair == NULL)
1536 goto Done;
1537
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001538 if (count < PyList_GET_SIZE(pieces))
1539 PyList_SET_ITEM(pieces, count, pair); /* steals reference */
1540 else {
1541 if (PyList_Append(pieces, pair) < 0) {
1542 Py_DECREF(pair);
1543 goto Done;
1544 }
1545 Py_DECREF(pair);
1546 }
1547 count++;
Eric Snow96c6af92015-05-29 22:21:39 -06001548 }
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001549 if (count < PyList_GET_SIZE(pieces))
1550 PyList_GET_SIZE(pieces) = count;
Eric Snow96c6af92015-05-29 22:21:39 -06001551 }
1552 else {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001553 PyObject *items = _PyObject_CallMethodIdObjArgs((PyObject *)self,
1554 &PyId_items, NULL);
Eric Snow96c6af92015-05-29 22:21:39 -06001555 if (items == NULL)
1556 goto Done;
1557 pieces = PySequence_List(items);
1558 Py_DECREF(items);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001559 if (pieces == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -06001560 goto Done;
1561 }
1562
Serhiy Storchaka4575beb2015-10-22 20:18:24 +03001563 result = PyUnicode_FromFormat("%s(%R)", classname, pieces);
Eric Snow96c6af92015-05-29 22:21:39 -06001564
Eric Snow96c6af92015-05-29 22:21:39 -06001565Done:
1566 Py_XDECREF(pieces);
Eric Snow96c6af92015-05-29 22:21:39 -06001567 Py_ReprLeave((PyObject *)self);
1568 return result;
1569};
1570
1571/* tp_doc */
1572
1573PyDoc_STRVAR(odict_doc,
1574 "Dictionary that remembers insertion order");
1575
1576/* tp_traverse */
1577
1578static int
1579odict_traverse(PyODictObject *od, visitproc visit, void *arg)
1580{
1581 Py_VISIT(od->od_inst_dict);
1582 Py_VISIT(od->od_weakreflist);
1583 return PyDict_Type.tp_traverse((PyObject *)od, visit, arg);
1584}
1585
1586/* tp_clear */
1587
1588static int
1589odict_tp_clear(PyODictObject *od)
1590{
1591 PyObject *res;
1592 Py_CLEAR(od->od_inst_dict);
1593 Py_CLEAR(od->od_weakreflist);
1594 res = odict_clear(od);
1595 if (res == NULL)
1596 return -1;
1597 Py_DECREF(res);
1598 return 0;
1599}
1600
1601/* tp_richcompare */
1602
1603static PyObject *
1604odict_richcompare(PyObject *v, PyObject *w, int op)
1605{
1606 if (!PyODict_Check(v) || !PyDict_Check(w)) {
1607 Py_RETURN_NOTIMPLEMENTED;
1608 }
1609
1610 if (op == Py_EQ || op == Py_NE) {
1611 PyObject *res, *cmp;
1612 int eq;
1613
1614 cmp = PyDict_Type.tp_richcompare(v, w, op);
1615 if (cmp == NULL)
1616 return NULL;
1617 if (!PyODict_Check(w))
1618 return cmp;
1619 if (op == Py_EQ && cmp == Py_False)
1620 return cmp;
1621 if (op == Py_NE && cmp == Py_True)
1622 return cmp;
1623 Py_DECREF(cmp);
1624
1625 /* Try comparing odict keys. */
1626 eq = _odict_keys_equal((PyODictObject *)v, (PyODictObject *)w);
1627 if (eq < 0)
1628 return NULL;
1629
1630 res = (eq == (op == Py_EQ)) ? Py_True : Py_False;
1631 Py_INCREF(res);
1632 return res;
1633 } else {
1634 Py_RETURN_NOTIMPLEMENTED;
1635 }
1636};
1637
1638/* tp_iter */
1639
1640static PyObject *
1641odict_iter(PyODictObject *od)
1642{
1643 return odictiter_new(od, _odict_ITER_KEYS);
1644};
1645
1646/* tp_init */
1647
1648static int
1649odict_init(PyObject *self, PyObject *args, PyObject *kwds)
1650{
1651 PyObject *res;
1652 Py_ssize_t len = PyObject_Length(args);
1653
1654 if (len == -1)
1655 return -1;
1656 if (len > 1) {
1657 char *msg = "expected at most 1 arguments, got %d";
1658 PyErr_Format(PyExc_TypeError, msg, len);
1659 return -1;
1660 }
1661
1662 /* __init__() triggering update() is just the way things are! */
1663 res = odict_update(self, args, kwds);
1664 if (res == NULL) {
1665 return -1;
1666 } else {
1667 Py_DECREF(res);
1668 return 0;
1669 }
1670};
1671
1672/* tp_new */
1673
1674static PyObject *
1675odict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1676{
Victor Stinnerca30b022015-09-03 17:50:04 +02001677 PyObject *dict;
1678 PyODictObject *od;
1679
1680 dict = PyDict_New();
1681 if (dict == NULL)
1682 return NULL;
1683
1684 od = (PyODictObject *)PyDict_Type.tp_new(type, args, kwds);
1685 if (od == NULL) {
1686 Py_DECREF(dict);
1687 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001688 }
Victor Stinnerca30b022015-09-03 17:50:04 +02001689
1690 od->od_inst_dict = dict;
1691 /* type constructor fills the memory with zeros (see
1692 PyType_GenericAlloc()), there is no need to set them to zero again */
1693 if (_odict_resize(od) < 0) {
1694 Py_DECREF(od);
1695 return NULL;
1696 }
1697
1698 return (PyObject*)od;
Eric Snow96c6af92015-05-29 22:21:39 -06001699}
1700
1701/* PyODict_Type */
1702
1703PyTypeObject PyODict_Type = {
1704 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1705 "collections.OrderedDict", /* tp_name */
1706 sizeof(PyODictObject), /* tp_basicsize */
1707 0, /* tp_itemsize */
1708 (destructor)odict_dealloc, /* tp_dealloc */
1709 0, /* tp_print */
1710 0, /* tp_getattr */
1711 0, /* tp_setattr */
1712 0, /* tp_reserved */
1713 (reprfunc)odict_repr, /* tp_repr */
1714 0, /* tp_as_number */
1715 0, /* tp_as_sequence */
1716 &odict_as_mapping, /* tp_as_mapping */
1717 0, /* tp_hash */
1718 0, /* tp_call */
1719 0, /* tp_str */
1720 0, /* tp_getattro */
1721 0, /* tp_setattro */
1722 0, /* tp_as_buffer */
1723 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,/* tp_flags */
1724 odict_doc, /* tp_doc */
1725 (traverseproc)odict_traverse, /* tp_traverse */
1726 (inquiry)odict_tp_clear, /* tp_clear */
1727 (richcmpfunc)odict_richcompare, /* tp_richcompare */
1728 offsetof(PyODictObject, od_weakreflist), /* tp_weaklistoffset */
1729 (getiterfunc)odict_iter, /* tp_iter */
1730 0, /* tp_iternext */
1731 odict_methods, /* tp_methods */
1732 odict_members, /* tp_members */
1733 0, /* tp_getset */
1734 &PyDict_Type, /* tp_base */
1735 0, /* tp_dict */
1736 0, /* tp_descr_get */
1737 0, /* tp_descr_set */
1738 offsetof(PyODictObject, od_inst_dict), /* tp_dictoffset */
1739 (initproc)odict_init, /* tp_init */
1740 PyType_GenericAlloc, /* tp_alloc */
1741 (newfunc)odict_new, /* tp_new */
1742 0, /* tp_free */
1743};
1744
1745
1746/* ----------------------------------------------
1747 * the public OrderedDict API
1748 */
1749
1750PyObject *
1751PyODict_New(void) {
1752 return odict_new(&PyODict_Type, NULL, NULL);
1753};
1754
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001755static int
1756_PyODict_SetItem_KnownHash(PyObject *od, PyObject *key, PyObject *value,
1757 Py_hash_t hash)
1758{
1759 int res = _PyDict_SetItem_KnownHash(od, key, value, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001760 if (res == 0) {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001761 res = _odict_add_new_node((PyODictObject *)od, key, hash);
Serhiy Storchakad5f353e2015-11-06 11:07:11 +02001762 if (res < 0) {
1763 /* Revert setting the value on the dict */
1764 PyObject *exc, *val, *tb;
1765 PyErr_Fetch(&exc, &val, &tb);
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001766 (void) _PyDict_DelItem_KnownHash(od, key, hash);
Serhiy Storchakad5f353e2015-11-06 11:07:11 +02001767 _PyErr_ChainExceptions(exc, val, tb);
1768 }
Eric Snow96c6af92015-05-29 22:21:39 -06001769 }
1770 return res;
1771};
1772
1773int
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001774PyODict_SetItem(PyObject *od, PyObject *key, PyObject *value)
1775{
1776 Py_hash_t hash = PyObject_Hash(key);
1777 if (hash == -1)
1778 return -1;
1779 return _PyODict_SetItem_KnownHash(od, key, value, hash);
1780};
1781
1782int
1783PyODict_DelItem(PyObject *od, PyObject *key)
1784{
1785 int res;
1786 Py_hash_t hash = PyObject_Hash(key);
1787 if (hash == -1)
1788 return -1;
1789 res = _odict_clear_node((PyODictObject *)od, NULL, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001790 if (res < 0)
1791 return -1;
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001792 return _PyDict_DelItem_KnownHash(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001793};
1794
1795
1796/* -------------------------------------------
1797 * The OrderedDict views (keys/values/items)
1798 */
1799
1800typedef struct {
1801 PyObject_HEAD
1802 int kind;
1803 PyODictObject *di_odict;
Eric Snowb952ab42015-06-01 23:35:13 -06001804 Py_ssize_t di_size;
Eric Snow4fabf022015-06-04 00:09:56 -06001805 size_t di_state;
Eric Snow96c6af92015-05-29 22:21:39 -06001806 PyObject *di_current;
1807 PyObject *di_result; /* reusable result tuple for iteritems */
1808} odictiterobject;
1809
1810static void
1811odictiter_dealloc(odictiterobject *di)
1812{
1813 _PyObject_GC_UNTRACK(di);
Eric Snowa762af72015-06-01 22:59:08 -06001814 Py_XDECREF(di->di_odict);
Eric Snow96c6af92015-05-29 22:21:39 -06001815 Py_XDECREF(di->di_current);
1816 if (di->kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)) {
1817 Py_DECREF(di->di_result);
1818 }
1819 PyObject_GC_Del(di);
1820}
1821
1822static int
1823odictiter_traverse(odictiterobject *di, visitproc visit, void *arg)
1824{
1825 Py_VISIT(di->di_odict);
1826 Py_VISIT(di->di_current); /* A key could be any type, not just str. */
1827 Py_VISIT(di->di_result);
1828 return 0;
1829}
1830
Eric Snowa762af72015-06-01 22:59:08 -06001831/* In order to protect against modifications during iteration, we track
1832 * the current key instead of the current node. */
Eric Snow96c6af92015-05-29 22:21:39 -06001833static PyObject *
1834odictiter_nextkey(odictiterobject *di)
1835{
Eric Snowa762af72015-06-01 22:59:08 -06001836 PyObject *key = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001837 _ODictNode *node;
1838 int reversed = di->kind & _odict_ITER_REVERSED;
1839
Eric Snowa762af72015-06-01 22:59:08 -06001840 if (di->di_odict == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -06001841 return NULL;
Eric Snowa762af72015-06-01 22:59:08 -06001842 if (di->di_current == NULL)
1843 goto done; /* We're already done. */
1844
Eric Snowb952ab42015-06-01 23:35:13 -06001845 /* Check for unsupported changes. */
Eric Snow4fabf022015-06-04 00:09:56 -06001846 if (di->di_odict->od_state != di->di_state) {
1847 PyErr_SetString(PyExc_RuntimeError,
1848 "OrderedDict mutated during iteration");
1849 goto done;
1850 }
Eric Snowb952ab42015-06-01 23:35:13 -06001851 if (di->di_size != PyODict_SIZE(di->di_odict)) {
1852 PyErr_SetString(PyExc_RuntimeError,
1853 "OrderedDict changed size during iteration");
1854 di->di_size = -1; /* Make this state sticky */
1855 return NULL;
1856 }
1857
Eric Snowa762af72015-06-01 22:59:08 -06001858 /* Get the key. */
Eric Snow96c6af92015-05-29 22:21:39 -06001859 node = _odict_find_node(di->di_odict, di->di_current);
1860 if (node == NULL) {
Serhiy Storchakab45b7b22015-11-04 22:05:38 +02001861 if (!PyErr_Occurred())
1862 PyErr_SetObject(PyExc_KeyError, di->di_current);
Eric Snow96c6af92015-05-29 22:21:39 -06001863 /* Must have been deleted. */
Eric Snowe3dfa9e2015-05-30 12:51:15 -06001864 Py_CLEAR(di->di_current);
Eric Snow96c6af92015-05-29 22:21:39 -06001865 return NULL;
1866 }
1867 key = di->di_current;
1868
1869 /* Advance to the next key. */
1870 node = reversed ? _odictnode_PREV(node) : _odictnode_NEXT(node);
1871 if (node == NULL) {
1872 /* Reached the end. */
1873 di->di_current = NULL;
1874 }
1875 else {
1876 di->di_current = _odictnode_KEY(node);
1877 Py_INCREF(di->di_current);
1878 }
1879
1880 return key;
Eric Snowa762af72015-06-01 22:59:08 -06001881
1882done:
1883 Py_CLEAR(di->di_odict);
1884 return key;
Eric Snow96c6af92015-05-29 22:21:39 -06001885}
1886
1887static PyObject *
1888odictiter_iternext(odictiterobject *di)
1889{
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001890 PyObject *result, *value;
Eric Snow96c6af92015-05-29 22:21:39 -06001891 PyObject *key = odictiter_nextkey(di); /* new reference */
1892
1893 if (key == NULL)
1894 return NULL;
1895
1896 /* Handle the keys case. */
1897 if (! (di->kind & _odict_ITER_VALUES)) {
1898 return key;
1899 }
1900
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001901 value = PyODict_GetItem((PyObject *)di->di_odict, key); /* borrowed */
1902 if (value == NULL) {
1903 if (!PyErr_Occurred())
1904 PyErr_SetObject(PyExc_KeyError, key);
Eric Snow96c6af92015-05-29 22:21:39 -06001905 Py_DECREF(key);
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001906 goto done;
1907 }
1908 Py_INCREF(value);
1909
1910 /* Handle the values case. */
1911 if (!(di->kind & _odict_ITER_KEYS)) {
1912 Py_DECREF(key);
Eric Snow96c6af92015-05-29 22:21:39 -06001913 return value;
1914 }
Eric Snowa762af72015-06-01 22:59:08 -06001915
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001916 /* Handle the items case. */
1917 result = di->di_result;
1918
1919 if (Py_REFCNT(result) == 1) {
1920 /* not in use so we can reuse it
1921 * (the common case during iteration) */
1922 Py_INCREF(result);
1923 Py_DECREF(PyTuple_GET_ITEM(result, 0)); /* borrowed */
1924 Py_DECREF(PyTuple_GET_ITEM(result, 1)); /* borrowed */
1925 }
1926 else {
1927 result = PyTuple_New(2);
1928 if (result == NULL) {
1929 Py_DECREF(key);
1930 Py_DECREF(value);
1931 goto done;
1932 }
1933 }
1934
1935 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
1936 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
1937 return result;
1938
Eric Snowa762af72015-06-01 22:59:08 -06001939done:
1940 Py_CLEAR(di->di_current);
1941 Py_CLEAR(di->di_odict);
1942 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001943}
1944
1945/* No need for tp_clear because odictiterobject is not mutable. */
1946
1947PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
1948
1949static PyObject *
1950odictiter_reduce(odictiterobject *di)
1951{
Eric Snowc5e59602015-05-30 11:28:56 -06001952 PyObject *list, *iter;
Eric Snow96c6af92015-05-29 22:21:39 -06001953
1954 list = PyList_New(0);
1955 if (!list)
1956 return NULL;
1957
1958 /* iterate the temporary into a list */
1959 for(;;) {
1960 PyObject *element = odictiter_iternext(di);
1961 if (element) {
1962 if (PyList_Append(list, element)) {
1963 Py_DECREF(element);
1964 Py_DECREF(list);
1965 return NULL;
1966 }
1967 Py_DECREF(element);
1968 }
1969 else {
1970 /* done iterating? */
1971 break;
1972 }
1973 }
1974 if (PyErr_Occurred()) {
1975 Py_DECREF(list);
1976 return NULL;
1977 }
Eric Snowc5e59602015-05-30 11:28:56 -06001978 iter = _PyObject_GetBuiltin("iter");
1979 if (iter == NULL) {
1980 Py_DECREF(list);
1981 return NULL;
1982 }
1983 return Py_BuildValue("N(N)", iter, list);
Eric Snow96c6af92015-05-29 22:21:39 -06001984}
1985
1986static PyMethodDef odictiter_methods[] = {
1987 {"__reduce__", (PyCFunction)odictiter_reduce, METH_NOARGS, reduce_doc},
1988 {NULL, NULL} /* sentinel */
1989};
1990
1991PyTypeObject PyODictIter_Type = {
1992 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1993 "odict_iterator", /* tp_name */
1994 sizeof(odictiterobject), /* tp_basicsize */
1995 0, /* tp_itemsize */
1996 /* methods */
1997 (destructor)odictiter_dealloc, /* tp_dealloc */
1998 0, /* tp_print */
1999 0, /* tp_getattr */
2000 0, /* tp_setattr */
2001 0, /* tp_reserved */
2002 0, /* tp_repr */
2003 0, /* tp_as_number */
2004 0, /* tp_as_sequence */
2005 0, /* tp_as_mapping */
2006 0, /* tp_hash */
2007 0, /* tp_call */
2008 0, /* tp_str */
2009 PyObject_GenericGetAttr, /* tp_getattro */
2010 0, /* tp_setattro */
2011 0, /* tp_as_buffer */
2012 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2013 0, /* tp_doc */
2014 (traverseproc)odictiter_traverse, /* tp_traverse */
2015 0, /* tp_clear */
2016 0, /* tp_richcompare */
2017 0, /* tp_weaklistoffset */
2018 PyObject_SelfIter, /* tp_iter */
2019 (iternextfunc)odictiter_iternext, /* tp_iternext */
2020 odictiter_methods, /* tp_methods */
2021 0,
2022};
2023
2024static PyObject *
2025odictiter_new(PyODictObject *od, int kind)
2026{
2027 odictiterobject *di;
2028 _ODictNode *node;
2029 int reversed = kind & _odict_ITER_REVERSED;
2030
2031 di = PyObject_GC_New(odictiterobject, &PyODictIter_Type);
2032 if (di == NULL)
2033 return NULL;
2034
2035 if (kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)){
2036 di->di_result = PyTuple_Pack(2, Py_None, Py_None);
2037 if (di->di_result == NULL) {
2038 Py_DECREF(di);
2039 return NULL;
2040 }
2041 }
2042 else
2043 di->di_result = NULL;
2044
2045 di->kind = kind;
2046 node = reversed ? _odict_LAST(od) : _odict_FIRST(od);
2047 di->di_current = node ? _odictnode_KEY(node) : NULL;
2048 Py_XINCREF(di->di_current);
Eric Snowb952ab42015-06-01 23:35:13 -06002049 di->di_size = PyODict_SIZE(od);
Eric Snow4fabf022015-06-04 00:09:56 -06002050 di->di_state = od->od_state;
Eric Snow96c6af92015-05-29 22:21:39 -06002051 di->di_odict = od;
2052 Py_INCREF(od);
2053
2054 _PyObject_GC_TRACK(di);
2055 return (PyObject *)di;
2056}
2057
2058/* keys() */
2059
2060static PyObject *
2061odictkeys_iter(_PyDictViewObject *dv)
2062{
2063 if (dv->dv_dict == NULL) {
2064 Py_RETURN_NONE;
2065 }
2066 return odictiter_new((PyODictObject *)dv->dv_dict,
2067 _odict_ITER_KEYS);
2068}
2069
2070static PyObject *
2071odictkeys_reversed(_PyDictViewObject *dv)
2072{
2073 if (dv->dv_dict == NULL) {
2074 Py_RETURN_NONE;
2075 }
2076 return odictiter_new((PyODictObject *)dv->dv_dict,
2077 _odict_ITER_KEYS|_odict_ITER_REVERSED);
2078}
2079
2080static PyMethodDef odictkeys_methods[] = {
2081 {"__reversed__", (PyCFunction)odictkeys_reversed, METH_NOARGS, NULL},
2082 {NULL, NULL} /* sentinel */
2083};
2084
2085PyTypeObject PyODictKeys_Type = {
2086 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2087 "odict_keys", /* tp_name */
2088 0, /* tp_basicsize */
2089 0, /* tp_itemsize */
2090 0, /* tp_dealloc */
2091 0, /* tp_print */
2092 0, /* tp_getattr */
2093 0, /* tp_setattr */
2094 0, /* tp_reserved */
2095 0, /* tp_repr */
2096 0, /* tp_as_number */
2097 0, /* tp_as_sequence */
2098 0, /* tp_as_mapping */
2099 0, /* tp_hash */
2100 0, /* tp_call */
2101 0, /* tp_str */
2102 0, /* tp_getattro */
2103 0, /* tp_setattro */
2104 0, /* tp_as_buffer */
2105 0, /* tp_flags */
2106 0, /* tp_doc */
2107 0, /* tp_traverse */
2108 0, /* tp_clear */
2109 0, /* tp_richcompare */
2110 0, /* tp_weaklistoffset */
2111 (getiterfunc)odictkeys_iter, /* tp_iter */
2112 0, /* tp_iternext */
2113 odictkeys_methods, /* tp_methods */
2114 0, /* tp_members */
2115 0, /* tp_getset */
2116 &PyDictKeys_Type, /* tp_base */
2117};
2118
2119static PyObject *
2120odictkeys_new(PyObject *od)
2121{
2122 return _PyDictView_New(od, &PyODictKeys_Type);
2123}
2124
2125/* items() */
2126
2127static PyObject *
2128odictitems_iter(_PyDictViewObject *dv)
2129{
2130 if (dv->dv_dict == NULL) {
2131 Py_RETURN_NONE;
2132 }
2133 return odictiter_new((PyODictObject *)dv->dv_dict,
2134 _odict_ITER_KEYS|_odict_ITER_VALUES);
2135}
2136
2137static PyObject *
2138odictitems_reversed(_PyDictViewObject *dv)
2139{
2140 if (dv->dv_dict == NULL) {
2141 Py_RETURN_NONE;
2142 }
2143 return odictiter_new((PyODictObject *)dv->dv_dict,
2144 _odict_ITER_KEYS|_odict_ITER_VALUES|_odict_ITER_REVERSED);
2145}
2146
2147static PyMethodDef odictitems_methods[] = {
2148 {"__reversed__", (PyCFunction)odictitems_reversed, METH_NOARGS, NULL},
2149 {NULL, NULL} /* sentinel */
2150};
2151
2152PyTypeObject PyODictItems_Type = {
2153 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2154 "odict_items", /* tp_name */
2155 0, /* tp_basicsize */
2156 0, /* tp_itemsize */
2157 0, /* tp_dealloc */
2158 0, /* tp_print */
2159 0, /* tp_getattr */
2160 0, /* tp_setattr */
2161 0, /* tp_reserved */
2162 0, /* tp_repr */
2163 0, /* tp_as_number */
2164 0, /* tp_as_sequence */
2165 0, /* tp_as_mapping */
2166 0, /* tp_hash */
2167 0, /* tp_call */
2168 0, /* tp_str */
2169 0, /* tp_getattro */
2170 0, /* tp_setattro */
2171 0, /* tp_as_buffer */
2172 0, /* tp_flags */
2173 0, /* tp_doc */
2174 0, /* tp_traverse */
2175 0, /* tp_clear */
2176 0, /* tp_richcompare */
2177 0, /* tp_weaklistoffset */
2178 (getiterfunc)odictitems_iter, /* tp_iter */
2179 0, /* tp_iternext */
2180 odictitems_methods, /* tp_methods */
2181 0, /* tp_members */
2182 0, /* tp_getset */
2183 &PyDictItems_Type, /* tp_base */
2184};
2185
2186static PyObject *
2187odictitems_new(PyObject *od)
2188{
2189 return _PyDictView_New(od, &PyODictItems_Type);
2190}
2191
2192/* values() */
2193
2194static PyObject *
2195odictvalues_iter(_PyDictViewObject *dv)
2196{
2197 if (dv->dv_dict == NULL) {
2198 Py_RETURN_NONE;
2199 }
2200 return odictiter_new((PyODictObject *)dv->dv_dict,
2201 _odict_ITER_VALUES);
2202}
2203
2204static PyObject *
2205odictvalues_reversed(_PyDictViewObject *dv)
2206{
2207 if (dv->dv_dict == NULL) {
2208 Py_RETURN_NONE;
2209 }
2210 return odictiter_new((PyODictObject *)dv->dv_dict,
2211 _odict_ITER_VALUES|_odict_ITER_REVERSED);
2212}
2213
2214static PyMethodDef odictvalues_methods[] = {
2215 {"__reversed__", (PyCFunction)odictvalues_reversed, METH_NOARGS, NULL},
2216 {NULL, NULL} /* sentinel */
2217};
2218
2219PyTypeObject PyODictValues_Type = {
2220 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2221 "odict_values", /* tp_name */
2222 0, /* tp_basicsize */
2223 0, /* tp_itemsize */
2224 0, /* tp_dealloc */
2225 0, /* tp_print */
2226 0, /* tp_getattr */
2227 0, /* tp_setattr */
2228 0, /* tp_reserved */
2229 0, /* tp_repr */
2230 0, /* tp_as_number */
2231 0, /* tp_as_sequence */
2232 0, /* tp_as_mapping */
2233 0, /* tp_hash */
2234 0, /* tp_call */
2235 0, /* tp_str */
2236 0, /* tp_getattro */
2237 0, /* tp_setattro */
2238 0, /* tp_as_buffer */
2239 0, /* tp_flags */
2240 0, /* tp_doc */
2241 0, /* tp_traverse */
2242 0, /* tp_clear */
2243 0, /* tp_richcompare */
2244 0, /* tp_weaklistoffset */
2245 (getiterfunc)odictvalues_iter, /* tp_iter */
2246 0, /* tp_iternext */
2247 odictvalues_methods, /* tp_methods */
2248 0, /* tp_members */
2249 0, /* tp_getset */
2250 &PyDictValues_Type, /* tp_base */
2251};
2252
2253static PyObject *
2254odictvalues_new(PyObject *od)
2255{
2256 return _PyDictView_New(od, &PyODictValues_Type);
2257}
2258
2259
2260/* ----------------------------------------------
2261 MutableMappping implementations
2262
2263Mapping:
2264
2265============ ===========
2266method uses
2267============ ===========
2268__contains__ __getitem__
2269__eq__ items
2270__getitem__ +
2271__iter__ +
2272__len__ +
2273__ne__ __eq__
2274get __getitem__
2275items ItemsView
2276keys KeysView
2277values ValuesView
2278============ ===========
2279
2280ItemsView uses __len__, __iter__, and __getitem__.
2281KeysView uses __len__, __iter__, and __contains__.
2282ValuesView uses __len__, __iter__, and __getitem__.
2283
2284MutableMapping:
2285
2286============ ===========
2287method uses
2288============ ===========
2289__delitem__ +
2290__setitem__ +
2291clear popitem
2292pop __getitem__
2293 __delitem__
2294popitem __iter__
2295 _getitem__
2296 __delitem__
2297setdefault __getitem__
2298 __setitem__
2299update __setitem__
2300============ ===========
2301*/
2302
2303static int
2304mutablemapping_add_pairs(PyObject *self, PyObject *pairs)
2305{
2306 PyObject *pair, *iterator, *unexpected;
2307 int res = 0;
2308
2309 iterator = PyObject_GetIter(pairs);
2310 if (iterator == NULL)
2311 return -1;
2312 PyErr_Clear();
2313
2314 while ((pair = PyIter_Next(iterator)) != NULL) {
2315 /* could be more efficient (see UNPACK_SEQUENCE in ceval.c) */
Eric Snowc5e59602015-05-30 11:28:56 -06002316 PyObject *key = NULL, *value = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06002317 PyObject *pair_iterator = PyObject_GetIter(pair);
Eric Snowc5e59602015-05-30 11:28:56 -06002318 if (pair_iterator == NULL)
2319 goto Done;
Eric Snow96c6af92015-05-29 22:21:39 -06002320
2321 key = PyIter_Next(pair_iterator);
2322 if (key == NULL) {
2323 if (!PyErr_Occurred())
2324 PyErr_SetString(PyExc_ValueError,
2325 "need more than 0 values to unpack");
2326 goto Done;
2327 }
2328
2329 value = PyIter_Next(pair_iterator);
2330 if (value == NULL) {
2331 if (!PyErr_Occurred())
2332 PyErr_SetString(PyExc_ValueError,
2333 "need more than 1 value to unpack");
2334 goto Done;
2335 }
2336
2337 unexpected = PyIter_Next(pair_iterator);
2338 if (unexpected != NULL) {
2339 Py_DECREF(unexpected);
2340 PyErr_SetString(PyExc_ValueError,
2341 "too many values to unpack (expected 2)");
2342 goto Done;
2343 }
2344 else if (PyErr_Occurred())
2345 goto Done;
2346
2347 res = PyObject_SetItem(self, key, value);
2348
2349Done:
2350 Py_DECREF(pair);
Eric Snowc5e59602015-05-30 11:28:56 -06002351 Py_XDECREF(pair_iterator);
Eric Snow96c6af92015-05-29 22:21:39 -06002352 Py_XDECREF(key);
2353 Py_XDECREF(value);
2354 if (PyErr_Occurred())
2355 break;
2356 }
2357 Py_DECREF(iterator);
2358
2359 if (res < 0 || PyErr_Occurred() != NULL)
2360 return -1;
2361 else
2362 return 0;
2363}
2364
2365static PyObject *
2366mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
2367{
2368 int res = 0;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002369 Py_ssize_t len;
2370 _Py_IDENTIFIER(items);
2371 _Py_IDENTIFIER(keys);
Eric Snow96c6af92015-05-29 22:21:39 -06002372
2373 /* first handle args, if any */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002374 assert(args == NULL || PyTuple_Check(args));
2375 len = (args != NULL) ? PyTuple_GET_SIZE(args) : 0;
Benjamin Peterson99e96f22015-06-06 23:20:32 -05002376 if (len > 1) {
Eric Snow96c6af92015-05-29 22:21:39 -06002377 char *msg = "update() takes at most 1 positional argument (%d given)";
2378 PyErr_Format(PyExc_TypeError, msg, len);
2379 return NULL;
2380 }
Eric Snow96c6af92015-05-29 22:21:39 -06002381
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002382 if (len) {
Benjamin Peterson0718de92015-06-07 00:00:42 -05002383 PyObject *other = PyTuple_GET_ITEM(args, 0); /* borrowed reference */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002384 assert(other != NULL);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002385 Py_INCREF(other);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002386 if (PyDict_CheckExact(other) ||
2387 _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);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002393 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 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002401 else if (_PyObject_HasAttrId(other, &PyId_keys)) { /* never fails */
Benjamin Peterson0718de92015-06-07 00:00:42 -05002402 PyObject *keys, *iterator, *key;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002403 keys = _PyObject_CallMethodIdObjArgs(other, &PyId_keys, NULL);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002404 if (keys == NULL) {
2405 Py_DECREF(other);
2406 return NULL;
2407 }
2408 iterator = PyObject_GetIter(keys);
2409 Py_DECREF(keys);
2410 if (iterator == NULL) {
2411 Py_DECREF(other);
2412 return NULL;
2413 }
2414 while (res == 0 && (key = PyIter_Next(iterator))) {
2415 PyObject *value = PyObject_GetItem(other, key);
2416 if (value != NULL) {
2417 res = PyObject_SetItem(self, key, value);
2418 Py_DECREF(value);
2419 }
2420 else {
2421 res = -1;
2422 }
2423 Py_DECREF(key);
2424 }
2425 Py_DECREF(other);
2426 Py_DECREF(iterator);
2427 if (res != 0 || PyErr_Occurred())
2428 return NULL;
2429 }
2430 else {
2431 res = mutablemapping_add_pairs(self, other);
2432 Py_DECREF(other);
2433 if (res != 0)
2434 return NULL;
2435 }
2436 }
2437
2438 /* now handle kwargs */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002439 assert(kwargs == NULL || PyDict_Check(kwargs));
2440 len = (kwargs != NULL) ? PyDict_Size(kwargs) : 0;
Benjamin Peterson0718de92015-06-07 00:00:42 -05002441 if (len > 0) {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002442 PyObject *items = PyDict_Items(kwargs);
Eric Snow96c6af92015-05-29 22:21:39 -06002443 if (items == NULL)
2444 return NULL;
2445 res = mutablemapping_add_pairs(self, items);
2446 Py_DECREF(items);
2447 if (res == -1)
2448 return NULL;
2449 }
Eric Snow96c6af92015-05-29 22:21:39 -06002450
2451 Py_RETURN_NONE;
2452}