blob: 90bafb0ea86d9293b2f654cb40ac36cce7d36507 [file] [log] [blame]
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001#include "Python.h"
Victor Stinner37834132020-10-27 17:12:53 +01002#include "pycore_long.h" // _PyLong_GetZero()
Victor Stinner4a21e572020-04-15 02:35:41 +02003#include "structmember.h" // PyMemberDef
Raymond Hettinger756b3f32004-01-29 06:37:52 +00004
Raymond Hettingerc2083082015-02-28 23:29:16 -08005#ifdef STDC_HEADERS
6#include <stddef.h>
7#else
Victor Stinner4a21e572020-04-15 02:35:41 +02008#include <sys/types.h> // size_t
Raymond Hettingerc2083082015-02-28 23:29:16 -08009#endif
10
Pablo Galindo3f5fc702018-12-30 09:24:03 +000011/*[clinic input]
Raymond Hettingere9858042019-06-05 16:05:25 -070012module _collections
Pablo Galindo3f5fc702018-12-30 09:24:03 +000013class _tuplegetter "_tuplegetterobject *" "&tuplegetter_type"
14[clinic start generated code]*/
Raymond Hettingere9858042019-06-05 16:05:25 -070015/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a8ece4ccad7e30ac]*/
Pablo Galindo3f5fc702018-12-30 09:24:03 +000016
17static PyTypeObject tuplegetter_type;
18#include "clinic/_collectionsmodule.c.h"
19
Raymond Hettinger756b3f32004-01-29 06:37:52 +000020/* collections module implementation of a deque() datatype
21 Written and maintained by Raymond D. Hettinger <python@rcn.com>
Raymond Hettinger756b3f32004-01-29 06:37:52 +000022*/
23
Raymond Hettinger77e8bf12004-10-01 15:25:53 +000024/* The block length may be set to any number over 1. Larger numbers
Raymond Hettinger20b0f872013-06-23 15:44:33 -070025 * reduce the number of calls to the memory allocator, give faster
Raymond Hettinger30c90742015-03-02 22:31:35 -080026 * indexing and rotation, and reduce the link to data overhead ratio.
Raymond Hettingerdaf57f22015-02-26 23:21:29 -080027 * Making the block length a power of two speeds-up the modulo
Raymond Hettinger30c90742015-03-02 22:31:35 -080028 * and division calculations in deque_item() and deque_ass_item().
Raymond Hettinger77e8bf12004-10-01 15:25:53 +000029 */
30
Raymond Hettingerdaf57f22015-02-26 23:21:29 -080031#define BLOCKLEN 64
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000032#define CENTER ((BLOCKLEN - 1) / 2)
Raymond Hettinger756b3f32004-01-29 06:37:52 +000033
Raymond Hettinger551350a2015-03-24 00:19:53 -070034/* Data for deque objects is stored in a doubly-linked list of fixed
35 * length blocks. This assures that appends or pops never move any
36 * other data elements besides the one being appended or popped.
37 *
38 * Another advantage is that it completely avoids use of realloc(),
39 * resulting in more predictable performance.
40 *
41 * Textbook implementations of doubly-linked lists store one datum
42 * per link, but that gives them a 200% memory overhead (a prev and
43 * next link for each datum) and it costs one malloc() call per data
44 * element. By using fixed-length blocks, the link to data ratio is
45 * significantly improved and there are proportionally fewer calls
46 * to malloc() and free(). The data blocks of consecutive pointers
47 * also improve cache locality.
48 *
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000049 * The list of blocks is never empty, so d.leftblock and d.rightblock
Raymond Hettinger82df9252013-07-07 01:43:42 -100050 * are never equal to NULL. The list is not circular.
51 *
52 * A deque d's first element is at d.leftblock[leftindex]
53 * and its last element is at d.rightblock[rightindex].
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000054 *
Raymond Hettinger551350a2015-03-24 00:19:53 -070055 * Unlike Python slice indices, these indices are inclusive on both
56 * ends. This makes the algorithms for left and right operations
57 * more symmetrical and it simplifies the design.
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000058 *
Raymond Hettinger551350a2015-03-24 00:19:53 -070059 * The indices, d.leftindex and d.rightindex are always in the range:
60 * 0 <= index < BLOCKLEN
61 *
62 * And their exact relationship is:
63 * (d.leftindex + d.len - 1) % BLOCKLEN == d.rightindex
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000064 *
Raymond Hettinger8dbbae22015-03-24 21:01:50 -070065 * Whenever d.leftblock == d.rightblock, then:
Raymond Hettinger551350a2015-03-24 00:19:53 -070066 * d.leftindex + d.len - 1 == d.rightindex
Thomas Wouters0e3f5912006-08-11 14:57:12 +000067 *
Raymond Hettinger551350a2015-03-24 00:19:53 -070068 * However, when d.leftblock != d.rightblock, the d.leftindex and
69 * d.rightindex become indices into distinct blocks and either may
70 * be larger than the other.
71 *
72 * Empty deques have:
73 * d.len == 0
74 * d.leftblock == d.rightblock
75 * d.leftindex == CENTER + 1
76 * d.rightindex == CENTER
77 *
78 * Checking for d.len == 0 is the intended way to see whether d is empty.
Tim Petersd8768d32004-10-01 01:32:53 +000079 */
80
Raymond Hettinger756b3f32004-01-29 06:37:52 +000081typedef struct BLOCK {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000082 struct BLOCK *leftlink;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 PyObject *data[BLOCKLEN];
Raymond Hettinger20b0f872013-06-23 15:44:33 -070084 struct BLOCK *rightlink;
Raymond Hettinger756b3f32004-01-29 06:37:52 +000085} block;
86
Raymond Hettinger30c90742015-03-02 22:31:35 -080087typedef struct {
88 PyObject_VAR_HEAD
89 block *leftblock;
90 block *rightblock;
Raymond Hettinger551350a2015-03-24 00:19:53 -070091 Py_ssize_t leftindex; /* 0 <= leftindex < BLOCKLEN */
92 Py_ssize_t rightindex; /* 0 <= rightindex < BLOCKLEN */
Raymond Hettingerf9d9c792015-03-02 22:47:46 -080093 size_t state; /* incremented whenever the indices move */
Raymond Hettingerd84ec222016-01-24 09:12:06 -080094 Py_ssize_t maxlen; /* maxlen is -1 for unbounded deques */
Raymond Hettinger0f6f9472015-03-21 01:42:10 -070095 PyObject *weakreflist;
Raymond Hettinger30c90742015-03-02 22:31:35 -080096} dequeobject;
97
98static PyTypeObject deque_type;
99
Raymond Hettinger82df9252013-07-07 01:43:42 -1000100/* For debug builds, add error checking to track the endpoints
101 * in the chain of links. The goal is to make sure that link
102 * assignments only take place at endpoints so that links already
103 * in use do not get overwritten.
104 *
105 * CHECK_END should happen before each assignment to a block's link field.
106 * MARK_END should happen whenever a link field becomes a new endpoint.
107 * This happens when new blocks are added or whenever an existing
108 * block is freed leaving another existing block as the new endpoint.
109 */
110
Raymond Hettinger3223dd52013-07-26 23:14:22 -0700111#ifndef NDEBUG
Raymond Hettinger82df9252013-07-07 01:43:42 -1000112#define MARK_END(link) link = NULL;
113#define CHECK_END(link) assert(link == NULL);
114#define CHECK_NOT_END(link) assert(link != NULL);
115#else
116#define MARK_END(link)
117#define CHECK_END(link)
118#define CHECK_NOT_END(link)
119#endif
120
Tim Peters6f853562004-10-01 01:04:50 +0000121static block *
Raymond Hettingerdb41fd42015-10-22 22:48:16 -0700122newblock(void) {
Raymond Hettinger32f2eda2020-06-23 06:50:15 -0700123 block *b = PyMem_Malloc(sizeof(block));
Raymond Hettinger82df9252013-07-07 01:43:42 -1000124 if (b != NULL) {
125 return b;
126 }
127 PyErr_NoMemory();
128 return NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000129}
130
Martin v. Löwis59683e82008-06-13 07:50:45 +0000131static void
Guido van Rossum58da9312007-11-10 23:39:45 +0000132freeblock(block *b)
133{
Raymond Hettinger32f2eda2020-06-23 06:50:15 -0700134 PyMem_Free(b);
Guido van Rossum58da9312007-11-10 23:39:45 +0000135}
136
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000137static PyObject *
138deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
139{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000140 dequeobject *deque;
141 block *b;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000143 /* create dequeobject structure */
144 deque = (dequeobject *)type->tp_alloc(type, 0);
145 if (deque == NULL)
146 return NULL;
Tim Peters1065f752004-10-01 01:03:29 +0000147
Raymond Hettingerdb41fd42015-10-22 22:48:16 -0700148 b = newblock();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 if (b == NULL) {
150 Py_DECREF(deque);
151 return NULL;
152 }
Raymond Hettinger82df9252013-07-07 01:43:42 -1000153 MARK_END(b->leftlink);
154 MARK_END(b->rightlink);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000155
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000156 assert(BLOCKLEN >= 2);
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100157 Py_SET_SIZE(deque, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158 deque->leftblock = b;
159 deque->rightblock = b;
160 deque->leftindex = CENTER + 1;
161 deque->rightindex = CENTER;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 deque->state = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 deque->maxlen = -1;
Raymond Hettinger87e69122015-03-02 23:32:02 -0800164 deque->weakreflist = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000166 return (PyObject *)deque;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000167}
168
169static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000170deque_pop(dequeobject *deque, PyObject *unused)
171{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000172 PyObject *item;
173 block *prevblock;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000174
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000175 if (Py_SIZE(deque) == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
177 return NULL;
178 }
179 item = deque->rightblock->data[deque->rightindex];
180 deque->rightindex--;
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100181 Py_SET_SIZE(deque, Py_SIZE(deque) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182 deque->state++;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000183
Raymond Hettingerd3d2b2c2015-09-21 23:41:56 -0700184 if (deque->rightindex < 0) {
Raymond Hettinger8dbbae22015-03-24 21:01:50 -0700185 if (Py_SIZE(deque)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 prevblock = deque->rightblock->leftlink;
187 assert(deque->leftblock != deque->rightblock);
188 freeblock(deque->rightblock);
Raymond Hettinger82df9252013-07-07 01:43:42 -1000189 CHECK_NOT_END(prevblock);
190 MARK_END(prevblock->rightlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 deque->rightblock = prevblock;
192 deque->rightindex = BLOCKLEN - 1;
Raymond Hettinger8dbbae22015-03-24 21:01:50 -0700193 } else {
194 assert(deque->leftblock == deque->rightblock);
195 assert(deque->leftindex == deque->rightindex+1);
196 /* re-center instead of freeing a block */
197 deque->leftindex = CENTER + 1;
198 deque->rightindex = CENTER;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 }
200 }
201 return item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000202}
203
204PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
205
206static PyObject *
207deque_popleft(dequeobject *deque, PyObject *unused)
208{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 PyObject *item;
210 block *prevblock;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000211
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000212 if (Py_SIZE(deque) == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
214 return NULL;
215 }
216 assert(deque->leftblock != NULL);
217 item = deque->leftblock->data[deque->leftindex];
218 deque->leftindex++;
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100219 Py_SET_SIZE(deque, Py_SIZE(deque) - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 deque->state++;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 if (deque->leftindex == BLOCKLEN) {
Raymond Hettinger8dbbae22015-03-24 21:01:50 -0700223 if (Py_SIZE(deque)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 assert(deque->leftblock != deque->rightblock);
225 prevblock = deque->leftblock->rightlink;
226 freeblock(deque->leftblock);
Raymond Hettinger82df9252013-07-07 01:43:42 -1000227 CHECK_NOT_END(prevblock);
228 MARK_END(prevblock->leftlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 deque->leftblock = prevblock;
230 deque->leftindex = 0;
Raymond Hettinger8dbbae22015-03-24 21:01:50 -0700231 } else {
232 assert(deque->leftblock == deque->rightblock);
233 assert(deque->leftindex == deque->rightindex+1);
234 /* re-center instead of freeing a block */
235 deque->leftindex = CENTER + 1;
236 deque->rightindex = CENTER;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 }
238 }
239 return item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000240}
241
242PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
243
Raymond Hettingerf30f5b92015-03-02 22:23:37 -0800244/* The deque's size limit is d.maxlen. The limit can be zero or positive.
245 * If there is no limit, then d.maxlen == -1.
246 *
Raymond Hettingera4b13d02015-10-15 08:05:31 -0700247 * After an item is added to a deque, we check to see if the size has
248 * grown past the limit. If it has, we get the size back down to the limit
249 * by popping an item off of the opposite end. The methods that can
250 * trigger this are append(), appendleft(), extend(), and extendleft().
Raymond Hettingerd96db092015-10-11 22:34:48 -0700251 *
252 * The macro to check whether a deque needs to be trimmed uses a single
253 * unsigned test that returns true whenever 0 <= maxlen < Py_SIZE(deque).
Raymond Hettingerf30f5b92015-03-02 22:23:37 -0800254 */
255
Raymond Hettingerd96db092015-10-11 22:34:48 -0700256#define NEEDS_TRIM(deque, maxlen) ((size_t)(maxlen) < (size_t)(Py_SIZE(deque)))
Raymond Hettingerf30f5b92015-03-02 22:23:37 -0800257
Raymond Hettinger66953f02018-07-10 04:17:40 -0700258static inline int
Raymond Hettingerd84ec222016-01-24 09:12:06 -0800259deque_append_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000260{
Raymond Hettinger8dbbae22015-03-24 21:01:50 -0700261 if (deque->rightindex == BLOCKLEN - 1) {
Raymond Hettingerdb41fd42015-10-22 22:48:16 -0700262 block *b = newblock();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 if (b == NULL)
Raymond Hettingerd84ec222016-01-24 09:12:06 -0800264 return -1;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000265 b->leftlink = deque->rightblock;
266 CHECK_END(deque->rightblock->rightlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 deque->rightblock->rightlink = b;
268 deque->rightblock = b;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000269 MARK_END(b->rightlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 deque->rightindex = -1;
271 }
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100272 Py_SET_SIZE(deque, Py_SIZE(deque) + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 deque->rightindex++;
274 deque->rightblock->data[deque->rightindex] = item;
Raymond Hettingerd84ec222016-01-24 09:12:06 -0800275 if (NEEDS_TRIM(deque, maxlen)) {
Raymond Hettinger1286d142015-10-14 23:16:57 -0700276 PyObject *olditem = deque_popleft(deque, NULL);
277 Py_DECREF(olditem);
Raymond Hettinger0f43bb12015-10-20 00:03:33 -0700278 } else {
279 deque->state++;
Raymond Hettingerd96db092015-10-11 22:34:48 -0700280 }
Raymond Hettingerd84ec222016-01-24 09:12:06 -0800281 return 0;
282}
283
284static PyObject *
285deque_append(dequeobject *deque, PyObject *item)
286{
287 Py_INCREF(item);
288 if (deque_append_internal(deque, item, deque->maxlen) < 0)
289 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 Py_RETURN_NONE;
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000291}
292
293PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
294
Raymond Hettinger66953f02018-07-10 04:17:40 -0700295static inline int
Raymond Hettingerd84ec222016-01-24 09:12:06 -0800296deque_appendleft_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000297{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000298 if (deque->leftindex == 0) {
Raymond Hettingerdb41fd42015-10-22 22:48:16 -0700299 block *b = newblock();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 if (b == NULL)
Raymond Hettingerd84ec222016-01-24 09:12:06 -0800301 return -1;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000302 b->rightlink = deque->leftblock;
303 CHECK_END(deque->leftblock->leftlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 deque->leftblock->leftlink = b;
305 deque->leftblock = b;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000306 MARK_END(b->leftlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 deque->leftindex = BLOCKLEN;
308 }
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100309 Py_SET_SIZE(deque, Py_SIZE(deque) + 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 deque->leftindex--;
311 deque->leftblock->data[deque->leftindex] = item;
Raymond Hettingerd96db092015-10-11 22:34:48 -0700312 if (NEEDS_TRIM(deque, deque->maxlen)) {
Raymond Hettinger1286d142015-10-14 23:16:57 -0700313 PyObject *olditem = deque_pop(deque, NULL);
314 Py_DECREF(olditem);
Raymond Hettinger0f43bb12015-10-20 00:03:33 -0700315 } else {
316 deque->state++;
Raymond Hettingerd96db092015-10-11 22:34:48 -0700317 }
Raymond Hettingerd84ec222016-01-24 09:12:06 -0800318 return 0;
319}
320
321static PyObject *
322deque_appendleft(dequeobject *deque, PyObject *item)
323{
324 Py_INCREF(item);
325 if (deque_appendleft_internal(deque, item, deque->maxlen) < 0)
326 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327 Py_RETURN_NONE;
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000328}
329
330PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
331
Raymond Hettingerfd265f42015-10-02 23:17:33 -0700332static PyObject*
333finalize_iterator(PyObject *it)
334{
335 if (PyErr_Occurred()) {
336 if (PyErr_ExceptionMatches(PyExc_StopIteration))
337 PyErr_Clear();
338 else {
339 Py_DECREF(it);
340 return NULL;
341 }
342 }
343 Py_DECREF(it);
344 Py_RETURN_NONE;
345}
Raymond Hettinger060c7f62009-03-10 09:36:07 +0000346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347/* Run an iterator to exhaustion. Shortcut for
Raymond Hettinger060c7f62009-03-10 09:36:07 +0000348 the extend/extendleft methods when maxlen == 0. */
349static PyObject*
350consume_iterator(PyObject *it)
351{
Raymond Hettingerfd265f42015-10-02 23:17:33 -0700352 PyObject *(*iternext)(PyObject *);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 PyObject *item;
Raymond Hettinger060c7f62009-03-10 09:36:07 +0000354
Raymond Hettingerfd265f42015-10-02 23:17:33 -0700355 iternext = *Py_TYPE(it)->tp_iternext;
356 while ((item = iternext(it)) != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 Py_DECREF(item);
358 }
Raymond Hettingerfd265f42015-10-02 23:17:33 -0700359 return finalize_iterator(it);
Raymond Hettinger060c7f62009-03-10 09:36:07 +0000360}
361
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000362static PyObject *
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000363deque_extend(dequeobject *deque, PyObject *iterable)
364{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000365 PyObject *it, *item;
Raymond Hettinger7a845522015-09-26 01:30:51 -0700366 PyObject *(*iternext)(PyObject *);
Raymond Hettinger6b1e1132015-10-11 09:43:50 -0700367 Py_ssize_t maxlen = deque->maxlen;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 /* Handle case where id(deque) == id(iterable) */
370 if ((PyObject *)deque == iterable) {
371 PyObject *result;
372 PyObject *s = PySequence_List(iterable);
373 if (s == NULL)
374 return NULL;
375 result = deque_extend(deque, s);
376 Py_DECREF(s);
377 return result;
378 }
Raymond Hettinger3f9afd82009-12-10 03:03:02 +0000379
Raymond Hettingerd79d5b12016-03-04 09:55:07 -0800380 it = PyObject_GetIter(iterable);
381 if (it == NULL)
382 return NULL;
383
384 if (maxlen == 0)
385 return consume_iterator(it);
386
Raymond Hettingerd9c116c2013-07-09 00:13:21 -0700387 /* Space saving heuristic. Start filling from the left */
388 if (Py_SIZE(deque) == 0) {
389 assert(deque->leftblock == deque->rightblock);
390 assert(deque->leftindex == deque->rightindex+1);
391 deque->leftindex = 1;
392 deque->rightindex = 0;
393 }
394
Raymond Hettinger7a845522015-09-26 01:30:51 -0700395 iternext = *Py_TYPE(it)->tp_iternext;
396 while ((item = iternext(it)) != NULL) {
Raymond Hettinger66953f02018-07-10 04:17:40 -0700397 if (deque_append_internal(deque, item, maxlen) == -1) {
398 Py_DECREF(item);
399 Py_DECREF(it);
400 return NULL;
Raymond Hettinger6b1e1132015-10-11 09:43:50 -0700401 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 }
Raymond Hettingerfd265f42015-10-02 23:17:33 -0700403 return finalize_iterator(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000404}
405
Tim Peters1065f752004-10-01 01:03:29 +0000406PyDoc_STRVAR(extend_doc,
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000407"Extend the right side of the deque with elements from the iterable");
408
409static PyObject *
410deque_extendleft(dequeobject *deque, PyObject *iterable)
411{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 PyObject *it, *item;
Raymond Hettinger7a845522015-09-26 01:30:51 -0700413 PyObject *(*iternext)(PyObject *);
Raymond Hettinger6b1e1132015-10-11 09:43:50 -0700414 Py_ssize_t maxlen = deque->maxlen;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 /* Handle case where id(deque) == id(iterable) */
417 if ((PyObject *)deque == iterable) {
418 PyObject *result;
419 PyObject *s = PySequence_List(iterable);
420 if (s == NULL)
421 return NULL;
422 result = deque_extendleft(deque, s);
423 Py_DECREF(s);
424 return result;
425 }
Raymond Hettinger3f9afd82009-12-10 03:03:02 +0000426
Raymond Hettingerd79d5b12016-03-04 09:55:07 -0800427 it = PyObject_GetIter(iterable);
428 if (it == NULL)
429 return NULL;
430
431 if (maxlen == 0)
432 return consume_iterator(it);
433
Raymond Hettingerd9c116c2013-07-09 00:13:21 -0700434 /* Space saving heuristic. Start filling from the right */
435 if (Py_SIZE(deque) == 0) {
436 assert(deque->leftblock == deque->rightblock);
437 assert(deque->leftindex == deque->rightindex+1);
438 deque->leftindex = BLOCKLEN - 1;
439 deque->rightindex = BLOCKLEN - 2;
440 }
441
Raymond Hettinger7a845522015-09-26 01:30:51 -0700442 iternext = *Py_TYPE(it)->tp_iternext;
443 while ((item = iternext(it)) != NULL) {
Raymond Hettinger66953f02018-07-10 04:17:40 -0700444 if (deque_appendleft_internal(deque, item, maxlen) == -1) {
445 Py_DECREF(item);
446 Py_DECREF(it);
447 return NULL;
Raymond Hettinger6b1e1132015-10-11 09:43:50 -0700448 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 }
Raymond Hettingerfd265f42015-10-02 23:17:33 -0700450 return finalize_iterator(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000451}
452
Tim Peters1065f752004-10-01 01:03:29 +0000453PyDoc_STRVAR(extendleft_doc,
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000454"Extend the left side of the deque with elements from the iterable");
455
Raymond Hettinger3f9afd82009-12-10 03:03:02 +0000456static PyObject *
457deque_inplace_concat(dequeobject *deque, PyObject *other)
458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 PyObject *result;
Raymond Hettinger3f9afd82009-12-10 03:03:02 +0000460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 result = deque_extend(deque, other);
462 if (result == NULL)
463 return result;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 Py_INCREF(deque);
Raymond Hettinger2b2b7532015-09-05 17:05:52 -0700465 Py_DECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 return (PyObject *)deque;
Raymond Hettinger3f9afd82009-12-10 03:03:02 +0000467}
468
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700469static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530470deque_copy(PyObject *deque, PyObject *Py_UNUSED(ignored))
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700471{
Oren Milman24bd50b2018-09-11 21:46:55 +0300472 PyObject *result;
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700473 dequeobject *old_deque = (dequeobject *)deque;
Andy Lesterdffe4c02020-03-04 07:15:20 -0600474 if (Py_IS_TYPE(deque, &deque_type)) {
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700475 dequeobject *new_deque;
476 PyObject *rv;
477
478 new_deque = (dequeobject *)deque_new(&deque_type, (PyObject *)NULL, (PyObject *)NULL);
479 if (new_deque == NULL)
480 return NULL;
481 new_deque->maxlen = old_deque->maxlen;
482 /* Fast path for the deque_repeat() common case where len(deque) == 1 */
Raymond Hettinger0443ac22015-10-05 22:52:37 -0400483 if (Py_SIZE(deque) == 1) {
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700484 PyObject *item = old_deque->leftblock->data[old_deque->leftindex];
485 rv = deque_append(new_deque, item);
486 } else {
487 rv = deque_extend(new_deque, deque);
488 }
489 if (rv != NULL) {
490 Py_DECREF(rv);
491 return (PyObject *)new_deque;
492 }
493 Py_DECREF(new_deque);
494 return NULL;
495 }
496 if (old_deque->maxlen < 0)
Petr Viktorinffd97532020-02-11 17:46:57 +0100497 result = PyObject_CallOneArg((PyObject *)(Py_TYPE(deque)), deque);
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700498 else
Oren Milman24bd50b2018-09-11 21:46:55 +0300499 result = PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi",
500 deque, old_deque->maxlen, NULL);
501 if (result != NULL && !PyObject_TypeCheck(result, &deque_type)) {
502 PyErr_Format(PyExc_TypeError,
503 "%.200s() must return a deque, not %.200s",
504 Py_TYPE(deque)->tp_name, Py_TYPE(result)->tp_name);
505 Py_DECREF(result);
506 return NULL;
507 }
508 return result;
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700509}
510
511PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
Raymond Hettinger41290a62015-03-31 08:12:23 -0700512
513static PyObject *
514deque_concat(dequeobject *deque, PyObject *other)
515{
Benjamin Peterson1a629212015-04-04 10:52:36 -0400516 PyObject *new_deque, *result;
Raymond Hettinger41290a62015-03-31 08:12:23 -0700517 int rv;
518
519 rv = PyObject_IsInstance(other, (PyObject *)&deque_type);
520 if (rv <= 0) {
521 if (rv == 0) {
522 PyErr_Format(PyExc_TypeError,
523 "can only concatenate deque (not \"%.200s\") to deque",
Victor Stinnerdaa97562020-02-07 03:37:06 +0100524 Py_TYPE(other)->tp_name);
Raymond Hettinger41290a62015-03-31 08:12:23 -0700525 }
526 return NULL;
527 }
528
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530529 new_deque = deque_copy((PyObject *)deque, NULL);
Raymond Hettinger41290a62015-03-31 08:12:23 -0700530 if (new_deque == NULL)
531 return NULL;
Benjamin Peterson1a629212015-04-04 10:52:36 -0400532 result = deque_extend((dequeobject *)new_deque, other);
533 if (result == NULL) {
534 Py_DECREF(new_deque);
535 return NULL;
536 }
537 Py_DECREF(result);
538 return new_deque;
Raymond Hettinger41290a62015-03-31 08:12:23 -0700539}
540
Serhiy Storchakaa5c42282018-05-31 07:34:34 +0300541static int
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700542deque_clear(dequeobject *deque)
543{
544 block *b;
545 block *prevblock;
546 block *leftblock;
547 Py_ssize_t leftindex;
Raymond Hettingerd84ec222016-01-24 09:12:06 -0800548 Py_ssize_t n, m;
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700549 PyObject *item;
Raymond Hettingerd84ec222016-01-24 09:12:06 -0800550 PyObject **itemptr, **limit;
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700551
Raymond Hettinger38031142015-09-29 22:45:05 -0700552 if (Py_SIZE(deque) == 0)
Serhiy Storchakaa5c42282018-05-31 07:34:34 +0300553 return 0;
Raymond Hettinger38031142015-09-29 22:45:05 -0700554
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700555 /* During the process of clearing a deque, decrefs can cause the
556 deque to mutate. To avoid fatal confusion, we have to make the
557 deque empty before clearing the blocks and never refer to
558 anything via deque->ref while clearing. (This is the same
559 technique used for clearing lists, sets, and dicts.)
560
561 Making the deque empty requires allocating a new empty block. In
562 the unlikely event that memory is full, we fall back to an
563 alternate method that doesn't require a new block. Repeating
564 pops in a while-loop is slower, possibly re-entrant (and a clever
565 adversary could cause it to never terminate).
566 */
567
Raymond Hettingerdb41fd42015-10-22 22:48:16 -0700568 b = newblock();
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700569 if (b == NULL) {
570 PyErr_Clear();
571 goto alternate_method;
572 }
573
574 /* Remember the old size, leftblock, and leftindex */
Raymond Hettinger6f86a332016-03-02 00:30:58 -0800575 n = Py_SIZE(deque);
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700576 leftblock = deque->leftblock;
577 leftindex = deque->leftindex;
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700578
579 /* Set the deque to be empty using the newly allocated block */
580 MARK_END(b->leftlink);
581 MARK_END(b->rightlink);
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100582 Py_SET_SIZE(deque, 0);
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700583 deque->leftblock = b;
584 deque->rightblock = b;
585 deque->leftindex = CENTER + 1;
586 deque->rightindex = CENTER;
587 deque->state++;
588
589 /* Now the old size, leftblock, and leftindex are disconnected from
590 the empty deque and we can use them to decref the pointers.
591 */
Raymond Hettingerd84ec222016-01-24 09:12:06 -0800592 m = (BLOCKLEN - leftindex > n) ? n : BLOCKLEN - leftindex;
Raymond Hettinger589106b2016-03-02 00:06:21 -0800593 itemptr = &leftblock->data[leftindex];
Raymond Hettinger6f86a332016-03-02 00:30:58 -0800594 limit = itemptr + m;
Raymond Hettingerd84ec222016-01-24 09:12:06 -0800595 n -= m;
596 while (1) {
597 if (itemptr == limit) {
598 if (n == 0)
599 break;
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700600 CHECK_NOT_END(leftblock->rightlink);
601 prevblock = leftblock;
602 leftblock = leftblock->rightlink;
Raymond Hettingerd84ec222016-01-24 09:12:06 -0800603 m = (n > BLOCKLEN) ? BLOCKLEN : n;
Raymond Hettinger589106b2016-03-02 00:06:21 -0800604 itemptr = leftblock->data;
Raymond Hettinger6f86a332016-03-02 00:30:58 -0800605 limit = itemptr + m;
Raymond Hettingerd84ec222016-01-24 09:12:06 -0800606 n -= m;
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700607 freeblock(prevblock);
608 }
Raymond Hettingerd84ec222016-01-24 09:12:06 -0800609 item = *(itemptr++);
610 Py_DECREF(item);
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700611 }
612 CHECK_END(leftblock->rightlink);
613 freeblock(leftblock);
Serhiy Storchakaa5c42282018-05-31 07:34:34 +0300614 return 0;
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700615
616 alternate_method:
617 while (Py_SIZE(deque)) {
618 item = deque_pop(deque, NULL);
619 assert (item != NULL);
620 Py_DECREF(item);
621 }
Serhiy Storchakaa5c42282018-05-31 07:34:34 +0300622 return 0;
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700623}
624
625static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530626deque_clearmethod(dequeobject *deque, PyObject *Py_UNUSED(ignored))
Raymond Hettinger8299e9b2015-09-26 21:31:23 -0700627{
628 deque_clear(deque);
629 Py_RETURN_NONE;
630}
631
632PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
Raymond Hettinger41290a62015-03-31 08:12:23 -0700633
634static PyObject *
Raymond Hettinger41290a62015-03-31 08:12:23 -0700635deque_inplace_repeat(dequeobject *deque, Py_ssize_t n)
636{
Raymond Hettingerc22eee62015-09-26 02:14:50 -0700637 Py_ssize_t i, m, size;
Raymond Hettinger41290a62015-03-31 08:12:23 -0700638 PyObject *seq;
639 PyObject *rv;
640
641 size = Py_SIZE(deque);
642 if (size == 0 || n == 1) {
643 Py_INCREF(deque);
644 return (PyObject *)deque;
645 }
646
647 if (n <= 0) {
648 deque_clear(deque);
649 Py_INCREF(deque);
650 return (PyObject *)deque;
651 }
652
Raymond Hettinger41290a62015-03-31 08:12:23 -0700653 if (size == 1) {
654 /* common case, repeating a single element */
655 PyObject *item = deque->leftblock->data[deque->leftindex];
656
Raymond Hettingera7f630092015-10-10 23:56:02 -0400657 if (deque->maxlen >= 0 && n > deque->maxlen)
Raymond Hettinger41290a62015-03-31 08:12:23 -0700658 n = deque->maxlen;
659
Raymond Hettinger67c78b52015-09-12 11:00:20 -0400660 deque->state++;
Raymond Hettingerad262252015-09-14 01:03:04 -0400661 for (i = 0 ; i < n-1 ; ) {
Raymond Hettinger67c78b52015-09-12 11:00:20 -0400662 if (deque->rightindex == BLOCKLEN - 1) {
Raymond Hettingerdb41fd42015-10-22 22:48:16 -0700663 block *b = newblock();
Raymond Hettinger67c78b52015-09-12 11:00:20 -0400664 if (b == NULL) {
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100665 Py_SET_SIZE(deque, Py_SIZE(deque) + i);
Raymond Hettinger67c78b52015-09-12 11:00:20 -0400666 return NULL;
667 }
668 b->leftlink = deque->rightblock;
669 CHECK_END(deque->rightblock->rightlink);
670 deque->rightblock->rightlink = b;
671 deque->rightblock = b;
672 MARK_END(b->rightlink);
673 deque->rightindex = -1;
674 }
Raymond Hettingerc22eee62015-09-26 02:14:50 -0700675 m = n - 1 - i;
676 if (m > BLOCKLEN - 1 - deque->rightindex)
677 m = BLOCKLEN - 1 - deque->rightindex;
678 i += m;
679 while (m--) {
Raymond Hettingerad262252015-09-14 01:03:04 -0400680 deque->rightindex++;
681 Py_INCREF(item);
682 deque->rightblock->data[deque->rightindex] = item;
683 }
Raymond Hettinger41290a62015-03-31 08:12:23 -0700684 }
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100685 Py_SET_SIZE(deque, Py_SIZE(deque) + i);
Raymond Hettinger41290a62015-03-31 08:12:23 -0700686 Py_INCREF(deque);
687 return (PyObject *)deque;
688 }
689
Raymond Hettinger20151f52015-10-16 22:47:29 -0700690 if ((size_t)size > PY_SSIZE_T_MAX / (size_t)n) {
Raymond Hettingerf5d72f32015-09-09 22:39:44 -0400691 return PyErr_NoMemory();
692 }
693
Raymond Hettinger41290a62015-03-31 08:12:23 -0700694 seq = PySequence_List((PyObject *)deque);
695 if (seq == NULL)
696 return seq;
697
Louie Lu357bad72017-02-24 11:59:49 +0800698 /* Reduce the number of repetitions when maxlen would be exceeded */
699 if (deque->maxlen >= 0 && n * size > deque->maxlen)
700 n = (deque->maxlen + size - 1) / size;
701
Raymond Hettinger41290a62015-03-31 08:12:23 -0700702 for (i = 0 ; i < n-1 ; i++) {
703 rv = deque_extend(deque, seq);
704 if (rv == NULL) {
705 Py_DECREF(seq);
706 return NULL;
707 }
708 Py_DECREF(rv);
709 }
710 Py_INCREF(deque);
711 Py_DECREF(seq);
712 return (PyObject *)deque;
713}
714
Raymond Hettingerf5d72f32015-09-09 22:39:44 -0400715static PyObject *
716deque_repeat(dequeobject *deque, Py_ssize_t n)
717{
718 dequeobject *new_deque;
Raymond Hettinger95e2cc52015-09-13 02:41:18 -0400719 PyObject *rv;
Raymond Hettingerf5d72f32015-09-09 22:39:44 -0400720
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530721 new_deque = (dequeobject *)deque_copy((PyObject *) deque, NULL);
Raymond Hettingerf5d72f32015-09-09 22:39:44 -0400722 if (new_deque == NULL)
723 return NULL;
Raymond Hettinger95e2cc52015-09-13 02:41:18 -0400724 rv = deque_inplace_repeat(new_deque, n);
725 Py_DECREF(new_deque);
726 return rv;
Raymond Hettingerf5d72f32015-09-09 22:39:44 -0400727}
728
Raymond Hettinger54023152014-04-23 00:58:48 -0700729/* The rotate() method is part of the public API and is used internally
730as a primitive for other methods.
731
732Rotation by 1 or -1 is a common case, so any optimizations for high
733volume rotations should take care not to penalize the common case.
734
735Conceptually, a rotate by one is equivalent to a pop on one side and an
736append on the other. However, a pop/append pair is unnecessarily slow
Martin Panterd2ad5712015-11-02 04:20:33 +0000737because it requires an incref/decref pair for an object located randomly
Raymond Hettinger54023152014-04-23 00:58:48 -0700738in memory. It is better to just move the object pointer from one block
739to the next without changing the reference count.
740
741When moving batches of pointers, it is tempting to use memcpy() but that
742proved to be slower than a simple loop for a variety of reasons.
743Memcpy() cannot know in advance that we're copying pointers instead of
744bytes, that the source and destination are pointer aligned and
745non-overlapping, that moving just one pointer is a common case, that we
746never need to move more than BLOCKLEN pointers, and that at least one
747pointer is always moved.
748
749For high volume rotations, newblock() and freeblock() are never called
750more than once. Previously emptied blocks are immediately reused as a
751destination block. If a block is left-over at the end, it is freed.
752*/
753
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000754static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000755_deque_rotate(dequeobject *deque, Py_ssize_t n)
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000756{
Raymond Hettinger3959af92013-07-13 02:34:08 -0700757 block *b = NULL;
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700758 block *leftblock = deque->leftblock;
759 block *rightblock = deque->rightblock;
760 Py_ssize_t leftindex = deque->leftindex;
761 Py_ssize_t rightindex = deque->rightindex;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000762 Py_ssize_t len=Py_SIZE(deque), halflen=len>>1;
Raymond Hettinger3959af92013-07-13 02:34:08 -0700763 int rv = -1;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000764
Raymond Hettinger464d89b2013-01-11 22:29:50 -0800765 if (len <= 1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000766 return 0;
767 if (n > halflen || n < -halflen) {
768 n %= len;
769 if (n > halflen)
770 n -= len;
771 else if (n < -halflen)
772 n += len;
773 }
Raymond Hettinger1f0044c2013-02-05 01:30:46 -0500774 assert(len > 1);
Raymond Hettingera4409c12013-02-04 00:08:12 -0500775 assert(-halflen <= n && n <= halflen);
Raymond Hettinger231ee4d2013-02-02 11:24:43 -0800776
Raymond Hettinger464d89b2013-01-11 22:29:50 -0800777 deque->state++;
Raymond Hettinger1f0044c2013-02-05 01:30:46 -0500778 while (n > 0) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700779 if (leftindex == 0) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700780 if (b == NULL) {
Raymond Hettingerdb41fd42015-10-22 22:48:16 -0700781 b = newblock();
Raymond Hettinger3959af92013-07-13 02:34:08 -0700782 if (b == NULL)
783 goto done;
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700784 }
Raymond Hettinger82df9252013-07-07 01:43:42 -1000785 b->rightlink = leftblock;
786 CHECK_END(leftblock->leftlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700787 leftblock->leftlink = b;
788 leftblock = b;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000789 MARK_END(b->leftlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700790 leftindex = BLOCKLEN;
Raymond Hettinger3959af92013-07-13 02:34:08 -0700791 b = NULL;
Raymond Hettinger464d89b2013-01-11 22:29:50 -0800792 }
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700793 assert(leftindex > 0);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700794 {
795 PyObject **src, **dest;
796 Py_ssize_t m = n;
Raymond Hettinger21777ac2013-02-02 09:56:08 -0800797
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700798 if (m > rightindex + 1)
799 m = rightindex + 1;
800 if (m > leftindex)
801 m = leftindex;
802 assert (m > 0 && m <= len);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700803 rightindex -= m;
804 leftindex -= m;
Raymond Hettinger0e259f12015-02-01 22:53:41 -0800805 src = &rightblock->data[rightindex + 1];
806 dest = &leftblock->data[leftindex];
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700807 n -= m;
Raymond Hettinger840533b2013-07-13 17:03:58 -0700808 do {
Raymond Hettinger0e259f12015-02-01 22:53:41 -0800809 *(dest++) = *(src++);
Raymond Hettinger840533b2013-07-13 17:03:58 -0700810 } while (--m);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700811 }
Raymond Hettingerd3d2b2c2015-09-21 23:41:56 -0700812 if (rightindex < 0) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700813 assert(leftblock != rightblock);
Raymond Hettinger840533b2013-07-13 17:03:58 -0700814 assert(b == NULL);
Raymond Hettinger3959af92013-07-13 02:34:08 -0700815 b = rightblock;
Raymond Hettingerb97cc492013-07-21 01:51:07 -0700816 CHECK_NOT_END(rightblock->leftlink);
817 rightblock = rightblock->leftlink;
818 MARK_END(rightblock->rightlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700819 rightindex = BLOCKLEN - 1;
Raymond Hettinger464d89b2013-01-11 22:29:50 -0800820 }
Raymond Hettinger21777ac2013-02-02 09:56:08 -0800821 }
Raymond Hettinger1f0044c2013-02-05 01:30:46 -0500822 while (n < 0) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700823 if (rightindex == BLOCKLEN - 1) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700824 if (b == NULL) {
Raymond Hettingerdb41fd42015-10-22 22:48:16 -0700825 b = newblock();
Raymond Hettinger3959af92013-07-13 02:34:08 -0700826 if (b == NULL)
827 goto done;
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700828 }
Raymond Hettinger82df9252013-07-07 01:43:42 -1000829 b->leftlink = rightblock;
830 CHECK_END(rightblock->rightlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700831 rightblock->rightlink = b;
832 rightblock = b;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000833 MARK_END(b->rightlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700834 rightindex = -1;
Raymond Hettinger3959af92013-07-13 02:34:08 -0700835 b = NULL;
Raymond Hettinger464d89b2013-01-11 22:29:50 -0800836 }
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700837 assert (rightindex < BLOCKLEN - 1);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700838 {
839 PyObject **src, **dest;
840 Py_ssize_t m = -n;
Raymond Hettinger21777ac2013-02-02 09:56:08 -0800841
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700842 if (m > BLOCKLEN - leftindex)
843 m = BLOCKLEN - leftindex;
844 if (m > BLOCKLEN - 1 - rightindex)
845 m = BLOCKLEN - 1 - rightindex;
846 assert (m > 0 && m <= len);
847 src = &leftblock->data[leftindex];
848 dest = &rightblock->data[rightindex + 1];
849 leftindex += m;
850 rightindex += m;
851 n += m;
Raymond Hettinger840533b2013-07-13 17:03:58 -0700852 do {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700853 *(dest++) = *(src++);
Raymond Hettinger840533b2013-07-13 17:03:58 -0700854 } while (--m);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700855 }
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700856 if (leftindex == BLOCKLEN) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700857 assert(leftblock != rightblock);
Raymond Hettinger840533b2013-07-13 17:03:58 -0700858 assert(b == NULL);
Raymond Hettinger3959af92013-07-13 02:34:08 -0700859 b = leftblock;
Raymond Hettingerb97cc492013-07-21 01:51:07 -0700860 CHECK_NOT_END(leftblock->rightlink);
861 leftblock = leftblock->rightlink;
862 MARK_END(leftblock->leftlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700863 leftindex = 0;
Raymond Hettinger21777ac2013-02-02 09:56:08 -0800864 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 }
Raymond Hettinger3959af92013-07-13 02:34:08 -0700866 rv = 0;
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700867done:
Raymond Hettinger3959af92013-07-13 02:34:08 -0700868 if (b != NULL)
869 freeblock(b);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700870 deque->leftblock = leftblock;
871 deque->rightblock = rightblock;
872 deque->leftindex = leftindex;
873 deque->rightindex = rightindex;
874
875 return rv;
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000876}
877
878static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +0200879deque_rotate(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000880{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000881 Py_ssize_t n=1;
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000882
Victor Stinnerdd407d52017-02-06 16:06:49 +0100883 if (!_PyArg_ParseStack(args, nargs, "|n:rotate", &n)) {
884 return NULL;
885 }
886
Raymond Hettinger6921c132015-03-21 02:03:40 -0700887 if (!_deque_rotate(deque, n))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000888 Py_RETURN_NONE;
889 return NULL;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000890}
891
Tim Peters1065f752004-10-01 01:03:29 +0000892PyDoc_STRVAR(rotate_doc,
Raymond Hettingeree33b272004-02-08 04:05:26 +0000893"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000894
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000895static PyObject *
896deque_reverse(dequeobject *deque, PyObject *unused)
897{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 block *leftblock = deque->leftblock;
899 block *rightblock = deque->rightblock;
900 Py_ssize_t leftindex = deque->leftindex;
901 Py_ssize_t rightindex = deque->rightindex;
Raymond Hettingercfe5b6c2015-07-20 00:25:50 -0400902 Py_ssize_t n = Py_SIZE(deque) >> 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 PyObject *tmp;
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000904
Raymond Hettingere1b02872017-09-04 16:07:06 -0700905 while (--n >= 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 /* Validate that pointers haven't met in the middle */
907 assert(leftblock != rightblock || leftindex < rightindex);
Raymond Hettinger82df9252013-07-07 01:43:42 -1000908 CHECK_NOT_END(leftblock);
909 CHECK_NOT_END(rightblock);
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 /* Swap */
912 tmp = leftblock->data[leftindex];
913 leftblock->data[leftindex] = rightblock->data[rightindex];
914 rightblock->data[rightindex] = tmp;
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000915
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 /* Advance left block/index pair */
917 leftindex++;
918 if (leftindex == BLOCKLEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000919 leftblock = leftblock->rightlink;
920 leftindex = 0;
921 }
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000923 /* Step backwards with the right block/index pair */
924 rightindex--;
Raymond Hettingerd3d2b2c2015-09-21 23:41:56 -0700925 if (rightindex < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 rightblock = rightblock->leftlink;
927 rightindex = BLOCKLEN - 1;
928 }
929 }
930 Py_RETURN_NONE;
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000931}
932
933PyDoc_STRVAR(reverse_doc,
934"D.reverse() -- reverse *IN PLACE*");
935
Raymond Hettinger44459de2010-04-03 23:20:46 +0000936static PyObject *
937deque_count(dequeobject *deque, PyObject *v)
938{
Raymond Hettingerf3a67b72013-07-06 17:49:06 -1000939 block *b = deque->leftblock;
940 Py_ssize_t index = deque->leftindex;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000941 Py_ssize_t n = Py_SIZE(deque);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000942 Py_ssize_t count = 0;
Raymond Hettingerf9d9c792015-03-02 22:47:46 -0800943 size_t start_state = deque->state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000944 PyObject *item;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000945 int cmp;
Raymond Hettinger44459de2010-04-03 23:20:46 +0000946
Raymond Hettingere1b02872017-09-04 16:07:06 -0700947 while (--n >= 0) {
Raymond Hettinger82df9252013-07-07 01:43:42 -1000948 CHECK_NOT_END(b);
Raymond Hettingerf3a67b72013-07-06 17:49:06 -1000949 item = b->data[index];
sweeneydec6dedde2020-02-09 03:16:43 -0500950 Py_INCREF(item);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 cmp = PyObject_RichCompareBool(item, v, Py_EQ);
sweeneydec6dedde2020-02-09 03:16:43 -0500952 Py_DECREF(item);
Raymond Hettinger2b0d6462015-09-23 19:15:44 -0700953 if (cmp < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 return NULL;
Raymond Hettinger2b0d6462015-09-23 19:15:44 -0700955 count += cmp;
Raymond Hettinger44459de2010-04-03 23:20:46 +0000956
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 if (start_state != deque->state) {
958 PyErr_SetString(PyExc_RuntimeError,
959 "deque mutated during iteration");
960 return NULL;
961 }
Raymond Hettinger44459de2010-04-03 23:20:46 +0000962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 /* Advance left block/index pair */
Raymond Hettingerf3a67b72013-07-06 17:49:06 -1000964 index++;
965 if (index == BLOCKLEN) {
966 b = b->rightlink;
967 index = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000968 }
969 }
970 return PyLong_FromSsize_t(count);
Raymond Hettinger44459de2010-04-03 23:20:46 +0000971}
972
973PyDoc_STRVAR(count_doc,
974"D.count(value) -> integer -- return number of occurrences of value");
975
Raymond Hettinger39dadf72015-03-20 16:38:56 -0700976static int
977deque_contains(dequeobject *deque, PyObject *v)
978{
979 block *b = deque->leftblock;
980 Py_ssize_t index = deque->leftindex;
981 Py_ssize_t n = Py_SIZE(deque);
Raymond Hettinger39dadf72015-03-20 16:38:56 -0700982 size_t start_state = deque->state;
983 PyObject *item;
984 int cmp;
985
Raymond Hettingere1b02872017-09-04 16:07:06 -0700986 while (--n >= 0) {
Raymond Hettinger39dadf72015-03-20 16:38:56 -0700987 CHECK_NOT_END(b);
988 item = b->data[index];
sweeneydec6dedde2020-02-09 03:16:43 -0500989 Py_INCREF(item);
Raymond Hettinger39dadf72015-03-20 16:38:56 -0700990 cmp = PyObject_RichCompareBool(item, v, Py_EQ);
sweeneydec6dedde2020-02-09 03:16:43 -0500991 Py_DECREF(item);
Raymond Hettinger39dadf72015-03-20 16:38:56 -0700992 if (cmp) {
993 return cmp;
994 }
995 if (start_state != deque->state) {
996 PyErr_SetString(PyExc_RuntimeError,
997 "deque mutated during iteration");
998 return -1;
999 }
1000 index++;
1001 if (index == BLOCKLEN) {
1002 b = b->rightlink;
1003 index = 0;
1004 }
1005 }
1006 return 0;
1007}
1008
Martin v. Löwis18e16552006-02-15 17:27:45 +00001009static Py_ssize_t
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001010deque_len(dequeobject *deque)
1011{
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001012 return Py_SIZE(deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001013}
1014
Raymond Hettinger4aec61e2005-03-18 21:20:23 +00001015static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001016deque_index(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001017{
Raymond Hettinger67b97b82015-11-01 23:57:37 -05001018 Py_ssize_t i, n, start=0, stop=Py_SIZE(deque);
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001019 PyObject *v, *item;
1020 block *b = deque->leftblock;
1021 Py_ssize_t index = deque->leftindex;
1022 size_t start_state = deque->state;
Raymond Hettinger67b97b82015-11-01 23:57:37 -05001023 int cmp;
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001024
Victor Stinnerdd407d52017-02-06 16:06:49 +01001025 if (!_PyArg_ParseStack(args, nargs, "O|O&O&:index", &v,
Serhiy Storchakad4edfc92017-03-30 18:29:23 +03001026 _PyEval_SliceIndexNotNone, &start,
1027 _PyEval_SliceIndexNotNone, &stop)) {
Victor Stinnerdd407d52017-02-06 16:06:49 +01001028 return NULL;
1029 }
1030
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001031 if (start < 0) {
1032 start += Py_SIZE(deque);
1033 if (start < 0)
1034 start = 0;
1035 }
1036 if (stop < 0) {
1037 stop += Py_SIZE(deque);
1038 if (stop < 0)
1039 stop = 0;
1040 }
Raymond Hettinger87674ec2015-08-26 08:08:38 -07001041 if (stop > Py_SIZE(deque))
1042 stop = Py_SIZE(deque);
Raymond Hettinger67b97b82015-11-01 23:57:37 -05001043 if (start > stop)
1044 start = stop;
1045 assert(0 <= start && start <= stop && stop <= Py_SIZE(deque));
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001046
Raymond Hettingerb46ad542018-09-21 01:46:41 -07001047 for (i=0 ; i < start - BLOCKLEN ; i += BLOCKLEN) {
1048 b = b->rightlink;
1049 }
1050 for ( ; i < start ; i++) {
Raymond Hettinger67b97b82015-11-01 23:57:37 -05001051 index++;
1052 if (index == BLOCKLEN) {
1053 b = b->rightlink;
1054 index = 0;
1055 }
1056 }
1057
Raymond Hettingere1b02872017-09-04 16:07:06 -07001058 n = stop - i;
1059 while (--n >= 0) {
Raymond Hettinger67b97b82015-11-01 23:57:37 -05001060 CHECK_NOT_END(b);
1061 item = b->data[index];
1062 cmp = PyObject_RichCompareBool(item, v, Py_EQ);
1063 if (cmp > 0)
Raymond Hettingere1b02872017-09-04 16:07:06 -07001064 return PyLong_FromSsize_t(stop - n - 1);
Raymond Hettingerdf8f5b52015-11-02 07:27:40 -05001065 if (cmp < 0)
Raymond Hettinger67b97b82015-11-01 23:57:37 -05001066 return NULL;
1067 if (start_state != deque->state) {
1068 PyErr_SetString(PyExc_RuntimeError,
1069 "deque mutated during iteration");
1070 return NULL;
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001071 }
1072 index++;
1073 if (index == BLOCKLEN) {
1074 b = b->rightlink;
1075 index = 0;
1076 }
1077 }
1078 PyErr_Format(PyExc_ValueError, "%R is not in deque", v);
1079 return NULL;
1080}
1081
1082PyDoc_STRVAR(index_doc,
1083"D.index(value, [start, [stop]]) -> integer -- return first index of value.\n"
1084"Raises ValueError if the value is not present.");
1085
Raymond Hettinger551350a2015-03-24 00:19:53 -07001086/* insert(), remove(), and delitem() are implemented in terms of
1087 rotate() for simplicity and reasonable performance near the end
1088 points. If for some reason these methods become popular, it is not
1089 hard to re-implement this using direct data movement (similar to
1090 the code used in list slice assignments) and achieve a performance
Raymond Hettingerfef9c1b2015-03-24 21:12:57 -07001091 boost (by moving each pointer only once instead of twice).
Raymond Hettinger551350a2015-03-24 00:19:53 -07001092*/
1093
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001094static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001095deque_insert(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001096{
1097 Py_ssize_t index;
1098 Py_ssize_t n = Py_SIZE(deque);
1099 PyObject *value;
1100 PyObject *rv;
1101
Victor Stinnerdd407d52017-02-06 16:06:49 +01001102 if (!_PyArg_ParseStack(args, nargs, "nO:insert", &index, &value)) {
1103 return NULL;
1104 }
1105
Raymond Hettinger37434322016-01-26 21:44:16 -08001106 if (deque->maxlen == Py_SIZE(deque)) {
Raymond Hettingera6389712016-02-01 21:21:19 -08001107 PyErr_SetString(PyExc_IndexError, "deque already at its maximum size");
1108 return NULL;
Raymond Hettinger37434322016-01-26 21:44:16 -08001109 }
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001110 if (index >= n)
1111 return deque_append(deque, value);
1112 if (index <= -n || index == 0)
1113 return deque_appendleft(deque, value);
1114 if (_deque_rotate(deque, -index))
1115 return NULL;
1116 if (index < 0)
1117 rv = deque_append(deque, value);
1118 else
1119 rv = deque_appendleft(deque, value);
1120 if (rv == NULL)
1121 return NULL;
1122 Py_DECREF(rv);
1123 if (_deque_rotate(deque, index))
1124 return NULL;
1125 Py_RETURN_NONE;
1126}
1127
1128PyDoc_STRVAR(insert_doc,
1129"D.insert(index, object) -- insert object before index");
1130
Raymond Hettinger4aec61e2005-03-18 21:20:23 +00001131PyDoc_STRVAR(remove_doc,
1132"D.remove(value) -- remove first occurrence of value.");
1133
Raymond Hettinger3c186ba2015-03-02 21:45:02 -08001134static int
1135valid_index(Py_ssize_t i, Py_ssize_t limit)
1136{
Raymond Hettinger12f896c2015-07-31 12:03:20 -07001137 /* The cast to size_t lets us use just a single comparison
Raymond Hettinger3c186ba2015-03-02 21:45:02 -08001138 to check whether i is in the range: 0 <= i < limit */
1139 return (size_t) i < (size_t) limit;
1140}
1141
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001142static PyObject *
Benjamin Petersond6313712008-07-31 16:23:04 +00001143deque_item(dequeobject *deque, Py_ssize_t i)
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00001144{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 block *b;
1146 PyObject *item;
1147 Py_ssize_t n, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00001148
Raymond Hettinger3c186ba2015-03-02 21:45:02 -08001149 if (!valid_index(i, Py_SIZE(deque))) {
1150 PyErr_SetString(PyExc_IndexError, "deque index out of range");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 return NULL;
1152 }
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00001153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 if (i == 0) {
1155 i = deque->leftindex;
1156 b = deque->leftblock;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001157 } else if (i == Py_SIZE(deque) - 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 i = deque->rightindex;
1159 b = deque->rightblock;
1160 } else {
1161 i += deque->leftindex;
Raymond Hettingerc2083082015-02-28 23:29:16 -08001162 n = (Py_ssize_t)((size_t) i / BLOCKLEN);
1163 i = (Py_ssize_t)((size_t) i % BLOCKLEN);
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001164 if (index < (Py_SIZE(deque) >> 1)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 b = deque->leftblock;
Raymond Hettingere1b02872017-09-04 16:07:06 -07001166 while (--n >= 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001167 b = b->rightlink;
1168 } else {
Raymond Hettinger63d1ff22015-02-28 07:41:30 -08001169 n = (Py_ssize_t)(
Raymond Hettingerc2083082015-02-28 23:29:16 -08001170 ((size_t)(deque->leftindex + Py_SIZE(deque) - 1))
Raymond Hettinger63d1ff22015-02-28 07:41:30 -08001171 / BLOCKLEN - n);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 b = deque->rightblock;
Raymond Hettingere1b02872017-09-04 16:07:06 -07001173 while (--n >= 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001174 b = b->leftlink;
1175 }
1176 }
1177 item = b->data[i];
1178 Py_INCREF(item);
1179 return item;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00001180}
1181
1182static int
Martin v. Löwis18e16552006-02-15 17:27:45 +00001183deque_del_item(dequeobject *deque, Py_ssize_t i)
Raymond Hettinger0e371f22004-05-12 20:55:56 +00001184{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 PyObject *item;
Raymond Hettingerac13ad62015-03-21 01:53:16 -07001186 int rv;
Raymond Hettinger0e371f22004-05-12 20:55:56 +00001187
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001188 assert (i >= 0 && i < Py_SIZE(deque));
Raymond Hettinger6921c132015-03-21 02:03:40 -07001189 if (_deque_rotate(deque, -i))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001191 item = deque_popleft(deque, NULL);
Raymond Hettingerac13ad62015-03-21 01:53:16 -07001192 rv = _deque_rotate(deque, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 assert (item != NULL);
1194 Py_DECREF(item);
Raymond Hettingerac13ad62015-03-21 01:53:16 -07001195 return rv;
Raymond Hettinger0e371f22004-05-12 20:55:56 +00001196}
1197
Raymond Hettinger6b1ac802020-12-23 11:45:06 -08001198static PyObject *
1199deque_remove(dequeobject *deque, PyObject *value)
1200{
1201 PyObject *item;
1202 block *b = deque->leftblock;
1203 Py_ssize_t i, n = Py_SIZE(deque), index = deque->leftindex;
1204 size_t start_state = deque->state;
1205 int cmp, rv;
1206
1207 for (i = 0 ; i < n; i++) {
1208 item = b->data[index];
1209 Py_INCREF(item);
1210 cmp = PyObject_RichCompareBool(item, value, Py_EQ);
1211 Py_DECREF(item);
1212 if (cmp < 0) {
1213 return NULL;
1214 }
1215 if (start_state != deque->state) {
1216 PyErr_SetString(PyExc_IndexError,
1217 "deque mutated during iteration");
1218 return NULL;
1219 }
1220 if (cmp > 0) {
1221 break;
1222 }
1223 index++;
1224 if (index == BLOCKLEN) {
1225 b = b->rightlink;
1226 index = 0;
1227 }
1228 }
1229 if (i == n) {
1230 PyErr_Format(PyExc_ValueError, "%R is not in deque", value);
1231 return NULL;
1232 }
1233 rv = deque_del_item(deque, i);
1234 if (rv == -1) {
1235 return NULL;
1236 }
1237 Py_RETURN_NONE;
1238}
1239
Raymond Hettinger0e371f22004-05-12 20:55:56 +00001240static int
Martin v. Löwis18e16552006-02-15 17:27:45 +00001241deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v)
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00001242{
Raymond Hettinger38418662016-02-08 20:34:49 -08001243 PyObject *old_value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 block *b;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001245 Py_ssize_t n, len=Py_SIZE(deque), halflen=(len+1)>>1, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00001246
Raymond Hettinger3c186ba2015-03-02 21:45:02 -08001247 if (!valid_index(i, len)) {
1248 PyErr_SetString(PyExc_IndexError, "deque index out of range");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 return -1;
1250 }
1251 if (v == NULL)
1252 return deque_del_item(deque, i);
Raymond Hettinger0e371f22004-05-12 20:55:56 +00001253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 i += deque->leftindex;
Raymond Hettingerc2083082015-02-28 23:29:16 -08001255 n = (Py_ssize_t)((size_t) i / BLOCKLEN);
1256 i = (Py_ssize_t)((size_t) i % BLOCKLEN);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 if (index <= halflen) {
1258 b = deque->leftblock;
Raymond Hettingere1b02872017-09-04 16:07:06 -07001259 while (--n >= 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 b = b->rightlink;
1261 } else {
Raymond Hettingera473b9d2015-02-28 17:49:47 -08001262 n = (Py_ssize_t)(
Raymond Hettingerc2083082015-02-28 23:29:16 -08001263 ((size_t)(deque->leftindex + Py_SIZE(deque) - 1))
Raymond Hettingera473b9d2015-02-28 17:49:47 -08001264 / BLOCKLEN - n);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001265 b = deque->rightblock;
Raymond Hettingere1b02872017-09-04 16:07:06 -07001266 while (--n >= 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 b = b->leftlink;
1268 }
1269 Py_INCREF(v);
Raymond Hettinger38418662016-02-08 20:34:49 -08001270 old_value = b->data[i];
1271 b->data[i] = v;
1272 Py_DECREF(old_value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 return 0;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00001274}
1275
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001276static void
1277deque_dealloc(dequeobject *deque)
1278{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 PyObject_GC_UnTrack(deque);
1280 if (deque->weakreflist != NULL)
1281 PyObject_ClearWeakRefs((PyObject *) deque);
1282 if (deque->leftblock != NULL) {
1283 deque_clear(deque);
1284 assert(deque->leftblock != NULL);
1285 freeblock(deque->leftblock);
1286 }
1287 deque->leftblock = NULL;
1288 deque->rightblock = NULL;
1289 Py_TYPE(deque)->tp_free(deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001290}
1291
1292static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00001293deque_traverse(dequeobject *deque, visitproc visit, void *arg)
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001294{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 block *b;
1296 PyObject *item;
1297 Py_ssize_t index;
1298 Py_ssize_t indexlo = deque->leftindex;
Raymond Hettinger1286d142015-10-14 23:16:57 -07001299 Py_ssize_t indexhigh;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001300
Raymond Hettinger5bfa8672013-07-06 11:58:09 -10001301 for (b = deque->leftblock; b != deque->rightblock; b = b->rightlink) {
1302 for (index = indexlo; index < BLOCKLEN ; index++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 item = b->data[index];
1304 Py_VISIT(item);
1305 }
1306 indexlo = 0;
1307 }
Raymond Hettinger1286d142015-10-14 23:16:57 -07001308 indexhigh = deque->rightindex;
1309 for (index = indexlo; index <= indexhigh; index++) {
Raymond Hettinger5bfa8672013-07-06 11:58:09 -10001310 item = b->data[index];
1311 Py_VISIT(item);
1312 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 return 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001314}
1315
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001316static PyObject *
Serhiy Storchaka81524022018-11-27 13:05:02 +02001317deque_reduce(dequeobject *deque, PyObject *Py_UNUSED(ignored))
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001318{
Serhiy Storchakaa0d416f2016-03-06 08:55:21 +02001319 PyObject *dict, *it;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001320 _Py_IDENTIFIER(__dict__);
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001321
Serhiy Storchakaf320be72018-01-25 10:49:40 +02001322 if (_PyObject_LookupAttrId((PyObject *)deque, &PyId___dict__, &dict) < 0) {
1323 return NULL;
1324 }
Serhiy Storchakaa0d416f2016-03-06 08:55:21 +02001325 if (dict == NULL) {
Serhiy Storchakaa0d416f2016-03-06 08:55:21 +02001326 dict = Py_None;
1327 Py_INCREF(dict);
1328 }
1329
1330 it = PyObject_GetIter((PyObject *)deque);
1331 if (it == NULL) {
1332 Py_DECREF(dict);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 return NULL;
1334 }
Serhiy Storchakaa0d416f2016-03-06 08:55:21 +02001335
1336 if (deque->maxlen < 0) {
1337 return Py_BuildValue("O()NN", Py_TYPE(deque), dict, it);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 }
Serhiy Storchakaa0d416f2016-03-06 08:55:21 +02001339 else {
1340 return Py_BuildValue("O(()n)NN", Py_TYPE(deque), deque->maxlen, dict, it);
1341 }
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001342}
1343
1344PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
1345
1346static PyObject *
1347deque_repr(PyObject *deque)
1348{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 PyObject *aslist, *result;
1350 int i;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001352 i = Py_ReprEnter(deque);
1353 if (i != 0) {
1354 if (i < 0)
1355 return NULL;
1356 return PyUnicode_FromString("[...]");
1357 }
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 aslist = PySequence_List(deque);
1360 if (aslist == NULL) {
1361 Py_ReprLeave(deque);
1362 return NULL;
1363 }
Raymond Hettingera7f630092015-10-10 23:56:02 -04001364 if (((dequeobject *)deque)->maxlen >= 0)
Serhiy Storchakab3a77962017-09-21 14:24:13 +03001365 result = PyUnicode_FromFormat("%s(%R, maxlen=%zd)",
1366 _PyType_Name(Py_TYPE(deque)), aslist,
1367 ((dequeobject *)deque)->maxlen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 else
Serhiy Storchakab3a77962017-09-21 14:24:13 +03001369 result = PyUnicode_FromFormat("%s(%R)",
1370 _PyType_Name(Py_TYPE(deque)), aslist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 Py_ReprLeave(deque);
Raymond Hettinger2b2b7532015-09-05 17:05:52 -07001372 Py_DECREF(aslist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 return result;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001374}
1375
Raymond Hettinger738ec902004-02-29 02:15:56 +00001376static PyObject *
1377deque_richcompare(PyObject *v, PyObject *w, int op)
1378{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 PyObject *it1=NULL, *it2=NULL, *x, *y;
1380 Py_ssize_t vs, ws;
1381 int b, cmp=-1;
Raymond Hettinger738ec902004-02-29 02:15:56 +00001382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 if (!PyObject_TypeCheck(v, &deque_type) ||
1384 !PyObject_TypeCheck(w, &deque_type)) {
Brian Curtindfc80e32011-08-10 20:28:54 -05001385 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 }
Raymond Hettinger738ec902004-02-29 02:15:56 +00001387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 /* Shortcuts */
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001389 vs = Py_SIZE((dequeobject *)v);
1390 ws = Py_SIZE((dequeobject *)w);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 if (op == Py_EQ) {
1392 if (v == w)
1393 Py_RETURN_TRUE;
1394 if (vs != ws)
1395 Py_RETURN_FALSE;
1396 }
1397 if (op == Py_NE) {
1398 if (v == w)
1399 Py_RETURN_FALSE;
1400 if (vs != ws)
1401 Py_RETURN_TRUE;
1402 }
Raymond Hettinger738ec902004-02-29 02:15:56 +00001403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001404 /* Search for the first index where items are different */
1405 it1 = PyObject_GetIter(v);
1406 if (it1 == NULL)
1407 goto done;
1408 it2 = PyObject_GetIter(w);
1409 if (it2 == NULL)
1410 goto done;
1411 for (;;) {
1412 x = PyIter_Next(it1);
1413 if (x == NULL && PyErr_Occurred())
1414 goto done;
1415 y = PyIter_Next(it2);
1416 if (x == NULL || y == NULL)
1417 break;
1418 b = PyObject_RichCompareBool(x, y, Py_EQ);
1419 if (b == 0) {
1420 cmp = PyObject_RichCompareBool(x, y, op);
1421 Py_DECREF(x);
1422 Py_DECREF(y);
1423 goto done;
1424 }
1425 Py_DECREF(x);
1426 Py_DECREF(y);
Raymond Hettingerd3d2b2c2015-09-21 23:41:56 -07001427 if (b < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 goto done;
1429 }
1430 /* We reached the end of one deque or both */
1431 Py_XDECREF(x);
1432 Py_XDECREF(y);
1433 if (PyErr_Occurred())
1434 goto done;
1435 switch (op) {
1436 case Py_LT: cmp = y != NULL; break; /* if w was longer */
1437 case Py_LE: cmp = x == NULL; break; /* if v was not longer */
1438 case Py_EQ: cmp = x == y; break; /* if we reached the end of both */
1439 case Py_NE: cmp = x != y; break; /* if one deque continues */
1440 case Py_GT: cmp = x != NULL; break; /* if v was longer */
1441 case Py_GE: cmp = y == NULL; break; /* if w was not longer */
1442 }
Tim Peters1065f752004-10-01 01:03:29 +00001443
Raymond Hettinger738ec902004-02-29 02:15:56 +00001444done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 Py_XDECREF(it1);
1446 Py_XDECREF(it2);
1447 if (cmp == 1)
1448 Py_RETURN_TRUE;
1449 if (cmp == 0)
1450 Py_RETURN_FALSE;
1451 return NULL;
Raymond Hettinger738ec902004-02-29 02:15:56 +00001452}
1453
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001454static int
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001455deque_init(dequeobject *deque, PyObject *args, PyObject *kwdargs)
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001456{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 PyObject *iterable = NULL;
1458 PyObject *maxlenobj = NULL;
1459 Py_ssize_t maxlen = -1;
1460 char *kwlist[] = {"iterable", "maxlen", 0};
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001461
Raymond Hettinger05f1b932019-01-31 22:13:43 -08001462 if (kwdargs == NULL && PyTuple_GET_SIZE(args) <= 2) {
1463 if (PyTuple_GET_SIZE(args) > 0) {
1464 iterable = PyTuple_GET_ITEM(args, 0);
1465 }
1466 if (PyTuple_GET_SIZE(args) > 1) {
1467 maxlenobj = PyTuple_GET_ITEM(args, 1);
1468 }
Raymond Hettinger0d309402015-09-30 23:15:02 -07001469 } else {
1470 if (!PyArg_ParseTupleAndKeywords(args, kwdargs, "|OO:deque", kwlist,
1471 &iterable, &maxlenobj))
1472 return -1;
1473 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 if (maxlenobj != NULL && maxlenobj != Py_None) {
1475 maxlen = PyLong_AsSsize_t(maxlenobj);
1476 if (maxlen == -1 && PyErr_Occurred())
1477 return -1;
1478 if (maxlen < 0) {
1479 PyErr_SetString(PyExc_ValueError, "maxlen must be non-negative");
1480 return -1;
1481 }
1482 }
1483 deque->maxlen = maxlen;
Raymond Hettinger0d309402015-09-30 23:15:02 -07001484 if (Py_SIZE(deque) > 0)
1485 deque_clear(deque);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 if (iterable != NULL) {
1487 PyObject *rv = deque_extend(deque, iterable);
1488 if (rv == NULL)
1489 return -1;
1490 Py_DECREF(rv);
1491 }
1492 return 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001493}
1494
Raymond Hettinger5bb0f0e2009-03-10 12:56:32 +00001495static PyObject *
Jesus Cea16e2fca2012-08-03 14:49:42 +02001496deque_sizeof(dequeobject *deque, void *unused)
1497{
1498 Py_ssize_t res;
1499 Py_ssize_t blocks;
1500
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001501 res = _PyObject_SIZE(Py_TYPE(deque));
Raymond Hettingerbc003412015-10-14 23:33:23 -07001502 blocks = (size_t)(deque->leftindex + Py_SIZE(deque) + BLOCKLEN - 1) / BLOCKLEN;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001503 assert(deque->leftindex + Py_SIZE(deque) - 1 ==
Jesus Cea16e2fca2012-08-03 14:49:42 +02001504 (blocks - 1) * BLOCKLEN + deque->rightindex);
1505 res += blocks * sizeof(block);
1506 return PyLong_FromSsize_t(res);
1507}
1508
1509PyDoc_STRVAR(sizeof_doc,
1510"D.__sizeof__() -- size of D in memory, in bytes");
1511
Raymond Hettinger0f1451c2015-03-23 23:23:55 -07001512static int
1513deque_bool(dequeobject *deque)
1514{
1515 return Py_SIZE(deque) != 0;
1516}
1517
Jesus Cea16e2fca2012-08-03 14:49:42 +02001518static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02001519deque_get_maxlen(dequeobject *deque, void *Py_UNUSED(ignored))
Raymond Hettinger5bb0f0e2009-03-10 12:56:32 +00001520{
Raymond Hettingerd3d2b2c2015-09-21 23:41:56 -07001521 if (deque->maxlen < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 Py_RETURN_NONE;
1523 return PyLong_FromSsize_t(deque->maxlen);
Raymond Hettinger5bb0f0e2009-03-10 12:56:32 +00001524}
1525
Raymond Hettinger41290a62015-03-31 08:12:23 -07001526
1527/* deque object ********************************************************/
1528
Raymond Hettinger5bb0f0e2009-03-10 12:56:32 +00001529static PyGetSetDef deque_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530 {"maxlen", (getter)deque_get_maxlen, (setter)NULL,
1531 "maximum size of a deque or None if unbounded"},
1532 {0}
Raymond Hettinger5bb0f0e2009-03-10 12:56:32 +00001533};
1534
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001535static PySequenceMethods deque_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001536 (lenfunc)deque_len, /* sq_length */
Raymond Hettinger41290a62015-03-31 08:12:23 -07001537 (binaryfunc)deque_concat, /* sq_concat */
1538 (ssizeargfunc)deque_repeat, /* sq_repeat */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 (ssizeargfunc)deque_item, /* sq_item */
1540 0, /* sq_slice */
Raymond Hettinger87e69122015-03-02 23:32:02 -08001541 (ssizeobjargproc)deque_ass_item, /* sq_ass_item */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 0, /* sq_ass_slice */
Raymond Hettinger39dadf72015-03-20 16:38:56 -07001543 (objobjproc)deque_contains, /* sq_contains */
Raymond Hettinger87e69122015-03-02 23:32:02 -08001544 (binaryfunc)deque_inplace_concat, /* sq_inplace_concat */
Raymond Hettinger41290a62015-03-31 08:12:23 -07001545 (ssizeargfunc)deque_inplace_repeat, /* sq_inplace_repeat */
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001546};
1547
Raymond Hettinger0f1451c2015-03-23 23:23:55 -07001548static PyNumberMethods deque_as_number = {
1549 0, /* nb_add */
1550 0, /* nb_subtract */
1551 0, /* nb_multiply */
1552 0, /* nb_remainder */
1553 0, /* nb_divmod */
1554 0, /* nb_power */
1555 0, /* nb_negative */
1556 0, /* nb_positive */
1557 0, /* nb_absolute */
1558 (inquiry)deque_bool, /* nb_bool */
1559 0, /* nb_invert */
Raymond Hettinger0f1451c2015-03-23 23:23:55 -07001560 };
1561
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001562static PyObject *deque_iter(dequeobject *deque);
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301563static PyObject *deque_reviter(dequeobject *deque, PyObject *Py_UNUSED(ignored));
Tim Peters1065f752004-10-01 01:03:29 +00001564PyDoc_STRVAR(reversed_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001566
1567static PyMethodDef deque_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001568 {"append", (PyCFunction)deque_append,
1569 METH_O, append_doc},
1570 {"appendleft", (PyCFunction)deque_appendleft,
1571 METH_O, appendleft_doc},
1572 {"clear", (PyCFunction)deque_clearmethod,
1573 METH_NOARGS, clear_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301574 {"__copy__", deque_copy,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 METH_NOARGS, copy_doc},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301576 {"copy", deque_copy,
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001577 METH_NOARGS, copy_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 {"count", (PyCFunction)deque_count,
Raymond Hettinger0f6f9472015-03-21 01:42:10 -07001579 METH_O, count_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 {"extend", (PyCFunction)deque_extend,
1581 METH_O, extend_doc},
1582 {"extendleft", (PyCFunction)deque_extendleft,
1583 METH_O, extendleft_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001584 {"index", (PyCFunction)(void(*)(void))deque_index,
Victor Stinnerdd407d52017-02-06 16:06:49 +01001585 METH_FASTCALL, index_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001586 {"insert", (PyCFunction)(void(*)(void))deque_insert,
Victor Stinnerdd407d52017-02-06 16:06:49 +01001587 METH_FASTCALL, insert_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 {"pop", (PyCFunction)deque_pop,
1589 METH_NOARGS, pop_doc},
1590 {"popleft", (PyCFunction)deque_popleft,
1591 METH_NOARGS, popleft_doc},
Raymond Hettinger0f6f9472015-03-21 01:42:10 -07001592 {"__reduce__", (PyCFunction)deque_reduce,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 METH_NOARGS, reduce_doc},
1594 {"remove", (PyCFunction)deque_remove,
1595 METH_O, remove_doc},
1596 {"__reversed__", (PyCFunction)deque_reviter,
1597 METH_NOARGS, reversed_doc},
1598 {"reverse", (PyCFunction)deque_reverse,
1599 METH_NOARGS, reverse_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02001600 {"rotate", (PyCFunction)(void(*)(void))deque_rotate,
Victor Stinnerdd407d52017-02-06 16:06:49 +01001601 METH_FASTCALL, rotate_doc},
Jesus Cea16e2fca2012-08-03 14:49:42 +02001602 {"__sizeof__", (PyCFunction)deque_sizeof,
1603 METH_NOARGS, sizeof_doc},
Guido van Rossum48b069a2020-04-07 09:50:06 -07001604 {"__class_getitem__", (PyCFunction)Py_GenericAlias,
1605 METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 {NULL, NULL} /* sentinel */
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001607};
1608
1609PyDoc_STRVAR(deque_doc,
Andrew Svetlov6a5c7c32012-10-31 11:50:40 +02001610"deque([iterable[, maxlen]]) --> deque object\n\
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001611\n\
Raymond Hettinger41290a62015-03-31 08:12:23 -07001612A list-like sequence optimized for data accesses near its endpoints.");
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001613
Neal Norwitz87f10132004-02-29 15:40:53 +00001614static PyTypeObject deque_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 PyVarObject_HEAD_INIT(NULL, 0)
1616 "collections.deque", /* tp_name */
1617 sizeof(dequeobject), /* tp_basicsize */
1618 0, /* tp_itemsize */
1619 /* methods */
1620 (destructor)deque_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001621 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001622 0, /* tp_getattr */
1623 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001624 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001625 deque_repr, /* tp_repr */
Raymond Hettinger0f1451c2015-03-23 23:23:55 -07001626 &deque_as_number, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 &deque_as_sequence, /* tp_as_sequence */
1628 0, /* tp_as_mapping */
Georg Brandlf038b322010-10-18 07:35:09 +00001629 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 0, /* tp_call */
1631 0, /* tp_str */
1632 PyObject_GenericGetAttr, /* tp_getattro */
1633 0, /* tp_setattro */
1634 0, /* tp_as_buffer */
1635 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Georg Brandlf038b322010-10-18 07:35:09 +00001636 /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 deque_doc, /* tp_doc */
1638 (traverseproc)deque_traverse, /* tp_traverse */
1639 (inquiry)deque_clear, /* tp_clear */
1640 (richcmpfunc)deque_richcompare, /* tp_richcompare */
Georg Brandlf038b322010-10-18 07:35:09 +00001641 offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 (getiterfunc)deque_iter, /* tp_iter */
1643 0, /* tp_iternext */
1644 deque_methods, /* tp_methods */
1645 0, /* tp_members */
Georg Brandlf038b322010-10-18 07:35:09 +00001646 deque_getset, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 0, /* tp_base */
1648 0, /* tp_dict */
1649 0, /* tp_descr_get */
1650 0, /* tp_descr_set */
1651 0, /* tp_dictoffset */
1652 (initproc)deque_init, /* tp_init */
1653 PyType_GenericAlloc, /* tp_alloc */
1654 deque_new, /* tp_new */
1655 PyObject_GC_Del, /* tp_free */
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001656};
1657
1658/*********************** Deque Iterator **************************/
1659
1660typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001661 PyObject_HEAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001662 block *b;
Raymond Hettinger87e69122015-03-02 23:32:02 -08001663 Py_ssize_t index;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001664 dequeobject *deque;
Raymond Hettingerf9d9c792015-03-02 22:47:46 -08001665 size_t state; /* state when the iterator is created */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 Py_ssize_t counter; /* number of items remaining for iteration */
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001667} dequeiterobject;
1668
Martin v. Löwis59683e82008-06-13 07:50:45 +00001669static PyTypeObject dequeiter_type;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001670
1671static PyObject *
1672deque_iter(dequeobject *deque)
1673{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001674 dequeiterobject *it;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001676 it = PyObject_GC_New(dequeiterobject, &dequeiter_type);
1677 if (it == NULL)
1678 return NULL;
1679 it->b = deque->leftblock;
1680 it->index = deque->leftindex;
1681 Py_INCREF(deque);
1682 it->deque = deque;
1683 it->state = deque->state;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001684 it->counter = Py_SIZE(deque);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001685 PyObject_GC_Track(it);
1686 return (PyObject *)it;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001687}
1688
Antoine Pitrou7ddda782009-01-01 15:35:33 +00001689static int
1690dequeiter_traverse(dequeiterobject *dio, visitproc visit, void *arg)
1691{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001692 Py_VISIT(dio->deque);
1693 return 0;
Antoine Pitrou7ddda782009-01-01 15:35:33 +00001694}
1695
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001696static void
1697dequeiter_dealloc(dequeiterobject *dio)
1698{
INADA Naokia6296d32017-08-24 14:55:17 +09001699 /* bpo-31095: UnTrack is needed before calling any callbacks */
1700 PyObject_GC_UnTrack(dio);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001701 Py_XDECREF(dio->deque);
1702 PyObject_GC_Del(dio);
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001703}
1704
1705static PyObject *
1706dequeiter_next(dequeiterobject *it)
1707{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001708 PyObject *item;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +00001709
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001710 if (it->deque->state != it->state) {
1711 it->counter = 0;
1712 PyErr_SetString(PyExc_RuntimeError,
1713 "deque mutated during iteration");
1714 return NULL;
1715 }
1716 if (it->counter == 0)
1717 return NULL;
1718 assert (!(it->b == it->deque->rightblock &&
1719 it->index > it->deque->rightindex));
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001720
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001721 item = it->b->data[it->index];
1722 it->index++;
1723 it->counter--;
1724 if (it->index == BLOCKLEN && it->counter > 0) {
Raymond Hettinger82df9252013-07-07 01:43:42 -10001725 CHECK_NOT_END(it->b->rightlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001726 it->b = it->b->rightlink;
1727 it->index = 0;
1728 }
1729 Py_INCREF(item);
1730 return item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001731}
1732
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00001733static PyObject *
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001734dequeiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1735{
1736 Py_ssize_t i, index=0;
1737 PyObject *deque;
1738 dequeiterobject *it;
1739 if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index))
1740 return NULL;
1741 assert(type == &dequeiter_type);
1742
1743 it = (dequeiterobject*)deque_iter((dequeobject *)deque);
1744 if (!it)
1745 return NULL;
1746 /* consume items from the queue */
1747 for(i=0; i<index; i++) {
1748 PyObject *item = dequeiter_next(it);
1749 if (item) {
1750 Py_DECREF(item);
1751 } else {
1752 if (it->counter) {
1753 Py_DECREF(it);
1754 return NULL;
1755 } else
1756 break;
1757 }
1758 }
1759 return (PyObject*)it;
1760}
1761
1762static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301763dequeiter_len(dequeiterobject *it, PyObject *Py_UNUSED(ignored))
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001764{
Antoine Pitrou554f3342010-08-17 18:30:06 +00001765 return PyLong_FromSsize_t(it->counter);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001766}
1767
Armin Rigof5b3e362006-02-11 21:32:43 +00001768PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00001769
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001770static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301771dequeiter_reduce(dequeiterobject *it, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001772{
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001773 return Py_BuildValue("O(On)", Py_TYPE(it), it->deque, Py_SIZE(it->deque) - it->counter);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001774}
1775
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00001776static PyMethodDef dequeiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 {"__length_hint__", (PyCFunction)dequeiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001778 {"__reduce__", (PyCFunction)dequeiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 {NULL, NULL} /* sentinel */
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001780};
1781
Martin v. Löwis59683e82008-06-13 07:50:45 +00001782static PyTypeObject dequeiter_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 PyVarObject_HEAD_INIT(NULL, 0)
Raymond Hettinger87e69122015-03-02 23:32:02 -08001784 "_collections._deque_iterator", /* tp_name */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001785 sizeof(dequeiterobject), /* tp_basicsize */
1786 0, /* tp_itemsize */
1787 /* methods */
1788 (destructor)dequeiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001789 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790 0, /* tp_getattr */
1791 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001792 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001793 0, /* tp_repr */
1794 0, /* tp_as_number */
1795 0, /* tp_as_sequence */
1796 0, /* tp_as_mapping */
1797 0, /* tp_hash */
1798 0, /* tp_call */
1799 0, /* tp_str */
1800 PyObject_GenericGetAttr, /* tp_getattro */
1801 0, /* tp_setattro */
1802 0, /* tp_as_buffer */
Raymond Hettinger87e69122015-03-02 23:32:02 -08001803 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001804 0, /* tp_doc */
1805 (traverseproc)dequeiter_traverse, /* tp_traverse */
1806 0, /* tp_clear */
1807 0, /* tp_richcompare */
1808 0, /* tp_weaklistoffset */
1809 PyObject_SelfIter, /* tp_iter */
1810 (iternextfunc)dequeiter_next, /* tp_iternext */
1811 dequeiter_methods, /* tp_methods */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001812 0, /* tp_members */
1813 0, /* tp_getset */
1814 0, /* tp_base */
1815 0, /* tp_dict */
1816 0, /* tp_descr_get */
1817 0, /* tp_descr_set */
1818 0, /* tp_dictoffset */
1819 0, /* tp_init */
1820 0, /* tp_alloc */
1821 dequeiter_new, /* tp_new */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001822 0,
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001823};
1824
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001825/*********************** Deque Reverse Iterator **************************/
1826
Martin v. Löwis59683e82008-06-13 07:50:45 +00001827static PyTypeObject dequereviter_type;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001828
1829static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301830deque_reviter(dequeobject *deque, PyObject *Py_UNUSED(ignored))
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001831{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 dequeiterobject *it;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001833
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 it = PyObject_GC_New(dequeiterobject, &dequereviter_type);
1835 if (it == NULL)
1836 return NULL;
1837 it->b = deque->rightblock;
1838 it->index = deque->rightindex;
1839 Py_INCREF(deque);
1840 it->deque = deque;
1841 it->state = deque->state;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001842 it->counter = Py_SIZE(deque);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001843 PyObject_GC_Track(it);
1844 return (PyObject *)it;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001845}
1846
1847static PyObject *
1848dequereviter_next(dequeiterobject *it)
1849{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 PyObject *item;
1851 if (it->counter == 0)
1852 return NULL;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001853
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 if (it->deque->state != it->state) {
1855 it->counter = 0;
1856 PyErr_SetString(PyExc_RuntimeError,
1857 "deque mutated during iteration");
1858 return NULL;
1859 }
1860 assert (!(it->b == it->deque->leftblock &&
1861 it->index < it->deque->leftindex));
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001862
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 item = it->b->data[it->index];
1864 it->index--;
1865 it->counter--;
Raymond Hettingerd3d2b2c2015-09-21 23:41:56 -07001866 if (it->index < 0 && it->counter > 0) {
Raymond Hettinger82df9252013-07-07 01:43:42 -10001867 CHECK_NOT_END(it->b->leftlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 it->b = it->b->leftlink;
1869 it->index = BLOCKLEN - 1;
1870 }
1871 Py_INCREF(item);
1872 return item;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001873}
1874
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001875static PyObject *
1876dequereviter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1877{
1878 Py_ssize_t i, index=0;
1879 PyObject *deque;
1880 dequeiterobject *it;
1881 if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index))
1882 return NULL;
1883 assert(type == &dequereviter_type);
1884
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301885 it = (dequeiterobject*)deque_reviter((dequeobject *)deque, NULL);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001886 if (!it)
1887 return NULL;
1888 /* consume items from the queue */
1889 for(i=0; i<index; i++) {
1890 PyObject *item = dequereviter_next(it);
1891 if (item) {
1892 Py_DECREF(item);
1893 } else {
1894 if (it->counter) {
1895 Py_DECREF(it);
1896 return NULL;
1897 } else
1898 break;
1899 }
1900 }
1901 return (PyObject*)it;
1902}
1903
Martin v. Löwis59683e82008-06-13 07:50:45 +00001904static PyTypeObject dequereviter_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 PyVarObject_HEAD_INIT(NULL, 0)
Raymond Hettinger87e69122015-03-02 23:32:02 -08001906 "_collections._deque_reverse_iterator", /* tp_name */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 sizeof(dequeiterobject), /* tp_basicsize */
1908 0, /* tp_itemsize */
1909 /* methods */
1910 (destructor)dequeiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001911 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 0, /* tp_getattr */
1913 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001914 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 0, /* tp_repr */
1916 0, /* tp_as_number */
1917 0, /* tp_as_sequence */
1918 0, /* tp_as_mapping */
1919 0, /* tp_hash */
1920 0, /* tp_call */
1921 0, /* tp_str */
1922 PyObject_GenericGetAttr, /* tp_getattro */
1923 0, /* tp_setattro */
1924 0, /* tp_as_buffer */
Raymond Hettinger87e69122015-03-02 23:32:02 -08001925 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 0, /* tp_doc */
1927 (traverseproc)dequeiter_traverse, /* tp_traverse */
1928 0, /* tp_clear */
1929 0, /* tp_richcompare */
1930 0, /* tp_weaklistoffset */
1931 PyObject_SelfIter, /* tp_iter */
1932 (iternextfunc)dequereviter_next, /* tp_iternext */
1933 dequeiter_methods, /* tp_methods */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001934 0, /* tp_members */
1935 0, /* tp_getset */
1936 0, /* tp_base */
1937 0, /* tp_dict */
1938 0, /* tp_descr_get */
1939 0, /* tp_descr_set */
1940 0, /* tp_dictoffset */
1941 0, /* tp_init */
1942 0, /* tp_alloc */
1943 dequereviter_new, /* tp_new */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001944 0,
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001945};
1946
Guido van Rossum1968ad32006-02-25 22:38:04 +00001947/* defaultdict type *********************************************************/
1948
1949typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001950 PyDictObject dict;
1951 PyObject *default_factory;
Guido van Rossum1968ad32006-02-25 22:38:04 +00001952} defdictobject;
1953
1954static PyTypeObject defdict_type; /* Forward */
1955
1956PyDoc_STRVAR(defdict_missing_doc,
1957"__missing__(key) # Called by __getitem__ for missing key; pseudo-code:\n\
Guido van Rossumd8faa362007-04-27 19:54:29 +00001958 if self.default_factory is None: raise KeyError((key,))\n\
Guido van Rossum1968ad32006-02-25 22:38:04 +00001959 self[key] = value = self.default_factory()\n\
1960 return value\n\
1961");
1962
1963static PyObject *
1964defdict_missing(defdictobject *dd, PyObject *key)
1965{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001966 PyObject *factory = dd->default_factory;
1967 PyObject *value;
1968 if (factory == NULL || factory == Py_None) {
1969 /* XXX Call dict.__missing__(key) */
1970 PyObject *tup;
1971 tup = PyTuple_Pack(1, key);
1972 if (!tup) return NULL;
1973 PyErr_SetObject(PyExc_KeyError, tup);
1974 Py_DECREF(tup);
1975 return NULL;
1976 }
Jeroen Demeyer7f41c8e2019-07-04 12:35:31 +02001977 value = _PyObject_CallNoArg(factory);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001978 if (value == NULL)
1979 return value;
1980 if (PyObject_SetItem((PyObject *)dd, key, value) < 0) {
1981 Py_DECREF(value);
1982 return NULL;
1983 }
1984 return value;
Guido van Rossum1968ad32006-02-25 22:38:04 +00001985}
1986
Brandt Bucher57c9d172020-03-06 09:24:08 -08001987static inline PyObject*
1988new_defdict(defdictobject *dd, PyObject *arg)
1989{
1990 return PyObject_CallFunctionObjArgs((PyObject*)Py_TYPE(dd),
1991 dd->default_factory ? dd->default_factory : Py_None, arg, NULL);
1992}
1993
Guido van Rossum1968ad32006-02-25 22:38:04 +00001994PyDoc_STRVAR(defdict_copy_doc, "D.copy() -> a shallow copy of D.");
1995
1996static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301997defdict_copy(defdictobject *dd, PyObject *Py_UNUSED(ignored))
Guido van Rossum1968ad32006-02-25 22:38:04 +00001998{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 /* This calls the object's class. That only works for subclasses
2000 whose class constructor has the same signature. Subclasses that
2001 define a different constructor signature must override copy().
2002 */
Brandt Bucher57c9d172020-03-06 09:24:08 -08002003 return new_defdict(dd, (PyObject*)dd);
Guido van Rossum1968ad32006-02-25 22:38:04 +00002004}
2005
2006static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302007defdict_reduce(defdictobject *dd, PyObject *Py_UNUSED(ignored))
Guido van Rossum1968ad32006-02-25 22:38:04 +00002008{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 /* __reduce__ must return a 5-tuple as follows:
Guido van Rossum1968ad32006-02-25 22:38:04 +00002010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002011 - factory function
2012 - tuple of args for the factory function
2013 - additional state (here None)
2014 - sequence iterator (here None)
2015 - dictionary iterator (yielding successive (key, value) pairs
Guido van Rossum1968ad32006-02-25 22:38:04 +00002016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002017 This API is used by pickle.py and copy.py.
Guido van Rossum1968ad32006-02-25 22:38:04 +00002018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002019 For this to be useful with pickle.py, the default_factory
2020 must be picklable; e.g., None, a built-in, or a global
2021 function in a module or package.
Guido van Rossum1968ad32006-02-25 22:38:04 +00002022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002023 Both shallow and deep copying are supported, but for deep
2024 copying, the default_factory must be deep-copyable; e.g. None,
2025 or a built-in (functions are not copyable at this time).
Guido van Rossum1968ad32006-02-25 22:38:04 +00002026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002027 This only works for subclasses as long as their constructor
2028 signature is compatible; the first argument must be the
2029 optional default_factory, defaulting to None.
2030 */
2031 PyObject *args;
2032 PyObject *items;
2033 PyObject *iter;
2034 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002035 _Py_IDENTIFIER(items);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002036
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002037 if (dd->default_factory == NULL || dd->default_factory == Py_None)
2038 args = PyTuple_New(0);
2039 else
2040 args = PyTuple_Pack(1, dd->default_factory);
2041 if (args == NULL)
2042 return NULL;
Jeroen Demeyer762f93f2019-07-08 10:19:25 +02002043 items = _PyObject_CallMethodIdNoArgs((PyObject *)dd, &PyId_items);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002044 if (items == NULL) {
2045 Py_DECREF(args);
2046 return NULL;
2047 }
2048 iter = PyObject_GetIter(items);
2049 if (iter == NULL) {
2050 Py_DECREF(items);
2051 Py_DECREF(args);
2052 return NULL;
2053 }
2054 result = PyTuple_Pack(5, Py_TYPE(dd), args,
2055 Py_None, Py_None, iter);
2056 Py_DECREF(iter);
2057 Py_DECREF(items);
2058 Py_DECREF(args);
2059 return result;
Guido van Rossum1968ad32006-02-25 22:38:04 +00002060}
2061
2062static PyMethodDef defdict_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002063 {"__missing__", (PyCFunction)defdict_missing, METH_O,
2064 defdict_missing_doc},
2065 {"copy", (PyCFunction)defdict_copy, METH_NOARGS,
2066 defdict_copy_doc},
2067 {"__copy__", (PyCFunction)defdict_copy, METH_NOARGS,
2068 defdict_copy_doc},
2069 {"__reduce__", (PyCFunction)defdict_reduce, METH_NOARGS,
2070 reduce_doc},
Guido van Rossum48b069a2020-04-07 09:50:06 -07002071 {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS,
2072 PyDoc_STR("See PEP 585")},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 {NULL}
Guido van Rossum1968ad32006-02-25 22:38:04 +00002074};
2075
2076static PyMemberDef defdict_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002077 {"default_factory", T_OBJECT,
2078 offsetof(defdictobject, default_factory), 0,
2079 PyDoc_STR("Factory for default value called by __missing__().")},
2080 {NULL}
Guido van Rossum1968ad32006-02-25 22:38:04 +00002081};
2082
2083static void
2084defdict_dealloc(defdictobject *dd)
2085{
INADA Naokia6296d32017-08-24 14:55:17 +09002086 /* bpo-31095: UnTrack is needed before calling any callbacks */
2087 PyObject_GC_UnTrack(dd);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 Py_CLEAR(dd->default_factory);
2089 PyDict_Type.tp_dealloc((PyObject *)dd);
Guido van Rossum1968ad32006-02-25 22:38:04 +00002090}
2091
Guido van Rossum1968ad32006-02-25 22:38:04 +00002092static PyObject *
2093defdict_repr(defdictobject *dd)
2094{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002095 PyObject *baserepr;
2096 PyObject *defrepr;
2097 PyObject *result;
2098 baserepr = PyDict_Type.tp_repr((PyObject *)dd);
2099 if (baserepr == NULL)
2100 return NULL;
2101 if (dd->default_factory == NULL)
2102 defrepr = PyUnicode_FromString("None");
2103 else
2104 {
2105 int status = Py_ReprEnter(dd->default_factory);
2106 if (status != 0) {
Antoine Pitrouf5f1fe02012-02-15 02:42:46 +01002107 if (status < 0) {
2108 Py_DECREF(baserepr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 return NULL;
Antoine Pitrouf5f1fe02012-02-15 02:42:46 +01002110 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 defrepr = PyUnicode_FromString("...");
2112 }
2113 else
2114 defrepr = PyObject_Repr(dd->default_factory);
2115 Py_ReprLeave(dd->default_factory);
2116 }
2117 if (defrepr == NULL) {
2118 Py_DECREF(baserepr);
2119 return NULL;
2120 }
Serhiy Storchakab3a77962017-09-21 14:24:13 +03002121 result = PyUnicode_FromFormat("%s(%U, %U)",
2122 _PyType_Name(Py_TYPE(dd)),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 defrepr, baserepr);
2124 Py_DECREF(defrepr);
2125 Py_DECREF(baserepr);
2126 return result;
Guido van Rossum1968ad32006-02-25 22:38:04 +00002127}
2128
Brandt Bucher57c9d172020-03-06 09:24:08 -08002129static PyObject*
2130defdict_or(PyObject* left, PyObject* right)
2131{
Brandt Bucher57c9d172020-03-06 09:24:08 -08002132 PyObject *self, *other;
Brandt Bucher1dd37942020-03-11 21:06:46 -07002133 if (PyObject_TypeCheck(left, &defdict_type)) {
Brandt Bucher57c9d172020-03-06 09:24:08 -08002134 self = left;
2135 other = right;
2136 }
2137 else {
2138 self = right;
2139 other = left;
2140 }
2141 if (!PyDict_Check(other)) {
2142 Py_RETURN_NOTIMPLEMENTED;
2143 }
2144 // Like copy(), this calls the object's class.
2145 // Override __or__/__ror__ for subclasses with different constructors.
2146 PyObject *new = new_defdict((defdictobject*)self, left);
2147 if (!new) {
2148 return NULL;
2149 }
2150 if (PyDict_Update(new, right)) {
2151 Py_DECREF(new);
2152 return NULL;
2153 }
2154 return new;
2155}
2156
2157static PyNumberMethods defdict_as_number = {
2158 .nb_or = defdict_or,
2159};
2160
Guido van Rossum1968ad32006-02-25 22:38:04 +00002161static int
2162defdict_traverse(PyObject *self, visitproc visit, void *arg)
2163{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 Py_VISIT(((defdictobject *)self)->default_factory);
2165 return PyDict_Type.tp_traverse(self, visit, arg);
Guido van Rossum1968ad32006-02-25 22:38:04 +00002166}
2167
2168static int
2169defdict_tp_clear(defdictobject *dd)
2170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 Py_CLEAR(dd->default_factory);
2172 return PyDict_Type.tp_clear((PyObject *)dd);
Guido van Rossum1968ad32006-02-25 22:38:04 +00002173}
2174
2175static int
2176defdict_init(PyObject *self, PyObject *args, PyObject *kwds)
2177{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 defdictobject *dd = (defdictobject *)self;
2179 PyObject *olddefault = dd->default_factory;
2180 PyObject *newdefault = NULL;
2181 PyObject *newargs;
2182 int result;
2183 if (args == NULL || !PyTuple_Check(args))
2184 newargs = PyTuple_New(0);
2185 else {
2186 Py_ssize_t n = PyTuple_GET_SIZE(args);
2187 if (n > 0) {
2188 newdefault = PyTuple_GET_ITEM(args, 0);
2189 if (!PyCallable_Check(newdefault) && newdefault != Py_None) {
2190 PyErr_SetString(PyExc_TypeError,
Raymond Hettinger239aba72015-07-20 03:09:22 -04002191 "first argument must be callable or None");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002192 return -1;
2193 }
2194 }
2195 newargs = PySequence_GetSlice(args, 1, n);
2196 }
2197 if (newargs == NULL)
2198 return -1;
2199 Py_XINCREF(newdefault);
2200 dd->default_factory = newdefault;
2201 result = PyDict_Type.tp_init(self, newargs, kwds);
2202 Py_DECREF(newargs);
2203 Py_XDECREF(olddefault);
2204 return result;
Guido van Rossum1968ad32006-02-25 22:38:04 +00002205}
2206
2207PyDoc_STRVAR(defdict_doc,
Benjamin Peterson9cb33b72014-01-13 23:56:05 -05002208"defaultdict(default_factory[, ...]) --> dict with default factory\n\
Guido van Rossum1968ad32006-02-25 22:38:04 +00002209\n\
2210The default factory is called without arguments to produce\n\
2211a new value when a key is not present, in __getitem__ only.\n\
2212A defaultdict compares equal to a dict with the same items.\n\
Benjamin Peterson9cb33b72014-01-13 23:56:05 -05002213All remaining arguments are treated the same as if they were\n\
2214passed to the dict constructor, including keyword arguments.\n\
Guido van Rossum1968ad32006-02-25 22:38:04 +00002215");
2216
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002217/* See comment in xxsubtype.c */
2218#define DEFERRED_ADDRESS(ADDR) 0
2219
Guido van Rossum1968ad32006-02-25 22:38:04 +00002220static PyTypeObject defdict_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002221 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
2222 "collections.defaultdict", /* tp_name */
2223 sizeof(defdictobject), /* tp_basicsize */
2224 0, /* tp_itemsize */
2225 /* methods */
2226 (destructor)defdict_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002227 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002228 0, /* tp_getattr */
2229 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002230 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 (reprfunc)defdict_repr, /* tp_repr */
Brandt Bucher57c9d172020-03-06 09:24:08 -08002232 &defdict_as_number, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002233 0, /* tp_as_sequence */
2234 0, /* tp_as_mapping */
2235 0, /* tp_hash */
2236 0, /* tp_call */
2237 0, /* tp_str */
2238 PyObject_GenericGetAttr, /* tp_getattro */
2239 0, /* tp_setattro */
2240 0, /* tp_as_buffer */
2241 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
2242 /* tp_flags */
2243 defdict_doc, /* tp_doc */
2244 defdict_traverse, /* tp_traverse */
2245 (inquiry)defdict_tp_clear, /* tp_clear */
2246 0, /* tp_richcompare */
2247 0, /* tp_weaklistoffset*/
2248 0, /* tp_iter */
2249 0, /* tp_iternext */
2250 defdict_methods, /* tp_methods */
2251 defdict_members, /* tp_members */
2252 0, /* tp_getset */
2253 DEFERRED_ADDRESS(&PyDict_Type), /* tp_base */
2254 0, /* tp_dict */
2255 0, /* tp_descr_get */
2256 0, /* tp_descr_set */
2257 0, /* tp_dictoffset */
2258 defdict_init, /* tp_init */
2259 PyType_GenericAlloc, /* tp_alloc */
2260 0, /* tp_new */
2261 PyObject_GC_Del, /* tp_free */
Guido van Rossum1968ad32006-02-25 22:38:04 +00002262};
2263
Raymond Hettinger96f34102010-12-15 16:30:37 +00002264/* helper function for Counter *********************************************/
2265
Raymond Hettingere9858042019-06-05 16:05:25 -07002266/*[clinic input]
2267_collections._count_elements
2268
2269 mapping: object
2270 iterable: object
2271 /
2272
2273Count elements in the iterable, updating the mapping
2274[clinic start generated code]*/
Raymond Hettinger96f34102010-12-15 16:30:37 +00002275
2276static PyObject *
Raymond Hettingere9858042019-06-05 16:05:25 -07002277_collections__count_elements_impl(PyObject *module, PyObject *mapping,
2278 PyObject *iterable)
2279/*[clinic end generated code: output=7e0c1789636b3d8f input=e79fad04534a0b45]*/
Raymond Hettinger96f34102010-12-15 16:30:37 +00002280{
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002281 _Py_IDENTIFIER(get);
Raymond Hettinger2ff21902013-10-01 00:55:43 -07002282 _Py_IDENTIFIER(__setitem__);
Raymond Hettingere9858042019-06-05 16:05:25 -07002283 PyObject *it, *oldval;
Raymond Hettinger96f34102010-12-15 16:30:37 +00002284 PyObject *newval = NULL;
2285 PyObject *key = NULL;
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002286 PyObject *bound_get = NULL;
2287 PyObject *mapping_get;
2288 PyObject *dict_get;
Raymond Hettinger2ff21902013-10-01 00:55:43 -07002289 PyObject *mapping_setitem;
Raymond Hettinger2ff21902013-10-01 00:55:43 -07002290 PyObject *dict_setitem;
Victor Stinner35b95aa2020-10-27 22:24:33 +01002291 PyObject *one = _PyLong_GetOne(); // borrowed reference
Raymond Hettinger96f34102010-12-15 16:30:37 +00002292
Raymond Hettinger96f34102010-12-15 16:30:37 +00002293 it = PyObject_GetIter(iterable);
2294 if (it == NULL)
2295 return NULL;
Raymond Hettinger426e0522011-01-03 02:12:02 +00002296
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002297 /* Only take the fast path when get() and __setitem__()
2298 * have not been overridden.
2299 */
2300 mapping_get = _PyType_LookupId(Py_TYPE(mapping), &PyId_get);
2301 dict_get = _PyType_LookupId(&PyDict_Type, &PyId_get);
Raymond Hettinger2ff21902013-10-01 00:55:43 -07002302 mapping_setitem = _PyType_LookupId(Py_TYPE(mapping), &PyId___setitem__);
2303 dict_setitem = _PyType_LookupId(&PyDict_Type, &PyId___setitem__);
2304
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002305 if (mapping_get != NULL && mapping_get == dict_get &&
Oren Milman31aca4b2017-09-27 06:18:21 +03002306 mapping_setitem != NULL && mapping_setitem == dict_setitem &&
2307 PyDict_Check(mapping))
2308 {
Raymond Hettinger426e0522011-01-03 02:12:02 +00002309 while (1) {
Raymond Hettinger507d9972014-05-18 21:32:40 +01002310 /* Fast path advantages:
2311 1. Eliminate double hashing
2312 (by re-using the same hash for both the get and set)
2313 2. Avoid argument overhead of PyObject_CallFunctionObjArgs
2314 (argument tuple creation and parsing)
2315 3. Avoid indirection through a bound method object
2316 (creates another argument tuple)
2317 4. Avoid initial increment from zero
2318 (reuse an existing one-object instead)
2319 */
Raymond Hettinger4b0b1ac2014-05-03 16:41:19 -07002320 Py_hash_t hash;
2321
Raymond Hettinger426e0522011-01-03 02:12:02 +00002322 key = PyIter_Next(it);
Victor Stinnera154b5c2011-04-20 23:23:52 +02002323 if (key == NULL)
2324 break;
Raymond Hettinger4b0b1ac2014-05-03 16:41:19 -07002325
2326 if (!PyUnicode_CheckExact(key) ||
2327 (hash = ((PyASCIIObject *) key)->hash) == -1)
2328 {
2329 hash = PyObject_Hash(key);
Raymond Hettingerda2850f2015-02-27 12:42:54 -08002330 if (hash == -1)
Raymond Hettinger4b0b1ac2014-05-03 16:41:19 -07002331 goto done;
2332 }
2333
2334 oldval = _PyDict_GetItem_KnownHash(mapping, key, hash);
Raymond Hettinger426e0522011-01-03 02:12:02 +00002335 if (oldval == NULL) {
Serhiy Storchakaf0b311b2016-11-06 13:18:24 +02002336 if (PyErr_Occurred())
2337 goto done;
Victor Stinner35b95aa2020-10-27 22:24:33 +01002338 if (_PyDict_SetItem_KnownHash(mapping, key, one, hash) < 0)
Raymond Hettinger507d9972014-05-18 21:32:40 +01002339 goto done;
Raymond Hettinger426e0522011-01-03 02:12:02 +00002340 } else {
Victor Stinner35b95aa2020-10-27 22:24:33 +01002341 newval = PyNumber_Add(oldval, one);
Raymond Hettinger426e0522011-01-03 02:12:02 +00002342 if (newval == NULL)
Raymond Hettinger507d9972014-05-18 21:32:40 +01002343 goto done;
Raymond Hettinger28c995d2015-08-14 02:07:41 -07002344 if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) < 0)
Raymond Hettinger507d9972014-05-18 21:32:40 +01002345 goto done;
Raymond Hettinger426e0522011-01-03 02:12:02 +00002346 Py_CLEAR(newval);
2347 }
2348 Py_DECREF(key);
Raymond Hettinger96f34102010-12-15 16:30:37 +00002349 }
Victor Stinner35b95aa2020-10-27 22:24:33 +01002350 }
2351 else {
Victor Stinnere7f516c2013-11-06 23:52:55 +01002352 bound_get = _PyObject_GetAttrId(mapping, &PyId_get);
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002353 if (bound_get == NULL)
Raymond Hettinger224c87d2013-10-01 21:36:09 -07002354 goto done;
2355
Victor Stinner37834132020-10-27 17:12:53 +01002356 PyObject *zero = _PyLong_GetZero(); // borrowed reference
Raymond Hettinger426e0522011-01-03 02:12:02 +00002357 while (1) {
2358 key = PyIter_Next(it);
Victor Stinnera154b5c2011-04-20 23:23:52 +02002359 if (key == NULL)
2360 break;
Victor Stinner37834132020-10-27 17:12:53 +01002361 oldval = PyObject_CallFunctionObjArgs(bound_get, key, zero, NULL);
Raymond Hettinger224c87d2013-10-01 21:36:09 -07002362 if (oldval == NULL)
2363 break;
Victor Stinner37834132020-10-27 17:12:53 +01002364 newval = PyNumber_Add(oldval, one);
Raymond Hettinger224c87d2013-10-01 21:36:09 -07002365 Py_DECREF(oldval);
2366 if (newval == NULL)
2367 break;
Raymond Hettinger28c995d2015-08-14 02:07:41 -07002368 if (PyObject_SetItem(mapping, key, newval) < 0)
Raymond Hettinger96f34102010-12-15 16:30:37 +00002369 break;
2370 Py_CLEAR(newval);
Raymond Hettinger426e0522011-01-03 02:12:02 +00002371 Py_DECREF(key);
Raymond Hettinger96f34102010-12-15 16:30:37 +00002372 }
Raymond Hettinger96f34102010-12-15 16:30:37 +00002373 }
Raymond Hettinger426e0522011-01-03 02:12:02 +00002374
Raymond Hettinger224c87d2013-10-01 21:36:09 -07002375done:
Raymond Hettinger96f34102010-12-15 16:30:37 +00002376 Py_DECREF(it);
2377 Py_XDECREF(key);
2378 Py_XDECREF(newval);
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002379 Py_XDECREF(bound_get);
Raymond Hettinger96f34102010-12-15 16:30:37 +00002380 if (PyErr_Occurred())
2381 return NULL;
2382 Py_RETURN_NONE;
2383}
2384
Serhiy Storchaka052b2df2018-12-31 14:15:16 +02002385/* Helper function for namedtuple() ************************************/
Pablo Galindo3f5fc702018-12-30 09:24:03 +00002386
2387typedef struct {
2388 PyObject_HEAD
2389 Py_ssize_t index;
2390 PyObject* doc;
2391} _tuplegetterobject;
2392
2393/*[clinic input]
2394@classmethod
2395_tuplegetter.__new__ as tuplegetter_new
2396
2397 index: Py_ssize_t
2398 doc: object
2399 /
2400[clinic start generated code]*/
2401
2402static PyObject *
2403tuplegetter_new_impl(PyTypeObject *type, Py_ssize_t index, PyObject *doc)
2404/*[clinic end generated code: output=014be444ad80263f input=87c576a5bdbc0bbb]*/
2405{
2406 _tuplegetterobject* self;
2407 self = (_tuplegetterobject *)type->tp_alloc(type, 0);
2408 if (self == NULL) {
2409 return NULL;
2410 }
2411 self->index = index;
2412 Py_INCREF(doc);
2413 self->doc = doc;
2414 return (PyObject *)self;
2415}
2416
2417static PyObject *
Serhiy Storchaka052b2df2018-12-31 14:15:16 +02002418tuplegetter_descr_get(PyObject *self, PyObject *obj, PyObject *type)
Pablo Galindo3f5fc702018-12-30 09:24:03 +00002419{
Serhiy Storchaka052b2df2018-12-31 14:15:16 +02002420 Py_ssize_t index = ((_tuplegetterobject*)self)->index;
Pablo Galindo3f5fc702018-12-30 09:24:03 +00002421 PyObject *result;
Serhiy Storchaka052b2df2018-12-31 14:15:16 +02002422
Pablo Galindo3f5fc702018-12-30 09:24:03 +00002423 if (obj == NULL) {
2424 Py_INCREF(self);
2425 return self;
2426 }
2427 if (!PyTuple_Check(obj)) {
2428 if (obj == Py_None) {
2429 Py_INCREF(self);
2430 return self;
2431 }
2432 PyErr_Format(PyExc_TypeError,
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +02002433 "descriptor for index '%zd' for tuple subclasses "
Pablo Galindo3f5fc702018-12-30 09:24:03 +00002434 "doesn't apply to '%s' object",
Serhiy Storchaka052b2df2018-12-31 14:15:16 +02002435 index,
Victor Stinnerdaa97562020-02-07 03:37:06 +01002436 Py_TYPE(obj)->tp_name);
Pablo Galindo3f5fc702018-12-30 09:24:03 +00002437 return NULL;
2438 }
2439
Pablo Galindo3f5fc702018-12-30 09:24:03 +00002440 if (!valid_index(index, PyTuple_GET_SIZE(obj))) {
2441 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
2442 return NULL;
2443 }
2444
2445 result = PyTuple_GET_ITEM(obj, index);
2446 Py_INCREF(result);
2447 return result;
2448}
2449
2450static int
Serhiy Storchaka052b2df2018-12-31 14:15:16 +02002451tuplegetter_descr_set(PyObject *self, PyObject *obj, PyObject *value)
Pablo Galindo3f5fc702018-12-30 09:24:03 +00002452{
2453 if (value == NULL) {
2454 PyErr_SetString(PyExc_AttributeError, "can't delete attribute");
2455 } else {
2456 PyErr_SetString(PyExc_AttributeError, "can't set attribute");
2457 }
2458 return -1;
2459}
2460
2461static int
2462tuplegetter_traverse(PyObject *self, visitproc visit, void *arg)
2463{
2464 _tuplegetterobject *tuplegetter = (_tuplegetterobject *)self;
2465 Py_VISIT(tuplegetter->doc);
2466 return 0;
2467}
2468
2469static int
2470tuplegetter_clear(PyObject *self)
2471{
2472 _tuplegetterobject *tuplegetter = (_tuplegetterobject *)self;
2473 Py_CLEAR(tuplegetter->doc);
2474 return 0;
2475}
2476
2477static void
2478tuplegetter_dealloc(_tuplegetterobject *self)
2479{
2480 PyObject_GC_UnTrack(self);
2481 tuplegetter_clear((PyObject*)self);
2482 Py_TYPE(self)->tp_free((PyObject*)self);
2483}
2484
Joe Jevnikf36f8922019-02-21 16:00:40 -05002485static PyObject*
Serhiy Storchakaadfffc72019-03-05 18:41:09 +02002486tuplegetter_reduce(_tuplegetterobject *self, PyObject *Py_UNUSED(ignored))
Joe Jevnikf36f8922019-02-21 16:00:40 -05002487{
2488 return Py_BuildValue("(O(nO))", (PyObject*) Py_TYPE(self), self->index, self->doc);
2489}
2490
Ammar Askara86b5222020-04-14 23:36:08 -07002491static PyObject*
2492tuplegetter_repr(_tuplegetterobject *self)
2493{
2494 return PyUnicode_FromFormat("%s(%zd, %R)",
2495 _PyType_Name(Py_TYPE(self)),
2496 self->index, self->doc);
2497}
2498
Pablo Galindo3f5fc702018-12-30 09:24:03 +00002499
2500static PyMemberDef tuplegetter_members[] = {
2501 {"__doc__", T_OBJECT, offsetof(_tuplegetterobject, doc), 0},
2502 {0}
2503};
2504
Joe Jevnikf36f8922019-02-21 16:00:40 -05002505static PyMethodDef tuplegetter_methods[] = {
Serhiy Storchakaadfffc72019-03-05 18:41:09 +02002506 {"__reduce__", (PyCFunction)tuplegetter_reduce, METH_NOARGS, NULL},
Joe Jevnikf36f8922019-02-21 16:00:40 -05002507 {NULL},
2508};
2509
Pablo Galindo3f5fc702018-12-30 09:24:03 +00002510static PyTypeObject tuplegetter_type = {
2511 PyVarObject_HEAD_INIT(NULL, 0)
2512 "_collections._tuplegetter", /* tp_name */
2513 sizeof(_tuplegetterobject), /* tp_basicsize */
2514 0, /* tp_itemsize */
2515 /* methods */
2516 (destructor)tuplegetter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002517 0, /* tp_vectorcall_offset */
Pablo Galindo3f5fc702018-12-30 09:24:03 +00002518 0, /* tp_getattr */
2519 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002520 0, /* tp_as_async */
Ammar Askara86b5222020-04-14 23:36:08 -07002521 (reprfunc)tuplegetter_repr, /* tp_repr */
Pablo Galindo3f5fc702018-12-30 09:24:03 +00002522 0, /* tp_as_number */
2523 0, /* tp_as_sequence */
2524 0, /* tp_as_mapping */
2525 0, /* tp_hash */
2526 0, /* tp_call */
2527 0, /* tp_str */
2528 0, /* tp_getattro */
2529 0, /* tp_setattro */
2530 0, /* tp_as_buffer */
2531 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2532 0, /* tp_doc */
2533 (traverseproc)tuplegetter_traverse, /* tp_traverse */
2534 (inquiry)tuplegetter_clear, /* tp_clear */
2535 0, /* tp_richcompare */
2536 0, /* tp_weaklistoffset */
2537 0, /* tp_iter */
2538 0, /* tp_iternext */
Joe Jevnikf36f8922019-02-21 16:00:40 -05002539 tuplegetter_methods, /* tp_methods */
Pablo Galindo3f5fc702018-12-30 09:24:03 +00002540 tuplegetter_members, /* tp_members */
2541 0, /* tp_getset */
2542 0, /* tp_base */
2543 0, /* tp_dict */
Serhiy Storchaka052b2df2018-12-31 14:15:16 +02002544 tuplegetter_descr_get, /* tp_descr_get */
2545 tuplegetter_descr_set, /* tp_descr_set */
Pablo Galindo3f5fc702018-12-30 09:24:03 +00002546 0, /* tp_dictoffset */
2547 0, /* tp_init */
2548 0, /* tp_alloc */
2549 tuplegetter_new, /* tp_new */
2550 0,
2551};
2552
2553
Raymond Hettinger756b3f32004-01-29 06:37:52 +00002554/* module level code ********************************************************/
2555
Dong-hee Na77248a22020-03-20 01:16:04 +09002556PyDoc_STRVAR(collections_doc,
Guido van Rossum1968ad32006-02-25 22:38:04 +00002557"High performance data structures.\n\
2558- deque: ordered collection accessible from endpoints only\n\
2559- defaultdict: dict subclass with a default value factory\n\
Raymond Hettinger756b3f32004-01-29 06:37:52 +00002560");
2561
Dong-hee Na77248a22020-03-20 01:16:04 +09002562static struct PyMethodDef collections_methods[] = {
Raymond Hettingere9858042019-06-05 16:05:25 -07002563 _COLLECTIONS__COUNT_ELEMENTS_METHODDEF
Raymond Hettinger96f34102010-12-15 16:30:37 +00002564 {NULL, NULL} /* sentinel */
2565};
Martin v. Löwis1a214512008-06-11 05:26:20 +00002566
Dong-hee Na77248a22020-03-20 01:16:04 +09002567static int
2568collections_exec(PyObject *module) {
2569 PyTypeObject *typelist[] = {
2570 &deque_type,
2571 &defdict_type,
2572 &PyODict_Type,
2573 &dequeiter_type,
2574 &dequereviter_type,
Dong-hee Na05e4a292020-03-23 01:17:34 +09002575 &tuplegetter_type
Dong-hee Na77248a22020-03-20 01:16:04 +09002576 };
2577
2578 defdict_type.tp_base = &PyDict_Type;
2579
Dong-hee Na05e4a292020-03-23 01:17:34 +09002580 for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) {
2581 if (PyModule_AddType(module, typelist[i]) < 0) {
Dong-hee Na77248a22020-03-20 01:16:04 +09002582 return -1;
2583 }
2584 }
2585
2586 return 0;
2587}
2588
2589static struct PyModuleDef_Slot collections_slots[] = {
2590 {Py_mod_exec, collections_exec},
2591 {0, NULL}
2592};
2593
Martin v. Löwis1a214512008-06-11 05:26:20 +00002594static struct PyModuleDef _collectionsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002595 PyModuleDef_HEAD_INIT,
2596 "_collections",
Dong-hee Na77248a22020-03-20 01:16:04 +09002597 collections_doc,
2598 0,
2599 collections_methods,
2600 collections_slots,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002601 NULL,
2602 NULL,
2603 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002604};
2605
Raymond Hettinger756b3f32004-01-29 06:37:52 +00002606PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002607PyInit__collections(void)
Raymond Hettinger756b3f32004-01-29 06:37:52 +00002608{
Dong-hee Na77248a22020-03-20 01:16:04 +09002609 return PyModuleDef_Init(&_collectionsmodule);
Raymond Hettinger756b3f32004-01-29 06:37:52 +00002610}