blob: 6c75a42f4ee73e8c97742dfb3a39cc7f6a5b9ef5 [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
Robert Krzyzanowski6f19fc62018-07-06 05:54:26 -050070that end, we use a simple API to interact with the linked-list. Here's a
Eric Snow96c6af92015-05-29 22:21:39 -060071summary 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
Eric Snow96c6af92015-05-29 22:21:39 -0600104And here's a look at how the linked-list relates to the OrderedDict API:
105
106============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
107method key val prev next mem 1st last empty iter find add rmv clr keq
108============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
109__del__ ~ X
110__delitem__ free ~ node
111__eq__ ~ X
112__iter__ X X
113__new__ X X
114__reduce__ X ~ X
115__repr__ X X X
116__reversed__ X X
117__setitem__ key
118__sizeof__ size X
119clear ~ ~ X
120copy X X X
121items X X X
122keys X X
123move_to_end X X X ~ h/t key
124pop free key
125popitem X X free X X node
126setdefault ~ ? ~
127values X X
128============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
129
130__delitem__ is the only method that directly relies on finding an arbitrary
131node in the linked-list. Everything else is iteration or relates to the
132ends of the linked-list.
133
134Situation that Endangers Consistency
135------------------------------------
136Using a raw linked-list for OrderedDict exposes a key situation that can
137cause problems. If a node is stored in a variable, there is a chance that
138the node may have been deallocated before the variable gets used, thus
139potentially leading to a segmentation fault. A key place where this shows
140up is during iteration through the linked list (via _odict_FOREACH or
141otherwise).
142
143A number of solutions are available to resolve this situation:
144
145* defer looking up the node until as late as possible and certainly after
146 any code that could possibly result in a deletion;
147* if the node is needed both before and after a point where the node might
148 be removed, do a check before using the node at the "after" location to
149 see if the node is still valid;
150* like the last one, but simply pull the node again to ensure it's right;
151* keep the key in the variable instead of the node and then look up the
152 node using the key at the point where the node is needed (this is what
153 we do for the iterators).
154
155Another related problem, preserving consistent ordering during iteration,
156is described below. That one is not exclusive to using linked-lists.
157
158
159Challenges from Subclassing dict
160================================
161
162OrderedDict subclasses dict, which is an unusual relationship between two
163builtin types (other than the base object type). Doing so results in
164some complication and deserves further explanation. There are two things
165to consider here. First, in what circumstances or with what adjustments
166can OrderedDict be used as a drop-in replacement for dict (at the C level)?
167Second, how can the OrderedDict implementation leverage the dict
168implementation effectively without introducing unnecessary coupling or
169inefficiencies?
170
171This second point is reflected here and in the implementation, so the
172further focus is on the first point. It is worth noting that for
173overridden methods, the dict implementation is deferred to as much as
174possible. Furthermore, coupling is limited to as little as is reasonable.
175
176Concrete API Compatibility
177--------------------------
178
179Use of the concrete C-API for dict (PyDict_*) with OrderedDict is
180problematic. (See http://bugs.python.org/issue10977.) The concrete API
181has a number of hard-coded assumptions tied to the dict implementation.
182This is, in part, due to performance reasons, which is understandable
183given the part dict plays in Python.
184
185Any attempt to replace dict with OrderedDict for any role in the
186interpreter (e.g. **kwds) faces a challenge. Such any effort must
187recognize that the instances in affected locations currently interact with
188the concrete API.
189
190Here are some ways to address this challenge:
191
1921. Change the relevant usage of the concrete API in CPython and add
Martin Panter69332c12016-08-04 13:07:31 +0000193 PyDict_CheckExact() calls to each of the concrete API functions.
Eric Snow96c6af92015-05-29 22:21:39 -06001942. Adjust the relevant concrete API functions to explicitly accommodate
195 OrderedDict.
1963. As with #1, add the checks, but improve the abstract API with smart fast
197 paths for dict and OrderedDict, and refactor CPython to use the abstract
198 API. Improvements to the abstract API would be valuable regardless.
199
200Adding the checks to the concrete API would help make any interpreter
201switch to OrderedDict less painful for extension modules. However, this
202won't work. The equivalent C API call to `dict.__setitem__(obj, k, v)`
203is 'PyDict_SetItem(obj, k, v)`. This illustrates how subclasses in C call
204the base class's methods, since there is no equivalent of super() in the
205C API. Calling into Python for parent class API would work, but some
206extension modules already rely on this feature of the concrete API.
207
208For reference, here is a breakdown of some of the dict concrete API:
209
210========================== ============= =======================
211concrete API uses abstract API
212========================== ============= =======================
213PyDict_Check PyMapping_Check
214(PyDict_CheckExact) -
215(PyDict_New) -
216(PyDictProxy_New) -
217PyDict_Clear -
218PyDict_Contains PySequence_Contains
219PyDict_Copy -
220PyDict_SetItem PyObject_SetItem
221PyDict_SetItemString PyMapping_SetItemString
222PyDict_DelItem PyMapping_DelItem
223PyDict_DelItemString PyMapping_DelItemString
224PyDict_GetItem -
225PyDict_GetItemWithError PyObject_GetItem
226_PyDict_GetItemIdWithError -
227PyDict_GetItemString PyMapping_GetItemString
228PyDict_Items PyMapping_Items
229PyDict_Keys PyMapping_Keys
230PyDict_Values PyMapping_Values
231PyDict_Size PyMapping_Size
232 PyMapping_Length
233PyDict_Next PyIter_Next
234_PyDict_Next -
235PyDict_Merge -
236PyDict_Update -
237PyDict_MergeFromSeq2 -
238PyDict_ClearFreeList -
239- PyMapping_HasKeyString
240- PyMapping_HasKey
241========================== ============= =======================
242
243
244The dict Interface Relative to OrderedDict
245==========================================
246
247Since OrderedDict subclasses dict, understanding the various methods and
248attributes of dict is important for implementing OrderedDict.
249
250Relevant Type Slots
251-------------------
252
253================= ================ =================== ================
254slot attribute object dict
255================= ================ =================== ================
256tp_dealloc - object_dealloc dict_dealloc
257tp_repr __repr__ object_repr dict_repr
258sq_contains __contains__ - dict_contains
259mp_length __len__ - dict_length
260mp_subscript __getitem__ - dict_subscript
261mp_ass_subscript __setitem__ - dict_ass_sub
262 __delitem__
263tp_hash __hash__ _Py_HashPointer ..._HashNotImpl
264tp_str __str__ object_str -
265tp_getattro __getattribute__ ..._GenericGetAttr (repeated)
266 __getattr__
267tp_setattro __setattr__ ..._GenericSetAttr (disabled)
268tp_doc __doc__ (literal) dictionary_doc
269tp_traverse - - dict_traverse
270tp_clear - - dict_tp_clear
271tp_richcompare __eq__ object_richcompare dict_richcompare
272 __ne__
273tp_weaklistoffset (__weakref__) - -
274tp_iter __iter__ - dict_iter
275tp_dictoffset (__dict__) - -
276tp_init __init__ object_init dict_init
277tp_alloc - PyType_GenericAlloc (repeated)
278tp_new __new__ object_new dict_new
279tp_free - PyObject_Del PyObject_GC_Del
280================= ================ =================== ================
281
282Relevant Methods
283----------------
284
285================ =================== ===============
286method object dict
287================ =================== ===============
288__reduce__ object_reduce -
289__sizeof__ object_sizeof dict_sizeof
290clear - dict_clear
291copy - dict_copy
292fromkeys - dict_fromkeys
293get - dict_get
294items - dictitems_new
295keys - dictkeys_new
296pop - dict_pop
297popitem - dict_popitem
298setdefault - dict_setdefault
299update - dict_update
300values - dictvalues_new
301================ =================== ===============
302
303
304Pure Python OrderedDict
305=======================
306
307As already noted, compatibility with the pure Python OrderedDict
308implementation is a key goal of this C implementation. To further that
309goal, here's a summary of how OrderedDict-specific methods are implemented
310in collections/__init__.py. Also provided is an indication of which
311methods directly mutate or iterate the object, as well as any relationship
312with the underlying linked-list.
313
314============= ============== == ================ === === ====
315method impl used ll uses inq mut iter
316============= ============== == ================ === === ====
317__contains__ dict - - X
318__delitem__ OrderedDict Y dict.__delitem__ X
319__eq__ OrderedDict N OrderedDict ~
320 dict.__eq__
321 __iter__
322__getitem__ dict - - X
323__iter__ OrderedDict Y - X
324__init__ OrderedDict N update
325__len__ dict - - X
326__ne__ MutableMapping - __eq__ ~
327__reduce__ OrderedDict N OrderedDict ~
328 __iter__
329 __getitem__
330__repr__ OrderedDict N __class__ ~
331 items
332__reversed__ OrderedDict Y - X
333__setitem__ OrderedDict Y __contains__ X
334 dict.__setitem__
335__sizeof__ OrderedDict Y __len__ ~
336 __dict__
337clear OrderedDict Y dict.clear X
338copy OrderedDict N __class__
339 __init__
340fromkeys OrderedDict N __setitem__
341get dict - - ~
342items MutableMapping - ItemsView X
343keys MutableMapping - KeysView X
344move_to_end OrderedDict Y - X
345pop OrderedDict N __contains__ X
346 __getitem__
347 __delitem__
348popitem OrderedDict Y dict.pop X
349setdefault OrderedDict N __contains__ ~
350 __getitem__
351 __setitem__
352update MutableMapping - __setitem__ ~
353values MutableMapping - ValuesView X
354============= ============== == ================ === === ====
355
356__reversed__ and move_to_end are both exclusive to OrderedDict.
357
358
359C OrderedDict Implementation
360============================
361
362================= ================
363slot impl
364================= ================
365tp_dealloc odict_dealloc
366tp_repr odict_repr
367mp_ass_subscript odict_ass_sub
368tp_doc odict_doc
369tp_traverse odict_traverse
370tp_clear odict_tp_clear
371tp_richcompare odict_richcompare
372tp_weaklistoffset (offset)
373tp_iter odict_iter
374tp_dictoffset (offset)
375tp_init odict_init
376tp_alloc (repeated)
Eric Snow96c6af92015-05-29 22:21:39 -0600377================= ================
378
379================= ================
380method impl
381================= ================
382__reduce__ odict_reduce
383__sizeof__ odict_sizeof
384clear odict_clear
385copy odict_copy
386fromkeys odict_fromkeys
387items odictitems_new
388keys odictkeys_new
389pop odict_pop
390popitem odict_popitem
391setdefault odict_setdefault
392update odict_update
393values odictvalues_new
394================= ================
395
396Inherited unchanged from object/dict:
397
398================ ==========================
399method type field
400================ ==========================
401- tp_free
402__contains__ tp_as_sequence.sq_contains
403__getattr__ tp_getattro
404__getattribute__ tp_getattro
405__getitem__ tp_as_mapping.mp_subscript
406__hash__ tp_hash
407__len__ tp_as_mapping.mp_length
408__setattr__ tp_setattro
409__str__ tp_str
410get -
411================ ==========================
412
413
414Other Challenges
415================
416
417Preserving Ordering During Iteration
418------------------------------------
419During iteration through an OrderedDict, it is possible that items could
420get added, removed, or reordered. For a linked-list implementation, as
421with some other implementations, that situation may lead to undefined
422behavior. The documentation for dict mentions this in the `iter()` section
423of http://docs.python.org/3.4/library/stdtypes.html#dictionary-view-objects.
424In this implementation we follow dict's lead (as does the pure Python
425implementation) for __iter__(), keys(), values(), and items().
426
427For internal iteration (using _odict_FOREACH or not), there is still the
428risk that not all nodes that we expect to be seen in the loop actually get
429seen. Thus, we are careful in each of those places to ensure that they
430are. This comes, of course, at a small price at each location. The
431solutions are much the same as those detailed in the `Situation that
432Endangers Consistency` section above.
433
434
435Potential Optimizations
436=======================
437
438* Allocate the nodes as a block via od_fast_nodes instead of individually.
439 - Set node->key to NULL to indicate the node is not-in-use.
440 - Add _odict_EXISTS()?
441 - How to maintain consistency across resizes? Existing node pointers
Robert Krzyzanowski6f19fc62018-07-06 05:54:26 -0500442 would be invalidated after a resize, which is particularly problematic
Eric Snow96c6af92015-05-29 22:21:39 -0600443 for the iterators.
444* Use a more stream-lined implementation of update() and, likely indirectly,
445 __init__().
446
447*/
448
449/* TODO
450
451sooner:
452- reentrancy (make sure everything is at a thread-safe state when calling
453 into Python). I've already checked this multiple times, but want to
454 make one more pass.
455- add unit tests for reentrancy?
456
457later:
458- make the dict views support the full set API (the pure Python impl does)
459- implement a fuller MutableMapping API in C?
460- move the MutableMapping implementation to abstract.c?
461- optimize mutablemapping_update
462- use PyObject_MALLOC (small object allocator) for odict nodes?
463- support subclasses better (e.g. in odict_richcompare)
464
465*/
466
467#include "Python.h"
Victor Stinnerbcda8f12018-11-21 22:27:47 +0100468#include "pycore_object.h"
Victor Stinner621cebe2018-11-12 16:53:38 +0100469#include "pycore_pystate.h"
Eric Snow96c6af92015-05-29 22:21:39 -0600470#include "structmember.h"
471#include "dict-common.h"
472#include <stddef.h>
473
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100474#include "clinic/odictobject.c.h"
475
476/*[clinic input]
477class OrderedDict "PyODictObject *" "&PyODict_Type"
478[clinic start generated code]*/
479/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ca0641cf6143d4af]*/
480
Eric Snow96c6af92015-05-29 22:21:39 -0600481
482typedef struct _odictnode _ODictNode;
483
484/* PyODictObject */
485struct _odictobject {
Eric Snow4fabf022015-06-04 00:09:56 -0600486 PyDictObject od_dict; /* the underlying dict */
487 _ODictNode *od_first; /* first node in the linked list, if any */
488 _ODictNode *od_last; /* last node in the linked list, if any */
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200489 /* od_fast_nodes, od_fast_nodes_size and od_resize_sentinel are managed
490 * by _odict_resize().
Eric Snow8c7f9552015-08-07 17:45:12 -0600491 * Note that we rely on implementation details of dict for both. */
492 _ODictNode **od_fast_nodes; /* hash table that mirrors the dict table */
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200493 Py_ssize_t od_fast_nodes_size;
494 void *od_resize_sentinel; /* changes if odict should be resized */
Eric Snow8c7f9552015-08-07 17:45:12 -0600495
Eric Snow4fabf022015-06-04 00:09:56 -0600496 size_t od_state; /* incremented whenever the LL changes */
497 PyObject *od_inst_dict; /* OrderedDict().__dict__ */
498 PyObject *od_weakreflist; /* holds weakrefs to the odict */
Eric Snow96c6af92015-05-29 22:21:39 -0600499};
500
501
502/* ----------------------------------------------
503 * odict keys (a simple doubly-linked list)
504 */
505
506struct _odictnode {
507 PyObject *key;
Eric Snow4c729182015-06-03 10:50:37 -0600508 Py_hash_t hash;
Eric Snow96c6af92015-05-29 22:21:39 -0600509 _ODictNode *next;
510 _ODictNode *prev;
511};
512
513#define _odictnode_KEY(node) \
514 (node->key)
Eric Snow4c729182015-06-03 10:50:37 -0600515#define _odictnode_HASH(node) \
516 (node->hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600517/* borrowed reference */
518#define _odictnode_VALUE(node, od) \
Eric Snowa762af72015-06-01 22:59:08 -0600519 PyODict_GetItemWithError((PyObject *)od, _odictnode_KEY(node))
Eric Snow96c6af92015-05-29 22:21:39 -0600520#define _odictnode_PREV(node) (node->prev)
521#define _odictnode_NEXT(node) (node->next)
522
523#define _odict_FIRST(od) (((PyODictObject *)od)->od_first)
524#define _odict_LAST(od) (((PyODictObject *)od)->od_last)
525#define _odict_EMPTY(od) (_odict_FIRST(od) == NULL)
526#define _odict_FOREACH(od, node) \
527 for (node = _odict_FIRST(od); node != NULL; node = _odictnode_NEXT(node))
528
Eric Snow4c729182015-06-03 10:50:37 -0600529/* Return the index into the hash table, regardless of a valid node. */
530static Py_ssize_t
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200531_odict_get_index_raw(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow4c729182015-06-03 10:50:37 -0600532{
INADA Naokiba609772016-12-07 20:41:42 +0900533 PyObject *value = NULL;
Eric Snow4c729182015-06-03 10:50:37 -0600534 PyDictKeysObject *keys = ((PyDictObject *)od)->ma_keys;
Victor Stinner742da042016-09-07 17:40:12 -0700535 Py_ssize_t ix;
Eric Snow4c729182015-06-03 10:50:37 -0600536
INADA Naoki778928b2017-08-03 23:45:15 +0900537 ix = (keys->dk_lookup)((PyDictObject *)od, key, hash, &value);
Victor Stinner742da042016-09-07 17:40:12 -0700538 if (ix == DKIX_EMPTY) {
539 return keys->dk_nentries; /* index of new entry */
540 }
541 if (ix < 0)
Eric Snow4c729182015-06-03 10:50:37 -0600542 return -1;
543 /* We use pointer arithmetic to get the entry's index into the table. */
Victor Stinner742da042016-09-07 17:40:12 -0700544 return ix;
Eric Snow4c729182015-06-03 10:50:37 -0600545}
546
547/* Replace od->od_fast_nodes with a new table matching the size of dict's. */
Eric Snow96c6af92015-05-29 22:21:39 -0600548static int
Serhiy Storchaka6f17e512018-10-20 02:27:45 +0300549_odict_resize(PyODictObject *od)
550{
Eric Snow4c729182015-06-03 10:50:37 -0600551 Py_ssize_t size, i;
Eric Snow96c6af92015-05-29 22:21:39 -0600552 _ODictNode **fast_nodes, *node;
553
554 /* Initialize a new "fast nodes" table. */
555 size = ((PyDictObject *)od)->ma_keys->dk_size;
556 fast_nodes = PyMem_NEW(_ODictNode *, size);
557 if (fast_nodes == NULL) {
558 PyErr_NoMemory();
559 return -1;
560 }
561 for (i = 0; i < size; i++)
562 fast_nodes[i] = NULL;
563
564 /* Copy the current nodes into the table. */
Eric Snow96c6af92015-05-29 22:21:39 -0600565 _odict_FOREACH(od, node) {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200566 i = _odict_get_index_raw(od, _odictnode_KEY(node),
Victor Stinner742da042016-09-07 17:40:12 -0700567 _odictnode_HASH(node));
Eric Snow96c6af92015-05-29 22:21:39 -0600568 if (i < 0) {
Eric Snow96c6af92015-05-29 22:21:39 -0600569 PyMem_FREE(fast_nodes);
570 return -1;
571 }
572 fast_nodes[i] = node;
573 }
Eric Snow96c6af92015-05-29 22:21:39 -0600574
575 /* Replace the old fast nodes table. */
Serhiy Storchaka6f17e512018-10-20 02:27:45 +0300576 PyMem_FREE(od->od_fast_nodes);
Eric Snow96c6af92015-05-29 22:21:39 -0600577 od->od_fast_nodes = fast_nodes;
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200578 od->od_fast_nodes_size = size;
579 od->od_resize_sentinel = ((PyDictObject *)od)->ma_keys;
Eric Snow96c6af92015-05-29 22:21:39 -0600580 return 0;
581}
582
583/* Return the index into the hash table, regardless of a valid node. */
584static Py_ssize_t
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200585_odict_get_index(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600586{
Eric Snow4c729182015-06-03 10:50:37 -0600587 PyDictKeysObject *keys;
Eric Snow96c6af92015-05-29 22:21:39 -0600588
589 assert(key != NULL);
Eric Snow4c729182015-06-03 10:50:37 -0600590 keys = ((PyDictObject *)od)->ma_keys;
591
592 /* Ensure od_fast_nodes and dk_entries are in sync. */
Serhiy Storchaka97f46db2015-11-06 12:00:03 +0200593 if (od->od_resize_sentinel != keys ||
594 od->od_fast_nodes_size != keys->dk_size) {
Eric Snow4c729182015-06-03 10:50:37 -0600595 int resize_res = _odict_resize(od);
596 if (resize_res < 0)
597 return -1;
598 }
599
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200600 return _odict_get_index_raw(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 *
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200605_odict_find_node_hash(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600606{
607 Py_ssize_t index;
608
609 if (_odict_EMPTY(od))
610 return NULL;
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200611 index = _odict_get_index(od, key, hash);
612 if (index < 0)
613 return NULL;
Serhiy Storchaka6f17e512018-10-20 02:27:45 +0300614 assert(od->od_fast_nodes != NULL);
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200615 return od->od_fast_nodes[index];
616}
617
618static _ODictNode *
619_odict_find_node(PyODictObject *od, PyObject *key)
620{
621 Py_ssize_t index;
622 Py_hash_t hash;
623
624 if (_odict_EMPTY(od))
625 return NULL;
626 hash = PyObject_Hash(key);
627 if (hash == -1)
628 return NULL;
629 index = _odict_get_index(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600630 if (index < 0)
631 return NULL;
Serhiy Storchaka6f17e512018-10-20 02:27:45 +0300632 assert(od->od_fast_nodes != NULL);
Eric Snow96c6af92015-05-29 22:21:39 -0600633 return od->od_fast_nodes[index];
634}
635
636static void
637_odict_add_head(PyODictObject *od, _ODictNode *node)
638{
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300639 _odictnode_PREV(node) = NULL;
640 _odictnode_NEXT(node) = _odict_FIRST(od);
641 if (_odict_FIRST(od) == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -0600642 _odict_LAST(od) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300643 else
Eric Snow96c6af92015-05-29 22:21:39 -0600644 _odictnode_PREV(_odict_FIRST(od)) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300645 _odict_FIRST(od) = node;
Eric Snow4fabf022015-06-04 00:09:56 -0600646 od->od_state++;
Eric Snow96c6af92015-05-29 22:21:39 -0600647}
648
649static void
650_odict_add_tail(PyODictObject *od, _ODictNode *node)
651{
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300652 _odictnode_PREV(node) = _odict_LAST(od);
653 _odictnode_NEXT(node) = NULL;
654 if (_odict_LAST(od) == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -0600655 _odict_FIRST(od) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300656 else
Eric Snow96c6af92015-05-29 22:21:39 -0600657 _odictnode_NEXT(_odict_LAST(od)) = node;
Serhiy Storchaka992ec462015-10-14 19:21:24 +0300658 _odict_LAST(od) = node;
Eric Snow4fabf022015-06-04 00:09:56 -0600659 od->od_state++;
Eric Snow96c6af92015-05-29 22:21:39 -0600660}
661
662/* adds the node to the end of the list */
663static int
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200664_odict_add_new_node(PyODictObject *od, PyObject *key, Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600665{
666 Py_ssize_t i;
667 _ODictNode *node;
668
Serhiy Storchakad17427b2015-10-20 18:21:48 +0300669 Py_INCREF(key);
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200670 i = _odict_get_index(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600671 if (i < 0) {
672 if (!PyErr_Occurred())
673 PyErr_SetObject(PyExc_KeyError, key);
674 Py_DECREF(key);
675 return -1;
676 }
Serhiy Storchaka6f17e512018-10-20 02:27:45 +0300677 assert(od->od_fast_nodes != NULL);
678 if (od->od_fast_nodes[i] != NULL) {
Eric Snow96c6af92015-05-29 22:21:39 -0600679 /* We already have a node for the key so there's no need to add one. */
680 Py_DECREF(key);
681 return 0;
682 }
683
684 /* must not be added yet */
685 node = (_ODictNode *)PyMem_MALLOC(sizeof(_ODictNode));
686 if (node == NULL) {
687 Py_DECREF(key);
688 PyErr_NoMemory();
689 return -1;
690 }
691
692 _odictnode_KEY(node) = key;
Eric Snow4c729182015-06-03 10:50:37 -0600693 _odictnode_HASH(node) = hash;
Eric Snow96c6af92015-05-29 22:21:39 -0600694 _odict_add_tail(od, node);
695 od->od_fast_nodes[i] = node;
696 return 0;
697}
698
699/* Putting the decref after the free causes problems. */
700#define _odictnode_DEALLOC(node) \
701 do { \
702 Py_DECREF(_odictnode_KEY(node)); \
703 PyMem_FREE((void *)node); \
704 } while (0)
705
706/* Repeated calls on the same node are no-ops. */
707static void
708_odict_remove_node(PyODictObject *od, _ODictNode *node)
709{
710 if (_odict_FIRST(od) == node)
711 _odict_FIRST(od) = _odictnode_NEXT(node);
712 else if (_odictnode_PREV(node) != NULL)
713 _odictnode_NEXT(_odictnode_PREV(node)) = _odictnode_NEXT(node);
714
715 if (_odict_LAST(od) == node)
716 _odict_LAST(od) = _odictnode_PREV(node);
717 else if (_odictnode_NEXT(node) != NULL)
718 _odictnode_PREV(_odictnode_NEXT(node)) = _odictnode_PREV(node);
719
720 _odictnode_PREV(node) = NULL;
721 _odictnode_NEXT(node) = NULL;
Eric Snow4fabf022015-06-04 00:09:56 -0600722 od->od_state++;
Eric Snow96c6af92015-05-29 22:21:39 -0600723}
724
Eric Snow96c6af92015-05-29 22:21:39 -0600725/* If someone calls PyDict_DelItem() directly on an OrderedDict, we'll
726 get all sorts of problems here. In PyODict_DelItem we make sure to
727 call _odict_clear_node first.
Victor Stinnerca30b022015-09-03 17:50:04 +0200728
Eric Snow96c6af92015-05-29 22:21:39 -0600729 This matters in the case of colliding keys. Suppose we add 3 keys:
730 [A, B, C], where the hash of C collides with A and the next possible
731 index in the hash table is occupied by B. If we remove B then for C
732 the dict's looknode func will give us the old index of B instead of
733 the index we got before deleting B. However, the node for C in
734 od_fast_nodes is still at the old dict index of C. Thus to be sure
735 things don't get out of sync, we clear the node in od_fast_nodes
736 *before* calling PyDict_DelItem.
737
738 The same must be done for any other OrderedDict operations where
739 we modify od_fast_nodes.
740*/
741static int
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200742_odict_clear_node(PyODictObject *od, _ODictNode *node, PyObject *key,
743 Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -0600744{
745 Py_ssize_t i;
746
747 assert(key != NULL);
748 if (_odict_EMPTY(od)) {
749 /* Let later code decide if this is a KeyError. */
750 return 0;
751 }
752
Serhiy Storchaka19a70e72015-11-13 14:48:36 +0200753 i = _odict_get_index(od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -0600754 if (i < 0)
755 return PyErr_Occurred() ? -1 : 0;
756
Serhiy Storchaka6f17e512018-10-20 02:27:45 +0300757 assert(od->od_fast_nodes != NULL);
Eric Snow96c6af92015-05-29 22:21:39 -0600758 if (node == NULL)
759 node = od->od_fast_nodes[i];
760 assert(node == od->od_fast_nodes[i]);
761 if (node == NULL) {
762 /* Let later code decide if this is a KeyError. */
763 return 0;
764 }
765
766 // Now clear the node.
767 od->od_fast_nodes[i] = NULL;
768 _odict_remove_node(od, node);
769 _odictnode_DEALLOC(node);
770 return 0;
771}
772
773static void
774_odict_clear_nodes(PyODictObject *od)
775{
776 _ODictNode *node, *next;
777
Serhiy Storchaka6f17e512018-10-20 02:27:45 +0300778 PyMem_FREE(od->od_fast_nodes);
Eric Snow96c6af92015-05-29 22:21:39 -0600779 od->od_fast_nodes = NULL;
Serhiy Storchaka6f17e512018-10-20 02:27:45 +0300780 od->od_fast_nodes_size = 0;
781 od->od_resize_sentinel = NULL;
Serhiy Storchakad205d012016-01-19 14:46:25 +0200782
783 node = _odict_FIRST(od);
784 _odict_FIRST(od) = NULL;
785 _odict_LAST(od) = NULL;
786 while (node != NULL) {
787 next = _odictnode_NEXT(node);
788 _odictnode_DEALLOC(node);
789 node = next;
790 }
Eric Snow96c6af92015-05-29 22:21:39 -0600791}
792
793/* There isn't any memory management of nodes past this point. */
794#undef _odictnode_DEALLOC
795
796static int
797_odict_keys_equal(PyODictObject *a, PyODictObject *b)
798{
799 _ODictNode *node_a, *node_b;
800
801 node_a = _odict_FIRST(a);
802 node_b = _odict_FIRST(b);
803 while (1) {
804 if (node_a == NULL && node_b == NULL)
805 /* success: hit the end of each at the same time */
806 return 1;
807 else if (node_a == NULL || node_b == NULL)
808 /* unequal length */
809 return 0;
810 else {
811 int res = PyObject_RichCompareBool(
812 (PyObject *)_odictnode_KEY(node_a),
813 (PyObject *)_odictnode_KEY(node_b),
814 Py_EQ);
815 if (res < 0)
816 return res;
817 else if (res == 0)
818 return 0;
819
820 /* otherwise it must match, so move on to the next one */
821 node_a = _odictnode_NEXT(node_a);
822 node_b = _odictnode_NEXT(node_b);
823 }
824 }
825}
826
827
828/* ----------------------------------------------
829 * OrderedDict mapping methods
830 */
831
832/* mp_ass_subscript: __setitem__() and __delitem__() */
833
834static int
835odict_mp_ass_sub(PyODictObject *od, PyObject *v, PyObject *w)
836{
837 if (w == NULL)
838 return PyODict_DelItem((PyObject *)od, v);
839 else
840 return PyODict_SetItem((PyObject *)od, v, w);
841}
842
843/* tp_as_mapping */
844
845static PyMappingMethods odict_as_mapping = {
846 0, /*mp_length*/
847 0, /*mp_subscript*/
848 (objobjargproc)odict_mp_ass_sub, /*mp_ass_subscript*/
849};
850
851
852/* ----------------------------------------------
853 * OrderedDict methods
854 */
855
Eric Snow96c6af92015-05-29 22:21:39 -0600856/* fromkeys() */
857
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100858/*[clinic input]
859@classmethod
860OrderedDict.fromkeys
861
862 iterable as seq: object
863 value: object = None
864
Serhiy Storchaka78d9e582017-01-25 00:30:04 +0200865Create a new ordered dictionary with keys from iterable and values set to value.
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100866[clinic start generated code]*/
Eric Snow96c6af92015-05-29 22:21:39 -0600867
868static PyObject *
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100869OrderedDict_fromkeys_impl(PyTypeObject *type, PyObject *seq, PyObject *value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +0200870/*[clinic end generated code: output=c10390d452d78d6d input=1a0476c229c597b3]*/
Eric Snow96c6af92015-05-29 22:21:39 -0600871{
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100872 return _PyDict_FromKeys((PyObject *)type, seq, value);
Eric Snow96c6af92015-05-29 22:21:39 -0600873}
874
875/* __sizeof__() */
876
877/* OrderedDict.__sizeof__() does not have a docstring. */
878PyDoc_STRVAR(odict_sizeof__doc__, "");
879
880static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530881odict_sizeof(PyODictObject *od, PyObject *Py_UNUSED(ignored))
Eric Snow96c6af92015-05-29 22:21:39 -0600882{
Serhiy Storchaka0ce7a3a2015-12-22 08:16:18 +0200883 Py_ssize_t res = _PyDict_SizeOf((PyDictObject *)od);
Serhiy Storchaka6f17e512018-10-20 02:27:45 +0300884 res += sizeof(_ODictNode *) * od->od_fast_nodes_size; /* od_fast_nodes */
Eric Snow96c6af92015-05-29 22:21:39 -0600885 if (!_odict_EMPTY(od)) {
886 res += sizeof(_ODictNode) * PyODict_SIZE(od); /* linked-list */
887 }
888 return PyLong_FromSsize_t(res);
889}
890
891/* __reduce__() */
892
893PyDoc_STRVAR(odict_reduce__doc__, "Return state information for pickling");
894
895static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530896odict_reduce(register PyODictObject *od, PyObject *Py_UNUSED(ignored))
Eric Snow96c6af92015-05-29 22:21:39 -0600897{
898 _Py_IDENTIFIER(__dict__);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300899 _Py_IDENTIFIER(items);
Serhiy Storchaka4575beb2015-10-22 20:18:24 +0300900 PyObject *dict = NULL, *result = NULL;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300901 PyObject *items_iter, *items, *args = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -0600902
903 /* capture any instance state */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300904 dict = _PyObject_GetAttrId((PyObject *)od, &PyId___dict__);
905 if (dict == NULL)
Eric Snowc5e59602015-05-30 11:28:56 -0600906 goto Done;
907 else {
Eric Snow96c6af92015-05-29 22:21:39 -0600908 /* od.__dict__ isn't necessarily a dict... */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300909 Py_ssize_t dict_len = PyObject_Length(dict);
910 if (dict_len == -1)
Eric Snow96c6af92015-05-29 22:21:39 -0600911 goto Done;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300912 if (!dict_len) {
913 /* nothing to pickle in od.__dict__ */
914 Py_CLEAR(dict);
Eric Snow96c6af92015-05-29 22:21:39 -0600915 }
916 }
917
918 /* build the result */
Eric Snow96c6af92015-05-29 22:21:39 -0600919 args = PyTuple_New(0);
920 if (args == NULL)
921 goto Done;
922
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300923 items = _PyObject_CallMethodIdObjArgs((PyObject *)od, &PyId_items, NULL);
Eric Snow96c6af92015-05-29 22:21:39 -0600924 if (items == NULL)
925 goto Done;
926
927 items_iter = PyObject_GetIter(items);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300928 Py_DECREF(items);
Eric Snow96c6af92015-05-29 22:21:39 -0600929 if (items_iter == NULL)
930 goto Done;
931
Serhiy Storchaka4575beb2015-10-22 20:18:24 +0300932 result = PyTuple_Pack(5, Py_TYPE(od), args, dict ? dict : Py_None, Py_None, items_iter);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300933 Py_DECREF(items_iter);
Eric Snow96c6af92015-05-29 22:21:39 -0600934
935Done:
Serhiy Storchaka8003baf2015-10-18 09:53:17 +0300936 Py_XDECREF(dict);
Eric Snow96c6af92015-05-29 22:21:39 -0600937 Py_XDECREF(args);
Eric Snow96c6af92015-05-29 22:21:39 -0600938
939 return result;
940}
941
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100942/* setdefault(): Skips __missing__() calls. */
Eric Snow96c6af92015-05-29 22:21:39 -0600943
Eric Snow96c6af92015-05-29 22:21:39 -0600944
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100945/*[clinic input]
946OrderedDict.setdefault
947
948 key: object
Serhiy Storchakaa70eaf22017-01-19 19:38:13 +0200949 default: object = None
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100950
Serhiy Storchaka78d9e582017-01-25 00:30:04 +0200951Insert key with a value of default if key is not in the dictionary.
952
953Return the value for key if key is in the dictionary, else default.
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100954[clinic start generated code]*/
955
Eric Snow96c6af92015-05-29 22:21:39 -0600956static PyObject *
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100957OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key,
Serhiy Storchakaa70eaf22017-01-19 19:38:13 +0200958 PyObject *default_value)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +0200959/*[clinic end generated code: output=97537cb7c28464b6 input=38e098381c1efbc6]*/
Eric Snow96c6af92015-05-29 22:21:39 -0600960{
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100961 PyObject *result = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -0600962
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100963 if (PyODict_CheckExact(self)) {
964 result = PyODict_GetItemWithError(self, key); /* borrowed */
Eric Snowd1719752015-06-01 23:12:13 -0600965 if (result == NULL) {
966 if (PyErr_Occurred())
967 return NULL;
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100968 assert(_odict_find_node(self, key) == NULL);
Serhiy Storchakaa70eaf22017-01-19 19:38:13 +0200969 if (PyODict_SetItem((PyObject *)self, key, default_value) >= 0) {
970 result = default_value;
971 Py_INCREF(result);
Eric Snow96c6af92015-05-29 22:21:39 -0600972 }
973 }
974 else {
Eric Snowd1719752015-06-01 23:12:13 -0600975 Py_INCREF(result);
Eric Snow96c6af92015-05-29 22:21:39 -0600976 }
977 }
978 else {
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100979 int exists = PySequence_Contains((PyObject *)self, key);
Eric Snow96c6af92015-05-29 22:21:39 -0600980 if (exists < 0) {
Eric Snowd1719752015-06-01 23:12:13 -0600981 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -0600982 }
983 else if (exists) {
Victor Stinnerb05cbac2017-01-17 03:46:13 +0100984 result = PyObject_GetItem((PyObject *)self, key);
Eric Snow96c6af92015-05-29 22:21:39 -0600985 }
Serhiy Storchakaa70eaf22017-01-19 19:38:13 +0200986 else if (PyObject_SetItem((PyObject *)self, key, default_value) >= 0) {
987 result = default_value;
988 Py_INCREF(result);
Eric Snow96c6af92015-05-29 22:21:39 -0600989 }
990 }
991
Eric Snow96c6af92015-05-29 22:21:39 -0600992 return result;
993}
994
995/* pop() */
996
997PyDoc_STRVAR(odict_pop__doc__,
998"od.pop(k[,d]) -> v, remove specified key and return the corresponding\n\
999 value. If key is not found, d is returned if given, otherwise KeyError\n\
1000 is raised.\n\
1001\n\
1002 ");
1003
1004/* forward */
1005static PyObject * _odict_popkey(PyObject *, PyObject *, PyObject *);
1006
1007/* Skips __missing__() calls. */
1008static PyObject *
Eric Snowac02ef32015-06-02 20:42:14 -06001009odict_pop(PyObject *od, PyObject *args, PyObject *kwargs)
Eric Snow96c6af92015-05-29 22:21:39 -06001010{
Eric Snowac02ef32015-06-02 20:42:14 -06001011 static char *kwlist[] = {"key", "default", 0};
Eric Snow96c6af92015-05-29 22:21:39 -06001012 PyObject *key, *failobj = NULL;
1013
Eric Snowac02ef32015-06-02 20:42:14 -06001014 /* borrowed */
1015 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:pop", kwlist,
1016 &key, &failobj)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001017 return NULL;
1018 }
1019
1020 return _odict_popkey(od, key, failobj);
1021}
1022
1023static PyObject *
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001024_odict_popkey_hash(PyObject *od, PyObject *key, PyObject *failobj,
1025 Py_hash_t hash)
Eric Snow96c6af92015-05-29 22:21:39 -06001026{
1027 _ODictNode *node;
1028 PyObject *value = NULL;
1029
Eric Snow96c6af92015-05-29 22:21:39 -06001030 /* Pop the node first to avoid a possible dict resize (due to
1031 eval loop reentrancy) and complications due to hash collision
1032 resolution. */
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001033 node = _odict_find_node_hash((PyODictObject *)od, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001034 if (node == NULL) {
1035 if (PyErr_Occurred())
Eric Snowd1719752015-06-01 23:12:13 -06001036 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001037 }
1038 else {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001039 int res = _odict_clear_node((PyODictObject *)od, node, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001040 if (res < 0) {
Eric Snowd1719752015-06-01 23:12:13 -06001041 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001042 }
1043 }
1044
1045 /* Now delete the value from the dict. */
Serhiy Storchaka04386832016-10-30 17:17:24 +02001046 if (PyODict_CheckExact(od)) {
1047 if (node != NULL) {
1048 value = _PyDict_GetItem_KnownHash(od, key, hash); /* borrowed */
1049 if (value != NULL) {
1050 Py_INCREF(value);
1051 if (_PyDict_DelItem_KnownHash(od, key, hash) < 0) {
1052 Py_DECREF(value);
1053 return NULL;
1054 }
1055 }
1056 }
1057 }
1058 else {
1059 int exists = PySequence_Contains(od, key);
1060 if (exists < 0)
1061 return NULL;
1062 if (exists) {
1063 value = PyObject_GetItem(od, key);
1064 if (value != NULL) {
1065 if (PyObject_DelItem(od, key) == -1) {
1066 Py_CLEAR(value);
1067 }
Eric Snow96c6af92015-05-29 22:21:39 -06001068 }
1069 }
1070 }
1071
1072 /* Apply the fallback value, if necessary. */
1073 if (value == NULL && !PyErr_Occurred()) {
1074 if (failobj) {
1075 value = failobj;
1076 Py_INCREF(failobj);
1077 }
1078 else {
1079 PyErr_SetObject(PyExc_KeyError, key);
1080 }
1081 }
1082
Eric Snow96c6af92015-05-29 22:21:39 -06001083 return value;
1084}
1085
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001086static PyObject *
1087_odict_popkey(PyObject *od, PyObject *key, PyObject *failobj)
1088{
1089 Py_hash_t hash = PyObject_Hash(key);
1090 if (hash == -1)
1091 return NULL;
1092
1093 return _odict_popkey_hash(od, key, failobj, hash);
1094}
1095
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001096
Eric Snow96c6af92015-05-29 22:21:39 -06001097/* popitem() */
1098
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001099/*[clinic input]
1100OrderedDict.popitem
1101
1102 last: bool = True
1103
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001104Remove and return a (key, value) pair from the dictionary.
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001105
1106Pairs are returned in LIFO order if last is true or FIFO order if false.
1107[clinic start generated code]*/
Eric Snow96c6af92015-05-29 22:21:39 -06001108
1109static PyObject *
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001110OrderedDict_popitem_impl(PyODictObject *self, int last)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001111/*[clinic end generated code: output=98e7d986690d49eb input=d992ac5ee8305e1a]*/
Eric Snow96c6af92015-05-29 22:21:39 -06001112{
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001113 PyObject *key, *value, *item = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001114 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001115
1116 /* pull the item */
1117
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001118 if (_odict_EMPTY(self)) {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001119 PyErr_SetString(PyExc_KeyError, "dictionary is empty");
1120 return NULL;
Eric Snowac02ef32015-06-02 20:42:14 -06001121 }
Eric Snow96c6af92015-05-29 22:21:39 -06001122
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001123 node = last ? _odict_LAST(self) : _odict_FIRST(self);
Eric Snow96c6af92015-05-29 22:21:39 -06001124 key = _odictnode_KEY(node);
Eric Snowd1719752015-06-01 23:12:13 -06001125 Py_INCREF(key);
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001126 value = _odict_popkey_hash((PyObject *)self, key, NULL, _odictnode_HASH(node));
Eric Snow96c6af92015-05-29 22:21:39 -06001127 if (value == NULL)
1128 return NULL;
1129 item = PyTuple_Pack(2, key, value);
Eric Snowd1719752015-06-01 23:12:13 -06001130 Py_DECREF(key);
Eric Snow96c6af92015-05-29 22:21:39 -06001131 Py_DECREF(value);
1132 return item;
1133}
1134
1135/* keys() */
1136
1137/* MutableMapping.keys() does not have a docstring. */
1138PyDoc_STRVAR(odict_keys__doc__, "");
1139
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301140static PyObject * odictkeys_new(PyObject *od, PyObject *Py_UNUSED(ignored)); /* forward */
Eric Snow96c6af92015-05-29 22:21:39 -06001141
1142/* values() */
1143
1144/* MutableMapping.values() does not have a docstring. */
1145PyDoc_STRVAR(odict_values__doc__, "");
1146
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301147static PyObject * odictvalues_new(PyObject *od, PyObject *Py_UNUSED(ignored)); /* forward */
Eric Snow96c6af92015-05-29 22:21:39 -06001148
1149/* items() */
1150
1151/* MutableMapping.items() does not have a docstring. */
1152PyDoc_STRVAR(odict_items__doc__, "");
1153
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301154static PyObject * odictitems_new(PyObject *od, PyObject *Py_UNUSED(ignored)); /* forward */
Eric Snow96c6af92015-05-29 22:21:39 -06001155
1156/* update() */
1157
1158/* MutableMapping.update() does not have a docstring. */
1159PyDoc_STRVAR(odict_update__doc__, "");
1160
1161/* forward */
1162static PyObject * mutablemapping_update(PyObject *, PyObject *, PyObject *);
1163
1164#define odict_update mutablemapping_update
1165
1166/* clear() */
1167
1168PyDoc_STRVAR(odict_clear__doc__,
1169 "od.clear() -> None. Remove all items from od.");
1170
1171static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301172odict_clear(register PyODictObject *od, PyObject *Py_UNUSED(ignored))
Eric Snow96c6af92015-05-29 22:21:39 -06001173{
1174 PyDict_Clear((PyObject *)od);
1175 _odict_clear_nodes(od);
Eric Snow96c6af92015-05-29 22:21:39 -06001176 Py_RETURN_NONE;
1177}
1178
1179/* copy() */
1180
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001181/* forward */
1182static int _PyODict_SetItem_KnownHash(PyObject *, PyObject *, PyObject *,
1183 Py_hash_t);
1184
Eric Snow96c6af92015-05-29 22:21:39 -06001185PyDoc_STRVAR(odict_copy__doc__, "od.copy() -> a shallow copy of od");
1186
1187static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301188odict_copy(register PyODictObject *od, PyObject *Py_UNUSED(ignored))
Eric Snow96c6af92015-05-29 22:21:39 -06001189{
1190 _ODictNode *node;
1191 PyObject *od_copy;
1192
1193 if (PyODict_CheckExact(od))
1194 od_copy = PyODict_New();
1195 else
Victor Stinnerf17c3de2016-12-06 18:46:19 +01001196 od_copy = _PyObject_CallNoArg((PyObject *)Py_TYPE(od));
Eric Snow96c6af92015-05-29 22:21:39 -06001197 if (od_copy == NULL)
1198 return NULL;
1199
1200 if (PyODict_CheckExact(od)) {
1201 _odict_FOREACH(od, node) {
Eric Snowa762af72015-06-01 22:59:08 -06001202 PyObject *key = _odictnode_KEY(node);
1203 PyObject *value = _odictnode_VALUE(node, od);
1204 if (value == NULL) {
1205 if (!PyErr_Occurred())
1206 PyErr_SetObject(PyExc_KeyError, key);
1207 goto fail;
1208 }
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001209 if (_PyODict_SetItem_KnownHash((PyObject *)od_copy, key, value,
1210 _odictnode_HASH(node)) != 0)
Eric Snow96c6af92015-05-29 22:21:39 -06001211 goto fail;
1212 }
1213 }
1214 else {
1215 _odict_FOREACH(od, node) {
1216 int res;
1217 PyObject *value = PyObject_GetItem((PyObject *)od,
1218 _odictnode_KEY(node));
1219 if (value == NULL)
1220 goto fail;
1221 res = PyObject_SetItem((PyObject *)od_copy,
1222 _odictnode_KEY(node), value);
1223 Py_DECREF(value);
1224 if (res != 0)
1225 goto fail;
1226 }
1227 }
1228 return od_copy;
1229
1230fail:
1231 Py_DECREF(od_copy);
1232 return NULL;
1233}
1234
1235/* __reversed__() */
1236
1237PyDoc_STRVAR(odict_reversed__doc__, "od.__reversed__() <==> reversed(od)");
1238
1239#define _odict_ITER_REVERSED 1
1240#define _odict_ITER_KEYS 2
1241#define _odict_ITER_VALUES 4
1242
1243/* forward */
1244static PyObject * odictiter_new(PyODictObject *, int);
1245
1246static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301247odict_reversed(PyODictObject *od, PyObject *Py_UNUSED(ignored))
Eric Snow96c6af92015-05-29 22:21:39 -06001248{
Eric Snow96c6af92015-05-29 22:21:39 -06001249 return odictiter_new(od, _odict_ITER_KEYS|_odict_ITER_REVERSED);
1250}
1251
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001252
Eric Snow96c6af92015-05-29 22:21:39 -06001253/* move_to_end() */
1254
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001255/*[clinic input]
1256OrderedDict.move_to_end
1257
1258 key: object
1259 last: bool = True
1260
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001261Move an existing element to the end (or beginning if last is false).
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001262
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001263Raise KeyError if the element does not exist.
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001264[clinic start generated code]*/
Eric Snow96c6af92015-05-29 22:21:39 -06001265
1266static PyObject *
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001267OrderedDict_move_to_end_impl(PyODictObject *self, PyObject *key, int last)
Serhiy Storchaka78d9e582017-01-25 00:30:04 +02001268/*[clinic end generated code: output=fafa4c5cc9b92f20 input=d6ceff7132a2fcd7]*/
Eric Snow96c6af92015-05-29 22:21:39 -06001269{
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001270 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001271
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001272 if (_odict_EMPTY(self)) {
Eric Snow96c6af92015-05-29 22:21:39 -06001273 PyErr_SetObject(PyExc_KeyError, key);
Eric Snow96c6af92015-05-29 22:21:39 -06001274 return NULL;
1275 }
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001276 node = last ? _odict_LAST(self) : _odict_FIRST(self);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001277 if (key != _odictnode_KEY(node)) {
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001278 node = _odict_find_node(self, key);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001279 if (node == NULL) {
1280 if (!PyErr_Occurred())
1281 PyErr_SetObject(PyExc_KeyError, key);
Eric Snowc5e59602015-05-30 11:28:56 -06001282 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001283 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001284 if (last) {
1285 /* Only move if not already the last one. */
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001286 if (node != _odict_LAST(self)) {
1287 _odict_remove_node(self, node);
1288 _odict_add_tail(self, node);
Eric Snow96c6af92015-05-29 22:21:39 -06001289 }
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001290 }
1291 else {
1292 /* Only move if not already the first one. */
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001293 if (node != _odict_FIRST(self)) {
1294 _odict_remove_node(self, node);
1295 _odict_add_head(self, node);
Eric Snow96c6af92015-05-29 22:21:39 -06001296 }
1297 }
1298 }
Eric Snow96c6af92015-05-29 22:21:39 -06001299 Py_RETURN_NONE;
1300}
1301
1302
1303/* tp_methods */
1304
1305static PyMethodDef odict_methods[] = {
1306
Eric Snow96c6af92015-05-29 22:21:39 -06001307 /* overridden dict methods */
Serhiy Storchaka827d49f2018-04-09 19:14:26 +03001308 ORDEREDDICT_FROMKEYS_METHODDEF
Eric Snow96c6af92015-05-29 22:21:39 -06001309 {"__sizeof__", (PyCFunction)odict_sizeof, METH_NOARGS,
1310 odict_sizeof__doc__},
1311 {"__reduce__", (PyCFunction)odict_reduce, METH_NOARGS,
1312 odict_reduce__doc__},
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001313 ORDEREDDICT_SETDEFAULT_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001314 {"pop", (PyCFunction)(void(*)(void))odict_pop,
Eric Snowac02ef32015-06-02 20:42:14 -06001315 METH_VARARGS | METH_KEYWORDS, odict_pop__doc__},
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001316 ORDEREDDICT_POPITEM_METHODDEF
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301317 {"keys", odictkeys_new, METH_NOARGS,
Eric Snow96c6af92015-05-29 22:21:39 -06001318 odict_keys__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301319 {"values", odictvalues_new, METH_NOARGS,
Eric Snow96c6af92015-05-29 22:21:39 -06001320 odict_values__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301321 {"items", odictitems_new, METH_NOARGS,
Eric Snow96c6af92015-05-29 22:21:39 -06001322 odict_items__doc__},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001323 {"update", (PyCFunction)(void(*)(void))odict_update, METH_VARARGS | METH_KEYWORDS,
Eric Snow96c6af92015-05-29 22:21:39 -06001324 odict_update__doc__},
1325 {"clear", (PyCFunction)odict_clear, METH_NOARGS,
1326 odict_clear__doc__},
1327 {"copy", (PyCFunction)odict_copy, METH_NOARGS,
1328 odict_copy__doc__},
1329
1330 /* new methods */
1331 {"__reversed__", (PyCFunction)odict_reversed, METH_NOARGS,
1332 odict_reversed__doc__},
Victor Stinnerb05cbac2017-01-17 03:46:13 +01001333 ORDEREDDICT_MOVE_TO_END_METHODDEF
Eric Snow96c6af92015-05-29 22:21:39 -06001334
1335 {NULL, NULL} /* sentinel */
1336};
1337
1338
1339/* ----------------------------------------------
1340 * OrderedDict members
1341 */
1342
Serhiy Storchakad2962f12016-02-08 16:39:05 +02001343/* tp_getset */
Eric Snow96c6af92015-05-29 22:21:39 -06001344
Serhiy Storchakad2962f12016-02-08 16:39:05 +02001345static PyGetSetDef odict_getset[] = {
1346 {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
1347 {NULL}
Eric Snow96c6af92015-05-29 22:21:39 -06001348};
1349
Eric Snow96c6af92015-05-29 22:21:39 -06001350/* ----------------------------------------------
1351 * OrderedDict type slot methods
1352 */
1353
1354/* tp_dealloc */
1355
1356static void
1357odict_dealloc(PyODictObject *self)
1358{
Victor Stinner50b48572018-11-01 01:51:40 +01001359 PyThreadState *tstate = _PyThreadState_GET();
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001360
Eric Snow96c6af92015-05-29 22:21:39 -06001361 PyObject_GC_UnTrack(self);
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001362 Py_TRASHCAN_SAFE_BEGIN(self)
1363
Eric Snow96c6af92015-05-29 22:21:39 -06001364 Py_XDECREF(self->od_inst_dict);
1365 if (self->od_weakreflist != NULL)
1366 PyObject_ClearWeakRefs((PyObject *)self);
1367
1368 _odict_clear_nodes(self);
Eric Snow96c6af92015-05-29 22:21:39 -06001369
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001370 /* Call the base tp_dealloc(). Since it too uses the trashcan mechanism,
1371 * temporarily decrement trash_delete_nesting to prevent triggering it
1372 * and putting the partially deallocated object on the trashcan's
1373 * to-be-deleted-later list.
1374 */
1375 --tstate->trash_delete_nesting;
1376 assert(_tstate->trash_delete_nesting < PyTrash_UNWIND_LEVEL);
Eric Snow96c6af92015-05-29 22:21:39 -06001377 PyDict_Type.tp_dealloc((PyObject *)self);
Serhiy Storchaka14eefe32015-11-01 16:12:34 +02001378 ++tstate->trash_delete_nesting;
1379
1380 Py_TRASHCAN_SAFE_END(self)
Victor Stinnere1871952016-06-08 10:18:18 +02001381}
Eric Snow96c6af92015-05-29 22:21:39 -06001382
1383/* tp_repr */
1384
1385static PyObject *
1386odict_repr(PyODictObject *self)
1387{
1388 int i;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001389 _Py_IDENTIFIER(items);
Serhiy Storchaka4575beb2015-10-22 20:18:24 +03001390 PyObject *pieces = NULL, *result = NULL;
Serhiy Storchaka4575beb2015-10-22 20:18:24 +03001391
1392 if (PyODict_SIZE(self) == 0)
Serhiy Storchaka4ab46d72017-09-17 21:11:04 +03001393 return PyUnicode_FromFormat("%s()", _PyType_Name(Py_TYPE(self)));
Eric Snow96c6af92015-05-29 22:21:39 -06001394
1395 i = Py_ReprEnter((PyObject *)self);
1396 if (i != 0) {
1397 return i > 0 ? PyUnicode_FromString("...") : NULL;
1398 }
1399
Eric Snow96c6af92015-05-29 22:21:39 -06001400 if (PyODict_CheckExact(self)) {
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001401 Py_ssize_t count = 0;
Eric Snowa762af72015-06-01 22:59:08 -06001402 _ODictNode *node;
Eric Snow96c6af92015-05-29 22:21:39 -06001403 pieces = PyList_New(PyODict_SIZE(self));
1404 if (pieces == NULL)
1405 goto Done;
1406
1407 _odict_FOREACH(self, node) {
Eric Snowa762af72015-06-01 22:59:08 -06001408 PyObject *pair;
1409 PyObject *key = _odictnode_KEY(node);
1410 PyObject *value = _odictnode_VALUE(node, self);
1411 if (value == NULL) {
1412 if (!PyErr_Occurred())
1413 PyErr_SetObject(PyExc_KeyError, key);
Eric Snowdb4061c2015-06-03 11:09:48 -06001414 goto Done;
Eric Snowa762af72015-06-01 22:59:08 -06001415 }
1416 pair = PyTuple_Pack(2, key, value);
Eric Snow96c6af92015-05-29 22:21:39 -06001417 if (pair == NULL)
1418 goto Done;
1419
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001420 if (count < PyList_GET_SIZE(pieces))
1421 PyList_SET_ITEM(pieces, count, pair); /* steals reference */
1422 else {
1423 if (PyList_Append(pieces, pair) < 0) {
1424 Py_DECREF(pair);
1425 goto Done;
1426 }
1427 Py_DECREF(pair);
1428 }
1429 count++;
Eric Snow96c6af92015-05-29 22:21:39 -06001430 }
Serhiy Storchaka710cd342015-11-04 22:33:07 +02001431 if (count < PyList_GET_SIZE(pieces))
Serhiy Storchaka1a5856b2017-04-22 02:48:11 +03001432 Py_SIZE(pieces) = count;
Eric Snow96c6af92015-05-29 22:21:39 -06001433 }
1434 else {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001435 PyObject *items = _PyObject_CallMethodIdObjArgs((PyObject *)self,
1436 &PyId_items, NULL);
Eric Snow96c6af92015-05-29 22:21:39 -06001437 if (items == NULL)
1438 goto Done;
1439 pieces = PySequence_List(items);
1440 Py_DECREF(items);
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03001441 if (pieces == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -06001442 goto Done;
1443 }
1444
Serhiy Storchaka4ab46d72017-09-17 21:11:04 +03001445 result = PyUnicode_FromFormat("%s(%R)",
1446 _PyType_Name(Py_TYPE(self)), pieces);
Eric Snow96c6af92015-05-29 22:21:39 -06001447
Eric Snow96c6af92015-05-29 22:21:39 -06001448Done:
1449 Py_XDECREF(pieces);
Eric Snow96c6af92015-05-29 22:21:39 -06001450 Py_ReprLeave((PyObject *)self);
1451 return result;
Victor Stinnere1871952016-06-08 10:18:18 +02001452}
Eric Snow96c6af92015-05-29 22:21:39 -06001453
1454/* tp_doc */
1455
1456PyDoc_STRVAR(odict_doc,
1457 "Dictionary that remembers insertion order");
1458
1459/* tp_traverse */
1460
1461static int
1462odict_traverse(PyODictObject *od, visitproc visit, void *arg)
1463{
Serhiy Storchakad205d012016-01-19 14:46:25 +02001464 _ODictNode *node;
1465
Eric Snow96c6af92015-05-29 22:21:39 -06001466 Py_VISIT(od->od_inst_dict);
1467 Py_VISIT(od->od_weakreflist);
Serhiy Storchakad205d012016-01-19 14:46:25 +02001468 _odict_FOREACH(od, node) {
1469 Py_VISIT(_odictnode_KEY(node));
1470 }
Eric Snow96c6af92015-05-29 22:21:39 -06001471 return PyDict_Type.tp_traverse((PyObject *)od, visit, arg);
1472}
1473
1474/* tp_clear */
1475
1476static int
1477odict_tp_clear(PyODictObject *od)
1478{
Eric Snow96c6af92015-05-29 22:21:39 -06001479 Py_CLEAR(od->od_inst_dict);
1480 Py_CLEAR(od->od_weakreflist);
Serhiy Storchaka6f17e512018-10-20 02:27:45 +03001481 PyDict_Clear((PyObject *)od);
1482 _odict_clear_nodes(od);
Eric Snow96c6af92015-05-29 22:21:39 -06001483 return 0;
1484}
1485
1486/* tp_richcompare */
1487
1488static PyObject *
1489odict_richcompare(PyObject *v, PyObject *w, int op)
1490{
1491 if (!PyODict_Check(v) || !PyDict_Check(w)) {
1492 Py_RETURN_NOTIMPLEMENTED;
1493 }
1494
1495 if (op == Py_EQ || op == Py_NE) {
1496 PyObject *res, *cmp;
1497 int eq;
1498
1499 cmp = PyDict_Type.tp_richcompare(v, w, op);
1500 if (cmp == NULL)
1501 return NULL;
1502 if (!PyODict_Check(w))
1503 return cmp;
1504 if (op == Py_EQ && cmp == Py_False)
1505 return cmp;
1506 if (op == Py_NE && cmp == Py_True)
1507 return cmp;
1508 Py_DECREF(cmp);
1509
1510 /* Try comparing odict keys. */
1511 eq = _odict_keys_equal((PyODictObject *)v, (PyODictObject *)w);
1512 if (eq < 0)
1513 return NULL;
1514
1515 res = (eq == (op == Py_EQ)) ? Py_True : Py_False;
1516 Py_INCREF(res);
1517 return res;
1518 } else {
1519 Py_RETURN_NOTIMPLEMENTED;
1520 }
Victor Stinnere1871952016-06-08 10:18:18 +02001521}
Eric Snow96c6af92015-05-29 22:21:39 -06001522
1523/* tp_iter */
1524
1525static PyObject *
1526odict_iter(PyODictObject *od)
1527{
1528 return odictiter_new(od, _odict_ITER_KEYS);
Victor Stinnere1871952016-06-08 10:18:18 +02001529}
Eric Snow96c6af92015-05-29 22:21:39 -06001530
1531/* tp_init */
1532
1533static int
1534odict_init(PyObject *self, PyObject *args, PyObject *kwds)
1535{
1536 PyObject *res;
1537 Py_ssize_t len = PyObject_Length(args);
1538
1539 if (len == -1)
1540 return -1;
1541 if (len > 1) {
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02001542 const char *msg = "expected at most 1 arguments, got %zd";
Eric Snow96c6af92015-05-29 22:21:39 -06001543 PyErr_Format(PyExc_TypeError, msg, len);
1544 return -1;
1545 }
1546
1547 /* __init__() triggering update() is just the way things are! */
1548 res = odict_update(self, args, kwds);
1549 if (res == NULL) {
1550 return -1;
1551 } else {
1552 Py_DECREF(res);
1553 return 0;
1554 }
Victor Stinnere1871952016-06-08 10:18:18 +02001555}
Eric Snow96c6af92015-05-29 22:21:39 -06001556
Eric Snow96c6af92015-05-29 22:21:39 -06001557/* PyODict_Type */
1558
1559PyTypeObject PyODict_Type = {
1560 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1561 "collections.OrderedDict", /* tp_name */
1562 sizeof(PyODictObject), /* tp_basicsize */
1563 0, /* tp_itemsize */
1564 (destructor)odict_dealloc, /* tp_dealloc */
1565 0, /* tp_print */
1566 0, /* tp_getattr */
1567 0, /* tp_setattr */
1568 0, /* tp_reserved */
1569 (reprfunc)odict_repr, /* tp_repr */
1570 0, /* tp_as_number */
1571 0, /* tp_as_sequence */
1572 &odict_as_mapping, /* tp_as_mapping */
1573 0, /* tp_hash */
1574 0, /* tp_call */
1575 0, /* tp_str */
1576 0, /* tp_getattro */
1577 0, /* tp_setattro */
1578 0, /* tp_as_buffer */
1579 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,/* tp_flags */
1580 odict_doc, /* tp_doc */
1581 (traverseproc)odict_traverse, /* tp_traverse */
1582 (inquiry)odict_tp_clear, /* tp_clear */
1583 (richcmpfunc)odict_richcompare, /* tp_richcompare */
1584 offsetof(PyODictObject, od_weakreflist), /* tp_weaklistoffset */
1585 (getiterfunc)odict_iter, /* tp_iter */
1586 0, /* tp_iternext */
1587 odict_methods, /* tp_methods */
Serhiy Storchakad2962f12016-02-08 16:39:05 +02001588 0, /* tp_members */
1589 odict_getset, /* tp_getset */
Eric Snow96c6af92015-05-29 22:21:39 -06001590 &PyDict_Type, /* tp_base */
1591 0, /* tp_dict */
1592 0, /* tp_descr_get */
1593 0, /* tp_descr_set */
1594 offsetof(PyODictObject, od_inst_dict), /* tp_dictoffset */
1595 (initproc)odict_init, /* tp_init */
1596 PyType_GenericAlloc, /* tp_alloc */
Serhiy Storchaka6f17e512018-10-20 02:27:45 +03001597 0, /* tp_new */
Eric Snow96c6af92015-05-29 22:21:39 -06001598 0, /* tp_free */
1599};
1600
1601
1602/* ----------------------------------------------
1603 * the public OrderedDict API
1604 */
1605
1606PyObject *
Serhiy Storchaka6f17e512018-10-20 02:27:45 +03001607PyODict_New(void)
1608{
1609 return PyDict_Type.tp_new(&PyODict_Type, NULL, NULL);
Victor Stinnere1871952016-06-08 10:18:18 +02001610}
Eric Snow96c6af92015-05-29 22:21:39 -06001611
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001612static int
1613_PyODict_SetItem_KnownHash(PyObject *od, PyObject *key, PyObject *value,
1614 Py_hash_t hash)
1615{
1616 int res = _PyDict_SetItem_KnownHash(od, key, value, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001617 if (res == 0) {
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001618 res = _odict_add_new_node((PyODictObject *)od, key, hash);
Serhiy Storchakad5f353e2015-11-06 11:07:11 +02001619 if (res < 0) {
1620 /* Revert setting the value on the dict */
1621 PyObject *exc, *val, *tb;
1622 PyErr_Fetch(&exc, &val, &tb);
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001623 (void) _PyDict_DelItem_KnownHash(od, key, hash);
Serhiy Storchakad5f353e2015-11-06 11:07:11 +02001624 _PyErr_ChainExceptions(exc, val, tb);
1625 }
Eric Snow96c6af92015-05-29 22:21:39 -06001626 }
1627 return res;
Victor Stinnere1871952016-06-08 10:18:18 +02001628}
Eric Snow96c6af92015-05-29 22:21:39 -06001629
1630int
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001631PyODict_SetItem(PyObject *od, PyObject *key, PyObject *value)
1632{
1633 Py_hash_t hash = PyObject_Hash(key);
1634 if (hash == -1)
1635 return -1;
1636 return _PyODict_SetItem_KnownHash(od, key, value, hash);
Victor Stinnere1871952016-06-08 10:18:18 +02001637}
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001638
1639int
1640PyODict_DelItem(PyObject *od, PyObject *key)
1641{
1642 int res;
1643 Py_hash_t hash = PyObject_Hash(key);
1644 if (hash == -1)
1645 return -1;
1646 res = _odict_clear_node((PyODictObject *)od, NULL, key, hash);
Eric Snow96c6af92015-05-29 22:21:39 -06001647 if (res < 0)
1648 return -1;
Serhiy Storchaka19a70e72015-11-13 14:48:36 +02001649 return _PyDict_DelItem_KnownHash(od, key, hash);
Victor Stinnere1871952016-06-08 10:18:18 +02001650}
Eric Snow96c6af92015-05-29 22:21:39 -06001651
1652
1653/* -------------------------------------------
1654 * The OrderedDict views (keys/values/items)
1655 */
1656
1657typedef struct {
1658 PyObject_HEAD
1659 int kind;
1660 PyODictObject *di_odict;
Eric Snowb952ab42015-06-01 23:35:13 -06001661 Py_ssize_t di_size;
Eric Snow4fabf022015-06-04 00:09:56 -06001662 size_t di_state;
Eric Snow96c6af92015-05-29 22:21:39 -06001663 PyObject *di_current;
1664 PyObject *di_result; /* reusable result tuple for iteritems */
1665} odictiterobject;
1666
1667static void
1668odictiter_dealloc(odictiterobject *di)
1669{
1670 _PyObject_GC_UNTRACK(di);
Eric Snowa762af72015-06-01 22:59:08 -06001671 Py_XDECREF(di->di_odict);
Eric Snow96c6af92015-05-29 22:21:39 -06001672 Py_XDECREF(di->di_current);
1673 if (di->kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)) {
1674 Py_DECREF(di->di_result);
1675 }
1676 PyObject_GC_Del(di);
1677}
1678
1679static int
1680odictiter_traverse(odictiterobject *di, visitproc visit, void *arg)
1681{
1682 Py_VISIT(di->di_odict);
1683 Py_VISIT(di->di_current); /* A key could be any type, not just str. */
1684 Py_VISIT(di->di_result);
1685 return 0;
1686}
1687
Eric Snowa762af72015-06-01 22:59:08 -06001688/* In order to protect against modifications during iteration, we track
1689 * the current key instead of the current node. */
Eric Snow96c6af92015-05-29 22:21:39 -06001690static PyObject *
1691odictiter_nextkey(odictiterobject *di)
1692{
Eric Snowa762af72015-06-01 22:59:08 -06001693 PyObject *key = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001694 _ODictNode *node;
1695 int reversed = di->kind & _odict_ITER_REVERSED;
1696
Eric Snowa762af72015-06-01 22:59:08 -06001697 if (di->di_odict == NULL)
Eric Snow96c6af92015-05-29 22:21:39 -06001698 return NULL;
Eric Snowa762af72015-06-01 22:59:08 -06001699 if (di->di_current == NULL)
1700 goto done; /* We're already done. */
1701
Eric Snowb952ab42015-06-01 23:35:13 -06001702 /* Check for unsupported changes. */
Eric Snow4fabf022015-06-04 00:09:56 -06001703 if (di->di_odict->od_state != di->di_state) {
1704 PyErr_SetString(PyExc_RuntimeError,
1705 "OrderedDict mutated during iteration");
1706 goto done;
1707 }
Eric Snowb952ab42015-06-01 23:35:13 -06001708 if (di->di_size != PyODict_SIZE(di->di_odict)) {
1709 PyErr_SetString(PyExc_RuntimeError,
1710 "OrderedDict changed size during iteration");
1711 di->di_size = -1; /* Make this state sticky */
1712 return NULL;
1713 }
1714
Eric Snowa762af72015-06-01 22:59:08 -06001715 /* Get the key. */
Eric Snow96c6af92015-05-29 22:21:39 -06001716 node = _odict_find_node(di->di_odict, di->di_current);
1717 if (node == NULL) {
Serhiy Storchakab45b7b22015-11-04 22:05:38 +02001718 if (!PyErr_Occurred())
1719 PyErr_SetObject(PyExc_KeyError, di->di_current);
Eric Snow96c6af92015-05-29 22:21:39 -06001720 /* Must have been deleted. */
Eric Snowe3dfa9e2015-05-30 12:51:15 -06001721 Py_CLEAR(di->di_current);
Eric Snow96c6af92015-05-29 22:21:39 -06001722 return NULL;
1723 }
1724 key = di->di_current;
1725
1726 /* Advance to the next key. */
1727 node = reversed ? _odictnode_PREV(node) : _odictnode_NEXT(node);
1728 if (node == NULL) {
1729 /* Reached the end. */
1730 di->di_current = NULL;
1731 }
1732 else {
1733 di->di_current = _odictnode_KEY(node);
1734 Py_INCREF(di->di_current);
1735 }
1736
1737 return key;
Eric Snowa762af72015-06-01 22:59:08 -06001738
1739done:
1740 Py_CLEAR(di->di_odict);
1741 return key;
Eric Snow96c6af92015-05-29 22:21:39 -06001742}
1743
1744static PyObject *
1745odictiter_iternext(odictiterobject *di)
1746{
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001747 PyObject *result, *value;
Eric Snow96c6af92015-05-29 22:21:39 -06001748 PyObject *key = odictiter_nextkey(di); /* new reference */
1749
1750 if (key == NULL)
1751 return NULL;
1752
1753 /* Handle the keys case. */
1754 if (! (di->kind & _odict_ITER_VALUES)) {
1755 return key;
1756 }
1757
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001758 value = PyODict_GetItem((PyObject *)di->di_odict, key); /* borrowed */
1759 if (value == NULL) {
1760 if (!PyErr_Occurred())
1761 PyErr_SetObject(PyExc_KeyError, key);
Eric Snow96c6af92015-05-29 22:21:39 -06001762 Py_DECREF(key);
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001763 goto done;
1764 }
1765 Py_INCREF(value);
1766
1767 /* Handle the values case. */
1768 if (!(di->kind & _odict_ITER_KEYS)) {
1769 Py_DECREF(key);
Eric Snow96c6af92015-05-29 22:21:39 -06001770 return value;
1771 }
Eric Snowa762af72015-06-01 22:59:08 -06001772
Serhiy Storchaka9c967612015-11-06 10:39:51 +02001773 /* Handle the items case. */
1774 result = di->di_result;
1775
1776 if (Py_REFCNT(result) == 1) {
1777 /* not in use so we can reuse it
1778 * (the common case during iteration) */
1779 Py_INCREF(result);
1780 Py_DECREF(PyTuple_GET_ITEM(result, 0)); /* borrowed */
1781 Py_DECREF(PyTuple_GET_ITEM(result, 1)); /* borrowed */
1782 }
1783 else {
1784 result = PyTuple_New(2);
1785 if (result == NULL) {
1786 Py_DECREF(key);
1787 Py_DECREF(value);
1788 goto done;
1789 }
1790 }
1791
1792 PyTuple_SET_ITEM(result, 0, key); /* steals reference */
1793 PyTuple_SET_ITEM(result, 1, value); /* steals reference */
1794 return result;
1795
Eric Snowa762af72015-06-01 22:59:08 -06001796done:
1797 Py_CLEAR(di->di_current);
1798 Py_CLEAR(di->di_odict);
1799 return NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06001800}
1801
1802/* No need for tp_clear because odictiterobject is not mutable. */
1803
1804PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
1805
1806static PyObject *
Serhiy Storchaka81524022018-11-27 13:05:02 +02001807odictiter_reduce(odictiterobject *di, PyObject *Py_UNUSED(ignored))
Eric Snow96c6af92015-05-29 22:21:39 -06001808{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02001809 _Py_IDENTIFIER(iter);
Sergey Fedoseeva5259fb2018-10-20 10:20:39 +05001810 /* copy the iterator state */
1811 odictiterobject tmp = *di;
1812 Py_XINCREF(tmp.di_odict);
1813 Py_XINCREF(tmp.di_current);
Eric Snow96c6af92015-05-29 22:21:39 -06001814
1815 /* iterate the temporary into a list */
Sergey Fedoseeva5259fb2018-10-20 10:20:39 +05001816 PyObject *list = PySequence_List((PyObject*)&tmp);
1817 Py_XDECREF(tmp.di_odict);
1818 Py_XDECREF(tmp.di_current);
1819 if (list == NULL) {
Eric Snow96c6af92015-05-29 22:21:39 -06001820 return NULL;
1821 }
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02001822 return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list);
Eric Snow96c6af92015-05-29 22:21:39 -06001823}
1824
1825static PyMethodDef odictiter_methods[] = {
1826 {"__reduce__", (PyCFunction)odictiter_reduce, METH_NOARGS, reduce_doc},
1827 {NULL, NULL} /* sentinel */
1828};
1829
1830PyTypeObject PyODictIter_Type = {
1831 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1832 "odict_iterator", /* tp_name */
1833 sizeof(odictiterobject), /* tp_basicsize */
1834 0, /* tp_itemsize */
1835 /* methods */
1836 (destructor)odictiter_dealloc, /* tp_dealloc */
1837 0, /* tp_print */
1838 0, /* tp_getattr */
1839 0, /* tp_setattr */
1840 0, /* tp_reserved */
1841 0, /* tp_repr */
1842 0, /* tp_as_number */
1843 0, /* tp_as_sequence */
1844 0, /* tp_as_mapping */
1845 0, /* tp_hash */
1846 0, /* tp_call */
1847 0, /* tp_str */
1848 PyObject_GenericGetAttr, /* tp_getattro */
1849 0, /* tp_setattro */
1850 0, /* tp_as_buffer */
1851 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1852 0, /* tp_doc */
1853 (traverseproc)odictiter_traverse, /* tp_traverse */
1854 0, /* tp_clear */
1855 0, /* tp_richcompare */
1856 0, /* tp_weaklistoffset */
1857 PyObject_SelfIter, /* tp_iter */
1858 (iternextfunc)odictiter_iternext, /* tp_iternext */
1859 odictiter_methods, /* tp_methods */
1860 0,
1861};
1862
1863static PyObject *
1864odictiter_new(PyODictObject *od, int kind)
1865{
1866 odictiterobject *di;
1867 _ODictNode *node;
1868 int reversed = kind & _odict_ITER_REVERSED;
1869
1870 di = PyObject_GC_New(odictiterobject, &PyODictIter_Type);
1871 if (di == NULL)
1872 return NULL;
1873
1874 if (kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)){
1875 di->di_result = PyTuple_Pack(2, Py_None, Py_None);
1876 if (di->di_result == NULL) {
1877 Py_DECREF(di);
1878 return NULL;
1879 }
1880 }
1881 else
1882 di->di_result = NULL;
1883
1884 di->kind = kind;
1885 node = reversed ? _odict_LAST(od) : _odict_FIRST(od);
1886 di->di_current = node ? _odictnode_KEY(node) : NULL;
1887 Py_XINCREF(di->di_current);
Eric Snowb952ab42015-06-01 23:35:13 -06001888 di->di_size = PyODict_SIZE(od);
Eric Snow4fabf022015-06-04 00:09:56 -06001889 di->di_state = od->od_state;
Eric Snow96c6af92015-05-29 22:21:39 -06001890 di->di_odict = od;
1891 Py_INCREF(od);
1892
1893 _PyObject_GC_TRACK(di);
1894 return (PyObject *)di;
1895}
1896
1897/* keys() */
1898
1899static PyObject *
1900odictkeys_iter(_PyDictViewObject *dv)
1901{
1902 if (dv->dv_dict == NULL) {
1903 Py_RETURN_NONE;
1904 }
1905 return odictiter_new((PyODictObject *)dv->dv_dict,
1906 _odict_ITER_KEYS);
1907}
1908
1909static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301910odictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored))
Eric Snow96c6af92015-05-29 22:21:39 -06001911{
1912 if (dv->dv_dict == NULL) {
1913 Py_RETURN_NONE;
1914 }
1915 return odictiter_new((PyODictObject *)dv->dv_dict,
1916 _odict_ITER_KEYS|_odict_ITER_REVERSED);
1917}
1918
1919static PyMethodDef odictkeys_methods[] = {
1920 {"__reversed__", (PyCFunction)odictkeys_reversed, METH_NOARGS, NULL},
1921 {NULL, NULL} /* sentinel */
1922};
1923
1924PyTypeObject PyODictKeys_Type = {
1925 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1926 "odict_keys", /* tp_name */
1927 0, /* tp_basicsize */
1928 0, /* tp_itemsize */
1929 0, /* tp_dealloc */
1930 0, /* tp_print */
1931 0, /* tp_getattr */
1932 0, /* tp_setattr */
1933 0, /* tp_reserved */
1934 0, /* tp_repr */
1935 0, /* tp_as_number */
1936 0, /* tp_as_sequence */
1937 0, /* tp_as_mapping */
1938 0, /* tp_hash */
1939 0, /* tp_call */
1940 0, /* tp_str */
1941 0, /* tp_getattro */
1942 0, /* tp_setattro */
1943 0, /* tp_as_buffer */
1944 0, /* tp_flags */
1945 0, /* tp_doc */
1946 0, /* tp_traverse */
1947 0, /* tp_clear */
1948 0, /* tp_richcompare */
1949 0, /* tp_weaklistoffset */
1950 (getiterfunc)odictkeys_iter, /* tp_iter */
1951 0, /* tp_iternext */
1952 odictkeys_methods, /* tp_methods */
1953 0, /* tp_members */
1954 0, /* tp_getset */
1955 &PyDictKeys_Type, /* tp_base */
1956};
1957
1958static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301959odictkeys_new(PyObject *od, PyObject *Py_UNUSED(ignored))
Eric Snow96c6af92015-05-29 22:21:39 -06001960{
1961 return _PyDictView_New(od, &PyODictKeys_Type);
1962}
1963
1964/* items() */
1965
1966static PyObject *
1967odictitems_iter(_PyDictViewObject *dv)
1968{
1969 if (dv->dv_dict == NULL) {
1970 Py_RETURN_NONE;
1971 }
1972 return odictiter_new((PyODictObject *)dv->dv_dict,
1973 _odict_ITER_KEYS|_odict_ITER_VALUES);
1974}
1975
1976static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301977odictitems_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored))
Eric Snow96c6af92015-05-29 22:21:39 -06001978{
1979 if (dv->dv_dict == NULL) {
1980 Py_RETURN_NONE;
1981 }
1982 return odictiter_new((PyODictObject *)dv->dv_dict,
1983 _odict_ITER_KEYS|_odict_ITER_VALUES|_odict_ITER_REVERSED);
1984}
1985
1986static PyMethodDef odictitems_methods[] = {
1987 {"__reversed__", (PyCFunction)odictitems_reversed, METH_NOARGS, NULL},
1988 {NULL, NULL} /* sentinel */
1989};
1990
1991PyTypeObject PyODictItems_Type = {
1992 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1993 "odict_items", /* tp_name */
1994 0, /* tp_basicsize */
1995 0, /* tp_itemsize */
1996 0, /* tp_dealloc */
1997 0, /* tp_print */
1998 0, /* tp_getattr */
1999 0, /* tp_setattr */
2000 0, /* tp_reserved */
2001 0, /* tp_repr */
2002 0, /* tp_as_number */
2003 0, /* tp_as_sequence */
2004 0, /* tp_as_mapping */
2005 0, /* tp_hash */
2006 0, /* tp_call */
2007 0, /* tp_str */
2008 0, /* tp_getattro */
2009 0, /* tp_setattro */
2010 0, /* tp_as_buffer */
2011 0, /* tp_flags */
2012 0, /* tp_doc */
2013 0, /* tp_traverse */
2014 0, /* tp_clear */
2015 0, /* tp_richcompare */
2016 0, /* tp_weaklistoffset */
2017 (getiterfunc)odictitems_iter, /* tp_iter */
2018 0, /* tp_iternext */
2019 odictitems_methods, /* tp_methods */
2020 0, /* tp_members */
2021 0, /* tp_getset */
2022 &PyDictItems_Type, /* tp_base */
2023};
2024
2025static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302026odictitems_new(PyObject *od, PyObject *Py_UNUSED(ignored))
Eric Snow96c6af92015-05-29 22:21:39 -06002027{
2028 return _PyDictView_New(od, &PyODictItems_Type);
2029}
2030
2031/* values() */
2032
2033static PyObject *
2034odictvalues_iter(_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_VALUES);
2041}
2042
2043static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302044odictvalues_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored))
Eric Snow96c6af92015-05-29 22:21:39 -06002045{
2046 if (dv->dv_dict == NULL) {
2047 Py_RETURN_NONE;
2048 }
2049 return odictiter_new((PyODictObject *)dv->dv_dict,
2050 _odict_ITER_VALUES|_odict_ITER_REVERSED);
2051}
2052
2053static PyMethodDef odictvalues_methods[] = {
2054 {"__reversed__", (PyCFunction)odictvalues_reversed, METH_NOARGS, NULL},
2055 {NULL, NULL} /* sentinel */
2056};
2057
2058PyTypeObject PyODictValues_Type = {
2059 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2060 "odict_values", /* tp_name */
2061 0, /* tp_basicsize */
2062 0, /* tp_itemsize */
2063 0, /* tp_dealloc */
2064 0, /* tp_print */
2065 0, /* tp_getattr */
2066 0, /* tp_setattr */
2067 0, /* tp_reserved */
2068 0, /* tp_repr */
2069 0, /* tp_as_number */
2070 0, /* tp_as_sequence */
2071 0, /* tp_as_mapping */
2072 0, /* tp_hash */
2073 0, /* tp_call */
2074 0, /* tp_str */
2075 0, /* tp_getattro */
2076 0, /* tp_setattro */
2077 0, /* tp_as_buffer */
2078 0, /* tp_flags */
2079 0, /* tp_doc */
2080 0, /* tp_traverse */
2081 0, /* tp_clear */
2082 0, /* tp_richcompare */
2083 0, /* tp_weaklistoffset */
2084 (getiterfunc)odictvalues_iter, /* tp_iter */
2085 0, /* tp_iternext */
2086 odictvalues_methods, /* tp_methods */
2087 0, /* tp_members */
2088 0, /* tp_getset */
2089 &PyDictValues_Type, /* tp_base */
2090};
2091
2092static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302093odictvalues_new(PyObject *od, PyObject *Py_UNUSED(ignored))
Eric Snow96c6af92015-05-29 22:21:39 -06002094{
2095 return _PyDictView_New(od, &PyODictValues_Type);
2096}
2097
2098
2099/* ----------------------------------------------
Martin Panter536d70e2017-01-14 08:23:08 +00002100 MutableMapping implementations
Eric Snow96c6af92015-05-29 22:21:39 -06002101
2102Mapping:
2103
2104============ ===========
2105method uses
2106============ ===========
2107__contains__ __getitem__
2108__eq__ items
2109__getitem__ +
2110__iter__ +
2111__len__ +
2112__ne__ __eq__
2113get __getitem__
2114items ItemsView
2115keys KeysView
2116values ValuesView
2117============ ===========
2118
2119ItemsView uses __len__, __iter__, and __getitem__.
2120KeysView uses __len__, __iter__, and __contains__.
2121ValuesView uses __len__, __iter__, and __getitem__.
2122
2123MutableMapping:
2124
2125============ ===========
2126method uses
2127============ ===========
2128__delitem__ +
2129__setitem__ +
2130clear popitem
2131pop __getitem__
2132 __delitem__
2133popitem __iter__
2134 _getitem__
2135 __delitem__
2136setdefault __getitem__
2137 __setitem__
2138update __setitem__
2139============ ===========
2140*/
2141
2142static int
2143mutablemapping_add_pairs(PyObject *self, PyObject *pairs)
2144{
2145 PyObject *pair, *iterator, *unexpected;
2146 int res = 0;
2147
2148 iterator = PyObject_GetIter(pairs);
2149 if (iterator == NULL)
2150 return -1;
2151 PyErr_Clear();
2152
2153 while ((pair = PyIter_Next(iterator)) != NULL) {
2154 /* could be more efficient (see UNPACK_SEQUENCE in ceval.c) */
Eric Snowc5e59602015-05-30 11:28:56 -06002155 PyObject *key = NULL, *value = NULL;
Eric Snow96c6af92015-05-29 22:21:39 -06002156 PyObject *pair_iterator = PyObject_GetIter(pair);
Eric Snowc5e59602015-05-30 11:28:56 -06002157 if (pair_iterator == NULL)
2158 goto Done;
Eric Snow96c6af92015-05-29 22:21:39 -06002159
2160 key = PyIter_Next(pair_iterator);
2161 if (key == NULL) {
2162 if (!PyErr_Occurred())
2163 PyErr_SetString(PyExc_ValueError,
2164 "need more than 0 values to unpack");
2165 goto Done;
2166 }
2167
2168 value = PyIter_Next(pair_iterator);
2169 if (value == NULL) {
2170 if (!PyErr_Occurred())
2171 PyErr_SetString(PyExc_ValueError,
2172 "need more than 1 value to unpack");
2173 goto Done;
2174 }
2175
2176 unexpected = PyIter_Next(pair_iterator);
2177 if (unexpected != NULL) {
2178 Py_DECREF(unexpected);
2179 PyErr_SetString(PyExc_ValueError,
2180 "too many values to unpack (expected 2)");
2181 goto Done;
2182 }
2183 else if (PyErr_Occurred())
2184 goto Done;
2185
2186 res = PyObject_SetItem(self, key, value);
2187
2188Done:
2189 Py_DECREF(pair);
Eric Snowc5e59602015-05-30 11:28:56 -06002190 Py_XDECREF(pair_iterator);
Eric Snow96c6af92015-05-29 22:21:39 -06002191 Py_XDECREF(key);
2192 Py_XDECREF(value);
2193 if (PyErr_Occurred())
2194 break;
2195 }
2196 Py_DECREF(iterator);
2197
2198 if (res < 0 || PyErr_Occurred() != NULL)
2199 return -1;
2200 else
2201 return 0;
2202}
2203
2204static PyObject *
2205mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
2206{
2207 int res = 0;
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002208 Py_ssize_t len;
2209 _Py_IDENTIFIER(items);
2210 _Py_IDENTIFIER(keys);
Eric Snow96c6af92015-05-29 22:21:39 -06002211
2212 /* first handle args, if any */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002213 assert(args == NULL || PyTuple_Check(args));
2214 len = (args != NULL) ? PyTuple_GET_SIZE(args) : 0;
Benjamin Peterson99e96f22015-06-06 23:20:32 -05002215 if (len > 1) {
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02002216 const char *msg = "update() takes at most 1 positional argument (%zd given)";
Eric Snow96c6af92015-05-29 22:21:39 -06002217 PyErr_Format(PyExc_TypeError, msg, len);
2218 return NULL;
2219 }
Eric Snow96c6af92015-05-29 22:21:39 -06002220
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002221 if (len) {
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002222 PyObject *func;
Benjamin Peterson0718de92015-06-07 00:00:42 -05002223 PyObject *other = PyTuple_GET_ITEM(args, 0); /* borrowed reference */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002224 assert(other != NULL);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002225 Py_INCREF(other);
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002226 if (PyDict_CheckExact(other)) {
2227 PyObject *items = PyDict_Items(other);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002228 Py_DECREF(other);
2229 if (items == NULL)
2230 return NULL;
2231 res = mutablemapping_add_pairs(self, items);
2232 Py_DECREF(items);
2233 if (res == -1)
2234 return NULL;
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002235 goto handle_kwargs;
Benjamin Peterson0718de92015-06-07 00:00:42 -05002236 }
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002237
Serhiy Storchakaf320be72018-01-25 10:49:40 +02002238 if (_PyObject_LookupAttrId(other, &PyId_keys, &func) < 0) {
2239 Py_DECREF(other);
2240 return NULL;
2241 }
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002242 if (func != NULL) {
Benjamin Peterson0718de92015-06-07 00:00:42 -05002243 PyObject *keys, *iterator, *key;
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002244 keys = _PyObject_CallNoArg(func);
2245 Py_DECREF(func);
Benjamin Peterson0718de92015-06-07 00:00:42 -05002246 if (keys == NULL) {
2247 Py_DECREF(other);
2248 return NULL;
2249 }
2250 iterator = PyObject_GetIter(keys);
2251 Py_DECREF(keys);
2252 if (iterator == NULL) {
2253 Py_DECREF(other);
2254 return NULL;
2255 }
2256 while (res == 0 && (key = PyIter_Next(iterator))) {
2257 PyObject *value = PyObject_GetItem(other, key);
2258 if (value != NULL) {
2259 res = PyObject_SetItem(self, key, value);
2260 Py_DECREF(value);
2261 }
2262 else {
2263 res = -1;
2264 }
2265 Py_DECREF(key);
2266 }
2267 Py_DECREF(other);
2268 Py_DECREF(iterator);
2269 if (res != 0 || PyErr_Occurred())
2270 return NULL;
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002271 goto handle_kwargs;
Benjamin Peterson0718de92015-06-07 00:00:42 -05002272 }
Serhiy Storchakaf320be72018-01-25 10:49:40 +02002273
2274 if (_PyObject_LookupAttrId(other, &PyId_items, &func) < 0) {
Eric Snow06aed902016-09-09 11:59:08 -07002275 Py_DECREF(other);
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002276 return NULL;
2277 }
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002278 if (func != NULL) {
2279 PyObject *items;
2280 Py_DECREF(other);
2281 items = _PyObject_CallNoArg(func);
2282 Py_DECREF(func);
Eric Snow06aed902016-09-09 11:59:08 -07002283 if (items == NULL)
2284 return NULL;
2285 res = mutablemapping_add_pairs(self, items);
2286 Py_DECREF(items);
2287 if (res == -1)
2288 return NULL;
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002289 goto handle_kwargs;
2290 }
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002291
2292 res = mutablemapping_add_pairs(self, other);
2293 Py_DECREF(other);
2294 if (res != 0)
2295 return NULL;
Benjamin Peterson0718de92015-06-07 00:00:42 -05002296 }
2297
Serhiy Storchaka60c3d352017-11-11 16:19:56 +02002298 handle_kwargs:
Benjamin Peterson0718de92015-06-07 00:00:42 -05002299 /* now handle kwargs */
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002300 assert(kwargs == NULL || PyDict_Check(kwargs));
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02002301 if (kwargs != NULL && PyDict_GET_SIZE(kwargs)) {
Serhiy Storchaka8003baf2015-10-18 09:53:17 +03002302 PyObject *items = PyDict_Items(kwargs);
Eric Snow96c6af92015-05-29 22:21:39 -06002303 if (items == NULL)
2304 return NULL;
2305 res = mutablemapping_add_pairs(self, items);
2306 Py_DECREF(items);
2307 if (res == -1)
2308 return NULL;
2309 }
Eric Snow96c6af92015-05-29 22:21:39 -06002310
2311 Py_RETURN_NONE;
2312}