• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "Python.h"
2 #include "structmember.h"         // PyMemberDef
3 
4 #ifdef STDC_HEADERS
5 #include <stddef.h>
6 #else
7 #include <sys/types.h>            // size_t
8 #endif
9 
10 /*[clinic input]
11 module _collections
12 class _tuplegetter "_tuplegetterobject *" "&tuplegetter_type"
13 [clinic start generated code]*/
14 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=a8ece4ccad7e30ac]*/
15 
16 static PyTypeObject tuplegetter_type;
17 #include "clinic/_collectionsmodule.c.h"
18 
19 /* collections module implementation of a deque() datatype
20    Written and maintained by Raymond D. Hettinger <python@rcn.com>
21 */
22 
23 /* The block length may be set to any number over 1.  Larger numbers
24  * reduce the number of calls to the memory allocator, give faster
25  * indexing and rotation, and reduce the link to data overhead ratio.
26  * Making the block length a power of two speeds-up the modulo
27  * and division calculations in deque_item() and deque_ass_item().
28  */
29 
30 #define BLOCKLEN 64
31 #define CENTER ((BLOCKLEN - 1) / 2)
32 
33 /* Data for deque objects is stored in a doubly-linked list of fixed
34  * length blocks.  This assures that appends or pops never move any
35  * other data elements besides the one being appended or popped.
36  *
37  * Another advantage is that it completely avoids use of realloc(),
38  * resulting in more predictable performance.
39  *
40  * Textbook implementations of doubly-linked lists store one datum
41  * per link, but that gives them a 200% memory overhead (a prev and
42  * next link for each datum) and it costs one malloc() call per data
43  * element.  By using fixed-length blocks, the link to data ratio is
44  * significantly improved and there are proportionally fewer calls
45  * to malloc() and free().  The data blocks of consecutive pointers
46  * also improve cache locality.
47  *
48  * The list of blocks is never empty, so d.leftblock and d.rightblock
49  * are never equal to NULL.  The list is not circular.
50  *
51  * A deque d's first element is at d.leftblock[leftindex]
52  * and its last element is at d.rightblock[rightindex].
53  *
54  * Unlike Python slice indices, these indices are inclusive on both
55  * ends.  This makes the algorithms for left and right operations
56  * more symmetrical and it simplifies the design.
57  *
58  * The indices, d.leftindex and d.rightindex are always in the range:
59  *     0 <= index < BLOCKLEN
60  *
61  * And their exact relationship is:
62  *     (d.leftindex + d.len - 1) % BLOCKLEN == d.rightindex
63  *
64  * Whenever d.leftblock == d.rightblock, then:
65  *     d.leftindex + d.len - 1 == d.rightindex
66  *
67  * However, when d.leftblock != d.rightblock, the d.leftindex and
68  * d.rightindex become indices into distinct blocks and either may
69  * be larger than the other.
70  *
71  * Empty deques have:
72  *     d.len == 0
73  *     d.leftblock == d.rightblock
74  *     d.leftindex == CENTER + 1
75  *     d.rightindex == CENTER
76  *
77  * Checking for d.len == 0 is the intended way to see whether d is empty.
78  */
79 
80 typedef struct BLOCK {
81     struct BLOCK *leftlink;
82     PyObject *data[BLOCKLEN];
83     struct BLOCK *rightlink;
84 } block;
85 
86 typedef struct {
87     PyObject_VAR_HEAD
88     block *leftblock;
89     block *rightblock;
90     Py_ssize_t leftindex;       /* 0 <= leftindex < BLOCKLEN */
91     Py_ssize_t rightindex;      /* 0 <= rightindex < BLOCKLEN */
92     size_t state;               /* incremented whenever the indices move */
93     Py_ssize_t maxlen;          /* maxlen is -1 for unbounded deques */
94     PyObject *weakreflist;
95 } dequeobject;
96 
97 static PyTypeObject deque_type;
98 
99 /* For debug builds, add error checking to track the endpoints
100  * in the chain of links.  The goal is to make sure that link
101  * assignments only take place at endpoints so that links already
102  * in use do not get overwritten.
103  *
104  * CHECK_END should happen before each assignment to a block's link field.
105  * MARK_END should happen whenever a link field becomes a new endpoint.
106  * This happens when new blocks are added or whenever an existing
107  * block is freed leaving another existing block as the new endpoint.
108  */
109 
110 #ifndef NDEBUG
111 #define MARK_END(link)  link = NULL;
112 #define CHECK_END(link) assert(link == NULL);
113 #define CHECK_NOT_END(link) assert(link != NULL);
114 #else
115 #define MARK_END(link)
116 #define CHECK_END(link)
117 #define CHECK_NOT_END(link)
118 #endif
119 
120 /* A simple freelisting scheme is used to minimize calls to the memory
121    allocator.  It accommodates common use cases where new blocks are being
122    added at about the same rate as old blocks are being freed.
123  */
124 
125 #define MAXFREEBLOCKS 16
126 static Py_ssize_t numfreeblocks = 0;
127 static block *freeblocks[MAXFREEBLOCKS];
128 
129 static block *
newblock(void)130 newblock(void) {
131     block *b;
132     if (numfreeblocks) {
133         numfreeblocks--;
134         return freeblocks[numfreeblocks];
135     }
136     b = PyMem_Malloc(sizeof(block));
137     if (b != NULL) {
138         return b;
139     }
140     PyErr_NoMemory();
141     return NULL;
142 }
143 
144 static void
freeblock(block * b)145 freeblock(block *b)
146 {
147     if (numfreeblocks < MAXFREEBLOCKS) {
148         freeblocks[numfreeblocks] = b;
149         numfreeblocks++;
150     } else {
151         PyMem_Free(b);
152     }
153 }
154 
155 static PyObject *
deque_new(PyTypeObject * type,PyObject * args,PyObject * kwds)156 deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
157 {
158     dequeobject *deque;
159     block *b;
160 
161     /* create dequeobject structure */
162     deque = (dequeobject *)type->tp_alloc(type, 0);
163     if (deque == NULL)
164         return NULL;
165 
166     b = newblock();
167     if (b == NULL) {
168         Py_DECREF(deque);
169         return NULL;
170     }
171     MARK_END(b->leftlink);
172     MARK_END(b->rightlink);
173 
174     assert(BLOCKLEN >= 2);
175     Py_SET_SIZE(deque, 0);
176     deque->leftblock = b;
177     deque->rightblock = b;
178     deque->leftindex = CENTER + 1;
179     deque->rightindex = CENTER;
180     deque->state = 0;
181     deque->maxlen = -1;
182     deque->weakreflist = NULL;
183 
184     return (PyObject *)deque;
185 }
186 
187 static PyObject *
deque_pop(dequeobject * deque,PyObject * unused)188 deque_pop(dequeobject *deque, PyObject *unused)
189 {
190     PyObject *item;
191     block *prevblock;
192 
193     if (Py_SIZE(deque) == 0) {
194         PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
195         return NULL;
196     }
197     item = deque->rightblock->data[deque->rightindex];
198     deque->rightindex--;
199     Py_SET_SIZE(deque, Py_SIZE(deque) - 1);
200     deque->state++;
201 
202     if (deque->rightindex < 0) {
203         if (Py_SIZE(deque)) {
204             prevblock = deque->rightblock->leftlink;
205             assert(deque->leftblock != deque->rightblock);
206             freeblock(deque->rightblock);
207             CHECK_NOT_END(prevblock);
208             MARK_END(prevblock->rightlink);
209             deque->rightblock = prevblock;
210             deque->rightindex = BLOCKLEN - 1;
211         } else {
212             assert(deque->leftblock == deque->rightblock);
213             assert(deque->leftindex == deque->rightindex+1);
214             /* re-center instead of freeing a block */
215             deque->leftindex = CENTER + 1;
216             deque->rightindex = CENTER;
217         }
218     }
219     return item;
220 }
221 
222 PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
223 
224 static PyObject *
deque_popleft(dequeobject * deque,PyObject * unused)225 deque_popleft(dequeobject *deque, PyObject *unused)
226 {
227     PyObject *item;
228     block *prevblock;
229 
230     if (Py_SIZE(deque) == 0) {
231         PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
232         return NULL;
233     }
234     assert(deque->leftblock != NULL);
235     item = deque->leftblock->data[deque->leftindex];
236     deque->leftindex++;
237     Py_SET_SIZE(deque, Py_SIZE(deque) - 1);
238     deque->state++;
239 
240     if (deque->leftindex == BLOCKLEN) {
241         if (Py_SIZE(deque)) {
242             assert(deque->leftblock != deque->rightblock);
243             prevblock = deque->leftblock->rightlink;
244             freeblock(deque->leftblock);
245             CHECK_NOT_END(prevblock);
246             MARK_END(prevblock->leftlink);
247             deque->leftblock = prevblock;
248             deque->leftindex = 0;
249         } else {
250             assert(deque->leftblock == deque->rightblock);
251             assert(deque->leftindex == deque->rightindex+1);
252             /* re-center instead of freeing a block */
253             deque->leftindex = CENTER + 1;
254             deque->rightindex = CENTER;
255         }
256     }
257     return item;
258 }
259 
260 PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
261 
262 /* The deque's size limit is d.maxlen.  The limit can be zero or positive.
263  * If there is no limit, then d.maxlen == -1.
264  *
265  * After an item is added to a deque, we check to see if the size has
266  * grown past the limit. If it has, we get the size back down to the limit
267  * by popping an item off of the opposite end.  The methods that can
268  * trigger this are append(), appendleft(), extend(), and extendleft().
269  *
270  * The macro to check whether a deque needs to be trimmed uses a single
271  * unsigned test that returns true whenever 0 <= maxlen < Py_SIZE(deque).
272  */
273 
274 #define NEEDS_TRIM(deque, maxlen) ((size_t)(maxlen) < (size_t)(Py_SIZE(deque)))
275 
276 static inline int
deque_append_internal(dequeobject * deque,PyObject * item,Py_ssize_t maxlen)277 deque_append_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen)
278 {
279     if (deque->rightindex == BLOCKLEN - 1) {
280         block *b = newblock();
281         if (b == NULL)
282             return -1;
283         b->leftlink = deque->rightblock;
284         CHECK_END(deque->rightblock->rightlink);
285         deque->rightblock->rightlink = b;
286         deque->rightblock = b;
287         MARK_END(b->rightlink);
288         deque->rightindex = -1;
289     }
290     Py_SET_SIZE(deque, Py_SIZE(deque) + 1);
291     deque->rightindex++;
292     deque->rightblock->data[deque->rightindex] = item;
293     if (NEEDS_TRIM(deque, maxlen)) {
294         PyObject *olditem = deque_popleft(deque, NULL);
295         Py_DECREF(olditem);
296     } else {
297         deque->state++;
298     }
299     return 0;
300 }
301 
302 static PyObject *
deque_append(dequeobject * deque,PyObject * item)303 deque_append(dequeobject *deque, PyObject *item)
304 {
305     Py_INCREF(item);
306     if (deque_append_internal(deque, item, deque->maxlen) < 0)
307         return NULL;
308     Py_RETURN_NONE;
309 }
310 
311 PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
312 
313 static inline int
deque_appendleft_internal(dequeobject * deque,PyObject * item,Py_ssize_t maxlen)314 deque_appendleft_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen)
315 {
316     if (deque->leftindex == 0) {
317         block *b = newblock();
318         if (b == NULL)
319             return -1;
320         b->rightlink = deque->leftblock;
321         CHECK_END(deque->leftblock->leftlink);
322         deque->leftblock->leftlink = b;
323         deque->leftblock = b;
324         MARK_END(b->leftlink);
325         deque->leftindex = BLOCKLEN;
326     }
327     Py_SET_SIZE(deque, Py_SIZE(deque) + 1);
328     deque->leftindex--;
329     deque->leftblock->data[deque->leftindex] = item;
330     if (NEEDS_TRIM(deque, deque->maxlen)) {
331         PyObject *olditem = deque_pop(deque, NULL);
332         Py_DECREF(olditem);
333     } else {
334         deque->state++;
335     }
336     return 0;
337 }
338 
339 static PyObject *
deque_appendleft(dequeobject * deque,PyObject * item)340 deque_appendleft(dequeobject *deque, PyObject *item)
341 {
342     Py_INCREF(item);
343     if (deque_appendleft_internal(deque, item, deque->maxlen) < 0)
344         return NULL;
345     Py_RETURN_NONE;
346 }
347 
348 PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
349 
350 static PyObject*
finalize_iterator(PyObject * it)351 finalize_iterator(PyObject *it)
352 {
353     if (PyErr_Occurred()) {
354         if (PyErr_ExceptionMatches(PyExc_StopIteration))
355             PyErr_Clear();
356         else {
357             Py_DECREF(it);
358             return NULL;
359         }
360     }
361     Py_DECREF(it);
362     Py_RETURN_NONE;
363 }
364 
365 /* Run an iterator to exhaustion.  Shortcut for
366    the extend/extendleft methods when maxlen == 0. */
367 static PyObject*
consume_iterator(PyObject * it)368 consume_iterator(PyObject *it)
369 {
370     PyObject *(*iternext)(PyObject *);
371     PyObject *item;
372 
373     iternext = *Py_TYPE(it)->tp_iternext;
374     while ((item = iternext(it)) != NULL) {
375         Py_DECREF(item);
376     }
377     return finalize_iterator(it);
378 }
379 
380 static PyObject *
deque_extend(dequeobject * deque,PyObject * iterable)381 deque_extend(dequeobject *deque, PyObject *iterable)
382 {
383     PyObject *it, *item;
384     PyObject *(*iternext)(PyObject *);
385     Py_ssize_t maxlen = deque->maxlen;
386 
387     /* Handle case where id(deque) == id(iterable) */
388     if ((PyObject *)deque == iterable) {
389         PyObject *result;
390         PyObject *s = PySequence_List(iterable);
391         if (s == NULL)
392             return NULL;
393         result = deque_extend(deque, s);
394         Py_DECREF(s);
395         return result;
396     }
397 
398     it = PyObject_GetIter(iterable);
399     if (it == NULL)
400         return NULL;
401 
402     if (maxlen == 0)
403         return consume_iterator(it);
404 
405     /* Space saving heuristic.  Start filling from the left */
406     if (Py_SIZE(deque) == 0) {
407         assert(deque->leftblock == deque->rightblock);
408         assert(deque->leftindex == deque->rightindex+1);
409         deque->leftindex = 1;
410         deque->rightindex = 0;
411     }
412 
413     iternext = *Py_TYPE(it)->tp_iternext;
414     while ((item = iternext(it)) != NULL) {
415         if (deque_append_internal(deque, item, maxlen) == -1) {
416             Py_DECREF(item);
417             Py_DECREF(it);
418             return NULL;
419         }
420     }
421     return finalize_iterator(it);
422 }
423 
424 PyDoc_STRVAR(extend_doc,
425 "Extend the right side of the deque with elements from the iterable");
426 
427 static PyObject *
deque_extendleft(dequeobject * deque,PyObject * iterable)428 deque_extendleft(dequeobject *deque, PyObject *iterable)
429 {
430     PyObject *it, *item;
431     PyObject *(*iternext)(PyObject *);
432     Py_ssize_t maxlen = deque->maxlen;
433 
434     /* Handle case where id(deque) == id(iterable) */
435     if ((PyObject *)deque == iterable) {
436         PyObject *result;
437         PyObject *s = PySequence_List(iterable);
438         if (s == NULL)
439             return NULL;
440         result = deque_extendleft(deque, s);
441         Py_DECREF(s);
442         return result;
443     }
444 
445     it = PyObject_GetIter(iterable);
446     if (it == NULL)
447         return NULL;
448 
449     if (maxlen == 0)
450         return consume_iterator(it);
451 
452     /* Space saving heuristic.  Start filling from the right */
453     if (Py_SIZE(deque) == 0) {
454         assert(deque->leftblock == deque->rightblock);
455         assert(deque->leftindex == deque->rightindex+1);
456         deque->leftindex = BLOCKLEN - 1;
457         deque->rightindex = BLOCKLEN - 2;
458     }
459 
460     iternext = *Py_TYPE(it)->tp_iternext;
461     while ((item = iternext(it)) != NULL) {
462         if (deque_appendleft_internal(deque, item, maxlen) == -1) {
463             Py_DECREF(item);
464             Py_DECREF(it);
465             return NULL;
466         }
467     }
468     return finalize_iterator(it);
469 }
470 
471 PyDoc_STRVAR(extendleft_doc,
472 "Extend the left side of the deque with elements from the iterable");
473 
474 static PyObject *
deque_inplace_concat(dequeobject * deque,PyObject * other)475 deque_inplace_concat(dequeobject *deque, PyObject *other)
476 {
477     PyObject *result;
478 
479     result = deque_extend(deque, other);
480     if (result == NULL)
481         return result;
482     Py_INCREF(deque);
483     Py_DECREF(result);
484     return (PyObject *)deque;
485 }
486 
487 static PyObject *
deque_copy(PyObject * deque,PyObject * Py_UNUSED (ignored))488 deque_copy(PyObject *deque, PyObject *Py_UNUSED(ignored))
489 {
490     PyObject *result;
491     dequeobject *old_deque = (dequeobject *)deque;
492     if (Py_IS_TYPE(deque, &deque_type)) {
493         dequeobject *new_deque;
494         PyObject *rv;
495 
496         new_deque = (dequeobject *)deque_new(&deque_type, (PyObject *)NULL, (PyObject *)NULL);
497         if (new_deque == NULL)
498             return NULL;
499         new_deque->maxlen = old_deque->maxlen;
500         /* Fast path for the deque_repeat() common case where len(deque) == 1 */
501         if (Py_SIZE(deque) == 1) {
502             PyObject *item = old_deque->leftblock->data[old_deque->leftindex];
503             rv = deque_append(new_deque, item);
504         } else {
505             rv = deque_extend(new_deque, deque);
506         }
507         if (rv != NULL) {
508             Py_DECREF(rv);
509             return (PyObject *)new_deque;
510         }
511         Py_DECREF(new_deque);
512         return NULL;
513     }
514     if (old_deque->maxlen < 0)
515         result = PyObject_CallOneArg((PyObject *)(Py_TYPE(deque)), deque);
516     else
517         result = PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi",
518                                        deque, old_deque->maxlen, NULL);
519     if (result != NULL && !PyObject_TypeCheck(result, &deque_type)) {
520         PyErr_Format(PyExc_TypeError,
521                      "%.200s() must return a deque, not %.200s",
522                      Py_TYPE(deque)->tp_name, Py_TYPE(result)->tp_name);
523         Py_DECREF(result);
524         return NULL;
525     }
526     return result;
527 }
528 
529 PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
530 
531 static PyObject *
deque_concat(dequeobject * deque,PyObject * other)532 deque_concat(dequeobject *deque, PyObject *other)
533 {
534     PyObject *new_deque, *result;
535     int rv;
536 
537     rv = PyObject_IsInstance(other, (PyObject *)&deque_type);
538     if (rv <= 0) {
539         if (rv == 0) {
540             PyErr_Format(PyExc_TypeError,
541                          "can only concatenate deque (not \"%.200s\") to deque",
542                          Py_TYPE(other)->tp_name);
543         }
544         return NULL;
545     }
546 
547     new_deque = deque_copy((PyObject *)deque, NULL);
548     if (new_deque == NULL)
549         return NULL;
550     result = deque_extend((dequeobject *)new_deque, other);
551     if (result == NULL) {
552         Py_DECREF(new_deque);
553         return NULL;
554     }
555     Py_DECREF(result);
556     return new_deque;
557 }
558 
559 static int
deque_clear(dequeobject * deque)560 deque_clear(dequeobject *deque)
561 {
562     block *b;
563     block *prevblock;
564     block *leftblock;
565     Py_ssize_t leftindex;
566     Py_ssize_t n, m;
567     PyObject *item;
568     PyObject **itemptr, **limit;
569 
570     if (Py_SIZE(deque) == 0)
571         return 0;
572 
573     /* During the process of clearing a deque, decrefs can cause the
574        deque to mutate.  To avoid fatal confusion, we have to make the
575        deque empty before clearing the blocks and never refer to
576        anything via deque->ref while clearing.  (This is the same
577        technique used for clearing lists, sets, and dicts.)
578 
579        Making the deque empty requires allocating a new empty block.  In
580        the unlikely event that memory is full, we fall back to an
581        alternate method that doesn't require a new block.  Repeating
582        pops in a while-loop is slower, possibly re-entrant (and a clever
583        adversary could cause it to never terminate).
584     */
585 
586     b = newblock();
587     if (b == NULL) {
588         PyErr_Clear();
589         goto alternate_method;
590     }
591 
592     /* Remember the old size, leftblock, and leftindex */
593     n = Py_SIZE(deque);
594     leftblock = deque->leftblock;
595     leftindex = deque->leftindex;
596 
597     /* Set the deque to be empty using the newly allocated block */
598     MARK_END(b->leftlink);
599     MARK_END(b->rightlink);
600     Py_SET_SIZE(deque, 0);
601     deque->leftblock = b;
602     deque->rightblock = b;
603     deque->leftindex = CENTER + 1;
604     deque->rightindex = CENTER;
605     deque->state++;
606 
607     /* Now the old size, leftblock, and leftindex are disconnected from
608        the empty deque and we can use them to decref the pointers.
609     */
610     m = (BLOCKLEN - leftindex > n) ? n : BLOCKLEN - leftindex;
611     itemptr = &leftblock->data[leftindex];
612     limit = itemptr + m;
613     n -= m;
614     while (1) {
615         if (itemptr == limit) {
616             if (n == 0)
617                 break;
618             CHECK_NOT_END(leftblock->rightlink);
619             prevblock = leftblock;
620             leftblock = leftblock->rightlink;
621             m = (n > BLOCKLEN) ? BLOCKLEN : n;
622             itemptr = leftblock->data;
623             limit = itemptr + m;
624             n -= m;
625             freeblock(prevblock);
626         }
627         item = *(itemptr++);
628         Py_DECREF(item);
629     }
630     CHECK_END(leftblock->rightlink);
631     freeblock(leftblock);
632     return 0;
633 
634   alternate_method:
635     while (Py_SIZE(deque)) {
636         item = deque_pop(deque, NULL);
637         assert (item != NULL);
638         Py_DECREF(item);
639     }
640     return 0;
641 }
642 
643 static PyObject *
deque_clearmethod(dequeobject * deque,PyObject * Py_UNUSED (ignored))644 deque_clearmethod(dequeobject *deque, PyObject *Py_UNUSED(ignored))
645 {
646     deque_clear(deque);
647     Py_RETURN_NONE;
648 }
649 
650 PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
651 
652 static PyObject *
deque_inplace_repeat(dequeobject * deque,Py_ssize_t n)653 deque_inplace_repeat(dequeobject *deque, Py_ssize_t n)
654 {
655     Py_ssize_t i, m, size;
656     PyObject *seq;
657     PyObject *rv;
658 
659     size = Py_SIZE(deque);
660     if (size == 0 || n == 1) {
661         Py_INCREF(deque);
662         return (PyObject *)deque;
663     }
664 
665     if (n <= 0) {
666         deque_clear(deque);
667         Py_INCREF(deque);
668         return (PyObject *)deque;
669     }
670 
671     if (size == 1) {
672         /* common case, repeating a single element */
673         PyObject *item = deque->leftblock->data[deque->leftindex];
674 
675         if (deque->maxlen >= 0 && n > deque->maxlen)
676             n = deque->maxlen;
677 
678         deque->state++;
679         for (i = 0 ; i < n-1 ; ) {
680             if (deque->rightindex == BLOCKLEN - 1) {
681                 block *b = newblock();
682                 if (b == NULL) {
683                     Py_SET_SIZE(deque, Py_SIZE(deque) + i);
684                     return NULL;
685                 }
686                 b->leftlink = deque->rightblock;
687                 CHECK_END(deque->rightblock->rightlink);
688                 deque->rightblock->rightlink = b;
689                 deque->rightblock = b;
690                 MARK_END(b->rightlink);
691                 deque->rightindex = -1;
692             }
693             m = n - 1 - i;
694             if (m > BLOCKLEN - 1 - deque->rightindex)
695                 m = BLOCKLEN - 1 - deque->rightindex;
696             i += m;
697             while (m--) {
698                 deque->rightindex++;
699                 Py_INCREF(item);
700                 deque->rightblock->data[deque->rightindex] = item;
701             }
702         }
703         Py_SET_SIZE(deque, Py_SIZE(deque) + i);
704         Py_INCREF(deque);
705         return (PyObject *)deque;
706     }
707 
708     if ((size_t)size > PY_SSIZE_T_MAX / (size_t)n) {
709         return PyErr_NoMemory();
710     }
711 
712     seq = PySequence_List((PyObject *)deque);
713     if (seq == NULL)
714         return seq;
715 
716     /* Reduce the number of repetitions when maxlen would be exceeded */
717     if (deque->maxlen >= 0 && n * size > deque->maxlen)
718         n = (deque->maxlen + size - 1) / size;
719 
720     for (i = 0 ; i < n-1 ; i++) {
721         rv = deque_extend(deque, seq);
722         if (rv == NULL) {
723             Py_DECREF(seq);
724             return NULL;
725         }
726         Py_DECREF(rv);
727     }
728     Py_INCREF(deque);
729     Py_DECREF(seq);
730     return (PyObject *)deque;
731 }
732 
733 static PyObject *
deque_repeat(dequeobject * deque,Py_ssize_t n)734 deque_repeat(dequeobject *deque, Py_ssize_t n)
735 {
736     dequeobject *new_deque;
737     PyObject *rv;
738 
739     new_deque = (dequeobject *)deque_copy((PyObject *) deque, NULL);
740     if (new_deque == NULL)
741         return NULL;
742     rv = deque_inplace_repeat(new_deque, n);
743     Py_DECREF(new_deque);
744     return rv;
745 }
746 
747 /* The rotate() method is part of the public API and is used internally
748 as a primitive for other methods.
749 
750 Rotation by 1 or -1 is a common case, so any optimizations for high
751 volume rotations should take care not to penalize the common case.
752 
753 Conceptually, a rotate by one is equivalent to a pop on one side and an
754 append on the other.  However, a pop/append pair is unnecessarily slow
755 because it requires an incref/decref pair for an object located randomly
756 in memory.  It is better to just move the object pointer from one block
757 to the next without changing the reference count.
758 
759 When moving batches of pointers, it is tempting to use memcpy() but that
760 proved to be slower than a simple loop for a variety of reasons.
761 Memcpy() cannot know in advance that we're copying pointers instead of
762 bytes, that the source and destination are pointer aligned and
763 non-overlapping, that moving just one pointer is a common case, that we
764 never need to move more than BLOCKLEN pointers, and that at least one
765 pointer is always moved.
766 
767 For high volume rotations, newblock() and freeblock() are never called
768 more than once.  Previously emptied blocks are immediately reused as a
769 destination block.  If a block is left-over at the end, it is freed.
770 */
771 
772 static int
_deque_rotate(dequeobject * deque,Py_ssize_t n)773 _deque_rotate(dequeobject *deque, Py_ssize_t n)
774 {
775     block *b = NULL;
776     block *leftblock = deque->leftblock;
777     block *rightblock = deque->rightblock;
778     Py_ssize_t leftindex = deque->leftindex;
779     Py_ssize_t rightindex = deque->rightindex;
780     Py_ssize_t len=Py_SIZE(deque), halflen=len>>1;
781     int rv = -1;
782 
783     if (len <= 1)
784         return 0;
785     if (n > halflen || n < -halflen) {
786         n %= len;
787         if (n > halflen)
788             n -= len;
789         else if (n < -halflen)
790             n += len;
791     }
792     assert(len > 1);
793     assert(-halflen <= n && n <= halflen);
794 
795     deque->state++;
796     while (n > 0) {
797         if (leftindex == 0) {
798             if (b == NULL) {
799                 b = newblock();
800                 if (b == NULL)
801                     goto done;
802             }
803             b->rightlink = leftblock;
804             CHECK_END(leftblock->leftlink);
805             leftblock->leftlink = b;
806             leftblock = b;
807             MARK_END(b->leftlink);
808             leftindex = BLOCKLEN;
809             b = NULL;
810         }
811         assert(leftindex > 0);
812         {
813             PyObject **src, **dest;
814             Py_ssize_t m = n;
815 
816             if (m > rightindex + 1)
817                 m = rightindex + 1;
818             if (m > leftindex)
819                 m = leftindex;
820             assert (m > 0 && m <= len);
821             rightindex -= m;
822             leftindex -= m;
823             src = &rightblock->data[rightindex + 1];
824             dest = &leftblock->data[leftindex];
825             n -= m;
826             do {
827                 *(dest++) = *(src++);
828             } while (--m);
829         }
830         if (rightindex < 0) {
831             assert(leftblock != rightblock);
832             assert(b == NULL);
833             b = rightblock;
834             CHECK_NOT_END(rightblock->leftlink);
835             rightblock = rightblock->leftlink;
836             MARK_END(rightblock->rightlink);
837             rightindex = BLOCKLEN - 1;
838         }
839     }
840     while (n < 0) {
841         if (rightindex == BLOCKLEN - 1) {
842             if (b == NULL) {
843                 b = newblock();
844                 if (b == NULL)
845                     goto done;
846             }
847             b->leftlink = rightblock;
848             CHECK_END(rightblock->rightlink);
849             rightblock->rightlink = b;
850             rightblock = b;
851             MARK_END(b->rightlink);
852             rightindex = -1;
853             b = NULL;
854         }
855         assert (rightindex < BLOCKLEN - 1);
856         {
857             PyObject **src, **dest;
858             Py_ssize_t m = -n;
859 
860             if (m > BLOCKLEN - leftindex)
861                 m = BLOCKLEN - leftindex;
862             if (m > BLOCKLEN - 1 - rightindex)
863                 m = BLOCKLEN - 1 - rightindex;
864             assert (m > 0 && m <= len);
865             src = &leftblock->data[leftindex];
866             dest = &rightblock->data[rightindex + 1];
867             leftindex += m;
868             rightindex += m;
869             n += m;
870             do {
871                 *(dest++) = *(src++);
872             } while (--m);
873         }
874         if (leftindex == BLOCKLEN) {
875             assert(leftblock != rightblock);
876             assert(b == NULL);
877             b = leftblock;
878             CHECK_NOT_END(leftblock->rightlink);
879             leftblock = leftblock->rightlink;
880             MARK_END(leftblock->leftlink);
881             leftindex = 0;
882         }
883     }
884     rv = 0;
885 done:
886     if (b != NULL)
887         freeblock(b);
888     deque->leftblock = leftblock;
889     deque->rightblock = rightblock;
890     deque->leftindex = leftindex;
891     deque->rightindex = rightindex;
892 
893     return rv;
894 }
895 
896 static PyObject *
deque_rotate(dequeobject * deque,PyObject * const * args,Py_ssize_t nargs)897 deque_rotate(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
898 {
899     Py_ssize_t n=1;
900 
901     if (!_PyArg_ParseStack(args, nargs, "|n:rotate", &n)) {
902         return NULL;
903     }
904 
905     if (!_deque_rotate(deque, n))
906         Py_RETURN_NONE;
907     return NULL;
908 }
909 
910 PyDoc_STRVAR(rotate_doc,
911 "Rotate the deque n steps to the right (default n=1).  If n is negative, rotates left.");
912 
913 static PyObject *
deque_reverse(dequeobject * deque,PyObject * unused)914 deque_reverse(dequeobject *deque, PyObject *unused)
915 {
916     block *leftblock = deque->leftblock;
917     block *rightblock = deque->rightblock;
918     Py_ssize_t leftindex = deque->leftindex;
919     Py_ssize_t rightindex = deque->rightindex;
920     Py_ssize_t n = Py_SIZE(deque) >> 1;
921     PyObject *tmp;
922 
923     while (--n >= 0) {
924         /* Validate that pointers haven't met in the middle */
925         assert(leftblock != rightblock || leftindex < rightindex);
926         CHECK_NOT_END(leftblock);
927         CHECK_NOT_END(rightblock);
928 
929         /* Swap */
930         tmp = leftblock->data[leftindex];
931         leftblock->data[leftindex] = rightblock->data[rightindex];
932         rightblock->data[rightindex] = tmp;
933 
934         /* Advance left block/index pair */
935         leftindex++;
936         if (leftindex == BLOCKLEN) {
937             leftblock = leftblock->rightlink;
938             leftindex = 0;
939         }
940 
941         /* Step backwards with the right block/index pair */
942         rightindex--;
943         if (rightindex < 0) {
944             rightblock = rightblock->leftlink;
945             rightindex = BLOCKLEN - 1;
946         }
947     }
948     Py_RETURN_NONE;
949 }
950 
951 PyDoc_STRVAR(reverse_doc,
952 "D.reverse() -- reverse *IN PLACE*");
953 
954 static PyObject *
deque_count(dequeobject * deque,PyObject * v)955 deque_count(dequeobject *deque, PyObject *v)
956 {
957     block *b = deque->leftblock;
958     Py_ssize_t index = deque->leftindex;
959     Py_ssize_t n = Py_SIZE(deque);
960     Py_ssize_t count = 0;
961     size_t start_state = deque->state;
962     PyObject *item;
963     int cmp;
964 
965     while (--n >= 0) {
966         CHECK_NOT_END(b);
967         item = b->data[index];
968         Py_INCREF(item);
969         cmp = PyObject_RichCompareBool(item, v, Py_EQ);
970         Py_DECREF(item);
971         if (cmp < 0)
972             return NULL;
973         count += cmp;
974 
975         if (start_state != deque->state) {
976             PyErr_SetString(PyExc_RuntimeError,
977                             "deque mutated during iteration");
978             return NULL;
979         }
980 
981         /* Advance left block/index pair */
982         index++;
983         if (index == BLOCKLEN) {
984             b = b->rightlink;
985             index = 0;
986         }
987     }
988     return PyLong_FromSsize_t(count);
989 }
990 
991 PyDoc_STRVAR(count_doc,
992 "D.count(value) -> integer -- return number of occurrences of value");
993 
994 static int
deque_contains(dequeobject * deque,PyObject * v)995 deque_contains(dequeobject *deque, PyObject *v)
996 {
997     block *b = deque->leftblock;
998     Py_ssize_t index = deque->leftindex;
999     Py_ssize_t n = Py_SIZE(deque);
1000     size_t start_state = deque->state;
1001     PyObject *item;
1002     int cmp;
1003 
1004     while (--n >= 0) {
1005         CHECK_NOT_END(b);
1006         item = b->data[index];
1007         Py_INCREF(item);
1008         cmp = PyObject_RichCompareBool(item, v, Py_EQ);
1009         Py_DECREF(item);
1010         if (cmp) {
1011             return cmp;
1012         }
1013         if (start_state != deque->state) {
1014             PyErr_SetString(PyExc_RuntimeError,
1015                             "deque mutated during iteration");
1016             return -1;
1017         }
1018         index++;
1019         if (index == BLOCKLEN) {
1020             b = b->rightlink;
1021             index = 0;
1022         }
1023     }
1024     return 0;
1025 }
1026 
1027 static Py_ssize_t
deque_len(dequeobject * deque)1028 deque_len(dequeobject *deque)
1029 {
1030     return Py_SIZE(deque);
1031 }
1032 
1033 static PyObject *
deque_index(dequeobject * deque,PyObject * const * args,Py_ssize_t nargs)1034 deque_index(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
1035 {
1036     Py_ssize_t i, n, start=0, stop=Py_SIZE(deque);
1037     PyObject *v, *item;
1038     block *b = deque->leftblock;
1039     Py_ssize_t index = deque->leftindex;
1040     size_t start_state = deque->state;
1041     int cmp;
1042 
1043     if (!_PyArg_ParseStack(args, nargs, "O|O&O&:index", &v,
1044                            _PyEval_SliceIndexNotNone, &start,
1045                            _PyEval_SliceIndexNotNone, &stop)) {
1046         return NULL;
1047     }
1048 
1049     if (start < 0) {
1050         start += Py_SIZE(deque);
1051         if (start < 0)
1052             start = 0;
1053     }
1054     if (stop < 0) {
1055         stop += Py_SIZE(deque);
1056         if (stop < 0)
1057             stop = 0;
1058     }
1059     if (stop > Py_SIZE(deque))
1060         stop = Py_SIZE(deque);
1061     if (start > stop)
1062         start = stop;
1063     assert(0 <= start && start <= stop && stop <= Py_SIZE(deque));
1064 
1065     for (i=0 ; i < start - BLOCKLEN ; i += BLOCKLEN) {
1066         b = b->rightlink;
1067     }
1068     for ( ; i < start ; i++) {
1069         index++;
1070         if (index == BLOCKLEN) {
1071             b = b->rightlink;
1072             index = 0;
1073         }
1074     }
1075 
1076     n = stop - i;
1077     while (--n >= 0) {
1078         CHECK_NOT_END(b);
1079         item = b->data[index];
1080         cmp = PyObject_RichCompareBool(item, v, Py_EQ);
1081         if (cmp > 0)
1082             return PyLong_FromSsize_t(stop - n - 1);
1083         if (cmp < 0)
1084             return NULL;
1085         if (start_state != deque->state) {
1086             PyErr_SetString(PyExc_RuntimeError,
1087                             "deque mutated during iteration");
1088             return NULL;
1089         }
1090         index++;
1091         if (index == BLOCKLEN) {
1092             b = b->rightlink;
1093             index = 0;
1094         }
1095     }
1096     PyErr_Format(PyExc_ValueError, "%R is not in deque", v);
1097     return NULL;
1098 }
1099 
1100 PyDoc_STRVAR(index_doc,
1101 "D.index(value, [start, [stop]]) -> integer -- return first index of value.\n"
1102 "Raises ValueError if the value is not present.");
1103 
1104 /* insert(), remove(), and delitem() are implemented in terms of
1105    rotate() for simplicity and reasonable performance near the end
1106    points.  If for some reason these methods become popular, it is not
1107    hard to re-implement this using direct data movement (similar to
1108    the code used in list slice assignments) and achieve a performance
1109    boost (by moving each pointer only once instead of twice).
1110 */
1111 
1112 static PyObject *
deque_insert(dequeobject * deque,PyObject * const * args,Py_ssize_t nargs)1113 deque_insert(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
1114 {
1115     Py_ssize_t index;
1116     Py_ssize_t n = Py_SIZE(deque);
1117     PyObject *value;
1118     PyObject *rv;
1119 
1120     if (!_PyArg_ParseStack(args, nargs, "nO:insert", &index, &value)) {
1121         return NULL;
1122     }
1123 
1124     if (deque->maxlen == Py_SIZE(deque)) {
1125         PyErr_SetString(PyExc_IndexError, "deque already at its maximum size");
1126         return NULL;
1127     }
1128     if (index >= n)
1129         return deque_append(deque, value);
1130     if (index <= -n || index == 0)
1131         return deque_appendleft(deque, value);
1132     if (_deque_rotate(deque, -index))
1133         return NULL;
1134     if (index < 0)
1135         rv = deque_append(deque, value);
1136     else
1137         rv = deque_appendleft(deque, value);
1138     if (rv == NULL)
1139         return NULL;
1140     Py_DECREF(rv);
1141     if (_deque_rotate(deque, index))
1142         return NULL;
1143     Py_RETURN_NONE;
1144 }
1145 
1146 PyDoc_STRVAR(insert_doc,
1147 "D.insert(index, object) -- insert object before index");
1148 
1149 static PyObject *
deque_remove(dequeobject * deque,PyObject * value)1150 deque_remove(dequeobject *deque, PyObject *value)
1151 {
1152     Py_ssize_t i, n=Py_SIZE(deque);
1153 
1154     for (i=0 ; i<n ; i++) {
1155         PyObject *item = deque->leftblock->data[deque->leftindex];
1156         int cmp = PyObject_RichCompareBool(item, value, Py_EQ);
1157 
1158         if (Py_SIZE(deque) != n) {
1159             PyErr_SetString(PyExc_IndexError,
1160                 "deque mutated during remove().");
1161             return NULL;
1162         }
1163         if (cmp > 0) {
1164             PyObject *tgt = deque_popleft(deque, NULL);
1165             assert (tgt != NULL);
1166             if (_deque_rotate(deque, i))
1167                 return NULL;
1168             Py_DECREF(tgt);
1169             Py_RETURN_NONE;
1170         }
1171         else if (cmp < 0) {
1172             _deque_rotate(deque, i);
1173             return NULL;
1174         }
1175         _deque_rotate(deque, -1);
1176     }
1177     PyErr_SetString(PyExc_ValueError, "deque.remove(x): x not in deque");
1178     return NULL;
1179 }
1180 
1181 PyDoc_STRVAR(remove_doc,
1182 "D.remove(value) -- remove first occurrence of value.");
1183 
1184 static int
valid_index(Py_ssize_t i,Py_ssize_t limit)1185 valid_index(Py_ssize_t i, Py_ssize_t limit)
1186 {
1187     /* The cast to size_t lets us use just a single comparison
1188        to check whether i is in the range: 0 <= i < limit */
1189     return (size_t) i < (size_t) limit;
1190 }
1191 
1192 static PyObject *
deque_item(dequeobject * deque,Py_ssize_t i)1193 deque_item(dequeobject *deque, Py_ssize_t i)
1194 {
1195     block *b;
1196     PyObject *item;
1197     Py_ssize_t n, index=i;
1198 
1199     if (!valid_index(i, Py_SIZE(deque))) {
1200         PyErr_SetString(PyExc_IndexError, "deque index out of range");
1201         return NULL;
1202     }
1203 
1204     if (i == 0) {
1205         i = deque->leftindex;
1206         b = deque->leftblock;
1207     } else if (i == Py_SIZE(deque) - 1) {
1208         i = deque->rightindex;
1209         b = deque->rightblock;
1210     } else {
1211         i += deque->leftindex;
1212         n = (Py_ssize_t)((size_t) i / BLOCKLEN);
1213         i = (Py_ssize_t)((size_t) i % BLOCKLEN);
1214         if (index < (Py_SIZE(deque) >> 1)) {
1215             b = deque->leftblock;
1216             while (--n >= 0)
1217                 b = b->rightlink;
1218         } else {
1219             n = (Py_ssize_t)(
1220                     ((size_t)(deque->leftindex + Py_SIZE(deque) - 1))
1221                     / BLOCKLEN - n);
1222             b = deque->rightblock;
1223             while (--n >= 0)
1224                 b = b->leftlink;
1225         }
1226     }
1227     item = b->data[i];
1228     Py_INCREF(item);
1229     return item;
1230 }
1231 
1232 static int
deque_del_item(dequeobject * deque,Py_ssize_t i)1233 deque_del_item(dequeobject *deque, Py_ssize_t i)
1234 {
1235     PyObject *item;
1236     int rv;
1237 
1238     assert (i >= 0 && i < Py_SIZE(deque));
1239     if (_deque_rotate(deque, -i))
1240         return -1;
1241     item = deque_popleft(deque, NULL);
1242     rv = _deque_rotate(deque, i);
1243     assert (item != NULL);
1244     Py_DECREF(item);
1245     return rv;
1246 }
1247 
1248 static int
deque_ass_item(dequeobject * deque,Py_ssize_t i,PyObject * v)1249 deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v)
1250 {
1251     PyObject *old_value;
1252     block *b;
1253     Py_ssize_t n, len=Py_SIZE(deque), halflen=(len+1)>>1, index=i;
1254 
1255     if (!valid_index(i, len)) {
1256         PyErr_SetString(PyExc_IndexError, "deque index out of range");
1257         return -1;
1258     }
1259     if (v == NULL)
1260         return deque_del_item(deque, i);
1261 
1262     i += deque->leftindex;
1263     n = (Py_ssize_t)((size_t) i / BLOCKLEN);
1264     i = (Py_ssize_t)((size_t) i % BLOCKLEN);
1265     if (index <= halflen) {
1266         b = deque->leftblock;
1267         while (--n >= 0)
1268             b = b->rightlink;
1269     } else {
1270         n = (Py_ssize_t)(
1271                 ((size_t)(deque->leftindex + Py_SIZE(deque) - 1))
1272                 / BLOCKLEN - n);
1273         b = deque->rightblock;
1274         while (--n >= 0)
1275             b = b->leftlink;
1276     }
1277     Py_INCREF(v);
1278     old_value = b->data[i];
1279     b->data[i] = v;
1280     Py_DECREF(old_value);
1281     return 0;
1282 }
1283 
1284 static void
deque_dealloc(dequeobject * deque)1285 deque_dealloc(dequeobject *deque)
1286 {
1287     PyObject_GC_UnTrack(deque);
1288     if (deque->weakreflist != NULL)
1289         PyObject_ClearWeakRefs((PyObject *) deque);
1290     if (deque->leftblock != NULL) {
1291         deque_clear(deque);
1292         assert(deque->leftblock != NULL);
1293         freeblock(deque->leftblock);
1294     }
1295     deque->leftblock = NULL;
1296     deque->rightblock = NULL;
1297     Py_TYPE(deque)->tp_free(deque);
1298 }
1299 
1300 static int
deque_traverse(dequeobject * deque,visitproc visit,void * arg)1301 deque_traverse(dequeobject *deque, visitproc visit, void *arg)
1302 {
1303     block *b;
1304     PyObject *item;
1305     Py_ssize_t index;
1306     Py_ssize_t indexlo = deque->leftindex;
1307     Py_ssize_t indexhigh;
1308 
1309     for (b = deque->leftblock; b != deque->rightblock; b = b->rightlink) {
1310         for (index = indexlo; index < BLOCKLEN ; index++) {
1311             item = b->data[index];
1312             Py_VISIT(item);
1313         }
1314         indexlo = 0;
1315     }
1316     indexhigh = deque->rightindex;
1317     for (index = indexlo; index <= indexhigh; index++) {
1318         item = b->data[index];
1319         Py_VISIT(item);
1320     }
1321     return 0;
1322 }
1323 
1324 static PyObject *
deque_reduce(dequeobject * deque,PyObject * Py_UNUSED (ignored))1325 deque_reduce(dequeobject *deque, PyObject *Py_UNUSED(ignored))
1326 {
1327     PyObject *dict, *it;
1328     _Py_IDENTIFIER(__dict__);
1329 
1330     if (_PyObject_LookupAttrId((PyObject *)deque, &PyId___dict__, &dict) < 0) {
1331         return NULL;
1332     }
1333     if (dict == NULL) {
1334         dict = Py_None;
1335         Py_INCREF(dict);
1336     }
1337 
1338     it = PyObject_GetIter((PyObject *)deque);
1339     if (it == NULL) {
1340         Py_DECREF(dict);
1341         return NULL;
1342     }
1343 
1344     if (deque->maxlen < 0) {
1345         return Py_BuildValue("O()NN", Py_TYPE(deque), dict, it);
1346     }
1347     else {
1348         return Py_BuildValue("O(()n)NN", Py_TYPE(deque), deque->maxlen, dict, it);
1349     }
1350 }
1351 
1352 PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
1353 
1354 static PyObject *
deque_repr(PyObject * deque)1355 deque_repr(PyObject *deque)
1356 {
1357     PyObject *aslist, *result;
1358     int i;
1359 
1360     i = Py_ReprEnter(deque);
1361     if (i != 0) {
1362         if (i < 0)
1363             return NULL;
1364         return PyUnicode_FromString("[...]");
1365     }
1366 
1367     aslist = PySequence_List(deque);
1368     if (aslist == NULL) {
1369         Py_ReprLeave(deque);
1370         return NULL;
1371     }
1372     if (((dequeobject *)deque)->maxlen >= 0)
1373         result = PyUnicode_FromFormat("%s(%R, maxlen=%zd)",
1374                                       _PyType_Name(Py_TYPE(deque)), aslist,
1375                                       ((dequeobject *)deque)->maxlen);
1376     else
1377         result = PyUnicode_FromFormat("%s(%R)",
1378                                       _PyType_Name(Py_TYPE(deque)), aslist);
1379     Py_ReprLeave(deque);
1380     Py_DECREF(aslist);
1381     return result;
1382 }
1383 
1384 static PyObject *
deque_richcompare(PyObject * v,PyObject * w,int op)1385 deque_richcompare(PyObject *v, PyObject *w, int op)
1386 {
1387     PyObject *it1=NULL, *it2=NULL, *x, *y;
1388     Py_ssize_t vs, ws;
1389     int b, cmp=-1;
1390 
1391     if (!PyObject_TypeCheck(v, &deque_type) ||
1392         !PyObject_TypeCheck(w, &deque_type)) {
1393         Py_RETURN_NOTIMPLEMENTED;
1394     }
1395 
1396     /* Shortcuts */
1397     vs = Py_SIZE((dequeobject *)v);
1398     ws = Py_SIZE((dequeobject *)w);
1399     if (op == Py_EQ) {
1400         if (v == w)
1401             Py_RETURN_TRUE;
1402         if (vs != ws)
1403             Py_RETURN_FALSE;
1404     }
1405     if (op == Py_NE) {
1406         if (v == w)
1407             Py_RETURN_FALSE;
1408         if (vs != ws)
1409             Py_RETURN_TRUE;
1410     }
1411 
1412     /* Search for the first index where items are different */
1413     it1 = PyObject_GetIter(v);
1414     if (it1 == NULL)
1415         goto done;
1416     it2 = PyObject_GetIter(w);
1417     if (it2 == NULL)
1418         goto done;
1419     for (;;) {
1420         x = PyIter_Next(it1);
1421         if (x == NULL && PyErr_Occurred())
1422             goto done;
1423         y = PyIter_Next(it2);
1424         if (x == NULL || y == NULL)
1425             break;
1426         b = PyObject_RichCompareBool(x, y, Py_EQ);
1427         if (b == 0) {
1428             cmp = PyObject_RichCompareBool(x, y, op);
1429             Py_DECREF(x);
1430             Py_DECREF(y);
1431             goto done;
1432         }
1433         Py_DECREF(x);
1434         Py_DECREF(y);
1435         if (b < 0)
1436             goto done;
1437     }
1438     /* We reached the end of one deque or both */
1439     Py_XDECREF(x);
1440     Py_XDECREF(y);
1441     if (PyErr_Occurred())
1442         goto done;
1443     switch (op) {
1444     case Py_LT: cmp = y != NULL; break;  /* if w was longer */
1445     case Py_LE: cmp = x == NULL; break;  /* if v was not longer */
1446     case Py_EQ: cmp = x == y;    break;  /* if we reached the end of both */
1447     case Py_NE: cmp = x != y;    break;  /* if one deque continues */
1448     case Py_GT: cmp = x != NULL; break;  /* if v was longer */
1449     case Py_GE: cmp = y == NULL; break;  /* if w was not longer */
1450     }
1451 
1452 done:
1453     Py_XDECREF(it1);
1454     Py_XDECREF(it2);
1455     if (cmp == 1)
1456         Py_RETURN_TRUE;
1457     if (cmp == 0)
1458         Py_RETURN_FALSE;
1459     return NULL;
1460 }
1461 
1462 static int
deque_init(dequeobject * deque,PyObject * args,PyObject * kwdargs)1463 deque_init(dequeobject *deque, PyObject *args, PyObject *kwdargs)
1464 {
1465     PyObject *iterable = NULL;
1466     PyObject *maxlenobj = NULL;
1467     Py_ssize_t maxlen = -1;
1468     char *kwlist[] = {"iterable", "maxlen", 0};
1469 
1470     if (kwdargs == NULL && PyTuple_GET_SIZE(args) <= 2) {
1471         if (PyTuple_GET_SIZE(args) > 0) {
1472             iterable = PyTuple_GET_ITEM(args, 0);
1473         }
1474         if (PyTuple_GET_SIZE(args) > 1) {
1475             maxlenobj = PyTuple_GET_ITEM(args, 1);
1476         }
1477     } else {
1478         if (!PyArg_ParseTupleAndKeywords(args, kwdargs, "|OO:deque", kwlist,
1479                                          &iterable, &maxlenobj))
1480             return -1;
1481     }
1482     if (maxlenobj != NULL && maxlenobj != Py_None) {
1483         maxlen = PyLong_AsSsize_t(maxlenobj);
1484         if (maxlen == -1 && PyErr_Occurred())
1485             return -1;
1486         if (maxlen < 0) {
1487             PyErr_SetString(PyExc_ValueError, "maxlen must be non-negative");
1488             return -1;
1489         }
1490     }
1491     deque->maxlen = maxlen;
1492     if (Py_SIZE(deque) > 0)
1493         deque_clear(deque);
1494     if (iterable != NULL) {
1495         PyObject *rv = deque_extend(deque, iterable);
1496         if (rv == NULL)
1497             return -1;
1498         Py_DECREF(rv);
1499     }
1500     return 0;
1501 }
1502 
1503 static PyObject *
deque_sizeof(dequeobject * deque,void * unused)1504 deque_sizeof(dequeobject *deque, void *unused)
1505 {
1506     Py_ssize_t res;
1507     Py_ssize_t blocks;
1508 
1509     res = _PyObject_SIZE(Py_TYPE(deque));
1510     blocks = (size_t)(deque->leftindex + Py_SIZE(deque) + BLOCKLEN - 1) / BLOCKLEN;
1511     assert(deque->leftindex + Py_SIZE(deque) - 1 ==
1512            (blocks - 1) * BLOCKLEN + deque->rightindex);
1513     res += blocks * sizeof(block);
1514     return PyLong_FromSsize_t(res);
1515 }
1516 
1517 PyDoc_STRVAR(sizeof_doc,
1518 "D.__sizeof__() -- size of D in memory, in bytes");
1519 
1520 static int
deque_bool(dequeobject * deque)1521 deque_bool(dequeobject *deque)
1522 {
1523     return Py_SIZE(deque) != 0;
1524 }
1525 
1526 static PyObject *
deque_get_maxlen(dequeobject * deque,void * Py_UNUSED (ignored))1527 deque_get_maxlen(dequeobject *deque, void *Py_UNUSED(ignored))
1528 {
1529     if (deque->maxlen < 0)
1530         Py_RETURN_NONE;
1531     return PyLong_FromSsize_t(deque->maxlen);
1532 }
1533 
1534 
1535 /* deque object ********************************************************/
1536 
1537 static PyGetSetDef deque_getset[] = {
1538     {"maxlen", (getter)deque_get_maxlen, (setter)NULL,
1539      "maximum size of a deque or None if unbounded"},
1540     {0}
1541 };
1542 
1543 static PySequenceMethods deque_as_sequence = {
1544     (lenfunc)deque_len,                 /* sq_length */
1545     (binaryfunc)deque_concat,           /* sq_concat */
1546     (ssizeargfunc)deque_repeat,         /* sq_repeat */
1547     (ssizeargfunc)deque_item,           /* sq_item */
1548     0,                                  /* sq_slice */
1549     (ssizeobjargproc)deque_ass_item,    /* sq_ass_item */
1550     0,                                  /* sq_ass_slice */
1551     (objobjproc)deque_contains,         /* sq_contains */
1552     (binaryfunc)deque_inplace_concat,   /* sq_inplace_concat */
1553     (ssizeargfunc)deque_inplace_repeat, /* sq_inplace_repeat */
1554 };
1555 
1556 static PyNumberMethods deque_as_number = {
1557     0,                                  /* nb_add */
1558     0,                                  /* nb_subtract */
1559     0,                                  /* nb_multiply */
1560     0,                                  /* nb_remainder */
1561     0,                                  /* nb_divmod */
1562     0,                                  /* nb_power */
1563     0,                                  /* nb_negative */
1564     0,                                  /* nb_positive */
1565     0,                                  /* nb_absolute */
1566     (inquiry)deque_bool,                /* nb_bool */
1567     0,                                  /* nb_invert */
1568  };
1569 
1570 static PyObject *deque_iter(dequeobject *deque);
1571 static PyObject *deque_reviter(dequeobject *deque, PyObject *Py_UNUSED(ignored));
1572 PyDoc_STRVAR(reversed_doc,
1573     "D.__reversed__() -- return a reverse iterator over the deque");
1574 
1575 static PyMethodDef deque_methods[] = {
1576     {"append",                  (PyCFunction)deque_append,
1577         METH_O,                  append_doc},
1578     {"appendleft",              (PyCFunction)deque_appendleft,
1579         METH_O,                  appendleft_doc},
1580     {"clear",                   (PyCFunction)deque_clearmethod,
1581         METH_NOARGS,             clear_doc},
1582     {"__copy__",                deque_copy,
1583         METH_NOARGS,             copy_doc},
1584     {"copy",                    deque_copy,
1585         METH_NOARGS,             copy_doc},
1586     {"count",                   (PyCFunction)deque_count,
1587         METH_O,                  count_doc},
1588     {"extend",                  (PyCFunction)deque_extend,
1589         METH_O,                  extend_doc},
1590     {"extendleft",              (PyCFunction)deque_extendleft,
1591         METH_O,                  extendleft_doc},
1592     {"index",                   (PyCFunction)(void(*)(void))deque_index,
1593         METH_FASTCALL,            index_doc},
1594     {"insert",                  (PyCFunction)(void(*)(void))deque_insert,
1595         METH_FASTCALL,            insert_doc},
1596     {"pop",                     (PyCFunction)deque_pop,
1597         METH_NOARGS,             pop_doc},
1598     {"popleft",                 (PyCFunction)deque_popleft,
1599         METH_NOARGS,             popleft_doc},
1600     {"__reduce__",              (PyCFunction)deque_reduce,
1601         METH_NOARGS,             reduce_doc},
1602     {"remove",                  (PyCFunction)deque_remove,
1603         METH_O,                  remove_doc},
1604     {"__reversed__",            (PyCFunction)deque_reviter,
1605         METH_NOARGS,             reversed_doc},
1606     {"reverse",                 (PyCFunction)deque_reverse,
1607         METH_NOARGS,             reverse_doc},
1608     {"rotate",                  (PyCFunction)(void(*)(void))deque_rotate,
1609         METH_FASTCALL,            rotate_doc},
1610     {"__sizeof__",              (PyCFunction)deque_sizeof,
1611         METH_NOARGS,             sizeof_doc},
1612     {"__class_getitem__",       (PyCFunction)Py_GenericAlias,
1613         METH_O|METH_CLASS,       PyDoc_STR("See PEP 585")},
1614     {NULL,              NULL}   /* sentinel */
1615 };
1616 
1617 PyDoc_STRVAR(deque_doc,
1618 "deque([iterable[, maxlen]]) --> deque object\n\
1619 \n\
1620 A list-like sequence optimized for data accesses near its endpoints.");
1621 
1622 static PyTypeObject deque_type = {
1623     PyVarObject_HEAD_INIT(NULL, 0)
1624     "collections.deque",                /* tp_name */
1625     sizeof(dequeobject),                /* tp_basicsize */
1626     0,                                  /* tp_itemsize */
1627     /* methods */
1628     (destructor)deque_dealloc,          /* tp_dealloc */
1629     0,                                  /* tp_vectorcall_offset */
1630     0,                                  /* tp_getattr */
1631     0,                                  /* tp_setattr */
1632     0,                                  /* tp_as_async */
1633     deque_repr,                         /* tp_repr */
1634     &deque_as_number,                   /* tp_as_number */
1635     &deque_as_sequence,                 /* tp_as_sequence */
1636     0,                                  /* tp_as_mapping */
1637     PyObject_HashNotImplemented,        /* tp_hash */
1638     0,                                  /* tp_call */
1639     0,                                  /* tp_str */
1640     PyObject_GenericGetAttr,            /* tp_getattro */
1641     0,                                  /* tp_setattro */
1642     0,                                  /* tp_as_buffer */
1643     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1644                                         /* tp_flags */
1645     deque_doc,                          /* tp_doc */
1646     (traverseproc)deque_traverse,       /* tp_traverse */
1647     (inquiry)deque_clear,               /* tp_clear */
1648     (richcmpfunc)deque_richcompare,     /* tp_richcompare */
1649     offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
1650     (getiterfunc)deque_iter,            /* tp_iter */
1651     0,                                  /* tp_iternext */
1652     deque_methods,                      /* tp_methods */
1653     0,                                  /* tp_members */
1654     deque_getset,                       /* tp_getset */
1655     0,                                  /* tp_base */
1656     0,                                  /* tp_dict */
1657     0,                                  /* tp_descr_get */
1658     0,                                  /* tp_descr_set */
1659     0,                                  /* tp_dictoffset */
1660     (initproc)deque_init,               /* tp_init */
1661     PyType_GenericAlloc,                /* tp_alloc */
1662     deque_new,                          /* tp_new */
1663     PyObject_GC_Del,                    /* tp_free */
1664 };
1665 
1666 /*********************** Deque Iterator **************************/
1667 
1668 typedef struct {
1669     PyObject_HEAD
1670     block *b;
1671     Py_ssize_t index;
1672     dequeobject *deque;
1673     size_t state;          /* state when the iterator is created */
1674     Py_ssize_t counter;    /* number of items remaining for iteration */
1675 } dequeiterobject;
1676 
1677 static PyTypeObject dequeiter_type;
1678 
1679 static PyObject *
deque_iter(dequeobject * deque)1680 deque_iter(dequeobject *deque)
1681 {
1682     dequeiterobject *it;
1683 
1684     it = PyObject_GC_New(dequeiterobject, &dequeiter_type);
1685     if (it == NULL)
1686         return NULL;
1687     it->b = deque->leftblock;
1688     it->index = deque->leftindex;
1689     Py_INCREF(deque);
1690     it->deque = deque;
1691     it->state = deque->state;
1692     it->counter = Py_SIZE(deque);
1693     PyObject_GC_Track(it);
1694     return (PyObject *)it;
1695 }
1696 
1697 static int
dequeiter_traverse(dequeiterobject * dio,visitproc visit,void * arg)1698 dequeiter_traverse(dequeiterobject *dio, visitproc visit, void *arg)
1699 {
1700     Py_VISIT(dio->deque);
1701     return 0;
1702 }
1703 
1704 static void
dequeiter_dealloc(dequeiterobject * dio)1705 dequeiter_dealloc(dequeiterobject *dio)
1706 {
1707     /* bpo-31095: UnTrack is needed before calling any callbacks */
1708     PyObject_GC_UnTrack(dio);
1709     Py_XDECREF(dio->deque);
1710     PyObject_GC_Del(dio);
1711 }
1712 
1713 static PyObject *
dequeiter_next(dequeiterobject * it)1714 dequeiter_next(dequeiterobject *it)
1715 {
1716     PyObject *item;
1717 
1718     if (it->deque->state != it->state) {
1719         it->counter = 0;
1720         PyErr_SetString(PyExc_RuntimeError,
1721                         "deque mutated during iteration");
1722         return NULL;
1723     }
1724     if (it->counter == 0)
1725         return NULL;
1726     assert (!(it->b == it->deque->rightblock &&
1727               it->index > it->deque->rightindex));
1728 
1729     item = it->b->data[it->index];
1730     it->index++;
1731     it->counter--;
1732     if (it->index == BLOCKLEN && it->counter > 0) {
1733         CHECK_NOT_END(it->b->rightlink);
1734         it->b = it->b->rightlink;
1735         it->index = 0;
1736     }
1737     Py_INCREF(item);
1738     return item;
1739 }
1740 
1741 static PyObject *
dequeiter_new(PyTypeObject * type,PyObject * args,PyObject * kwds)1742 dequeiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1743 {
1744     Py_ssize_t i, index=0;
1745     PyObject *deque;
1746     dequeiterobject *it;
1747     if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index))
1748         return NULL;
1749     assert(type == &dequeiter_type);
1750 
1751     it = (dequeiterobject*)deque_iter((dequeobject *)deque);
1752     if (!it)
1753         return NULL;
1754     /* consume items from the queue */
1755     for(i=0; i<index; i++) {
1756         PyObject *item = dequeiter_next(it);
1757         if (item) {
1758             Py_DECREF(item);
1759         } else {
1760             if (it->counter) {
1761                 Py_DECREF(it);
1762                 return NULL;
1763             } else
1764                 break;
1765         }
1766     }
1767     return (PyObject*)it;
1768 }
1769 
1770 static PyObject *
dequeiter_len(dequeiterobject * it,PyObject * Py_UNUSED (ignored))1771 dequeiter_len(dequeiterobject *it, PyObject *Py_UNUSED(ignored))
1772 {
1773     return PyLong_FromSsize_t(it->counter);
1774 }
1775 
1776 PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
1777 
1778 static PyObject *
dequeiter_reduce(dequeiterobject * it,PyObject * Py_UNUSED (ignored))1779 dequeiter_reduce(dequeiterobject *it, PyObject *Py_UNUSED(ignored))
1780 {
1781     return Py_BuildValue("O(On)", Py_TYPE(it), it->deque, Py_SIZE(it->deque) - it->counter);
1782 }
1783 
1784 static PyMethodDef dequeiter_methods[] = {
1785     {"__length_hint__", (PyCFunction)dequeiter_len, METH_NOARGS, length_hint_doc},
1786     {"__reduce__", (PyCFunction)dequeiter_reduce, METH_NOARGS, reduce_doc},
1787     {NULL,              NULL}           /* sentinel */
1788 };
1789 
1790 static PyTypeObject dequeiter_type = {
1791     PyVarObject_HEAD_INIT(NULL, 0)
1792     "_collections._deque_iterator",             /* tp_name */
1793     sizeof(dequeiterobject),                    /* tp_basicsize */
1794     0,                                          /* tp_itemsize */
1795     /* methods */
1796     (destructor)dequeiter_dealloc,              /* tp_dealloc */
1797     0,                                          /* tp_vectorcall_offset */
1798     0,                                          /* tp_getattr */
1799     0,                                          /* tp_setattr */
1800     0,                                          /* tp_as_async */
1801     0,                                          /* tp_repr */
1802     0,                                          /* tp_as_number */
1803     0,                                          /* tp_as_sequence */
1804     0,                                          /* tp_as_mapping */
1805     0,                                          /* tp_hash */
1806     0,                                          /* tp_call */
1807     0,                                          /* tp_str */
1808     PyObject_GenericGetAttr,                    /* tp_getattro */
1809     0,                                          /* tp_setattro */
1810     0,                                          /* tp_as_buffer */
1811     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
1812     0,                                          /* tp_doc */
1813     (traverseproc)dequeiter_traverse,           /* tp_traverse */
1814     0,                                          /* tp_clear */
1815     0,                                          /* tp_richcompare */
1816     0,                                          /* tp_weaklistoffset */
1817     PyObject_SelfIter,                          /* tp_iter */
1818     (iternextfunc)dequeiter_next,               /* tp_iternext */
1819     dequeiter_methods,                          /* tp_methods */
1820     0,                                          /* tp_members */
1821     0,                                          /* tp_getset */
1822     0,                                          /* tp_base */
1823     0,                                          /* tp_dict */
1824     0,                                          /* tp_descr_get */
1825     0,                                          /* tp_descr_set */
1826     0,                                          /* tp_dictoffset */
1827     0,                                          /* tp_init */
1828     0,                                          /* tp_alloc */
1829     dequeiter_new,                              /* tp_new */
1830     0,
1831 };
1832 
1833 /*********************** Deque Reverse Iterator **************************/
1834 
1835 static PyTypeObject dequereviter_type;
1836 
1837 static PyObject *
deque_reviter(dequeobject * deque,PyObject * Py_UNUSED (ignored))1838 deque_reviter(dequeobject *deque, PyObject *Py_UNUSED(ignored))
1839 {
1840     dequeiterobject *it;
1841 
1842     it = PyObject_GC_New(dequeiterobject, &dequereviter_type);
1843     if (it == NULL)
1844         return NULL;
1845     it->b = deque->rightblock;
1846     it->index = deque->rightindex;
1847     Py_INCREF(deque);
1848     it->deque = deque;
1849     it->state = deque->state;
1850     it->counter = Py_SIZE(deque);
1851     PyObject_GC_Track(it);
1852     return (PyObject *)it;
1853 }
1854 
1855 static PyObject *
dequereviter_next(dequeiterobject * it)1856 dequereviter_next(dequeiterobject *it)
1857 {
1858     PyObject *item;
1859     if (it->counter == 0)
1860         return NULL;
1861 
1862     if (it->deque->state != it->state) {
1863         it->counter = 0;
1864         PyErr_SetString(PyExc_RuntimeError,
1865                         "deque mutated during iteration");
1866         return NULL;
1867     }
1868     assert (!(it->b == it->deque->leftblock &&
1869               it->index < it->deque->leftindex));
1870 
1871     item = it->b->data[it->index];
1872     it->index--;
1873     it->counter--;
1874     if (it->index < 0 && it->counter > 0) {
1875         CHECK_NOT_END(it->b->leftlink);
1876         it->b = it->b->leftlink;
1877         it->index = BLOCKLEN - 1;
1878     }
1879     Py_INCREF(item);
1880     return item;
1881 }
1882 
1883 static PyObject *
dequereviter_new(PyTypeObject * type,PyObject * args,PyObject * kwds)1884 dequereviter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1885 {
1886     Py_ssize_t i, index=0;
1887     PyObject *deque;
1888     dequeiterobject *it;
1889     if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index))
1890         return NULL;
1891     assert(type == &dequereviter_type);
1892 
1893     it = (dequeiterobject*)deque_reviter((dequeobject *)deque, NULL);
1894     if (!it)
1895         return NULL;
1896     /* consume items from the queue */
1897     for(i=0; i<index; i++) {
1898         PyObject *item = dequereviter_next(it);
1899         if (item) {
1900             Py_DECREF(item);
1901         } else {
1902             if (it->counter) {
1903                 Py_DECREF(it);
1904                 return NULL;
1905             } else
1906                 break;
1907         }
1908     }
1909     return (PyObject*)it;
1910 }
1911 
1912 static PyTypeObject dequereviter_type = {
1913     PyVarObject_HEAD_INIT(NULL, 0)
1914     "_collections._deque_reverse_iterator",     /* tp_name */
1915     sizeof(dequeiterobject),                    /* tp_basicsize */
1916     0,                                          /* tp_itemsize */
1917     /* methods */
1918     (destructor)dequeiter_dealloc,              /* 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     PyObject_GenericGetAttr,                    /* tp_getattro */
1931     0,                                          /* tp_setattro */
1932     0,                                          /* tp_as_buffer */
1933     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
1934     0,                                          /* tp_doc */
1935     (traverseproc)dequeiter_traverse,           /* tp_traverse */
1936     0,                                          /* tp_clear */
1937     0,                                          /* tp_richcompare */
1938     0,                                          /* tp_weaklistoffset */
1939     PyObject_SelfIter,                          /* tp_iter */
1940     (iternextfunc)dequereviter_next,            /* tp_iternext */
1941     dequeiter_methods,                          /* tp_methods */
1942     0,                                          /* tp_members */
1943     0,                                          /* tp_getset */
1944     0,                                          /* tp_base */
1945     0,                                          /* tp_dict */
1946     0,                                          /* tp_descr_get */
1947     0,                                          /* tp_descr_set */
1948     0,                                          /* tp_dictoffset */
1949     0,                                          /* tp_init */
1950     0,                                          /* tp_alloc */
1951     dequereviter_new,                           /* tp_new */
1952     0,
1953 };
1954 
1955 /* defaultdict type *********************************************************/
1956 
1957 typedef struct {
1958     PyDictObject dict;
1959     PyObject *default_factory;
1960 } defdictobject;
1961 
1962 static PyTypeObject defdict_type; /* Forward */
1963 
1964 PyDoc_STRVAR(defdict_missing_doc,
1965 "__missing__(key) # Called by __getitem__ for missing key; pseudo-code:\n\
1966   if self.default_factory is None: raise KeyError((key,))\n\
1967   self[key] = value = self.default_factory()\n\
1968   return value\n\
1969 ");
1970 
1971 static PyObject *
defdict_missing(defdictobject * dd,PyObject * key)1972 defdict_missing(defdictobject *dd, PyObject *key)
1973 {
1974     PyObject *factory = dd->default_factory;
1975     PyObject *value;
1976     if (factory == NULL || factory == Py_None) {
1977         /* XXX Call dict.__missing__(key) */
1978         PyObject *tup;
1979         tup = PyTuple_Pack(1, key);
1980         if (!tup) return NULL;
1981         PyErr_SetObject(PyExc_KeyError, tup);
1982         Py_DECREF(tup);
1983         return NULL;
1984     }
1985     value = _PyObject_CallNoArg(factory);
1986     if (value == NULL)
1987         return value;
1988     if (PyObject_SetItem((PyObject *)dd, key, value) < 0) {
1989         Py_DECREF(value);
1990         return NULL;
1991     }
1992     return value;
1993 }
1994 
1995 static inline PyObject*
new_defdict(defdictobject * dd,PyObject * arg)1996 new_defdict(defdictobject *dd, PyObject *arg)
1997 {
1998     return PyObject_CallFunctionObjArgs((PyObject*)Py_TYPE(dd),
1999         dd->default_factory ? dd->default_factory : Py_None, arg, NULL);
2000 }
2001 
2002 PyDoc_STRVAR(defdict_copy_doc, "D.copy() -> a shallow copy of D.");
2003 
2004 static PyObject *
defdict_copy(defdictobject * dd,PyObject * Py_UNUSED (ignored))2005 defdict_copy(defdictobject *dd, PyObject *Py_UNUSED(ignored))
2006 {
2007     /* This calls the object's class.  That only works for subclasses
2008        whose class constructor has the same signature.  Subclasses that
2009        define a different constructor signature must override copy().
2010     */
2011     return new_defdict(dd, (PyObject*)dd);
2012 }
2013 
2014 static PyObject *
defdict_reduce(defdictobject * dd,PyObject * Py_UNUSED (ignored))2015 defdict_reduce(defdictobject *dd, PyObject *Py_UNUSED(ignored))
2016 {
2017     /* __reduce__ must return a 5-tuple as follows:
2018 
2019        - factory function
2020        - tuple of args for the factory function
2021        - additional state (here None)
2022        - sequence iterator (here None)
2023        - dictionary iterator (yielding successive (key, value) pairs
2024 
2025        This API is used by pickle.py and copy.py.
2026 
2027        For this to be useful with pickle.py, the default_factory
2028        must be picklable; e.g., None, a built-in, or a global
2029        function in a module or package.
2030 
2031        Both shallow and deep copying are supported, but for deep
2032        copying, the default_factory must be deep-copyable; e.g. None,
2033        or a built-in (functions are not copyable at this time).
2034 
2035        This only works for subclasses as long as their constructor
2036        signature is compatible; the first argument must be the
2037        optional default_factory, defaulting to None.
2038     */
2039     PyObject *args;
2040     PyObject *items;
2041     PyObject *iter;
2042     PyObject *result;
2043     _Py_IDENTIFIER(items);
2044 
2045     if (dd->default_factory == NULL || dd->default_factory == Py_None)
2046         args = PyTuple_New(0);
2047     else
2048         args = PyTuple_Pack(1, dd->default_factory);
2049     if (args == NULL)
2050         return NULL;
2051     items = _PyObject_CallMethodIdNoArgs((PyObject *)dd, &PyId_items);
2052     if (items == NULL) {
2053         Py_DECREF(args);
2054         return NULL;
2055     }
2056     iter = PyObject_GetIter(items);
2057     if (iter == NULL) {
2058         Py_DECREF(items);
2059         Py_DECREF(args);
2060         return NULL;
2061     }
2062     result = PyTuple_Pack(5, Py_TYPE(dd), args,
2063                           Py_None, Py_None, iter);
2064     Py_DECREF(iter);
2065     Py_DECREF(items);
2066     Py_DECREF(args);
2067     return result;
2068 }
2069 
2070 static PyMethodDef defdict_methods[] = {
2071     {"__missing__", (PyCFunction)defdict_missing, METH_O,
2072      defdict_missing_doc},
2073     {"copy", (PyCFunction)defdict_copy, METH_NOARGS,
2074      defdict_copy_doc},
2075     {"__copy__", (PyCFunction)defdict_copy, METH_NOARGS,
2076      defdict_copy_doc},
2077     {"__reduce__", (PyCFunction)defdict_reduce, METH_NOARGS,
2078      reduce_doc},
2079     {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS,
2080      PyDoc_STR("See PEP 585")},
2081     {NULL}
2082 };
2083 
2084 static PyMemberDef defdict_members[] = {
2085     {"default_factory", T_OBJECT,
2086      offsetof(defdictobject, default_factory), 0,
2087      PyDoc_STR("Factory for default value called by __missing__().")},
2088     {NULL}
2089 };
2090 
2091 static void
defdict_dealloc(defdictobject * dd)2092 defdict_dealloc(defdictobject *dd)
2093 {
2094     /* bpo-31095: UnTrack is needed before calling any callbacks */
2095     PyObject_GC_UnTrack(dd);
2096     Py_CLEAR(dd->default_factory);
2097     PyDict_Type.tp_dealloc((PyObject *)dd);
2098 }
2099 
2100 static PyObject *
defdict_repr(defdictobject * dd)2101 defdict_repr(defdictobject *dd)
2102 {
2103     PyObject *baserepr;
2104     PyObject *defrepr;
2105     PyObject *result;
2106     baserepr = PyDict_Type.tp_repr((PyObject *)dd);
2107     if (baserepr == NULL)
2108         return NULL;
2109     if (dd->default_factory == NULL)
2110         defrepr = PyUnicode_FromString("None");
2111     else
2112     {
2113         int status = Py_ReprEnter(dd->default_factory);
2114         if (status != 0) {
2115             if (status < 0) {
2116                 Py_DECREF(baserepr);
2117                 return NULL;
2118             }
2119             defrepr = PyUnicode_FromString("...");
2120         }
2121         else
2122             defrepr = PyObject_Repr(dd->default_factory);
2123         Py_ReprLeave(dd->default_factory);
2124     }
2125     if (defrepr == NULL) {
2126         Py_DECREF(baserepr);
2127         return NULL;
2128     }
2129     result = PyUnicode_FromFormat("%s(%U, %U)",
2130                                   _PyType_Name(Py_TYPE(dd)),
2131                                   defrepr, baserepr);
2132     Py_DECREF(defrepr);
2133     Py_DECREF(baserepr);
2134     return result;
2135 }
2136 
2137 static PyObject*
defdict_or(PyObject * left,PyObject * right)2138 defdict_or(PyObject* left, PyObject* right)
2139 {
2140     PyObject *self, *other;
2141     if (PyObject_TypeCheck(left, &defdict_type)) {
2142         self = left;
2143         other = right;
2144     }
2145     else {
2146         self = right;
2147         other = left;
2148     }
2149     if (!PyDict_Check(other)) {
2150         Py_RETURN_NOTIMPLEMENTED;
2151     }
2152     // Like copy(), this calls the object's class.
2153     // Override __or__/__ror__ for subclasses with different constructors.
2154     PyObject *new = new_defdict((defdictobject*)self, left);
2155     if (!new) {
2156         return NULL;
2157     }
2158     if (PyDict_Update(new, right)) {
2159         Py_DECREF(new);
2160         return NULL;
2161     }
2162     return new;
2163 }
2164 
2165 static PyNumberMethods defdict_as_number = {
2166     .nb_or = defdict_or,
2167 };
2168 
2169 static int
defdict_traverse(PyObject * self,visitproc visit,void * arg)2170 defdict_traverse(PyObject *self, visitproc visit, void *arg)
2171 {
2172     Py_VISIT(((defdictobject *)self)->default_factory);
2173     return PyDict_Type.tp_traverse(self, visit, arg);
2174 }
2175 
2176 static int
defdict_tp_clear(defdictobject * dd)2177 defdict_tp_clear(defdictobject *dd)
2178 {
2179     Py_CLEAR(dd->default_factory);
2180     return PyDict_Type.tp_clear((PyObject *)dd);
2181 }
2182 
2183 static int
defdict_init(PyObject * self,PyObject * args,PyObject * kwds)2184 defdict_init(PyObject *self, PyObject *args, PyObject *kwds)
2185 {
2186     defdictobject *dd = (defdictobject *)self;
2187     PyObject *olddefault = dd->default_factory;
2188     PyObject *newdefault = NULL;
2189     PyObject *newargs;
2190     int result;
2191     if (args == NULL || !PyTuple_Check(args))
2192         newargs = PyTuple_New(0);
2193     else {
2194         Py_ssize_t n = PyTuple_GET_SIZE(args);
2195         if (n > 0) {
2196             newdefault = PyTuple_GET_ITEM(args, 0);
2197             if (!PyCallable_Check(newdefault) && newdefault != Py_None) {
2198                 PyErr_SetString(PyExc_TypeError,
2199                     "first argument must be callable or None");
2200                 return -1;
2201             }
2202         }
2203         newargs = PySequence_GetSlice(args, 1, n);
2204     }
2205     if (newargs == NULL)
2206         return -1;
2207     Py_XINCREF(newdefault);
2208     dd->default_factory = newdefault;
2209     result = PyDict_Type.tp_init(self, newargs, kwds);
2210     Py_DECREF(newargs);
2211     Py_XDECREF(olddefault);
2212     return result;
2213 }
2214 
2215 PyDoc_STRVAR(defdict_doc,
2216 "defaultdict(default_factory[, ...]) --> dict with default factory\n\
2217 \n\
2218 The default factory is called without arguments to produce\n\
2219 a new value when a key is not present, in __getitem__ only.\n\
2220 A defaultdict compares equal to a dict with the same items.\n\
2221 All remaining arguments are treated the same as if they were\n\
2222 passed to the dict constructor, including keyword arguments.\n\
2223 ");
2224 
2225 /* See comment in xxsubtype.c */
2226 #define DEFERRED_ADDRESS(ADDR) 0
2227 
2228 static PyTypeObject defdict_type = {
2229     PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
2230     "collections.defaultdict",          /* tp_name */
2231     sizeof(defdictobject),              /* tp_basicsize */
2232     0,                                  /* tp_itemsize */
2233     /* methods */
2234     (destructor)defdict_dealloc,        /* tp_dealloc */
2235     0,                                  /* tp_vectorcall_offset */
2236     0,                                  /* tp_getattr */
2237     0,                                  /* tp_setattr */
2238     0,                                  /* tp_as_async */
2239     (reprfunc)defdict_repr,             /* tp_repr */
2240     &defdict_as_number,                 /* tp_as_number */
2241     0,                                  /* tp_as_sequence */
2242     0,                                  /* tp_as_mapping */
2243     0,                                  /* tp_hash */
2244     0,                                  /* tp_call */
2245     0,                                  /* tp_str */
2246     PyObject_GenericGetAttr,            /* tp_getattro */
2247     0,                                  /* tp_setattro */
2248     0,                                  /* tp_as_buffer */
2249     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
2250                                     /* tp_flags */
2251     defdict_doc,                        /* tp_doc */
2252     defdict_traverse,                   /* tp_traverse */
2253     (inquiry)defdict_tp_clear,          /* tp_clear */
2254     0,                                  /* tp_richcompare */
2255     0,                                  /* tp_weaklistoffset*/
2256     0,                                  /* tp_iter */
2257     0,                                  /* tp_iternext */
2258     defdict_methods,                    /* tp_methods */
2259     defdict_members,                    /* tp_members */
2260     0,                                  /* tp_getset */
2261     DEFERRED_ADDRESS(&PyDict_Type),     /* tp_base */
2262     0,                                  /* tp_dict */
2263     0,                                  /* tp_descr_get */
2264     0,                                  /* tp_descr_set */
2265     0,                                  /* tp_dictoffset */
2266     defdict_init,                       /* tp_init */
2267     PyType_GenericAlloc,                /* tp_alloc */
2268     0,                                  /* tp_new */
2269     PyObject_GC_Del,                    /* tp_free */
2270 };
2271 
2272 /* helper function for Counter  *********************************************/
2273 
2274 /*[clinic input]
2275 _collections._count_elements
2276 
2277     mapping: object
2278     iterable: object
2279     /
2280 
2281 Count elements in the iterable, updating the mapping
2282 [clinic start generated code]*/
2283 
2284 static PyObject *
_collections__count_elements_impl(PyObject * module,PyObject * mapping,PyObject * iterable)2285 _collections__count_elements_impl(PyObject *module, PyObject *mapping,
2286                                   PyObject *iterable)
2287 /*[clinic end generated code: output=7e0c1789636b3d8f input=e79fad04534a0b45]*/
2288 {
2289     _Py_IDENTIFIER(get);
2290     _Py_IDENTIFIER(__setitem__);
2291     PyObject *it, *oldval;
2292     PyObject *newval = NULL;
2293     PyObject *key = NULL;
2294     PyObject *bound_get = NULL;
2295     PyObject *mapping_get;
2296     PyObject *dict_get;
2297     PyObject *mapping_setitem;
2298     PyObject *dict_setitem;
2299 
2300     it = PyObject_GetIter(iterable);
2301     if (it == NULL)
2302         return NULL;
2303 
2304     /* Only take the fast path when get() and __setitem__()
2305      * have not been overridden.
2306      */
2307     mapping_get = _PyType_LookupId(Py_TYPE(mapping), &PyId_get);
2308     dict_get = _PyType_LookupId(&PyDict_Type, &PyId_get);
2309     mapping_setitem = _PyType_LookupId(Py_TYPE(mapping), &PyId___setitem__);
2310     dict_setitem = _PyType_LookupId(&PyDict_Type, &PyId___setitem__);
2311 
2312     if (mapping_get != NULL && mapping_get == dict_get &&
2313         mapping_setitem != NULL && mapping_setitem == dict_setitem &&
2314         PyDict_Check(mapping))
2315     {
2316         while (1) {
2317             /* Fast path advantages:
2318                    1. Eliminate double hashing
2319                       (by re-using the same hash for both the get and set)
2320                    2. Avoid argument overhead of PyObject_CallFunctionObjArgs
2321                       (argument tuple creation and parsing)
2322                    3. Avoid indirection through a bound method object
2323                       (creates another argument tuple)
2324                    4. Avoid initial increment from zero
2325                       (reuse an existing one-object instead)
2326             */
2327             Py_hash_t hash;
2328 
2329             key = PyIter_Next(it);
2330             if (key == NULL)
2331                 break;
2332 
2333             if (!PyUnicode_CheckExact(key) ||
2334                 (hash = ((PyASCIIObject *) key)->hash) == -1)
2335             {
2336                 hash = PyObject_Hash(key);
2337                 if (hash == -1)
2338                     goto done;
2339             }
2340 
2341             oldval = _PyDict_GetItem_KnownHash(mapping, key, hash);
2342             if (oldval == NULL) {
2343                 if (PyErr_Occurred())
2344                     goto done;
2345                 if (_PyDict_SetItem_KnownHash(mapping, key, _PyLong_One, hash) < 0)
2346                     goto done;
2347             } else {
2348                 newval = PyNumber_Add(oldval, _PyLong_One);
2349                 if (newval == NULL)
2350                     goto done;
2351                 if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) < 0)
2352                     goto done;
2353                 Py_CLEAR(newval);
2354             }
2355             Py_DECREF(key);
2356         }
2357     } else {
2358         bound_get = _PyObject_GetAttrId(mapping, &PyId_get);
2359         if (bound_get == NULL)
2360             goto done;
2361 
2362         while (1) {
2363             key = PyIter_Next(it);
2364             if (key == NULL)
2365                 break;
2366             oldval = PyObject_CallFunctionObjArgs(bound_get, key, _PyLong_Zero, NULL);
2367             if (oldval == NULL)
2368                 break;
2369             newval = PyNumber_Add(oldval, _PyLong_One);
2370             Py_DECREF(oldval);
2371             if (newval == NULL)
2372                 break;
2373             if (PyObject_SetItem(mapping, key, newval) < 0)
2374                 break;
2375             Py_CLEAR(newval);
2376             Py_DECREF(key);
2377         }
2378     }
2379 
2380 done:
2381     Py_DECREF(it);
2382     Py_XDECREF(key);
2383     Py_XDECREF(newval);
2384     Py_XDECREF(bound_get);
2385     if (PyErr_Occurred())
2386         return NULL;
2387     Py_RETURN_NONE;
2388 }
2389 
2390 /* Helper function for namedtuple() ************************************/
2391 
2392 typedef struct {
2393     PyObject_HEAD
2394     Py_ssize_t index;
2395     PyObject* doc;
2396 } _tuplegetterobject;
2397 
2398 /*[clinic input]
2399 @classmethod
2400 _tuplegetter.__new__ as tuplegetter_new
2401 
2402     index: Py_ssize_t
2403     doc: object
2404     /
2405 [clinic start generated code]*/
2406 
2407 static PyObject *
tuplegetter_new_impl(PyTypeObject * type,Py_ssize_t index,PyObject * doc)2408 tuplegetter_new_impl(PyTypeObject *type, Py_ssize_t index, PyObject *doc)
2409 /*[clinic end generated code: output=014be444ad80263f input=87c576a5bdbc0bbb]*/
2410 {
2411     _tuplegetterobject* self;
2412     self = (_tuplegetterobject *)type->tp_alloc(type, 0);
2413     if (self == NULL) {
2414         return NULL;
2415     }
2416     self->index = index;
2417     Py_INCREF(doc);
2418     self->doc = doc;
2419     return (PyObject *)self;
2420 }
2421 
2422 static PyObject *
tuplegetter_descr_get(PyObject * self,PyObject * obj,PyObject * type)2423 tuplegetter_descr_get(PyObject *self, PyObject *obj, PyObject *type)
2424 {
2425     Py_ssize_t index = ((_tuplegetterobject*)self)->index;
2426     PyObject *result;
2427 
2428     if (obj == NULL) {
2429         Py_INCREF(self);
2430         return self;
2431     }
2432     if (!PyTuple_Check(obj)) {
2433         if (obj == Py_None) {
2434             Py_INCREF(self);
2435             return self;
2436         }
2437         PyErr_Format(PyExc_TypeError,
2438                      "descriptor for index '%zd' for tuple subclasses "
2439                      "doesn't apply to '%s' object",
2440                      index,
2441                      Py_TYPE(obj)->tp_name);
2442         return NULL;
2443     }
2444 
2445     if (!valid_index(index, PyTuple_GET_SIZE(obj))) {
2446         PyErr_SetString(PyExc_IndexError, "tuple index out of range");
2447         return NULL;
2448     }
2449 
2450     result = PyTuple_GET_ITEM(obj, index);
2451     Py_INCREF(result);
2452     return result;
2453 }
2454 
2455 static int
tuplegetter_descr_set(PyObject * self,PyObject * obj,PyObject * value)2456 tuplegetter_descr_set(PyObject *self, PyObject *obj, PyObject *value)
2457 {
2458     if (value == NULL) {
2459         PyErr_SetString(PyExc_AttributeError, "can't delete attribute");
2460     } else {
2461         PyErr_SetString(PyExc_AttributeError, "can't set attribute");
2462     }
2463     return -1;
2464 }
2465 
2466 static int
tuplegetter_traverse(PyObject * self,visitproc visit,void * arg)2467 tuplegetter_traverse(PyObject *self, visitproc visit, void *arg)
2468 {
2469     _tuplegetterobject *tuplegetter = (_tuplegetterobject *)self;
2470     Py_VISIT(tuplegetter->doc);
2471     return 0;
2472 }
2473 
2474 static int
tuplegetter_clear(PyObject * self)2475 tuplegetter_clear(PyObject *self)
2476 {
2477     _tuplegetterobject *tuplegetter = (_tuplegetterobject *)self;
2478     Py_CLEAR(tuplegetter->doc);
2479     return 0;
2480 }
2481 
2482 static void
tuplegetter_dealloc(_tuplegetterobject * self)2483 tuplegetter_dealloc(_tuplegetterobject *self)
2484 {
2485     PyObject_GC_UnTrack(self);
2486     tuplegetter_clear((PyObject*)self);
2487     Py_TYPE(self)->tp_free((PyObject*)self);
2488 }
2489 
2490 static PyObject*
tuplegetter_reduce(_tuplegetterobject * self,PyObject * Py_UNUSED (ignored))2491 tuplegetter_reduce(_tuplegetterobject *self, PyObject *Py_UNUSED(ignored))
2492 {
2493     return Py_BuildValue("(O(nO))", (PyObject*) Py_TYPE(self), self->index, self->doc);
2494 }
2495 
2496 static PyObject*
tuplegetter_repr(_tuplegetterobject * self)2497 tuplegetter_repr(_tuplegetterobject *self)
2498 {
2499     return PyUnicode_FromFormat("%s(%zd, %R)",
2500                                 _PyType_Name(Py_TYPE(self)),
2501                                 self->index, self->doc);
2502 }
2503 
2504 
2505 static PyMemberDef tuplegetter_members[] = {
2506     {"__doc__",  T_OBJECT, offsetof(_tuplegetterobject, doc), 0},
2507     {0}
2508 };
2509 
2510 static PyMethodDef tuplegetter_methods[] = {
2511     {"__reduce__", (PyCFunction)tuplegetter_reduce, METH_NOARGS, NULL},
2512     {NULL},
2513 };
2514 
2515 static PyTypeObject tuplegetter_type = {
2516     PyVarObject_HEAD_INIT(NULL, 0)
2517     "_collections._tuplegetter",                /* tp_name */
2518     sizeof(_tuplegetterobject),                 /* tp_basicsize */
2519     0,                                          /* tp_itemsize */
2520     /* methods */
2521     (destructor)tuplegetter_dealloc,            /* tp_dealloc */
2522     0,                                          /* tp_vectorcall_offset */
2523     0,                                          /* tp_getattr */
2524     0,                                          /* tp_setattr */
2525     0,                                          /* tp_as_async */
2526     (reprfunc)tuplegetter_repr,                 /* tp_repr */
2527     0,                                          /* tp_as_number */
2528     0,                                          /* tp_as_sequence */
2529     0,                                          /* tp_as_mapping */
2530     0,                                          /* tp_hash */
2531     0,                                          /* tp_call */
2532     0,                                          /* tp_str */
2533     0,                                          /* tp_getattro */
2534     0,                                          /* tp_setattro */
2535     0,                                          /* tp_as_buffer */
2536     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
2537     0,                                          /* tp_doc */
2538     (traverseproc)tuplegetter_traverse,         /* tp_traverse */
2539     (inquiry)tuplegetter_clear,                 /* tp_clear */
2540     0,                                          /* tp_richcompare */
2541     0,                                          /* tp_weaklistoffset */
2542     0,                                          /* tp_iter */
2543     0,                                          /* tp_iternext */
2544     tuplegetter_methods,                        /* tp_methods */
2545     tuplegetter_members,                        /* tp_members */
2546     0,                                          /* tp_getset */
2547     0,                                          /* tp_base */
2548     0,                                          /* tp_dict */
2549     tuplegetter_descr_get,                      /* tp_descr_get */
2550     tuplegetter_descr_set,                      /* tp_descr_set */
2551     0,                                          /* tp_dictoffset */
2552     0,                                          /* tp_init */
2553     0,                                          /* tp_alloc */
2554     tuplegetter_new,                            /* tp_new */
2555     0,
2556 };
2557 
2558 
2559 /* module level code ********************************************************/
2560 
2561 PyDoc_STRVAR(collections_doc,
2562 "High performance data structures.\n\
2563 - deque:        ordered collection accessible from endpoints only\n\
2564 - defaultdict:  dict subclass with a default value factory\n\
2565 ");
2566 
2567 static struct PyMethodDef collections_methods[] = {
2568     _COLLECTIONS__COUNT_ELEMENTS_METHODDEF
2569     {NULL,       NULL}          /* sentinel */
2570 };
2571 
2572 static int
collections_exec(PyObject * module)2573 collections_exec(PyObject *module) {
2574     PyTypeObject *typelist[] = {
2575         &deque_type,
2576         &defdict_type,
2577         &PyODict_Type,
2578         &dequeiter_type,
2579         &dequereviter_type,
2580         &tuplegetter_type
2581     };
2582 
2583     defdict_type.tp_base = &PyDict_Type;
2584 
2585     for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) {
2586         if (PyModule_AddType(module, typelist[i]) < 0) {
2587             return -1;
2588         }
2589     }
2590 
2591     return 0;
2592 }
2593 
2594 static struct PyModuleDef_Slot collections_slots[] = {
2595     {Py_mod_exec, collections_exec},
2596     {0, NULL}
2597 };
2598 
2599 static struct PyModuleDef _collectionsmodule = {
2600     PyModuleDef_HEAD_INIT,
2601     "_collections",
2602     collections_doc,
2603     0,
2604     collections_methods,
2605     collections_slots,
2606     NULL,
2607     NULL,
2608     NULL
2609 };
2610 
2611 PyMODINIT_FUNC
PyInit__collections(void)2612 PyInit__collections(void)
2613 {
2614     return PyModuleDef_Init(&_collectionsmodule);
2615 }
2616