blob: 1796b968bfdd3240a1a8bc6f95c84134f4d09a8b [file] [log] [blame]
Eric Snow96c6af92015-05-29 22:21:39 -06001/* Ordered Dictionary object implementation.
2
3This implementation is necessarily explicitly equivalent to the pure Python
4OrderedDict class in Lib/collections/__init__.py. The strategy there
5involves using a doubly-linked-list to capture the order. We keep to that
6strategy, using a lower-level linked-list.
7
8About the Linked-List
9=====================
10
11For the linked list we use a basic doubly-linked-list. Using a circularly-
12linked-list does have some benefits, but they don't apply so much here
13since OrderedDict is focused on the ends of the list (for the most part).
14Furthermore, there are some features of generic linked-lists that we simply
15don't need for OrderedDict. Thus a simple custom implementation meets our
16needs. Alternatives to our simple approach include the QCIRCLE_*
17macros from BSD's queue.h, and the linux's list.h.
18
19Getting O(1) Node Lookup
20------------------------
21
22One invariant of Python's OrderedDict is that it preserves time complexity
23of dict's methods, particularly the O(1) operations. Simply adding a
24linked-list on top of dict is not sufficient here; operations for nodes in
25the middle of the linked-list implicitly require finding the node first.
26With a simple linked-list like we're using, that is an O(n) operation.
27Consequently, methods like __delitem__() would change from O(1) to O(n),
28which is unacceptable.
29
30In order to preserve O(1) performance for node removal (finding nodes), we
31must do better than just looping through the linked-list. Here are options
32we've considered:
33
341. use a second dict to map keys to nodes (a la the pure Python version).
352. keep a simple hash table mirroring the order of dict's, mapping each key
36 to the corresponding node in the linked-list.
373. use a version of shared keys (split dict) that allows non-unicode keys.
384. have the value stored for each key be a (value, node) pair, and adjust
39 __getitem__(), get(), etc. accordingly.
40
41The approach with the least performance impact (time and space) is #2,
Benjamin Petersonee178e62016-09-08 11:08:30 -070042mirroring the key order of dict's dk_entries with an array of node pointers.
Eric Snow96c6af92015-05-29 22:21:39 -060043While lookdict() and friends (dk_lookup) don't give us the index into the
44array, we make use of pointer arithmetic to get that index. An alternative
45would be to refactor lookdict() to provide the index, explicitly exposing
46the implementation detail. We could even just use a custom lookup function
47for OrderedDict that facilitates our need. However, both approaches are
48significantly more complicated than just using pointer arithmetic.
49
50The catch with mirroring the hash table ordering is that we have to keep
51the ordering in sync through any dict resizes. However, that order only
52matters during node lookup. We can simply defer any potential resizing
53until we need to do a lookup.
54
55Linked-List Nodes
56-----------------
57
58The current implementation stores a pointer to the associated key only.
59One alternative would be to store a pointer to the PyDictKeyEntry instead.
60This would save one pointer de-reference per item, which is nice during
61calls to values() and items(). However, it adds unnecessary overhead
62otherwise, so we stick with just the key.
63
64Linked-List API
65---------------
66
67As noted, the linked-list implemented here does not have all the bells and
68whistles. However, we recognize that the implementation may need to
69change to accommodate performance improvements or extra functionality. To
70that end, We use a simple API to interact with the linked-list. Here's a
71summary of the methods/macros:
72
73Node info:
74
75* _odictnode_KEY(node)
76* _odictnode_VALUE(od, node)
77* _odictnode_PREV(node)
78* _odictnode_NEXT(node)
79
80Linked-List info:
81
82* _odict_FIRST(od)
83* _odict_LAST(od)
84* _odict_EMPTY(od)
85* _odict_FOREACH(od, node) - used in place of `for (node=...)`
86
87For adding nodes:
88
89* _odict_add_head(od, node)
90* _odict_add_tail(od, node)
Serhiy Storchaka19a70e72015-11-13 14:48:36 +020091* _odict_add_new_node(od, key, hash)
Eric Snow96c6af92015-05-29 22:21:39 -060092
93For removing nodes:
94
Serhiy Storchaka19a70e72015-11-13 14:48:36 +020095* _odict_clear_node(od, node, key, hash)
Eric Snow96c6af92015-05-29 22:21:39 -060096* _odict_clear_nodes(od, clear_each)
97
98Others:
99
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200100* _odict_find_node_hash(od, key, hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600101* _odict_find_node(od, key)
102* _odict_keys_equal(od1, od2)
103
104Used, but specific to the linked-list implementation:
105
106* _odict_free_fast_nodes(od)
107
108And here's a look at how the linked-list relates to the OrderedDict API:
109
110============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
111method key val prev next mem 1st last empty iter find add rmv clr keq
112============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
113__del__ ~ X
114__delitem__ free ~ node
115__eq__ ~ X
116__iter__ X X
117__new__ X X
118__reduce__ X ~ X
119__repr__ X X X
120__reversed__ X X
121__setitem__ key
122__sizeof__ size X
123clear ~ ~ X
124copy X X X
125items X X X
126keys X X
127move_to_end X X X ~ h/t key
128pop free key
129popitem X X free X X node
130setdefault ~ ? ~
131values X X
132============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
133
134__delitem__ is the only method that directly relies on finding an arbitrary
135node in the linked-list. Everything else is iteration or relates to the
136ends of the linked-list.
137
138Situation that Endangers Consistency
139------------------------------------
140Using a raw linked-list for OrderedDict exposes a key situation that can
141cause problems. If a node is stored in a variable, there is a chance that
142the node may have been deallocated before the variable gets used, thus
143potentially leading to a segmentation fault. A key place where this shows
144up is during iteration through the linked list (via _odict_FOREACH or
145otherwise).
146
147A number of solutions are available to resolve this situation:
148
149* defer looking up the node until as late as possible and certainly after
150 any code that could possibly result in a deletion;
151* if the node is needed both before and after a point where the node might
152 be removed, do a check before using the node at the "after" location to
153 see if the node is still valid;
154* like the last one, but simply pull the node again to ensure it's right;
155* keep the key in the variable instead of the node and then look up the
156 node using the key at the point where the node is needed (this is what
157 we do for the iterators).
158
159Another related problem, preserving consistent ordering during iteration,
160is described below. That one is not exclusive to using linked-lists.
161
162
163Challenges from Subclassing dict
164================================
165
166OrderedDict subclasses dict, which is an unusual relationship between two
167builtin types (other than the base object type). Doing so results in
168some complication and deserves further explanation. There are two things
169to consider here. First, in what circumstances or with what adjustments
170can OrderedDict be used as a drop-in replacement for dict (at the C level)?
171Second, how can the OrderedDict implementation leverage the dict
172implementation effectively without introducing unnecessary coupling or
173inefficiencies?
174
175This second point is reflected here and in the implementation, so the
176further focus is on the first point. It is worth noting that for
177overridden methods, the dict implementation is deferred to as much as
178possible. Furthermore, coupling is limited to as little as is reasonable.
179
180Concrete API Compatibility
181--------------------------
182
183Use of the concrete C-API for dict (PyDict_*) with OrderedDict is
184problematic. (See http://bugs.python.org/issue10977.) The concrete API
185has a number of hard-coded assumptions tied to the dict implementation.
186This is, in part, due to performance reasons, which is understandable
187given the part dict plays in Python.
188
189Any attempt to replace dict with OrderedDict for any role in the
190interpreter (e.g. **kwds) faces a challenge. Such any effort must
191recognize that the instances in affected locations currently interact with
192the concrete API.
193
194Here are some ways to address this challenge:
195
1961. Change the relevant usage of the concrete API in CPython and add
Martin Panter69332c12016-08-04 13:07:31 +0000197 PyDict_CheckExact() calls to each of the concrete API functions.
Eric Snow96c6af92015-05-29 22:21:39 -06001982. Adjust the relevant concrete API functions to explicitly accommodate
199 OrderedDict.
2003. As with #1, add the checks, but improve the abstract API with smart fast
201 paths for dict and OrderedDict, and refactor CPython to use the abstract
202 API. Improvements to the abstract API would be valuable regardless.
203
204Adding the checks to the concrete API would help make any interpreter
205switch to OrderedDict less painful for extension modules. However, this
206won't work. The equivalent C API call to `dict.__setitem__(obj, k, v)`
207is 'PyDict_SetItem(obj, k, v)`. This illustrates how subclasses in C call
208the base class's methods, since there is no equivalent of super() in the
209C API. Calling into Python for parent class API would work, but some
210extension modules already rely on this feature of the concrete API.
211
212For reference, here is a breakdown of some of the dict concrete API:
213
214========================== ============= =======================
215concrete API uses abstract API
216========================== ============= =======================
217PyDict_Check PyMapping_Check
218(PyDict_CheckExact) -
219(PyDict_New) -
220(PyDictProxy_New) -
221PyDict_Clear -
222PyDict_Contains PySequence_Contains
223PyDict_Copy -
224PyDict_SetItem PyObject_SetItem
225PyDict_SetItemString PyMapping_SetItemString
226PyDict_DelItem PyMapping_DelItem
227PyDict_DelItemString PyMapping_DelItemString
228PyDict_GetItem -
229PyDict_GetItemWithError PyObject_GetItem
230_PyDict_GetItemIdWithError -
231PyDict_GetItemString PyMapping_GetItemString
232PyDict_Items PyMapping_Items
233PyDict_Keys PyMapping_Keys
234PyDict_Values PyMapping_Values
235PyDict_Size PyMapping_Size
236 PyMapping_Length
237PyDict_Next PyIter_Next
238_PyDict_Next -
239PyDict_Merge -
240PyDict_Update -
241PyDict_MergeFromSeq2 -
242PyDict_ClearFreeList -
243- PyMapping_HasKeyString
244- PyMapping_HasKey
245========================== ============= =======================
246
247
248The dict Interface Relative to OrderedDict
249==========================================
250
251Since OrderedDict subclasses dict, understanding the various methods and
252attributes of dict is important for implementing OrderedDict.
253
254Relevant Type Slots
255-------------------
256
257================= ================ =================== ================
258slot attribute object dict
259================= ================ =================== ================
260tp_dealloc - object_dealloc dict_dealloc
261tp_repr __repr__ object_repr dict_repr
262sq_contains __contains__ - dict_contains
263mp_length __len__ - dict_length
264mp_subscript __getitem__ - dict_subscript
265mp_ass_subscript __setitem__ - dict_ass_sub
266 __delitem__
267tp_hash __hash__ _Py_HashPointer ..._HashNotImpl
268tp_str __str__ object_str -
269tp_getattro __getattribute__ ..._GenericGetAttr (repeated)
270 __getattr__
271tp_setattro __setattr__ ..._GenericSetAttr (disabled)
272tp_doc __doc__ (literal) dictionary_doc
273tp_traverse - - dict_traverse
274tp_clear - - dict_tp_clear
275tp_richcompare __eq__ object_richcompare dict_richcompare
276 __ne__
277tp_weaklistoffset (__weakref__) - -
278tp_iter __iter__ - dict_iter
279tp_dictoffset (__dict__) - -
280tp_init __init__ object_init dict_init
281tp_alloc - PyType_GenericAlloc (repeated)
282tp_new __new__ object_new dict_new
283tp_free - PyObject_Del PyObject_GC_Del
284================= ================ =================== ================
285
286Relevant Methods
287----------------
288
289================ =================== ===============
290method object dict
291================ =================== ===============
292__reduce__ object_reduce -
293__sizeof__ object_sizeof dict_sizeof
294clear - dict_clear
295copy - dict_copy
296fromkeys - dict_fromkeys
297get - dict_get
298items - dictitems_new
299keys - dictkeys_new
300pop - dict_pop
301popitem - dict_popitem
302setdefault - dict_setdefault
303update - dict_update
304values - dictvalues_new
305================ =================== ===============
306
307
308Pure Python OrderedDict
309=======================
310
311As already noted, compatibility with the pure Python OrderedDict
312implementation is a key goal of this C implementation. To further that
313goal, here's a summary of how OrderedDict-specific methods are implemented
314in collections/__init__.py. Also provided is an indication of which
315methods directly mutate or iterate the object, as well as any relationship
316with the underlying linked-list.
317
318============= ============== == ================ === === ====
319method impl used ll uses inq mut iter
320============= ============== == ================ === === ====
321__contains__ dict - - X
322__delitem__ OrderedDict Y dict.__delitem__ X
323__eq__ OrderedDict N OrderedDict ~
324 dict.__eq__
325 __iter__
326__getitem__ dict - - X
327__iter__ OrderedDict Y - X
328__init__ OrderedDict N update
329__len__ dict - - X
330__ne__ MutableMapping - __eq__ ~
331__reduce__ OrderedDict N OrderedDict ~
332 __iter__
333 __getitem__
334__repr__ OrderedDict N __class__ ~
335 items
336__reversed__ OrderedDict Y - X
337__setitem__ OrderedDict Y __contains__ X
338 dict.__setitem__
339__sizeof__ OrderedDict Y __len__ ~
340 __dict__
341clear OrderedDict Y dict.clear X
342copy OrderedDict N __class__
343 __init__
344fromkeys OrderedDict N __setitem__
345get dict - - ~
346items MutableMapping - ItemsView X
347keys MutableMapping - KeysView X
348move_to_end OrderedDict Y - X
349pop OrderedDict N __contains__ X
350 __getitem__
351 __delitem__
352popitem OrderedDict Y dict.pop X
353setdefault OrderedDict N __contains__ ~
354 __getitem__
355 __setitem__
356update MutableMapping - __setitem__ ~
357values MutableMapping - ValuesView X
358============= ============== == ================ === === ====
359
360__reversed__ and move_to_end are both exclusive to OrderedDict.
361
362
363C OrderedDict Implementation
364============================
365
366================= ================
367slot impl
368================= ================
369tp_dealloc odict_dealloc
370tp_repr odict_repr
371mp_ass_subscript odict_ass_sub
372tp_doc odict_doc
373tp_traverse odict_traverse
374tp_clear odict_tp_clear
375tp_richcompare odict_richcompare
376tp_weaklistoffset (offset)
377tp_iter odict_iter
378tp_dictoffset (offset)
379tp_init odict_init
380tp_alloc (repeated)
381tp_new odict_new
382================= ================
383
384================= ================
385method impl
386================= ================
387__reduce__ odict_reduce
388__sizeof__ odict_sizeof
389clear odict_clear
390copy odict_copy
391fromkeys odict_fromkeys
392items odictitems_new
393keys odictkeys_new
394pop odict_pop
395popitem odict_popitem
396setdefault odict_setdefault
397update odict_update
398values odictvalues_new
399================= ================
400
401Inherited unchanged from object/dict:
402
403================ ==========================
404method type field
405================ ==========================
406- tp_free
407__contains__ tp_as_sequence.sq_contains
408__getattr__ tp_getattro
409__getattribute__ tp_getattro
410__getitem__ tp_as_mapping.mp_subscript
411__hash__ tp_hash
412__len__ tp_as_mapping.mp_length
413__setattr__ tp_setattro
414__str__ tp_str
415get -
416================ ==========================
417
418
419Other Challenges
420================
421
422Preserving Ordering During Iteration
423------------------------------------
424During iteration through an OrderedDict, it is possible that items could
425get added, removed, or reordered. For a linked-list implementation, as
426with some other implementations, that situation may lead to undefined
427behavior. The documentation for dict mentions this in the `iter()` section
428of http://docs.python.org/3.4/library/stdtypes.html#dictionary-view-objects.
429In this implementation we follow dict's lead (as does the pure Python
430implementation) for __iter__(), keys(), values(), and items().
431
432For internal iteration (using _odict_FOREACH or not), there is still the
433risk that not all nodes that we expect to be seen in the loop actually get
434seen. Thus, we are careful in each of those places to ensure that they
435are. This comes, of course, at a small price at each location. The
436solutions are much the same as those detailed in the `Situation that
437Endangers Consistency` section above.
438
439
440Potential Optimizations
441=======================
442
443* Allocate the nodes as a block via od_fast_nodes instead of individually.
444 - Set node->key to NULL to indicate the node is not-in-use.
445 - Add _odict_EXISTS()?
446 - How to maintain consistency across resizes? Existing node pointers
447 would be invalidate after a resize, which is particularly problematic
448 for the iterators.
449* Use a more stream-lined implementation of update() and, likely indirectly,
450 __init__().
451
452*/
453
454/* TODO
455
456sooner:
457- reentrancy (make sure everything is at a thread-safe state when calling
458 into Python). I've already checked this multiple times, but want to
459 make one more pass.
460- add unit tests for reentrancy?
461
462later:
463- make the dict views support the full set API (the pure Python impl does)
464- implement a fuller MutableMapping API in C?
465- move the MutableMapping implementation to abstract.c?
466- optimize mutablemapping_update
467- use PyObject_MALLOC (small object allocator) for odict nodes?
468- support subclasses better (e.g. in odict_richcompare)
469
470*/
471
472#include "Python.h"
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600473#include "internal/pystate.h"
Eric Snow96c6af92015-05-29 22:21:39 -0600474#include "structmember.h"
475#include "dict-common.h"
476#include <stddef.h>
477
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100478#include "clinic/odictobject.c.h"
479
480/*[clinic input]
481class OrderedDict "PyODictObject *" "&PyODict_Type"
482[clinic start generated code]*/
483/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ca0641cf6143d4af]*/
484
Eric Snow96c6af92015-05-29 22:21:39 -0600485
486typedef struct _odictnode _ODictNode;
487
488/* PyODictObject */
489struct _odictobject {
Eric Snow4fabf022015-06-04 00:09:56 -0600490 PyDictObject od_dict; /* the underlying dict */
491 _ODictNode *od_first; /* first node in the linked list, if any */
492 _ODictNode *od_last; /* last node in the linked list, if any */
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200493 /* od_fast_nodes, od_fast_nodes_size and od_resize_sentinel are managed
494 * by _odict_resize().
Eric Snow8c7f9552015-08-07 17:45:12 -0600495 * Note that we rely on implementation details of dict for both. */
496 _ODictNode **od_fast_nodes; /* hash table that mirrors the dict table */
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200497 Py_ssize_t od_fast_nodes_size;
498 void *od_resize_sentinel; /* changes if odict should be resized */
Eric Snow8c7f9552015-08-07 17:45:12 -0600499
Eric Snow4fabf022015-06-04 00:09:56 -0600500 size_t od_state; /* incremented whenever the LL changes */
501 PyObject *od_inst_dict; /* OrderedDict().__dict__ */
502 PyObject *od_weakreflist; /* holds weakrefs to the odict */
Eric Snow96c6af92015-05-29 22:21:39 -0600503};
504
505
506/* ----------------------------------------------
507 * odict keys (a simple doubly-linked list)
508 */
509
510struct _odictnode {
511 PyObject *key;
Eric Snow4c729182015-06-03 10:50:37 -0600512 Py_hash_t hash;
Eric Snow96c6af92015-05-29 22:21:39 -0600513 _ODictNode *next;
514 _ODictNode *prev;
515};
516
517#define _odictnode_KEY(node) \
518 (node->key)
Eric Snow4c729182015-06-03 10:50:37 -0600519#define _odictnode_HASH(node) \
520 (node->hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600521/* borrowed reference */
522#define _odictnode_VALUE(node, od) \
Eric Snowa762af72015-06-01 22:59:08 -0600523 PyODict_GetItemWithError((PyObject *)od, _odictnode_KEY(node))
Eric Snow96c6af92015-05-29 22:21:39 -0600524#define _odictnode_PREV(node) (node->prev)
525#define _odictnode_NEXT(node) (node->next)
526
527#define _odict_FIRST(od) (((PyODictObject *)od)->od_first)
528#define _odict_LAST(od) (((PyODictObject *)od)->od_last)
529#define _odict_EMPTY(od) (_odict_FIRST(od) == NULL)
530#define _odict_FOREACH(od, node) \
531 for (node = _odict_FIRST(od); node != NULL; node = _odictnode_NEXT(node))
532
Eric Snow8c7f9552015-08-07 17:45:12 -0600533#define _odict_FAST_SIZE(od) ((PyDictObject *)od)->ma_keys->dk_size
Eric Snow96c6af92015-05-29 22:21:39 -0600534
Eric Snow96c6af92015-05-29 22:21:39 -0600535static void
536_odict_free_fast_nodes(PyODictObject *od) {
537 if (od->od_fast_nodes) {
538 PyMem_FREE(od->od_fast_nodes);
539 }
540}
541
Eric Snow4c729182015-06-03 10:50:37 -0600542/* Return the index into the hash table, regardless of a valid node. */
543static Py_ssize_t
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200544_odict_get_index_raw(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow4c729182015-06-03 10:50:37 -0600545{
INADA Naokiba609772016-12-07 20:41:42 +0900546 PyObject *value = NULL;
Eric Snow4c729182015-06-03 10:50:37 -0600547 PyDictKeysObject *keys = ((PyDictObject *)od)->ma_keys;
Victor Stinner742da042016-09-07 17:40:12 -0700548 Py_ssize_t ix;
Eric Snow4c729182015-06-03 10:50:37 -0600549
INADA Naoki778928b2017-08-03 23:45:15 +0900550 ix = (keys->dk_lookup)((PyDictObject *)od, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -0700551 if (ix == DKIX_EMPTY) {
552 return keys->dk_nentries; /* index of new entry */
553 }
554 if (ix < 0)
Eric Snow4c729182015-06-03 10:50:37 -0600555 return -1;
556 /* We use pointer arithmetic to get the entry's index into the table. */
Victor Stinner742da042016-09-07 17:40:12 -0700557 return ix;
Eric Snow4c729182015-06-03 10:50:37 -0600558}
559
560/* Replace od->od_fast_nodes with a new table matching the size of dict's. */
Eric Snow96c6af92015-05-29 22:21:39 -0600561static int
562_odict_resize(PyODictObject *od) {
Eric Snow4c729182015-06-03 10:50:37 -0600563 Py_ssize_t size, i;
Eric Snow96c6af92015-05-29 22:21:39 -0600564 _ODictNode **fast_nodes, *node;
565
566 /* Initialize a new "fast nodes" table. */
567 size = ((PyDictObject *)od)->ma_keys->dk_size;
568 fast_nodes = PyMem_NEW(_ODictNode *, size);
569 if (fast_nodes == NULL) {
570 PyErr_NoMemory();
571 return -1;
572 }
573 for (i = 0; i < size; i++)
574 fast_nodes[i] = NULL;
575
576 /* Copy the current nodes into the table. */
Eric Snow96c6af92015-05-29 22:21:39 -0600577 _odict_FOREACH(od, node) {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200578 i = _odict_get_index_raw(od, _odictnode_KEY(node),
Victor Stinner742da042016-09-07 17:40:12 -0700579 _odictnode_HASH(node));
Eric Snow96c6af92015-05-29 22:21:39 -0600580 if (i < 0) {
Eric Snow96c6af92015-05-29 22:21:39 -0600581 PyMem_FREE(fast_nodes);
582 return -1;
583 }
584 fast_nodes[i] = node;
585 }
Eric Snow96c6af92015-05-29 22:21:39 -0600586
587 /* Replace the old fast nodes table. */
588 _odict_free_fast_nodes(od);
589 od->od_fast_nodes = fast_nodes;
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200590 od->od_fast_nodes_size = size;
591 od->od_resize_sentinel = ((PyDictObject *)od)->ma_keys;
Eric Snow96c6af92015-05-29 22:21:39 -0600592 return 0;
593}
594
595/* Return the index into the hash table, regardless of a valid node. */
596static Py_ssize_t
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200597_odict_get_index(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600598{
Eric Snow4c729182015-06-03 10:50:37 -0600599 PyDictKeysObject *keys;
Eric Snow96c6af92015-05-29 22:21:39 -0600600
601 assert(key != NULL);
Eric Snow4c729182015-06-03 10:50:37 -0600602 keys = ((PyDictObject *)od)->ma_keys;
603
604 /* Ensure od_fast_nodes and dk_entries are in sync. */
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200605 if (od->od_resize_sentinel != keys ||
606 od->od_fast_nodes_size != keys->dk_size) {
Eric Snow4c729182015-06-03 10:50:37 -0600607 int resize_res = _odict_resize(od);
608 if (resize_res < 0)
609 return -1;
610 }
611
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200612 return _odict_get_index_raw(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600613}
614
Eric Snow96c6af92015-05-29 22:21:39 -0600615/* Returns NULL if there was some error or the key was not found. */
616static _ODictNode *
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200617_odict_find_node_hash(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600618{
619 Py_ssize_t index;
620
621 if (_odict_EMPTY(od))
622 return NULL;
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200623 index = _odict_get_index(od, key, hash);
624 if (index < 0)
625 return NULL;
626 return od->od_fast_nodes[index];
627}
628
629static _ODictNode *
630_odict_find_node(PyODictObject *od, PyObject *key)
631{
632 Py_ssize_t index;
633 Py_hash_t hash;
634
635 if (_odict_EMPTY(od))
636 return NULL;
637 hash = PyObject_Hash(key);
638 if (hash == -1)
639 return NULL;
640 index = _odict_get_index(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600641 if (index < 0)
642 return NULL;
643 return od->od_fast_nodes[index];
644}
645
646static void
647_odict_add_head(PyODictObject *od, _ODictNode *node)
648{
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300649 _odictnode_PREV(node) = NULL;
650 _odictnode_NEXT(node) = _odict_FIRST(od);
651 if (_odict_FIRST(od) == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -0600652 _odict_LAST(od) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300653 else
Eric Snow96c6af92015-05-29 22:21:39 -0600654 _odictnode_PREV(_odict_FIRST(od)) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300655 _odict_FIRST(od) = node;
Eric Snow4fabf022015-06-04 00:09:56 -0600656 od->od_state++;
Eric Snow96c6af92015-05-29 22:21:39 -0600657}
658
659static void
660_odict_add_tail(PyODictObject *od, _ODictNode *node)
661{
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300662 _odictnode_PREV(node) = _odict_LAST(od);
663 _odictnode_NEXT(node) = NULL;
664 if (_odict_LAST(od) == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -0600665 _odict_FIRST(od) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300666 else
Eric Snow96c6af92015-05-29 22:21:39 -0600667 _odictnode_NEXT(_odict_LAST(od)) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300668 _odict_LAST(od) = node;
Eric Snow4fabf022015-06-04 00:09:56 -0600669 od->od_state++;
Eric Snow96c6af92015-05-29 22:21:39 -0600670}
671
672/* adds the node to the end of the list */
673static int
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200674_odict_add_new_node(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600675{
676 Py_ssize_t i;
677 _ODictNode *node;
678
Serhiy Storchakad17427b2015-10-20 18:21:48 +0300679 Py_INCREF(key);
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200680 i = _odict_get_index(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600681 if (i < 0) {
682 if (!PyErr_Occurred())
683 PyErr_SetObject(PyExc_KeyError, key);
684 Py_DECREF(key);
685 return -1;
686 }
687 else if (od->od_fast_nodes[i] != NULL) {
688 /* We already have a node for the key so there's no need to add one. */
689 Py_DECREF(key);
690 return 0;
691 }
692
693 /* must not be added yet */
694 node = (_ODictNode *)PyMem_MALLOC(sizeof(_ODictNode));
695 if (node == NULL) {
696 Py_DECREF(key);
697 PyErr_NoMemory();
698 return -1;
699 }
700
701 _odictnode_KEY(node) = key;
Eric Snow4c729182015-06-03 10:50:37 -0600702 _odictnode_HASH(node) = hash;
Eric Snow96c6af92015-05-29 22:21:39 -0600703 _odict_add_tail(od, node);
704 od->od_fast_nodes[i] = node;
705 return 0;
706}
707
708/* Putting the decref after the free causes problems. */
709#define _odictnode_DEALLOC(node) \
710 do { \
711 Py_DECREF(_odictnode_KEY(node)); \
712 PyMem_FREE((void *)node); \
713 } while (0)
714
715/* Repeated calls on the same node are no-ops. */
716static void
717_odict_remove_node(PyODictObject *od, _ODictNode *node)
718{
719 if (_odict_FIRST(od) == node)
720 _odict_FIRST(od) = _odictnode_NEXT(node);
721 else if (_odictnode_PREV(node) != NULL)
722 _odictnode_NEXT(_odictnode_PREV(node)) = _odictnode_NEXT(node);
723
724 if (_odict_LAST(od) == node)
725 _odict_LAST(od) = _odictnode_PREV(node);
726 else if (_odictnode_NEXT(node) != NULL)
727 _odictnode_PREV(_odictnode_NEXT(node)) = _odictnode_PREV(node);
728
729 _odictnode_PREV(node) = NULL;
730 _odictnode_NEXT(node) = NULL;
Eric Snow4fabf022015-06-04 00:09:56 -0600731 od->od_state++;
Eric Snow96c6af92015-05-29 22:21:39 -0600732}
733
Eric Snow96c6af92015-05-29 22:21:39 -0600734/* If someone calls PyDict_DelItem() directly on an OrderedDict, we'll
735 get all sorts of problems here. In PyODict_DelItem we make sure to
736 call _odict_clear_node first.
Victor Stinnerca30b022015-09-03 17:50:04 +0200737
Eric Snow96c6af92015-05-29 22:21:39 -0600738 This matters in the case of colliding keys. Suppose we add 3 keys:
739 [A, B, C], where the hash of C collides with A and the next possible
740 index in the hash table is occupied by B. If we remove B then for C
741 the dict's looknode func will give us the old index of B instead of
742 the index we got before deleting B. However, the node for C in
743 od_fast_nodes is still at the old dict index of C. Thus to be sure
744 things don't get out of sync, we clear the node in od_fast_nodes
745 *before* calling PyDict_DelItem.
746
747 The same must be done for any other OrderedDict operations where
748 we modify od_fast_nodes.
749*/
750static int
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200751_odict_clear_node(PyODictObject *od, _ODictNode *node, PyObject *key,
752 Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600753{
754 Py_ssize_t i;
755
756 assert(key != NULL);
757 if (_odict_EMPTY(od)) {
758 /* Let later code decide if this is a KeyError. */
759 return 0;
760 }
761
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200762 i = _odict_get_index(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600763 if (i < 0)
764 return PyErr_Occurred() ? -1 : 0;
765
766 if (node == NULL)
767 node = od->od_fast_nodes[i];
768 assert(node == od->od_fast_nodes[i]);
769 if (node == NULL) {
770 /* Let later code decide if this is a KeyError. */
771 return 0;
772 }
773
774 // Now clear the node.
775 od->od_fast_nodes[i] = NULL;
776 _odict_remove_node(od, node);
777 _odictnode_DEALLOC(node);
778 return 0;
779}
780
781static void
782_odict_clear_nodes(PyODictObject *od)
783{
784 _ODictNode *node, *next;
785
Eric Snow96c6af92015-05-29 22:21:39 -0600786 _odict_free_fast_nodes(od);
787 od->od_fast_nodes = NULL;
Serhiy Storchakad205d012016-01-19 14:46:25 +0200788
789 node = _odict_FIRST(od);
790 _odict_FIRST(od) = NULL;
791 _odict_LAST(od) = NULL;
792 while (node != NULL) {
793 next = _odictnode_NEXT(node);
794 _odictnode_DEALLOC(node);
795 node = next;
796 }
Eric Snow96c6af92015-05-29 22:21:39 -0600797}
798
799/* There isn't any memory management of nodes past this point. */
800#undef _odictnode_DEALLOC
801
802static int
803_odict_keys_equal(PyODictObject *a, PyODictObject *b)
804{
805 _ODictNode *node_a, *node_b;
806
807 node_a = _odict_FIRST(a);
808 node_b = _odict_FIRST(b);
809 while (1) {
810 if (node_a == NULL && node_b == NULL)
811 /* success: hit the end of each at the same time */
812 return 1;
813 else if (node_a == NULL || node_b == NULL)
814 /* unequal length */
815 return 0;
816 else {
817 int res = PyObject_RichCompareBool(
818 (PyObject *)_odictnode_KEY(node_a),
819 (PyObject *)_odictnode_KEY(node_b),
820 Py_EQ);
821 if (res < 0)
822 return res;
823 else if (res == 0)
824 return 0;
825
826 /* otherwise it must match, so move on to the next one */
827 node_a = _odictnode_NEXT(node_a);
828 node_b = _odictnode_NEXT(node_b);
829 }
830 }
831}
832
833
834/* ----------------------------------------------
835 * OrderedDict mapping methods
836 */
837
838/* mp_ass_subscript: __setitem__() and __delitem__() */
839
840static int
841odict_mp_ass_sub(PyODictObject *od, PyObject *v, PyObject *w)
842{
843 if (w == NULL)
844 return PyODict_DelItem((PyObject *)od, v);
845 else
846 return PyODict_SetItem((PyObject *)od, v, w);
847}
848
849/* tp_as_mapping */
850
851static PyMappingMethods odict_as_mapping = {
852 0, /*mp_length*/
853 0, /*mp_subscript*/
854 (objobjargproc)odict_mp_ass_sub, /*mp_ass_subscript*/
855};
856
857
858/* ----------------------------------------------
859 * OrderedDict methods
860 */
861
862/* __delitem__() */
863
864PyDoc_STRVAR(odict_delitem__doc__, "od.__delitem__(y) <==> del od[y]");
865
866/* __eq__() */
867
868PyDoc_STRVAR(odict_eq__doc__,
oldkaa0735f2018-02-02 16:52:55 +0800869"od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive\n\
Eric Snow96c6af92015-05-29 22:21:39 -0600870 while comparison to a regular mapping is order-insensitive.\n\
871 ");
872
873/* forward */
874static PyObject * odict_richcompare(PyObject *v, PyObject *w, int op);
875
876static PyObject *
877odict_eq(PyObject *a, PyObject *b)
878{
879 return odict_richcompare(a, b, Py_EQ);
880}
881
882/* __init__() */
883
884PyDoc_STRVAR(odict_init__doc__,
885"Initialize an ordered dictionary. The signature is the same as\n\
Jonathan Eunicefaa57cb2017-09-05 19:23:49 -0400886 regular dictionaries. Keyword argument order is preserved.\n\
Eric Snow96c6af92015-05-29 22:21:39 -0600887\n\
888 ");
889
890/* forward */
891static int odict_init(PyObject *self, PyObject *args, PyObject *kwds);
892
893/* __iter__() */
894
895PyDoc_STRVAR(odict_iter__doc__, "od.__iter__() <==> iter(od)");
896
897static PyObject * odict_iter(PyODictObject *self); /* forward */
898
899/* __ne__() */
900
901/* Mapping.__ne__() does not have a docstring. */
902PyDoc_STRVAR(odict_ne__doc__, "");
903
904static PyObject *
905odict_ne(PyObject *a, PyObject *b)
906{
907 return odict_richcompare(a, b, Py_NE);
908}
909
910/* __repr__() */
911
912PyDoc_STRVAR(odict_repr__doc__, "od.__repr__() <==> repr(od)");
913
914static PyObject * odict_repr(PyODictObject *self); /* forward */
915
916/* __setitem__() */
917
918PyDoc_STRVAR(odict_setitem__doc__, "od.__setitem__(i, y) <==> od[i]=y");
919
920/* fromkeys() */
921
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100922/*[clinic input]
923@classmethod
924OrderedDict.fromkeys
925
926 iterable as seq: object
927 value: object = None
928
Serhiy Storchaka78d9e582017-01-25 00:30:04 +0200929Create a new ordered dictionary with keys from iterable and values set to value.
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100930[clinic start generated code]*/
Eric Snow96c6af92015-05-29 22:21:39 -0600931
932static PyObject *
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100933OrderedDict_fromkeys_impl(PyTypeObject *type, PyObject *seq, PyObject *value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +0200934/*[clinic end generated code: output=c10390d452d78d6d input=1a0476c229c597b3]*/
Eric Snow96c6af92015-05-29 22:21:39 -0600935{
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100936 return _PyDict_FromKeys((PyObject *)type, seq, value);
Eric Snow96c6af92015-05-29 22:21:39 -0600937}
938
939/* __sizeof__() */
940
941/* OrderedDict.__sizeof__() does not have a docstring. */
942PyDoc_STRVAR(odict_sizeof__doc__, "");
943
944static PyObject *
945odict_sizeof(PyODictObject *od)
946{
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +0200947 Py_ssize_t res = _PyDict_SizeOf((PyDictObject *)od);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300948 res += sizeof(_ODictNode *) * _odict_FAST_SIZE(od); /* od_fast_nodes */
Eric Snow96c6af92015-05-29 22:21:39 -0600949 if (!_odict_EMPTY(od)) {
950 res += sizeof(_ODictNode) * PyODict_SIZE(od); /* linked-list */
951 }
952 return PyLong_FromSsize_t(res);
953}
954
955/* __reduce__() */
956
957PyDoc_STRVAR(odict_reduce__doc__, "Return state information for pickling");
958
959static PyObject *
960odict_reduce(register PyODictObject *od)
961{
962 _Py_IDENTIFIER(__dict__);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300963 _Py_IDENTIFIER(items);
Serhiy Storchaka4575beb2015-10-22 20:18:24 +0300964 PyObject *dict = NULL, *result = NULL;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300965 PyObject *items_iter, *items, *args = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -0600966
967 /* capture any instance state */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300968 dict = _PyObject_GetAttrId((PyObject *)od, &PyId___dict__);
969 if (dict == NULL)
Eric Snowc5e59602015-05-30 11:28:56 -0600970 goto Done;
971 else {
Eric Snow96c6af92015-05-29 22:21:39 -0600972 /* od.__dict__ isn't necessarily a dict... */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300973 Py_ssize_t dict_len = PyObject_Length(dict);
974 if (dict_len == -1)
Eric Snow96c6af92015-05-29 22:21:39 -0600975 goto Done;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300976 if (!dict_len) {
977 /* nothing to pickle in od.__dict__ */
978 Py_CLEAR(dict);
Eric Snow96c6af92015-05-29 22:21:39 -0600979 }
980 }
981
982 /* build the result */
Eric Snow96c6af92015-05-29 22:21:39 -0600983 args = PyTuple_New(0);
984 if (args == NULL)
985 goto Done;
986
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300987 items = _PyObject_CallMethodIdObjArgs((PyObject *)od, &PyId_items, NULL);
Eric Snow96c6af92015-05-29 22:21:39 -0600988 if (items == NULL)
989 goto Done;
990
991 items_iter = PyObject_GetIter(items);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300992 Py_DECREF(items);
Eric Snow96c6af92015-05-29 22:21:39 -0600993 if (items_iter == NULL)
994 goto Done;
995
Serhiy Storchaka4575beb2015-10-22 20:18:24 +0300996 result = PyTuple_Pack(5, Py_TYPE(od), args, dict ? dict : Py_None, Py_None, items_iter);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300997 Py_DECREF(items_iter);
Eric Snow96c6af92015-05-29 22:21:39 -0600998
999Done:
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001000 Py_XDECREF(dict);
Eric Snow96c6af92015-05-29 22:21:39 -06001001 Py_XDECREF(args);
Eric Snow96c6af92015-05-29 22:21:39 -06001002
1003 return result;
1004}
1005
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001006/* setdefault(): Skips __missing__() calls. */
Eric Snow96c6af92015-05-29 22:21:39 -06001007
Eric Snow96c6af92015-05-29 22:21:39 -06001008
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001009/*[clinic input]
1010OrderedDict.setdefault
1011
1012 key: object
Serhiy Storchakaa70eaf22017-01-19 19:38:13 +02001013 default: object = None
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001014
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001015Insert key with a value of default if key is not in the dictionary.
1016
1017Return the value for key if key is in the dictionary, else default.
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001018[clinic start generated code]*/
1019
Eric Snow96c6af92015-05-29 22:21:39 -06001020static PyObject *
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001021OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key,
Serhiy Storchakaa70eaf22017-01-19 19:38:13 +02001022 PyObject *default_value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001023/*[clinic end generated code: output=97537cb7c28464b6 input=38e098381c1efbc6]*/
Eric Snow96c6af92015-05-29 22:21:39 -06001024{
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001025 PyObject *result = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001026
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001027 if (PyODict_CheckExact(self)) {
1028 result = PyODict_GetItemWithError(self, key); /* borrowed */
Eric Snowd1719752015-06-01 23:12:13 -06001029 if (result == NULL) {
1030 if (PyErr_Occurred())
1031 return NULL;
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001032 assert(_odict_find_node(self, key) == NULL);
Serhiy Storchakaa70eaf22017-01-19 19:38:13 +02001033 if (PyODict_SetItem((PyObject *)self, key, default_value) >= 0) {
1034 result = default_value;
1035 Py_INCREF(result);
Eric Snow96c6af92015-05-29 22:21:39 -06001036 }
1037 }
1038 else {
Eric Snowd1719752015-06-01 23:12:13 -06001039 Py_INCREF(result);
Eric Snow96c6af92015-05-29 22:21:39 -06001040 }
1041 }
1042 else {
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001043 int exists = PySequence_Contains((PyObject *)self, key);
Eric Snow96c6af92015-05-29 22:21:39 -06001044 if (exists < 0) {
Eric Snowd1719752015-06-01 23:12:13 -06001045 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001046 }
1047 else if (exists) {
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001048 result = PyObject_GetItem((PyObject *)self, key);
Eric Snow96c6af92015-05-29 22:21:39 -06001049 }
Serhiy Storchakaa70eaf22017-01-19 19:38:13 +02001050 else if (PyObject_SetItem((PyObject *)self, key, default_value) >= 0) {
1051 result = default_value;
1052 Py_INCREF(result);
Eric Snow96c6af92015-05-29 22:21:39 -06001053 }
1054 }
1055
Eric Snow96c6af92015-05-29 22:21:39 -06001056 return result;
1057}
1058
1059/* pop() */
1060
1061PyDoc_STRVAR(odict_pop__doc__,
1062"od.pop(k[,d]) -> v, remove specified key and return the corresponding\n\
1063 value. If key is not found, d is returned if given, otherwise KeyError\n\
1064 is raised.\n\
1065\n\
1066 ");
1067
1068/* forward */
1069static PyObject * _odict_popkey(PyObject *, PyObject *, PyObject *);
1070
1071/* Skips __missing__() calls. */
1072static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001073odict_pop(PyObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001074{
Eric Snowac02ef32015-06-02 20:42:14 -06001075 static char *kwlist[] = {"key", "default", 0};
Eric Snow96c6af92015-05-29 22:21:39 -06001076 PyObject *key, *failobj = NULL;
1077
Eric Snowac02ef32015-06-02 20:42:14 -06001078 /* borrowed */
1079 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:pop", kwlist,
1080 &key, &failobj)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001081 return NULL;
1082 }
1083
1084 return _odict_popkey(od, key, failobj);
1085}
1086
1087static PyObject *
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001088_odict_popkey_hash(PyObject *od, PyObject *key, PyObject *failobj,
1089 Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -06001090{
1091 _ODictNode *node;
1092 PyObject *value = NULL;
1093
Eric Snow96c6af92015-05-29 22:21:39 -06001094 /* Pop the node first to avoid a possible dict resize (due to
1095 eval loop reentrancy) and complications due to hash collision
1096 resolution. */
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001097 node = _odict_find_node_hash((PyODictObject *)od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001098 if (node == NULL) {
1099 if (PyErr_Occurred())
Eric Snowd1719752015-06-01 23:12:13 -06001100 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001101 }
1102 else {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001103 int res = _odict_clear_node((PyODictObject *)od, node, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001104 if (res < 0) {
Eric Snowd1719752015-06-01 23:12:13 -06001105 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001106 }
1107 }
1108
1109 /* Now delete the value from the dict. */
Serhiy Storchaka04386832016-10-30 17:17:24 +02001110 if (PyODict_CheckExact(od)) {
1111 if (node != NULL) {
1112 value = _PyDict_GetItem_KnownHash(od, key, hash); /* borrowed */
1113 if (value != NULL) {
1114 Py_INCREF(value);
1115 if (_PyDict_DelItem_KnownHash(od, key, hash) < 0) {
1116 Py_DECREF(value);
1117 return NULL;
1118 }
1119 }
1120 }
1121 }
1122 else {
1123 int exists = PySequence_Contains(od, key);
1124 if (exists < 0)
1125 return NULL;
1126 if (exists) {
1127 value = PyObject_GetItem(od, key);
1128 if (value != NULL) {
1129 if (PyObject_DelItem(od, key) == -1) {
1130 Py_CLEAR(value);
1131 }
Eric Snow96c6af92015-05-29 22:21:39 -06001132 }
1133 }
1134 }
1135
1136 /* Apply the fallback value, if necessary. */
1137 if (value == NULL && !PyErr_Occurred()) {
1138 if (failobj) {
1139 value = failobj;
1140 Py_INCREF(failobj);
1141 }
1142 else {
1143 PyErr_SetObject(PyExc_KeyError, key);
1144 }
1145 }
1146
Eric Snow96c6af92015-05-29 22:21:39 -06001147 return value;
1148}
1149
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001150static PyObject *
1151_odict_popkey(PyObject *od, PyObject *key, PyObject *failobj)
1152{
1153 Py_hash_t hash = PyObject_Hash(key);
1154 if (hash == -1)
1155 return NULL;
1156
1157 return _odict_popkey_hash(od, key, failobj, hash);
1158}
1159
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001160
Eric Snow96c6af92015-05-29 22:21:39 -06001161/* popitem() */
1162
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001163/*[clinic input]
1164OrderedDict.popitem
1165
1166 last: bool = True
1167
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001168Remove and return a (key, value) pair from the dictionary.
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001169
1170Pairs are returned in LIFO order if last is true or FIFO order if false.
1171[clinic start generated code]*/
Eric Snow96c6af92015-05-29 22:21:39 -06001172
1173static PyObject *
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001174OrderedDict_popitem_impl(PyODictObject *self, int last)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001175/*[clinic end generated code: output=98e7d986690d49eb input=d992ac5ee8305e1a]*/
Eric Snow96c6af92015-05-29 22:21:39 -06001176{
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001177 PyObject *key, *value, *item = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001178 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001179
1180 /* pull the item */
1181
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001182 if (_odict_EMPTY(self)) {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001183 PyErr_SetString(PyExc_KeyError, "dictionary is empty");
1184 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001185 }
Eric Snow96c6af92015-05-29 22:21:39 -06001186
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001187 node = last ? _odict_LAST(self) : _odict_FIRST(self);
Eric Snow96c6af92015-05-29 22:21:39 -06001188 key = _odictnode_KEY(node);
Eric Snowd1719752015-06-01 23:12:13 -06001189 Py_INCREF(key);
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001190 value = _odict_popkey_hash((PyObject *)self, key, NULL, _odictnode_HASH(node));
Eric Snow96c6af92015-05-29 22:21:39 -06001191 if (value == NULL)
1192 return NULL;
1193 item = PyTuple_Pack(2, key, value);
Eric Snowd1719752015-06-01 23:12:13 -06001194 Py_DECREF(key);
Eric Snow96c6af92015-05-29 22:21:39 -06001195 Py_DECREF(value);
1196 return item;
1197}
1198
1199/* keys() */
1200
1201/* MutableMapping.keys() does not have a docstring. */
1202PyDoc_STRVAR(odict_keys__doc__, "");
1203
1204static PyObject * odictkeys_new(PyObject *od); /* forward */
1205
1206/* values() */
1207
1208/* MutableMapping.values() does not have a docstring. */
1209PyDoc_STRVAR(odict_values__doc__, "");
1210
1211static PyObject * odictvalues_new(PyObject *od); /* forward */
1212
1213/* items() */
1214
1215/* MutableMapping.items() does not have a docstring. */
1216PyDoc_STRVAR(odict_items__doc__, "");
1217
1218static PyObject * odictitems_new(PyObject *od); /* forward */
1219
1220/* update() */
1221
1222/* MutableMapping.update() does not have a docstring. */
1223PyDoc_STRVAR(odict_update__doc__, "");
1224
1225/* forward */
1226static PyObject * mutablemapping_update(PyObject *, PyObject *, PyObject *);
1227
1228#define odict_update mutablemapping_update
1229
1230/* clear() */
1231
1232PyDoc_STRVAR(odict_clear__doc__,
1233 "od.clear() -> None. Remove all items from od.");
1234
1235static PyObject *
1236odict_clear(register PyODictObject *od)
1237{
1238 PyDict_Clear((PyObject *)od);
1239 _odict_clear_nodes(od);
Eric Snow96c6af92015-05-29 22:21:39 -06001240 if (_odict_resize(od) < 0)
1241 return NULL;
1242 Py_RETURN_NONE;
1243}
1244
1245/* copy() */
1246
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001247/* forward */
1248static int _PyODict_SetItem_KnownHash(PyObject *, PyObject *, PyObject *,
1249 Py_hash_t);
1250
Eric Snow96c6af92015-05-29 22:21:39 -06001251PyDoc_STRVAR(odict_copy__doc__, "od.copy() -> a shallow copy of od");
1252
1253static PyObject *
1254odict_copy(register PyODictObject *od)
1255{
1256 _ODictNode *node;
1257 PyObject *od_copy;
1258
1259 if (PyODict_CheckExact(od))
1260 od_copy = PyODict_New();
1261 else
Victor Stinnerf17c3de2016-12-06 18:46:19 +01001262 od_copy = _PyObject_CallNoArg((PyObject *)Py_TYPE(od));
Eric Snow96c6af92015-05-29 22:21:39 -06001263 if (od_copy == NULL)
1264 return NULL;
1265
1266 if (PyODict_CheckExact(od)) {
1267 _odict_FOREACH(od, node) {
Eric Snowa762af72015-06-01 22:59:08 -06001268 PyObject *key = _odictnode_KEY(node);
1269 PyObject *value = _odictnode_VALUE(node, od);
1270 if (value == NULL) {
1271 if (!PyErr_Occurred())
1272 PyErr_SetObject(PyExc_KeyError, key);
1273 goto fail;
1274 }
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001275 if (_PyODict_SetItem_KnownHash((PyObject *)od_copy, key, value,
1276 _odictnode_HASH(node)) != 0)
Eric Snow96c6af92015-05-29 22:21:39 -06001277 goto fail;
1278 }
1279 }
1280 else {
1281 _odict_FOREACH(od, node) {
1282 int res;
1283 PyObject *value = PyObject_GetItem((PyObject *)od,
1284 _odictnode_KEY(node));
1285 if (value == NULL)
1286 goto fail;
1287 res = PyObject_SetItem((PyObject *)od_copy,
1288 _odictnode_KEY(node), value);
1289 Py_DECREF(value);
1290 if (res != 0)
1291 goto fail;
1292 }
1293 }
1294 return od_copy;
1295
1296fail:
1297 Py_DECREF(od_copy);
1298 return NULL;
1299}
1300
1301/* __reversed__() */
1302
1303PyDoc_STRVAR(odict_reversed__doc__, "od.__reversed__() <==> reversed(od)");
1304
1305#define _odict_ITER_REVERSED 1
1306#define _odict_ITER_KEYS 2
1307#define _odict_ITER_VALUES 4
1308
1309/* forward */
1310static PyObject * odictiter_new(PyODictObject *, int);
1311
1312static PyObject *
1313odict_reversed(PyODictObject *od)
1314{
Eric Snow96c6af92015-05-29 22:21:39 -06001315 return odictiter_new(od, _odict_ITER_KEYS|_odict_ITER_REVERSED);
1316}
1317
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001318
Eric Snow96c6af92015-05-29 22:21:39 -06001319/* move_to_end() */
1320
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001321/*[clinic input]
1322OrderedDict.move_to_end
1323
1324 key: object
1325 last: bool = True
1326
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001327Move an existing element to the end (or beginning if last is false).
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001328
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001329Raise KeyError if the element does not exist.
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001330[clinic start generated code]*/
Eric Snow96c6af92015-05-29 22:21:39 -06001331
1332static PyObject *
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001333OrderedDict_move_to_end_impl(PyODictObject *self, PyObject *key, int last)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001334/*[clinic end generated code: output=fafa4c5cc9b92f20 input=d6ceff7132a2fcd7]*/
Eric Snow96c6af92015-05-29 22:21:39 -06001335{
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001336 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001337
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001338 if (_odict_EMPTY(self)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001339 PyErr_SetObject(PyExc_KeyError, key);
Eric Snow96c6af92015-05-29 22:21:39 -06001340 return NULL;
1341 }
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001342 node = last ? _odict_LAST(self) : _odict_FIRST(self);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001343 if (key != _odictnode_KEY(node)) {
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001344 node = _odict_find_node(self, key);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001345 if (node == NULL) {
1346 if (!PyErr_Occurred())
1347 PyErr_SetObject(PyExc_KeyError, key);
Eric Snowc5e59602015-05-30 11:28:56 -06001348 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001349 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001350 if (last) {
1351 /* Only move if not already the last one. */
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001352 if (node != _odict_LAST(self)) {
1353 _odict_remove_node(self, node);
1354 _odict_add_tail(self, node);
Eric Snow96c6af92015-05-29 22:21:39 -06001355 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001356 }
1357 else {
1358 /* Only move if not already the first one. */
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001359 if (node != _odict_FIRST(self)) {
1360 _odict_remove_node(self, node);
1361 _odict_add_head(self, node);
Eric Snow96c6af92015-05-29 22:21:39 -06001362 }
1363 }
1364 }
Eric Snow96c6af92015-05-29 22:21:39 -06001365 Py_RETURN_NONE;
1366}
1367
1368
1369/* tp_methods */
1370
1371static PyMethodDef odict_methods[] = {
1372
1373 /* explicitly defined so we can align docstrings with
1374 * collections.OrderedDict */
1375 {"__delitem__", (PyCFunction)odict_mp_ass_sub, METH_NOARGS,
1376 odict_delitem__doc__},
1377 {"__eq__", (PyCFunction)odict_eq, METH_NOARGS,
1378 odict_eq__doc__},
1379 {"__init__", (PyCFunction)odict_init, METH_NOARGS,
1380 odict_init__doc__},
1381 {"__iter__", (PyCFunction)odict_iter, METH_NOARGS,
1382 odict_iter__doc__},
1383 {"__ne__", (PyCFunction)odict_ne, METH_NOARGS,
1384 odict_ne__doc__},
1385 {"__repr__", (PyCFunction)odict_repr, METH_NOARGS,
1386 odict_repr__doc__},
1387 {"__setitem__", (PyCFunction)odict_mp_ass_sub, METH_NOARGS,
1388 odict_setitem__doc__},
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001389 ORDEREDDICT_FROMKEYS_METHODDEF
Eric Snow96c6af92015-05-29 22:21:39 -06001390
1391 /* overridden dict methods */
1392 {"__sizeof__", (PyCFunction)odict_sizeof, METH_NOARGS,
1393 odict_sizeof__doc__},
1394 {"__reduce__", (PyCFunction)odict_reduce, METH_NOARGS,
1395 odict_reduce__doc__},
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001396 ORDEREDDICT_SETDEFAULT_METHODDEF
Eric Snowac02ef32015-06-02 20:42:14 -06001397 {"pop", (PyCFunction)odict_pop,
1398 METH_VARARGS | METH_KEYWORDS, odict_pop__doc__},
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001399 ORDEREDDICT_POPITEM_METHODDEF
Eric Snow96c6af92015-05-29 22:21:39 -06001400 {"keys", (PyCFunction)odictkeys_new, METH_NOARGS,
1401 odict_keys__doc__},
1402 {"values", (PyCFunction)odictvalues_new, METH_NOARGS,
1403 odict_values__doc__},
1404 {"items", (PyCFunction)odictitems_new, METH_NOARGS,
1405 odict_items__doc__},
1406 {"update", (PyCFunction)odict_update, METH_VARARGS | METH_KEYWORDS,
1407 odict_update__doc__},
1408 {"clear", (PyCFunction)odict_clear, METH_NOARGS,
1409 odict_clear__doc__},
1410 {"copy", (PyCFunction)odict_copy, METH_NOARGS,
1411 odict_copy__doc__},
1412
1413 /* new methods */
1414 {"__reversed__", (PyCFunction)odict_reversed, METH_NOARGS,
1415 odict_reversed__doc__},
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001416 ORDEREDDICT_MOVE_TO_END_METHODDEF
Eric Snow96c6af92015-05-29 22:21:39 -06001417
1418 {NULL, NULL} /* sentinel */
1419};
1420
1421
1422/* ----------------------------------------------
1423 * OrderedDict members
1424 */
1425
Serhiy Storchakad2962f12016-02-08 16:39:05 +02001426/* tp_getset */
Eric Snow96c6af92015-05-29 22:21:39 -06001427
Serhiy Storchakad2962f12016-02-08 16:39:05 +02001428static PyGetSetDef odict_getset[] = {
1429 {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
1430 {NULL}
Eric Snow96c6af92015-05-29 22:21:39 -06001431};
1432
Eric Snow96c6af92015-05-29 22:21:39 -06001433/* ----------------------------------------------
1434 * OrderedDict type slot methods
1435 */
1436
1437/* tp_dealloc */
1438
1439static void
1440odict_dealloc(PyODictObject *self)
1441{
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001442 PyThreadState *tstate = PyThreadState_GET();
1443
Eric Snow96c6af92015-05-29 22:21:39 -06001444 PyObject_GC_UnTrack(self);
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001445 Py_TRASHCAN_SAFE_BEGIN(self)
1446
Eric Snow96c6af92015-05-29 22:21:39 -06001447 Py_XDECREF(self->od_inst_dict);
1448 if (self->od_weakreflist != NULL)
1449 PyObject_ClearWeakRefs((PyObject *)self);
1450
1451 _odict_clear_nodes(self);
Eric Snow96c6af92015-05-29 22:21:39 -06001452
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001453 /* Call the base tp_dealloc(). Since it too uses the trashcan mechanism,
1454 * temporarily decrement trash_delete_nesting to prevent triggering it
1455 * and putting the partially deallocated object on the trashcan's
1456 * to-be-deleted-later list.
1457 */
1458 --tstate->trash_delete_nesting;
1459 assert(_tstate->trash_delete_nesting < PyTrash_UNWIND_LEVEL);
Eric Snow96c6af92015-05-29 22:21:39 -06001460 PyDict_Type.tp_dealloc((PyObject *)self);
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001461 ++tstate->trash_delete_nesting;
1462
1463 Py_TRASHCAN_SAFE_END(self)
Victor Stinnere1871952016-06-08 10:18:18 +02001464}
Eric Snow96c6af92015-05-29 22:21:39 -06001465
1466/* tp_repr */
1467
1468static PyObject *
1469odict_repr(PyODictObject *self)
1470{
1471 int i;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001472 _Py_IDENTIFIER(items);
Serhiy Storchaka4575beb2015-10-22 20:18:24 +03001473 PyObject *pieces = NULL, *result = NULL;
Serhiy Storchaka4575beb2015-10-22 20:18:24 +03001474
1475 if (PyODict_SIZE(self) == 0)
Serhiy Storchaka4ab46d72017-09-17 21:11:04 +03001476 return PyUnicode_FromFormat("%s()", _PyType_Name(Py_TYPE(self)));
Eric Snow96c6af92015-05-29 22:21:39 -06001477
1478 i = Py_ReprEnter((PyObject *)self);
1479 if (i != 0) {
1480 return i > 0 ? PyUnicode_FromString("...") : NULL;
1481 }
1482
Eric Snow96c6af92015-05-29 22:21:39 -06001483 if (PyODict_CheckExact(self)) {
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001484 Py_ssize_t count = 0;
Eric Snowa762af72015-06-01 22:59:08 -06001485 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001486 pieces = PyList_New(PyODict_SIZE(self));
1487 if (pieces == NULL)
1488 goto Done;
1489
1490 _odict_FOREACH(self, node) {
Eric Snowa762af72015-06-01 22:59:08 -06001491 PyObject *pair;
1492 PyObject *key = _odictnode_KEY(node);
1493 PyObject *value = _odictnode_VALUE(node, self);
1494 if (value == NULL) {
1495 if (!PyErr_Occurred())
1496 PyErr_SetObject(PyExc_KeyError, key);
Eric Snowdb4061c2015-06-03 11:09:48 -06001497 goto Done;
Eric Snowa762af72015-06-01 22:59:08 -06001498 }
1499 pair = PyTuple_Pack(2, key, value);
Eric Snow96c6af92015-05-29 22:21:39 -06001500 if (pair == NULL)
1501 goto Done;
1502
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001503 if (count < PyList_GET_SIZE(pieces))
1504 PyList_SET_ITEM(pieces, count, pair); /* steals reference */
1505 else {
1506 if (PyList_Append(pieces, pair) < 0) {
1507 Py_DECREF(pair);
1508 goto Done;
1509 }
1510 Py_DECREF(pair);
1511 }
1512 count++;
Eric Snow96c6af92015-05-29 22:21:39 -06001513 }
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001514 if (count < PyList_GET_SIZE(pieces))
Serhiy Storchaka1a5856b2017-04-22 02:48:11 +03001515 Py_SIZE(pieces) = count;
Eric Snow96c6af92015-05-29 22:21:39 -06001516 }
1517 else {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001518 PyObject *items = _PyObject_CallMethodIdObjArgs((PyObject *)self,
1519 &PyId_items, NULL);
Eric Snow96c6af92015-05-29 22:21:39 -06001520 if (items == NULL)
1521 goto Done;
1522 pieces = PySequence_List(items);
1523 Py_DECREF(items);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001524 if (pieces == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -06001525 goto Done;
1526 }
1527
Serhiy Storchaka4ab46d72017-09-17 21:11:04 +03001528 result = PyUnicode_FromFormat("%s(%R)",
1529 _PyType_Name(Py_TYPE(self)), pieces);
Eric Snow96c6af92015-05-29 22:21:39 -06001530
Eric Snow96c6af92015-05-29 22:21:39 -06001531Done:
1532 Py_XDECREF(pieces);
Eric Snow96c6af92015-05-29 22:21:39 -06001533 Py_ReprLeave((PyObject *)self);
1534 return result;
Victor Stinnere1871952016-06-08 10:18:18 +02001535}
Eric Snow96c6af92015-05-29 22:21:39 -06001536
1537/* tp_doc */
1538
1539PyDoc_STRVAR(odict_doc,
1540 "Dictionary that remembers insertion order");
1541
1542/* tp_traverse */
1543
1544static int
1545odict_traverse(PyODictObject *od, visitproc visit, void *arg)
1546{
Serhiy Storchakad205d012016-01-19 14:46:25 +02001547 _ODictNode *node;
1548
Eric Snow96c6af92015-05-29 22:21:39 -06001549 Py_VISIT(od->od_inst_dict);
1550 Py_VISIT(od->od_weakreflist);
Serhiy Storchakad205d012016-01-19 14:46:25 +02001551 _odict_FOREACH(od, node) {
1552 Py_VISIT(_odictnode_KEY(node));
1553 }
Eric Snow96c6af92015-05-29 22:21:39 -06001554 return PyDict_Type.tp_traverse((PyObject *)od, visit, arg);
1555}
1556
1557/* tp_clear */
1558
1559static int
1560odict_tp_clear(PyODictObject *od)
1561{
1562 PyObject *res;
1563 Py_CLEAR(od->od_inst_dict);
1564 Py_CLEAR(od->od_weakreflist);
1565 res = odict_clear(od);
1566 if (res == NULL)
1567 return -1;
1568 Py_DECREF(res);
1569 return 0;
1570}
1571
1572/* tp_richcompare */
1573
1574static PyObject *
1575odict_richcompare(PyObject *v, PyObject *w, int op)
1576{
1577 if (!PyODict_Check(v) || !PyDict_Check(w)) {
1578 Py_RETURN_NOTIMPLEMENTED;
1579 }
1580
1581 if (op == Py_EQ || op == Py_NE) {
1582 PyObject *res, *cmp;
1583 int eq;
1584
1585 cmp = PyDict_Type.tp_richcompare(v, w, op);
1586 if (cmp == NULL)
1587 return NULL;
1588 if (!PyODict_Check(w))
1589 return cmp;
1590 if (op == Py_EQ && cmp == Py_False)
1591 return cmp;
1592 if (op == Py_NE && cmp == Py_True)
1593 return cmp;
1594 Py_DECREF(cmp);
1595
1596 /* Try comparing odict keys. */
1597 eq = _odict_keys_equal((PyODictObject *)v, (PyODictObject *)w);
1598 if (eq < 0)
1599 return NULL;
1600
1601 res = (eq == (op == Py_EQ)) ? Py_True : Py_False;
1602 Py_INCREF(res);
1603 return res;
1604 } else {
1605 Py_RETURN_NOTIMPLEMENTED;
1606 }
Victor Stinnere1871952016-06-08 10:18:18 +02001607}
Eric Snow96c6af92015-05-29 22:21:39 -06001608
1609/* tp_iter */
1610
1611static PyObject *
1612odict_iter(PyODictObject *od)
1613{
1614 return odictiter_new(od, _odict_ITER_KEYS);
Victor Stinnere1871952016-06-08 10:18:18 +02001615}
Eric Snow96c6af92015-05-29 22:21:39 -06001616
1617/* tp_init */
1618
1619static int
1620odict_init(PyObject *self, PyObject *args, PyObject *kwds)
1621{
1622 PyObject *res;
1623 Py_ssize_t len = PyObject_Length(args);
1624
1625 if (len == -1)
1626 return -1;
1627 if (len > 1) {
Serhiy Storchakae2f92de2017-11-11 13:06:26 +02001628 const char *msg = "expected at most 1 arguments, got %d";
Eric Snow96c6af92015-05-29 22:21:39 -06001629 PyErr_Format(PyExc_TypeError, msg, len);
1630 return -1;
1631 }
1632
1633 /* __init__() triggering update() is just the way things are! */
1634 res = odict_update(self, args, kwds);
1635 if (res == NULL) {
1636 return -1;
1637 } else {
1638 Py_DECREF(res);
1639 return 0;
1640 }
Victor Stinnere1871952016-06-08 10:18:18 +02001641}
Eric Snow96c6af92015-05-29 22:21:39 -06001642
1643/* tp_new */
1644
1645static PyObject *
1646odict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1647{
Victor Stinnerca30b022015-09-03 17:50:04 +02001648 PyODictObject *od;
1649
Victor Stinnerca30b022015-09-03 17:50:04 +02001650 od = (PyODictObject *)PyDict_Type.tp_new(type, args, kwds);
Serhiy Storchakad2962f12016-02-08 16:39:05 +02001651 if (od == NULL)
Victor Stinnerca30b022015-09-03 17:50:04 +02001652 return NULL;
Victor Stinnerca30b022015-09-03 17:50:04 +02001653
Victor Stinnerca30b022015-09-03 17:50:04 +02001654 /* type constructor fills the memory with zeros (see
1655 PyType_GenericAlloc()), there is no need to set them to zero again */
1656 if (_odict_resize(od) < 0) {
1657 Py_DECREF(od);
1658 return NULL;
1659 }
1660
1661 return (PyObject*)od;
Eric Snow96c6af92015-05-29 22:21:39 -06001662}
1663
1664/* PyODict_Type */
1665
1666PyTypeObject PyODict_Type = {
1667 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1668 "collections.OrderedDict", /* tp_name */
1669 sizeof(PyODictObject), /* tp_basicsize */
1670 0, /* tp_itemsize */
1671 (destructor)odict_dealloc, /* tp_dealloc */
1672 0, /* tp_print */
1673 0, /* tp_getattr */
1674 0, /* tp_setattr */
1675 0, /* tp_reserved */
1676 (reprfunc)odict_repr, /* tp_repr */
1677 0, /* tp_as_number */
1678 0, /* tp_as_sequence */
1679 &odict_as_mapping, /* tp_as_mapping */
1680 0, /* tp_hash */
1681 0, /* tp_call */
1682 0, /* tp_str */
1683 0, /* tp_getattro */
1684 0, /* tp_setattro */
1685 0, /* tp_as_buffer */
1686 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,/* tp_flags */
1687 odict_doc, /* tp_doc */
1688 (traverseproc)odict_traverse, /* tp_traverse */
1689 (inquiry)odict_tp_clear, /* tp_clear */
1690 (richcmpfunc)odict_richcompare, /* tp_richcompare */
1691 offsetof(PyODictObject, od_weakreflist), /* tp_weaklistoffset */
1692 (getiterfunc)odict_iter, /* tp_iter */
1693 0, /* tp_iternext */
1694 odict_methods, /* tp_methods */
Serhiy Storchakad2962f12016-02-08 16:39:05 +02001695 0, /* tp_members */
1696 odict_getset, /* tp_getset */
Eric Snow96c6af92015-05-29 22:21:39 -06001697 &PyDict_Type, /* tp_base */
1698 0, /* tp_dict */
1699 0, /* tp_descr_get */
1700 0, /* tp_descr_set */
1701 offsetof(PyODictObject, od_inst_dict), /* tp_dictoffset */
1702 (initproc)odict_init, /* tp_init */
1703 PyType_GenericAlloc, /* tp_alloc */
1704 (newfunc)odict_new, /* tp_new */
1705 0, /* tp_free */
1706};
1707
1708
1709/* ----------------------------------------------
1710 * the public OrderedDict API
1711 */
1712
1713PyObject *
1714PyODict_New(void) {
1715 return odict_new(&PyODict_Type, NULL, NULL);
Victor Stinnere1871952016-06-08 10:18:18 +02001716}
Eric Snow96c6af92015-05-29 22:21:39 -06001717
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001718static int
1719_PyODict_SetItem_KnownHash(PyObject *od, PyObject *key, PyObject *value,
1720 Py_hash_t hash)
1721{
1722 int res = _PyDict_SetItem_KnownHash(od, key, value, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001723 if (res == 0) {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001724 res = _odict_add_new_node((PyODictObject *)od, key, hash);
Serhiy Storchakad5f353e2015-11-06 11:07:11 +02001725 if (res < 0) {
1726 /* Revert setting the value on the dict */
1727 PyObject *exc, *val, *tb;
1728 PyErr_Fetch(&exc, &val, &tb);
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001729 (void) _PyDict_DelItem_KnownHash(od, key, hash);
Serhiy Storchakad5f353e2015-11-06 11:07:11 +02001730 _PyErr_ChainExceptions(exc, val, tb);
1731 }
Eric Snow96c6af92015-05-29 22:21:39 -06001732 }
1733 return res;
Victor Stinnere1871952016-06-08 10:18:18 +02001734}
Eric Snow96c6af92015-05-29 22:21:39 -06001735
1736int
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001737PyODict_SetItem(PyObject *od, PyObject *key, PyObject *value)
1738{
1739 Py_hash_t hash = PyObject_Hash(key);
1740 if (hash == -1)
1741 return -1;
1742 return _PyODict_SetItem_KnownHash(od, key, value, hash);
Victor Stinnere1871952016-06-08 10:18:18 +02001743}
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001744
1745int
1746PyODict_DelItem(PyObject *od, PyObject *key)
1747{
1748 int res;
1749 Py_hash_t hash = PyObject_Hash(key);
1750 if (hash == -1)
1751 return -1;
1752 res = _odict_clear_node((PyODictObject *)od, NULL, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001753 if (res < 0)
1754 return -1;
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001755 return _PyDict_DelItem_KnownHash(od, key, hash);
Victor Stinnere1871952016-06-08 10:18:18 +02001756}
Eric Snow96c6af92015-05-29 22:21:39 -06001757
1758
1759/* -------------------------------------------
1760 * The OrderedDict views (keys/values/items)
1761 */
1762
1763typedef struct {
1764 PyObject_HEAD
1765 int kind;
1766 PyODictObject *di_odict;
Eric Snowb952ab42015-06-01 23:35:13 -06001767 Py_ssize_t di_size;
Eric Snow4fabf022015-06-04 00:09:56 -06001768 size_t di_state;
Eric Snow96c6af92015-05-29 22:21:39 -06001769 PyObject *di_current;
1770 PyObject *di_result; /* reusable result tuple for iteritems */
1771} odictiterobject;
1772
1773static void
1774odictiter_dealloc(odictiterobject *di)
1775{
1776 _PyObject_GC_UNTRACK(di);
Eric Snowa762af72015-06-01 22:59:08 -06001777 Py_XDECREF(di->di_odict);
Eric Snow96c6af92015-05-29 22:21:39 -06001778 Py_XDECREF(di->di_current);
1779 if (di->kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)) {
1780 Py_DECREF(di->di_result);
1781 }
1782 PyObject_GC_Del(di);
1783}
1784
1785static int
1786odictiter_traverse(odictiterobject *di, visitproc visit, void *arg)
1787{
1788 Py_VISIT(di->di_odict);
1789 Py_VISIT(di->di_current); /* A key could be any type, not just str. */
1790 Py_VISIT(di->di_result);
1791 return 0;
1792}
1793
Eric Snowa762af72015-06-01 22:59:08 -06001794/* In order to protect against modifications during iteration, we track
1795 * the current key instead of the current node. */
Eric Snow96c6af92015-05-29 22:21:39 -06001796static PyObject *
1797odictiter_nextkey(odictiterobject *di)
1798{
Eric Snowa762af72015-06-01 22:59:08 -06001799 PyObject *key = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001800 _ODictNode *node;
1801 int reversed = di->kind & _odict_ITER_REVERSED;
1802
Eric Snowa762af72015-06-01 22:59:08 -06001803 if (di->di_odict == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -06001804 return NULL;
Eric Snowa762af72015-06-01 22:59:08 -06001805 if (di->di_current == NULL)
1806 goto done; /* We're already done. */
1807
Eric Snowb952ab42015-06-01 23:35:13 -06001808 /* Check for unsupported changes. */
Eric Snow4fabf022015-06-04 00:09:56 -06001809 if (di->di_odict->od_state != di->di_state) {
1810 PyErr_SetString(PyExc_RuntimeError,
1811 "OrderedDict mutated during iteration");
1812 goto done;
1813 }
Eric Snowb952ab42015-06-01 23:35:13 -06001814 if (di->di_size != PyODict_SIZE(di->di_odict)) {
1815 PyErr_SetString(PyExc_RuntimeError,
1816 "OrderedDict changed size during iteration");
1817 di->di_size = -1; /* Make this state sticky */
1818 return NULL;
1819 }
1820
Eric Snowa762af72015-06-01 22:59:08 -06001821 /* Get the key. */
Eric Snow96c6af92015-05-29 22:21:39 -06001822 node = _odict_find_node(di->di_odict, di->di_current);
1823 if (node == NULL) {
Serhiy Storchakab45b7b22015-11-04 22:05:38 +02001824 if (!PyErr_Occurred())
1825 PyErr_SetObject(PyExc_KeyError, di->di_current);
Eric Snow96c6af92015-05-29 22:21:39 -06001826 /* Must have been deleted. */
Eric Snowe3dfa9e2015-05-30 12:51:15 -06001827 Py_CLEAR(di->di_current);
Eric Snow96c6af92015-05-29 22:21:39 -06001828 return NULL;
1829 }
1830 key = di->di_current;
1831
1832 /* Advance to the next key. */
1833 node = reversed ? _odictnode_PREV(node) : _odictnode_NEXT(node);
1834 if (node == NULL) {
1835 /* Reached the end. */
1836 di->di_current = NULL;
1837 }
1838 else {
1839 di->di_current = _odictnode_KEY(node);
1840 Py_INCREF(di->di_current);
1841 }
1842
1843 return key;
Eric Snowa762af72015-06-01 22:59:08 -06001844
1845done:
1846 Py_CLEAR(di->di_odict);
1847 return key;
Eric Snow96c6af92015-05-29 22:21:39 -06001848}
1849
1850static PyObject *
1851odictiter_iternext(odictiterobject *di)
1852{
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001853 PyObject *result, *value;
Eric Snow96c6af92015-05-29 22:21:39 -06001854 PyObject *key = odictiter_nextkey(di); /* new reference */
1855
1856 if (key == NULL)
1857 return NULL;
1858
1859 /* Handle the keys case. */
1860 if (! (di->kind & _odict_ITER_VALUES)) {
1861 return key;
1862 }
1863
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001864 value = PyODict_GetItem((PyObject *)di->di_odict, key); /* borrowed */
1865 if (value == NULL) {
1866 if (!PyErr_Occurred())
1867 PyErr_SetObject(PyExc_KeyError, key);
Eric Snow96c6af92015-05-29 22:21:39 -06001868 Py_DECREF(key);
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001869 goto done;
1870 }
1871 Py_INCREF(value);
1872
1873 /* Handle the values case. */
1874 if (!(di->kind & _odict_ITER_KEYS)) {
1875 Py_DECREF(key);
Eric Snow96c6af92015-05-29 22:21:39 -06001876 return value;
1877 }
Eric Snowa762af72015-06-01 22:59:08 -06001878
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001879 /* Handle the items case. */
1880 result = di->di_result;
1881
1882 if (Py_REFCNT(result) == 1) {
1883 /* not in use so we can reuse it
1884 * (the common case during iteration) */
1885 Py_INCREF(result);
1886 Py_DECREF(PyTuple_GET_ITEM(result, 0)); /* borrowed */
1887 Py_DECREF(PyTuple_GET_ITEM(result, 1)); /* borrowed */
1888 }
1889 else {
1890 result = PyTuple_New(2);
1891 if (result == NULL) {
1892 Py_DECREF(key);
1893 Py_DECREF(value);
1894 goto done;
1895 }
1896 }
1897
1898 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
1899 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
1900 return result;
1901
Eric Snowa762af72015-06-01 22:59:08 -06001902done:
1903 Py_CLEAR(di->di_current);
1904 Py_CLEAR(di->di_odict);
1905 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001906}
1907
1908/* No need for tp_clear because odictiterobject is not mutable. */
1909
1910PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
1911
1912static PyObject *
1913odictiter_reduce(odictiterobject *di)
1914{
Eric Snowc5e59602015-05-30 11:28:56 -06001915 PyObject *list, *iter;
Eric Snow96c6af92015-05-29 22:21:39 -06001916
1917 list = PyList_New(0);
1918 if (!list)
1919 return NULL;
1920
1921 /* iterate the temporary into a list */
1922 for(;;) {
1923 PyObject *element = odictiter_iternext(di);
1924 if (element) {
1925 if (PyList_Append(list, element)) {
1926 Py_DECREF(element);
1927 Py_DECREF(list);
1928 return NULL;
1929 }
1930 Py_DECREF(element);
1931 }
1932 else {
1933 /* done iterating? */
1934 break;
1935 }
1936 }
1937 if (PyErr_Occurred()) {
1938 Py_DECREF(list);
1939 return NULL;
1940 }
Eric Snowc5e59602015-05-30 11:28:56 -06001941 iter = _PyObject_GetBuiltin("iter");
1942 if (iter == NULL) {
1943 Py_DECREF(list);
1944 return NULL;
1945 }
1946 return Py_BuildValue("N(N)", iter, list);
Eric Snow96c6af92015-05-29 22:21:39 -06001947}
1948
1949static PyMethodDef odictiter_methods[] = {
1950 {"__reduce__", (PyCFunction)odictiter_reduce, METH_NOARGS, reduce_doc},
1951 {NULL, NULL} /* sentinel */
1952};
1953
1954PyTypeObject PyODictIter_Type = {
1955 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1956 "odict_iterator", /* tp_name */
1957 sizeof(odictiterobject), /* tp_basicsize */
1958 0, /* tp_itemsize */
1959 /* methods */
1960 (destructor)odictiter_dealloc, /* tp_dealloc */
1961 0, /* tp_print */
1962 0, /* tp_getattr */
1963 0, /* tp_setattr */
1964 0, /* tp_reserved */
1965 0, /* tp_repr */
1966 0, /* tp_as_number */
1967 0, /* tp_as_sequence */
1968 0, /* tp_as_mapping */
1969 0, /* tp_hash */
1970 0, /* tp_call */
1971 0, /* tp_str */
1972 PyObject_GenericGetAttr, /* tp_getattro */
1973 0, /* tp_setattro */
1974 0, /* tp_as_buffer */
1975 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1976 0, /* tp_doc */
1977 (traverseproc)odictiter_traverse, /* tp_traverse */
1978 0, /* tp_clear */
1979 0, /* tp_richcompare */
1980 0, /* tp_weaklistoffset */
1981 PyObject_SelfIter, /* tp_iter */
1982 (iternextfunc)odictiter_iternext, /* tp_iternext */
1983 odictiter_methods, /* tp_methods */
1984 0,
1985};
1986
1987static PyObject *
1988odictiter_new(PyODictObject *od, int kind)
1989{
1990 odictiterobject *di;
1991 _ODictNode *node;
1992 int reversed = kind & _odict_ITER_REVERSED;
1993
1994 di = PyObject_GC_New(odictiterobject, &PyODictIter_Type);
1995 if (di == NULL)
1996 return NULL;
1997
1998 if (kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)){
1999 di->di_result = PyTuple_Pack(2, Py_None, Py_None);
2000 if (di->di_result == NULL) {
2001 Py_DECREF(di);
2002 return NULL;
2003 }
2004 }
2005 else
2006 di->di_result = NULL;
2007
2008 di->kind = kind;
2009 node = reversed ? _odict_LAST(od) : _odict_FIRST(od);
2010 di->di_current = node ? _odictnode_KEY(node) : NULL;
2011 Py_XINCREF(di->di_current);
Eric Snowb952ab42015-06-01 23:35:13 -06002012 di->di_size = PyODict_SIZE(od);
Eric Snow4fabf022015-06-04 00:09:56 -06002013 di->di_state = od->od_state;
Eric Snow96c6af92015-05-29 22:21:39 -06002014 di->di_odict = od;
2015 Py_INCREF(od);
2016
2017 _PyObject_GC_TRACK(di);
2018 return (PyObject *)di;
2019}
2020
2021/* keys() */
2022
2023static PyObject *
2024odictkeys_iter(_PyDictViewObject *dv)
2025{
2026 if (dv->dv_dict == NULL) {
2027 Py_RETURN_NONE;
2028 }
2029 return odictiter_new((PyODictObject *)dv->dv_dict,
2030 _odict_ITER_KEYS);
2031}
2032
2033static PyObject *
2034odictkeys_reversed(_PyDictViewObject *dv)
2035{
2036 if (dv->dv_dict == NULL) {
2037 Py_RETURN_NONE;
2038 }
2039 return odictiter_new((PyODictObject *)dv->dv_dict,
2040 _odict_ITER_KEYS|_odict_ITER_REVERSED);
2041}
2042
2043static PyMethodDef odictkeys_methods[] = {
2044 {"__reversed__", (PyCFunction)odictkeys_reversed, METH_NOARGS, NULL},
2045 {NULL, NULL} /* sentinel */
2046};
2047
2048PyTypeObject PyODictKeys_Type = {
2049 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2050 "odict_keys", /* tp_name */
2051 0, /* tp_basicsize */
2052 0, /* tp_itemsize */
2053 0, /* tp_dealloc */
2054 0, /* tp_print */
2055 0, /* tp_getattr */
2056 0, /* tp_setattr */
2057 0, /* tp_reserved */
2058 0, /* tp_repr */
2059 0, /* tp_as_number */
2060 0, /* tp_as_sequence */
2061 0, /* tp_as_mapping */
2062 0, /* tp_hash */
2063 0, /* tp_call */
2064 0, /* tp_str */
2065 0, /* tp_getattro */
2066 0, /* tp_setattro */
2067 0, /* tp_as_buffer */
2068 0, /* tp_flags */
2069 0, /* tp_doc */
2070 0, /* tp_traverse */
2071 0, /* tp_clear */
2072 0, /* tp_richcompare */
2073 0, /* tp_weaklistoffset */
2074 (getiterfunc)odictkeys_iter, /* tp_iter */
2075 0, /* tp_iternext */
2076 odictkeys_methods, /* tp_methods */
2077 0, /* tp_members */
2078 0, /* tp_getset */
2079 &PyDictKeys_Type, /* tp_base */
2080};
2081
2082static PyObject *
2083odictkeys_new(PyObject *od)
2084{
2085 return _PyDictView_New(od, &PyODictKeys_Type);
2086}
2087
2088/* items() */
2089
2090static PyObject *
2091odictitems_iter(_PyDictViewObject *dv)
2092{
2093 if (dv->dv_dict == NULL) {
2094 Py_RETURN_NONE;
2095 }
2096 return odictiter_new((PyODictObject *)dv->dv_dict,
2097 _odict_ITER_KEYS|_odict_ITER_VALUES);
2098}
2099
2100static PyObject *
2101odictitems_reversed(_PyDictViewObject *dv)
2102{
2103 if (dv->dv_dict == NULL) {
2104 Py_RETURN_NONE;
2105 }
2106 return odictiter_new((PyODictObject *)dv->dv_dict,
2107 _odict_ITER_KEYS|_odict_ITER_VALUES|_odict_ITER_REVERSED);
2108}
2109
2110static PyMethodDef odictitems_methods[] = {
2111 {"__reversed__", (PyCFunction)odictitems_reversed, METH_NOARGS, NULL},
2112 {NULL, NULL} /* sentinel */
2113};
2114
2115PyTypeObject PyODictItems_Type = {
2116 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2117 "odict_items", /* tp_name */
2118 0, /* tp_basicsize */
2119 0, /* tp_itemsize */
2120 0, /* tp_dealloc */
2121 0, /* tp_print */
2122 0, /* tp_getattr */
2123 0, /* tp_setattr */
2124 0, /* tp_reserved */
2125 0, /* tp_repr */
2126 0, /* tp_as_number */
2127 0, /* tp_as_sequence */
2128 0, /* tp_as_mapping */
2129 0, /* tp_hash */
2130 0, /* tp_call */
2131 0, /* tp_str */
2132 0, /* tp_getattro */
2133 0, /* tp_setattro */
2134 0, /* tp_as_buffer */
2135 0, /* tp_flags */
2136 0, /* tp_doc */
2137 0, /* tp_traverse */
2138 0, /* tp_clear */
2139 0, /* tp_richcompare */
2140 0, /* tp_weaklistoffset */
2141 (getiterfunc)odictitems_iter, /* tp_iter */
2142 0, /* tp_iternext */
2143 odictitems_methods, /* tp_methods */
2144 0, /* tp_members */
2145 0, /* tp_getset */
2146 &PyDictItems_Type, /* tp_base */
2147};
2148
2149static PyObject *
2150odictitems_new(PyObject *od)
2151{
2152 return _PyDictView_New(od, &PyODictItems_Type);
2153}
2154
2155/* values() */
2156
2157static PyObject *
2158odictvalues_iter(_PyDictViewObject *dv)
2159{
2160 if (dv->dv_dict == NULL) {
2161 Py_RETURN_NONE;
2162 }
2163 return odictiter_new((PyODictObject *)dv->dv_dict,
2164 _odict_ITER_VALUES);
2165}
2166
2167static PyObject *
2168odictvalues_reversed(_PyDictViewObject *dv)
2169{
2170 if (dv->dv_dict == NULL) {
2171 Py_RETURN_NONE;
2172 }
2173 return odictiter_new((PyODictObject *)dv->dv_dict,
2174 _odict_ITER_VALUES|_odict_ITER_REVERSED);
2175}
2176
2177static PyMethodDef odictvalues_methods[] = {
2178 {"__reversed__", (PyCFunction)odictvalues_reversed, METH_NOARGS, NULL},
2179 {NULL, NULL} /* sentinel */
2180};
2181
2182PyTypeObject PyODictValues_Type = {
2183 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2184 "odict_values", /* tp_name */
2185 0, /* tp_basicsize */
2186 0, /* tp_itemsize */
2187 0, /* tp_dealloc */
2188 0, /* tp_print */
2189 0, /* tp_getattr */
2190 0, /* tp_setattr */
2191 0, /* tp_reserved */
2192 0, /* tp_repr */
2193 0, /* tp_as_number */
2194 0, /* tp_as_sequence */
2195 0, /* tp_as_mapping */
2196 0, /* tp_hash */
2197 0, /* tp_call */
2198 0, /* tp_str */
2199 0, /* tp_getattro */
2200 0, /* tp_setattro */
2201 0, /* tp_as_buffer */
2202 0, /* tp_flags */
2203 0, /* tp_doc */
2204 0, /* tp_traverse */
2205 0, /* tp_clear */
2206 0, /* tp_richcompare */
2207 0, /* tp_weaklistoffset */
2208 (getiterfunc)odictvalues_iter, /* tp_iter */
2209 0, /* tp_iternext */
2210 odictvalues_methods, /* tp_methods */
2211 0, /* tp_members */
2212 0, /* tp_getset */
2213 &PyDictValues_Type, /* tp_base */
2214};
2215
2216static PyObject *
2217odictvalues_new(PyObject *od)
2218{
2219 return _PyDictView_New(od, &PyODictValues_Type);
2220}
2221
2222
2223/* ----------------------------------------------
Martin Panter536d70e2017-01-14 08:23:08 +00002224 MutableMapping implementations
Eric Snow96c6af92015-05-29 22:21:39 -06002225
2226Mapping:
2227
2228============ ===========
2229method uses
2230============ ===========
2231__contains__ __getitem__
2232__eq__ items
2233__getitem__ +
2234__iter__ +
2235__len__ +
2236__ne__ __eq__
2237get __getitem__
2238items ItemsView
2239keys KeysView
2240values ValuesView
2241============ ===========
2242
2243ItemsView uses __len__, __iter__, and __getitem__.
2244KeysView uses __len__, __iter__, and __contains__.
2245ValuesView uses __len__, __iter__, and __getitem__.
2246
2247MutableMapping:
2248
2249============ ===========
2250method uses
2251============ ===========
2252__delitem__ +
2253__setitem__ +
2254clear popitem
2255pop __getitem__
2256 __delitem__
2257popitem __iter__
2258 _getitem__
2259 __delitem__
2260setdefault __getitem__
2261 __setitem__
2262update __setitem__
2263============ ===========
2264*/
2265
2266static int
2267mutablemapping_add_pairs(PyObject *self, PyObject *pairs)
2268{
2269 PyObject *pair, *iterator, *unexpected;
2270 int res = 0;
2271
2272 iterator = PyObject_GetIter(pairs);
2273 if (iterator == NULL)
2274 return -1;
2275 PyErr_Clear();
2276
2277 while ((pair = PyIter_Next(iterator)) != NULL) {
2278 /* could be more efficient (see UNPACK_SEQUENCE in ceval.c) */
Eric Snowc5e59602015-05-30 11:28:56 -06002279 PyObject *key = NULL, *value = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06002280 PyObject *pair_iterator = PyObject_GetIter(pair);
Eric Snowc5e59602015-05-30 11:28:56 -06002281 if (pair_iterator == NULL)
2282 goto Done;
Eric Snow96c6af92015-05-29 22:21:39 -06002283
2284 key = PyIter_Next(pair_iterator);
2285 if (key == NULL) {
2286 if (!PyErr_Occurred())
2287 PyErr_SetString(PyExc_ValueError,
2288 "need more than 0 values to unpack");
2289 goto Done;
2290 }
2291
2292 value = PyIter_Next(pair_iterator);
2293 if (value == NULL) {
2294 if (!PyErr_Occurred())
2295 PyErr_SetString(PyExc_ValueError,
2296 "need more than 1 value to unpack");
2297 goto Done;
2298 }
2299
2300 unexpected = PyIter_Next(pair_iterator);
2301 if (unexpected != NULL) {
2302 Py_DECREF(unexpected);
2303 PyErr_SetString(PyExc_ValueError,
2304 "too many values to unpack (expected 2)");
2305 goto Done;
2306 }
2307 else if (PyErr_Occurred())
2308 goto Done;
2309
2310 res = PyObject_SetItem(self, key, value);
2311
2312Done:
2313 Py_DECREF(pair);
Eric Snowc5e59602015-05-30 11:28:56 -06002314 Py_XDECREF(pair_iterator);
Eric Snow96c6af92015-05-29 22:21:39 -06002315 Py_XDECREF(key);
2316 Py_XDECREF(value);
2317 if (PyErr_Occurred())
2318 break;
2319 }
2320 Py_DECREF(iterator);
2321
2322 if (res < 0 || PyErr_Occurred() != NULL)
2323 return -1;
2324 else
2325 return 0;
2326}
2327
2328static PyObject *
2329mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
2330{
2331 int res = 0;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002332 Py_ssize_t len;
2333 _Py_IDENTIFIER(items);
2334 _Py_IDENTIFIER(keys);
Eric Snow96c6af92015-05-29 22:21:39 -06002335
2336 /* first handle args, if any */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002337 assert(args == NULL || PyTuple_Check(args));
2338 len = (args != NULL) ? PyTuple_GET_SIZE(args) : 0;
Benjamin Peterson99e96f22015-06-06 23:20:32 -05002339 if (len > 1) {
Serhiy Storchakae2f92de2017-11-11 13:06:26 +02002340 const char *msg = "update() takes at most 1 positional argument (%d given)";
Eric Snow96c6af92015-05-29 22:21:39 -06002341 PyErr_Format(PyExc_TypeError, msg, len);
2342 return NULL;
2343 }
Eric Snow96c6af92015-05-29 22:21:39 -06002344
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002345 if (len) {
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002346 PyObject *func;
Benjamin Peterson0718de92015-06-07 00:00:42 -05002347 PyObject *other = PyTuple_GET_ITEM(args, 0); /* borrowed reference */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002348 assert(other != NULL);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002349 Py_INCREF(other);
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002350 if (PyDict_CheckExact(other)) {
2351 PyObject *items = PyDict_Items(other);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002352 Py_DECREF(other);
2353 if (items == NULL)
2354 return NULL;
2355 res = mutablemapping_add_pairs(self, items);
2356 Py_DECREF(items);
2357 if (res == -1)
2358 return NULL;
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002359 goto handle_kwargs;
Benjamin Peterson0718de92015-06-07 00:00:42 -05002360 }
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002361
Serhiy Storchakaf320be72018-01-25 10:49:40 +02002362 if (_PyObject_LookupAttrId(other, &PyId_keys, &func) < 0) {
2363 Py_DECREF(other);
2364 return NULL;
2365 }
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002366 if (func != NULL) {
Benjamin Peterson0718de92015-06-07 00:00:42 -05002367 PyObject *keys, *iterator, *key;
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002368 keys = _PyObject_CallNoArg(func);
2369 Py_DECREF(func);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002370 if (keys == NULL) {
2371 Py_DECREF(other);
2372 return NULL;
2373 }
2374 iterator = PyObject_GetIter(keys);
2375 Py_DECREF(keys);
2376 if (iterator == NULL) {
2377 Py_DECREF(other);
2378 return NULL;
2379 }
2380 while (res == 0 && (key = PyIter_Next(iterator))) {
2381 PyObject *value = PyObject_GetItem(other, key);
2382 if (value != NULL) {
2383 res = PyObject_SetItem(self, key, value);
2384 Py_DECREF(value);
2385 }
2386 else {
2387 res = -1;
2388 }
2389 Py_DECREF(key);
2390 }
2391 Py_DECREF(other);
2392 Py_DECREF(iterator);
2393 if (res != 0 || PyErr_Occurred())
2394 return NULL;
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002395 goto handle_kwargs;
Benjamin Peterson0718de92015-06-07 00:00:42 -05002396 }
Serhiy Storchakaf320be72018-01-25 10:49:40 +02002397
2398 if (_PyObject_LookupAttrId(other, &PyId_items, &func) < 0) {
Eric Snow06aed902016-09-09 11:59:08 -07002399 Py_DECREF(other);
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002400 return NULL;
2401 }
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002402 if (func != NULL) {
2403 PyObject *items;
2404 Py_DECREF(other);
2405 items = _PyObject_CallNoArg(func);
2406 Py_DECREF(func);
Eric Snow06aed902016-09-09 11:59:08 -07002407 if (items == NULL)
2408 return NULL;
2409 res = mutablemapping_add_pairs(self, items);
2410 Py_DECREF(items);
2411 if (res == -1)
2412 return NULL;
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002413 goto handle_kwargs;
2414 }
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002415
2416 res = mutablemapping_add_pairs(self, other);
2417 Py_DECREF(other);
2418 if (res != 0)
2419 return NULL;
Benjamin Peterson0718de92015-06-07 00:00:42 -05002420 }
2421
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002422 handle_kwargs:
Benjamin Peterson0718de92015-06-07 00:00:42 -05002423 /* now handle kwargs */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002424 assert(kwargs == NULL || PyDict_Check(kwargs));
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02002425 if (kwargs != NULL && PyDict_GET_SIZE(kwargs)) {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002426 PyObject *items = PyDict_Items(kwargs);
Eric Snow96c6af92015-05-29 22:21:39 -06002427 if (items == NULL)
2428 return NULL;
2429 res = mutablemapping_add_pairs(self, items);
2430 Py_DECREF(items);
2431 if (res == -1)
2432 return NULL;
2433 }
Eric Snow96c6af92015-05-29 22:21:39 -06002434
2435 Py_RETURN_NONE;
2436}