1 /* Ordered Dictionary object implementation.
2 
3 This implementation is necessarily explicitly equivalent to the pure Python
4 OrderedDict class in Lib/collections/__init__.py.  The strategy there
5 involves using a doubly-linked-list to capture the order.  We keep to that
6 strategy, using a lower-level linked-list.
7 
8 About the Linked-List
9 =====================
10 
11 For the linked list we use a basic doubly-linked-list.  Using a circularly-
12 linked-list does have some benefits, but they don't apply so much here
13 since OrderedDict is focused on the ends of the list (for the most part).
14 Furthermore, there are some features of generic linked-lists that we simply
15 don't need for OrderedDict.  Thus a simple custom implementation meets our
16 needs.  Alternatives to our simple approach include the QCIRCLE_*
17 macros from BSD's queue.h, and the linux's list.h.
18 
19 Getting O(1) Node Lookup
20 ------------------------
21 
22 One invariant of Python's OrderedDict is that it preserves time complexity
23 of dict's methods, particularly the O(1) operations.  Simply adding a
24 linked-list on top of dict is not sufficient here; operations for nodes in
25 the middle of the linked-list implicitly require finding the node first.
26 With a simple linked-list like we're using, that is an O(n) operation.
27 Consequently, methods like __delitem__() would change from O(1) to O(n),
28 which is unacceptable.
29 
30 In order to preserve O(1) performance for node removal (finding nodes), we
31 must do better than just looping through the linked-list.  Here are options
32 we've considered:
33 
34 1. use a second dict to map keys to nodes (a la the pure Python version).
35 2. keep a simple hash table mirroring the order of dict's, mapping each key
36    to the corresponding node in the linked-list.
37 3. use a version of shared keys (split dict) that allows non-unicode keys.
38 4. have the value stored for each key be a (value, node) pair, and adjust
39    __getitem__(), get(), etc. accordingly.
40 
41 The approach with the least performance impact (time and space) is #2,
42 mirroring the key order of dict's dk_entries with an array of node pointers.
43 While _Py_dict_lookup() does not give us the index into the array,
44 we make use of pointer arithmetic to get that index.  An alternative would
45 be to refactor _Py_dict_lookup() to provide the index, explicitly exposing
46 the implementation detail.  We could even just use a custom lookup function
47 for OrderedDict that facilitates our need.  However, both approaches are
48 significantly more complicated than just using pointer arithmetic.
49 
50 The catch with mirroring the hash table ordering is that we have to keep
51 the ordering in sync through any dict resizes.  However, that order only
52 matters during node lookup.  We can simply defer any potential resizing
53 until we need to do a lookup.
54 
55 Linked-List Nodes
56 -----------------
57 
58 The current implementation stores a pointer to the associated key only.
59 One alternative would be to store a pointer to the PyDictKeyEntry instead.
60 This would save one pointer de-reference per item, which is nice during
61 calls to values() and items().  However, it adds unnecessary overhead
62 otherwise, so we stick with just the key.
63 
64 Linked-List API
65 ---------------
66 
67 As noted, the linked-list implemented here does not have all the bells and
68 whistles.  However, we recognize that the implementation may need to
69 change to accommodate performance improvements or extra functionality.  To
70 that end, we use a simple API to interact with the linked-list.  Here's a
71 summary of the methods/macros:
72 
73 Node info:
74 
75 * _odictnode_KEY(node)
76 * _odictnode_VALUE(od, node)
77 * _odictnode_PREV(node)
78 * _odictnode_NEXT(node)
79 
80 Linked-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 
87 For adding nodes:
88 
89 * _odict_add_head(od, node)
90 * _odict_add_tail(od, node)
91 * _odict_add_new_node(od, key, hash)
92 
93 For removing nodes:
94 
95 * _odict_clear_node(od, node, key, hash)
96 * _odict_clear_nodes(od, clear_each)
97 
98 Others:
99 
100 * _odict_find_node_hash(od, key, hash)
101 * _odict_find_node(od, key)
102 * _odict_keys_equal(od1, od2)
103 
104 And here's a look at how the linked-list relates to the OrderedDict API:
105 
106 ============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
107 method       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
119 clear                          ~             ~                        X
120 copy         X   X                                 X
121 items        X   X        X
122 keys         X            X
123 move_to_end  X                      X   X               ~    h/t key
124 pop                            free                              key
125 popitem      X   X             free X   X                        node
126 setdefault       ~                                      ?    ~
127 values           X        X
128 ============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
129 
130 __delitem__ is the only method that directly relies on finding an arbitrary
131 node in the linked-list.  Everything else is iteration or relates to the
132 ends of the linked-list.
133 
134 Situation that Endangers Consistency
135 ------------------------------------
136 Using a raw linked-list for OrderedDict exposes a key situation that can
137 cause problems.  If a node is stored in a variable, there is a chance that
138 the node may have been deallocated before the variable gets used, thus
139 potentially leading to a segmentation fault.  A key place where this shows
140 up is during iteration through the linked list (via _odict_FOREACH or
141 otherwise).
142 
143 A 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 
155 Another related problem, preserving consistent ordering during iteration,
156 is described below.  That one is not exclusive to using linked-lists.
157 
158 
159 Challenges from Subclassing dict
160 ================================
161 
162 OrderedDict subclasses dict, which is an unusual relationship between two
163 builtin types (other than the base object type).  Doing so results in
164 some complication and deserves further explanation.  There are two things
165 to consider here.  First, in what circumstances or with what adjustments
166 can OrderedDict be used as a drop-in replacement for dict (at the C level)?
167 Second, how can the OrderedDict implementation leverage the dict
168 implementation effectively without introducing unnecessary coupling or
169 inefficiencies?
170 
171 This second point is reflected here and in the implementation, so the
172 further focus is on the first point.  It is worth noting that for
173 overridden methods, the dict implementation is deferred to as much as
174 possible.  Furthermore, coupling is limited to as little as is reasonable.
175 
176 Concrete API Compatibility
177 --------------------------
178 
179 Use of the concrete C-API for dict (PyDict_*) with OrderedDict is
180 problematic.  (See http://bugs.python.org/issue10977.)  The concrete API
181 has a number of hard-coded assumptions tied to the dict implementation.
182 This is, in part, due to performance reasons, which is understandable
183 given the part dict plays in Python.
184 
185 Any attempt to replace dict with OrderedDict for any role in the
186 interpreter (e.g. **kwds) faces a challenge.  Such any effort must
187 recognize that the instances in affected locations currently interact with
188 the concrete API.
189 
190 Here are some ways to address this challenge:
191 
192 1. Change the relevant usage of the concrete API in CPython and add
193    PyDict_CheckExact() calls to each of the concrete API functions.
194 2. Adjust the relevant concrete API functions to explicitly accommodate
195    OrderedDict.
196 3. 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 
200 Adding the checks to the concrete API would help make any interpreter
201 switch to OrderedDict less painful for extension modules.  However, this
202 won't work.  The equivalent C API call to `dict.__setitem__(obj, k, v)`
203 is 'PyDict_SetItem(obj, k, v)`.  This illustrates how subclasses in C call
204 the base class's methods, since there is no equivalent of super() in the
205 C API.  Calling into Python for parent class API would work, but some
206 extension modules already rely on this feature of the concrete API.
207 
208 For reference, here is a breakdown of some of the dict concrete API:
209 
210 ========================== ============= =======================
211 concrete API               uses          abstract API
212 ========================== ============= =======================
213 PyDict_Check                             PyMapping_Check
214 (PyDict_CheckExact)                      -
215 (PyDict_New)                             -
216 (PyDictProxy_New)                        -
217 PyDict_Clear                             -
218 PyDict_Contains                          PySequence_Contains
219 PyDict_Copy                              -
220 PyDict_SetItem                           PyObject_SetItem
221 PyDict_SetItemString                     PyMapping_SetItemString
222 PyDict_DelItem                           PyMapping_DelItem
223 PyDict_DelItemString                     PyMapping_DelItemString
224 PyDict_GetItem                           -
225 PyDict_GetItemWithError                  PyObject_GetItem
226 _PyDict_GetItemIdWithError               -
227 PyDict_GetItemString                     PyMapping_GetItemString
228 PyDict_Items                             PyMapping_Items
229 PyDict_Keys                              PyMapping_Keys
230 PyDict_Values                            PyMapping_Values
231 PyDict_Size                              PyMapping_Size
232                                          PyMapping_Length
233 PyDict_Next                              PyIter_Next
234 _PyDict_Next                             -
235 PyDict_Merge                             -
236 PyDict_Update                            -
237 PyDict_MergeFromSeq2                     -
238 PyDict_ClearFreeList                     -
239 -                                        PyMapping_HasKeyString
240 -                                        PyMapping_HasKey
241 ========================== ============= =======================
242 
243 
244 The dict Interface Relative to OrderedDict
245 ==========================================
246 
247 Since OrderedDict subclasses dict, understanding the various methods and
248 attributes of dict is important for implementing OrderedDict.
249 
250 Relevant Type Slots
251 -------------------
252 
253 ================= ================ =================== ================
254 slot              attribute        object              dict
255 ================= ================ =================== ================
256 tp_dealloc        -                object_dealloc      dict_dealloc
257 tp_repr           __repr__         object_repr         dict_repr
258 sq_contains       __contains__     -                   dict_contains
259 mp_length         __len__          -                   dict_length
260 mp_subscript      __getitem__      -                   dict_subscript
261 mp_ass_subscript  __setitem__      -                   dict_ass_sub
262                   __delitem__
263 tp_hash           __hash__         _Py_HashPointer     ..._HashNotImpl
264 tp_str            __str__          object_str          -
265 tp_getattro       __getattribute__ ..._GenericGetAttr  (repeated)
266                   __getattr__
267 tp_setattro       __setattr__      ..._GenericSetAttr  (disabled)
268 tp_doc            __doc__          (literal)           dictionary_doc
269 tp_traverse       -                -                   dict_traverse
270 tp_clear          -                -                   dict_tp_clear
271 tp_richcompare    __eq__           object_richcompare  dict_richcompare
272                   __ne__
273 tp_weaklistoffset (__weakref__)    -                   -
274 tp_iter           __iter__         -                   dict_iter
275 tp_dictoffset     (__dict__)       -                   -
276 tp_init           __init__         object_init         dict_init
277 tp_alloc          -                PyType_GenericAlloc (repeated)
278 tp_new            __new__          object_new          dict_new
279 tp_free           -                PyObject_Del        PyObject_GC_Del
280 ================= ================ =================== ================
281 
282 Relevant Methods
283 ----------------
284 
285 ================ =================== ===============
286 method           object              dict
287 ================ =================== ===============
288 __reduce__       object_reduce       -
289 __sizeof__       object_sizeof       dict_sizeof
290 clear            -                   dict_clear
291 copy             -                   dict_copy
292 fromkeys         -                   dict_fromkeys
293 get              -                   dict_get
294 items            -                   dictitems_new
295 keys             -                   dictkeys_new
296 pop              -                   dict_pop
297 popitem          -                   dict_popitem
298 setdefault       -                   dict_setdefault
299 update           -                   dict_update
300 values           -                   dictvalues_new
301 ================ =================== ===============
302 
303 
304 Pure Python OrderedDict
305 =======================
306 
307 As already noted, compatibility with the pure Python OrderedDict
308 implementation is a key goal of this C implementation.  To further that
309 goal, here's a summary of how OrderedDict-specific methods are implemented
310 in collections/__init__.py.  Also provided is an indication of which
311 methods directly mutate or iterate the object, as well as any relationship
312 with the underlying linked-list.
313 
314 ============= ============== == ================ === === ====
315 method        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__
337 clear         OrderedDict    Y  dict.clear           X
338 copy          OrderedDict    N  __class__
339                                 __init__
340 fromkeys      OrderedDict    N  __setitem__
341 get           dict           -  -                ~
342 items         MutableMapping -  ItemsView                X
343 keys          MutableMapping -  KeysView                 X
344 move_to_end   OrderedDict    Y  -                    X
345 pop           OrderedDict    N  __contains__         X
346                                 __getitem__
347                                 __delitem__
348 popitem       OrderedDict    Y  dict.pop             X
349 setdefault    OrderedDict    N  __contains__         ~
350                                 __getitem__
351                                 __setitem__
352 update        MutableMapping -  __setitem__          ~
353 values        MutableMapping -  ValuesView               X
354 ============= ============== == ================ === === ====
355 
356 __reversed__ and move_to_end are both exclusive to OrderedDict.
357 
358 
359 C OrderedDict Implementation
360 ============================
361 
362 ================= ================
363 slot              impl
364 ================= ================
365 tp_dealloc        odict_dealloc
366 tp_repr           odict_repr
367 mp_ass_subscript  odict_ass_sub
368 tp_doc            odict_doc
369 tp_traverse       odict_traverse
370 tp_clear          odict_tp_clear
371 tp_richcompare    odict_richcompare
372 tp_weaklistoffset (offset)
373 tp_iter           odict_iter
374 tp_dictoffset     (offset)
375 tp_init           odict_init
376 tp_alloc          (repeated)
377 ================= ================
378 
379 ================= ================
380 method            impl
381 ================= ================
382 __reduce__        odict_reduce
383 __sizeof__        odict_sizeof
384 clear             odict_clear
385 copy              odict_copy
386 fromkeys          odict_fromkeys
387 items             odictitems_new
388 keys              odictkeys_new
389 pop               odict_pop
390 popitem           odict_popitem
391 setdefault        odict_setdefault
392 update            odict_update
393 values            odictvalues_new
394 ================= ================
395 
396 Inherited unchanged from object/dict:
397 
398 ================ ==========================
399 method           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
410 get              -
411 ================ ==========================
412 
413 
414 Other Challenges
415 ================
416 
417 Preserving Ordering During Iteration
418 ------------------------------------
419 During iteration through an OrderedDict, it is possible that items could
420 get added, removed, or reordered.  For a linked-list implementation, as
421 with some other implementations, that situation may lead to undefined
422 behavior.  The documentation for dict mentions this in the `iter()` section
423 of http://docs.python.org/3.4/library/stdtypes.html#dictionary-view-objects.
424 In this implementation we follow dict's lead (as does the pure Python
425 implementation) for __iter__(), keys(), values(), and items().
426 
427 For internal iteration (using _odict_FOREACH or not), there is still the
428 risk that not all nodes that we expect to be seen in the loop actually get
429 seen.  Thus, we are careful in each of those places to ensure that they
430 are.  This comes, of course, at a small price at each location.  The
431 solutions are much the same as those detailed in the `Situation that
432 Endangers Consistency` section above.
433 
434 
435 Potential 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
442     would be invalidated after a resize, which is particularly problematic
443     for the iterators.
444 * Use a more stream-lined implementation of update() and, likely indirectly,
445   __init__().
446 
447 */
448 
449 /* TODO
450 
451 sooner:
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 
457 later:
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"
468 #include "pycore_call.h"          // _PyObject_CallNoArgs()
469 #include "pycore_object.h"        // _PyObject_GC_UNTRACK()
470 #include "pycore_dict.h"          // _Py_dict_lookup()
471 #include <stddef.h>               // offsetof()
472 
473 #include "clinic/odictobject.c.h"
474 
475 /*[clinic input]
476 class OrderedDict "PyODictObject *" "&PyODict_Type"
477 [clinic start generated code]*/
478 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ca0641cf6143d4af]*/
479 
480 
481 typedef struct _odictnode _ODictNode;
482 
483 /* PyODictObject */
484 struct _odictobject {
485     PyDictObject od_dict;        /* the underlying dict */
486     _ODictNode *od_first;        /* first node in the linked list, if any */
487     _ODictNode *od_last;         /* last node in the linked list, if any */
488     /* od_fast_nodes, od_fast_nodes_size and od_resize_sentinel are managed
489      * by _odict_resize().
490      * Note that we rely on implementation details of dict for both. */
491     _ODictNode **od_fast_nodes;  /* hash table that mirrors the dict table */
492     Py_ssize_t od_fast_nodes_size;
493     void *od_resize_sentinel;    /* changes if odict should be resized */
494 
495     size_t od_state;             /* incremented whenever the LL changes */
496     PyObject *od_inst_dict;      /* OrderedDict().__dict__ */
497     PyObject *od_weakreflist;    /* holds weakrefs to the odict */
498 };
499 
500 
501 /* ----------------------------------------------
502  * odict keys (a simple doubly-linked list)
503  */
504 
505 struct _odictnode {
506     PyObject *key;
507     Py_hash_t hash;
508     _ODictNode *next;
509     _ODictNode *prev;
510 };
511 
512 #define _odictnode_KEY(node) \
513     (node->key)
514 #define _odictnode_HASH(node) \
515     (node->hash)
516 /* borrowed reference */
517 #define _odictnode_VALUE(node, od) \
518     PyODict_GetItemWithError((PyObject *)od, _odictnode_KEY(node))
519 #define _odictnode_PREV(node) (node->prev)
520 #define _odictnode_NEXT(node) (node->next)
521 
522 #define _odict_FIRST(od) (((PyODictObject *)od)->od_first)
523 #define _odict_LAST(od) (((PyODictObject *)od)->od_last)
524 #define _odict_EMPTY(od) (_odict_FIRST(od) == NULL)
525 #define _odict_FOREACH(od, node) \
526     for (node = _odict_FIRST(od); node != NULL; node = _odictnode_NEXT(node))
527 
528 /* Return the index into the hash table, regardless of a valid node. */
529 static Py_ssize_t
_odict_get_index_raw(PyODictObject * od,PyObject * key,Py_hash_t hash)530 _odict_get_index_raw(PyODictObject *od, PyObject *key, Py_hash_t hash)
531 {
532     PyObject *value = NULL;
533     PyDictKeysObject *keys = ((PyDictObject *)od)->ma_keys;
534     Py_ssize_t ix;
535 
536     ix = _Py_dict_lookup((PyDictObject *)od, key, hash, &value);
537     if (ix == DKIX_EMPTY) {
538         return keys->dk_nentries;  /* index of new entry */
539     }
540     if (ix < 0)
541         return -1;
542     /* We use pointer arithmetic to get the entry's index into the table. */
543     return ix;
544 }
545 
546 #define ONE ((Py_ssize_t)1)
547 
548 /* Replace od->od_fast_nodes with a new table matching the size of dict's. */
549 static int
_odict_resize(PyODictObject * od)550 _odict_resize(PyODictObject *od)
551 {
552     Py_ssize_t size, i;
553     _ODictNode **fast_nodes, *node;
554 
555     /* Initialize a new "fast nodes" table. */
556     size = ONE << (((PyDictObject *)od)->ma_keys->dk_log2_size);
557     fast_nodes = PyMem_NEW(_ODictNode *, size);
558     if (fast_nodes == NULL) {
559         PyErr_NoMemory();
560         return -1;
561     }
562     for (i = 0; i < size; i++)
563         fast_nodes[i] = NULL;
564 
565     /* Copy the current nodes into the table. */
566     _odict_FOREACH(od, node) {
567         i = _odict_get_index_raw(od, _odictnode_KEY(node),
568                                  _odictnode_HASH(node));
569         if (i < 0) {
570             PyMem_Free(fast_nodes);
571             return -1;
572         }
573         fast_nodes[i] = node;
574     }
575 
576     /* Replace the old fast nodes table. */
577     PyMem_Free(od->od_fast_nodes);
578     od->od_fast_nodes = fast_nodes;
579     od->od_fast_nodes_size = size;
580     od->od_resize_sentinel = ((PyDictObject *)od)->ma_keys;
581     return 0;
582 }
583 
584 /* Return the index into the hash table, regardless of a valid node. */
585 static Py_ssize_t
_odict_get_index(PyODictObject * od,PyObject * key,Py_hash_t hash)586 _odict_get_index(PyODictObject *od, PyObject *key, Py_hash_t hash)
587 {
588     PyDictKeysObject *keys;
589 
590     assert(key != NULL);
591     keys = ((PyDictObject *)od)->ma_keys;
592 
593     /* Ensure od_fast_nodes and dk_entries are in sync. */
594     if (od->od_resize_sentinel != keys ||
595         od->od_fast_nodes_size != (ONE << (keys->dk_log2_size))) {
596         int resize_res = _odict_resize(od);
597         if (resize_res < 0)
598             return -1;
599     }
600 
601     return _odict_get_index_raw(od, key, hash);
602 }
603 
604 /* Returns NULL if there was some error or the key was not found. */
605 static _ODictNode *
_odict_find_node_hash(PyODictObject * od,PyObject * key,Py_hash_t hash)606 _odict_find_node_hash(PyODictObject *od, PyObject *key, Py_hash_t hash)
607 {
608     Py_ssize_t index;
609 
610     if (_odict_EMPTY(od))
611         return NULL;
612     index = _odict_get_index(od, key, hash);
613     if (index < 0)
614         return NULL;
615     assert(od->od_fast_nodes != NULL);
616     return od->od_fast_nodes[index];
617 }
618 
619 static _ODictNode *
_odict_find_node(PyODictObject * od,PyObject * key)620 _odict_find_node(PyODictObject *od, PyObject *key)
621 {
622     Py_ssize_t index;
623     Py_hash_t hash;
624 
625     if (_odict_EMPTY(od))
626         return NULL;
627     hash = PyObject_Hash(key);
628     if (hash == -1)
629         return NULL;
630     index = _odict_get_index(od, key, hash);
631     if (index < 0)
632         return NULL;
633     assert(od->od_fast_nodes != NULL);
634     return od->od_fast_nodes[index];
635 }
636 
637 static void
_odict_add_head(PyODictObject * od,_ODictNode * node)638 _odict_add_head(PyODictObject *od, _ODictNode *node)
639 {
640     _odictnode_PREV(node) = NULL;
641     _odictnode_NEXT(node) = _odict_FIRST(od);
642     if (_odict_FIRST(od) == NULL)
643         _odict_LAST(od) = node;
644     else
645         _odictnode_PREV(_odict_FIRST(od)) = node;
646     _odict_FIRST(od) = node;
647     od->od_state++;
648 }
649 
650 static void
_odict_add_tail(PyODictObject * od,_ODictNode * node)651 _odict_add_tail(PyODictObject *od, _ODictNode *node)
652 {
653     _odictnode_PREV(node) = _odict_LAST(od);
654     _odictnode_NEXT(node) = NULL;
655     if (_odict_LAST(od) == NULL)
656         _odict_FIRST(od) = node;
657     else
658         _odictnode_NEXT(_odict_LAST(od)) = node;
659     _odict_LAST(od) = node;
660     od->od_state++;
661 }
662 
663 /* adds the node to the end of the list */
664 static int
_odict_add_new_node(PyODictObject * od,PyObject * key,Py_hash_t hash)665 _odict_add_new_node(PyODictObject *od, PyObject *key, Py_hash_t hash)
666 {
667     Py_ssize_t i;
668     _ODictNode *node;
669 
670     Py_INCREF(key);
671     i = _odict_get_index(od, key, hash);
672     if (i < 0) {
673         if (!PyErr_Occurred())
674             PyErr_SetObject(PyExc_KeyError, key);
675         Py_DECREF(key);
676         return -1;
677     }
678     assert(od->od_fast_nodes != NULL);
679     if (od->od_fast_nodes[i] != NULL) {
680         /* We already have a node for the key so there's no need to add one. */
681         Py_DECREF(key);
682         return 0;
683     }
684 
685     /* must not be added yet */
686     node = (_ODictNode *)PyMem_Malloc(sizeof(_ODictNode));
687     if (node == NULL) {
688         Py_DECREF(key);
689         PyErr_NoMemory();
690         return -1;
691     }
692 
693     _odictnode_KEY(node) = key;
694     _odictnode_HASH(node) = hash;
695     _odict_add_tail(od, node);
696     od->od_fast_nodes[i] = node;
697     return 0;
698 }
699 
700 /* Putting the decref after the free causes problems. */
701 #define _odictnode_DEALLOC(node) \
702     do { \
703         Py_DECREF(_odictnode_KEY(node)); \
704         PyMem_Free((void *)node); \
705     } while (0)
706 
707 /* Repeated calls on the same node are no-ops. */
708 static void
_odict_remove_node(PyODictObject * od,_ODictNode * node)709 _odict_remove_node(PyODictObject *od, _ODictNode *node)
710 {
711     if (_odict_FIRST(od) == node)
712         _odict_FIRST(od) = _odictnode_NEXT(node);
713     else if (_odictnode_PREV(node) != NULL)
714         _odictnode_NEXT(_odictnode_PREV(node)) = _odictnode_NEXT(node);
715 
716     if (_odict_LAST(od) == node)
717         _odict_LAST(od) = _odictnode_PREV(node);
718     else if (_odictnode_NEXT(node) != NULL)
719         _odictnode_PREV(_odictnode_NEXT(node)) = _odictnode_PREV(node);
720 
721     _odictnode_PREV(node) = NULL;
722     _odictnode_NEXT(node) = NULL;
723     od->od_state++;
724 }
725 
726 /* If someone calls PyDict_DelItem() directly on an OrderedDict, we'll
727    get all sorts of problems here.  In PyODict_DelItem we make sure to
728    call _odict_clear_node first.
729 
730    This matters in the case of colliding keys.  Suppose we add 3 keys:
731    [A, B, C], where the hash of C collides with A and the next possible
732    index in the hash table is occupied by B.  If we remove B then for C
733    the dict's looknode func will give us the old index of B instead of
734    the index we got before deleting B.  However, the node for C in
735    od_fast_nodes is still at the old dict index of C.  Thus to be sure
736    things don't get out of sync, we clear the node in od_fast_nodes
737    *before* calling PyDict_DelItem.
738 
739    The same must be done for any other OrderedDict operations where
740    we modify od_fast_nodes.
741 */
742 static int
_odict_clear_node(PyODictObject * od,_ODictNode * node,PyObject * key,Py_hash_t hash)743 _odict_clear_node(PyODictObject *od, _ODictNode *node, PyObject *key,
744                   Py_hash_t hash)
745 {
746     Py_ssize_t i;
747 
748     assert(key != NULL);
749     if (_odict_EMPTY(od)) {
750         /* Let later code decide if this is a KeyError. */
751         return 0;
752     }
753 
754     i = _odict_get_index(od, key, hash);
755     if (i < 0)
756         return PyErr_Occurred() ? -1 : 0;
757 
758     assert(od->od_fast_nodes != NULL);
759     if (node == NULL)
760         node = od->od_fast_nodes[i];
761     assert(node == od->od_fast_nodes[i]);
762     if (node == NULL) {
763         /* Let later code decide if this is a KeyError. */
764         return 0;
765     }
766 
767     // Now clear the node.
768     od->od_fast_nodes[i] = NULL;
769     _odict_remove_node(od, node);
770     _odictnode_DEALLOC(node);
771     return 0;
772 }
773 
774 static void
_odict_clear_nodes(PyODictObject * od)775 _odict_clear_nodes(PyODictObject *od)
776 {
777     _ODictNode *node, *next;
778 
779     PyMem_Free(od->od_fast_nodes);
780     od->od_fast_nodes = NULL;
781     od->od_fast_nodes_size = 0;
782     od->od_resize_sentinel = NULL;
783 
784     node = _odict_FIRST(od);
785     _odict_FIRST(od) = NULL;
786     _odict_LAST(od) = NULL;
787     while (node != NULL) {
788         next = _odictnode_NEXT(node);
789         _odictnode_DEALLOC(node);
790         node = next;
791     }
792 }
793 
794 /* There isn't any memory management of nodes past this point. */
795 #undef _odictnode_DEALLOC
796 
797 static int
_odict_keys_equal(PyODictObject * a,PyODictObject * b)798 _odict_keys_equal(PyODictObject *a, PyODictObject *b)
799 {
800     _ODictNode *node_a, *node_b;
801 
802     node_a = _odict_FIRST(a);
803     node_b = _odict_FIRST(b);
804     while (1) {
805         if (node_a == NULL && node_b == NULL)
806             /* success: hit the end of each at the same time */
807             return 1;
808         else if (node_a == NULL || node_b == NULL)
809             /* unequal length */
810             return 0;
811         else {
812             int res = PyObject_RichCompareBool(
813                                             (PyObject *)_odictnode_KEY(node_a),
814                                             (PyObject *)_odictnode_KEY(node_b),
815                                             Py_EQ);
816             if (res < 0)
817                 return res;
818             else if (res == 0)
819                 return 0;
820 
821             /* otherwise it must match, so move on to the next one */
822             node_a = _odictnode_NEXT(node_a);
823             node_b = _odictnode_NEXT(node_b);
824         }
825     }
826 }
827 
828 
829 /* ----------------------------------------------
830  * OrderedDict mapping methods
831  */
832 
833 /* mp_ass_subscript: __setitem__() and __delitem__() */
834 
835 static int
odict_mp_ass_sub(PyODictObject * od,PyObject * v,PyObject * w)836 odict_mp_ass_sub(PyODictObject *od, PyObject *v, PyObject *w)
837 {
838     if (w == NULL)
839         return PyODict_DelItem((PyObject *)od, v);
840     else
841         return PyODict_SetItem((PyObject *)od, v, w);
842 }
843 
844 /* tp_as_mapping */
845 
846 static PyMappingMethods odict_as_mapping = {
847     0,                                  /*mp_length*/
848     0,                                  /*mp_subscript*/
849     (objobjargproc)odict_mp_ass_sub,    /*mp_ass_subscript*/
850 };
851 
852 
853 /* ----------------------------------------------
854  * OrderedDict number methods
855  */
856 
857 static int mutablemapping_update_arg(PyObject*, PyObject*);
858 
859 static PyObject *
odict_or(PyObject * left,PyObject * right)860 odict_or(PyObject *left, PyObject *right)
861 {
862     PyTypeObject *type;
863     PyObject *other;
864     if (PyODict_Check(left)) {
865         type = Py_TYPE(left);
866         other = right;
867     }
868     else {
869         type = Py_TYPE(right);
870         other = left;
871     }
872     if (!PyDict_Check(other)) {
873         Py_RETURN_NOTIMPLEMENTED;
874     }
875     PyObject *new = PyObject_CallOneArg((PyObject*)type, left);
876     if (!new) {
877         return NULL;
878     }
879     if (mutablemapping_update_arg(new, right) < 0) {
880         Py_DECREF(new);
881         return NULL;
882     }
883     return new;
884 }
885 
886 static PyObject *
odict_inplace_or(PyObject * self,PyObject * other)887 odict_inplace_or(PyObject *self, PyObject *other)
888 {
889     if (mutablemapping_update_arg(self, other) < 0) {
890         return NULL;
891     }
892     Py_INCREF(self);
893     return self;
894 }
895 
896 /* tp_as_number */
897 
898 static PyNumberMethods odict_as_number = {
899     .nb_or = odict_or,
900     .nb_inplace_or = odict_inplace_or,
901 };
902 
903 
904 /* ----------------------------------------------
905  * OrderedDict methods
906  */
907 
908 /* fromkeys() */
909 
910 /*[clinic input]
911 @classmethod
912 OrderedDict.fromkeys
913 
914     iterable as seq: object
915     value: object = None
916 
917 Create a new ordered dictionary with keys from iterable and values set to value.
918 [clinic start generated code]*/
919 
920 static PyObject *
OrderedDict_fromkeys_impl(PyTypeObject * type,PyObject * seq,PyObject * value)921 OrderedDict_fromkeys_impl(PyTypeObject *type, PyObject *seq, PyObject *value)
922 /*[clinic end generated code: output=c10390d452d78d6d input=1a0476c229c597b3]*/
923 {
924     return _PyDict_FromKeys((PyObject *)type, seq, value);
925 }
926 
927 /* __sizeof__() */
928 
929 /* OrderedDict.__sizeof__() does not have a docstring. */
930 PyDoc_STRVAR(odict_sizeof__doc__, "");
931 
932 static PyObject *
odict_sizeof(PyODictObject * od,PyObject * Py_UNUSED (ignored))933 odict_sizeof(PyODictObject *od, PyObject *Py_UNUSED(ignored))
934 {
935     Py_ssize_t res = _PyDict_SizeOf((PyDictObject *)od);
936     res += sizeof(_ODictNode *) * od->od_fast_nodes_size;  /* od_fast_nodes */
937     if (!_odict_EMPTY(od)) {
938         res += sizeof(_ODictNode) * PyODict_SIZE(od);  /* linked-list */
939     }
940     return PyLong_FromSsize_t(res);
941 }
942 
943 /* __reduce__() */
944 
945 PyDoc_STRVAR(odict_reduce__doc__, "Return state information for pickling");
946 
947 static PyObject *
odict_reduce(register PyODictObject * od,PyObject * Py_UNUSED (ignored))948 odict_reduce(register PyODictObject *od, PyObject *Py_UNUSED(ignored))
949 {
950     PyObject *state, *result = NULL;
951     PyObject *items_iter, *items, *args = NULL;
952 
953     /* capture any instance state */
954     state = _PyObject_GetState((PyObject *)od);
955     if (state == NULL)
956         goto Done;
957 
958     /* build the result */
959     args = PyTuple_New(0);
960     if (args == NULL)
961         goto Done;
962 
963     items = PyObject_CallMethodNoArgs((PyObject *)od, &_Py_ID(items));
964     if (items == NULL)
965         goto Done;
966 
967     items_iter = PyObject_GetIter(items);
968     Py_DECREF(items);
969     if (items_iter == NULL)
970         goto Done;
971 
972     result = PyTuple_Pack(5, Py_TYPE(od), args, state, Py_None, items_iter);
973     Py_DECREF(items_iter);
974 
975 Done:
976     Py_XDECREF(state);
977     Py_XDECREF(args);
978 
979     return result;
980 }
981 
982 /* setdefault(): Skips __missing__() calls. */
983 
984 
985 /*[clinic input]
986 OrderedDict.setdefault
987 
988     key: object
989     default: object = None
990 
991 Insert key with a value of default if key is not in the dictionary.
992 
993 Return the value for key if key is in the dictionary, else default.
994 [clinic start generated code]*/
995 
996 static PyObject *
OrderedDict_setdefault_impl(PyODictObject * self,PyObject * key,PyObject * default_value)997 OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key,
998                             PyObject *default_value)
999 /*[clinic end generated code: output=97537cb7c28464b6 input=38e098381c1efbc6]*/
1000 {
1001     PyObject *result = NULL;
1002 
1003     if (PyODict_CheckExact(self)) {
1004         result = PyODict_GetItemWithError(self, key);  /* borrowed */
1005         if (result == NULL) {
1006             if (PyErr_Occurred())
1007                 return NULL;
1008             assert(_odict_find_node(self, key) == NULL);
1009             if (PyODict_SetItem((PyObject *)self, key, default_value) >= 0) {
1010                 result = default_value;
1011                 Py_INCREF(result);
1012             }
1013         }
1014         else {
1015             Py_INCREF(result);
1016         }
1017     }
1018     else {
1019         int exists = PySequence_Contains((PyObject *)self, key);
1020         if (exists < 0) {
1021             return NULL;
1022         }
1023         else if (exists) {
1024             result = PyObject_GetItem((PyObject *)self, key);
1025         }
1026         else if (PyObject_SetItem((PyObject *)self, key, default_value) >= 0) {
1027             result = default_value;
1028             Py_INCREF(result);
1029         }
1030     }
1031 
1032     return result;
1033 }
1034 
1035 /* pop() */
1036 
1037 static PyObject *
_odict_popkey_hash(PyObject * od,PyObject * key,PyObject * failobj,Py_hash_t hash)1038 _odict_popkey_hash(PyObject *od, PyObject *key, PyObject *failobj,
1039                    Py_hash_t hash)
1040 {
1041     PyObject *value = NULL;
1042 
1043     _ODictNode *node = _odict_find_node_hash((PyODictObject *)od, key, hash);
1044     if (node != NULL) {
1045         /* Pop the node first to avoid a possible dict resize (due to
1046            eval loop reentrancy) and complications due to hash collision
1047            resolution. */
1048         int res = _odict_clear_node((PyODictObject *)od, node, key, hash);
1049         if (res < 0) {
1050             return NULL;
1051         }
1052         /* Now delete the value from the dict. */
1053         value = _PyDict_Pop_KnownHash(od, key, hash, failobj);
1054     }
1055     else if (value == NULL && !PyErr_Occurred()) {
1056         /* Apply the fallback value, if necessary. */
1057         if (failobj) {
1058             value = failobj;
1059             Py_INCREF(failobj);
1060         }
1061         else {
1062             PyErr_SetObject(PyExc_KeyError, key);
1063         }
1064     }
1065 
1066     return value;
1067 }
1068 
1069 /* Skips __missing__() calls. */
1070 /*[clinic input]
1071 OrderedDict.pop
1072 
1073     key: object
1074     default: object = NULL
1075 
1076 od.pop(key[,default]) -> v, remove specified key and return the corresponding value.
1077 
1078 If the key is not found, return the default if given; otherwise,
1079 raise a KeyError.
1080 [clinic start generated code]*/
1081 
1082 static PyObject *
OrderedDict_pop_impl(PyODictObject * self,PyObject * key,PyObject * default_value)1083 OrderedDict_pop_impl(PyODictObject *self, PyObject *key,
1084                      PyObject *default_value)
1085 /*[clinic end generated code: output=7a6447d104e7494b input=7efe36601007dff7]*/
1086 {
1087     Py_hash_t hash = PyObject_Hash(key);
1088     if (hash == -1)
1089         return NULL;
1090     return _odict_popkey_hash((PyObject *)self, key, default_value, hash);
1091 }
1092 
1093 
1094 /* popitem() */
1095 
1096 /*[clinic input]
1097 OrderedDict.popitem
1098 
1099     last: bool = True
1100 
1101 Remove and return a (key, value) pair from the dictionary.
1102 
1103 Pairs are returned in LIFO order if last is true or FIFO order if false.
1104 [clinic start generated code]*/
1105 
1106 static PyObject *
OrderedDict_popitem_impl(PyODictObject * self,int last)1107 OrderedDict_popitem_impl(PyODictObject *self, int last)
1108 /*[clinic end generated code: output=98e7d986690d49eb input=d992ac5ee8305e1a]*/
1109 {
1110     PyObject *key, *value, *item = NULL;
1111     _ODictNode *node;
1112 
1113     /* pull the item */
1114 
1115     if (_odict_EMPTY(self)) {
1116         PyErr_SetString(PyExc_KeyError, "dictionary is empty");
1117         return NULL;
1118     }
1119 
1120     node = last ? _odict_LAST(self) : _odict_FIRST(self);
1121     key = _odictnode_KEY(node);
1122     Py_INCREF(key);
1123     value = _odict_popkey_hash((PyObject *)self, key, NULL, _odictnode_HASH(node));
1124     if (value == NULL)
1125         return NULL;
1126     item = PyTuple_Pack(2, key, value);
1127     Py_DECREF(key);
1128     Py_DECREF(value);
1129     return item;
1130 }
1131 
1132 /* keys() */
1133 
1134 /* MutableMapping.keys() does not have a docstring. */
1135 PyDoc_STRVAR(odict_keys__doc__, "");
1136 
1137 static PyObject * odictkeys_new(PyObject *od, PyObject *Py_UNUSED(ignored));  /* forward */
1138 
1139 /* values() */
1140 
1141 /* MutableMapping.values() does not have a docstring. */
1142 PyDoc_STRVAR(odict_values__doc__, "");
1143 
1144 static PyObject * odictvalues_new(PyObject *od, PyObject *Py_UNUSED(ignored));  /* forward */
1145 
1146 /* items() */
1147 
1148 /* MutableMapping.items() does not have a docstring. */
1149 PyDoc_STRVAR(odict_items__doc__, "");
1150 
1151 static PyObject * odictitems_new(PyObject *od, PyObject *Py_UNUSED(ignored));  /* forward */
1152 
1153 /* update() */
1154 
1155 /* MutableMapping.update() does not have a docstring. */
1156 PyDoc_STRVAR(odict_update__doc__, "");
1157 
1158 /* forward */
1159 static PyObject * mutablemapping_update(PyObject *, PyObject *, PyObject *);
1160 
1161 #define odict_update mutablemapping_update
1162 
1163 /* clear() */
1164 
1165 PyDoc_STRVAR(odict_clear__doc__,
1166              "od.clear() -> None.  Remove all items from od.");
1167 
1168 static PyObject *
odict_clear(register PyODictObject * od,PyObject * Py_UNUSED (ignored))1169 odict_clear(register PyODictObject *od, PyObject *Py_UNUSED(ignored))
1170 {
1171     PyDict_Clear((PyObject *)od);
1172     _odict_clear_nodes(od);
1173     Py_RETURN_NONE;
1174 }
1175 
1176 /* copy() */
1177 
1178 /* forward */
1179 static int _PyODict_SetItem_KnownHash(PyObject *, PyObject *, PyObject *,
1180                                       Py_hash_t);
1181 
1182 PyDoc_STRVAR(odict_copy__doc__, "od.copy() -> a shallow copy of od");
1183 
1184 static PyObject *
odict_copy(register PyODictObject * od,PyObject * Py_UNUSED (ignored))1185 odict_copy(register PyODictObject *od, PyObject *Py_UNUSED(ignored))
1186 {
1187     _ODictNode *node;
1188     PyObject *od_copy;
1189 
1190     if (PyODict_CheckExact(od))
1191         od_copy = PyODict_New();
1192     else
1193         od_copy = _PyObject_CallNoArgs((PyObject *)Py_TYPE(od));
1194     if (od_copy == NULL)
1195         return NULL;
1196 
1197     if (PyODict_CheckExact(od)) {
1198         _odict_FOREACH(od, node) {
1199             PyObject *key = _odictnode_KEY(node);
1200             PyObject *value = _odictnode_VALUE(node, od);
1201             if (value == NULL) {
1202                 if (!PyErr_Occurred())
1203                     PyErr_SetObject(PyExc_KeyError, key);
1204                 goto fail;
1205             }
1206             if (_PyODict_SetItem_KnownHash((PyObject *)od_copy, key, value,
1207                                            _odictnode_HASH(node)) != 0)
1208                 goto fail;
1209         }
1210     }
1211     else {
1212         _odict_FOREACH(od, node) {
1213             int res;
1214             PyObject *value = PyObject_GetItem((PyObject *)od,
1215                                                _odictnode_KEY(node));
1216             if (value == NULL)
1217                 goto fail;
1218             res = PyObject_SetItem((PyObject *)od_copy,
1219                                    _odictnode_KEY(node), value);
1220             Py_DECREF(value);
1221             if (res != 0)
1222                 goto fail;
1223         }
1224     }
1225     return od_copy;
1226 
1227 fail:
1228     Py_DECREF(od_copy);
1229     return NULL;
1230 }
1231 
1232 /* __reversed__() */
1233 
1234 PyDoc_STRVAR(odict_reversed__doc__, "od.__reversed__() <==> reversed(od)");
1235 
1236 #define _odict_ITER_REVERSED 1
1237 #define _odict_ITER_KEYS 2
1238 #define _odict_ITER_VALUES 4
1239 #define _odict_ITER_ITEMS (_odict_ITER_KEYS|_odict_ITER_VALUES)
1240 
1241 /* forward */
1242 static PyObject * odictiter_new(PyODictObject *, int);
1243 
1244 static PyObject *
odict_reversed(PyODictObject * od,PyObject * Py_UNUSED (ignored))1245 odict_reversed(PyODictObject *od, PyObject *Py_UNUSED(ignored))
1246 {
1247     return odictiter_new(od, _odict_ITER_KEYS|_odict_ITER_REVERSED);
1248 }
1249 
1250 
1251 /* move_to_end() */
1252 
1253 /*[clinic input]
1254 OrderedDict.move_to_end
1255 
1256     key: object
1257     last: bool = True
1258 
1259 Move an existing element to the end (or beginning if last is false).
1260 
1261 Raise KeyError if the element does not exist.
1262 [clinic start generated code]*/
1263 
1264 static PyObject *
OrderedDict_move_to_end_impl(PyODictObject * self,PyObject * key,int last)1265 OrderedDict_move_to_end_impl(PyODictObject *self, PyObject *key, int last)
1266 /*[clinic end generated code: output=fafa4c5cc9b92f20 input=d6ceff7132a2fcd7]*/
1267 {
1268     _ODictNode *node;
1269 
1270     if (_odict_EMPTY(self)) {
1271         PyErr_SetObject(PyExc_KeyError, key);
1272         return NULL;
1273     }
1274     node = last ? _odict_LAST(self) : _odict_FIRST(self);
1275     if (key != _odictnode_KEY(node)) {
1276         node = _odict_find_node(self, key);
1277         if (node == NULL) {
1278             if (!PyErr_Occurred())
1279                 PyErr_SetObject(PyExc_KeyError, key);
1280             return NULL;
1281         }
1282         if (last) {
1283             /* Only move if not already the last one. */
1284             if (node != _odict_LAST(self)) {
1285                 _odict_remove_node(self, node);
1286                 _odict_add_tail(self, node);
1287             }
1288         }
1289         else {
1290             /* Only move if not already the first one. */
1291             if (node != _odict_FIRST(self)) {
1292                 _odict_remove_node(self, node);
1293                 _odict_add_head(self, node);
1294             }
1295         }
1296     }
1297     Py_RETURN_NONE;
1298 }
1299 
1300 
1301 /* tp_methods */
1302 
1303 static PyMethodDef odict_methods[] = {
1304 
1305     /* overridden dict methods */
1306     ORDEREDDICT_FROMKEYS_METHODDEF
1307     {"__sizeof__",      (PyCFunction)odict_sizeof,      METH_NOARGS,
1308      odict_sizeof__doc__},
1309     {"__reduce__",      (PyCFunction)odict_reduce,      METH_NOARGS,
1310      odict_reduce__doc__},
1311     ORDEREDDICT_SETDEFAULT_METHODDEF
1312     ORDEREDDICT_POP_METHODDEF
1313     ORDEREDDICT_POPITEM_METHODDEF
1314     {"keys",            odictkeys_new,                  METH_NOARGS,
1315      odict_keys__doc__},
1316     {"values",          odictvalues_new,                METH_NOARGS,
1317      odict_values__doc__},
1318     {"items",           odictitems_new,                 METH_NOARGS,
1319      odict_items__doc__},
1320     {"update",          _PyCFunction_CAST(odict_update), METH_VARARGS | METH_KEYWORDS,
1321      odict_update__doc__},
1322     {"clear",           (PyCFunction)odict_clear,       METH_NOARGS,
1323      odict_clear__doc__},
1324     {"copy",            (PyCFunction)odict_copy,        METH_NOARGS,
1325      odict_copy__doc__},
1326 
1327     /* new methods */
1328     {"__reversed__",    (PyCFunction)odict_reversed,    METH_NOARGS,
1329      odict_reversed__doc__},
1330     ORDEREDDICT_MOVE_TO_END_METHODDEF
1331 
1332     {NULL,              NULL}   /* sentinel */
1333 };
1334 
1335 
1336 /* ----------------------------------------------
1337  * OrderedDict members
1338  */
1339 
1340 /* tp_getset */
1341 
1342 static PyGetSetDef odict_getset[] = {
1343     {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
1344     {NULL}
1345 };
1346 
1347 /* ----------------------------------------------
1348  * OrderedDict type slot methods
1349  */
1350 
1351 /* tp_dealloc */
1352 
1353 static void
odict_dealloc(PyODictObject * self)1354 odict_dealloc(PyODictObject *self)
1355 {
1356     PyObject_GC_UnTrack(self);
1357     Py_TRASHCAN_BEGIN(self, odict_dealloc)
1358 
1359     Py_XDECREF(self->od_inst_dict);
1360     if (self->od_weakreflist != NULL)
1361         PyObject_ClearWeakRefs((PyObject *)self);
1362 
1363     _odict_clear_nodes(self);
1364     PyDict_Type.tp_dealloc((PyObject *)self);
1365 
1366     Py_TRASHCAN_END
1367 }
1368 
1369 /* tp_repr */
1370 
1371 static PyObject *
odict_repr(PyODictObject * self)1372 odict_repr(PyODictObject *self)
1373 {
1374     int i;
1375     PyObject *pieces = NULL, *result = NULL;
1376 
1377     if (PyODict_SIZE(self) == 0)
1378         return PyUnicode_FromFormat("%s()", _PyType_Name(Py_TYPE(self)));
1379 
1380     i = Py_ReprEnter((PyObject *)self);
1381     if (i != 0) {
1382         return i > 0 ? PyUnicode_FromString("...") : NULL;
1383     }
1384 
1385     if (PyODict_CheckExact(self)) {
1386         Py_ssize_t count = 0;
1387         _ODictNode *node;
1388         pieces = PyList_New(PyODict_SIZE(self));
1389         if (pieces == NULL)
1390             goto Done;
1391 
1392         _odict_FOREACH(self, node) {
1393             PyObject *pair;
1394             PyObject *key = _odictnode_KEY(node);
1395             PyObject *value = _odictnode_VALUE(node, self);
1396             if (value == NULL) {
1397                 if (!PyErr_Occurred())
1398                     PyErr_SetObject(PyExc_KeyError, key);
1399                 goto Done;
1400             }
1401             pair = PyTuple_Pack(2, key, value);
1402             if (pair == NULL)
1403                 goto Done;
1404 
1405             if (count < PyList_GET_SIZE(pieces))
1406                 PyList_SET_ITEM(pieces, count, pair);  /* steals reference */
1407             else {
1408                 if (PyList_Append(pieces, pair) < 0) {
1409                     Py_DECREF(pair);
1410                     goto Done;
1411                 }
1412                 Py_DECREF(pair);
1413             }
1414             count++;
1415         }
1416         if (count < PyList_GET_SIZE(pieces)) {
1417             Py_SET_SIZE(pieces, count);
1418         }
1419     }
1420     else {
1421         PyObject *items = PyObject_CallMethodNoArgs(
1422                 (PyObject *)self, &_Py_ID(items));
1423         if (items == NULL)
1424             goto Done;
1425         pieces = PySequence_List(items);
1426         Py_DECREF(items);
1427         if (pieces == NULL)
1428             goto Done;
1429     }
1430 
1431     result = PyUnicode_FromFormat("%s(%R)",
1432                                   _PyType_Name(Py_TYPE(self)), pieces);
1433 
1434 Done:
1435     Py_XDECREF(pieces);
1436     Py_ReprLeave((PyObject *)self);
1437     return result;
1438 }
1439 
1440 /* tp_doc */
1441 
1442 PyDoc_STRVAR(odict_doc,
1443         "Dictionary that remembers insertion order");
1444 
1445 /* tp_traverse */
1446 
1447 static int
odict_traverse(PyODictObject * od,visitproc visit,void * arg)1448 odict_traverse(PyODictObject *od, visitproc visit, void *arg)
1449 {
1450     _ODictNode *node;
1451 
1452     Py_VISIT(od->od_inst_dict);
1453     _odict_FOREACH(od, node) {
1454         Py_VISIT(_odictnode_KEY(node));
1455     }
1456     return PyDict_Type.tp_traverse((PyObject *)od, visit, arg);
1457 }
1458 
1459 /* tp_clear */
1460 
1461 static int
odict_tp_clear(PyODictObject * od)1462 odict_tp_clear(PyODictObject *od)
1463 {
1464     Py_CLEAR(od->od_inst_dict);
1465     PyDict_Clear((PyObject *)od);
1466     _odict_clear_nodes(od);
1467     return 0;
1468 }
1469 
1470 /* tp_richcompare */
1471 
1472 static PyObject *
odict_richcompare(PyObject * v,PyObject * w,int op)1473 odict_richcompare(PyObject *v, PyObject *w, int op)
1474 {
1475     if (!PyODict_Check(v) || !PyDict_Check(w)) {
1476         Py_RETURN_NOTIMPLEMENTED;
1477     }
1478 
1479     if (op == Py_EQ || op == Py_NE) {
1480         PyObject *res, *cmp;
1481         int eq;
1482 
1483         cmp = PyDict_Type.tp_richcompare(v, w, op);
1484         if (cmp == NULL)
1485             return NULL;
1486         if (!PyODict_Check(w))
1487             return cmp;
1488         if (op == Py_EQ && cmp == Py_False)
1489             return cmp;
1490         if (op == Py_NE && cmp == Py_True)
1491             return cmp;
1492         Py_DECREF(cmp);
1493 
1494         /* Try comparing odict keys. */
1495         eq = _odict_keys_equal((PyODictObject *)v, (PyODictObject *)w);
1496         if (eq < 0)
1497             return NULL;
1498 
1499         res = (eq == (op == Py_EQ)) ? Py_True : Py_False;
1500         Py_INCREF(res);
1501         return res;
1502     } else {
1503         Py_RETURN_NOTIMPLEMENTED;
1504     }
1505 }
1506 
1507 /* tp_iter */
1508 
1509 static PyObject *
odict_iter(PyODictObject * od)1510 odict_iter(PyODictObject *od)
1511 {
1512     return odictiter_new(od, _odict_ITER_KEYS);
1513 }
1514 
1515 /* tp_init */
1516 
1517 static int
odict_init(PyObject * self,PyObject * args,PyObject * kwds)1518 odict_init(PyObject *self, PyObject *args, PyObject *kwds)
1519 {
1520     PyObject *res;
1521     Py_ssize_t len = PyObject_Length(args);
1522 
1523     if (len == -1)
1524         return -1;
1525     if (len > 1) {
1526         const char *msg = "expected at most 1 arguments, got %zd";
1527         PyErr_Format(PyExc_TypeError, msg, len);
1528         return -1;
1529     }
1530 
1531     /* __init__() triggering update() is just the way things are! */
1532     res = odict_update(self, args, kwds);
1533     if (res == NULL) {
1534         return -1;
1535     } else {
1536         Py_DECREF(res);
1537         return 0;
1538     }
1539 }
1540 
1541 /* PyODict_Type */
1542 
1543 PyTypeObject PyODict_Type = {
1544     PyVarObject_HEAD_INIT(&PyType_Type, 0)
1545     "collections.OrderedDict",                  /* tp_name */
1546     sizeof(PyODictObject),                      /* tp_basicsize */
1547     0,                                          /* tp_itemsize */
1548     (destructor)odict_dealloc,                  /* tp_dealloc */
1549     0,                                          /* tp_vectorcall_offset */
1550     0,                                          /* tp_getattr */
1551     0,                                          /* tp_setattr */
1552     0,                                          /* tp_as_async */
1553     (reprfunc)odict_repr,                       /* tp_repr */
1554     &odict_as_number,                           /* tp_as_number */
1555     0,                                          /* tp_as_sequence */
1556     &odict_as_mapping,                          /* tp_as_mapping */
1557     0,                                          /* tp_hash */
1558     0,                                          /* tp_call */
1559     0,                                          /* tp_str */
1560     0,                                          /* tp_getattro */
1561     0,                                          /* tp_setattro */
1562     0,                                          /* tp_as_buffer */
1563     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,/* tp_flags */
1564     odict_doc,                                  /* tp_doc */
1565     (traverseproc)odict_traverse,               /* tp_traverse */
1566     (inquiry)odict_tp_clear,                    /* tp_clear */
1567     (richcmpfunc)odict_richcompare,             /* tp_richcompare */
1568     offsetof(PyODictObject, od_weakreflist),    /* tp_weaklistoffset */
1569     (getiterfunc)odict_iter,                    /* tp_iter */
1570     0,                                          /* tp_iternext */
1571     odict_methods,                              /* tp_methods */
1572     0,                                          /* tp_members */
1573     odict_getset,                               /* tp_getset */
1574     &PyDict_Type,                               /* tp_base */
1575     0,                                          /* tp_dict */
1576     0,                                          /* tp_descr_get */
1577     0,                                          /* tp_descr_set */
1578     offsetof(PyODictObject, od_inst_dict),      /* tp_dictoffset */
1579     (initproc)odict_init,                       /* tp_init */
1580     PyType_GenericAlloc,                        /* tp_alloc */
1581     0,                                          /* tp_new */
1582     0,                                          /* tp_free */
1583 };
1584 
1585 
1586 /* ----------------------------------------------
1587  * the public OrderedDict API
1588  */
1589 
1590 PyObject *
PyODict_New(void)1591 PyODict_New(void)
1592 {
1593     return PyDict_Type.tp_new(&PyODict_Type, NULL, NULL);
1594 }
1595 
1596 static int
_PyODict_SetItem_KnownHash(PyObject * od,PyObject * key,PyObject * value,Py_hash_t hash)1597 _PyODict_SetItem_KnownHash(PyObject *od, PyObject *key, PyObject *value,
1598                            Py_hash_t hash)
1599 {
1600     int res = _PyDict_SetItem_KnownHash(od, key, value, hash);
1601     if (res == 0) {
1602         res = _odict_add_new_node((PyODictObject *)od, key, hash);
1603         if (res < 0) {
1604             /* Revert setting the value on the dict */
1605             PyObject *exc, *val, *tb;
1606             PyErr_Fetch(&exc, &val, &tb);
1607             (void) _PyDict_DelItem_KnownHash(od, key, hash);
1608             _PyErr_ChainExceptions(exc, val, tb);
1609         }
1610     }
1611     return res;
1612 }
1613 
1614 int
PyODict_SetItem(PyObject * od,PyObject * key,PyObject * value)1615 PyODict_SetItem(PyObject *od, PyObject *key, PyObject *value)
1616 {
1617     Py_hash_t hash = PyObject_Hash(key);
1618     if (hash == -1)
1619         return -1;
1620     return _PyODict_SetItem_KnownHash(od, key, value, hash);
1621 }
1622 
1623 int
PyODict_DelItem(PyObject * od,PyObject * key)1624 PyODict_DelItem(PyObject *od, PyObject *key)
1625 {
1626     int res;
1627     Py_hash_t hash = PyObject_Hash(key);
1628     if (hash == -1)
1629         return -1;
1630     res = _odict_clear_node((PyODictObject *)od, NULL, key, hash);
1631     if (res < 0)
1632         return -1;
1633     return _PyDict_DelItem_KnownHash(od, key, hash);
1634 }
1635 
1636 
1637 /* -------------------------------------------
1638  * The OrderedDict views (keys/values/items)
1639  */
1640 
1641 typedef struct {
1642     PyObject_HEAD
1643     int kind;
1644     PyODictObject *di_odict;
1645     Py_ssize_t di_size;
1646     size_t di_state;
1647     PyObject *di_current;
1648     PyObject *di_result; /* reusable result tuple for iteritems */
1649 } odictiterobject;
1650 
1651 static void
odictiter_dealloc(odictiterobject * di)1652 odictiter_dealloc(odictiterobject *di)
1653 {
1654     _PyObject_GC_UNTRACK(di);
1655     Py_XDECREF(di->di_odict);
1656     Py_XDECREF(di->di_current);
1657     if ((di->kind & _odict_ITER_ITEMS) == _odict_ITER_ITEMS) {
1658         Py_DECREF(di->di_result);
1659     }
1660     PyObject_GC_Del(di);
1661 }
1662 
1663 static int
odictiter_traverse(odictiterobject * di,visitproc visit,void * arg)1664 odictiter_traverse(odictiterobject *di, visitproc visit, void *arg)
1665 {
1666     Py_VISIT(di->di_odict);
1667     Py_VISIT(di->di_current);  /* A key could be any type, not just str. */
1668     Py_VISIT(di->di_result);
1669     return 0;
1670 }
1671 
1672 /* In order to protect against modifications during iteration, we track
1673  * the current key instead of the current node. */
1674 static PyObject *
odictiter_nextkey(odictiterobject * di)1675 odictiter_nextkey(odictiterobject *di)
1676 {
1677     PyObject *key = NULL;
1678     _ODictNode *node;
1679     int reversed = di->kind & _odict_ITER_REVERSED;
1680 
1681     if (di->di_odict == NULL)
1682         return NULL;
1683     if (di->di_current == NULL)
1684         goto done;  /* We're already done. */
1685 
1686     /* Check for unsupported changes. */
1687     if (di->di_odict->od_state != di->di_state) {
1688         PyErr_SetString(PyExc_RuntimeError,
1689                         "OrderedDict mutated during iteration");
1690         goto done;
1691     }
1692     if (di->di_size != PyODict_SIZE(di->di_odict)) {
1693         PyErr_SetString(PyExc_RuntimeError,
1694                         "OrderedDict changed size during iteration");
1695         di->di_size = -1; /* Make this state sticky */
1696         return NULL;
1697     }
1698 
1699     /* Get the key. */
1700     node = _odict_find_node(di->di_odict, di->di_current);
1701     if (node == NULL) {
1702         if (!PyErr_Occurred())
1703             PyErr_SetObject(PyExc_KeyError, di->di_current);
1704         /* Must have been deleted. */
1705         Py_CLEAR(di->di_current);
1706         return NULL;
1707     }
1708     key = di->di_current;
1709 
1710     /* Advance to the next key. */
1711     node = reversed ? _odictnode_PREV(node) : _odictnode_NEXT(node);
1712     if (node == NULL) {
1713         /* Reached the end. */
1714         di->di_current = NULL;
1715     }
1716     else {
1717         di->di_current = _odictnode_KEY(node);
1718         Py_INCREF(di->di_current);
1719     }
1720 
1721     return key;
1722 
1723 done:
1724     Py_CLEAR(di->di_odict);
1725     return key;
1726 }
1727 
1728 static PyObject *
odictiter_iternext(odictiterobject * di)1729 odictiter_iternext(odictiterobject *di)
1730 {
1731     PyObject *result, *value;
1732     PyObject *key = odictiter_nextkey(di);  /* new reference */
1733 
1734     if (key == NULL)
1735         return NULL;
1736 
1737     /* Handle the keys case. */
1738     if (! (di->kind & _odict_ITER_VALUES)) {
1739         return key;
1740     }
1741 
1742     value = PyODict_GetItem((PyObject *)di->di_odict, key);  /* borrowed */
1743     if (value == NULL) {
1744         if (!PyErr_Occurred())
1745             PyErr_SetObject(PyExc_KeyError, key);
1746         Py_DECREF(key);
1747         goto done;
1748     }
1749     Py_INCREF(value);
1750 
1751     /* Handle the values case. */
1752     if (!(di->kind & _odict_ITER_KEYS)) {
1753         Py_DECREF(key);
1754         return value;
1755     }
1756 
1757     /* Handle the items case. */
1758     result = di->di_result;
1759 
1760     if (Py_REFCNT(result) == 1) {
1761         /* not in use so we can reuse it
1762          * (the common case during iteration) */
1763         Py_INCREF(result);
1764         Py_DECREF(PyTuple_GET_ITEM(result, 0));  /* borrowed */
1765         Py_DECREF(PyTuple_GET_ITEM(result, 1));  /* borrowed */
1766         // bpo-42536: The GC may have untracked this result tuple. Since we're
1767         // recycling it, make sure it's tracked again:
1768         if (!_PyObject_GC_IS_TRACKED(result)) {
1769             _PyObject_GC_TRACK(result);
1770         }
1771     }
1772     else {
1773         result = PyTuple_New(2);
1774         if (result == NULL) {
1775             Py_DECREF(key);
1776             Py_DECREF(value);
1777             goto done;
1778         }
1779     }
1780 
1781     PyTuple_SET_ITEM(result, 0, key);  /* steals reference */
1782     PyTuple_SET_ITEM(result, 1, value);  /* steals reference */
1783     return result;
1784 
1785 done:
1786     Py_CLEAR(di->di_current);
1787     Py_CLEAR(di->di_odict);
1788     return NULL;
1789 }
1790 
1791 /* No need for tp_clear because odictiterobject is not mutable. */
1792 
1793 PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
1794 
1795 static PyObject *
odictiter_reduce(odictiterobject * di,PyObject * Py_UNUSED (ignored))1796 odictiter_reduce(odictiterobject *di, PyObject *Py_UNUSED(ignored))
1797 {
1798     /* copy the iterator state */
1799     odictiterobject tmp = *di;
1800     Py_XINCREF(tmp.di_odict);
1801     Py_XINCREF(tmp.di_current);
1802 
1803     /* iterate the temporary into a list */
1804     PyObject *list = PySequence_List((PyObject*)&tmp);
1805     Py_XDECREF(tmp.di_odict);
1806     Py_XDECREF(tmp.di_current);
1807     if (list == NULL) {
1808         return NULL;
1809     }
1810     return Py_BuildValue("N(N)", _PyEval_GetBuiltin(&_Py_ID(iter)), list);
1811 }
1812 
1813 static PyMethodDef odictiter_methods[] = {
1814     {"__reduce__", (PyCFunction)odictiter_reduce, METH_NOARGS, reduce_doc},
1815     {NULL,              NULL}           /* sentinel */
1816 };
1817 
1818 PyTypeObject PyODictIter_Type = {
1819     PyVarObject_HEAD_INIT(&PyType_Type, 0)
1820     "odict_iterator",                         /* tp_name */
1821     sizeof(odictiterobject),                  /* tp_basicsize */
1822     0,                                        /* tp_itemsize */
1823     /* methods */
1824     (destructor)odictiter_dealloc,            /* tp_dealloc */
1825     0,                                        /* tp_vectorcall_offset */
1826     0,                                        /* tp_getattr */
1827     0,                                        /* tp_setattr */
1828     0,                                        /* tp_as_async */
1829     0,                                        /* tp_repr */
1830     0,                                        /* tp_as_number */
1831     0,                                        /* tp_as_sequence */
1832     0,                                        /* tp_as_mapping */
1833     0,                                        /* tp_hash */
1834     0,                                        /* tp_call */
1835     0,                                        /* tp_str */
1836     PyObject_GenericGetAttr,                  /* tp_getattro */
1837     0,                                        /* tp_setattro */
1838     0,                                        /* tp_as_buffer */
1839     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,  /* tp_flags */
1840     0,                                        /* tp_doc */
1841     (traverseproc)odictiter_traverse,         /* tp_traverse */
1842     0,                                        /* tp_clear */
1843     0,                                        /* tp_richcompare */
1844     0,                                        /* tp_weaklistoffset */
1845     PyObject_SelfIter,                        /* tp_iter */
1846     (iternextfunc)odictiter_iternext,         /* tp_iternext */
1847     odictiter_methods,                        /* tp_methods */
1848     0,
1849 };
1850 
1851 static PyObject *
odictiter_new(PyODictObject * od,int kind)1852 odictiter_new(PyODictObject *od, int kind)
1853 {
1854     odictiterobject *di;
1855     _ODictNode *node;
1856     int reversed = kind & _odict_ITER_REVERSED;
1857 
1858     di = PyObject_GC_New(odictiterobject, &PyODictIter_Type);
1859     if (di == NULL)
1860         return NULL;
1861 
1862     if ((kind & _odict_ITER_ITEMS) == _odict_ITER_ITEMS) {
1863         di->di_result = PyTuple_Pack(2, Py_None, Py_None);
1864         if (di->di_result == NULL) {
1865             Py_DECREF(di);
1866             return NULL;
1867         }
1868     }
1869     else {
1870         di->di_result = NULL;
1871     }
1872 
1873     di->kind = kind;
1874     node = reversed ? _odict_LAST(od) : _odict_FIRST(od);
1875     di->di_current = node ? _odictnode_KEY(node) : NULL;
1876     Py_XINCREF(di->di_current);
1877     di->di_size = PyODict_SIZE(od);
1878     di->di_state = od->od_state;
1879     di->di_odict = od;
1880     Py_INCREF(od);
1881 
1882     _PyObject_GC_TRACK(di);
1883     return (PyObject *)di;
1884 }
1885 
1886 /* keys() */
1887 
1888 static PyObject *
odictkeys_iter(_PyDictViewObject * dv)1889 odictkeys_iter(_PyDictViewObject *dv)
1890 {
1891     if (dv->dv_dict == NULL) {
1892         Py_RETURN_NONE;
1893     }
1894     return odictiter_new((PyODictObject *)dv->dv_dict,
1895             _odict_ITER_KEYS);
1896 }
1897 
1898 static PyObject *
odictkeys_reversed(_PyDictViewObject * dv,PyObject * Py_UNUSED (ignored))1899 odictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored))
1900 {
1901     if (dv->dv_dict == NULL) {
1902         Py_RETURN_NONE;
1903     }
1904     return odictiter_new((PyODictObject *)dv->dv_dict,
1905             _odict_ITER_KEYS|_odict_ITER_REVERSED);
1906 }
1907 
1908 static PyMethodDef odictkeys_methods[] = {
1909     {"__reversed__", (PyCFunction)odictkeys_reversed, METH_NOARGS, NULL},
1910     {NULL,          NULL}           /* sentinel */
1911 };
1912 
1913 PyTypeObject PyODictKeys_Type = {
1914     PyVarObject_HEAD_INIT(&PyType_Type, 0)
1915     "odict_keys",                             /* tp_name */
1916     0,                                        /* tp_basicsize */
1917     0,                                        /* tp_itemsize */
1918     0,                                        /* tp_dealloc */
1919     0,                                        /* tp_vectorcall_offset */
1920     0,                                        /* tp_getattr */
1921     0,                                        /* tp_setattr */
1922     0,                                        /* tp_as_async */
1923     0,                                        /* tp_repr */
1924     0,                                        /* tp_as_number */
1925     0,                                        /* tp_as_sequence */
1926     0,                                        /* tp_as_mapping */
1927     0,                                        /* tp_hash */
1928     0,                                        /* tp_call */
1929     0,                                        /* tp_str */
1930     0,                                        /* tp_getattro */
1931     0,                                        /* tp_setattro */
1932     0,                                        /* tp_as_buffer */
1933     0,                                        /* tp_flags */
1934     0,                                        /* tp_doc */
1935     0,                                        /* tp_traverse */
1936     0,                                        /* tp_clear */
1937     0,                                        /* tp_richcompare */
1938     0,                                        /* tp_weaklistoffset */
1939     (getiterfunc)odictkeys_iter,              /* tp_iter */
1940     0,                                        /* tp_iternext */
1941     odictkeys_methods,                        /* tp_methods */
1942     0,                                        /* tp_members */
1943     0,                                        /* tp_getset */
1944     &PyDictKeys_Type,                         /* tp_base */
1945 };
1946 
1947 static PyObject *
odictkeys_new(PyObject * od,PyObject * Py_UNUSED (ignored))1948 odictkeys_new(PyObject *od, PyObject *Py_UNUSED(ignored))
1949 {
1950     return _PyDictView_New(od, &PyODictKeys_Type);
1951 }
1952 
1953 /* items() */
1954 
1955 static PyObject *
odictitems_iter(_PyDictViewObject * dv)1956 odictitems_iter(_PyDictViewObject *dv)
1957 {
1958     if (dv->dv_dict == NULL) {
1959         Py_RETURN_NONE;
1960     }
1961     return odictiter_new((PyODictObject *)dv->dv_dict,
1962             _odict_ITER_KEYS|_odict_ITER_VALUES);
1963 }
1964 
1965 static PyObject *
odictitems_reversed(_PyDictViewObject * dv,PyObject * Py_UNUSED (ignored))1966 odictitems_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored))
1967 {
1968     if (dv->dv_dict == NULL) {
1969         Py_RETURN_NONE;
1970     }
1971     return odictiter_new((PyODictObject *)dv->dv_dict,
1972             _odict_ITER_KEYS|_odict_ITER_VALUES|_odict_ITER_REVERSED);
1973 }
1974 
1975 static PyMethodDef odictitems_methods[] = {
1976     {"__reversed__", (PyCFunction)odictitems_reversed, METH_NOARGS, NULL},
1977     {NULL,          NULL}           /* sentinel */
1978 };
1979 
1980 PyTypeObject PyODictItems_Type = {
1981     PyVarObject_HEAD_INIT(&PyType_Type, 0)
1982     "odict_items",                            /* tp_name */
1983     0,                                        /* tp_basicsize */
1984     0,                                        /* tp_itemsize */
1985     0,                                        /* tp_dealloc */
1986     0,                                        /* tp_vectorcall_offset */
1987     0,                                        /* tp_getattr */
1988     0,                                        /* tp_setattr */
1989     0,                                        /* tp_as_async */
1990     0,                                        /* tp_repr */
1991     0,                                        /* tp_as_number */
1992     0,                                        /* tp_as_sequence */
1993     0,                                        /* tp_as_mapping */
1994     0,                                        /* tp_hash */
1995     0,                                        /* tp_call */
1996     0,                                        /* tp_str */
1997     0,                                        /* tp_getattro */
1998     0,                                        /* tp_setattro */
1999     0,                                        /* tp_as_buffer */
2000     0,                                        /* tp_flags */
2001     0,                                        /* tp_doc */
2002     0,                                        /* tp_traverse */
2003     0,                                        /* tp_clear */
2004     0,                                        /* tp_richcompare */
2005     0,                                        /* tp_weaklistoffset */
2006     (getiterfunc)odictitems_iter,             /* tp_iter */
2007     0,                                        /* tp_iternext */
2008     odictitems_methods,                       /* tp_methods */
2009     0,                                        /* tp_members */
2010     0,                                        /* tp_getset */
2011     &PyDictItems_Type,                        /* tp_base */
2012 };
2013 
2014 static PyObject *
odictitems_new(PyObject * od,PyObject * Py_UNUSED (ignored))2015 odictitems_new(PyObject *od, PyObject *Py_UNUSED(ignored))
2016 {
2017     return _PyDictView_New(od, &PyODictItems_Type);
2018 }
2019 
2020 /* values() */
2021 
2022 static PyObject *
odictvalues_iter(_PyDictViewObject * dv)2023 odictvalues_iter(_PyDictViewObject *dv)
2024 {
2025     if (dv->dv_dict == NULL) {
2026         Py_RETURN_NONE;
2027     }
2028     return odictiter_new((PyODictObject *)dv->dv_dict,
2029             _odict_ITER_VALUES);
2030 }
2031 
2032 static PyObject *
odictvalues_reversed(_PyDictViewObject * dv,PyObject * Py_UNUSED (ignored))2033 odictvalues_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored))
2034 {
2035     if (dv->dv_dict == NULL) {
2036         Py_RETURN_NONE;
2037     }
2038     return odictiter_new((PyODictObject *)dv->dv_dict,
2039             _odict_ITER_VALUES|_odict_ITER_REVERSED);
2040 }
2041 
2042 static PyMethodDef odictvalues_methods[] = {
2043     {"__reversed__", (PyCFunction)odictvalues_reversed, METH_NOARGS, NULL},
2044     {NULL,          NULL}           /* sentinel */
2045 };
2046 
2047 PyTypeObject PyODictValues_Type = {
2048     PyVarObject_HEAD_INIT(&PyType_Type, 0)
2049     "odict_values",                           /* tp_name */
2050     0,                                        /* tp_basicsize */
2051     0,                                        /* tp_itemsize */
2052     0,                                        /* tp_dealloc */
2053     0,                                        /* tp_vectorcall_offset */
2054     0,                                        /* tp_getattr */
2055     0,                                        /* tp_setattr */
2056     0,                                        /* tp_as_async */
2057     0,                                        /* tp_repr */
2058     0,                                        /* tp_as_number */
2059     0,                                        /* tp_as_sequence */
2060     0,                                        /* tp_as_mapping */
2061     0,                                        /* tp_hash */
2062     0,                                        /* tp_call */
2063     0,                                        /* tp_str */
2064     0,                                        /* tp_getattro */
2065     0,                                        /* tp_setattro */
2066     0,                                        /* tp_as_buffer */
2067     0,                                        /* tp_flags */
2068     0,                                        /* tp_doc */
2069     0,                                        /* tp_traverse */
2070     0,                                        /* tp_clear */
2071     0,                                        /* tp_richcompare */
2072     0,                                        /* tp_weaklistoffset */
2073     (getiterfunc)odictvalues_iter,            /* tp_iter */
2074     0,                                        /* tp_iternext */
2075     odictvalues_methods,                      /* tp_methods */
2076     0,                                        /* tp_members */
2077     0,                                        /* tp_getset */
2078     &PyDictValues_Type,                       /* tp_base */
2079 };
2080 
2081 static PyObject *
odictvalues_new(PyObject * od,PyObject * Py_UNUSED (ignored))2082 odictvalues_new(PyObject *od, PyObject *Py_UNUSED(ignored))
2083 {
2084     return _PyDictView_New(od, &PyODictValues_Type);
2085 }
2086 
2087 
2088 /* ----------------------------------------------
2089    MutableMapping implementations
2090 
2091 Mapping:
2092 
2093 ============ ===========
2094 method       uses
2095 ============ ===========
2096 __contains__ __getitem__
2097 __eq__       items
2098 __getitem__  +
2099 __iter__     +
2100 __len__      +
2101 __ne__       __eq__
2102 get          __getitem__
2103 items        ItemsView
2104 keys         KeysView
2105 values       ValuesView
2106 ============ ===========
2107 
2108 ItemsView uses __len__, __iter__, and __getitem__.
2109 KeysView uses __len__, __iter__, and __contains__.
2110 ValuesView uses __len__, __iter__, and __getitem__.
2111 
2112 MutableMapping:
2113 
2114 ============ ===========
2115 method       uses
2116 ============ ===========
2117 __delitem__  +
2118 __setitem__  +
2119 clear        popitem
2120 pop          __getitem__
2121              __delitem__
2122 popitem      __iter__
2123              _getitem__
2124              __delitem__
2125 setdefault   __getitem__
2126              __setitem__
2127 update       __setitem__
2128 ============ ===========
2129 */
2130 
2131 static int
mutablemapping_add_pairs(PyObject * self,PyObject * pairs)2132 mutablemapping_add_pairs(PyObject *self, PyObject *pairs)
2133 {
2134     PyObject *pair, *iterator, *unexpected;
2135     int res = 0;
2136 
2137     iterator = PyObject_GetIter(pairs);
2138     if (iterator == NULL)
2139         return -1;
2140     PyErr_Clear();
2141 
2142     while ((pair = PyIter_Next(iterator)) != NULL) {
2143         /* could be more efficient (see UNPACK_SEQUENCE in ceval.c) */
2144         PyObject *key = NULL, *value = NULL;
2145         PyObject *pair_iterator = PyObject_GetIter(pair);
2146         if (pair_iterator == NULL)
2147             goto Done;
2148 
2149         key = PyIter_Next(pair_iterator);
2150         if (key == NULL) {
2151             if (!PyErr_Occurred())
2152                 PyErr_SetString(PyExc_ValueError,
2153                                 "need more than 0 values to unpack");
2154             goto Done;
2155         }
2156 
2157         value = PyIter_Next(pair_iterator);
2158         if (value == NULL) {
2159             if (!PyErr_Occurred())
2160                 PyErr_SetString(PyExc_ValueError,
2161                                 "need more than 1 value to unpack");
2162             goto Done;
2163         }
2164 
2165         unexpected = PyIter_Next(pair_iterator);
2166         if (unexpected != NULL) {
2167             Py_DECREF(unexpected);
2168             PyErr_SetString(PyExc_ValueError,
2169                             "too many values to unpack (expected 2)");
2170             goto Done;
2171         }
2172         else if (PyErr_Occurred())
2173             goto Done;
2174 
2175         res = PyObject_SetItem(self, key, value);
2176 
2177 Done:
2178         Py_DECREF(pair);
2179         Py_XDECREF(pair_iterator);
2180         Py_XDECREF(key);
2181         Py_XDECREF(value);
2182         if (PyErr_Occurred())
2183             break;
2184     }
2185     Py_DECREF(iterator);
2186 
2187     if (res < 0 || PyErr_Occurred() != NULL)
2188         return -1;
2189     else
2190         return 0;
2191 }
2192 
2193 static int
mutablemapping_update_arg(PyObject * self,PyObject * arg)2194 mutablemapping_update_arg(PyObject *self, PyObject *arg)
2195 {
2196     int res = 0;
2197     if (PyDict_CheckExact(arg)) {
2198         PyObject *items = PyDict_Items(arg);
2199         if (items == NULL) {
2200             return -1;
2201         }
2202         res = mutablemapping_add_pairs(self, items);
2203         Py_DECREF(items);
2204         return res;
2205     }
2206     PyObject *func;
2207     if (_PyObject_LookupAttr(arg, &_Py_ID(keys), &func) < 0) {
2208         return -1;
2209     }
2210     if (func != NULL) {
2211         PyObject *keys = _PyObject_CallNoArgs(func);
2212         Py_DECREF(func);
2213         if (keys == NULL) {
2214             return -1;
2215         }
2216         PyObject *iterator = PyObject_GetIter(keys);
2217         Py_DECREF(keys);
2218         if (iterator == NULL) {
2219             return -1;
2220         }
2221         PyObject *key;
2222         while (res == 0 && (key = PyIter_Next(iterator))) {
2223             PyObject *value = PyObject_GetItem(arg, key);
2224             if (value != NULL) {
2225                 res = PyObject_SetItem(self, key, value);
2226                 Py_DECREF(value);
2227             }
2228             else {
2229                 res = -1;
2230             }
2231             Py_DECREF(key);
2232         }
2233         Py_DECREF(iterator);
2234         if (res != 0 || PyErr_Occurred()) {
2235             return -1;
2236         }
2237         return 0;
2238     }
2239     if (_PyObject_LookupAttr(arg, &_Py_ID(items), &func) < 0) {
2240         return -1;
2241     }
2242     if (func != NULL) {
2243         PyObject *items = _PyObject_CallNoArgs(func);
2244         Py_DECREF(func);
2245         if (items == NULL) {
2246             return -1;
2247         }
2248         res = mutablemapping_add_pairs(self, items);
2249         Py_DECREF(items);
2250         return res;
2251     }
2252     res = mutablemapping_add_pairs(self, arg);
2253     return res;
2254 }
2255 
2256 static PyObject *
mutablemapping_update(PyObject * self,PyObject * args,PyObject * kwargs)2257 mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
2258 {
2259     int res;
2260     /* first handle args, if any */
2261     assert(args == NULL || PyTuple_Check(args));
2262     Py_ssize_t len = (args != NULL) ? PyTuple_GET_SIZE(args) : 0;
2263     if (len > 1) {
2264         const char *msg = "update() takes at most 1 positional argument (%zd given)";
2265         PyErr_Format(PyExc_TypeError, msg, len);
2266         return NULL;
2267     }
2268 
2269     if (len) {
2270         PyObject *other = PyTuple_GET_ITEM(args, 0);  /* borrowed reference */
2271         assert(other != NULL);
2272         Py_INCREF(other);
2273         res = mutablemapping_update_arg(self, other);
2274         Py_DECREF(other);
2275         if (res < 0) {
2276             return NULL;
2277         }
2278     }
2279 
2280     /* now handle kwargs */
2281     assert(kwargs == NULL || PyDict_Check(kwargs));
2282     if (kwargs != NULL && PyDict_GET_SIZE(kwargs)) {
2283         PyObject *items = PyDict_Items(kwargs);
2284         if (items == NULL)
2285             return NULL;
2286         res = mutablemapping_add_pairs(self, items);
2287         Py_DECREF(items);
2288         if (res == -1)
2289             return NULL;
2290     }
2291 
2292     Py_RETURN_NONE;
2293 }
2294