blob: 4bdd45ab82694dcf205ad1b931cb6ba818c80df6 [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)
91* _odict_add_new_node(od, key)
92
93For removing nodes:
94
Eric Snow96c6af92015-05-29 22:21:39 -060095* _odict_clear_node(od, node)
96* _odict_clear_nodes(od, clear_each)
97
98Others:
99
Eric Snow96c6af92015-05-29 22:21:39 -0600100* _odict_find_node(od, key)
101* _odict_keys_equal(od1, od2)
102
103Used, but specific to the linked-list implementation:
104
105* _odict_free_fast_nodes(od)
106
107And here's a look at how the linked-list relates to the OrderedDict API:
108
109============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
110method key val prev next mem 1st last empty iter find add rmv clr keq
111============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
112__del__ ~ X
113__delitem__ free ~ node
114__eq__ ~ X
115__iter__ X X
116__new__ X X
117__reduce__ X ~ X
118__repr__ X X X
119__reversed__ X X
120__setitem__ key
121__sizeof__ size X
122clear ~ ~ X
123copy X X X
124items X X X
125keys X X
126move_to_end X X X ~ h/t key
127pop free key
128popitem X X free X X node
129setdefault ~ ? ~
130values X X
131============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
132
133__delitem__ is the only method that directly relies on finding an arbitrary
134node in the linked-list. Everything else is iteration or relates to the
135ends of the linked-list.
136
137Situation that Endangers Consistency
138------------------------------------
139Using a raw linked-list for OrderedDict exposes a key situation that can
140cause problems. If a node is stored in a variable, there is a chance that
141the node may have been deallocated before the variable gets used, thus
142potentially leading to a segmentation fault. A key place where this shows
143up is during iteration through the linked list (via _odict_FOREACH or
144otherwise).
145
146A number of solutions are available to resolve this situation:
147
148* defer looking up the node until as late as possible and certainly after
149 any code that could possibly result in a deletion;
150* if the node is needed both before and after a point where the node might
151 be removed, do a check before using the node at the "after" location to
152 see if the node is still valid;
153* like the last one, but simply pull the node again to ensure it's right;
154* keep the key in the variable instead of the node and then look up the
155 node using the key at the point where the node is needed (this is what
156 we do for the iterators).
157
158Another related problem, preserving consistent ordering during iteration,
159is described below. That one is not exclusive to using linked-lists.
160
161
162Challenges from Subclassing dict
163================================
164
165OrderedDict subclasses dict, which is an unusual relationship between two
166builtin types (other than the base object type). Doing so results in
167some complication and deserves further explanation. There are two things
168to consider here. First, in what circumstances or with what adjustments
169can OrderedDict be used as a drop-in replacement for dict (at the C level)?
170Second, how can the OrderedDict implementation leverage the dict
171implementation effectively without introducing unnecessary coupling or
172inefficiencies?
173
174This second point is reflected here and in the implementation, so the
175further focus is on the first point. It is worth noting that for
176overridden methods, the dict implementation is deferred to as much as
177possible. Furthermore, coupling is limited to as little as is reasonable.
178
179Concrete API Compatibility
180--------------------------
181
182Use of the concrete C-API for dict (PyDict_*) with OrderedDict is
183problematic. (See http://bugs.python.org/issue10977.) The concrete API
184has a number of hard-coded assumptions tied to the dict implementation.
185This is, in part, due to performance reasons, which is understandable
186given the part dict plays in Python.
187
188Any attempt to replace dict with OrderedDict for any role in the
189interpreter (e.g. **kwds) faces a challenge. Such any effort must
190recognize that the instances in affected locations currently interact with
191the concrete API.
192
193Here are some ways to address this challenge:
194
1951. Change the relevant usage of the concrete API in CPython and add
196 PyDict_CheckExact() calls to each of the concrete API funcions.
1972. Adjust the relevant concrete API functions to explicitly accommodate
198 OrderedDict.
1993. As with #1, add the checks, but improve the abstract API with smart fast
200 paths for dict and OrderedDict, and refactor CPython to use the abstract
201 API. Improvements to the abstract API would be valuable regardless.
202
203Adding the checks to the concrete API would help make any interpreter
204switch to OrderedDict less painful for extension modules. However, this
205won't work. The equivalent C API call to `dict.__setitem__(obj, k, v)`
206is 'PyDict_SetItem(obj, k, v)`. This illustrates how subclasses in C call
207the base class's methods, since there is no equivalent of super() in the
208C API. Calling into Python for parent class API would work, but some
209extension modules already rely on this feature of the concrete API.
210
211For reference, here is a breakdown of some of the dict concrete API:
212
213========================== ============= =======================
214concrete API uses abstract API
215========================== ============= =======================
216PyDict_Check PyMapping_Check
217(PyDict_CheckExact) -
218(PyDict_New) -
219(PyDictProxy_New) -
220PyDict_Clear -
221PyDict_Contains PySequence_Contains
222PyDict_Copy -
223PyDict_SetItem PyObject_SetItem
224PyDict_SetItemString PyMapping_SetItemString
225PyDict_DelItem PyMapping_DelItem
226PyDict_DelItemString PyMapping_DelItemString
227PyDict_GetItem -
228PyDict_GetItemWithError PyObject_GetItem
229_PyDict_GetItemIdWithError -
230PyDict_GetItemString PyMapping_GetItemString
231PyDict_Items PyMapping_Items
232PyDict_Keys PyMapping_Keys
233PyDict_Values PyMapping_Values
234PyDict_Size PyMapping_Size
235 PyMapping_Length
236PyDict_Next PyIter_Next
237_PyDict_Next -
238PyDict_Merge -
239PyDict_Update -
240PyDict_MergeFromSeq2 -
241PyDict_ClearFreeList -
242- PyMapping_HasKeyString
243- PyMapping_HasKey
244========================== ============= =======================
245
246
247The dict Interface Relative to OrderedDict
248==========================================
249
250Since OrderedDict subclasses dict, understanding the various methods and
251attributes of dict is important for implementing OrderedDict.
252
253Relevant Type Slots
254-------------------
255
256================= ================ =================== ================
257slot attribute object dict
258================= ================ =================== ================
259tp_dealloc - object_dealloc dict_dealloc
260tp_repr __repr__ object_repr dict_repr
261sq_contains __contains__ - dict_contains
262mp_length __len__ - dict_length
263mp_subscript __getitem__ - dict_subscript
264mp_ass_subscript __setitem__ - dict_ass_sub
265 __delitem__
266tp_hash __hash__ _Py_HashPointer ..._HashNotImpl
267tp_str __str__ object_str -
268tp_getattro __getattribute__ ..._GenericGetAttr (repeated)
269 __getattr__
270tp_setattro __setattr__ ..._GenericSetAttr (disabled)
271tp_doc __doc__ (literal) dictionary_doc
272tp_traverse - - dict_traverse
273tp_clear - - dict_tp_clear
274tp_richcompare __eq__ object_richcompare dict_richcompare
275 __ne__
276tp_weaklistoffset (__weakref__) - -
277tp_iter __iter__ - dict_iter
278tp_dictoffset (__dict__) - -
279tp_init __init__ object_init dict_init
280tp_alloc - PyType_GenericAlloc (repeated)
281tp_new __new__ object_new dict_new
282tp_free - PyObject_Del PyObject_GC_Del
283================= ================ =================== ================
284
285Relevant Methods
286----------------
287
288================ =================== ===============
289method object dict
290================ =================== ===============
291__reduce__ object_reduce -
292__sizeof__ object_sizeof dict_sizeof
293clear - dict_clear
294copy - dict_copy
295fromkeys - dict_fromkeys
296get - dict_get
297items - dictitems_new
298keys - dictkeys_new
299pop - dict_pop
300popitem - dict_popitem
301setdefault - dict_setdefault
302update - dict_update
303values - dictvalues_new
304================ =================== ===============
305
306
307Pure Python OrderedDict
308=======================
309
310As already noted, compatibility with the pure Python OrderedDict
311implementation is a key goal of this C implementation. To further that
312goal, here's a summary of how OrderedDict-specific methods are implemented
313in collections/__init__.py. Also provided is an indication of which
314methods directly mutate or iterate the object, as well as any relationship
315with the underlying linked-list.
316
317============= ============== == ================ === === ====
318method impl used ll uses inq mut iter
319============= ============== == ================ === === ====
320__contains__ dict - - X
321__delitem__ OrderedDict Y dict.__delitem__ X
322__eq__ OrderedDict N OrderedDict ~
323 dict.__eq__
324 __iter__
325__getitem__ dict - - X
326__iter__ OrderedDict Y - X
327__init__ OrderedDict N update
328__len__ dict - - X
329__ne__ MutableMapping - __eq__ ~
330__reduce__ OrderedDict N OrderedDict ~
331 __iter__
332 __getitem__
333__repr__ OrderedDict N __class__ ~
334 items
335__reversed__ OrderedDict Y - X
336__setitem__ OrderedDict Y __contains__ X
337 dict.__setitem__
338__sizeof__ OrderedDict Y __len__ ~
339 __dict__
340clear OrderedDict Y dict.clear X
341copy OrderedDict N __class__
342 __init__
343fromkeys OrderedDict N __setitem__
344get dict - - ~
345items MutableMapping - ItemsView X
346keys MutableMapping - KeysView X
347move_to_end OrderedDict Y - X
348pop OrderedDict N __contains__ X
349 __getitem__
350 __delitem__
351popitem OrderedDict Y dict.pop X
352setdefault OrderedDict N __contains__ ~
353 __getitem__
354 __setitem__
355update MutableMapping - __setitem__ ~
356values MutableMapping - ValuesView X
357============= ============== == ================ === === ====
358
359__reversed__ and move_to_end are both exclusive to OrderedDict.
360
361
362C OrderedDict Implementation
363============================
364
365================= ================
366slot impl
367================= ================
368tp_dealloc odict_dealloc
369tp_repr odict_repr
370mp_ass_subscript odict_ass_sub
371tp_doc odict_doc
372tp_traverse odict_traverse
373tp_clear odict_tp_clear
374tp_richcompare odict_richcompare
375tp_weaklistoffset (offset)
376tp_iter odict_iter
377tp_dictoffset (offset)
378tp_init odict_init
379tp_alloc (repeated)
380tp_new odict_new
381================= ================
382
383================= ================
384method impl
385================= ================
386__reduce__ odict_reduce
387__sizeof__ odict_sizeof
388clear odict_clear
389copy odict_copy
390fromkeys odict_fromkeys
391items odictitems_new
392keys odictkeys_new
393pop odict_pop
394popitem odict_popitem
395setdefault odict_setdefault
396update odict_update
397values odictvalues_new
398================= ================
399
400Inherited unchanged from object/dict:
401
402================ ==========================
403method type field
404================ ==========================
405- tp_free
406__contains__ tp_as_sequence.sq_contains
407__getattr__ tp_getattro
408__getattribute__ tp_getattro
409__getitem__ tp_as_mapping.mp_subscript
410__hash__ tp_hash
411__len__ tp_as_mapping.mp_length
412__setattr__ tp_setattro
413__str__ tp_str
414get -
415================ ==========================
416
417
418Other Challenges
419================
420
421Preserving Ordering During Iteration
422------------------------------------
423During iteration through an OrderedDict, it is possible that items could
424get added, removed, or reordered. For a linked-list implementation, as
425with some other implementations, that situation may lead to undefined
426behavior. The documentation for dict mentions this in the `iter()` section
427of http://docs.python.org/3.4/library/stdtypes.html#dictionary-view-objects.
428In this implementation we follow dict's lead (as does the pure Python
429implementation) for __iter__(), keys(), values(), and items().
430
431For internal iteration (using _odict_FOREACH or not), there is still the
432risk that not all nodes that we expect to be seen in the loop actually get
433seen. Thus, we are careful in each of those places to ensure that they
434are. This comes, of course, at a small price at each location. The
435solutions are much the same as those detailed in the `Situation that
436Endangers Consistency` section above.
437
438
439Potential Optimizations
440=======================
441
442* Allocate the nodes as a block via od_fast_nodes instead of individually.
443 - Set node->key to NULL to indicate the node is not-in-use.
444 - Add _odict_EXISTS()?
445 - How to maintain consistency across resizes? Existing node pointers
446 would be invalidate after a resize, which is particularly problematic
447 for the iterators.
448* Use a more stream-lined implementation of update() and, likely indirectly,
449 __init__().
450
451*/
452
453/* TODO
454
455sooner:
456- reentrancy (make sure everything is at a thread-safe state when calling
457 into Python). I've already checked this multiple times, but want to
458 make one more pass.
459- add unit tests for reentrancy?
460
461later:
462- make the dict views support the full set API (the pure Python impl does)
463- implement a fuller MutableMapping API in C?
464- move the MutableMapping implementation to abstract.c?
465- optimize mutablemapping_update
466- use PyObject_MALLOC (small object allocator) for odict nodes?
467- support subclasses better (e.g. in odict_richcompare)
468
469*/
470
471#include "Python.h"
472#include "structmember.h"
473#include "dict-common.h"
474#include <stddef.h>
475
476
477typedef struct _odictnode _ODictNode;
478
479/* PyODictObject */
480struct _odictobject {
Eric Snow4fabf022015-06-04 00:09:56 -0600481 PyDictObject od_dict; /* the underlying dict */
482 _ODictNode *od_first; /* first node in the linked list, if any */
483 _ODictNode *od_last; /* last node in the linked list, if any */
Eric Snow8c7f9552015-08-07 17:45:12 -0600484 /* od_fast_nodes and od_resize_sentinel are managed by _odict_resize()
485 * Note that we rely on implementation details of dict for both. */
486 _ODictNode **od_fast_nodes; /* hash table that mirrors the dict table */
487 Py_uintptr_t od_resize_sentinel; /* changes if odict should be resized */
488
Eric Snow4fabf022015-06-04 00:09:56 -0600489 size_t od_state; /* incremented whenever the LL changes */
490 PyObject *od_inst_dict; /* OrderedDict().__dict__ */
491 PyObject *od_weakreflist; /* holds weakrefs to the odict */
Eric Snow96c6af92015-05-29 22:21:39 -0600492};
493
494
495/* ----------------------------------------------
496 * odict keys (a simple doubly-linked list)
497 */
498
499struct _odictnode {
500 PyObject *key;
Eric Snow4c729182015-06-03 10:50:37 -0600501 Py_hash_t hash;
Eric Snow96c6af92015-05-29 22:21:39 -0600502 _ODictNode *next;
503 _ODictNode *prev;
504};
505
506#define _odictnode_KEY(node) \
507 (node->key)
Eric Snow4c729182015-06-03 10:50:37 -0600508#define _odictnode_HASH(node) \
509 (node->hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600510/* borrowed reference */
511#define _odictnode_VALUE(node, od) \
Eric Snowa762af72015-06-01 22:59:08 -0600512 PyODict_GetItemWithError((PyObject *)od, _odictnode_KEY(node))
Eric Snow96c6af92015-05-29 22:21:39 -0600513#define _odictnode_PREV(node) (node->prev)
514#define _odictnode_NEXT(node) (node->next)
515
516#define _odict_FIRST(od) (((PyODictObject *)od)->od_first)
517#define _odict_LAST(od) (((PyODictObject *)od)->od_last)
518#define _odict_EMPTY(od) (_odict_FIRST(od) == NULL)
519#define _odict_FOREACH(od, node) \
520 for (node = _odict_FIRST(od); node != NULL; node = _odictnode_NEXT(node))
521
Eric Snow8c7f9552015-08-07 17:45:12 -0600522#define _odict_FAST_SIZE(od) ((PyDictObject *)od)->ma_keys->dk_size
Eric Snow96c6af92015-05-29 22:21:39 -0600523
Eric Snow96c6af92015-05-29 22:21:39 -0600524static void
525_odict_free_fast_nodes(PyODictObject *od) {
526 if (od->od_fast_nodes) {
527 PyMem_FREE(od->od_fast_nodes);
528 }
529}
530
Eric Snow4c729182015-06-03 10:50:37 -0600531/* Return the index into the hash table, regardless of a valid node. */
532static Py_ssize_t
533_odict_get_index_hash(PyODictObject *od, PyObject *key, Py_hash_t hash)
534{
535 PyObject **value_addr = NULL;
536 PyDictKeyEntry *ep;
537 PyDictKeysObject *keys = ((PyDictObject *)od)->ma_keys;
538
539 ep = (keys->dk_lookup)((PyDictObject *)od, key, hash, &value_addr);
540 if (ep == NULL)
541 return -1;
542 /* We use pointer arithmetic to get the entry's index into the table. */
543 return ep - keys->dk_entries;
544}
545
546/* Replace od->od_fast_nodes with a new table matching the size of dict's. */
Eric Snow96c6af92015-05-29 22:21:39 -0600547static int
548_odict_resize(PyODictObject *od) {
Eric Snow4c729182015-06-03 10:50:37 -0600549 Py_ssize_t size, i;
Eric Snow96c6af92015-05-29 22:21:39 -0600550 _ODictNode **fast_nodes, *node;
551
552 /* Initialize a new "fast nodes" table. */
553 size = ((PyDictObject *)od)->ma_keys->dk_size;
554 fast_nodes = PyMem_NEW(_ODictNode *, size);
555 if (fast_nodes == NULL) {
556 PyErr_NoMemory();
557 return -1;
558 }
559 for (i = 0; i < size; i++)
560 fast_nodes[i] = NULL;
561
562 /* Copy the current nodes into the table. */
Eric Snow96c6af92015-05-29 22:21:39 -0600563 _odict_FOREACH(od, node) {
Eric Snow4c729182015-06-03 10:50:37 -0600564 i = _odict_get_index_hash(od, _odictnode_KEY(node),
565 _odictnode_HASH(node));
Eric Snow96c6af92015-05-29 22:21:39 -0600566 if (i < 0) {
Eric Snow96c6af92015-05-29 22:21:39 -0600567 PyMem_FREE(fast_nodes);
568 return -1;
569 }
570 fast_nodes[i] = node;
571 }
Eric Snow96c6af92015-05-29 22:21:39 -0600572
573 /* Replace the old fast nodes table. */
574 _odict_free_fast_nodes(od);
575 od->od_fast_nodes = fast_nodes;
Eric Snow8c7f9552015-08-07 17:45:12 -0600576 od->od_resize_sentinel = (Py_uintptr_t)(((PyDictObject *)od)->ma_keys);
Eric Snow96c6af92015-05-29 22:21:39 -0600577 return 0;
578}
579
580/* Return the index into the hash table, regardless of a valid node. */
581static Py_ssize_t
582_odict_get_index(PyODictObject *od, PyObject *key)
583{
584 Py_hash_t hash;
Eric Snow4c729182015-06-03 10:50:37 -0600585 PyDictKeysObject *keys;
Eric Snow96c6af92015-05-29 22:21:39 -0600586
587 assert(key != NULL);
Eric Snow4c729182015-06-03 10:50:37 -0600588 hash = PyObject_Hash(key);
589 if (hash == -1)
Eric Snow96c6af92015-05-29 22:21:39 -0600590 return -1;
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. */
Eric Snow8c7f9552015-08-07 17:45:12 -0600594 if (od->od_resize_sentinel != (Py_uintptr_t)keys) {
Eric Snow4c729182015-06-03 10:50:37 -0600595 int resize_res = _odict_resize(od);
596 if (resize_res < 0)
597 return -1;
598 }
599
600 return _odict_get_index_hash(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600601}
602
Eric Snow96c6af92015-05-29 22:21:39 -0600603/* Returns NULL if there was some error or the key was not found. */
604static _ODictNode *
605_odict_find_node(PyODictObject *od, PyObject *key)
606{
607 Py_ssize_t index;
608
609 if (_odict_EMPTY(od))
610 return NULL;
611 index = _odict_get_index(od, key);
612 if (index < 0)
613 return NULL;
614 return od->od_fast_nodes[index];
615}
616
617static void
618_odict_add_head(PyODictObject *od, _ODictNode *node)
619{
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300620 _odictnode_PREV(node) = NULL;
621 _odictnode_NEXT(node) = _odict_FIRST(od);
622 if (_odict_FIRST(od) == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -0600623 _odict_LAST(od) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300624 else
Eric Snow96c6af92015-05-29 22:21:39 -0600625 _odictnode_PREV(_odict_FIRST(od)) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300626 _odict_FIRST(od) = node;
Eric Snow4fabf022015-06-04 00:09:56 -0600627 od->od_state++;
Eric Snow96c6af92015-05-29 22:21:39 -0600628}
629
630static void
631_odict_add_tail(PyODictObject *od, _ODictNode *node)
632{
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300633 _odictnode_PREV(node) = _odict_LAST(od);
634 _odictnode_NEXT(node) = NULL;
635 if (_odict_LAST(od) == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -0600636 _odict_FIRST(od) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300637 else
Eric Snow96c6af92015-05-29 22:21:39 -0600638 _odictnode_NEXT(_odict_LAST(od)) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300639 _odict_LAST(od) = node;
Eric Snow4fabf022015-06-04 00:09:56 -0600640 od->od_state++;
Eric Snow96c6af92015-05-29 22:21:39 -0600641}
642
643/* adds the node to the end of the list */
644static int
645_odict_add_new_node(PyODictObject *od, PyObject *key)
646{
Eric Snow4c729182015-06-03 10:50:37 -0600647 Py_hash_t hash;
Eric Snow96c6af92015-05-29 22:21:39 -0600648 Py_ssize_t i;
649 _ODictNode *node;
650
Eric Snow4c729182015-06-03 10:50:37 -0600651 hash = PyObject_Hash(key);
652 if (hash == -1)
653 return -1;
654
Serhiy Storchakad17427b2015-10-20 18:21:48 +0300655 Py_INCREF(key);
Eric Snow96c6af92015-05-29 22:21:39 -0600656 i = _odict_get_index(od, key);
657 if (i < 0) {
658 if (!PyErr_Occurred())
659 PyErr_SetObject(PyExc_KeyError, key);
660 Py_DECREF(key);
661 return -1;
662 }
663 else if (od->od_fast_nodes[i] != NULL) {
664 /* We already have a node for the key so there's no need to add one. */
665 Py_DECREF(key);
666 return 0;
667 }
668
669 /* must not be added yet */
670 node = (_ODictNode *)PyMem_MALLOC(sizeof(_ODictNode));
671 if (node == NULL) {
672 Py_DECREF(key);
673 PyErr_NoMemory();
674 return -1;
675 }
676
677 _odictnode_KEY(node) = key;
Eric Snow4c729182015-06-03 10:50:37 -0600678 _odictnode_HASH(node) = hash;
Eric Snow96c6af92015-05-29 22:21:39 -0600679 _odict_add_tail(od, node);
680 od->od_fast_nodes[i] = node;
681 return 0;
682}
683
684/* Putting the decref after the free causes problems. */
685#define _odictnode_DEALLOC(node) \
686 do { \
687 Py_DECREF(_odictnode_KEY(node)); \
688 PyMem_FREE((void *)node); \
689 } while (0)
690
691/* Repeated calls on the same node are no-ops. */
692static void
693_odict_remove_node(PyODictObject *od, _ODictNode *node)
694{
695 if (_odict_FIRST(od) == node)
696 _odict_FIRST(od) = _odictnode_NEXT(node);
697 else if (_odictnode_PREV(node) != NULL)
698 _odictnode_NEXT(_odictnode_PREV(node)) = _odictnode_NEXT(node);
699
700 if (_odict_LAST(od) == node)
701 _odict_LAST(od) = _odictnode_PREV(node);
702 else if (_odictnode_NEXT(node) != NULL)
703 _odictnode_PREV(_odictnode_NEXT(node)) = _odictnode_PREV(node);
704
705 _odictnode_PREV(node) = NULL;
706 _odictnode_NEXT(node) = NULL;
Eric Snow4fabf022015-06-04 00:09:56 -0600707 od->od_state++;
Eric Snow96c6af92015-05-29 22:21:39 -0600708}
709
Eric Snow96c6af92015-05-29 22:21:39 -0600710/* If someone calls PyDict_DelItem() directly on an OrderedDict, we'll
711 get all sorts of problems here. In PyODict_DelItem we make sure to
712 call _odict_clear_node first.
Victor Stinnerca30b022015-09-03 17:50:04 +0200713
Eric Snow96c6af92015-05-29 22:21:39 -0600714 This matters in the case of colliding keys. Suppose we add 3 keys:
715 [A, B, C], where the hash of C collides with A and the next possible
716 index in the hash table is occupied by B. If we remove B then for C
717 the dict's looknode func will give us the old index of B instead of
718 the index we got before deleting B. However, the node for C in
719 od_fast_nodes is still at the old dict index of C. Thus to be sure
720 things don't get out of sync, we clear the node in od_fast_nodes
721 *before* calling PyDict_DelItem.
722
723 The same must be done for any other OrderedDict operations where
724 we modify od_fast_nodes.
725*/
726static int
727_odict_clear_node(PyODictObject *od, _ODictNode *node, PyObject *key)
728{
729 Py_ssize_t i;
730
731 assert(key != NULL);
732 if (_odict_EMPTY(od)) {
733 /* Let later code decide if this is a KeyError. */
734 return 0;
735 }
736
737 i = _odict_get_index(od, key);
738 if (i < 0)
739 return PyErr_Occurred() ? -1 : 0;
740
741 if (node == NULL)
742 node = od->od_fast_nodes[i];
743 assert(node == od->od_fast_nodes[i]);
744 if (node == NULL) {
745 /* Let later code decide if this is a KeyError. */
746 return 0;
747 }
748
749 // Now clear the node.
750 od->od_fast_nodes[i] = NULL;
751 _odict_remove_node(od, node);
752 _odictnode_DEALLOC(node);
753 return 0;
754}
755
756static void
757_odict_clear_nodes(PyODictObject *od)
758{
759 _ODictNode *node, *next;
760
761 if (!_odict_EMPTY(od)) {
762 node = _odict_FIRST(od);
763 while (node != NULL) {
764 next = _odictnode_NEXT(node);
765 _odictnode_DEALLOC(node);
766 node = next;
767 }
768 _odict_FIRST(od) = NULL;
769 _odict_LAST(od) = NULL;
770 }
771
772 _odict_free_fast_nodes(od);
773 od->od_fast_nodes = NULL;
774}
775
776/* There isn't any memory management of nodes past this point. */
777#undef _odictnode_DEALLOC
778
779static int
780_odict_keys_equal(PyODictObject *a, PyODictObject *b)
781{
782 _ODictNode *node_a, *node_b;
783
784 node_a = _odict_FIRST(a);
785 node_b = _odict_FIRST(b);
786 while (1) {
787 if (node_a == NULL && node_b == NULL)
788 /* success: hit the end of each at the same time */
789 return 1;
790 else if (node_a == NULL || node_b == NULL)
791 /* unequal length */
792 return 0;
793 else {
794 int res = PyObject_RichCompareBool(
795 (PyObject *)_odictnode_KEY(node_a),
796 (PyObject *)_odictnode_KEY(node_b),
797 Py_EQ);
798 if (res < 0)
799 return res;
800 else if (res == 0)
801 return 0;
802
803 /* otherwise it must match, so move on to the next one */
804 node_a = _odictnode_NEXT(node_a);
805 node_b = _odictnode_NEXT(node_b);
806 }
807 }
808}
809
810
811/* ----------------------------------------------
812 * OrderedDict mapping methods
813 */
814
815/* mp_ass_subscript: __setitem__() and __delitem__() */
816
817static int
818odict_mp_ass_sub(PyODictObject *od, PyObject *v, PyObject *w)
819{
820 if (w == NULL)
821 return PyODict_DelItem((PyObject *)od, v);
822 else
823 return PyODict_SetItem((PyObject *)od, v, w);
824}
825
826/* tp_as_mapping */
827
828static PyMappingMethods odict_as_mapping = {
829 0, /*mp_length*/
830 0, /*mp_subscript*/
831 (objobjargproc)odict_mp_ass_sub, /*mp_ass_subscript*/
832};
833
834
835/* ----------------------------------------------
836 * OrderedDict methods
837 */
838
839/* __delitem__() */
840
841PyDoc_STRVAR(odict_delitem__doc__, "od.__delitem__(y) <==> del od[y]");
842
843/* __eq__() */
844
845PyDoc_STRVAR(odict_eq__doc__,
846"od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive \n\
847 while comparison to a regular mapping is order-insensitive.\n\
848 ");
849
850/* forward */
851static PyObject * odict_richcompare(PyObject *v, PyObject *w, int op);
852
853static PyObject *
854odict_eq(PyObject *a, PyObject *b)
855{
856 return odict_richcompare(a, b, Py_EQ);
857}
858
859/* __init__() */
860
861PyDoc_STRVAR(odict_init__doc__,
862"Initialize an ordered dictionary. The signature is the same as\n\
863 regular dictionaries, but keyword arguments are not recommended because\n\
864 their insertion order is arbitrary.\n\
865\n\
866 ");
867
868/* forward */
869static int odict_init(PyObject *self, PyObject *args, PyObject *kwds);
870
871/* __iter__() */
872
873PyDoc_STRVAR(odict_iter__doc__, "od.__iter__() <==> iter(od)");
874
875static PyObject * odict_iter(PyODictObject *self); /* forward */
876
877/* __ne__() */
878
879/* Mapping.__ne__() does not have a docstring. */
880PyDoc_STRVAR(odict_ne__doc__, "");
881
882static PyObject *
883odict_ne(PyObject *a, PyObject *b)
884{
885 return odict_richcompare(a, b, Py_NE);
886}
887
888/* __repr__() */
889
890PyDoc_STRVAR(odict_repr__doc__, "od.__repr__() <==> repr(od)");
891
892static PyObject * odict_repr(PyODictObject *self); /* forward */
893
894/* __setitem__() */
895
896PyDoc_STRVAR(odict_setitem__doc__, "od.__setitem__(i, y) <==> od[i]=y");
897
898/* fromkeys() */
899
900PyDoc_STRVAR(odict_fromkeys__doc__,
901"OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.\n\
902 If not specified, the value defaults to None.\n\
903\n\
904 ");
905
906static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -0600907odict_fromkeys(PyObject *cls, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -0600908{
Eric Snowac02ef32015-06-02 20:42:14 -0600909 static char *kwlist[] = {"iterable", "value", 0};
Eric Snow96c6af92015-05-29 22:21:39 -0600910 PyObject *seq;
911 PyObject *value = Py_None;
Eric Snowac02ef32015-06-02 20:42:14 -0600912
913 /* both borrowed */
914 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:fromkeys", kwlist,
915 &seq, &value)) {
Eric Snow96c6af92015-05-29 22:21:39 -0600916 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -0600917 }
Eric Snow96c6af92015-05-29 22:21:39 -0600918 return _PyDict_FromKeys(cls, seq, value);
919}
920
921/* __sizeof__() */
922
923/* OrderedDict.__sizeof__() does not have a docstring. */
924PyDoc_STRVAR(odict_sizeof__doc__, "");
925
926static PyObject *
927odict_sizeof(PyODictObject *od)
928{
929 PyObject *pylong;
Eric Snowc5e59602015-05-30 11:28:56 -0600930 Py_ssize_t res, temp;
Eric Snow96c6af92015-05-29 22:21:39 -0600931
932 pylong = _PyDict_SizeOf((PyDictObject *)od);
933 if (pylong == NULL)
934 return NULL;
935 res = PyLong_AsSsize_t(pylong);
936 Py_DECREF(pylong);
937 if (res == -1 && PyErr_Occurred())
938 return NULL;
939
940 res += sizeof(PyODictObject) - sizeof(PyDictObject);
941
942 /* instance dict */
943 pylong = _PyDict_SizeOf((PyDictObject *)od->od_inst_dict);
944 if (pylong == NULL)
945 return NULL;
Eric Snowc5e59602015-05-30 11:28:56 -0600946 temp = PyLong_AsSsize_t(pylong);
Eric Snow96c6af92015-05-29 22:21:39 -0600947 Py_DECREF(pylong);
Eric Snowc5e59602015-05-30 11:28:56 -0600948 if (temp == -1 && PyErr_Occurred())
Eric Snow96c6af92015-05-29 22:21:39 -0600949 return NULL;
Eric Snowc5e59602015-05-30 11:28:56 -0600950 res += temp;
Eric Snow96c6af92015-05-29 22:21:39 -0600951
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300952 res += sizeof(_ODictNode *) * _odict_FAST_SIZE(od); /* od_fast_nodes */
Eric Snow96c6af92015-05-29 22:21:39 -0600953 if (!_odict_EMPTY(od)) {
954 res += sizeof(_ODictNode) * PyODict_SIZE(od); /* linked-list */
955 }
956 return PyLong_FromSsize_t(res);
957}
958
959/* __reduce__() */
960
961PyDoc_STRVAR(odict_reduce__doc__, "Return state information for pickling");
962
963static PyObject *
964odict_reduce(register PyODictObject *od)
965{
966 _Py_IDENTIFIER(__dict__);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300967 _Py_IDENTIFIER(items);
Serhiy Storchaka4575beb2015-10-22 20:18:24 +0300968 PyObject *dict = NULL, *result = NULL;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300969 PyObject *items_iter, *items, *args = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -0600970
971 /* capture any instance state */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300972 dict = _PyObject_GetAttrId((PyObject *)od, &PyId___dict__);
973 if (dict == NULL)
Eric Snowc5e59602015-05-30 11:28:56 -0600974 goto Done;
975 else {
Eric Snow96c6af92015-05-29 22:21:39 -0600976 /* od.__dict__ isn't necessarily a dict... */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300977 Py_ssize_t dict_len = PyObject_Length(dict);
978 if (dict_len == -1)
Eric Snow96c6af92015-05-29 22:21:39 -0600979 goto Done;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300980 if (!dict_len) {
981 /* nothing to pickle in od.__dict__ */
982 Py_CLEAR(dict);
Eric Snow96c6af92015-05-29 22:21:39 -0600983 }
984 }
985
986 /* build the result */
Eric Snow96c6af92015-05-29 22:21:39 -0600987 args = PyTuple_New(0);
988 if (args == NULL)
989 goto Done;
990
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300991 items = _PyObject_CallMethodIdObjArgs((PyObject *)od, &PyId_items, NULL);
Eric Snow96c6af92015-05-29 22:21:39 -0600992 if (items == NULL)
993 goto Done;
994
995 items_iter = PyObject_GetIter(items);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300996 Py_DECREF(items);
Eric Snow96c6af92015-05-29 22:21:39 -0600997 if (items_iter == NULL)
998 goto Done;
999
Serhiy Storchaka4575beb2015-10-22 20:18:24 +03001000 result = PyTuple_Pack(5, Py_TYPE(od), args, dict ? dict : Py_None, Py_None, items_iter);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001001 Py_DECREF(items_iter);
Eric Snow96c6af92015-05-29 22:21:39 -06001002
1003Done:
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001004 Py_XDECREF(dict);
Eric Snow96c6af92015-05-29 22:21:39 -06001005 Py_XDECREF(args);
Eric Snow96c6af92015-05-29 22:21:39 -06001006
1007 return result;
1008}
1009
1010/* setdefault() */
1011
1012PyDoc_STRVAR(odict_setdefault__doc__,
1013 "od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od");
1014
1015/* Skips __missing__() calls. */
1016static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001017odict_setdefault(register PyODictObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001018{
Eric Snowac02ef32015-06-02 20:42:14 -06001019 static char *kwlist[] = {"key", "default", 0};
Eric Snow96c6af92015-05-29 22:21:39 -06001020 PyObject *key, *result = NULL;
1021 PyObject *failobj = Py_None;
1022
1023 /* both borrowed */
Eric Snowac02ef32015-06-02 20:42:14 -06001024 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:setdefault", kwlist,
1025 &key, &failobj)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001026 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001027 }
Eric Snow96c6af92015-05-29 22:21:39 -06001028
1029 if (PyODict_CheckExact(od)) {
Eric Snowd1719752015-06-01 23:12:13 -06001030 result = PyODict_GetItemWithError(od, key); /* borrowed */
1031 if (result == NULL) {
1032 if (PyErr_Occurred())
1033 return NULL;
1034 assert(_odict_find_node(od, key) == NULL);
1035 if (PyODict_SetItem((PyObject *)od, key, failobj) >= 0) {
Eric Snow96c6af92015-05-29 22:21:39 -06001036 result = failobj;
1037 Py_INCREF(failobj);
1038 }
1039 }
1040 else {
Eric Snowd1719752015-06-01 23:12:13 -06001041 Py_INCREF(result);
Eric Snow96c6af92015-05-29 22:21:39 -06001042 }
1043 }
1044 else {
1045 int exists = PySequence_Contains((PyObject *)od, key);
1046 if (exists < 0) {
Eric Snowd1719752015-06-01 23:12:13 -06001047 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001048 }
1049 else if (exists) {
1050 result = PyObject_GetItem((PyObject *)od, key);
1051 }
1052 else if (PyObject_SetItem((PyObject *)od, key, failobj) >= 0) {
1053 result = failobj;
1054 Py_INCREF(failobj);
1055 }
1056 }
1057
Eric Snow96c6af92015-05-29 22:21:39 -06001058 return result;
1059}
1060
1061/* pop() */
1062
1063PyDoc_STRVAR(odict_pop__doc__,
1064"od.pop(k[,d]) -> v, remove specified key and return the corresponding\n\
1065 value. If key is not found, d is returned if given, otherwise KeyError\n\
1066 is raised.\n\
1067\n\
1068 ");
1069
1070/* forward */
1071static PyObject * _odict_popkey(PyObject *, PyObject *, PyObject *);
1072
1073/* Skips __missing__() calls. */
1074static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001075odict_pop(PyObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001076{
Eric Snowac02ef32015-06-02 20:42:14 -06001077 static char *kwlist[] = {"key", "default", 0};
Eric Snow96c6af92015-05-29 22:21:39 -06001078 PyObject *key, *failobj = NULL;
1079
Eric Snowac02ef32015-06-02 20:42:14 -06001080 /* borrowed */
1081 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:pop", kwlist,
1082 &key, &failobj)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001083 return NULL;
1084 }
1085
1086 return _odict_popkey(od, key, failobj);
1087}
1088
1089static PyObject *
1090_odict_popkey(PyObject *od, PyObject *key, PyObject *failobj)
1091{
1092 _ODictNode *node;
1093 PyObject *value = NULL;
1094
Eric Snow96c6af92015-05-29 22:21:39 -06001095 /* Pop the node first to avoid a possible dict resize (due to
1096 eval loop reentrancy) and complications due to hash collision
1097 resolution. */
1098 node = _odict_find_node((PyODictObject *)od, key);
1099 if (node == NULL) {
1100 if (PyErr_Occurred())
Eric Snowd1719752015-06-01 23:12:13 -06001101 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001102 }
1103 else {
1104 int res = _odict_clear_node((PyODictObject *)od, node, key);
1105 if (res < 0) {
Eric Snowd1719752015-06-01 23:12:13 -06001106 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001107 }
1108 }
1109
1110 /* Now delete the value from the dict. */
1111 if (PyODict_CheckExact(od)) {
1112 if (node != NULL) {
1113 /* We could do PyDict_GetItem() and PyDict_DelItem() directly... */
1114 value = _PyDict_Pop((PyDictObject *)od, key, failobj);
1115 }
1116 }
1117 else {
1118 int exists = PySequence_Contains(od, key);
1119 if (exists < 0)
Eric Snowd1719752015-06-01 23:12:13 -06001120 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001121 if (exists) {
1122 value = PyObject_GetItem(od, key);
1123 if (value != NULL) {
1124 if (PyObject_DelItem(od, key) == -1) {
Eric Snowe3dfa9e2015-05-30 12:51:15 -06001125 Py_CLEAR(value);
Eric Snow96c6af92015-05-29 22:21:39 -06001126 }
1127 }
1128 }
1129 }
1130
1131 /* Apply the fallback value, if necessary. */
1132 if (value == NULL && !PyErr_Occurred()) {
1133 if (failobj) {
1134 value = failobj;
1135 Py_INCREF(failobj);
1136 }
1137 else {
1138 PyErr_SetObject(PyExc_KeyError, key);
1139 }
1140 }
1141
Eric Snow96c6af92015-05-29 22:21:39 -06001142 return value;
1143}
1144
1145/* popitem() */
1146
1147PyDoc_STRVAR(odict_popitem__doc__,
1148"od.popitem() -> (k, v), return and remove a (key, value) pair.\n\
1149 Pairs are returned in LIFO order if last is true or FIFO order if false.\n\
1150\n\
1151 ");
1152
1153static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001154odict_popitem(PyObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001155{
Eric Snowac02ef32015-06-02 20:42:14 -06001156 static char *kwlist[] = {"last", 0};
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001157 PyObject *key, *value, *item = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001158 _ODictNode *node;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001159 int last = 1;
Eric Snow96c6af92015-05-29 22:21:39 -06001160
1161 /* pull the item */
1162
Eric Snowac02ef32015-06-02 20:42:14 -06001163 /* borrowed */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001164 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|p:popitem", kwlist,
Eric Snowac02ef32015-06-02 20:42:14 -06001165 &last)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001166 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001167 }
Eric Snow96c6af92015-05-29 22:21:39 -06001168
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001169 if (_odict_EMPTY(od)) {
1170 PyErr_SetString(PyExc_KeyError, "dictionary is empty");
1171 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001172 }
Eric Snow96c6af92015-05-29 22:21:39 -06001173
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001174 node = last ? _odict_LAST(od) : _odict_FIRST(od);
Eric Snow96c6af92015-05-29 22:21:39 -06001175 key = _odictnode_KEY(node);
Eric Snowd1719752015-06-01 23:12:13 -06001176 Py_INCREF(key);
Eric Snow96c6af92015-05-29 22:21:39 -06001177 value = _odict_popkey(od, key, NULL);
1178 if (value == NULL)
1179 return NULL;
1180 item = PyTuple_Pack(2, key, value);
Eric Snowd1719752015-06-01 23:12:13 -06001181 Py_DECREF(key);
Eric Snow96c6af92015-05-29 22:21:39 -06001182 Py_DECREF(value);
1183 return item;
1184}
1185
1186/* keys() */
1187
1188/* MutableMapping.keys() does not have a docstring. */
1189PyDoc_STRVAR(odict_keys__doc__, "");
1190
1191static PyObject * odictkeys_new(PyObject *od); /* forward */
1192
1193/* values() */
1194
1195/* MutableMapping.values() does not have a docstring. */
1196PyDoc_STRVAR(odict_values__doc__, "");
1197
1198static PyObject * odictvalues_new(PyObject *od); /* forward */
1199
1200/* items() */
1201
1202/* MutableMapping.items() does not have a docstring. */
1203PyDoc_STRVAR(odict_items__doc__, "");
1204
1205static PyObject * odictitems_new(PyObject *od); /* forward */
1206
1207/* update() */
1208
1209/* MutableMapping.update() does not have a docstring. */
1210PyDoc_STRVAR(odict_update__doc__, "");
1211
1212/* forward */
1213static PyObject * mutablemapping_update(PyObject *, PyObject *, PyObject *);
1214
1215#define odict_update mutablemapping_update
1216
1217/* clear() */
1218
1219PyDoc_STRVAR(odict_clear__doc__,
1220 "od.clear() -> None. Remove all items from od.");
1221
1222static PyObject *
1223odict_clear(register PyODictObject *od)
1224{
1225 PyDict_Clear((PyObject *)od);
1226 _odict_clear_nodes(od);
1227 _odict_FIRST(od) = NULL;
1228 _odict_LAST(od) = NULL;
1229 if (_odict_resize(od) < 0)
1230 return NULL;
1231 Py_RETURN_NONE;
1232}
1233
1234/* copy() */
1235
1236PyDoc_STRVAR(odict_copy__doc__, "od.copy() -> a shallow copy of od");
1237
1238static PyObject *
1239odict_copy(register PyODictObject *od)
1240{
1241 _ODictNode *node;
1242 PyObject *od_copy;
1243
1244 if (PyODict_CheckExact(od))
1245 od_copy = PyODict_New();
1246 else
1247 od_copy = PyObject_CallFunctionObjArgs((PyObject *)Py_TYPE(od), NULL);
1248 if (od_copy == NULL)
1249 return NULL;
1250
1251 if (PyODict_CheckExact(od)) {
1252 _odict_FOREACH(od, node) {
Eric Snowa762af72015-06-01 22:59:08 -06001253 PyObject *key = _odictnode_KEY(node);
1254 PyObject *value = _odictnode_VALUE(node, od);
1255 if (value == NULL) {
1256 if (!PyErr_Occurred())
1257 PyErr_SetObject(PyExc_KeyError, key);
1258 goto fail;
1259 }
1260 if (PyODict_SetItem((PyObject *)od_copy, key, value) != 0)
Eric Snow96c6af92015-05-29 22:21:39 -06001261 goto fail;
1262 }
1263 }
1264 else {
1265 _odict_FOREACH(od, node) {
1266 int res;
1267 PyObject *value = PyObject_GetItem((PyObject *)od,
1268 _odictnode_KEY(node));
1269 if (value == NULL)
1270 goto fail;
1271 res = PyObject_SetItem((PyObject *)od_copy,
1272 _odictnode_KEY(node), value);
1273 Py_DECREF(value);
1274 if (res != 0)
1275 goto fail;
1276 }
1277 }
1278 return od_copy;
1279
1280fail:
1281 Py_DECREF(od_copy);
1282 return NULL;
1283}
1284
1285/* __reversed__() */
1286
1287PyDoc_STRVAR(odict_reversed__doc__, "od.__reversed__() <==> reversed(od)");
1288
1289#define _odict_ITER_REVERSED 1
1290#define _odict_ITER_KEYS 2
1291#define _odict_ITER_VALUES 4
1292
1293/* forward */
1294static PyObject * odictiter_new(PyODictObject *, int);
1295
1296static PyObject *
1297odict_reversed(PyODictObject *od)
1298{
Eric Snow96c6af92015-05-29 22:21:39 -06001299 return odictiter_new(od, _odict_ITER_KEYS|_odict_ITER_REVERSED);
1300}
1301
1302/* move_to_end() */
1303
1304PyDoc_STRVAR(odict_move_to_end__doc__,
1305"Move an existing element to the end (or beginning if last==False).\n\
1306\n\
1307 Raises KeyError if the element does not exist.\n\
1308 When last=True, acts like a fast version of self[key]=self.pop(key).\n\
1309\n\
1310 ");
1311
1312static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001313odict_move_to_end(PyODictObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001314{
Eric Snowac02ef32015-06-02 20:42:14 -06001315 static char *kwlist[] = {"key", "last", 0};
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001316 PyObject *key;
1317 int last = 1;
1318 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001319
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001320 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|p:move_to_end", kwlist,
Eric Snowac02ef32015-06-02 20:42:14 -06001321 &key, &last)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001322 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001323 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001324
Eric Snow96c6af92015-05-29 22:21:39 -06001325 if (_odict_EMPTY(od)) {
1326 PyErr_SetObject(PyExc_KeyError, key);
Eric Snow96c6af92015-05-29 22:21:39 -06001327 return NULL;
1328 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001329 node = last ? _odict_LAST(od) : _odict_FIRST(od);
1330 if (key != _odictnode_KEY(node)) {
1331 node = _odict_find_node(od, key);
1332 if (node == NULL) {
1333 if (!PyErr_Occurred())
1334 PyErr_SetObject(PyExc_KeyError, key);
Eric Snowc5e59602015-05-30 11:28:56 -06001335 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001336 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001337 if (last) {
1338 /* Only move if not already the last one. */
1339 if (node != _odict_LAST(od)) {
1340 _odict_remove_node(od, node);
Eric Snow96c6af92015-05-29 22:21:39 -06001341 _odict_add_tail(od, node);
1342 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001343 }
1344 else {
1345 /* Only move if not already the first one. */
1346 if (node != _odict_FIRST(od)) {
1347 _odict_remove_node(od, node);
1348 _odict_add_head(od, node);
Eric Snow96c6af92015-05-29 22:21:39 -06001349 }
1350 }
1351 }
Eric Snow96c6af92015-05-29 22:21:39 -06001352 Py_RETURN_NONE;
1353}
1354
1355
1356/* tp_methods */
1357
1358static PyMethodDef odict_methods[] = {
1359
1360 /* explicitly defined so we can align docstrings with
1361 * collections.OrderedDict */
1362 {"__delitem__", (PyCFunction)odict_mp_ass_sub, METH_NOARGS,
1363 odict_delitem__doc__},
1364 {"__eq__", (PyCFunction)odict_eq, METH_NOARGS,
1365 odict_eq__doc__},
1366 {"__init__", (PyCFunction)odict_init, METH_NOARGS,
1367 odict_init__doc__},
1368 {"__iter__", (PyCFunction)odict_iter, METH_NOARGS,
1369 odict_iter__doc__},
1370 {"__ne__", (PyCFunction)odict_ne, METH_NOARGS,
1371 odict_ne__doc__},
1372 {"__repr__", (PyCFunction)odict_repr, METH_NOARGS,
1373 odict_repr__doc__},
1374 {"__setitem__", (PyCFunction)odict_mp_ass_sub, METH_NOARGS,
1375 odict_setitem__doc__},
Eric Snowac02ef32015-06-02 20:42:14 -06001376 {"fromkeys", (PyCFunction)odict_fromkeys,
1377 METH_VARARGS | METH_KEYWORDS | METH_CLASS, odict_fromkeys__doc__},
Eric Snow96c6af92015-05-29 22:21:39 -06001378
1379 /* overridden dict methods */
1380 {"__sizeof__", (PyCFunction)odict_sizeof, METH_NOARGS,
1381 odict_sizeof__doc__},
1382 {"__reduce__", (PyCFunction)odict_reduce, METH_NOARGS,
1383 odict_reduce__doc__},
Eric Snowac02ef32015-06-02 20:42:14 -06001384 {"setdefault", (PyCFunction)odict_setdefault,
1385 METH_VARARGS | METH_KEYWORDS, odict_setdefault__doc__},
1386 {"pop", (PyCFunction)odict_pop,
1387 METH_VARARGS | METH_KEYWORDS, odict_pop__doc__},
1388 {"popitem", (PyCFunction)odict_popitem,
1389 METH_VARARGS | METH_KEYWORDS, odict_popitem__doc__},
Eric Snow96c6af92015-05-29 22:21:39 -06001390 {"keys", (PyCFunction)odictkeys_new, METH_NOARGS,
1391 odict_keys__doc__},
1392 {"values", (PyCFunction)odictvalues_new, METH_NOARGS,
1393 odict_values__doc__},
1394 {"items", (PyCFunction)odictitems_new, METH_NOARGS,
1395 odict_items__doc__},
1396 {"update", (PyCFunction)odict_update, METH_VARARGS | METH_KEYWORDS,
1397 odict_update__doc__},
1398 {"clear", (PyCFunction)odict_clear, METH_NOARGS,
1399 odict_clear__doc__},
1400 {"copy", (PyCFunction)odict_copy, METH_NOARGS,
1401 odict_copy__doc__},
1402
1403 /* new methods */
1404 {"__reversed__", (PyCFunction)odict_reversed, METH_NOARGS,
1405 odict_reversed__doc__},
Eric Snowac02ef32015-06-02 20:42:14 -06001406 {"move_to_end", (PyCFunction)odict_move_to_end,
1407 METH_VARARGS | METH_KEYWORDS, odict_move_to_end__doc__},
Eric Snow96c6af92015-05-29 22:21:39 -06001408
1409 {NULL, NULL} /* sentinel */
1410};
1411
1412
1413/* ----------------------------------------------
1414 * OrderedDict members
1415 */
1416
1417/* tp_members */
1418
1419static PyMemberDef odict_members[] = {
1420 {"__dict__", T_OBJECT, offsetof(PyODictObject, od_inst_dict), READONLY},
1421 {0}
1422};
1423
1424
1425/* ----------------------------------------------
1426 * OrderedDict type slot methods
1427 */
1428
1429/* tp_dealloc */
1430
1431static void
1432odict_dealloc(PyODictObject *self)
1433{
1434 PyObject_GC_UnTrack(self);
1435 Py_TRASHCAN_SAFE_BEGIN(self);
1436 Py_XDECREF(self->od_inst_dict);
1437 if (self->od_weakreflist != NULL)
1438 PyObject_ClearWeakRefs((PyObject *)self);
1439
1440 _odict_clear_nodes(self);
1441 Py_TRASHCAN_SAFE_END(self);
1442
1443 /* must be last */
1444 PyDict_Type.tp_dealloc((PyObject *)self);
1445};
1446
1447/* tp_repr */
1448
1449static PyObject *
1450odict_repr(PyODictObject *self)
1451{
1452 int i;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001453 _Py_IDENTIFIER(items);
Eric Snow96c6af92015-05-29 22:21:39 -06001454 Py_ssize_t count = -1;
Serhiy Storchaka4575beb2015-10-22 20:18:24 +03001455 PyObject *pieces = NULL, *result = NULL;
1456 const char *classname;
1457
1458 classname = strrchr(Py_TYPE(self)->tp_name, '.');
1459 if (classname == NULL)
1460 classname = Py_TYPE(self)->tp_name;
1461 else
1462 classname++;
1463
1464 if (PyODict_SIZE(self) == 0)
1465 return PyUnicode_FromFormat("%s()", classname);
Eric Snow96c6af92015-05-29 22:21:39 -06001466
1467 i = Py_ReprEnter((PyObject *)self);
1468 if (i != 0) {
1469 return i > 0 ? PyUnicode_FromString("...") : NULL;
1470 }
1471
Eric Snow96c6af92015-05-29 22:21:39 -06001472 if (PyODict_CheckExact(self)) {
Eric Snowa762af72015-06-01 22:59:08 -06001473 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001474 pieces = PyList_New(PyODict_SIZE(self));
1475 if (pieces == NULL)
1476 goto Done;
1477
1478 _odict_FOREACH(self, node) {
Eric Snowa762af72015-06-01 22:59:08 -06001479 PyObject *pair;
1480 PyObject *key = _odictnode_KEY(node);
1481 PyObject *value = _odictnode_VALUE(node, self);
1482 if (value == NULL) {
1483 if (!PyErr_Occurred())
1484 PyErr_SetObject(PyExc_KeyError, key);
Eric Snowdb4061c2015-06-03 11:09:48 -06001485 goto Done;
Eric Snowa762af72015-06-01 22:59:08 -06001486 }
1487 pair = PyTuple_Pack(2, key, value);
Eric Snow96c6af92015-05-29 22:21:39 -06001488 if (pair == NULL)
1489 goto Done;
1490
1491 PyList_SET_ITEM(pieces, ++count, pair); /* steals reference */
1492 }
1493 }
1494 else {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001495 PyObject *items = _PyObject_CallMethodIdObjArgs((PyObject *)self,
1496 &PyId_items, NULL);
Eric Snow96c6af92015-05-29 22:21:39 -06001497 if (items == NULL)
1498 goto Done;
1499 pieces = PySequence_List(items);
1500 Py_DECREF(items);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001501 if (pieces == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -06001502 goto Done;
1503 }
1504
Serhiy Storchaka4575beb2015-10-22 20:18:24 +03001505 result = PyUnicode_FromFormat("%s(%R)", classname, pieces);
Eric Snow96c6af92015-05-29 22:21:39 -06001506
Eric Snow96c6af92015-05-29 22:21:39 -06001507Done:
1508 Py_XDECREF(pieces);
Eric Snow96c6af92015-05-29 22:21:39 -06001509 Py_ReprLeave((PyObject *)self);
1510 return result;
1511};
1512
1513/* tp_doc */
1514
1515PyDoc_STRVAR(odict_doc,
1516 "Dictionary that remembers insertion order");
1517
1518/* tp_traverse */
1519
1520static int
1521odict_traverse(PyODictObject *od, visitproc visit, void *arg)
1522{
1523 Py_VISIT(od->od_inst_dict);
1524 Py_VISIT(od->od_weakreflist);
1525 return PyDict_Type.tp_traverse((PyObject *)od, visit, arg);
1526}
1527
1528/* tp_clear */
1529
1530static int
1531odict_tp_clear(PyODictObject *od)
1532{
1533 PyObject *res;
1534 Py_CLEAR(od->od_inst_dict);
1535 Py_CLEAR(od->od_weakreflist);
1536 res = odict_clear(od);
1537 if (res == NULL)
1538 return -1;
1539 Py_DECREF(res);
1540 return 0;
1541}
1542
1543/* tp_richcompare */
1544
1545static PyObject *
1546odict_richcompare(PyObject *v, PyObject *w, int op)
1547{
1548 if (!PyODict_Check(v) || !PyDict_Check(w)) {
1549 Py_RETURN_NOTIMPLEMENTED;
1550 }
1551
1552 if (op == Py_EQ || op == Py_NE) {
1553 PyObject *res, *cmp;
1554 int eq;
1555
1556 cmp = PyDict_Type.tp_richcompare(v, w, op);
1557 if (cmp == NULL)
1558 return NULL;
1559 if (!PyODict_Check(w))
1560 return cmp;
1561 if (op == Py_EQ && cmp == Py_False)
1562 return cmp;
1563 if (op == Py_NE && cmp == Py_True)
1564 return cmp;
1565 Py_DECREF(cmp);
1566
1567 /* Try comparing odict keys. */
1568 eq = _odict_keys_equal((PyODictObject *)v, (PyODictObject *)w);
1569 if (eq < 0)
1570 return NULL;
1571
1572 res = (eq == (op == Py_EQ)) ? Py_True : Py_False;
1573 Py_INCREF(res);
1574 return res;
1575 } else {
1576 Py_RETURN_NOTIMPLEMENTED;
1577 }
1578};
1579
1580/* tp_iter */
1581
1582static PyObject *
1583odict_iter(PyODictObject *od)
1584{
1585 return odictiter_new(od, _odict_ITER_KEYS);
1586};
1587
1588/* tp_init */
1589
1590static int
1591odict_init(PyObject *self, PyObject *args, PyObject *kwds)
1592{
1593 PyObject *res;
1594 Py_ssize_t len = PyObject_Length(args);
1595
1596 if (len == -1)
1597 return -1;
1598 if (len > 1) {
1599 char *msg = "expected at most 1 arguments, got %d";
1600 PyErr_Format(PyExc_TypeError, msg, len);
1601 return -1;
1602 }
1603
1604 /* __init__() triggering update() is just the way things are! */
1605 res = odict_update(self, args, kwds);
1606 if (res == NULL) {
1607 return -1;
1608 } else {
1609 Py_DECREF(res);
1610 return 0;
1611 }
1612};
1613
1614/* tp_new */
1615
1616static PyObject *
1617odict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1618{
Victor Stinnerca30b022015-09-03 17:50:04 +02001619 PyObject *dict;
1620 PyODictObject *od;
1621
1622 dict = PyDict_New();
1623 if (dict == NULL)
1624 return NULL;
1625
1626 od = (PyODictObject *)PyDict_Type.tp_new(type, args, kwds);
1627 if (od == NULL) {
1628 Py_DECREF(dict);
1629 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001630 }
Victor Stinnerca30b022015-09-03 17:50:04 +02001631
1632 od->od_inst_dict = dict;
1633 /* type constructor fills the memory with zeros (see
1634 PyType_GenericAlloc()), there is no need to set them to zero again */
1635 if (_odict_resize(od) < 0) {
1636 Py_DECREF(od);
1637 return NULL;
1638 }
1639
1640 return (PyObject*)od;
Eric Snow96c6af92015-05-29 22:21:39 -06001641}
1642
1643/* PyODict_Type */
1644
1645PyTypeObject PyODict_Type = {
1646 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1647 "collections.OrderedDict", /* tp_name */
1648 sizeof(PyODictObject), /* tp_basicsize */
1649 0, /* tp_itemsize */
1650 (destructor)odict_dealloc, /* tp_dealloc */
1651 0, /* tp_print */
1652 0, /* tp_getattr */
1653 0, /* tp_setattr */
1654 0, /* tp_reserved */
1655 (reprfunc)odict_repr, /* tp_repr */
1656 0, /* tp_as_number */
1657 0, /* tp_as_sequence */
1658 &odict_as_mapping, /* tp_as_mapping */
1659 0, /* tp_hash */
1660 0, /* tp_call */
1661 0, /* tp_str */
1662 0, /* tp_getattro */
1663 0, /* tp_setattro */
1664 0, /* tp_as_buffer */
1665 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,/* tp_flags */
1666 odict_doc, /* tp_doc */
1667 (traverseproc)odict_traverse, /* tp_traverse */
1668 (inquiry)odict_tp_clear, /* tp_clear */
1669 (richcmpfunc)odict_richcompare, /* tp_richcompare */
1670 offsetof(PyODictObject, od_weakreflist), /* tp_weaklistoffset */
1671 (getiterfunc)odict_iter, /* tp_iter */
1672 0, /* tp_iternext */
1673 odict_methods, /* tp_methods */
1674 odict_members, /* tp_members */
1675 0, /* tp_getset */
1676 &PyDict_Type, /* tp_base */
1677 0, /* tp_dict */
1678 0, /* tp_descr_get */
1679 0, /* tp_descr_set */
1680 offsetof(PyODictObject, od_inst_dict), /* tp_dictoffset */
1681 (initproc)odict_init, /* tp_init */
1682 PyType_GenericAlloc, /* tp_alloc */
1683 (newfunc)odict_new, /* tp_new */
1684 0, /* tp_free */
1685};
1686
1687
1688/* ----------------------------------------------
1689 * the public OrderedDict API
1690 */
1691
1692PyObject *
1693PyODict_New(void) {
1694 return odict_new(&PyODict_Type, NULL, NULL);
1695};
1696
1697int
1698PyODict_SetItem(PyObject *od, PyObject *key, PyObject *value) {
1699 int res = PyDict_SetItem(od, key, value);
1700 if (res == 0) {
1701 res = _odict_add_new_node((PyODictObject *)od, key);
Eric Snowc5e59602015-05-30 11:28:56 -06001702 /* XXX Revert setting the value on the dict? */
Eric Snow96c6af92015-05-29 22:21:39 -06001703 }
1704 return res;
1705};
1706
1707int
1708PyODict_DelItem(PyObject *od, PyObject *key) {
1709 int res = _odict_clear_node((PyODictObject *)od, NULL, key);
1710 if (res < 0)
1711 return -1;
1712 return PyDict_DelItem(od, key);
1713};
1714
1715
1716/* -------------------------------------------
1717 * The OrderedDict views (keys/values/items)
1718 */
1719
1720typedef struct {
1721 PyObject_HEAD
1722 int kind;
1723 PyODictObject *di_odict;
Eric Snowb952ab42015-06-01 23:35:13 -06001724 Py_ssize_t di_size;
Eric Snow4fabf022015-06-04 00:09:56 -06001725 size_t di_state;
Eric Snow96c6af92015-05-29 22:21:39 -06001726 PyObject *di_current;
1727 PyObject *di_result; /* reusable result tuple for iteritems */
1728} odictiterobject;
1729
1730static void
1731odictiter_dealloc(odictiterobject *di)
1732{
1733 _PyObject_GC_UNTRACK(di);
Eric Snowa762af72015-06-01 22:59:08 -06001734 Py_XDECREF(di->di_odict);
Eric Snow96c6af92015-05-29 22:21:39 -06001735 Py_XDECREF(di->di_current);
1736 if (di->kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)) {
1737 Py_DECREF(di->di_result);
1738 }
1739 PyObject_GC_Del(di);
1740}
1741
1742static int
1743odictiter_traverse(odictiterobject *di, visitproc visit, void *arg)
1744{
1745 Py_VISIT(di->di_odict);
1746 Py_VISIT(di->di_current); /* A key could be any type, not just str. */
1747 Py_VISIT(di->di_result);
1748 return 0;
1749}
1750
Eric Snowa762af72015-06-01 22:59:08 -06001751/* In order to protect against modifications during iteration, we track
1752 * the current key instead of the current node. */
Eric Snow96c6af92015-05-29 22:21:39 -06001753static PyObject *
1754odictiter_nextkey(odictiterobject *di)
1755{
Eric Snowa762af72015-06-01 22:59:08 -06001756 PyObject *key = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001757 _ODictNode *node;
1758 int reversed = di->kind & _odict_ITER_REVERSED;
1759
Eric Snowa762af72015-06-01 22:59:08 -06001760 if (di->di_odict == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -06001761 return NULL;
Eric Snowa762af72015-06-01 22:59:08 -06001762 if (di->di_current == NULL)
1763 goto done; /* We're already done. */
1764
Eric Snowb952ab42015-06-01 23:35:13 -06001765 /* Check for unsupported changes. */
Eric Snow4fabf022015-06-04 00:09:56 -06001766 if (di->di_odict->od_state != di->di_state) {
1767 PyErr_SetString(PyExc_RuntimeError,
1768 "OrderedDict mutated during iteration");
1769 goto done;
1770 }
Eric Snowb952ab42015-06-01 23:35:13 -06001771 if (di->di_size != PyODict_SIZE(di->di_odict)) {
1772 PyErr_SetString(PyExc_RuntimeError,
1773 "OrderedDict changed size during iteration");
1774 di->di_size = -1; /* Make this state sticky */
1775 return NULL;
1776 }
1777
Eric Snowa762af72015-06-01 22:59:08 -06001778 /* Get the key. */
Eric Snow96c6af92015-05-29 22:21:39 -06001779 node = _odict_find_node(di->di_odict, di->di_current);
1780 if (node == NULL) {
1781 /* Must have been deleted. */
Eric Snowe3dfa9e2015-05-30 12:51:15 -06001782 Py_CLEAR(di->di_current);
Eric Snow96c6af92015-05-29 22:21:39 -06001783 return NULL;
1784 }
1785 key = di->di_current;
1786
1787 /* Advance to the next key. */
1788 node = reversed ? _odictnode_PREV(node) : _odictnode_NEXT(node);
1789 if (node == NULL) {
1790 /* Reached the end. */
1791 di->di_current = NULL;
1792 }
1793 else {
1794 di->di_current = _odictnode_KEY(node);
1795 Py_INCREF(di->di_current);
1796 }
1797
1798 return key;
Eric Snowa762af72015-06-01 22:59:08 -06001799
1800done:
1801 Py_CLEAR(di->di_odict);
1802 return key;
Eric Snow96c6af92015-05-29 22:21:39 -06001803}
1804
1805static PyObject *
1806odictiter_iternext(odictiterobject *di)
1807{
1808 PyObject *value;
1809 PyObject *key = odictiter_nextkey(di); /* new reference */
1810
1811 if (key == NULL)
1812 return NULL;
1813
1814 /* Handle the keys case. */
1815 if (! (di->kind & _odict_ITER_VALUES)) {
1816 return key;
1817 }
1818
1819 /* Handle the items case. */
1820 if (di->kind & _odict_ITER_KEYS) {
1821 PyObject *result = di->di_result;
1822
1823 value = PyODict_GetItem((PyObject *)di->di_odict, key); /* borrowed */
Eric Snowe3dfa9e2015-05-30 12:51:15 -06001824 if (value == NULL) {
Eric Snowa762af72015-06-01 22:59:08 -06001825 if (!PyErr_Occurred())
1826 PyErr_SetObject(PyExc_KeyError, key);
Eric Snowe3dfa9e2015-05-30 12:51:15 -06001827 Py_DECREF(key);
Eric Snowa762af72015-06-01 22:59:08 -06001828 goto done;
Eric Snowe3dfa9e2015-05-30 12:51:15 -06001829 }
1830 Py_INCREF(value);
Eric Snow96c6af92015-05-29 22:21:39 -06001831
1832 if (result->ob_refcnt == 1) {
1833 /* not in use so we can reuse it
1834 * (the common case during iteration) */
1835 Py_INCREF(result);
1836 Py_DECREF(PyTuple_GET_ITEM(result, 0)); /* borrowed */
1837 Py_DECREF(PyTuple_GET_ITEM(result, 1)); /* borrowed */
1838 }
1839 else {
1840 result = PyTuple_New(2);
Eric Snowe3dfa9e2015-05-30 12:51:15 -06001841 if (result == NULL) {
1842 Py_DECREF(key);
1843 Py_DECREF(value);
Eric Snowa762af72015-06-01 22:59:08 -06001844 goto done;
Eric Snowe3dfa9e2015-05-30 12:51:15 -06001845 }
Eric Snow96c6af92015-05-29 22:21:39 -06001846 }
1847
Eric Snow96c6af92015-05-29 22:21:39 -06001848 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
1849 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
1850
1851 return result;
1852 }
1853 /* Handle the values case. */
1854 else {
1855 value = PyODict_GetItem((PyObject *)di->di_odict, key);
Eric Snow96c6af92015-05-29 22:21:39 -06001856 Py_DECREF(key);
Eric Snowa762af72015-06-01 22:59:08 -06001857 if (value == NULL) {
1858 if (!PyErr_Occurred())
1859 PyErr_SetObject(PyExc_KeyError, key);
1860 goto done;
1861 }
1862 Py_INCREF(value);
Eric Snow96c6af92015-05-29 22:21:39 -06001863 return value;
1864 }
Eric Snowa762af72015-06-01 22:59:08 -06001865
1866done:
1867 Py_CLEAR(di->di_current);
1868 Py_CLEAR(di->di_odict);
1869 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001870}
1871
1872/* No need for tp_clear because odictiterobject is not mutable. */
1873
1874PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
1875
1876static PyObject *
1877odictiter_reduce(odictiterobject *di)
1878{
Eric Snowc5e59602015-05-30 11:28:56 -06001879 PyObject *list, *iter;
Eric Snow96c6af92015-05-29 22:21:39 -06001880
1881 list = PyList_New(0);
1882 if (!list)
1883 return NULL;
1884
1885 /* iterate the temporary into a list */
1886 for(;;) {
1887 PyObject *element = odictiter_iternext(di);
1888 if (element) {
1889 if (PyList_Append(list, element)) {
1890 Py_DECREF(element);
1891 Py_DECREF(list);
1892 return NULL;
1893 }
1894 Py_DECREF(element);
1895 }
1896 else {
1897 /* done iterating? */
1898 break;
1899 }
1900 }
1901 if (PyErr_Occurred()) {
1902 Py_DECREF(list);
1903 return NULL;
1904 }
Eric Snowc5e59602015-05-30 11:28:56 -06001905 iter = _PyObject_GetBuiltin("iter");
1906 if (iter == NULL) {
1907 Py_DECREF(list);
1908 return NULL;
1909 }
1910 return Py_BuildValue("N(N)", iter, list);
Eric Snow96c6af92015-05-29 22:21:39 -06001911}
1912
1913static PyMethodDef odictiter_methods[] = {
1914 {"__reduce__", (PyCFunction)odictiter_reduce, METH_NOARGS, reduce_doc},
1915 {NULL, NULL} /* sentinel */
1916};
1917
1918PyTypeObject PyODictIter_Type = {
1919 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1920 "odict_iterator", /* tp_name */
1921 sizeof(odictiterobject), /* tp_basicsize */
1922 0, /* tp_itemsize */
1923 /* methods */
1924 (destructor)odictiter_dealloc, /* tp_dealloc */
1925 0, /* tp_print */
1926 0, /* tp_getattr */
1927 0, /* tp_setattr */
1928 0, /* tp_reserved */
1929 0, /* tp_repr */
1930 0, /* tp_as_number */
1931 0, /* tp_as_sequence */
1932 0, /* tp_as_mapping */
1933 0, /* tp_hash */
1934 0, /* tp_call */
1935 0, /* tp_str */
1936 PyObject_GenericGetAttr, /* tp_getattro */
1937 0, /* tp_setattro */
1938 0, /* tp_as_buffer */
1939 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1940 0, /* tp_doc */
1941 (traverseproc)odictiter_traverse, /* tp_traverse */
1942 0, /* tp_clear */
1943 0, /* tp_richcompare */
1944 0, /* tp_weaklistoffset */
1945 PyObject_SelfIter, /* tp_iter */
1946 (iternextfunc)odictiter_iternext, /* tp_iternext */
1947 odictiter_methods, /* tp_methods */
1948 0,
1949};
1950
1951static PyObject *
1952odictiter_new(PyODictObject *od, int kind)
1953{
1954 odictiterobject *di;
1955 _ODictNode *node;
1956 int reversed = kind & _odict_ITER_REVERSED;
1957
1958 di = PyObject_GC_New(odictiterobject, &PyODictIter_Type);
1959 if (di == NULL)
1960 return NULL;
1961
1962 if (kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)){
1963 di->di_result = PyTuple_Pack(2, Py_None, Py_None);
1964 if (di->di_result == NULL) {
1965 Py_DECREF(di);
1966 return NULL;
1967 }
1968 }
1969 else
1970 di->di_result = NULL;
1971
1972 di->kind = kind;
1973 node = reversed ? _odict_LAST(od) : _odict_FIRST(od);
1974 di->di_current = node ? _odictnode_KEY(node) : NULL;
1975 Py_XINCREF(di->di_current);
Eric Snowb952ab42015-06-01 23:35:13 -06001976 di->di_size = PyODict_SIZE(od);
Eric Snow4fabf022015-06-04 00:09:56 -06001977 di->di_state = od->od_state;
Eric Snow96c6af92015-05-29 22:21:39 -06001978 di->di_odict = od;
1979 Py_INCREF(od);
1980
1981 _PyObject_GC_TRACK(di);
1982 return (PyObject *)di;
1983}
1984
1985/* keys() */
1986
1987static PyObject *
1988odictkeys_iter(_PyDictViewObject *dv)
1989{
1990 if (dv->dv_dict == NULL) {
1991 Py_RETURN_NONE;
1992 }
1993 return odictiter_new((PyODictObject *)dv->dv_dict,
1994 _odict_ITER_KEYS);
1995}
1996
1997static PyObject *
1998odictkeys_reversed(_PyDictViewObject *dv)
1999{
2000 if (dv->dv_dict == NULL) {
2001 Py_RETURN_NONE;
2002 }
2003 return odictiter_new((PyODictObject *)dv->dv_dict,
2004 _odict_ITER_KEYS|_odict_ITER_REVERSED);
2005}
2006
2007static PyMethodDef odictkeys_methods[] = {
2008 {"__reversed__", (PyCFunction)odictkeys_reversed, METH_NOARGS, NULL},
2009 {NULL, NULL} /* sentinel */
2010};
2011
2012PyTypeObject PyODictKeys_Type = {
2013 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2014 "odict_keys", /* tp_name */
2015 0, /* tp_basicsize */
2016 0, /* tp_itemsize */
2017 0, /* tp_dealloc */
2018 0, /* tp_print */
2019 0, /* tp_getattr */
2020 0, /* tp_setattr */
2021 0, /* tp_reserved */
2022 0, /* tp_repr */
2023 0, /* tp_as_number */
2024 0, /* tp_as_sequence */
2025 0, /* tp_as_mapping */
2026 0, /* tp_hash */
2027 0, /* tp_call */
2028 0, /* tp_str */
2029 0, /* tp_getattro */
2030 0, /* tp_setattro */
2031 0, /* tp_as_buffer */
2032 0, /* tp_flags */
2033 0, /* tp_doc */
2034 0, /* tp_traverse */
2035 0, /* tp_clear */
2036 0, /* tp_richcompare */
2037 0, /* tp_weaklistoffset */
2038 (getiterfunc)odictkeys_iter, /* tp_iter */
2039 0, /* tp_iternext */
2040 odictkeys_methods, /* tp_methods */
2041 0, /* tp_members */
2042 0, /* tp_getset */
2043 &PyDictKeys_Type, /* tp_base */
2044};
2045
2046static PyObject *
2047odictkeys_new(PyObject *od)
2048{
2049 return _PyDictView_New(od, &PyODictKeys_Type);
2050}
2051
2052/* items() */
2053
2054static PyObject *
2055odictitems_iter(_PyDictViewObject *dv)
2056{
2057 if (dv->dv_dict == NULL) {
2058 Py_RETURN_NONE;
2059 }
2060 return odictiter_new((PyODictObject *)dv->dv_dict,
2061 _odict_ITER_KEYS|_odict_ITER_VALUES);
2062}
2063
2064static PyObject *
2065odictitems_reversed(_PyDictViewObject *dv)
2066{
2067 if (dv->dv_dict == NULL) {
2068 Py_RETURN_NONE;
2069 }
2070 return odictiter_new((PyODictObject *)dv->dv_dict,
2071 _odict_ITER_KEYS|_odict_ITER_VALUES|_odict_ITER_REVERSED);
2072}
2073
2074static PyMethodDef odictitems_methods[] = {
2075 {"__reversed__", (PyCFunction)odictitems_reversed, METH_NOARGS, NULL},
2076 {NULL, NULL} /* sentinel */
2077};
2078
2079PyTypeObject PyODictItems_Type = {
2080 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2081 "odict_items", /* tp_name */
2082 0, /* tp_basicsize */
2083 0, /* tp_itemsize */
2084 0, /* tp_dealloc */
2085 0, /* tp_print */
2086 0, /* tp_getattr */
2087 0, /* tp_setattr */
2088 0, /* tp_reserved */
2089 0, /* tp_repr */
2090 0, /* tp_as_number */
2091 0, /* tp_as_sequence */
2092 0, /* tp_as_mapping */
2093 0, /* tp_hash */
2094 0, /* tp_call */
2095 0, /* tp_str */
2096 0, /* tp_getattro */
2097 0, /* tp_setattro */
2098 0, /* tp_as_buffer */
2099 0, /* tp_flags */
2100 0, /* tp_doc */
2101 0, /* tp_traverse */
2102 0, /* tp_clear */
2103 0, /* tp_richcompare */
2104 0, /* tp_weaklistoffset */
2105 (getiterfunc)odictitems_iter, /* tp_iter */
2106 0, /* tp_iternext */
2107 odictitems_methods, /* tp_methods */
2108 0, /* tp_members */
2109 0, /* tp_getset */
2110 &PyDictItems_Type, /* tp_base */
2111};
2112
2113static PyObject *
2114odictitems_new(PyObject *od)
2115{
2116 return _PyDictView_New(od, &PyODictItems_Type);
2117}
2118
2119/* values() */
2120
2121static PyObject *
2122odictvalues_iter(_PyDictViewObject *dv)
2123{
2124 if (dv->dv_dict == NULL) {
2125 Py_RETURN_NONE;
2126 }
2127 return odictiter_new((PyODictObject *)dv->dv_dict,
2128 _odict_ITER_VALUES);
2129}
2130
2131static PyObject *
2132odictvalues_reversed(_PyDictViewObject *dv)
2133{
2134 if (dv->dv_dict == NULL) {
2135 Py_RETURN_NONE;
2136 }
2137 return odictiter_new((PyODictObject *)dv->dv_dict,
2138 _odict_ITER_VALUES|_odict_ITER_REVERSED);
2139}
2140
2141static PyMethodDef odictvalues_methods[] = {
2142 {"__reversed__", (PyCFunction)odictvalues_reversed, METH_NOARGS, NULL},
2143 {NULL, NULL} /* sentinel */
2144};
2145
2146PyTypeObject PyODictValues_Type = {
2147 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2148 "odict_values", /* tp_name */
2149 0, /* tp_basicsize */
2150 0, /* tp_itemsize */
2151 0, /* tp_dealloc */
2152 0, /* tp_print */
2153 0, /* tp_getattr */
2154 0, /* tp_setattr */
2155 0, /* tp_reserved */
2156 0, /* tp_repr */
2157 0, /* tp_as_number */
2158 0, /* tp_as_sequence */
2159 0, /* tp_as_mapping */
2160 0, /* tp_hash */
2161 0, /* tp_call */
2162 0, /* tp_str */
2163 0, /* tp_getattro */
2164 0, /* tp_setattro */
2165 0, /* tp_as_buffer */
2166 0, /* tp_flags */
2167 0, /* tp_doc */
2168 0, /* tp_traverse */
2169 0, /* tp_clear */
2170 0, /* tp_richcompare */
2171 0, /* tp_weaklistoffset */
2172 (getiterfunc)odictvalues_iter, /* tp_iter */
2173 0, /* tp_iternext */
2174 odictvalues_methods, /* tp_methods */
2175 0, /* tp_members */
2176 0, /* tp_getset */
2177 &PyDictValues_Type, /* tp_base */
2178};
2179
2180static PyObject *
2181odictvalues_new(PyObject *od)
2182{
2183 return _PyDictView_New(od, &PyODictValues_Type);
2184}
2185
2186
2187/* ----------------------------------------------
2188 MutableMappping implementations
2189
2190Mapping:
2191
2192============ ===========
2193method uses
2194============ ===========
2195__contains__ __getitem__
2196__eq__ items
2197__getitem__ +
2198__iter__ +
2199__len__ +
2200__ne__ __eq__
2201get __getitem__
2202items ItemsView
2203keys KeysView
2204values ValuesView
2205============ ===========
2206
2207ItemsView uses __len__, __iter__, and __getitem__.
2208KeysView uses __len__, __iter__, and __contains__.
2209ValuesView uses __len__, __iter__, and __getitem__.
2210
2211MutableMapping:
2212
2213============ ===========
2214method uses
2215============ ===========
2216__delitem__ +
2217__setitem__ +
2218clear popitem
2219pop __getitem__
2220 __delitem__
2221popitem __iter__
2222 _getitem__
2223 __delitem__
2224setdefault __getitem__
2225 __setitem__
2226update __setitem__
2227============ ===========
2228*/
2229
2230static int
2231mutablemapping_add_pairs(PyObject *self, PyObject *pairs)
2232{
2233 PyObject *pair, *iterator, *unexpected;
2234 int res = 0;
2235
2236 iterator = PyObject_GetIter(pairs);
2237 if (iterator == NULL)
2238 return -1;
2239 PyErr_Clear();
2240
2241 while ((pair = PyIter_Next(iterator)) != NULL) {
2242 /* could be more efficient (see UNPACK_SEQUENCE in ceval.c) */
Eric Snowc5e59602015-05-30 11:28:56 -06002243 PyObject *key = NULL, *value = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06002244 PyObject *pair_iterator = PyObject_GetIter(pair);
Eric Snowc5e59602015-05-30 11:28:56 -06002245 if (pair_iterator == NULL)
2246 goto Done;
Eric Snow96c6af92015-05-29 22:21:39 -06002247
2248 key = PyIter_Next(pair_iterator);
2249 if (key == NULL) {
2250 if (!PyErr_Occurred())
2251 PyErr_SetString(PyExc_ValueError,
2252 "need more than 0 values to unpack");
2253 goto Done;
2254 }
2255
2256 value = PyIter_Next(pair_iterator);
2257 if (value == NULL) {
2258 if (!PyErr_Occurred())
2259 PyErr_SetString(PyExc_ValueError,
2260 "need more than 1 value to unpack");
2261 goto Done;
2262 }
2263
2264 unexpected = PyIter_Next(pair_iterator);
2265 if (unexpected != NULL) {
2266 Py_DECREF(unexpected);
2267 PyErr_SetString(PyExc_ValueError,
2268 "too many values to unpack (expected 2)");
2269 goto Done;
2270 }
2271 else if (PyErr_Occurred())
2272 goto Done;
2273
2274 res = PyObject_SetItem(self, key, value);
2275
2276Done:
2277 Py_DECREF(pair);
Eric Snowc5e59602015-05-30 11:28:56 -06002278 Py_XDECREF(pair_iterator);
Eric Snow96c6af92015-05-29 22:21:39 -06002279 Py_XDECREF(key);
2280 Py_XDECREF(value);
2281 if (PyErr_Occurred())
2282 break;
2283 }
2284 Py_DECREF(iterator);
2285
2286 if (res < 0 || PyErr_Occurred() != NULL)
2287 return -1;
2288 else
2289 return 0;
2290}
2291
2292static PyObject *
2293mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
2294{
2295 int res = 0;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002296 Py_ssize_t len;
2297 _Py_IDENTIFIER(items);
2298 _Py_IDENTIFIER(keys);
Eric Snow96c6af92015-05-29 22:21:39 -06002299
2300 /* first handle args, if any */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002301 assert(args == NULL || PyTuple_Check(args));
2302 len = (args != NULL) ? PyTuple_GET_SIZE(args) : 0;
Benjamin Peterson99e96f22015-06-06 23:20:32 -05002303 if (len > 1) {
Eric Snow96c6af92015-05-29 22:21:39 -06002304 char *msg = "update() takes at most 1 positional argument (%d given)";
2305 PyErr_Format(PyExc_TypeError, msg, len);
2306 return NULL;
2307 }
Eric Snow96c6af92015-05-29 22:21:39 -06002308
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002309 if (len) {
Benjamin Peterson0718de92015-06-07 00:00:42 -05002310 PyObject *other = PyTuple_GET_ITEM(args, 0); /* borrowed reference */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002311 assert(other != NULL);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002312 Py_INCREF(other);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002313 if (PyDict_CheckExact(other) ||
2314 _PyObject_HasAttrId(other, &PyId_items)) { /* never fails */
2315 PyObject *items;
2316 if (PyDict_CheckExact(other))
2317 items = PyDict_Items(other);
2318 else
2319 items = _PyObject_CallMethodId(other, &PyId_items, NULL);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002320 Py_DECREF(other);
2321 if (items == NULL)
2322 return NULL;
2323 res = mutablemapping_add_pairs(self, items);
2324 Py_DECREF(items);
2325 if (res == -1)
2326 return NULL;
2327 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002328 else if (_PyObject_HasAttrId(other, &PyId_keys)) { /* never fails */
Benjamin Peterson0718de92015-06-07 00:00:42 -05002329 PyObject *keys, *iterator, *key;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002330 keys = _PyObject_CallMethodIdObjArgs(other, &PyId_keys, NULL);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002331 if (keys == NULL) {
2332 Py_DECREF(other);
2333 return NULL;
2334 }
2335 iterator = PyObject_GetIter(keys);
2336 Py_DECREF(keys);
2337 if (iterator == NULL) {
2338 Py_DECREF(other);
2339 return NULL;
2340 }
2341 while (res == 0 && (key = PyIter_Next(iterator))) {
2342 PyObject *value = PyObject_GetItem(other, key);
2343 if (value != NULL) {
2344 res = PyObject_SetItem(self, key, value);
2345 Py_DECREF(value);
2346 }
2347 else {
2348 res = -1;
2349 }
2350 Py_DECREF(key);
2351 }
2352 Py_DECREF(other);
2353 Py_DECREF(iterator);
2354 if (res != 0 || PyErr_Occurred())
2355 return NULL;
2356 }
2357 else {
2358 res = mutablemapping_add_pairs(self, other);
2359 Py_DECREF(other);
2360 if (res != 0)
2361 return NULL;
2362 }
2363 }
2364
2365 /* now handle kwargs */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002366 assert(kwargs == NULL || PyDict_Check(kwargs));
2367 len = (kwargs != NULL) ? PyDict_Size(kwargs) : 0;
Benjamin Peterson0718de92015-06-07 00:00:42 -05002368 if (len > 0) {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002369 PyObject *items = PyDict_Items(kwargs);
Eric Snow96c6af92015-05-29 22:21:39 -06002370 if (items == NULL)
2371 return NULL;
2372 res = mutablemapping_add_pairs(self, items);
2373 Py_DECREF(items);
2374 if (res == -1)
2375 return NULL;
2376 }
Eric Snow96c6af92015-05-29 22:21:39 -06002377
2378 Py_RETURN_NONE;
2379}