Line data Source code
1 : #define PY_SSIZE_T_CLEAN
2 : #include "Python.h"
3 : #include "pycore_call.h" // _PyObject_CallNoArgs()
4 : #include "pycore_long.h" // _PyLong_GetZero()
5 : #include "pycore_object.h" // _PyObject_GC_TRACK()
6 : #include "pycore_tuple.h" // _PyTuple_ITEMS()
7 : #include <stddef.h> // offsetof()
8 :
9 : /* Itertools module written and maintained
10 : by Raymond D. Hettinger <python@rcn.com>
11 : */
12 :
13 : /*[clinic input]
14 : module itertools
15 : class itertools.groupby "groupbyobject *" "&groupby_type"
16 : class itertools._grouper "_grouperobject *" "&_grouper_type"
17 : class itertools.teedataobject "teedataobject *" "&teedataobject_type"
18 : class itertools._tee "teeobject *" "&tee_type"
19 : class itertools.cycle "cycleobject *" "&cycle_type"
20 : class itertools.dropwhile "dropwhileobject *" "&dropwhile_type"
21 : class itertools.takewhile "takewhileobject *" "&takewhile_type"
22 : class itertools.starmap "starmapobject *" "&starmap_type"
23 : class itertools.chain "chainobject *" "&chain_type"
24 : class itertools.combinations "combinationsobject *" "&combinations_type"
25 : class itertools.combinations_with_replacement "cwr_object *" "&cwr_type"
26 : class itertools.permutations "permutationsobject *" "&permutations_type"
27 : class itertools.accumulate "accumulateobject *" "&accumulate_type"
28 : class itertools.compress "compressobject *" "&compress_type"
29 : class itertools.filterfalse "filterfalseobject *" "&filterfalse_type"
30 : class itertools.count "countobject *" "&count_type"
31 : class itertools.pairwise "pairwiseobject *" "&pairwise_type"
32 : [clinic start generated code]*/
33 : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=6498ed21fbe1bf94]*/
34 :
35 : static PyTypeObject groupby_type;
36 : static PyTypeObject _grouper_type;
37 : static PyTypeObject teedataobject_type;
38 : static PyTypeObject tee_type;
39 : static PyTypeObject cycle_type;
40 : static PyTypeObject dropwhile_type;
41 : static PyTypeObject takewhile_type;
42 : static PyTypeObject starmap_type;
43 : static PyTypeObject combinations_type;
44 : static PyTypeObject cwr_type;
45 : static PyTypeObject permutations_type;
46 : static PyTypeObject accumulate_type;
47 : static PyTypeObject compress_type;
48 : static PyTypeObject filterfalse_type;
49 : static PyTypeObject count_type;
50 : static PyTypeObject pairwise_type;
51 :
52 : #include "clinic/itertoolsmodule.c.h"
53 :
54 : /* pairwise object ***********************************************************/
55 :
56 : typedef struct {
57 : PyObject_HEAD
58 : PyObject *it;
59 : PyObject *old;
60 : } pairwiseobject;
61 :
62 : /*[clinic input]
63 : @classmethod
64 : itertools.pairwise.__new__ as pairwise_new
65 : iterable: object
66 : /
67 : Return an iterator of overlapping pairs taken from the input iterator.
68 :
69 : s -> (s0,s1), (s1,s2), (s2, s3), ...
70 :
71 : [clinic start generated code]*/
72 :
73 : static PyObject *
74 52 : pairwise_new_impl(PyTypeObject *type, PyObject *iterable)
75 : /*[clinic end generated code: output=9f0267062d384456 input=6e7c3cddb431a8d6]*/
76 : {
77 : PyObject *it;
78 : pairwiseobject *po;
79 :
80 52 : it = PyObject_GetIter(iterable);
81 52 : if (it == NULL) {
82 11 : return NULL;
83 : }
84 41 : po = (pairwiseobject *)type->tp_alloc(type, 0);
85 41 : if (po == NULL) {
86 0 : Py_DECREF(it);
87 0 : return NULL;
88 : }
89 41 : po->it = it;
90 41 : po->old = NULL;
91 41 : return (PyObject *)po;
92 : }
93 :
94 : static void
95 41 : pairwise_dealloc(pairwiseobject *po)
96 : {
97 41 : PyObject_GC_UnTrack(po);
98 41 : Py_XDECREF(po->it);
99 41 : Py_XDECREF(po->old);
100 41 : Py_TYPE(po)->tp_free(po);
101 41 : }
102 :
103 : static int
104 8 : pairwise_traverse(pairwiseobject *po, visitproc visit, void *arg)
105 : {
106 8 : Py_VISIT(po->it);
107 8 : Py_VISIT(po->old);
108 8 : return 0;
109 : }
110 :
111 : static PyObject *
112 15250 : pairwise_next(pairwiseobject *po)
113 : {
114 15250 : PyObject *it = po->it;
115 15250 : PyObject *old = po->old;
116 : PyObject *new, *result;
117 :
118 15250 : if (it == NULL) {
119 0 : return NULL;
120 : }
121 15250 : if (old == NULL) {
122 41 : po->old = old = (*Py_TYPE(it)->tp_iternext)(it);
123 41 : if (old == NULL) {
124 16 : Py_CLEAR(po->it);
125 16 : return NULL;
126 : }
127 : }
128 15234 : new = (*Py_TYPE(it)->tp_iternext)(it);
129 15234 : if (new == NULL) {
130 24 : Py_CLEAR(po->it);
131 24 : Py_CLEAR(po->old);
132 24 : return NULL;
133 : }
134 : /* Future optimization: Reuse the result tuple as we do in enumerate() */
135 15210 : result = PyTuple_Pack(2, old, new);
136 15210 : Py_SETREF(po->old, new);
137 15210 : return result;
138 : }
139 :
140 : static PyTypeObject pairwise_type = {
141 : PyVarObject_HEAD_INIT(&PyType_Type, 0)
142 : "itertools.pairwise", /* tp_name */
143 : sizeof(pairwiseobject), /* tp_basicsize */
144 : 0, /* tp_itemsize */
145 : /* methods */
146 : (destructor)pairwise_dealloc, /* tp_dealloc */
147 : 0, /* tp_vectorcall_offset */
148 : 0, /* tp_getattr */
149 : 0, /* tp_setattr */
150 : 0, /* tp_as_async */
151 : 0, /* tp_repr */
152 : 0, /* tp_as_number */
153 : 0, /* tp_as_sequence */
154 : 0, /* tp_as_mapping */
155 : 0, /* tp_hash */
156 : 0, /* tp_call */
157 : 0, /* tp_str */
158 : PyObject_GenericGetAttr, /* tp_getattro */
159 : 0, /* tp_setattro */
160 : 0, /* tp_as_buffer */
161 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
162 : Py_TPFLAGS_BASETYPE, /* tp_flags */
163 : pairwise_new__doc__, /* tp_doc */
164 : (traverseproc)pairwise_traverse, /* tp_traverse */
165 : 0, /* tp_clear */
166 : 0, /* tp_richcompare */
167 : 0, /* tp_weaklistoffset */
168 : PyObject_SelfIter, /* tp_iter */
169 : (iternextfunc)pairwise_next, /* tp_iternext */
170 : 0, /* tp_methods */
171 : 0, /* tp_members */
172 : 0, /* tp_getset */
173 : 0, /* tp_base */
174 : 0, /* tp_dict */
175 : 0, /* tp_descr_get */
176 : 0, /* tp_descr_set */
177 : 0, /* tp_dictoffset */
178 : 0, /* tp_init */
179 : PyType_GenericAlloc, /* tp_alloc */
180 : pairwise_new, /* tp_new */
181 : PyObject_GC_Del, /* tp_free */
182 : };
183 :
184 :
185 : /* groupby object ************************************************************/
186 :
187 : typedef struct {
188 : PyObject_HEAD
189 : PyObject *it;
190 : PyObject *keyfunc;
191 : PyObject *tgtkey;
192 : PyObject *currkey;
193 : PyObject *currvalue;
194 : const void *currgrouper; /* borrowed reference */
195 : } groupbyobject;
196 :
197 : static PyObject *_grouper_create(groupbyobject *, PyObject *);
198 :
199 : /*[clinic input]
200 : @classmethod
201 : itertools.groupby.__new__
202 :
203 : iterable as it: object
204 : Elements to divide into groups according to the key function.
205 : key as keyfunc: object = None
206 : A function for computing the group category for each element.
207 : If the key function is not specified or is None, the element itself
208 : is used for grouping.
209 :
210 : make an iterator that returns consecutive keys and groups from the iterable
211 : [clinic start generated code]*/
212 :
213 : static PyObject *
214 3253 : itertools_groupby_impl(PyTypeObject *type, PyObject *it, PyObject *keyfunc)
215 : /*[clinic end generated code: output=cbb1ae3a90fd4141 input=6b3d123e87ff65a1]*/
216 : {
217 : groupbyobject *gbo;
218 :
219 3253 : gbo = (groupbyobject *)type->tp_alloc(type, 0);
220 3253 : if (gbo == NULL)
221 0 : return NULL;
222 3253 : gbo->tgtkey = NULL;
223 3253 : gbo->currkey = NULL;
224 3253 : gbo->currvalue = NULL;
225 3253 : gbo->keyfunc = keyfunc;
226 3253 : Py_INCREF(keyfunc);
227 3253 : gbo->it = PyObject_GetIter(it);
228 3253 : if (gbo->it == NULL) {
229 31 : Py_DECREF(gbo);
230 31 : return NULL;
231 : }
232 3222 : return (PyObject *)gbo;
233 : }
234 :
235 : static void
236 3253 : groupby_dealloc(groupbyobject *gbo)
237 : {
238 3253 : PyObject_GC_UnTrack(gbo);
239 3253 : Py_XDECREF(gbo->it);
240 3253 : Py_XDECREF(gbo->keyfunc);
241 3253 : Py_XDECREF(gbo->tgtkey);
242 3253 : Py_XDECREF(gbo->currkey);
243 3253 : Py_XDECREF(gbo->currvalue);
244 3253 : Py_TYPE(gbo)->tp_free(gbo);
245 3253 : }
246 :
247 : static int
248 8 : groupby_traverse(groupbyobject *gbo, visitproc visit, void *arg)
249 : {
250 8 : Py_VISIT(gbo->it);
251 8 : Py_VISIT(gbo->keyfunc);
252 8 : Py_VISIT(gbo->tgtkey);
253 8 : Py_VISIT(gbo->currkey);
254 8 : Py_VISIT(gbo->currvalue);
255 8 : return 0;
256 : }
257 :
258 : Py_LOCAL_INLINE(int)
259 254136 : groupby_step(groupbyobject *gbo)
260 : {
261 : PyObject *newvalue, *newkey, *oldvalue;
262 :
263 254136 : newvalue = PyIter_Next(gbo->it);
264 254136 : if (newvalue == NULL)
265 3871 : return -1;
266 :
267 250265 : if (gbo->keyfunc == Py_None) {
268 18572 : newkey = newvalue;
269 18572 : Py_INCREF(newvalue);
270 : } else {
271 231693 : newkey = PyObject_CallOneArg(gbo->keyfunc, newvalue);
272 231693 : if (newkey == NULL) {
273 3 : Py_DECREF(newvalue);
274 3 : return -1;
275 : }
276 : }
277 :
278 250262 : oldvalue = gbo->currvalue;
279 250262 : gbo->currvalue = newvalue;
280 250262 : Py_XSETREF(gbo->currkey, newkey);
281 250262 : Py_XDECREF(oldvalue);
282 250262 : return 0;
283 : }
284 :
285 : static PyObject *
286 119538 : groupby_next(groupbyobject *gbo)
287 : {
288 : PyObject *r, *grouper;
289 :
290 119538 : gbo->currgrouper = NULL;
291 : /* skip to next iteration group */
292 : for (;;) {
293 138908 : if (gbo->currkey == NULL)
294 : /* pass */;
295 135029 : else if (gbo->tgtkey == NULL)
296 3112 : break;
297 : else {
298 : int rcmp;
299 :
300 131917 : rcmp = PyObject_RichCompareBool(gbo->tgtkey, gbo->currkey, Py_EQ);
301 131917 : if (rcmp == -1)
302 1 : return NULL;
303 131916 : else if (rcmp == 0)
304 113284 : break;
305 : }
306 :
307 22511 : if (groupby_step(gbo) < 0)
308 3141 : return NULL;
309 : }
310 116396 : Py_INCREF(gbo->currkey);
311 116396 : Py_XSETREF(gbo->tgtkey, gbo->currkey);
312 :
313 116396 : grouper = _grouper_create(gbo, gbo->tgtkey);
314 116396 : if (grouper == NULL)
315 0 : return NULL;
316 :
317 116396 : r = PyTuple_Pack(2, gbo->currkey, grouper);
318 116396 : Py_DECREF(grouper);
319 116396 : return r;
320 : }
321 :
322 : static PyObject *
323 60 : groupby_reduce(groupbyobject *lz, PyObject *Py_UNUSED(ignored))
324 : {
325 : /* reduce as a 'new' call with an optional 'setstate' if groupby
326 : * has started
327 : */
328 : PyObject *value;
329 60 : if (lz->tgtkey && lz->currkey && lz->currvalue)
330 24 : value = Py_BuildValue("O(OO)(OOO)", Py_TYPE(lz),
331 : lz->it, lz->keyfunc, lz->currkey, lz->currvalue, lz->tgtkey);
332 : else
333 36 : value = Py_BuildValue("O(OO)", Py_TYPE(lz),
334 : lz->it, lz->keyfunc);
335 :
336 60 : return value;
337 : }
338 :
339 : PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
340 :
341 : static PyObject *
342 24 : groupby_setstate(groupbyobject *lz, PyObject *state)
343 : {
344 : PyObject *currkey, *currvalue, *tgtkey;
345 24 : if (!PyTuple_Check(state)) {
346 0 : PyErr_SetString(PyExc_TypeError, "state is not a tuple");
347 0 : return NULL;
348 : }
349 24 : if (!PyArg_ParseTuple(state, "OOO", &currkey, &currvalue, &tgtkey)) {
350 0 : return NULL;
351 : }
352 24 : Py_INCREF(currkey);
353 24 : Py_XSETREF(lz->currkey, currkey);
354 24 : Py_INCREF(currvalue);
355 24 : Py_XSETREF(lz->currvalue, currvalue);
356 24 : Py_INCREF(tgtkey);
357 24 : Py_XSETREF(lz->tgtkey, tgtkey);
358 24 : Py_RETURN_NONE;
359 : }
360 :
361 : PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
362 :
363 : static PyMethodDef groupby_methods[] = {
364 : {"__reduce__", (PyCFunction)groupby_reduce, METH_NOARGS,
365 : reduce_doc},
366 : {"__setstate__", (PyCFunction)groupby_setstate, METH_O,
367 : setstate_doc},
368 : {NULL, NULL} /* sentinel */
369 : };
370 :
371 : static PyTypeObject groupby_type = {
372 : PyVarObject_HEAD_INIT(NULL, 0)
373 : "itertools.groupby", /* tp_name */
374 : sizeof(groupbyobject), /* tp_basicsize */
375 : 0, /* tp_itemsize */
376 : /* methods */
377 : (destructor)groupby_dealloc, /* tp_dealloc */
378 : 0, /* tp_vectorcall_offset */
379 : 0, /* tp_getattr */
380 : 0, /* tp_setattr */
381 : 0, /* tp_as_async */
382 : 0, /* tp_repr */
383 : 0, /* tp_as_number */
384 : 0, /* tp_as_sequence */
385 : 0, /* tp_as_mapping */
386 : 0, /* tp_hash */
387 : 0, /* tp_call */
388 : 0, /* tp_str */
389 : PyObject_GenericGetAttr, /* tp_getattro */
390 : 0, /* tp_setattro */
391 : 0, /* tp_as_buffer */
392 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
393 : Py_TPFLAGS_BASETYPE, /* tp_flags */
394 : itertools_groupby__doc__, /* tp_doc */
395 : (traverseproc)groupby_traverse, /* tp_traverse */
396 : 0, /* tp_clear */
397 : 0, /* tp_richcompare */
398 : 0, /* tp_weaklistoffset */
399 : PyObject_SelfIter, /* tp_iter */
400 : (iternextfunc)groupby_next, /* tp_iternext */
401 : groupby_methods, /* tp_methods */
402 : 0, /* tp_members */
403 : 0, /* tp_getset */
404 : 0, /* tp_base */
405 : 0, /* tp_dict */
406 : 0, /* tp_descr_get */
407 : 0, /* tp_descr_set */
408 : 0, /* tp_dictoffset */
409 : 0, /* tp_init */
410 : 0, /* tp_alloc */
411 : itertools_groupby, /* tp_new */
412 : PyObject_GC_Del, /* tp_free */
413 : };
414 :
415 :
416 : /* _grouper object (internal) ************************************************/
417 :
418 : typedef struct {
419 : PyObject_HEAD
420 : PyObject *parent;
421 : PyObject *tgtkey;
422 : } _grouperobject;
423 :
424 : /*[clinic input]
425 : @classmethod
426 : itertools._grouper.__new__
427 :
428 : parent: object(subclass_of='&groupby_type')
429 : tgtkey: object
430 : /
431 : [clinic start generated code]*/
432 :
433 : static PyObject *
434 24 : itertools__grouper_impl(PyTypeObject *type, PyObject *parent,
435 : PyObject *tgtkey)
436 : /*[clinic end generated code: output=462efb1cdebb5914 input=dc180d7771fc8c59]*/
437 : {
438 24 : return _grouper_create((groupbyobject*) parent, tgtkey);
439 : }
440 :
441 : static PyObject *
442 116420 : _grouper_create(groupbyobject *parent, PyObject *tgtkey)
443 : {
444 : _grouperobject *igo;
445 :
446 116420 : igo = PyObject_GC_New(_grouperobject, &_grouper_type);
447 116420 : if (igo == NULL)
448 0 : return NULL;
449 116420 : igo->parent = (PyObject *)parent;
450 116420 : Py_INCREF(parent);
451 116420 : igo->tgtkey = tgtkey;
452 116420 : Py_INCREF(tgtkey);
453 116420 : parent->currgrouper = igo; /* borrowed reference */
454 :
455 116420 : PyObject_GC_Track(igo);
456 116420 : return (PyObject *)igo;
457 : }
458 :
459 : static void
460 116420 : _grouper_dealloc(_grouperobject *igo)
461 : {
462 116420 : PyObject_GC_UnTrack(igo);
463 116420 : Py_DECREF(igo->parent);
464 116420 : Py_DECREF(igo->tgtkey);
465 116420 : PyObject_GC_Del(igo);
466 116420 : }
467 :
468 : static int
469 116444 : _grouper_traverse(_grouperobject *igo, visitproc visit, void *arg)
470 : {
471 116444 : Py_VISIT(igo->parent);
472 116444 : Py_VISIT(igo->tgtkey);
473 116444 : return 0;
474 : }
475 :
476 : static PyObject *
477 335581 : _grouper_next(_grouperobject *igo)
478 : {
479 335581 : groupbyobject *gbo = (groupbyobject *)igo->parent;
480 : PyObject *r;
481 : int rcmp;
482 :
483 335581 : if (gbo->currgrouper != igo)
484 3 : return NULL;
485 335578 : if (gbo->currvalue == NULL) {
486 231625 : if (groupby_step(gbo) < 0)
487 733 : return NULL;
488 : }
489 :
490 334845 : assert(gbo->currkey != NULL);
491 334845 : rcmp = PyObject_RichCompareBool(igo->tgtkey, gbo->currkey, Py_EQ);
492 334845 : if (rcmp <= 0)
493 : /* got any error or current group is end */
494 103218 : return NULL;
495 :
496 231627 : r = gbo->currvalue;
497 231627 : gbo->currvalue = NULL;
498 231627 : Py_CLEAR(gbo->currkey);
499 :
500 231627 : return r;
501 : }
502 :
503 : static PyObject *
504 30 : _grouper_reduce(_grouperobject *lz, PyObject *Py_UNUSED(ignored))
505 : {
506 30 : if (((groupbyobject *)lz->parent)->currgrouper != lz) {
507 6 : return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter)));
508 : }
509 24 : return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->parent, lz->tgtkey);
510 : }
511 :
512 : static PyMethodDef _grouper_methods[] = {
513 : {"__reduce__", (PyCFunction)_grouper_reduce, METH_NOARGS,
514 : reduce_doc},
515 : {NULL, NULL} /* sentinel */
516 : };
517 :
518 :
519 : static PyTypeObject _grouper_type = {
520 : PyVarObject_HEAD_INIT(NULL, 0)
521 : "itertools._grouper", /* tp_name */
522 : sizeof(_grouperobject), /* tp_basicsize */
523 : 0, /* tp_itemsize */
524 : /* methods */
525 : (destructor)_grouper_dealloc, /* tp_dealloc */
526 : 0, /* tp_vectorcall_offset */
527 : 0, /* tp_getattr */
528 : 0, /* tp_setattr */
529 : 0, /* tp_as_async */
530 : 0, /* tp_repr */
531 : 0, /* tp_as_number */
532 : 0, /* tp_as_sequence */
533 : 0, /* tp_as_mapping */
534 : 0, /* tp_hash */
535 : 0, /* tp_call */
536 : 0, /* tp_str */
537 : PyObject_GenericGetAttr, /* tp_getattro */
538 : 0, /* tp_setattro */
539 : 0, /* tp_as_buffer */
540 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
541 : 0, /* tp_doc */
542 : (traverseproc)_grouper_traverse, /* tp_traverse */
543 : 0, /* tp_clear */
544 : 0, /* tp_richcompare */
545 : 0, /* tp_weaklistoffset */
546 : PyObject_SelfIter, /* tp_iter */
547 : (iternextfunc)_grouper_next, /* tp_iternext */
548 : _grouper_methods, /* tp_methods */
549 : 0, /* tp_members */
550 : 0, /* tp_getset */
551 : 0, /* tp_base */
552 : 0, /* tp_dict */
553 : 0, /* tp_descr_get */
554 : 0, /* tp_descr_set */
555 : 0, /* tp_dictoffset */
556 : 0, /* tp_init */
557 : 0, /* tp_alloc */
558 : itertools__grouper, /* tp_new */
559 : PyObject_GC_Del, /* tp_free */
560 : };
561 :
562 :
563 : /* tee object and with supporting function and objects ***********************/
564 :
565 : /* The teedataobject pre-allocates space for LINKCELLS number of objects.
566 : To help the object fit neatly inside cache lines (space for 16 to 32
567 : pointers), the value should be a multiple of 16 minus space for
568 : the other structure members including PyHEAD overhead. The larger the
569 : value, the less memory overhead per object and the less time spent
570 : allocating/deallocating new links. The smaller the number, the less
571 : wasted space and the more rapid freeing of older data.
572 : */
573 : #define LINKCELLS 57
574 :
575 : typedef struct {
576 : PyObject_HEAD
577 : PyObject *it;
578 : int numread; /* 0 <= numread <= LINKCELLS */
579 : int running;
580 : PyObject *nextlink;
581 : PyObject *(values[LINKCELLS]);
582 : } teedataobject;
583 :
584 : typedef struct {
585 : PyObject_HEAD
586 : teedataobject *dataobj;
587 : int index; /* 0 <= index <= LINKCELLS */
588 : PyObject *weakreflist;
589 : } teeobject;
590 :
591 : static PyObject *
592 352736 : teedataobject_newinternal(PyObject *it)
593 : {
594 : teedataobject *tdo;
595 :
596 352736 : tdo = PyObject_GC_New(teedataobject, &teedataobject_type);
597 352736 : if (tdo == NULL)
598 0 : return NULL;
599 :
600 352736 : tdo->running = 0;
601 352736 : tdo->numread = 0;
602 352736 : tdo->nextlink = NULL;
603 352736 : Py_INCREF(it);
604 352736 : tdo->it = it;
605 352736 : PyObject_GC_Track(tdo);
606 352736 : return (PyObject *)tdo;
607 : }
608 :
609 : static PyObject *
610 353777 : teedataobject_jumplink(teedataobject *tdo)
611 : {
612 353777 : if (tdo->nextlink == NULL)
613 352487 : tdo->nextlink = teedataobject_newinternal(tdo->it);
614 353777 : Py_XINCREF(tdo->nextlink);
615 353777 : return tdo->nextlink;
616 : }
617 :
618 : static PyObject *
619 20168500 : teedataobject_getitem(teedataobject *tdo, int i)
620 : {
621 : PyObject *value;
622 :
623 20168500 : assert(i < LINKCELLS);
624 20168500 : if (i < tdo->numread)
625 75015 : value = tdo->values[i];
626 : else {
627 : /* this is the lead iterator, so fetch more data */
628 20093400 : assert(i == tdo->numread);
629 20093400 : if (tdo->running) {
630 2 : PyErr_SetString(PyExc_RuntimeError,
631 : "cannot re-enter the tee iterator");
632 2 : return NULL;
633 : }
634 20093400 : tdo->running = 1;
635 20093400 : value = PyIter_Next(tdo->it);
636 20093400 : tdo->running = 0;
637 20093400 : if (value == NULL)
638 255 : return NULL;
639 20093200 : tdo->numread++;
640 20093200 : tdo->values[i] = value;
641 : }
642 20168200 : Py_INCREF(value);
643 20168200 : return value;
644 : }
645 :
646 : static int
647 2798850 : teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg)
648 : {
649 : int i;
650 :
651 2798850 : Py_VISIT(tdo->it);
652 142222000 : for (i = 0; i < tdo->numread; i++)
653 139423000 : Py_VISIT(tdo->values[i]);
654 2798850 : Py_VISIT(tdo->nextlink);
655 2798850 : return 0;
656 : }
657 :
658 : static void
659 352737 : teedataobject_safe_decref(PyObject *obj)
660 : {
661 1056280 : while (obj && Py_IS_TYPE(obj, &teedataobject_type) &&
662 352487 : Py_REFCNT(obj) == 1) {
663 351052 : PyObject *nextlink = ((teedataobject *)obj)->nextlink;
664 351052 : ((teedataobject *)obj)->nextlink = NULL;
665 351052 : Py_DECREF(obj);
666 351052 : obj = nextlink;
667 : }
668 352737 : Py_XDECREF(obj);
669 352737 : }
670 :
671 : static int
672 352737 : teedataobject_clear(teedataobject *tdo)
673 : {
674 : int i;
675 : PyObject *tmp;
676 :
677 352737 : Py_CLEAR(tdo->it);
678 20446100 : for (i=0 ; i<tdo->numread ; i++)
679 20093300 : Py_CLEAR(tdo->values[i]);
680 352737 : tmp = tdo->nextlink;
681 352737 : tdo->nextlink = NULL;
682 352737 : teedataobject_safe_decref(tmp);
683 352737 : return 0;
684 : }
685 :
686 : static void
687 352736 : teedataobject_dealloc(teedataobject *tdo)
688 : {
689 352736 : PyObject_GC_UnTrack(tdo);
690 352736 : teedataobject_clear(tdo);
691 352736 : PyObject_GC_Del(tdo);
692 352736 : }
693 :
694 : static PyObject *
695 44 : teedataobject_reduce(teedataobject *tdo, PyObject *Py_UNUSED(ignored))
696 : {
697 : int i;
698 : /* create a temporary list of already iterated values */
699 44 : PyObject *values = PyList_New(tdo->numread);
700 :
701 44 : if (!values)
702 0 : return NULL;
703 176 : for (i=0 ; i<tdo->numread ; i++) {
704 132 : Py_INCREF(tdo->values[i]);
705 132 : PyList_SET_ITEM(values, i, tdo->values[i]);
706 : }
707 44 : return Py_BuildValue("O(ONO)", Py_TYPE(tdo), tdo->it,
708 : values,
709 44 : tdo->nextlink ? tdo->nextlink : Py_None);
710 : }
711 :
712 : /*[clinic input]
713 : @classmethod
714 : itertools.teedataobject.__new__
715 : iterable as it: object
716 : values: object(subclass_of='&PyList_Type')
717 : next: object
718 : /
719 : Data container common to multiple tee objects.
720 : [clinic start generated code]*/
721 :
722 : static PyObject *
723 62 : itertools_teedataobject_impl(PyTypeObject *type, PyObject *it,
724 : PyObject *values, PyObject *next)
725 : /*[clinic end generated code: output=3343ceb07e08df5e input=be60f2fabd2b72ba]*/
726 : {
727 : teedataobject *tdo;
728 : Py_ssize_t i, len;
729 :
730 62 : assert(type == &teedataobject_type);
731 :
732 62 : tdo = (teedataobject *)teedataobject_newinternal(it);
733 62 : if (!tdo)
734 0 : return NULL;
735 :
736 62 : len = PyList_GET_SIZE(values);
737 62 : if (len > LINKCELLS)
738 0 : goto err;
739 212 : for (i=0; i<len; i++) {
740 150 : tdo->values[i] = PyList_GET_ITEM(values, i);
741 150 : Py_INCREF(tdo->values[i]);
742 : }
743 : /* len <= LINKCELLS < INT_MAX */
744 62 : tdo->numread = Py_SAFE_DOWNCAST(len, Py_ssize_t, int);
745 :
746 62 : if (len == LINKCELLS) {
747 0 : if (next != Py_None) {
748 0 : if (!Py_IS_TYPE(next, &teedataobject_type))
749 0 : goto err;
750 0 : assert(tdo->nextlink == NULL);
751 0 : Py_INCREF(next);
752 0 : tdo->nextlink = next;
753 : }
754 : } else {
755 62 : if (next != Py_None)
756 0 : goto err; /* shouldn't have a next if we are not full */
757 : }
758 62 : return (PyObject*)tdo;
759 :
760 0 : err:
761 0 : Py_XDECREF(tdo);
762 0 : PyErr_SetString(PyExc_ValueError, "Invalid arguments");
763 0 : return NULL;
764 : }
765 :
766 : static PyMethodDef teedataobject_methods[] = {
767 : {"__reduce__", (PyCFunction)teedataobject_reduce, METH_NOARGS,
768 : reduce_doc},
769 : {NULL, NULL} /* sentinel */
770 : };
771 :
772 : static PyTypeObject teedataobject_type = {
773 : PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */
774 : "itertools._tee_dataobject", /* tp_name */
775 : sizeof(teedataobject), /* tp_basicsize */
776 : 0, /* tp_itemsize */
777 : /* methods */
778 : (destructor)teedataobject_dealloc, /* tp_dealloc */
779 : 0, /* tp_vectorcall_offset */
780 : 0, /* tp_getattr */
781 : 0, /* tp_setattr */
782 : 0, /* tp_as_async */
783 : 0, /* tp_repr */
784 : 0, /* tp_as_number */
785 : 0, /* tp_as_sequence */
786 : 0, /* tp_as_mapping */
787 : 0, /* tp_hash */
788 : 0, /* tp_call */
789 : 0, /* tp_str */
790 : PyObject_GenericGetAttr, /* tp_getattro */
791 : 0, /* tp_setattro */
792 : 0, /* tp_as_buffer */
793 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
794 : itertools_teedataobject__doc__, /* tp_doc */
795 : (traverseproc)teedataobject_traverse, /* tp_traverse */
796 : (inquiry)teedataobject_clear, /* tp_clear */
797 : 0, /* tp_richcompare */
798 : 0, /* tp_weaklistoffset */
799 : 0, /* tp_iter */
800 : 0, /* tp_iternext */
801 : teedataobject_methods, /* tp_methods */
802 : 0, /* tp_members */
803 : 0, /* tp_getset */
804 : 0, /* tp_base */
805 : 0, /* tp_dict */
806 : 0, /* tp_descr_get */
807 : 0, /* tp_descr_set */
808 : 0, /* tp_dictoffset */
809 : 0, /* tp_init */
810 : 0, /* tp_alloc */
811 : itertools_teedataobject, /* tp_new */
812 : PyObject_GC_Del, /* tp_free */
813 : };
814 :
815 :
816 : static PyObject *
817 20168500 : tee_next(teeobject *to)
818 : {
819 : PyObject *value, *link;
820 :
821 20168500 : if (to->index >= LINKCELLS) {
822 353777 : link = teedataobject_jumplink(to->dataobj);
823 353777 : if (link == NULL)
824 0 : return NULL;
825 353777 : Py_SETREF(to->dataobj, (teedataobject *)link);
826 353777 : to->index = 0;
827 : }
828 20168500 : value = teedataobject_getitem(to->dataobj, to->index);
829 20168500 : if (value == NULL)
830 257 : return NULL;
831 20168200 : to->index++;
832 20168200 : return value;
833 : }
834 :
835 : static int
836 570 : tee_traverse(teeobject *to, visitproc visit, void *arg)
837 : {
838 570 : Py_VISIT((PyObject *)to->dataobj);
839 570 : return 0;
840 : }
841 :
842 : static PyObject *
843 122 : tee_copy(teeobject *to, PyObject *Py_UNUSED(ignored))
844 : {
845 : teeobject *newto;
846 :
847 122 : newto = PyObject_GC_New(teeobject, &tee_type);
848 122 : if (newto == NULL)
849 0 : return NULL;
850 122 : Py_INCREF(to->dataobj);
851 122 : newto->dataobj = to->dataobj;
852 122 : newto->index = to->index;
853 122 : newto->weakreflist = NULL;
854 122 : PyObject_GC_Track(newto);
855 122 : return (PyObject *)newto;
856 : }
857 :
858 : PyDoc_STRVAR(teecopy_doc, "Returns an independent iterator.");
859 :
860 : static PyObject *
861 189 : tee_fromiterable(PyObject *iterable)
862 : {
863 : teeobject *to;
864 : PyObject *it;
865 :
866 189 : it = PyObject_GetIter(iterable);
867 189 : if (it == NULL)
868 1 : return NULL;
869 188 : if (PyObject_TypeCheck(it, &tee_type)) {
870 1 : to = (teeobject *)tee_copy((teeobject *)it, NULL);
871 1 : goto done;
872 : }
873 :
874 187 : PyObject *dataobj = teedataobject_newinternal(it);
875 187 : if (!dataobj) {
876 0 : to = NULL;
877 0 : goto done;
878 : }
879 187 : to = PyObject_GC_New(teeobject, &tee_type);
880 187 : if (to == NULL) {
881 0 : Py_DECREF(dataobj);
882 0 : goto done;
883 : }
884 187 : to->dataobj = (teedataobject *)dataobj;
885 187 : to->index = 0;
886 187 : to->weakreflist = NULL;
887 187 : PyObject_GC_Track(to);
888 188 : done:
889 188 : Py_DECREF(it);
890 188 : return (PyObject *)to;
891 : }
892 :
893 : /*[clinic input]
894 : @classmethod
895 : itertools._tee.__new__
896 : iterable: object
897 : /
898 : Iterator wrapped to make it copyable.
899 : [clinic start generated code]*/
900 :
901 : static PyObject *
902 83 : itertools__tee_impl(PyTypeObject *type, PyObject *iterable)
903 : /*[clinic end generated code: output=b02d3fd26c810c3f input=adc0779d2afe37a2]*/
904 : {
905 83 : return tee_fromiterable(iterable);
906 : }
907 :
908 : static int
909 309 : tee_clear(teeobject *to)
910 : {
911 309 : if (to->weakreflist != NULL)
912 1 : PyObject_ClearWeakRefs((PyObject *) to);
913 309 : Py_CLEAR(to->dataobj);
914 309 : return 0;
915 : }
916 :
917 : static void
918 309 : tee_dealloc(teeobject *to)
919 : {
920 309 : PyObject_GC_UnTrack(to);
921 309 : tee_clear(to);
922 309 : PyObject_GC_Del(to);
923 309 : }
924 :
925 : static PyObject *
926 56 : tee_reduce(teeobject *to, PyObject *Py_UNUSED(ignored))
927 : {
928 56 : return Py_BuildValue("O(())(Oi)", Py_TYPE(to), to->dataobj, to->index);
929 : }
930 :
931 : static PyObject *
932 80 : tee_setstate(teeobject *to, PyObject *state)
933 : {
934 : teedataobject *tdo;
935 : int index;
936 80 : if (!PyTuple_Check(state)) {
937 0 : PyErr_SetString(PyExc_TypeError, "state is not a tuple");
938 0 : return NULL;
939 : }
940 80 : if (!PyArg_ParseTuple(state, "O!i", &teedataobject_type, &tdo, &index)) {
941 0 : return NULL;
942 : }
943 80 : if (index < 0 || index > LINKCELLS) {
944 0 : PyErr_SetString(PyExc_ValueError, "Index out of range");
945 0 : return NULL;
946 : }
947 80 : Py_INCREF(tdo);
948 80 : Py_XSETREF(to->dataobj, tdo);
949 80 : to->index = index;
950 80 : Py_RETURN_NONE;
951 : }
952 :
953 : static PyMethodDef tee_methods[] = {
954 : {"__copy__", (PyCFunction)tee_copy, METH_NOARGS, teecopy_doc},
955 : {"__reduce__", (PyCFunction)tee_reduce, METH_NOARGS, reduce_doc},
956 : {"__setstate__", (PyCFunction)tee_setstate, METH_O, setstate_doc},
957 : {NULL, NULL} /* sentinel */
958 : };
959 :
960 : static PyTypeObject tee_type = {
961 : PyVarObject_HEAD_INIT(NULL, 0)
962 : "itertools._tee", /* tp_name */
963 : sizeof(teeobject), /* tp_basicsize */
964 : 0, /* tp_itemsize */
965 : /* methods */
966 : (destructor)tee_dealloc, /* tp_dealloc */
967 : 0, /* tp_vectorcall_offset */
968 : 0, /* tp_getattr */
969 : 0, /* tp_setattr */
970 : 0, /* tp_as_async */
971 : 0, /* tp_repr */
972 : 0, /* tp_as_number */
973 : 0, /* tp_as_sequence */
974 : 0, /* tp_as_mapping */
975 : 0, /* tp_hash */
976 : 0, /* tp_call */
977 : 0, /* tp_str */
978 : 0, /* tp_getattro */
979 : 0, /* tp_setattro */
980 : 0, /* tp_as_buffer */
981 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
982 : itertools__tee__doc__, /* tp_doc */
983 : (traverseproc)tee_traverse, /* tp_traverse */
984 : (inquiry)tee_clear, /* tp_clear */
985 : 0, /* tp_richcompare */
986 : offsetof(teeobject, weakreflist), /* tp_weaklistoffset */
987 : PyObject_SelfIter, /* tp_iter */
988 : (iternextfunc)tee_next, /* tp_iternext */
989 : tee_methods, /* tp_methods */
990 : 0, /* tp_members */
991 : 0, /* tp_getset */
992 : 0, /* tp_base */
993 : 0, /* tp_dict */
994 : 0, /* tp_descr_get */
995 : 0, /* tp_descr_set */
996 : 0, /* tp_dictoffset */
997 : 0, /* tp_init */
998 : 0, /* tp_alloc */
999 : itertools__tee, /* tp_new */
1000 : PyObject_GC_Del, /* tp_free */
1001 : };
1002 :
1003 : /*[clinic input]
1004 : itertools.tee
1005 : iterable: object
1006 : n: Py_ssize_t = 2
1007 : /
1008 : Returns a tuple of n independent iterators.
1009 : [clinic start generated code]*/
1010 :
1011 : static PyObject *
1012 120 : itertools_tee_impl(PyObject *module, PyObject *iterable, Py_ssize_t n)
1013 : /*[clinic end generated code: output=1c64519cd859c2f0 input=c99a1472c425d66d]*/
1014 : {
1015 : Py_ssize_t i;
1016 : PyObject *it, *copyable, *copyfunc, *result;
1017 :
1018 120 : if (n < 0) {
1019 1 : PyErr_SetString(PyExc_ValueError, "n must be >= 0");
1020 1 : return NULL;
1021 : }
1022 119 : result = PyTuple_New(n);
1023 119 : if (result == NULL)
1024 0 : return NULL;
1025 119 : if (n == 0)
1026 1 : return result;
1027 118 : it = PyObject_GetIter(iterable);
1028 118 : if (it == NULL) {
1029 11 : Py_DECREF(result);
1030 11 : return NULL;
1031 : }
1032 :
1033 107 : if (_PyObject_LookupAttr(it, &_Py_ID(__copy__), ©func) < 0) {
1034 0 : Py_DECREF(it);
1035 0 : Py_DECREF(result);
1036 0 : return NULL;
1037 : }
1038 107 : if (copyfunc != NULL) {
1039 1 : copyable = it;
1040 : }
1041 : else {
1042 106 : copyable = tee_fromiterable(it);
1043 106 : Py_DECREF(it);
1044 106 : if (copyable == NULL) {
1045 0 : Py_DECREF(result);
1046 0 : return NULL;
1047 : }
1048 106 : copyfunc = PyObject_GetAttr(copyable, &_Py_ID(__copy__));
1049 106 : if (copyfunc == NULL) {
1050 0 : Py_DECREF(copyable);
1051 0 : Py_DECREF(result);
1052 0 : return NULL;
1053 : }
1054 : }
1055 :
1056 107 : PyTuple_SET_ITEM(result, 0, copyable);
1057 220 : for (i = 1; i < n; i++) {
1058 113 : copyable = _PyObject_CallNoArgs(copyfunc);
1059 113 : if (copyable == NULL) {
1060 0 : Py_DECREF(copyfunc);
1061 0 : Py_DECREF(result);
1062 0 : return NULL;
1063 : }
1064 113 : PyTuple_SET_ITEM(result, i, copyable);
1065 : }
1066 107 : Py_DECREF(copyfunc);
1067 107 : return result;
1068 : }
1069 :
1070 :
1071 : /* cycle object **************************************************************/
1072 :
1073 : typedef struct {
1074 : PyObject_HEAD
1075 : PyObject *it;
1076 : PyObject *saved;
1077 : Py_ssize_t index;
1078 : int firstpass;
1079 : } cycleobject;
1080 :
1081 : /*[clinic input]
1082 : @classmethod
1083 : itertools.cycle.__new__
1084 : iterable: object
1085 : /
1086 : Return elements from the iterable until it is exhausted. Then repeat the sequence indefinitely.
1087 : [clinic start generated code]*/
1088 :
1089 : static PyObject *
1090 216 : itertools_cycle_impl(PyTypeObject *type, PyObject *iterable)
1091 : /*[clinic end generated code: output=f60e5ec17a45b35c input=9d1d84bcf66e908b]*/
1092 : {
1093 : PyObject *it;
1094 : PyObject *saved;
1095 : cycleobject *lz;
1096 :
1097 : /* Get iterator. */
1098 216 : it = PyObject_GetIter(iterable);
1099 216 : if (it == NULL)
1100 11 : return NULL;
1101 :
1102 205 : saved = PyList_New(0);
1103 205 : if (saved == NULL) {
1104 0 : Py_DECREF(it);
1105 0 : return NULL;
1106 : }
1107 :
1108 : /* create cycleobject structure */
1109 205 : lz = (cycleobject *)type->tp_alloc(type, 0);
1110 205 : if (lz == NULL) {
1111 0 : Py_DECREF(it);
1112 0 : Py_DECREF(saved);
1113 0 : return NULL;
1114 : }
1115 205 : lz->it = it;
1116 205 : lz->saved = saved;
1117 205 : lz->index = 0;
1118 205 : lz->firstpass = 0;
1119 :
1120 205 : return (PyObject *)lz;
1121 : }
1122 :
1123 : static void
1124 205 : cycle_dealloc(cycleobject *lz)
1125 : {
1126 205 : PyObject_GC_UnTrack(lz);
1127 205 : Py_XDECREF(lz->it);
1128 205 : Py_XDECREF(lz->saved);
1129 205 : Py_TYPE(lz)->tp_free(lz);
1130 205 : }
1131 :
1132 : static int
1133 2 : cycle_traverse(cycleobject *lz, visitproc visit, void *arg)
1134 : {
1135 2 : Py_VISIT(lz->it);
1136 2 : Py_VISIT(lz->saved);
1137 2 : return 0;
1138 : }
1139 :
1140 : static PyObject *
1141 6221270 : cycle_next(cycleobject *lz)
1142 : {
1143 : PyObject *item;
1144 :
1145 6221270 : if (lz->it != NULL) {
1146 5838 : item = PyIter_Next(lz->it);
1147 5838 : if (item != NULL) {
1148 5650 : if (lz->firstpass)
1149 37 : return item;
1150 5613 : if (PyList_Append(lz->saved, item)) {
1151 0 : Py_DECREF(item);
1152 0 : return NULL;
1153 : }
1154 5613 : return item;
1155 : }
1156 : /* Note: StopIteration is already cleared by PyIter_Next() */
1157 188 : if (PyErr_Occurred())
1158 6 : return NULL;
1159 182 : Py_CLEAR(lz->it);
1160 : }
1161 6215610 : if (PyList_GET_SIZE(lz->saved) == 0)
1162 7 : return NULL;
1163 6215610 : item = PyList_GET_ITEM(lz->saved, lz->index);
1164 6215610 : lz->index++;
1165 6215610 : if (lz->index >= PyList_GET_SIZE(lz->saved))
1166 702492 : lz->index = 0;
1167 6215610 : Py_INCREF(item);
1168 6215610 : return item;
1169 : }
1170 :
1171 : static PyObject *
1172 37 : cycle_reduce(cycleobject *lz, PyObject *Py_UNUSED(ignored))
1173 : {
1174 : /* Create a new cycle with the iterator tuple, then set the saved state */
1175 37 : if (lz->it == NULL) {
1176 16 : PyObject *it = PyObject_GetIter(lz->saved);
1177 16 : if (it == NULL)
1178 0 : return NULL;
1179 16 : if (lz->index != 0) {
1180 16 : PyObject *res = _PyObject_CallMethod(it, &_Py_ID(__setstate__),
1181 : "n", lz->index);
1182 16 : if (res == NULL) {
1183 0 : Py_DECREF(it);
1184 0 : return NULL;
1185 : }
1186 16 : Py_DECREF(res);
1187 : }
1188 16 : return Py_BuildValue("O(N)(OO)", Py_TYPE(lz), it, lz->saved, Py_True);
1189 : }
1190 21 : return Py_BuildValue("O(O)(OO)", Py_TYPE(lz), lz->it, lz->saved,
1191 21 : lz->firstpass ? Py_True : Py_False);
1192 : }
1193 :
1194 : static PyObject *
1195 50 : cycle_setstate(cycleobject *lz, PyObject *state)
1196 : {
1197 50 : PyObject *saved=NULL;
1198 : int firstpass;
1199 50 : if (!PyTuple_Check(state)) {
1200 1 : PyErr_SetString(PyExc_TypeError, "state is not a tuple");
1201 1 : return NULL;
1202 : }
1203 49 : if (!PyArg_ParseTuple(state, "O!i", &PyList_Type, &saved, &firstpass)) {
1204 4 : return NULL;
1205 : }
1206 45 : Py_INCREF(saved);
1207 45 : Py_XSETREF(lz->saved, saved);
1208 45 : lz->firstpass = firstpass != 0;
1209 45 : lz->index = 0;
1210 45 : Py_RETURN_NONE;
1211 : }
1212 :
1213 : static PyMethodDef cycle_methods[] = {
1214 : {"__reduce__", (PyCFunction)cycle_reduce, METH_NOARGS,
1215 : reduce_doc},
1216 : {"__setstate__", (PyCFunction)cycle_setstate, METH_O,
1217 : setstate_doc},
1218 : {NULL, NULL} /* sentinel */
1219 : };
1220 :
1221 : static PyTypeObject cycle_type = {
1222 : PyVarObject_HEAD_INIT(NULL, 0)
1223 : "itertools.cycle", /* tp_name */
1224 : sizeof(cycleobject), /* tp_basicsize */
1225 : 0, /* tp_itemsize */
1226 : /* methods */
1227 : (destructor)cycle_dealloc, /* tp_dealloc */
1228 : 0, /* tp_vectorcall_offset */
1229 : 0, /* tp_getattr */
1230 : 0, /* tp_setattr */
1231 : 0, /* tp_as_async */
1232 : 0, /* tp_repr */
1233 : 0, /* tp_as_number */
1234 : 0, /* tp_as_sequence */
1235 : 0, /* tp_as_mapping */
1236 : 0, /* tp_hash */
1237 : 0, /* tp_call */
1238 : 0, /* tp_str */
1239 : PyObject_GenericGetAttr, /* tp_getattro */
1240 : 0, /* tp_setattro */
1241 : 0, /* tp_as_buffer */
1242 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1243 : Py_TPFLAGS_BASETYPE, /* tp_flags */
1244 : itertools_cycle__doc__, /* tp_doc */
1245 : (traverseproc)cycle_traverse, /* tp_traverse */
1246 : 0, /* tp_clear */
1247 : 0, /* tp_richcompare */
1248 : 0, /* tp_weaklistoffset */
1249 : PyObject_SelfIter, /* tp_iter */
1250 : (iternextfunc)cycle_next, /* tp_iternext */
1251 : cycle_methods, /* tp_methods */
1252 : 0, /* tp_members */
1253 : 0, /* tp_getset */
1254 : 0, /* tp_base */
1255 : 0, /* tp_dict */
1256 : 0, /* tp_descr_get */
1257 : 0, /* tp_descr_set */
1258 : 0, /* tp_dictoffset */
1259 : 0, /* tp_init */
1260 : 0, /* tp_alloc */
1261 : itertools_cycle, /* tp_new */
1262 : PyObject_GC_Del, /* tp_free */
1263 : };
1264 :
1265 :
1266 : /* dropwhile object **********************************************************/
1267 :
1268 : typedef struct {
1269 : PyObject_HEAD
1270 : PyObject *func;
1271 : PyObject *it;
1272 : long start;
1273 : } dropwhileobject;
1274 :
1275 : /*[clinic input]
1276 : @classmethod
1277 : itertools.dropwhile.__new__
1278 : predicate as func: object
1279 : iterable as seq: object
1280 : /
1281 : Drop items from the iterable while predicate(item) is true.
1282 :
1283 : Afterwards, return every element until the iterable is exhausted.
1284 : [clinic start generated code]*/
1285 :
1286 : static PyObject *
1287 436 : itertools_dropwhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq)
1288 : /*[clinic end generated code: output=92f9d0d89af149e4 input=d39737147c9f0a26]*/
1289 : {
1290 : PyObject *it;
1291 : dropwhileobject *lz;
1292 :
1293 : /* Get iterator. */
1294 436 : it = PyObject_GetIter(seq);
1295 436 : if (it == NULL)
1296 10 : return NULL;
1297 :
1298 : /* create dropwhileobject structure */
1299 426 : lz = (dropwhileobject *)type->tp_alloc(type, 0);
1300 426 : if (lz == NULL) {
1301 0 : Py_DECREF(it);
1302 0 : return NULL;
1303 : }
1304 426 : Py_INCREF(func);
1305 426 : lz->func = func;
1306 426 : lz->it = it;
1307 426 : lz->start = 0;
1308 :
1309 426 : return (PyObject *)lz;
1310 : }
1311 :
1312 : static void
1313 426 : dropwhile_dealloc(dropwhileobject *lz)
1314 : {
1315 426 : PyObject_GC_UnTrack(lz);
1316 426 : Py_XDECREF(lz->func);
1317 426 : Py_XDECREF(lz->it);
1318 426 : Py_TYPE(lz)->tp_free(lz);
1319 426 : }
1320 :
1321 : static int
1322 2 : dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg)
1323 : {
1324 2 : Py_VISIT(lz->it);
1325 2 : Py_VISIT(lz->func);
1326 2 : return 0;
1327 : }
1328 :
1329 : static PyObject *
1330 6574 : dropwhile_next(dropwhileobject *lz)
1331 : {
1332 : PyObject *item, *good;
1333 6574 : PyObject *it = lz->it;
1334 : long ok;
1335 : PyObject *(*iternext)(PyObject *);
1336 :
1337 6574 : iternext = *Py_TYPE(it)->tp_iternext;
1338 : for (;;) {
1339 6798 : item = iternext(it);
1340 6798 : if (item == NULL)
1341 397 : return NULL;
1342 6401 : if (lz->start == 1)
1343 5782 : return item;
1344 :
1345 619 : good = PyObject_CallOneArg(lz->func, item);
1346 619 : if (good == NULL) {
1347 2 : Py_DECREF(item);
1348 2 : return NULL;
1349 : }
1350 617 : ok = PyObject_IsTrue(good);
1351 617 : Py_DECREF(good);
1352 617 : if (ok == 0) {
1353 393 : lz->start = 1;
1354 393 : return item;
1355 : }
1356 224 : Py_DECREF(item);
1357 224 : if (ok < 0)
1358 0 : return NULL;
1359 : }
1360 : }
1361 :
1362 : static PyObject *
1363 14 : dropwhile_reduce(dropwhileobject *lz, PyObject *Py_UNUSED(ignored))
1364 : {
1365 14 : return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->start);
1366 : }
1367 :
1368 : static PyObject *
1369 20 : dropwhile_setstate(dropwhileobject *lz, PyObject *state)
1370 : {
1371 20 : int start = PyObject_IsTrue(state);
1372 20 : if (start < 0)
1373 0 : return NULL;
1374 20 : lz->start = start;
1375 20 : Py_RETURN_NONE;
1376 : }
1377 :
1378 : static PyMethodDef dropwhile_methods[] = {
1379 : {"__reduce__", (PyCFunction)dropwhile_reduce, METH_NOARGS,
1380 : reduce_doc},
1381 : {"__setstate__", (PyCFunction)dropwhile_setstate, METH_O,
1382 : setstate_doc},
1383 : {NULL, NULL} /* sentinel */
1384 : };
1385 :
1386 : static PyTypeObject dropwhile_type = {
1387 : PyVarObject_HEAD_INIT(NULL, 0)
1388 : "itertools.dropwhile", /* tp_name */
1389 : sizeof(dropwhileobject), /* tp_basicsize */
1390 : 0, /* tp_itemsize */
1391 : /* methods */
1392 : (destructor)dropwhile_dealloc, /* tp_dealloc */
1393 : 0, /* tp_vectorcall_offset */
1394 : 0, /* tp_getattr */
1395 : 0, /* tp_setattr */
1396 : 0, /* tp_as_async */
1397 : 0, /* tp_repr */
1398 : 0, /* tp_as_number */
1399 : 0, /* tp_as_sequence */
1400 : 0, /* tp_as_mapping */
1401 : 0, /* tp_hash */
1402 : 0, /* tp_call */
1403 : 0, /* tp_str */
1404 : PyObject_GenericGetAttr, /* tp_getattro */
1405 : 0, /* tp_setattro */
1406 : 0, /* tp_as_buffer */
1407 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1408 : Py_TPFLAGS_BASETYPE, /* tp_flags */
1409 : itertools_dropwhile__doc__, /* tp_doc */
1410 : (traverseproc)dropwhile_traverse, /* tp_traverse */
1411 : 0, /* tp_clear */
1412 : 0, /* tp_richcompare */
1413 : 0, /* tp_weaklistoffset */
1414 : PyObject_SelfIter, /* tp_iter */
1415 : (iternextfunc)dropwhile_next, /* tp_iternext */
1416 : dropwhile_methods, /* tp_methods */
1417 : 0, /* tp_members */
1418 : 0, /* tp_getset */
1419 : 0, /* tp_base */
1420 : 0, /* tp_dict */
1421 : 0, /* tp_descr_get */
1422 : 0, /* tp_descr_set */
1423 : 0, /* tp_dictoffset */
1424 : 0, /* tp_init */
1425 : 0, /* tp_alloc */
1426 : itertools_dropwhile, /* tp_new */
1427 : PyObject_GC_Del, /* tp_free */
1428 : };
1429 :
1430 :
1431 : /* takewhile object **********************************************************/
1432 :
1433 : typedef struct {
1434 : PyObject_HEAD
1435 : PyObject *func;
1436 : PyObject *it;
1437 : long stop;
1438 : } takewhileobject;
1439 :
1440 : /*[clinic input]
1441 : @classmethod
1442 : itertools.takewhile.__new__
1443 : predicate as func: object
1444 : iterable as seq: object
1445 : /
1446 : Return successive entries from an iterable as long as the predicate evaluates to true for each entry.
1447 : [clinic start generated code]*/
1448 :
1449 : static PyObject *
1450 86 : itertools_takewhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq)
1451 : /*[clinic end generated code: output=bb179ea7864e2ef6 input=ba5255f7519aa119]*/
1452 : {
1453 : PyObject *it;
1454 : takewhileobject *lz;
1455 :
1456 : /* Get iterator. */
1457 86 : it = PyObject_GetIter(seq);
1458 86 : if (it == NULL)
1459 10 : return NULL;
1460 :
1461 : /* create takewhileobject structure */
1462 76 : lz = (takewhileobject *)type->tp_alloc(type, 0);
1463 76 : if (lz == NULL) {
1464 0 : Py_DECREF(it);
1465 0 : return NULL;
1466 : }
1467 76 : Py_INCREF(func);
1468 76 : lz->func = func;
1469 76 : lz->it = it;
1470 76 : lz->stop = 0;
1471 :
1472 76 : return (PyObject *)lz;
1473 : }
1474 :
1475 : static void
1476 76 : takewhile_dealloc(takewhileobject *lz)
1477 : {
1478 76 : PyObject_GC_UnTrack(lz);
1479 76 : Py_XDECREF(lz->func);
1480 76 : Py_XDECREF(lz->it);
1481 76 : Py_TYPE(lz)->tp_free(lz);
1482 76 : }
1483 :
1484 : static int
1485 2 : takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg)
1486 : {
1487 2 : Py_VISIT(lz->it);
1488 2 : Py_VISIT(lz->func);
1489 2 : return 0;
1490 : }
1491 :
1492 : static PyObject *
1493 174 : takewhile_next(takewhileobject *lz)
1494 : {
1495 : PyObject *item, *good;
1496 174 : PyObject *it = lz->it;
1497 : long ok;
1498 :
1499 174 : if (lz->stop == 1)
1500 1 : return NULL;
1501 :
1502 173 : item = (*Py_TYPE(it)->tp_iternext)(it);
1503 173 : if (item == NULL)
1504 18 : return NULL;
1505 :
1506 155 : good = PyObject_CallOneArg(lz->func, item);
1507 155 : if (good == NULL) {
1508 2 : Py_DECREF(item);
1509 2 : return NULL;
1510 : }
1511 153 : ok = PyObject_IsTrue(good);
1512 153 : Py_DECREF(good);
1513 153 : if (ok > 0)
1514 100 : return item;
1515 53 : Py_DECREF(item);
1516 53 : if (ok == 0)
1517 53 : lz->stop = 1;
1518 53 : return NULL;
1519 : }
1520 :
1521 : static PyObject *
1522 14 : takewhile_reduce(takewhileobject *lz, PyObject *Py_UNUSED(ignored))
1523 : {
1524 14 : return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->stop);
1525 : }
1526 :
1527 : static PyObject *
1528 20 : takewhile_reduce_setstate(takewhileobject *lz, PyObject *state)
1529 : {
1530 20 : int stop = PyObject_IsTrue(state);
1531 :
1532 20 : if (stop < 0)
1533 0 : return NULL;
1534 20 : lz->stop = stop;
1535 20 : Py_RETURN_NONE;
1536 : }
1537 :
1538 : static PyMethodDef takewhile_reduce_methods[] = {
1539 : {"__reduce__", (PyCFunction)takewhile_reduce, METH_NOARGS,
1540 : reduce_doc},
1541 : {"__setstate__", (PyCFunction)takewhile_reduce_setstate, METH_O,
1542 : setstate_doc},
1543 : {NULL, NULL} /* sentinel */
1544 : };
1545 :
1546 : static PyTypeObject takewhile_type = {
1547 : PyVarObject_HEAD_INIT(NULL, 0)
1548 : "itertools.takewhile", /* tp_name */
1549 : sizeof(takewhileobject), /* tp_basicsize */
1550 : 0, /* tp_itemsize */
1551 : /* methods */
1552 : (destructor)takewhile_dealloc, /* tp_dealloc */
1553 : 0, /* tp_vectorcall_offset */
1554 : 0, /* tp_getattr */
1555 : 0, /* tp_setattr */
1556 : 0, /* tp_as_async */
1557 : 0, /* tp_repr */
1558 : 0, /* tp_as_number */
1559 : 0, /* tp_as_sequence */
1560 : 0, /* tp_as_mapping */
1561 : 0, /* tp_hash */
1562 : 0, /* tp_call */
1563 : 0, /* tp_str */
1564 : PyObject_GenericGetAttr, /* tp_getattro */
1565 : 0, /* tp_setattro */
1566 : 0, /* tp_as_buffer */
1567 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1568 : Py_TPFLAGS_BASETYPE, /* tp_flags */
1569 : itertools_takewhile__doc__, /* tp_doc */
1570 : (traverseproc)takewhile_traverse, /* tp_traverse */
1571 : 0, /* tp_clear */
1572 : 0, /* tp_richcompare */
1573 : 0, /* tp_weaklistoffset */
1574 : PyObject_SelfIter, /* tp_iter */
1575 : (iternextfunc)takewhile_next, /* tp_iternext */
1576 : takewhile_reduce_methods, /* tp_methods */
1577 : 0, /* tp_members */
1578 : 0, /* tp_getset */
1579 : 0, /* tp_base */
1580 : 0, /* tp_dict */
1581 : 0, /* tp_descr_get */
1582 : 0, /* tp_descr_set */
1583 : 0, /* tp_dictoffset */
1584 : 0, /* tp_init */
1585 : 0, /* tp_alloc */
1586 : itertools_takewhile, /* tp_new */
1587 : PyObject_GC_Del, /* tp_free */
1588 : };
1589 :
1590 :
1591 : /* islice object *************************************************************/
1592 :
1593 : typedef struct {
1594 : PyObject_HEAD
1595 : PyObject *it;
1596 : Py_ssize_t next;
1597 : Py_ssize_t stop;
1598 : Py_ssize_t step;
1599 : Py_ssize_t cnt;
1600 : } isliceobject;
1601 :
1602 : static PyTypeObject islice_type;
1603 :
1604 : static PyObject *
1605 173998 : islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1606 : {
1607 : PyObject *seq;
1608 173998 : Py_ssize_t start=0, stop=-1, step=1;
1609 173998 : PyObject *it, *a1=NULL, *a2=NULL, *a3=NULL;
1610 : Py_ssize_t numargs;
1611 : isliceobject *lz;
1612 :
1613 173998 : if ((type == &islice_type || type->tp_init == islice_type.tp_init) &&
1614 22 : !_PyArg_NoKeywords("islice", kwds))
1615 1 : return NULL;
1616 :
1617 173997 : if (!PyArg_UnpackTuple(args, "islice", 2, 4, &seq, &a1, &a2, &a3))
1618 2 : return NULL;
1619 :
1620 173995 : numargs = PyTuple_Size(args);
1621 173995 : if (numargs == 2) {
1622 144913 : if (a1 != Py_None) {
1623 144805 : stop = PyNumber_AsSsize_t(a1, PyExc_OverflowError);
1624 144805 : if (stop == -1) {
1625 1 : if (PyErr_Occurred())
1626 1 : PyErr_Clear();
1627 1 : PyErr_SetString(PyExc_ValueError,
1628 : "Stop argument for islice() must be None or "
1629 : "an integer: 0 <= x <= sys.maxsize.");
1630 1 : return NULL;
1631 : }
1632 : }
1633 : } else {
1634 29082 : if (a1 != Py_None)
1635 29080 : start = PyNumber_AsSsize_t(a1, PyExc_OverflowError);
1636 29082 : if (start == -1 && PyErr_Occurred())
1637 2 : PyErr_Clear();
1638 29082 : if (a2 != Py_None) {
1639 182 : stop = PyNumber_AsSsize_t(a2, PyExc_OverflowError);
1640 182 : if (stop == -1) {
1641 2 : if (PyErr_Occurred())
1642 2 : PyErr_Clear();
1643 2 : PyErr_SetString(PyExc_ValueError,
1644 : "Stop argument for islice() must be None or "
1645 : "an integer: 0 <= x <= sys.maxsize.");
1646 2 : return NULL;
1647 : }
1648 : }
1649 : }
1650 173992 : if (start<0 || stop<-1) {
1651 4 : PyErr_SetString(PyExc_ValueError,
1652 : "Indices for islice() must be None or "
1653 : "an integer: 0 <= x <= sys.maxsize.");
1654 4 : return NULL;
1655 : }
1656 :
1657 173988 : if (a3 != NULL) {
1658 213 : if (a3 != Py_None)
1659 212 : step = PyNumber_AsSsize_t(a3, PyExc_OverflowError);
1660 213 : if (step == -1 && PyErr_Occurred())
1661 0 : PyErr_Clear();
1662 : }
1663 173988 : if (step<1) {
1664 2 : PyErr_SetString(PyExc_ValueError,
1665 : "Step for islice() must be a positive integer or None.");
1666 2 : return NULL;
1667 : }
1668 :
1669 : /* Get iterator. */
1670 173986 : it = PyObject_GetIter(seq);
1671 173986 : if (it == NULL)
1672 23074 : return NULL;
1673 :
1674 : /* create isliceobject structure */
1675 150912 : lz = (isliceobject *)type->tp_alloc(type, 0);
1676 150912 : if (lz == NULL) {
1677 0 : Py_DECREF(it);
1678 0 : return NULL;
1679 : }
1680 150912 : lz->it = it;
1681 150912 : lz->next = start;
1682 150912 : lz->stop = stop;
1683 150912 : lz->step = step;
1684 150912 : lz->cnt = 0L;
1685 :
1686 150912 : return (PyObject *)lz;
1687 : }
1688 :
1689 : static void
1690 150912 : islice_dealloc(isliceobject *lz)
1691 : {
1692 150912 : PyObject_GC_UnTrack(lz);
1693 150912 : Py_XDECREF(lz->it);
1694 150912 : Py_TYPE(lz)->tp_free(lz);
1695 150912 : }
1696 :
1697 : static int
1698 60 : islice_traverse(isliceobject *lz, visitproc visit, void *arg)
1699 : {
1700 60 : Py_VISIT(lz->it);
1701 60 : return 0;
1702 : }
1703 :
1704 : static PyObject *
1705 9234660 : islice_next(isliceobject *lz)
1706 : {
1707 : PyObject *item;
1708 9234660 : PyObject *it = lz->it;
1709 9234660 : Py_ssize_t stop = lz->stop;
1710 : Py_ssize_t oldnext;
1711 : PyObject *(*iternext)(PyObject *);
1712 :
1713 9234660 : if (it == NULL)
1714 12 : return NULL;
1715 :
1716 9234640 : iternext = *Py_TYPE(it)->tp_iternext;
1717 9811010 : while (lz->cnt < lz->next) {
1718 576428 : item = iternext(it);
1719 576428 : if (item == NULL)
1720 61 : goto empty;
1721 576367 : Py_DECREF(item);
1722 576367 : lz->cnt++;
1723 : }
1724 9234580 : if (stop != -1 && lz->cnt >= stop)
1725 32683 : goto empty;
1726 9201900 : item = iternext(it);
1727 9201900 : if (item == NULL)
1728 111068 : goto empty;
1729 9090830 : lz->cnt++;
1730 9090830 : oldnext = lz->next;
1731 : /* The (size_t) cast below avoids the danger of undefined
1732 : behaviour from signed integer overflow. */
1733 9090830 : lz->next += (size_t)lz->step;
1734 9090830 : if (lz->next < oldnext || (stop != -1 && lz->next > stop))
1735 29 : lz->next = stop;
1736 9090830 : return item;
1737 :
1738 143812 : empty:
1739 143812 : Py_CLEAR(lz->it);
1740 143812 : return NULL;
1741 : }
1742 :
1743 : static PyObject *
1744 70 : islice_reduce(isliceobject *lz, PyObject *Py_UNUSED(ignored))
1745 : {
1746 : /* When unpickled, generate a new object with the same bounds,
1747 : * then 'setstate' with the next and count
1748 : */
1749 : PyObject *stop;
1750 :
1751 70 : if (lz->it == NULL) {
1752 : PyObject *empty_list;
1753 : PyObject *empty_it;
1754 12 : empty_list = PyList_New(0);
1755 12 : if (empty_list == NULL)
1756 0 : return NULL;
1757 12 : empty_it = PyObject_GetIter(empty_list);
1758 12 : Py_DECREF(empty_list);
1759 12 : if (empty_it == NULL)
1760 0 : return NULL;
1761 12 : return Py_BuildValue("O(Nn)n", Py_TYPE(lz), empty_it, 0, 0);
1762 : }
1763 58 : if (lz->stop == -1) {
1764 0 : stop = Py_None;
1765 0 : Py_INCREF(stop);
1766 : } else {
1767 58 : stop = PyLong_FromSsize_t(lz->stop);
1768 58 : if (stop == NULL)
1769 0 : return NULL;
1770 : }
1771 58 : return Py_BuildValue("O(OnNn)n", Py_TYPE(lz),
1772 : lz->it, lz->next, stop, lz->step,
1773 : lz->cnt);
1774 : }
1775 :
1776 : static PyObject *
1777 100 : islice_setstate(isliceobject *lz, PyObject *state)
1778 : {
1779 100 : Py_ssize_t cnt = PyLong_AsSsize_t(state);
1780 :
1781 100 : if (cnt == -1 && PyErr_Occurred())
1782 0 : return NULL;
1783 100 : lz->cnt = cnt;
1784 100 : Py_RETURN_NONE;
1785 : }
1786 :
1787 : static PyMethodDef islice_methods[] = {
1788 : {"__reduce__", (PyCFunction)islice_reduce, METH_NOARGS,
1789 : reduce_doc},
1790 : {"__setstate__", (PyCFunction)islice_setstate, METH_O,
1791 : setstate_doc},
1792 : {NULL, NULL} /* sentinel */
1793 : };
1794 :
1795 : PyDoc_STRVAR(islice_doc,
1796 : "islice(iterable, stop) --> islice object\n\
1797 : islice(iterable, start, stop[, step]) --> islice object\n\
1798 : \n\
1799 : Return an iterator whose next() method returns selected values from an\n\
1800 : iterable. If start is specified, will skip all preceding elements;\n\
1801 : otherwise, start defaults to zero. Step defaults to one. If\n\
1802 : specified as another value, step determines how many values are\n\
1803 : skipped between successive calls. Works like a slice() on a list\n\
1804 : but returns an iterator.");
1805 :
1806 : static PyTypeObject islice_type = {
1807 : PyVarObject_HEAD_INIT(NULL, 0)
1808 : "itertools.islice", /* tp_name */
1809 : sizeof(isliceobject), /* tp_basicsize */
1810 : 0, /* tp_itemsize */
1811 : /* methods */
1812 : (destructor)islice_dealloc, /* tp_dealloc */
1813 : 0, /* tp_vectorcall_offset */
1814 : 0, /* tp_getattr */
1815 : 0, /* tp_setattr */
1816 : 0, /* tp_as_async */
1817 : 0, /* tp_repr */
1818 : 0, /* tp_as_number */
1819 : 0, /* tp_as_sequence */
1820 : 0, /* tp_as_mapping */
1821 : 0, /* tp_hash */
1822 : 0, /* tp_call */
1823 : 0, /* tp_str */
1824 : PyObject_GenericGetAttr, /* tp_getattro */
1825 : 0, /* tp_setattro */
1826 : 0, /* tp_as_buffer */
1827 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1828 : Py_TPFLAGS_BASETYPE, /* tp_flags */
1829 : islice_doc, /* tp_doc */
1830 : (traverseproc)islice_traverse, /* tp_traverse */
1831 : 0, /* tp_clear */
1832 : 0, /* tp_richcompare */
1833 : 0, /* tp_weaklistoffset */
1834 : PyObject_SelfIter, /* tp_iter */
1835 : (iternextfunc)islice_next, /* tp_iternext */
1836 : islice_methods, /* tp_methods */
1837 : 0, /* tp_members */
1838 : 0, /* tp_getset */
1839 : 0, /* tp_base */
1840 : 0, /* tp_dict */
1841 : 0, /* tp_descr_get */
1842 : 0, /* tp_descr_set */
1843 : 0, /* tp_dictoffset */
1844 : 0, /* tp_init */
1845 : 0, /* tp_alloc */
1846 : islice_new, /* tp_new */
1847 : PyObject_GC_Del, /* tp_free */
1848 : };
1849 :
1850 :
1851 : /* starmap object ************************************************************/
1852 :
1853 : typedef struct {
1854 : PyObject_HEAD
1855 : PyObject *func;
1856 : PyObject *it;
1857 : } starmapobject;
1858 :
1859 : /*[clinic input]
1860 : @classmethod
1861 : itertools.starmap.__new__
1862 : function as func: object
1863 : iterable as seq: object
1864 : /
1865 : Return an iterator whose values are returned from the function evaluated with an argument tuple taken from the given sequence.
1866 : [clinic start generated code]*/
1867 :
1868 : static PyObject *
1869 9028 : itertools_starmap_impl(PyTypeObject *type, PyObject *func, PyObject *seq)
1870 : /*[clinic end generated code: output=79eeb81d452c6e8d input=844766df6a0d4dad]*/
1871 : {
1872 : PyObject *it;
1873 : starmapobject *lz;
1874 :
1875 : /* Get iterator. */
1876 9028 : it = PyObject_GetIter(seq);
1877 9028 : if (it == NULL)
1878 10 : return NULL;
1879 :
1880 : /* create starmapobject structure */
1881 9018 : lz = (starmapobject *)type->tp_alloc(type, 0);
1882 9018 : if (lz == NULL) {
1883 0 : Py_DECREF(it);
1884 0 : return NULL;
1885 : }
1886 9018 : Py_INCREF(func);
1887 9018 : lz->func = func;
1888 9018 : lz->it = it;
1889 :
1890 9018 : return (PyObject *)lz;
1891 : }
1892 :
1893 : static void
1894 9018 : starmap_dealloc(starmapobject *lz)
1895 : {
1896 9018 : PyObject_GC_UnTrack(lz);
1897 9018 : Py_XDECREF(lz->func);
1898 9018 : Py_XDECREF(lz->it);
1899 9018 : Py_TYPE(lz)->tp_free(lz);
1900 9018 : }
1901 :
1902 : static int
1903 2 : starmap_traverse(starmapobject *lz, visitproc visit, void *arg)
1904 : {
1905 2 : Py_VISIT(lz->it);
1906 2 : Py_VISIT(lz->func);
1907 2 : return 0;
1908 : }
1909 :
1910 : static PyObject *
1911 34314 : starmap_next(starmapobject *lz)
1912 : {
1913 : PyObject *args;
1914 : PyObject *result;
1915 34314 : PyObject *it = lz->it;
1916 :
1917 34314 : args = (*Py_TYPE(it)->tp_iternext)(it);
1918 34314 : if (args == NULL)
1919 9010 : return NULL;
1920 25304 : if (!PyTuple_CheckExact(args)) {
1921 26 : PyObject *newargs = PySequence_Tuple(args);
1922 26 : Py_DECREF(args);
1923 26 : if (newargs == NULL)
1924 1 : return NULL;
1925 25 : args = newargs;
1926 : }
1927 25303 : result = PyObject_Call(lz->func, args, NULL);
1928 25303 : Py_DECREF(args);
1929 25303 : return result;
1930 : }
1931 :
1932 : static PyObject *
1933 14 : starmap_reduce(starmapobject *lz, PyObject *Py_UNUSED(ignored))
1934 : {
1935 : /* Just pickle the iterator */
1936 14 : return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it);
1937 : }
1938 :
1939 : static PyMethodDef starmap_methods[] = {
1940 : {"__reduce__", (PyCFunction)starmap_reduce, METH_NOARGS,
1941 : reduce_doc},
1942 : {NULL, NULL} /* sentinel */
1943 : };
1944 :
1945 : static PyTypeObject starmap_type = {
1946 : PyVarObject_HEAD_INIT(NULL, 0)
1947 : "itertools.starmap", /* tp_name */
1948 : sizeof(starmapobject), /* tp_basicsize */
1949 : 0, /* tp_itemsize */
1950 : /* methods */
1951 : (destructor)starmap_dealloc, /* tp_dealloc */
1952 : 0, /* tp_vectorcall_offset */
1953 : 0, /* tp_getattr */
1954 : 0, /* tp_setattr */
1955 : 0, /* tp_as_async */
1956 : 0, /* tp_repr */
1957 : 0, /* tp_as_number */
1958 : 0, /* tp_as_sequence */
1959 : 0, /* tp_as_mapping */
1960 : 0, /* tp_hash */
1961 : 0, /* tp_call */
1962 : 0, /* tp_str */
1963 : PyObject_GenericGetAttr, /* tp_getattro */
1964 : 0, /* tp_setattro */
1965 : 0, /* tp_as_buffer */
1966 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1967 : Py_TPFLAGS_BASETYPE, /* tp_flags */
1968 : itertools_starmap__doc__, /* tp_doc */
1969 : (traverseproc)starmap_traverse, /* tp_traverse */
1970 : 0, /* tp_clear */
1971 : 0, /* tp_richcompare */
1972 : 0, /* tp_weaklistoffset */
1973 : PyObject_SelfIter, /* tp_iter */
1974 : (iternextfunc)starmap_next, /* tp_iternext */
1975 : starmap_methods, /* tp_methods */
1976 : 0, /* tp_members */
1977 : 0, /* tp_getset */
1978 : 0, /* tp_base */
1979 : 0, /* tp_dict */
1980 : 0, /* tp_descr_get */
1981 : 0, /* tp_descr_set */
1982 : 0, /* tp_dictoffset */
1983 : 0, /* tp_init */
1984 : 0, /* tp_alloc */
1985 : itertools_starmap, /* tp_new */
1986 : PyObject_GC_Del, /* tp_free */
1987 : };
1988 :
1989 :
1990 : /* chain object **************************************************************/
1991 :
1992 : typedef struct {
1993 : PyObject_HEAD
1994 : PyObject *source; /* Iterator over input iterables */
1995 : PyObject *active; /* Currently running input iterator */
1996 : } chainobject;
1997 :
1998 : static PyTypeObject chain_type;
1999 :
2000 : static PyObject *
2001 34548 : chain_new_internal(PyTypeObject *type, PyObject *source)
2002 : {
2003 : chainobject *lz;
2004 :
2005 34548 : lz = (chainobject *)type->tp_alloc(type, 0);
2006 34548 : if (lz == NULL) {
2007 0 : Py_DECREF(source);
2008 0 : return NULL;
2009 : }
2010 :
2011 34548 : lz->source = source;
2012 34548 : lz->active = NULL;
2013 34548 : return (PyObject *)lz;
2014 : }
2015 :
2016 : static PyObject *
2017 24876 : chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2018 : {
2019 : PyObject *source;
2020 :
2021 24876 : if ((type == &chain_type || type->tp_init == chain_type.tp_init) &&
2022 1 : !_PyArg_NoKeywords("chain", kwds))
2023 1 : return NULL;
2024 :
2025 24875 : source = PyObject_GetIter(args);
2026 24875 : if (source == NULL)
2027 0 : return NULL;
2028 :
2029 24875 : return chain_new_internal(type, source);
2030 : }
2031 :
2032 : /*[clinic input]
2033 : @classmethod
2034 : itertools.chain.from_iterable
2035 : iterable as arg: object
2036 : /
2037 : Alternative chain() constructor taking a single iterable argument that evaluates lazily.
2038 : [clinic start generated code]*/
2039 :
2040 : static PyObject *
2041 9673 : itertools_chain_from_iterable(PyTypeObject *type, PyObject *arg)
2042 : /*[clinic end generated code: output=667ae7a7f7b68654 input=72c39e3a2ca3be85]*/
2043 : {
2044 : PyObject *source;
2045 :
2046 9673 : source = PyObject_GetIter(arg);
2047 9673 : if (source == NULL)
2048 0 : return NULL;
2049 :
2050 9673 : return chain_new_internal(type, source);
2051 : }
2052 :
2053 : static void
2054 34548 : chain_dealloc(chainobject *lz)
2055 : {
2056 34548 : PyObject_GC_UnTrack(lz);
2057 34548 : Py_XDECREF(lz->active);
2058 34548 : Py_XDECREF(lz->source);
2059 34548 : Py_TYPE(lz)->tp_free(lz);
2060 34548 : }
2061 :
2062 : static int
2063 3924 : chain_traverse(chainobject *lz, visitproc visit, void *arg)
2064 : {
2065 3924 : Py_VISIT(lz->source);
2066 3924 : Py_VISIT(lz->active);
2067 3924 : return 0;
2068 : }
2069 :
2070 : static PyObject *
2071 4259280 : chain_next(chainobject *lz)
2072 : {
2073 : PyObject *item;
2074 :
2075 : /* lz->source is the iterator of iterables. If it's NULL, we've already
2076 : * consumed them all. lz->active is the current iterator. If it's NULL,
2077 : * we should grab a new one from lz->source. */
2078 14392600 : while (lz->source != NULL) {
2079 14392600 : if (lz->active == NULL) {
2080 10167800 : PyObject *iterable = PyIter_Next(lz->source);
2081 10167800 : if (iterable == NULL) {
2082 30881 : Py_CLEAR(lz->source);
2083 30881 : return NULL; /* no more input sources */
2084 : }
2085 10136900 : lz->active = PyObject_GetIter(iterable);
2086 10136900 : Py_DECREF(iterable);
2087 10136900 : if (lz->active == NULL) {
2088 19 : Py_CLEAR(lz->source);
2089 19 : return NULL; /* input not iterable */
2090 : }
2091 : }
2092 14361700 : item = (*Py_TYPE(lz->active)->tp_iternext)(lz->active);
2093 14361700 : if (item != NULL)
2094 4228360 : return item;
2095 10133300 : if (PyErr_Occurred()) {
2096 40 : if (PyErr_ExceptionMatches(PyExc_StopIteration))
2097 32 : PyErr_Clear();
2098 : else
2099 8 : return NULL; /* input raised an exception */
2100 : }
2101 : /* lz->active is consumed, try with the next iterable. */
2102 10133300 : Py_CLEAR(lz->active);
2103 : }
2104 : /* Everything had been consumed already. */
2105 5 : return NULL;
2106 : }
2107 :
2108 : static PyObject *
2109 66 : chain_reduce(chainobject *lz, PyObject *Py_UNUSED(ignored))
2110 : {
2111 66 : if (lz->source) {
2112 : /* we can't pickle function objects (itertools.from_iterable) so
2113 : * we must use setstate to replace the iterable. One day we
2114 : * will fix pickling of functions
2115 : */
2116 66 : if (lz->active) {
2117 19 : return Py_BuildValue("O()(OO)", Py_TYPE(lz), lz->source, lz->active);
2118 : } else {
2119 47 : return Py_BuildValue("O()(O)", Py_TYPE(lz), lz->source);
2120 : }
2121 : } else {
2122 0 : return Py_BuildValue("O()", Py_TYPE(lz)); /* exhausted */
2123 : }
2124 : return NULL;
2125 : }
2126 :
2127 : static PyObject *
2128 85 : chain_setstate(chainobject *lz, PyObject *state)
2129 : {
2130 85 : PyObject *source, *active=NULL;
2131 :
2132 85 : if (!PyTuple_Check(state)) {
2133 2 : PyErr_SetString(PyExc_TypeError, "state is not a tuple");
2134 2 : return NULL;
2135 : }
2136 83 : if (!PyArg_ParseTuple(state, "O|O", &source, &active)) {
2137 1 : return NULL;
2138 : }
2139 82 : if (!PyIter_Check(source) || (active != NULL && !PyIter_Check(active))) {
2140 2 : PyErr_SetString(PyExc_TypeError, "Arguments must be iterators.");
2141 2 : return NULL;
2142 : }
2143 :
2144 80 : Py_INCREF(source);
2145 80 : Py_XSETREF(lz->source, source);
2146 80 : Py_XINCREF(active);
2147 80 : Py_XSETREF(lz->active, active);
2148 80 : Py_RETURN_NONE;
2149 : }
2150 :
2151 : PyDoc_STRVAR(chain_doc,
2152 : "chain(*iterables) --> chain object\n\
2153 : \n\
2154 : Return a chain object whose .__next__() method returns elements from the\n\
2155 : first iterable until it is exhausted, then elements from the next\n\
2156 : iterable, until all of the iterables are exhausted.");
2157 :
2158 : static PyMethodDef chain_methods[] = {
2159 : ITERTOOLS_CHAIN_FROM_ITERABLE_METHODDEF
2160 : {"__reduce__", (PyCFunction)chain_reduce, METH_NOARGS,
2161 : reduce_doc},
2162 : {"__setstate__", (PyCFunction)chain_setstate, METH_O,
2163 : setstate_doc},
2164 : {"__class_getitem__", Py_GenericAlias,
2165 : METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
2166 : {NULL, NULL} /* sentinel */
2167 : };
2168 :
2169 : static PyTypeObject chain_type = {
2170 : PyVarObject_HEAD_INIT(NULL, 0)
2171 : "itertools.chain", /* tp_name */
2172 : sizeof(chainobject), /* tp_basicsize */
2173 : 0, /* tp_itemsize */
2174 : /* methods */
2175 : (destructor)chain_dealloc, /* tp_dealloc */
2176 : 0, /* tp_vectorcall_offset */
2177 : 0, /* tp_getattr */
2178 : 0, /* tp_setattr */
2179 : 0, /* tp_as_async */
2180 : 0, /* tp_repr */
2181 : 0, /* tp_as_number */
2182 : 0, /* tp_as_sequence */
2183 : 0, /* tp_as_mapping */
2184 : 0, /* tp_hash */
2185 : 0, /* tp_call */
2186 : 0, /* tp_str */
2187 : PyObject_GenericGetAttr, /* tp_getattro */
2188 : 0, /* tp_setattro */
2189 : 0, /* tp_as_buffer */
2190 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2191 : Py_TPFLAGS_BASETYPE, /* tp_flags */
2192 : chain_doc, /* tp_doc */
2193 : (traverseproc)chain_traverse, /* tp_traverse */
2194 : 0, /* tp_clear */
2195 : 0, /* tp_richcompare */
2196 : 0, /* tp_weaklistoffset */
2197 : PyObject_SelfIter, /* tp_iter */
2198 : (iternextfunc)chain_next, /* tp_iternext */
2199 : chain_methods, /* tp_methods */
2200 : 0, /* tp_members */
2201 : 0, /* tp_getset */
2202 : 0, /* tp_base */
2203 : 0, /* tp_dict */
2204 : 0, /* tp_descr_get */
2205 : 0, /* tp_descr_set */
2206 : 0, /* tp_dictoffset */
2207 : 0, /* tp_init */
2208 : 0, /* tp_alloc */
2209 : chain_new, /* tp_new */
2210 : PyObject_GC_Del, /* tp_free */
2211 : };
2212 :
2213 :
2214 : /* product object ************************************************************/
2215 :
2216 : typedef struct {
2217 : PyObject_HEAD
2218 : PyObject *pools; /* tuple of pool tuples */
2219 : Py_ssize_t *indices; /* one index per pool */
2220 : PyObject *result; /* most recently returned result tuple */
2221 : int stopped; /* set to 1 when the iterator is exhausted */
2222 : } productobject;
2223 :
2224 : static PyTypeObject product_type;
2225 :
2226 : static PyObject *
2227 59536 : product_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2228 : {
2229 : productobject *lz;
2230 59536 : Py_ssize_t nargs, npools, repeat=1;
2231 59536 : PyObject *pools = NULL;
2232 59536 : Py_ssize_t *indices = NULL;
2233 : Py_ssize_t i;
2234 :
2235 59536 : if (kwds != NULL) {
2236 529 : char *kwlist[] = {"repeat", 0};
2237 529 : PyObject *tmpargs = PyTuple_New(0);
2238 529 : if (tmpargs == NULL)
2239 1 : return NULL;
2240 529 : if (!PyArg_ParseTupleAndKeywords(tmpargs, kwds, "|n:product",
2241 : kwlist, &repeat)) {
2242 1 : Py_DECREF(tmpargs);
2243 1 : return NULL;
2244 : }
2245 528 : Py_DECREF(tmpargs);
2246 528 : if (repeat < 0) {
2247 0 : PyErr_SetString(PyExc_ValueError,
2248 : "repeat argument cannot be negative");
2249 0 : return NULL;
2250 : }
2251 : }
2252 :
2253 59535 : assert(PyTuple_CheckExact(args));
2254 59535 : if (repeat == 0) {
2255 26 : nargs = 0;
2256 : } else {
2257 59509 : nargs = PyTuple_GET_SIZE(args);
2258 59509 : if ((size_t)nargs > PY_SSIZE_T_MAX/sizeof(Py_ssize_t)/repeat) {
2259 0 : PyErr_SetString(PyExc_OverflowError, "repeat argument too large");
2260 0 : return NULL;
2261 : }
2262 : }
2263 59535 : npools = nargs * repeat;
2264 :
2265 59535 : indices = PyMem_New(Py_ssize_t, npools);
2266 59535 : if (indices == NULL) {
2267 0 : PyErr_NoMemory();
2268 0 : goto error;
2269 : }
2270 :
2271 59535 : pools = PyTuple_New(npools);
2272 59535 : if (pools == NULL)
2273 0 : goto error;
2274 :
2275 150442 : for (i=0; i < nargs ; ++i) {
2276 90923 : PyObject *item = PyTuple_GET_ITEM(args, i);
2277 90923 : PyObject *pool = PySequence_Tuple(item);
2278 90923 : if (pool == NULL)
2279 16 : goto error;
2280 90907 : PyTuple_SET_ITEM(pools, i, pool);
2281 90907 : indices[i] = 0;
2282 : }
2283 60510 : for ( ; i < npools; ++i) {
2284 991 : PyObject *pool = PyTuple_GET_ITEM(pools, i - nargs);
2285 991 : Py_INCREF(pool);
2286 991 : PyTuple_SET_ITEM(pools, i, pool);
2287 991 : indices[i] = 0;
2288 : }
2289 :
2290 : /* create productobject structure */
2291 59519 : lz = (productobject *)type->tp_alloc(type, 0);
2292 59519 : if (lz == NULL)
2293 0 : goto error;
2294 :
2295 59519 : lz->pools = pools;
2296 59519 : lz->indices = indices;
2297 59519 : lz->result = NULL;
2298 59519 : lz->stopped = 0;
2299 :
2300 59519 : return (PyObject *)lz;
2301 :
2302 16 : error:
2303 16 : if (indices != NULL)
2304 16 : PyMem_Free(indices);
2305 16 : Py_XDECREF(pools);
2306 16 : return NULL;
2307 : }
2308 :
2309 : static void
2310 59519 : product_dealloc(productobject *lz)
2311 : {
2312 59519 : PyObject_GC_UnTrack(lz);
2313 59519 : Py_XDECREF(lz->pools);
2314 59519 : Py_XDECREF(lz->result);
2315 59519 : if (lz->indices != NULL)
2316 59519 : PyMem_Free(lz->indices);
2317 59519 : Py_TYPE(lz)->tp_free(lz);
2318 59519 : }
2319 :
2320 : static PyObject *
2321 2 : product_sizeof(productobject *lz, void *unused)
2322 : {
2323 : Py_ssize_t res;
2324 :
2325 2 : res = _PyObject_SIZE(Py_TYPE(lz));
2326 2 : res += PyTuple_GET_SIZE(lz->pools) * sizeof(Py_ssize_t);
2327 2 : return PyLong_FromSsize_t(res);
2328 : }
2329 :
2330 : PyDoc_STRVAR(sizeof_doc, "Returns size in memory, in bytes.");
2331 :
2332 : static int
2333 46 : product_traverse(productobject *lz, visitproc visit, void *arg)
2334 : {
2335 46 : Py_VISIT(lz->pools);
2336 46 : Py_VISIT(lz->result);
2337 46 : return 0;
2338 : }
2339 :
2340 : static PyObject *
2341 1470370 : product_next(productobject *lz)
2342 : {
2343 : PyObject *pool;
2344 : PyObject *elem;
2345 : PyObject *oldelem;
2346 1470370 : PyObject *pools = lz->pools;
2347 1470370 : PyObject *result = lz->result;
2348 1470370 : Py_ssize_t npools = PyTuple_GET_SIZE(pools);
2349 : Py_ssize_t i;
2350 :
2351 1470370 : if (lz->stopped)
2352 19 : return NULL;
2353 :
2354 1470360 : if (result == NULL) {
2355 : /* On the first pass, return an initial tuple filled with the
2356 : first element from each pool. */
2357 59485 : result = PyTuple_New(npools);
2358 59485 : if (result == NULL)
2359 0 : goto empty;
2360 59485 : lz->result = result;
2361 150627 : for (i=0; i < npools; i++) {
2362 91474 : pool = PyTuple_GET_ITEM(pools, i);
2363 91474 : if (PyTuple_GET_SIZE(pool) == 0)
2364 332 : goto empty;
2365 91142 : elem = PyTuple_GET_ITEM(pool, 0);
2366 91142 : Py_INCREF(elem);
2367 91142 : PyTuple_SET_ITEM(result, i, elem);
2368 : }
2369 : } else {
2370 1410870 : Py_ssize_t *indices = lz->indices;
2371 :
2372 : /* Copy the previous result tuple or re-use it if available */
2373 1410870 : if (Py_REFCNT(result) > 1) {
2374 1306210 : PyObject *old_result = result;
2375 1306210 : result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), npools);
2376 1306210 : if (result == NULL)
2377 0 : goto empty;
2378 1306210 : lz->result = result;
2379 1306210 : Py_DECREF(old_result);
2380 : }
2381 : // bpo-42536: The GC may have untracked this result tuple. Since we're
2382 : // recycling it, make sure it's tracked again:
2383 104663 : else if (!_PyObject_GC_IS_TRACKED(result)) {
2384 4 : _PyObject_GC_TRACK(result);
2385 : }
2386 : /* Now, we've got the only copy so we can update it in-place */
2387 1410870 : assert (npools==0 || Py_REFCNT(result) == 1);
2388 :
2389 : /* Update the pool indices right-to-left. Only advance to the
2390 : next pool when the previous one rolls-over */
2391 1750570 : for (i=npools-1 ; i >= 0 ; i--) {
2392 1691940 : pool = PyTuple_GET_ITEM(pools, i);
2393 1691940 : indices[i]++;
2394 1691940 : if (indices[i] == PyTuple_GET_SIZE(pool)) {
2395 : /* Roll-over and advance to next pool */
2396 339702 : indices[i] = 0;
2397 339702 : elem = PyTuple_GET_ITEM(pool, 0);
2398 339702 : Py_INCREF(elem);
2399 339702 : oldelem = PyTuple_GET_ITEM(result, i);
2400 339702 : PyTuple_SET_ITEM(result, i, elem);
2401 339702 : Py_DECREF(oldelem);
2402 : } else {
2403 : /* No rollover. Just increment and stop here. */
2404 1352240 : elem = PyTuple_GET_ITEM(pool, indices[i]);
2405 1352240 : Py_INCREF(elem);
2406 1352240 : oldelem = PyTuple_GET_ITEM(result, i);
2407 1352240 : PyTuple_SET_ITEM(result, i, elem);
2408 1352240 : Py_DECREF(oldelem);
2409 1352240 : break;
2410 : }
2411 : }
2412 :
2413 : /* If i is negative, then the indices have all rolled-over
2414 : and we're done. */
2415 1410870 : if (i < 0)
2416 58633 : goto empty;
2417 : }
2418 :
2419 1411390 : Py_INCREF(result);
2420 1411390 : return result;
2421 :
2422 58965 : empty:
2423 58965 : lz->stopped = 1;
2424 58965 : return NULL;
2425 : }
2426 :
2427 : static PyObject *
2428 84 : product_reduce(productobject *lz, PyObject *Py_UNUSED(ignored))
2429 : {
2430 84 : if (lz->stopped) {
2431 18 : return Py_BuildValue("O(())", Py_TYPE(lz));
2432 66 : } else if (lz->result == NULL) {
2433 48 : return Py_BuildValue("OO", Py_TYPE(lz), lz->pools);
2434 : } else {
2435 : PyObject *indices;
2436 : Py_ssize_t n, i;
2437 :
2438 : /* we must pickle the indices use them for setstate, and
2439 : * additionally indicate that the iterator has started
2440 : */
2441 18 : n = PyTuple_GET_SIZE(lz->pools);
2442 18 : indices = PyTuple_New(n);
2443 18 : if (indices == NULL)
2444 0 : return NULL;
2445 36 : for (i=0; i<n; i++){
2446 18 : PyObject* index = PyLong_FromSsize_t(lz->indices[i]);
2447 18 : if (!index) {
2448 0 : Py_DECREF(indices);
2449 0 : return NULL;
2450 : }
2451 18 : PyTuple_SET_ITEM(indices, i, index);
2452 : }
2453 18 : return Py_BuildValue("OON", Py_TYPE(lz), lz->pools, indices);
2454 : }
2455 : }
2456 :
2457 : static PyObject *
2458 20 : product_setstate(productobject *lz, PyObject *state)
2459 : {
2460 : PyObject *result;
2461 : Py_ssize_t n, i;
2462 :
2463 20 : n = PyTuple_GET_SIZE(lz->pools);
2464 20 : if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != n) {
2465 0 : PyErr_SetString(PyExc_ValueError, "invalid arguments");
2466 0 : return NULL;
2467 : }
2468 41 : for (i=0; i<n; i++)
2469 : {
2470 22 : PyObject* indexObject = PyTuple_GET_ITEM(state, i);
2471 22 : Py_ssize_t index = PyLong_AsSsize_t(indexObject);
2472 : PyObject* pool;
2473 : Py_ssize_t poolsize;
2474 22 : if (index < 0 && PyErr_Occurred())
2475 0 : return NULL; /* not an integer */
2476 22 : pool = PyTuple_GET_ITEM(lz->pools, i);
2477 22 : poolsize = PyTuple_GET_SIZE(pool);
2478 22 : if (poolsize == 0) {
2479 1 : lz->stopped = 1;
2480 1 : Py_RETURN_NONE;
2481 : }
2482 : /* clamp the index */
2483 21 : if (index < 0)
2484 0 : index = 0;
2485 21 : else if (index > poolsize-1)
2486 1 : index = poolsize-1;
2487 21 : lz->indices[i] = index;
2488 : }
2489 :
2490 19 : result = PyTuple_New(n);
2491 19 : if (!result)
2492 0 : return NULL;
2493 39 : for (i=0; i<n; i++) {
2494 20 : PyObject *pool = PyTuple_GET_ITEM(lz->pools, i);
2495 20 : PyObject *element = PyTuple_GET_ITEM(pool, lz->indices[i]);
2496 20 : Py_INCREF(element);
2497 20 : PyTuple_SET_ITEM(result, i, element);
2498 : }
2499 19 : Py_XSETREF(lz->result, result);
2500 19 : Py_RETURN_NONE;
2501 : }
2502 :
2503 : static PyMethodDef product_methods[] = {
2504 : {"__reduce__", (PyCFunction)product_reduce, METH_NOARGS,
2505 : reduce_doc},
2506 : {"__setstate__", (PyCFunction)product_setstate, METH_O,
2507 : setstate_doc},
2508 : {"__sizeof__", (PyCFunction)product_sizeof, METH_NOARGS,
2509 : sizeof_doc},
2510 : {NULL, NULL} /* sentinel */
2511 : };
2512 :
2513 : PyDoc_STRVAR(product_doc,
2514 : "product(*iterables, repeat=1) --> product object\n\
2515 : \n\
2516 : Cartesian product of input iterables. Equivalent to nested for-loops.\n\n\
2517 : For example, product(A, B) returns the same as: ((x,y) for x in A for y in B).\n\
2518 : The leftmost iterators are in the outermost for-loop, so the output tuples\n\
2519 : cycle in a manner similar to an odometer (with the rightmost element changing\n\
2520 : on every iteration).\n\n\
2521 : To compute the product of an iterable with itself, specify the number\n\
2522 : of repetitions with the optional repeat keyword argument. For example,\n\
2523 : product(A, repeat=4) means the same as product(A, A, A, A).\n\n\
2524 : product('ab', range(3)) --> ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2)\n\
2525 : product((0,1), (0,1), (0,1)) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ...");
2526 :
2527 : static PyTypeObject product_type = {
2528 : PyVarObject_HEAD_INIT(NULL, 0)
2529 : "itertools.product", /* tp_name */
2530 : sizeof(productobject), /* tp_basicsize */
2531 : 0, /* tp_itemsize */
2532 : /* methods */
2533 : (destructor)product_dealloc, /* tp_dealloc */
2534 : 0, /* tp_vectorcall_offset */
2535 : 0, /* tp_getattr */
2536 : 0, /* tp_setattr */
2537 : 0, /* tp_as_async */
2538 : 0, /* tp_repr */
2539 : 0, /* tp_as_number */
2540 : 0, /* tp_as_sequence */
2541 : 0, /* tp_as_mapping */
2542 : 0, /* tp_hash */
2543 : 0, /* tp_call */
2544 : 0, /* tp_str */
2545 : PyObject_GenericGetAttr, /* tp_getattro */
2546 : 0, /* tp_setattro */
2547 : 0, /* tp_as_buffer */
2548 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2549 : Py_TPFLAGS_BASETYPE, /* tp_flags */
2550 : product_doc, /* tp_doc */
2551 : (traverseproc)product_traverse, /* tp_traverse */
2552 : 0, /* tp_clear */
2553 : 0, /* tp_richcompare */
2554 : 0, /* tp_weaklistoffset */
2555 : PyObject_SelfIter, /* tp_iter */
2556 : (iternextfunc)product_next, /* tp_iternext */
2557 : product_methods, /* tp_methods */
2558 : 0, /* tp_members */
2559 : 0, /* tp_getset */
2560 : 0, /* tp_base */
2561 : 0, /* tp_dict */
2562 : 0, /* tp_descr_get */
2563 : 0, /* tp_descr_set */
2564 : 0, /* tp_dictoffset */
2565 : 0, /* tp_init */
2566 : 0, /* tp_alloc */
2567 : product_new, /* tp_new */
2568 : PyObject_GC_Del, /* tp_free */
2569 : };
2570 :
2571 :
2572 : /* combinations object *******************************************************/
2573 :
2574 : typedef struct {
2575 : PyObject_HEAD
2576 : PyObject *pool; /* input converted to a tuple */
2577 : Py_ssize_t *indices; /* one index per result element */
2578 : PyObject *result; /* most recently returned result tuple */
2579 : Py_ssize_t r; /* size of result tuple */
2580 : int stopped; /* set to 1 when the iterator is exhausted */
2581 : } combinationsobject;
2582 :
2583 :
2584 : /*[clinic input]
2585 : @classmethod
2586 : itertools.combinations.__new__
2587 : iterable: object
2588 : r: Py_ssize_t
2589 : Return successive r-length combinations of elements in the iterable.
2590 :
2591 : combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)
2592 : [clinic start generated code]*/
2593 :
2594 : static PyObject *
2595 6012 : itertools_combinations_impl(PyTypeObject *type, PyObject *iterable,
2596 : Py_ssize_t r)
2597 : /*[clinic end generated code: output=87a689b39c40039c input=06bede09e3da20f8]*/
2598 : {
2599 : combinationsobject *co;
2600 : Py_ssize_t n;
2601 6012 : PyObject *pool = NULL;
2602 6012 : Py_ssize_t *indices = NULL;
2603 : Py_ssize_t i;
2604 :
2605 6012 : pool = PySequence_Tuple(iterable);
2606 6012 : if (pool == NULL)
2607 0 : goto error;
2608 6012 : n = PyTuple_GET_SIZE(pool);
2609 6012 : if (r < 0) {
2610 1 : PyErr_SetString(PyExc_ValueError, "r must be non-negative");
2611 1 : goto error;
2612 : }
2613 :
2614 6011 : indices = PyMem_New(Py_ssize_t, r);
2615 6011 : if (indices == NULL) {
2616 0 : PyErr_NoMemory();
2617 0 : goto error;
2618 : }
2619 :
2620 23548 : for (i=0 ; i<r ; i++)
2621 17537 : indices[i] = i;
2622 :
2623 : /* create combinationsobject structure */
2624 6011 : co = (combinationsobject *)type->tp_alloc(type, 0);
2625 6011 : if (co == NULL)
2626 0 : goto error;
2627 :
2628 6011 : co->pool = pool;
2629 6011 : co->indices = indices;
2630 6011 : co->result = NULL;
2631 6011 : co->r = r;
2632 6011 : co->stopped = r > n ? 1 : 0;
2633 :
2634 6011 : return (PyObject *)co;
2635 :
2636 1 : error:
2637 1 : if (indices != NULL)
2638 0 : PyMem_Free(indices);
2639 1 : Py_XDECREF(pool);
2640 1 : return NULL;
2641 : }
2642 :
2643 : static void
2644 6011 : combinations_dealloc(combinationsobject *co)
2645 : {
2646 6011 : PyObject_GC_UnTrack(co);
2647 6011 : Py_XDECREF(co->pool);
2648 6011 : Py_XDECREF(co->result);
2649 6011 : if (co->indices != NULL)
2650 6011 : PyMem_Free(co->indices);
2651 6011 : Py_TYPE(co)->tp_free(co);
2652 6011 : }
2653 :
2654 : static PyObject *
2655 2 : combinations_sizeof(combinationsobject *co, void *unused)
2656 : {
2657 : Py_ssize_t res;
2658 :
2659 2 : res = _PyObject_SIZE(Py_TYPE(co));
2660 2 : res += co->r * sizeof(Py_ssize_t);
2661 2 : return PyLong_FromSsize_t(res);
2662 : }
2663 :
2664 : static int
2665 14 : combinations_traverse(combinationsobject *co, visitproc visit, void *arg)
2666 : {
2667 14 : Py_VISIT(co->pool);
2668 14 : Py_VISIT(co->result);
2669 14 : return 0;
2670 : }
2671 :
2672 : static PyObject *
2673 1079380 : combinations_next(combinationsobject *co)
2674 : {
2675 : PyObject *elem;
2676 : PyObject *oldelem;
2677 1079380 : PyObject *pool = co->pool;
2678 1079380 : Py_ssize_t *indices = co->indices;
2679 1079380 : PyObject *result = co->result;
2680 1079380 : Py_ssize_t n = PyTuple_GET_SIZE(pool);
2681 1079380 : Py_ssize_t r = co->r;
2682 : Py_ssize_t i, j, index;
2683 :
2684 1079380 : if (co->stopped)
2685 258 : return NULL;
2686 :
2687 1079120 : if (result == NULL) {
2688 : /* On the first pass, initialize result tuple using the indices */
2689 5595 : result = PyTuple_New(r);
2690 5595 : if (result == NULL)
2691 0 : goto empty;
2692 5595 : co->result = result;
2693 21452 : for (i=0; i<r ; i++) {
2694 15857 : index = indices[i];
2695 15857 : elem = PyTuple_GET_ITEM(pool, index);
2696 15857 : Py_INCREF(elem);
2697 15857 : PyTuple_SET_ITEM(result, i, elem);
2698 : }
2699 : } else {
2700 : /* Copy the previous result tuple or re-use it if available */
2701 1073520 : if (Py_REFCNT(result) > 1) {
2702 24717 : PyObject *old_result = result;
2703 24717 : result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r);
2704 24717 : if (result == NULL)
2705 0 : goto empty;
2706 24717 : co->result = result;
2707 24717 : Py_DECREF(old_result);
2708 : }
2709 : // bpo-42536: The GC may have untracked this result tuple. Since we're
2710 : // recycling it, make sure it's tracked again:
2711 1048800 : else if (!_PyObject_GC_IS_TRACKED(result)) {
2712 1 : _PyObject_GC_TRACK(result);
2713 : }
2714 : /* Now, we've got the only copy so we can update it in-place
2715 : * CPython's empty tuple is a singleton and cached in
2716 : * PyTuple's freelist.
2717 : */
2718 1073520 : assert(r == 0 || Py_REFCNT(result) == 1);
2719 :
2720 : /* Scan indices right-to-left until finding one that is not
2721 : at its maximum (i + n - r). */
2722 2145760 : for (i=r-1 ; i >= 0 && indices[i] == i+n-r ; i--)
2723 : ;
2724 :
2725 : /* If i is negative, then the indices are all at
2726 : their maximum value and we're done. */
2727 1073520 : if (i < 0)
2728 5497 : goto empty;
2729 :
2730 : /* Increment the current index which we know is not at its
2731 : maximum. Then move back to the right setting each index
2732 : to its lowest possible value (one higher than the index
2733 : to its left -- this maintains the sort order invariant). */
2734 1068020 : indices[i]++;
2735 2124770 : for (j=i+1 ; j<r ; j++)
2736 1056740 : indices[j] = indices[j-1] + 1;
2737 :
2738 : /* Update the result tuple for the new indices
2739 : starting with i, the leftmost index that changed */
2740 3192800 : for ( ; i<r ; i++) {
2741 2124770 : index = indices[i];
2742 2124770 : elem = PyTuple_GET_ITEM(pool, index);
2743 2124770 : Py_INCREF(elem);
2744 2124770 : oldelem = PyTuple_GET_ITEM(result, i);
2745 2124770 : PyTuple_SET_ITEM(result, i, elem);
2746 2124770 : Py_DECREF(oldelem);
2747 : }
2748 : }
2749 :
2750 1073620 : Py_INCREF(result);
2751 1073620 : return result;
2752 :
2753 5497 : empty:
2754 5497 : co->stopped = 1;
2755 5497 : return NULL;
2756 : }
2757 :
2758 : static PyObject *
2759 450 : combinations_reduce(combinationsobject *lz, PyObject *Py_UNUSED(ignored))
2760 : {
2761 450 : if (lz->result == NULL) {
2762 270 : return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r);
2763 180 : } else if (lz->stopped) {
2764 0 : return Py_BuildValue("O(()n)", Py_TYPE(lz), lz->r);
2765 : } else {
2766 : PyObject *indices;
2767 : Py_ssize_t i;
2768 :
2769 : /* we must pickle the indices and use them for setstate */
2770 180 : indices = PyTuple_New(lz->r);
2771 180 : if (!indices)
2772 0 : return NULL;
2773 546 : for (i=0; i<lz->r; i++)
2774 : {
2775 366 : PyObject* index = PyLong_FromSsize_t(lz->indices[i]);
2776 366 : if (!index) {
2777 0 : Py_DECREF(indices);
2778 0 : return NULL;
2779 : }
2780 366 : PyTuple_SET_ITEM(indices, i, index);
2781 : }
2782 :
2783 180 : return Py_BuildValue("O(On)N", Py_TYPE(lz), lz->pool, lz->r, indices);
2784 : }
2785 : }
2786 :
2787 : static PyObject *
2788 180 : combinations_setstate(combinationsobject *lz, PyObject *state)
2789 : {
2790 : PyObject *result;
2791 : Py_ssize_t i;
2792 180 : Py_ssize_t n = PyTuple_GET_SIZE(lz->pool);
2793 :
2794 180 : if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r) {
2795 0 : PyErr_SetString(PyExc_ValueError, "invalid arguments");
2796 0 : return NULL;
2797 : }
2798 :
2799 546 : for (i=0; i<lz->r; i++) {
2800 : Py_ssize_t max;
2801 366 : PyObject* indexObject = PyTuple_GET_ITEM(state, i);
2802 366 : Py_ssize_t index = PyLong_AsSsize_t(indexObject);
2803 :
2804 366 : if (index == -1 && PyErr_Occurred())
2805 0 : return NULL; /* not an integer */
2806 366 : max = i + n - lz->r;
2807 : /* clamp the index (beware of negative max) */
2808 366 : if (index > max)
2809 0 : index = max;
2810 366 : if (index < 0)
2811 0 : index = 0;
2812 366 : lz->indices[i] = index;
2813 : }
2814 :
2815 180 : result = PyTuple_New(lz->r);
2816 180 : if (result == NULL)
2817 0 : return NULL;
2818 546 : for (i=0; i<lz->r; i++) {
2819 366 : PyObject *element = PyTuple_GET_ITEM(lz->pool, lz->indices[i]);
2820 366 : Py_INCREF(element);
2821 366 : PyTuple_SET_ITEM(result, i, element);
2822 : }
2823 :
2824 180 : Py_XSETREF(lz->result, result);
2825 180 : Py_RETURN_NONE;
2826 : }
2827 :
2828 : static PyMethodDef combinations_methods[] = {
2829 : {"__reduce__", (PyCFunction)combinations_reduce, METH_NOARGS,
2830 : reduce_doc},
2831 : {"__setstate__", (PyCFunction)combinations_setstate, METH_O,
2832 : setstate_doc},
2833 : {"__sizeof__", (PyCFunction)combinations_sizeof, METH_NOARGS,
2834 : sizeof_doc},
2835 : {NULL, NULL} /* sentinel */
2836 : };
2837 :
2838 : static PyTypeObject combinations_type = {
2839 : PyVarObject_HEAD_INIT(NULL, 0)
2840 : "itertools.combinations", /* tp_name */
2841 : sizeof(combinationsobject), /* tp_basicsize */
2842 : 0, /* tp_itemsize */
2843 : /* methods */
2844 : (destructor)combinations_dealloc, /* tp_dealloc */
2845 : 0, /* tp_vectorcall_offset */
2846 : 0, /* tp_getattr */
2847 : 0, /* tp_setattr */
2848 : 0, /* tp_as_async */
2849 : 0, /* tp_repr */
2850 : 0, /* tp_as_number */
2851 : 0, /* tp_as_sequence */
2852 : 0, /* tp_as_mapping */
2853 : 0, /* tp_hash */
2854 : 0, /* tp_call */
2855 : 0, /* tp_str */
2856 : PyObject_GenericGetAttr, /* tp_getattro */
2857 : 0, /* tp_setattro */
2858 : 0, /* tp_as_buffer */
2859 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2860 : Py_TPFLAGS_BASETYPE, /* tp_flags */
2861 : itertools_combinations__doc__, /* tp_doc */
2862 : (traverseproc)combinations_traverse,/* tp_traverse */
2863 : 0, /* tp_clear */
2864 : 0, /* tp_richcompare */
2865 : 0, /* tp_weaklistoffset */
2866 : PyObject_SelfIter, /* tp_iter */
2867 : (iternextfunc)combinations_next, /* tp_iternext */
2868 : combinations_methods, /* tp_methods */
2869 : 0, /* tp_members */
2870 : 0, /* tp_getset */
2871 : 0, /* tp_base */
2872 : 0, /* tp_dict */
2873 : 0, /* tp_descr_get */
2874 : 0, /* tp_descr_set */
2875 : 0, /* tp_dictoffset */
2876 : 0, /* tp_init */
2877 : 0, /* tp_alloc */
2878 : itertools_combinations, /* tp_new */
2879 : PyObject_GC_Del, /* tp_free */
2880 : };
2881 :
2882 :
2883 : /* combinations with replacement object **************************************/
2884 :
2885 : /* Equivalent to:
2886 :
2887 : def combinations_with_replacement(iterable, r):
2888 : "combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC"
2889 : # number items returned: (n+r-1)! / r! / (n-1)!
2890 : pool = tuple(iterable)
2891 : n = len(pool)
2892 : indices = [0] * r
2893 : yield tuple(pool[i] for i in indices)
2894 : while 1:
2895 : for i in reversed(range(r)):
2896 : if indices[i] != n - 1:
2897 : break
2898 : else:
2899 : return
2900 : indices[i:] = [indices[i] + 1] * (r - i)
2901 : yield tuple(pool[i] for i in indices)
2902 :
2903 : def combinations_with_replacement2(iterable, r):
2904 : 'Alternate version that filters from product()'
2905 : pool = tuple(iterable)
2906 : n = len(pool)
2907 : for indices in product(range(n), repeat=r):
2908 : if sorted(indices) == list(indices):
2909 : yield tuple(pool[i] for i in indices)
2910 : */
2911 : typedef struct {
2912 : PyObject_HEAD
2913 : PyObject *pool; /* input converted to a tuple */
2914 : Py_ssize_t *indices; /* one index per result element */
2915 : PyObject *result; /* most recently returned result tuple */
2916 : Py_ssize_t r; /* size of result tuple */
2917 : int stopped; /* set to 1 when the cwr iterator is exhausted */
2918 : } cwrobject;
2919 :
2920 : /*[clinic input]
2921 : @classmethod
2922 : itertools.combinations_with_replacement.__new__
2923 : iterable: object
2924 : r: Py_ssize_t
2925 : Return successive r-length combinations of elements in the iterable allowing individual elements to have successive repeats.
2926 :
2927 : combinations_with_replacement('ABC', 2) --> ('A','A'), ('A','B'), ('A','C'), ('B','B'), ('B','C'), ('C','C')
2928 : [clinic start generated code]*/
2929 :
2930 : static PyObject *
2931 998 : itertools_combinations_with_replacement_impl(PyTypeObject *type,
2932 : PyObject *iterable,
2933 : Py_ssize_t r)
2934 : /*[clinic end generated code: output=48b26856d4e659ca input=1dc58e82a0878fdc]*/
2935 : {
2936 : cwrobject *co;
2937 : Py_ssize_t n;
2938 998 : PyObject *pool = NULL;
2939 998 : Py_ssize_t *indices = NULL;
2940 : Py_ssize_t i;
2941 :
2942 998 : pool = PySequence_Tuple(iterable);
2943 998 : if (pool == NULL)
2944 0 : goto error;
2945 998 : n = PyTuple_GET_SIZE(pool);
2946 998 : if (r < 0) {
2947 1 : PyErr_SetString(PyExc_ValueError, "r must be non-negative");
2948 1 : goto error;
2949 : }
2950 :
2951 997 : indices = PyMem_New(Py_ssize_t, r);
2952 997 : if (indices == NULL) {
2953 0 : PyErr_NoMemory();
2954 0 : goto error;
2955 : }
2956 :
2957 3420 : for (i=0 ; i<r ; i++)
2958 2423 : indices[i] = 0;
2959 :
2960 : /* create cwrobject structure */
2961 997 : co = (cwrobject *)type->tp_alloc(type, 0);
2962 997 : if (co == NULL)
2963 0 : goto error;
2964 :
2965 997 : co->pool = pool;
2966 997 : co->indices = indices;
2967 997 : co->result = NULL;
2968 997 : co->r = r;
2969 997 : co->stopped = !n && r;
2970 :
2971 997 : return (PyObject *)co;
2972 :
2973 1 : error:
2974 1 : if (indices != NULL)
2975 0 : PyMem_Free(indices);
2976 1 : Py_XDECREF(pool);
2977 1 : return NULL;
2978 : }
2979 :
2980 : static void
2981 997 : cwr_dealloc(cwrobject *co)
2982 : {
2983 997 : PyObject_GC_UnTrack(co);
2984 997 : Py_XDECREF(co->pool);
2985 997 : Py_XDECREF(co->result);
2986 997 : if (co->indices != NULL)
2987 997 : PyMem_Free(co->indices);
2988 997 : Py_TYPE(co)->tp_free(co);
2989 997 : }
2990 :
2991 : static PyObject *
2992 2 : cwr_sizeof(cwrobject *co, void *unused)
2993 : {
2994 : Py_ssize_t res;
2995 :
2996 2 : res = _PyObject_SIZE(Py_TYPE(co));
2997 2 : res += co->r * sizeof(Py_ssize_t);
2998 2 : return PyLong_FromSsize_t(res);
2999 : }
3000 :
3001 : static int
3002 18 : cwr_traverse(cwrobject *co, visitproc visit, void *arg)
3003 : {
3004 18 : Py_VISIT(co->pool);
3005 18 : Py_VISIT(co->result);
3006 18 : return 0;
3007 : }
3008 :
3009 : static PyObject *
3010 9195 : cwr_next(cwrobject *co)
3011 : {
3012 : PyObject *elem;
3013 : PyObject *oldelem;
3014 9195 : PyObject *pool = co->pool;
3015 9195 : Py_ssize_t *indices = co->indices;
3016 9195 : PyObject *result = co->result;
3017 9195 : Py_ssize_t n = PyTuple_GET_SIZE(pool);
3018 9195 : Py_ssize_t r = co->r;
3019 : Py_ssize_t i, index;
3020 :
3021 9195 : if (co->stopped)
3022 39 : return NULL;
3023 :
3024 9156 : if (result == NULL) {
3025 : /* On the first pass, initialize result tuple with pool[0] */
3026 746 : result = PyTuple_New(r);
3027 746 : if (result == NULL)
3028 0 : goto empty;
3029 746 : co->result = result;
3030 746 : if (n > 0) {
3031 725 : elem = PyTuple_GET_ITEM(pool, 0);
3032 2565 : for (i=0; i<r ; i++) {
3033 1840 : assert(indices[i] == 0);
3034 1840 : Py_INCREF(elem);
3035 1840 : PyTuple_SET_ITEM(result, i, elem);
3036 : }
3037 : }
3038 : } else {
3039 : /* Copy the previous result tuple or re-use it if available */
3040 8410 : if (Py_REFCNT(result) > 1) {
3041 8043 : PyObject *old_result = result;
3042 8043 : result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r);
3043 8043 : if (result == NULL)
3044 0 : goto empty;
3045 8043 : co->result = result;
3046 8043 : Py_DECREF(old_result);
3047 : }
3048 : // bpo-42536: The GC may have untracked this result tuple. Since we're
3049 : // recycling it, make sure it's tracked again:
3050 367 : else if (!_PyObject_GC_IS_TRACKED(result)) {
3051 1 : _PyObject_GC_TRACK(result);
3052 : }
3053 : /* Now, we've got the only copy so we can update it in-place CPython's
3054 : empty tuple is a singleton and cached in PyTuple's freelist. */
3055 8410 : assert(r == 0 || Py_REFCNT(result) == 1);
3056 :
3057 : /* Scan indices right-to-left until finding one that is not
3058 : * at its maximum (n-1). */
3059 15356 : for (i=r-1 ; i >= 0 && indices[i] == n-1; i--)
3060 : ;
3061 :
3062 : /* If i is negative, then the indices are all at
3063 : their maximum value and we're done. */
3064 8410 : if (i < 0)
3065 438 : goto empty;
3066 :
3067 : /* Increment the current index which we know is not at its
3068 : maximum. Then set all to the right to the same value. */
3069 7972 : index = indices[i] + 1;
3070 7972 : assert(index < n);
3071 7972 : elem = PyTuple_GET_ITEM(pool, index);
3072 22332 : for ( ; i<r ; i++) {
3073 14360 : indices[i] = index;
3074 14360 : Py_INCREF(elem);
3075 14360 : oldelem = PyTuple_GET_ITEM(result, i);
3076 14360 : PyTuple_SET_ITEM(result, i, elem);
3077 14360 : Py_DECREF(oldelem);
3078 : }
3079 : }
3080 :
3081 8718 : Py_INCREF(result);
3082 8718 : return result;
3083 :
3084 438 : empty:
3085 438 : co->stopped = 1;
3086 438 : return NULL;
3087 : }
3088 :
3089 : static PyObject *
3090 432 : cwr_reduce(cwrobject *lz, PyObject *Py_UNUSED(ignored))
3091 : {
3092 432 : if (lz->result == NULL) {
3093 222 : return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r);
3094 210 : } else if (lz->stopped) {
3095 0 : return Py_BuildValue("O(()n)", Py_TYPE(lz), lz->r);
3096 : } else {
3097 : PyObject *indices;
3098 : Py_ssize_t i;
3099 :
3100 : /* we must pickle the indices and use them for setstate */
3101 210 : indices = PyTuple_New(lz->r);
3102 210 : if (!indices)
3103 0 : return NULL;
3104 720 : for (i=0; i<lz->r; i++) {
3105 510 : PyObject* index = PyLong_FromSsize_t(lz->indices[i]);
3106 510 : if (!index) {
3107 0 : Py_DECREF(indices);
3108 0 : return NULL;
3109 : }
3110 510 : PyTuple_SET_ITEM(indices, i, index);
3111 : }
3112 :
3113 210 : return Py_BuildValue("O(On)N", Py_TYPE(lz), lz->pool, lz->r, indices);
3114 : }
3115 : }
3116 :
3117 : static PyObject *
3118 210 : cwr_setstate(cwrobject *lz, PyObject *state)
3119 : {
3120 : PyObject *result;
3121 : Py_ssize_t n, i;
3122 :
3123 210 : if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r)
3124 : {
3125 0 : PyErr_SetString(PyExc_ValueError, "invalid arguments");
3126 0 : return NULL;
3127 : }
3128 :
3129 210 : n = PyTuple_GET_SIZE(lz->pool);
3130 720 : for (i=0; i<lz->r; i++) {
3131 510 : PyObject* indexObject = PyTuple_GET_ITEM(state, i);
3132 510 : Py_ssize_t index = PyLong_AsSsize_t(indexObject);
3133 :
3134 510 : if (index < 0 && PyErr_Occurred())
3135 0 : return NULL; /* not an integer */
3136 : /* clamp the index */
3137 510 : if (index < 0)
3138 0 : index = 0;
3139 510 : else if (index > n-1)
3140 0 : index = n-1;
3141 510 : lz->indices[i] = index;
3142 : }
3143 210 : result = PyTuple_New(lz->r);
3144 210 : if (result == NULL)
3145 0 : return NULL;
3146 720 : for (i=0; i<lz->r; i++) {
3147 510 : PyObject *element = PyTuple_GET_ITEM(lz->pool, lz->indices[i]);
3148 510 : Py_INCREF(element);
3149 510 : PyTuple_SET_ITEM(result, i, element);
3150 : }
3151 210 : Py_XSETREF(lz->result, result);
3152 210 : Py_RETURN_NONE;
3153 : }
3154 :
3155 : static PyMethodDef cwr_methods[] = {
3156 : {"__reduce__", (PyCFunction)cwr_reduce, METH_NOARGS,
3157 : reduce_doc},
3158 : {"__setstate__", (PyCFunction)cwr_setstate, METH_O,
3159 : setstate_doc},
3160 : {"__sizeof__", (PyCFunction)cwr_sizeof, METH_NOARGS,
3161 : sizeof_doc},
3162 : {NULL, NULL} /* sentinel */
3163 : };
3164 :
3165 : static PyTypeObject cwr_type = {
3166 : PyVarObject_HEAD_INIT(NULL, 0)
3167 : "itertools.combinations_with_replacement", /* tp_name */
3168 : sizeof(cwrobject), /* tp_basicsize */
3169 : 0, /* tp_itemsize */
3170 : /* methods */
3171 : (destructor)cwr_dealloc, /* tp_dealloc */
3172 : 0, /* tp_vectorcall_offset */
3173 : 0, /* tp_getattr */
3174 : 0, /* tp_setattr */
3175 : 0, /* tp_as_async */
3176 : 0, /* tp_repr */
3177 : 0, /* tp_as_number */
3178 : 0, /* tp_as_sequence */
3179 : 0, /* tp_as_mapping */
3180 : 0, /* tp_hash */
3181 : 0, /* tp_call */
3182 : 0, /* tp_str */
3183 : PyObject_GenericGetAttr, /* tp_getattro */
3184 : 0, /* tp_setattro */
3185 : 0, /* tp_as_buffer */
3186 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
3187 : Py_TPFLAGS_BASETYPE, /* tp_flags */
3188 : itertools_combinations_with_replacement__doc__, /* tp_doc */
3189 : (traverseproc)cwr_traverse, /* tp_traverse */
3190 : 0, /* tp_clear */
3191 : 0, /* tp_richcompare */
3192 : 0, /* tp_weaklistoffset */
3193 : PyObject_SelfIter, /* tp_iter */
3194 : (iternextfunc)cwr_next, /* tp_iternext */
3195 : cwr_methods, /* tp_methods */
3196 : 0, /* tp_members */
3197 : 0, /* tp_getset */
3198 : 0, /* tp_base */
3199 : 0, /* tp_dict */
3200 : 0, /* tp_descr_get */
3201 : 0, /* tp_descr_set */
3202 : 0, /* tp_dictoffset */
3203 : 0, /* tp_init */
3204 : 0, /* tp_alloc */
3205 : itertools_combinations_with_replacement, /* tp_new */
3206 : PyObject_GC_Del, /* tp_free */
3207 : };
3208 :
3209 :
3210 : /* permutations object ********************************************************
3211 :
3212 : def permutations(iterable, r=None):
3213 : # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
3214 : # permutations(range(3)) --> 012 021 102 120 201 210
3215 : pool = tuple(iterable)
3216 : n = len(pool)
3217 : r = n if r is None else r
3218 : if r > n:
3219 : return
3220 : indices = list(range(n))
3221 : cycles = list(range(n, n-r, -1))
3222 : yield tuple(pool[i] for i in indices[:r])
3223 : while n:
3224 : for i in reversed(range(r)):
3225 : cycles[i] -= 1
3226 : if cycles[i] == 0:
3227 : indices[i:] = indices[i+1:] + indices[i:i+1]
3228 : cycles[i] = n - i
3229 : else:
3230 : j = cycles[i]
3231 : indices[i], indices[-j] = indices[-j], indices[i]
3232 : yield tuple(pool[i] for i in indices[:r])
3233 : break
3234 : else:
3235 : return
3236 : */
3237 :
3238 : typedef struct {
3239 : PyObject_HEAD
3240 : PyObject *pool; /* input converted to a tuple */
3241 : Py_ssize_t *indices; /* one index per element in the pool */
3242 : Py_ssize_t *cycles; /* one rollover counter per element in the result */
3243 : PyObject *result; /* most recently returned result tuple */
3244 : Py_ssize_t r; /* size of result tuple */
3245 : int stopped; /* set to 1 when the iterator is exhausted */
3246 : } permutationsobject;
3247 :
3248 : /*[clinic input]
3249 : @classmethod
3250 : itertools.permutations.__new__
3251 : iterable: object
3252 : r as robj: object = None
3253 : Return successive r-length permutations of elements in the iterable.
3254 :
3255 : permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)
3256 : [clinic start generated code]*/
3257 :
3258 : static PyObject *
3259 28303 : itertools_permutations_impl(PyTypeObject *type, PyObject *iterable,
3260 : PyObject *robj)
3261 : /*[clinic end generated code: output=296a72fa76d620ea input=57d0170a4ac0ec7a]*/
3262 : {
3263 : permutationsobject *po;
3264 : Py_ssize_t n;
3265 : Py_ssize_t r;
3266 28303 : PyObject *pool = NULL;
3267 28303 : Py_ssize_t *indices = NULL;
3268 28303 : Py_ssize_t *cycles = NULL;
3269 : Py_ssize_t i;
3270 :
3271 28303 : pool = PySequence_Tuple(iterable);
3272 28303 : if (pool == NULL)
3273 1 : goto error;
3274 28302 : n = PyTuple_GET_SIZE(pool);
3275 :
3276 28302 : r = n;
3277 28302 : if (robj != Py_None) {
3278 973 : if (!PyLong_Check(robj)) {
3279 1 : PyErr_SetString(PyExc_TypeError, "Expected int as r");
3280 1 : goto error;
3281 : }
3282 972 : r = PyLong_AsSsize_t(robj);
3283 972 : if (r == -1 && PyErr_Occurred())
3284 0 : goto error;
3285 : }
3286 28301 : if (r < 0) {
3287 1 : PyErr_SetString(PyExc_ValueError, "r must be non-negative");
3288 1 : goto error;
3289 : }
3290 :
3291 28300 : indices = PyMem_New(Py_ssize_t, n);
3292 28300 : cycles = PyMem_New(Py_ssize_t, r);
3293 28300 : if (indices == NULL || cycles == NULL) {
3294 0 : PyErr_NoMemory();
3295 0 : goto error;
3296 : }
3297 :
3298 68414 : for (i=0 ; i<n ; i++)
3299 40114 : indices[i] = i;
3300 67196 : for (i=0 ; i<r ; i++)
3301 38896 : cycles[i] = n - i;
3302 :
3303 : /* create permutationsobject structure */
3304 28300 : po = (permutationsobject *)type->tp_alloc(type, 0);
3305 28300 : if (po == NULL)
3306 0 : goto error;
3307 :
3308 28300 : po->pool = pool;
3309 28300 : po->indices = indices;
3310 28300 : po->cycles = cycles;
3311 28300 : po->result = NULL;
3312 28300 : po->r = r;
3313 28300 : po->stopped = r > n ? 1 : 0;
3314 :
3315 28300 : return (PyObject *)po;
3316 :
3317 3 : error:
3318 3 : if (indices != NULL)
3319 0 : PyMem_Free(indices);
3320 3 : if (cycles != NULL)
3321 0 : PyMem_Free(cycles);
3322 3 : Py_XDECREF(pool);
3323 3 : return NULL;
3324 : }
3325 :
3326 : static void
3327 28300 : permutations_dealloc(permutationsobject *po)
3328 : {
3329 28300 : PyObject_GC_UnTrack(po);
3330 28300 : Py_XDECREF(po->pool);
3331 28300 : Py_XDECREF(po->result);
3332 28300 : PyMem_Free(po->indices);
3333 28300 : PyMem_Free(po->cycles);
3334 28300 : Py_TYPE(po)->tp_free(po);
3335 28300 : }
3336 :
3337 : static PyObject *
3338 4 : permutations_sizeof(permutationsobject *po, void *unused)
3339 : {
3340 : Py_ssize_t res;
3341 :
3342 4 : res = _PyObject_SIZE(Py_TYPE(po));
3343 4 : res += PyTuple_GET_SIZE(po->pool) * sizeof(Py_ssize_t);
3344 4 : res += po->r * sizeof(Py_ssize_t);
3345 4 : return PyLong_FromSsize_t(res);
3346 : }
3347 :
3348 : static int
3349 18 : permutations_traverse(permutationsobject *po, visitproc visit, void *arg)
3350 : {
3351 18 : Py_VISIT(po->pool);
3352 18 : Py_VISIT(po->result);
3353 18 : return 0;
3354 : }
3355 :
3356 : static PyObject *
3357 73642 : permutations_next(permutationsobject *po)
3358 : {
3359 : PyObject *elem;
3360 : PyObject *oldelem;
3361 73642 : PyObject *pool = po->pool;
3362 73642 : Py_ssize_t *indices = po->indices;
3363 73642 : Py_ssize_t *cycles = po->cycles;
3364 73642 : PyObject *result = po->result;
3365 73642 : Py_ssize_t n = PyTuple_GET_SIZE(pool);
3366 73642 : Py_ssize_t r = po->r;
3367 : Py_ssize_t i, j, k, index;
3368 :
3369 73642 : if (po->stopped)
3370 252 : return NULL;
3371 :
3372 73390 : if (result == NULL) {
3373 : /* On the first pass, initialize result tuple using the indices */
3374 27918 : result = PyTuple_New(r);
3375 27918 : if (result == NULL)
3376 0 : goto empty;
3377 27918 : po->result = result;
3378 65571 : for (i=0; i<r ; i++) {
3379 37653 : index = indices[i];
3380 37653 : elem = PyTuple_GET_ITEM(pool, index);
3381 37653 : Py_INCREF(elem);
3382 37653 : PyTuple_SET_ITEM(result, i, elem);
3383 : }
3384 : } else {
3385 45472 : if (n == 0)
3386 29 : goto empty;
3387 :
3388 : /* Copy the previous result tuple or re-use it if available */
3389 45443 : if (Py_REFCNT(result) > 1) {
3390 45130 : PyObject *old_result = result;
3391 45130 : result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r);
3392 45130 : if (result == NULL)
3393 0 : goto empty;
3394 45130 : po->result = result;
3395 45130 : Py_DECREF(old_result);
3396 : }
3397 : // bpo-42536: The GC may have untracked this result tuple. Since we're
3398 : // recycling it, make sure it's tracked again:
3399 313 : else if (!_PyObject_GC_IS_TRACKED(result)) {
3400 1 : _PyObject_GC_TRACK(result);
3401 : }
3402 : /* Now, we've got the only copy so we can update it in-place */
3403 45443 : assert(r == 0 || Py_REFCNT(result) == 1);
3404 :
3405 : /* Decrement rightmost cycle, moving leftward upon zero rollover */
3406 100399 : for (i=r-1 ; i>=0 ; i--) {
3407 72740 : cycles[i] -= 1;
3408 72740 : if (cycles[i] == 0) {
3409 : /* rotatation: indices[i:] = indices[i+1:] + indices[i:i+1] */
3410 54956 : index = indices[i];
3411 71863 : for (j=i ; j<n-1 ; j++)
3412 16907 : indices[j] = indices[j+1];
3413 54956 : indices[n-1] = index;
3414 54956 : cycles[i] = n - i;
3415 : } else {
3416 17784 : j = cycles[i];
3417 17784 : index = indices[i];
3418 17784 : indices[i] = indices[n-j];
3419 17784 : indices[n-j] = index;
3420 :
3421 53751 : for (k=i; k<r ; k++) {
3422 : /* start with i, the leftmost element that changed */
3423 : /* yield tuple(pool[k] for k in indices[:r]) */
3424 35967 : index = indices[k];
3425 35967 : elem = PyTuple_GET_ITEM(pool, index);
3426 35967 : Py_INCREF(elem);
3427 35967 : oldelem = PyTuple_GET_ITEM(result, k);
3428 35967 : PyTuple_SET_ITEM(result, k, elem);
3429 35967 : Py_DECREF(oldelem);
3430 : }
3431 17784 : break;
3432 : }
3433 : }
3434 : /* If i is negative, then the cycles have all
3435 : rolled-over and we're done. */
3436 45443 : if (i < 0)
3437 27659 : goto empty;
3438 : }
3439 45702 : Py_INCREF(result);
3440 45702 : return result;
3441 :
3442 27688 : empty:
3443 27688 : po->stopped = 1;
3444 27688 : return NULL;
3445 : }
3446 :
3447 : static PyObject *
3448 420 : permutations_reduce(permutationsobject *po, PyObject *Py_UNUSED(ignored))
3449 : {
3450 420 : if (po->result == NULL) {
3451 252 : return Py_BuildValue("O(On)", Py_TYPE(po), po->pool, po->r);
3452 168 : } else if (po->stopped) {
3453 0 : return Py_BuildValue("O(()n)", Py_TYPE(po), po->r);
3454 : } else {
3455 168 : PyObject *indices=NULL, *cycles=NULL;
3456 : Py_ssize_t n, i;
3457 :
3458 : /* we must pickle the indices and cycles and use them for setstate */
3459 168 : n = PyTuple_GET_SIZE(po->pool);
3460 168 : indices = PyTuple_New(n);
3461 168 : if (indices == NULL)
3462 0 : goto err;
3463 840 : for (i=0; i<n; i++) {
3464 672 : PyObject* index = PyLong_FromSsize_t(po->indices[i]);
3465 672 : if (!index)
3466 0 : goto err;
3467 672 : PyTuple_SET_ITEM(indices, i, index);
3468 : }
3469 :
3470 168 : cycles = PyTuple_New(po->r);
3471 168 : if (cycles == NULL)
3472 0 : goto err;
3473 504 : for (i=0 ; i<po->r ; i++) {
3474 336 : PyObject* index = PyLong_FromSsize_t(po->cycles[i]);
3475 336 : if (!index)
3476 0 : goto err;
3477 336 : PyTuple_SET_ITEM(cycles, i, index);
3478 : }
3479 168 : return Py_BuildValue("O(On)(NN)", Py_TYPE(po),
3480 : po->pool, po->r,
3481 : indices, cycles);
3482 0 : err:
3483 0 : Py_XDECREF(indices);
3484 0 : Py_XDECREF(cycles);
3485 0 : return NULL;
3486 : }
3487 : }
3488 :
3489 : static PyObject *
3490 168 : permutations_setstate(permutationsobject *po, PyObject *state)
3491 : {
3492 : PyObject *indices, *cycles, *result;
3493 : Py_ssize_t n, i;
3494 :
3495 168 : if (!PyTuple_Check(state)) {
3496 0 : PyErr_SetString(PyExc_TypeError, "state is not a tuple");
3497 0 : return NULL;
3498 : }
3499 168 : if (!PyArg_ParseTuple(state, "O!O!",
3500 : &PyTuple_Type, &indices,
3501 : &PyTuple_Type, &cycles)) {
3502 0 : return NULL;
3503 : }
3504 :
3505 168 : n = PyTuple_GET_SIZE(po->pool);
3506 168 : if (PyTuple_GET_SIZE(indices) != n || PyTuple_GET_SIZE(cycles) != po->r) {
3507 0 : PyErr_SetString(PyExc_ValueError, "invalid arguments");
3508 0 : return NULL;
3509 : }
3510 :
3511 840 : for (i=0; i<n; i++) {
3512 672 : PyObject* indexObject = PyTuple_GET_ITEM(indices, i);
3513 672 : Py_ssize_t index = PyLong_AsSsize_t(indexObject);
3514 672 : if (index < 0 && PyErr_Occurred())
3515 0 : return NULL; /* not an integer */
3516 : /* clamp the index */
3517 672 : if (index < 0)
3518 0 : index = 0;
3519 672 : else if (index > n-1)
3520 0 : index = n-1;
3521 672 : po->indices[i] = index;
3522 : }
3523 :
3524 504 : for (i=0; i<po->r; i++) {
3525 336 : PyObject* indexObject = PyTuple_GET_ITEM(cycles, i);
3526 336 : Py_ssize_t index = PyLong_AsSsize_t(indexObject);
3527 336 : if (index < 0 && PyErr_Occurred())
3528 0 : return NULL; /* not an integer */
3529 336 : if (index < 1)
3530 0 : index = 1;
3531 336 : else if (index > n-i)
3532 0 : index = n-i;
3533 336 : po->cycles[i] = index;
3534 : }
3535 168 : result = PyTuple_New(po->r);
3536 168 : if (result == NULL)
3537 0 : return NULL;
3538 504 : for (i=0; i<po->r; i++) {
3539 336 : PyObject *element = PyTuple_GET_ITEM(po->pool, po->indices[i]);
3540 336 : Py_INCREF(element);
3541 336 : PyTuple_SET_ITEM(result, i, element);
3542 : }
3543 168 : Py_XSETREF(po->result, result);
3544 168 : Py_RETURN_NONE;
3545 : }
3546 :
3547 : static PyMethodDef permuations_methods[] = {
3548 : {"__reduce__", (PyCFunction)permutations_reduce, METH_NOARGS,
3549 : reduce_doc},
3550 : {"__setstate__", (PyCFunction)permutations_setstate, METH_O,
3551 : setstate_doc},
3552 : {"__sizeof__", (PyCFunction)permutations_sizeof, METH_NOARGS,
3553 : sizeof_doc},
3554 : {NULL, NULL} /* sentinel */
3555 : };
3556 :
3557 : static PyTypeObject permutations_type = {
3558 : PyVarObject_HEAD_INIT(NULL, 0)
3559 : "itertools.permutations", /* tp_name */
3560 : sizeof(permutationsobject), /* tp_basicsize */
3561 : 0, /* tp_itemsize */
3562 : /* methods */
3563 : (destructor)permutations_dealloc, /* tp_dealloc */
3564 : 0, /* tp_vectorcall_offset */
3565 : 0, /* tp_getattr */
3566 : 0, /* tp_setattr */
3567 : 0, /* tp_as_async */
3568 : 0, /* tp_repr */
3569 : 0, /* tp_as_number */
3570 : 0, /* tp_as_sequence */
3571 : 0, /* tp_as_mapping */
3572 : 0, /* tp_hash */
3573 : 0, /* tp_call */
3574 : 0, /* tp_str */
3575 : PyObject_GenericGetAttr, /* tp_getattro */
3576 : 0, /* tp_setattro */
3577 : 0, /* tp_as_buffer */
3578 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
3579 : Py_TPFLAGS_BASETYPE, /* tp_flags */
3580 : itertools_permutations__doc__, /* tp_doc */
3581 : (traverseproc)permutations_traverse,/* tp_traverse */
3582 : 0, /* tp_clear */
3583 : 0, /* tp_richcompare */
3584 : 0, /* tp_weaklistoffset */
3585 : PyObject_SelfIter, /* tp_iter */
3586 : (iternextfunc)permutations_next, /* tp_iternext */
3587 : permuations_methods, /* tp_methods */
3588 : 0, /* tp_members */
3589 : 0, /* tp_getset */
3590 : 0, /* tp_base */
3591 : 0, /* tp_dict */
3592 : 0, /* tp_descr_get */
3593 : 0, /* tp_descr_set */
3594 : 0, /* tp_dictoffset */
3595 : 0, /* tp_init */
3596 : 0, /* tp_alloc */
3597 : itertools_permutations, /* tp_new */
3598 : PyObject_GC_Del, /* tp_free */
3599 : };
3600 :
3601 :
3602 : /* accumulate object ********************************************************/
3603 :
3604 : typedef struct {
3605 : PyObject_HEAD
3606 : PyObject *total;
3607 : PyObject *it;
3608 : PyObject *binop;
3609 : PyObject *initial;
3610 : } accumulateobject;
3611 :
3612 : /*[clinic input]
3613 : @classmethod
3614 : itertools.accumulate.__new__
3615 : iterable: object
3616 : func as binop: object = None
3617 : *
3618 : initial: object = None
3619 : Return series of accumulated sums (or other binary function results).
3620 : [clinic start generated code]*/
3621 :
3622 : static PyObject *
3623 182 : itertools_accumulate_impl(PyTypeObject *type, PyObject *iterable,
3624 : PyObject *binop, PyObject *initial)
3625 : /*[clinic end generated code: output=66da2650627128f8 input=c4ce20ac59bf7ffd]*/
3626 : {
3627 : PyObject *it;
3628 : accumulateobject *lz;
3629 :
3630 : /* Get iterator. */
3631 182 : it = PyObject_GetIter(iterable);
3632 182 : if (it == NULL)
3633 6 : return NULL;
3634 :
3635 : /* create accumulateobject structure */
3636 176 : lz = (accumulateobject *)type->tp_alloc(type, 0);
3637 176 : if (lz == NULL) {
3638 0 : Py_DECREF(it);
3639 0 : return NULL;
3640 : }
3641 :
3642 176 : if (binop != Py_None) {
3643 21 : Py_XINCREF(binop);
3644 21 : lz->binop = binop;
3645 : }
3646 176 : lz->total = NULL;
3647 176 : lz->it = it;
3648 176 : Py_XINCREF(initial);
3649 176 : lz->initial = initial;
3650 176 : return (PyObject *)lz;
3651 : }
3652 :
3653 : static void
3654 176 : accumulate_dealloc(accumulateobject *lz)
3655 : {
3656 176 : PyObject_GC_UnTrack(lz);
3657 176 : Py_XDECREF(lz->binop);
3658 176 : Py_XDECREF(lz->total);
3659 176 : Py_XDECREF(lz->it);
3660 176 : Py_XDECREF(lz->initial);
3661 176 : Py_TYPE(lz)->tp_free(lz);
3662 176 : }
3663 :
3664 : static int
3665 2 : accumulate_traverse(accumulateobject *lz, visitproc visit, void *arg)
3666 : {
3667 2 : Py_VISIT(lz->binop);
3668 2 : Py_VISIT(lz->it);
3669 2 : Py_VISIT(lz->total);
3670 2 : Py_VISIT(lz->initial);
3671 2 : return 0;
3672 : }
3673 :
3674 : static PyObject *
3675 105483 : accumulate_next(accumulateobject *lz)
3676 : {
3677 : PyObject *val, *newtotal;
3678 :
3679 105483 : if (lz->initial != Py_None) {
3680 8 : lz->total = lz->initial;
3681 8 : Py_INCREF(Py_None);
3682 8 : lz->initial = Py_None;
3683 8 : Py_INCREF(lz->total);
3684 8 : return lz->total;
3685 : }
3686 105475 : val = (*Py_TYPE(lz->it)->tp_iternext)(lz->it);
3687 105475 : if (val == NULL)
3688 107 : return NULL;
3689 :
3690 105368 : if (lz->total == NULL) {
3691 136 : Py_INCREF(val);
3692 136 : lz->total = val;
3693 136 : return lz->total;
3694 : }
3695 :
3696 105232 : if (lz->binop == NULL)
3697 105187 : newtotal = PyNumber_Add(lz->total, val);
3698 : else
3699 45 : newtotal = PyObject_CallFunctionObjArgs(lz->binop, lz->total, val, NULL);
3700 105232 : Py_DECREF(val);
3701 105232 : if (newtotal == NULL)
3702 5 : return NULL;
3703 :
3704 105227 : Py_INCREF(newtotal);
3705 105227 : Py_SETREF(lz->total, newtotal);
3706 105227 : return newtotal;
3707 : }
3708 :
3709 : static PyObject *
3710 53 : accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored))
3711 : {
3712 53 : if (lz->initial != Py_None) {
3713 : PyObject *it;
3714 :
3715 6 : assert(lz->total == NULL);
3716 6 : if (PyType_Ready(&chain_type) < 0)
3717 0 : return NULL;
3718 6 : it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O",
3719 : lz->initial, lz->it);
3720 6 : if (it == NULL)
3721 0 : return NULL;
3722 6 : return Py_BuildValue("O(NO)O", Py_TYPE(lz),
3723 6 : it, lz->binop?lz->binop:Py_None, Py_None);
3724 : }
3725 47 : if (lz->total == Py_None) {
3726 : PyObject *it;
3727 :
3728 8 : if (PyType_Ready(&chain_type) < 0)
3729 0 : return NULL;
3730 8 : if (PyType_Ready(&islice_type) < 0)
3731 0 : return NULL;
3732 8 : it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O",
3733 : lz->total, lz->it);
3734 8 : if (it == NULL)
3735 0 : return NULL;
3736 8 : it = PyObject_CallFunction((PyObject *)Py_TYPE(lz), "NO",
3737 8 : it, lz->binop ? lz->binop : Py_None);
3738 8 : if (it == NULL)
3739 0 : return NULL;
3740 8 : return Py_BuildValue("O(NiO)", &islice_type, it, 1, Py_None);
3741 : }
3742 78 : return Py_BuildValue("O(OO)O", Py_TYPE(lz),
3743 39 : lz->it, lz->binop?lz->binop:Py_None,
3744 39 : lz->total?lz->total:Py_None);
3745 : }
3746 :
3747 : static PyObject *
3748 20 : accumulate_setstate(accumulateobject *lz, PyObject *state)
3749 : {
3750 20 : Py_INCREF(state);
3751 20 : Py_XSETREF(lz->total, state);
3752 20 : Py_RETURN_NONE;
3753 : }
3754 :
3755 : static PyMethodDef accumulate_methods[] = {
3756 : {"__reduce__", (PyCFunction)accumulate_reduce, METH_NOARGS,
3757 : reduce_doc},
3758 : {"__setstate__", (PyCFunction)accumulate_setstate, METH_O,
3759 : setstate_doc},
3760 : {NULL, NULL} /* sentinel */
3761 : };
3762 :
3763 : static PyTypeObject accumulate_type = {
3764 : PyVarObject_HEAD_INIT(NULL, 0)
3765 : "itertools.accumulate", /* tp_name */
3766 : sizeof(accumulateobject), /* tp_basicsize */
3767 : 0, /* tp_itemsize */
3768 : /* methods */
3769 : (destructor)accumulate_dealloc, /* tp_dealloc */
3770 : 0, /* tp_vectorcall_offset */
3771 : 0, /* tp_getattr */
3772 : 0, /* tp_setattr */
3773 : 0, /* tp_as_async */
3774 : 0, /* tp_repr */
3775 : 0, /* tp_as_number */
3776 : 0, /* tp_as_sequence */
3777 : 0, /* tp_as_mapping */
3778 : 0, /* tp_hash */
3779 : 0, /* tp_call */
3780 : 0, /* tp_str */
3781 : PyObject_GenericGetAttr, /* tp_getattro */
3782 : 0, /* tp_setattro */
3783 : 0, /* tp_as_buffer */
3784 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
3785 : Py_TPFLAGS_BASETYPE, /* tp_flags */
3786 : itertools_accumulate__doc__, /* tp_doc */
3787 : (traverseproc)accumulate_traverse, /* tp_traverse */
3788 : 0, /* tp_clear */
3789 : 0, /* tp_richcompare */
3790 : 0, /* tp_weaklistoffset */
3791 : PyObject_SelfIter, /* tp_iter */
3792 : (iternextfunc)accumulate_next, /* tp_iternext */
3793 : accumulate_methods, /* tp_methods */
3794 : 0, /* tp_members */
3795 : 0, /* tp_getset */
3796 : 0, /* tp_base */
3797 : 0, /* tp_dict */
3798 : 0, /* tp_descr_get */
3799 : 0, /* tp_descr_set */
3800 : 0, /* tp_dictoffset */
3801 : 0, /* tp_init */
3802 : 0, /* tp_alloc */
3803 : itertools_accumulate, /* tp_new */
3804 : PyObject_GC_Del, /* tp_free */
3805 : };
3806 :
3807 :
3808 : /* compress object ************************************************************/
3809 :
3810 : /* Equivalent to:
3811 :
3812 : def compress(data, selectors):
3813 : "compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F"
3814 : return (d for d, s in zip(data, selectors) if s)
3815 : */
3816 :
3817 : typedef struct {
3818 : PyObject_HEAD
3819 : PyObject *data;
3820 : PyObject *selectors;
3821 : } compressobject;
3822 :
3823 : /*[clinic input]
3824 : @classmethod
3825 : itertools.compress.__new__
3826 : data as seq1: object
3827 : selectors as seq2: object
3828 : Return data elements corresponding to true selector elements.
3829 :
3830 : Forms a shorter iterator from selected data elements using the selectors to
3831 : choose the data elements.
3832 : [clinic start generated code]*/
3833 :
3834 : static PyObject *
3835 291 : itertools_compress_impl(PyTypeObject *type, PyObject *seq1, PyObject *seq2)
3836 : /*[clinic end generated code: output=7e67157212ed09e0 input=79596d7cd20c77e5]*/
3837 : {
3838 291 : PyObject *data=NULL, *selectors=NULL;
3839 : compressobject *lz;
3840 :
3841 291 : data = PyObject_GetIter(seq1);
3842 291 : if (data == NULL)
3843 11 : goto fail;
3844 280 : selectors = PyObject_GetIter(seq2);
3845 280 : if (selectors == NULL)
3846 2 : goto fail;
3847 :
3848 : /* create compressobject structure */
3849 278 : lz = (compressobject *)type->tp_alloc(type, 0);
3850 278 : if (lz == NULL)
3851 0 : goto fail;
3852 278 : lz->data = data;
3853 278 : lz->selectors = selectors;
3854 278 : return (PyObject *)lz;
3855 :
3856 13 : fail:
3857 13 : Py_XDECREF(data);
3858 13 : Py_XDECREF(selectors);
3859 13 : return NULL;
3860 : }
3861 :
3862 : static void
3863 278 : compress_dealloc(compressobject *lz)
3864 : {
3865 278 : PyObject_GC_UnTrack(lz);
3866 278 : Py_XDECREF(lz->data);
3867 278 : Py_XDECREF(lz->selectors);
3868 278 : Py_TYPE(lz)->tp_free(lz);
3869 278 : }
3870 :
3871 : static int
3872 2 : compress_traverse(compressobject *lz, visitproc visit, void *arg)
3873 : {
3874 2 : Py_VISIT(lz->data);
3875 2 : Py_VISIT(lz->selectors);
3876 2 : return 0;
3877 : }
3878 :
3879 : static PyObject *
3880 35745 : compress_next(compressobject *lz)
3881 : {
3882 35745 : PyObject *data = lz->data, *selectors = lz->selectors;
3883 : PyObject *datum, *selector;
3884 35745 : PyObject *(*datanext)(PyObject *) = *Py_TYPE(data)->tp_iternext;
3885 35745 : PyObject *(*selectornext)(PyObject *) = *Py_TYPE(selectors)->tp_iternext;
3886 : int ok;
3887 :
3888 : while (1) {
3889 : /* Steps: get datum, get selector, evaluate selector.
3890 : Order is important (to match the pure python version
3891 : in terms of which input gets a chance to raise an
3892 : exception first).
3893 : */
3894 :
3895 65953 : datum = datanext(data);
3896 65953 : if (datum == NULL)
3897 132 : return NULL;
3898 :
3899 65821 : selector = selectornext(selectors);
3900 65821 : if (selector == NULL) {
3901 25 : Py_DECREF(datum);
3902 25 : return NULL;
3903 : }
3904 :
3905 65796 : ok = PyObject_IsTrue(selector);
3906 65796 : Py_DECREF(selector);
3907 65796 : if (ok > 0)
3908 35588 : return datum;
3909 30208 : Py_DECREF(datum);
3910 30208 : if (ok < 0)
3911 0 : return NULL;
3912 : }
3913 : }
3914 :
3915 : static PyObject *
3916 112 : compress_reduce(compressobject *lz, PyObject *Py_UNUSED(ignored))
3917 : {
3918 112 : return Py_BuildValue("O(OO)", Py_TYPE(lz),
3919 : lz->data, lz->selectors);
3920 : }
3921 :
3922 : static PyMethodDef compress_methods[] = {
3923 : {"__reduce__", (PyCFunction)compress_reduce, METH_NOARGS,
3924 : reduce_doc},
3925 : {NULL, NULL} /* sentinel */
3926 : };
3927 :
3928 : static PyTypeObject compress_type = {
3929 : PyVarObject_HEAD_INIT(NULL, 0)
3930 : "itertools.compress", /* tp_name */
3931 : sizeof(compressobject), /* tp_basicsize */
3932 : 0, /* tp_itemsize */
3933 : /* methods */
3934 : (destructor)compress_dealloc, /* tp_dealloc */
3935 : 0, /* tp_vectorcall_offset */
3936 : 0, /* tp_getattr */
3937 : 0, /* tp_setattr */
3938 : 0, /* tp_as_async */
3939 : 0, /* tp_repr */
3940 : 0, /* tp_as_number */
3941 : 0, /* tp_as_sequence */
3942 : 0, /* tp_as_mapping */
3943 : 0, /* tp_hash */
3944 : 0, /* tp_call */
3945 : 0, /* tp_str */
3946 : PyObject_GenericGetAttr, /* tp_getattro */
3947 : 0, /* tp_setattro */
3948 : 0, /* tp_as_buffer */
3949 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
3950 : Py_TPFLAGS_BASETYPE, /* tp_flags */
3951 : itertools_compress__doc__, /* tp_doc */
3952 : (traverseproc)compress_traverse, /* tp_traverse */
3953 : 0, /* tp_clear */
3954 : 0, /* tp_richcompare */
3955 : 0, /* tp_weaklistoffset */
3956 : PyObject_SelfIter, /* tp_iter */
3957 : (iternextfunc)compress_next, /* tp_iternext */
3958 : compress_methods, /* tp_methods */
3959 : 0, /* tp_members */
3960 : 0, /* tp_getset */
3961 : 0, /* tp_base */
3962 : 0, /* tp_dict */
3963 : 0, /* tp_descr_get */
3964 : 0, /* tp_descr_set */
3965 : 0, /* tp_dictoffset */
3966 : 0, /* tp_init */
3967 : 0, /* tp_alloc */
3968 : itertools_compress, /* tp_new */
3969 : PyObject_GC_Del, /* tp_free */
3970 : };
3971 :
3972 :
3973 : /* filterfalse object ************************************************************/
3974 :
3975 : typedef struct {
3976 : PyObject_HEAD
3977 : PyObject *func;
3978 : PyObject *it;
3979 : } filterfalseobject;
3980 :
3981 : /*[clinic input]
3982 : @classmethod
3983 : itertools.filterfalse.__new__
3984 : function as func: object
3985 : iterable as seq: object
3986 : /
3987 : Return those items of iterable for which function(item) is false.
3988 :
3989 : If function is None, return the items that are false.
3990 : [clinic start generated code]*/
3991 :
3992 : static PyObject *
3993 403 : itertools_filterfalse_impl(PyTypeObject *type, PyObject *func, PyObject *seq)
3994 : /*[clinic end generated code: output=55f87eab9fc0484e input=2d684a2c66f99cde]*/
3995 : {
3996 : PyObject *it;
3997 : filterfalseobject *lz;
3998 :
3999 : /* Get iterator. */
4000 403 : it = PyObject_GetIter(seq);
4001 403 : if (it == NULL)
4002 11 : return NULL;
4003 :
4004 : /* create filterfalseobject structure */
4005 392 : lz = (filterfalseobject *)type->tp_alloc(type, 0);
4006 392 : if (lz == NULL) {
4007 0 : Py_DECREF(it);
4008 0 : return NULL;
4009 : }
4010 392 : Py_INCREF(func);
4011 392 : lz->func = func;
4012 392 : lz->it = it;
4013 :
4014 392 : return (PyObject *)lz;
4015 : }
4016 :
4017 : static void
4018 392 : filterfalse_dealloc(filterfalseobject *lz)
4019 : {
4020 392 : PyObject_GC_UnTrack(lz);
4021 392 : Py_XDECREF(lz->func);
4022 392 : Py_XDECREF(lz->it);
4023 392 : Py_TYPE(lz)->tp_free(lz);
4024 392 : }
4025 :
4026 : static int
4027 174 : filterfalse_traverse(filterfalseobject *lz, visitproc visit, void *arg)
4028 : {
4029 174 : Py_VISIT(lz->it);
4030 174 : Py_VISIT(lz->func);
4031 174 : return 0;
4032 : }
4033 :
4034 : static PyObject *
4035 305213 : filterfalse_next(filterfalseobject *lz)
4036 : {
4037 : PyObject *item;
4038 305213 : PyObject *it = lz->it;
4039 : long ok;
4040 : PyObject *(*iternext)(PyObject *);
4041 :
4042 305213 : iternext = *Py_TYPE(it)->tp_iternext;
4043 : for (;;) {
4044 308576 : item = iternext(it);
4045 308576 : if (item == NULL)
4046 405 : return NULL;
4047 :
4048 308171 : if (lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type) {
4049 16 : ok = PyObject_IsTrue(item);
4050 : } else {
4051 : PyObject *good;
4052 308155 : good = PyObject_CallOneArg(lz->func, item);
4053 308155 : if (good == NULL) {
4054 1 : Py_DECREF(item);
4055 1 : return NULL;
4056 : }
4057 308154 : ok = PyObject_IsTrue(good);
4058 308154 : Py_DECREF(good);
4059 : }
4060 308170 : if (ok == 0)
4061 304807 : return item;
4062 3363 : Py_DECREF(item);
4063 3363 : if (ok < 0)
4064 0 : return NULL;
4065 : }
4066 : }
4067 :
4068 : static PyObject *
4069 12 : filterfalse_reduce(filterfalseobject *lz, PyObject *Py_UNUSED(ignored))
4070 : {
4071 12 : return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it);
4072 : }
4073 :
4074 : static PyMethodDef filterfalse_methods[] = {
4075 : {"__reduce__", (PyCFunction)filterfalse_reduce, METH_NOARGS,
4076 : reduce_doc},
4077 : {NULL, NULL} /* sentinel */
4078 : };
4079 :
4080 : static PyTypeObject filterfalse_type = {
4081 : PyVarObject_HEAD_INIT(NULL, 0)
4082 : "itertools.filterfalse", /* tp_name */
4083 : sizeof(filterfalseobject), /* tp_basicsize */
4084 : 0, /* tp_itemsize */
4085 : /* methods */
4086 : (destructor)filterfalse_dealloc, /* tp_dealloc */
4087 : 0, /* tp_vectorcall_offset */
4088 : 0, /* tp_getattr */
4089 : 0, /* tp_setattr */
4090 : 0, /* tp_as_async */
4091 : 0, /* tp_repr */
4092 : 0, /* tp_as_number */
4093 : 0, /* tp_as_sequence */
4094 : 0, /* tp_as_mapping */
4095 : 0, /* tp_hash */
4096 : 0, /* tp_call */
4097 : 0, /* tp_str */
4098 : PyObject_GenericGetAttr, /* tp_getattro */
4099 : 0, /* tp_setattro */
4100 : 0, /* tp_as_buffer */
4101 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
4102 : Py_TPFLAGS_BASETYPE, /* tp_flags */
4103 : itertools_filterfalse__doc__, /* tp_doc */
4104 : (traverseproc)filterfalse_traverse, /* tp_traverse */
4105 : 0, /* tp_clear */
4106 : 0, /* tp_richcompare */
4107 : 0, /* tp_weaklistoffset */
4108 : PyObject_SelfIter, /* tp_iter */
4109 : (iternextfunc)filterfalse_next, /* tp_iternext */
4110 : filterfalse_methods, /* tp_methods */
4111 : 0, /* tp_members */
4112 : 0, /* tp_getset */
4113 : 0, /* tp_base */
4114 : 0, /* tp_dict */
4115 : 0, /* tp_descr_get */
4116 : 0, /* tp_descr_set */
4117 : 0, /* tp_dictoffset */
4118 : 0, /* tp_init */
4119 : 0, /* tp_alloc */
4120 : itertools_filterfalse, /* tp_new */
4121 : PyObject_GC_Del, /* tp_free */
4122 : };
4123 :
4124 :
4125 : /* count object ************************************************************/
4126 :
4127 : typedef struct {
4128 : PyObject_HEAD
4129 : Py_ssize_t cnt;
4130 : PyObject *long_cnt;
4131 : PyObject *long_step;
4132 : } countobject;
4133 :
4134 : /* Counting logic and invariants:
4135 :
4136 : fast_mode: when cnt an integer < PY_SSIZE_T_MAX and no step is specified.
4137 :
4138 : assert(cnt != PY_SSIZE_T_MAX && long_cnt == NULL && long_step==PyLong(1));
4139 : Advances with: cnt += 1
4140 : When count hits Y_SSIZE_T_MAX, switch to slow_mode.
4141 :
4142 : slow_mode: when cnt == PY_SSIZE_T_MAX, step is not int(1), or cnt is a float.
4143 :
4144 : assert(cnt == PY_SSIZE_T_MAX && long_cnt != NULL && long_step != NULL);
4145 : All counting is done with python objects (no overflows or underflows).
4146 : Advances with: long_cnt += long_step
4147 : Step may be zero -- effectively a slow version of repeat(cnt).
4148 : Either long_cnt or long_step may be a float, Fraction, or Decimal.
4149 : */
4150 :
4151 : /*[clinic input]
4152 : @classmethod
4153 : itertools.count.__new__
4154 : start as long_cnt: object(c_default="NULL") = 0
4155 : step as long_step: object(c_default="NULL") = 1
4156 : Return a count object whose .__next__() method returns consecutive values.
4157 :
4158 : Equivalent to:
4159 : def count(firstval=0, step=1):
4160 : x = firstval
4161 : while 1:
4162 : yield x
4163 : x += step
4164 : [clinic start generated code]*/
4165 :
4166 : static PyObject *
4167 17322 : itertools_count_impl(PyTypeObject *type, PyObject *long_cnt,
4168 : PyObject *long_step)
4169 : /*[clinic end generated code: output=09a9250aebd00b1c input=d7a85eec18bfcd94]*/
4170 : {
4171 : countobject *lz;
4172 : int fast_mode;
4173 17322 : Py_ssize_t cnt = 0;
4174 : long step;
4175 :
4176 17322 : if ((long_cnt != NULL && !PyNumber_Check(long_cnt)) ||
4177 1737 : (long_step != NULL && !PyNumber_Check(long_step))) {
4178 2 : PyErr_SetString(PyExc_TypeError, "a number is required");
4179 2 : return NULL;
4180 : }
4181 :
4182 19052 : fast_mode = (long_cnt == NULL || PyLong_Check(long_cnt)) &&
4183 1732 : (long_step == NULL || PyLong_Check(long_step));
4184 :
4185 : /* If not specified, start defaults to 0 */
4186 17320 : if (long_cnt != NULL) {
4187 13221 : if (fast_mode) {
4188 13204 : assert(PyLong_Check(long_cnt));
4189 13204 : cnt = PyLong_AsSsize_t(long_cnt);
4190 13204 : if (cnt == -1 && PyErr_Occurred()) {
4191 530 : PyErr_Clear();
4192 530 : fast_mode = 0;
4193 : }
4194 : }
4195 : } else {
4196 4099 : cnt = 0;
4197 4099 : long_cnt = _PyLong_GetZero();
4198 : }
4199 17320 : Py_INCREF(long_cnt);
4200 :
4201 : /* If not specified, step defaults to 1 */
4202 17320 : if (long_step == NULL) {
4203 15583 : long_step = _PyLong_GetOne();
4204 : }
4205 17320 : Py_INCREF(long_step);
4206 :
4207 17320 : assert(long_cnt != NULL && long_step != NULL);
4208 :
4209 : /* Fast mode only works when the step is 1 */
4210 17320 : if (fast_mode) {
4211 16773 : assert(PyLong_Check(long_step));
4212 16773 : step = PyLong_AsLong(long_step);
4213 16773 : if (step != 1) {
4214 1164 : fast_mode = 0;
4215 1164 : if (step == -1 && PyErr_Occurred())
4216 267 : PyErr_Clear();
4217 : }
4218 : }
4219 :
4220 17320 : if (fast_mode)
4221 15609 : Py_CLEAR(long_cnt);
4222 : else
4223 1711 : cnt = PY_SSIZE_T_MAX;
4224 :
4225 17320 : assert((cnt != PY_SSIZE_T_MAX && long_cnt == NULL && fast_mode) ||
4226 : (cnt == PY_SSIZE_T_MAX && long_cnt != NULL && !fast_mode));
4227 17320 : assert(!fast_mode ||
4228 : (PyLong_Check(long_step) && PyLong_AS_LONG(long_step) == 1));
4229 :
4230 : /* create countobject structure */
4231 17320 : lz = (countobject *)type->tp_alloc(type, 0);
4232 17320 : if (lz == NULL) {
4233 0 : Py_XDECREF(long_cnt);
4234 0 : Py_DECREF(long_step);
4235 0 : return NULL;
4236 : }
4237 17320 : lz->cnt = cnt;
4238 17320 : lz->long_cnt = long_cnt;
4239 17320 : lz->long_step = long_step;
4240 :
4241 17320 : return (PyObject *)lz;
4242 : }
4243 :
4244 : static void
4245 17316 : count_dealloc(countobject *lz)
4246 : {
4247 17316 : PyObject_GC_UnTrack(lz);
4248 17316 : Py_XDECREF(lz->long_cnt);
4249 17316 : Py_XDECREF(lz->long_step);
4250 17316 : Py_TYPE(lz)->tp_free(lz);
4251 17316 : }
4252 :
4253 : static int
4254 169988 : count_traverse(countobject *lz, visitproc visit, void *arg)
4255 : {
4256 169988 : Py_VISIT(lz->long_cnt);
4257 169988 : Py_VISIT(lz->long_step);
4258 169988 : return 0;
4259 : }
4260 :
4261 : static PyObject *
4262 6948 : count_nextlong(countobject *lz)
4263 : {
4264 : PyObject *long_cnt;
4265 : PyObject *stepped_up;
4266 :
4267 6948 : long_cnt = lz->long_cnt;
4268 6948 : if (long_cnt == NULL) {
4269 : /* Switch to slow_mode */
4270 1 : long_cnt = PyLong_FromSsize_t(PY_SSIZE_T_MAX);
4271 1 : if (long_cnt == NULL)
4272 0 : return NULL;
4273 : }
4274 6948 : assert(lz->cnt == PY_SSIZE_T_MAX && long_cnt != NULL);
4275 :
4276 6948 : stepped_up = PyNumber_Add(long_cnt, lz->long_step);
4277 6948 : if (stepped_up == NULL)
4278 0 : return NULL;
4279 6948 : lz->long_cnt = stepped_up;
4280 6948 : return long_cnt;
4281 : }
4282 :
4283 : static PyObject *
4284 129205 : count_next(countobject *lz)
4285 : {
4286 129205 : if (lz->cnt == PY_SSIZE_T_MAX)
4287 6948 : return count_nextlong(lz);
4288 122257 : return PyLong_FromSsize_t(lz->cnt++);
4289 : }
4290 :
4291 : static PyObject *
4292 96 : count_repr(countobject *lz)
4293 : {
4294 96 : if (lz->cnt != PY_SSIZE_T_MAX)
4295 15 : return PyUnicode_FromFormat("%s(%zd)",
4296 : _PyType_Name(Py_TYPE(lz)), lz->cnt);
4297 :
4298 81 : if (PyLong_Check(lz->long_step)) {
4299 78 : long step = PyLong_AsLong(lz->long_step);
4300 78 : if (step == -1 && PyErr_Occurred()) {
4301 16 : PyErr_Clear();
4302 : }
4303 78 : if (step == 1) {
4304 : /* Don't display step when it is an integer equal to 1 */
4305 7 : return PyUnicode_FromFormat("%s(%R)",
4306 : _PyType_Name(Py_TYPE(lz)),
4307 : lz->long_cnt);
4308 : }
4309 : }
4310 74 : return PyUnicode_FromFormat("%s(%R, %R)",
4311 : _PyType_Name(Py_TYPE(lz)),
4312 : lz->long_cnt, lz->long_step);
4313 : }
4314 :
4315 : static PyObject *
4316 958 : count_reduce(countobject *lz, PyObject *Py_UNUSED(ignored))
4317 : {
4318 958 : if (lz->cnt == PY_SSIZE_T_MAX)
4319 806 : return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->long_cnt, lz->long_step);
4320 152 : return Py_BuildValue("O(n)", Py_TYPE(lz), lz->cnt);
4321 : }
4322 :
4323 : static PyMethodDef count_methods[] = {
4324 : {"__reduce__", (PyCFunction)count_reduce, METH_NOARGS,
4325 : reduce_doc},
4326 : {NULL, NULL} /* sentinel */
4327 : };
4328 :
4329 : static PyTypeObject count_type = {
4330 : PyVarObject_HEAD_INIT(NULL, 0)
4331 : "itertools.count", /* tp_name */
4332 : sizeof(countobject), /* tp_basicsize */
4333 : 0, /* tp_itemsize */
4334 : /* methods */
4335 : (destructor)count_dealloc, /* tp_dealloc */
4336 : 0, /* tp_vectorcall_offset */
4337 : 0, /* tp_getattr */
4338 : 0, /* tp_setattr */
4339 : 0, /* tp_as_async */
4340 : (reprfunc)count_repr, /* tp_repr */
4341 : 0, /* tp_as_number */
4342 : 0, /* tp_as_sequence */
4343 : 0, /* tp_as_mapping */
4344 : 0, /* tp_hash */
4345 : 0, /* tp_call */
4346 : 0, /* tp_str */
4347 : PyObject_GenericGetAttr, /* tp_getattro */
4348 : 0, /* tp_setattro */
4349 : 0, /* tp_as_buffer */
4350 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
4351 : Py_TPFLAGS_BASETYPE, /* tp_flags */
4352 : itertools_count__doc__, /* tp_doc */
4353 : (traverseproc)count_traverse, /* tp_traverse */
4354 : 0, /* tp_clear */
4355 : 0, /* tp_richcompare */
4356 : 0, /* tp_weaklistoffset */
4357 : PyObject_SelfIter, /* tp_iter */
4358 : (iternextfunc)count_next, /* tp_iternext */
4359 : count_methods, /* tp_methods */
4360 : 0, /* tp_members */
4361 : 0, /* tp_getset */
4362 : 0, /* tp_base */
4363 : 0, /* tp_dict */
4364 : 0, /* tp_descr_get */
4365 : 0, /* tp_descr_set */
4366 : 0, /* tp_dictoffset */
4367 : 0, /* tp_init */
4368 : 0, /* tp_alloc */
4369 : itertools_count, /* tp_new */
4370 : PyObject_GC_Del, /* tp_free */
4371 : };
4372 :
4373 :
4374 : /* repeat object ************************************************************/
4375 :
4376 : typedef struct {
4377 : PyObject_HEAD
4378 : PyObject *element;
4379 : Py_ssize_t cnt;
4380 : } repeatobject;
4381 :
4382 : static PyTypeObject repeat_type;
4383 :
4384 : static PyObject *
4385 46435 : repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
4386 : {
4387 : repeatobject *ro;
4388 : PyObject *element;
4389 46435 : Py_ssize_t cnt = -1, n_args;
4390 : static char *kwargs[] = {"object", "times", NULL};
4391 :
4392 46435 : n_args = PyTuple_GET_SIZE(args);
4393 46435 : if (kwds != NULL)
4394 16 : n_args += PyDict_GET_SIZE(kwds);
4395 46435 : if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:repeat", kwargs,
4396 : &element, &cnt))
4397 6 : return NULL;
4398 : /* Does user supply times argument? */
4399 46429 : if (n_args == 2 && cnt < 0)
4400 13 : cnt = 0;
4401 :
4402 46429 : ro = (repeatobject *)type->tp_alloc(type, 0);
4403 46429 : if (ro == NULL)
4404 0 : return NULL;
4405 46429 : Py_INCREF(element);
4406 46429 : ro->element = element;
4407 46429 : ro->cnt = cnt;
4408 46429 : return (PyObject *)ro;
4409 : }
4410 :
4411 : static void
4412 46429 : repeat_dealloc(repeatobject *ro)
4413 : {
4414 46429 : PyObject_GC_UnTrack(ro);
4415 46429 : Py_XDECREF(ro->element);
4416 46429 : Py_TYPE(ro)->tp_free(ro);
4417 46429 : }
4418 :
4419 : static int
4420 3336 : repeat_traverse(repeatobject *ro, visitproc visit, void *arg)
4421 : {
4422 3336 : Py_VISIT(ro->element);
4423 3336 : return 0;
4424 : }
4425 :
4426 : static PyObject *
4427 28291500 : repeat_next(repeatobject *ro)
4428 : {
4429 28291500 : if (ro->cnt == 0)
4430 42975 : return NULL;
4431 28248600 : if (ro->cnt > 0)
4432 28210200 : ro->cnt--;
4433 28248600 : Py_INCREF(ro->element);
4434 28248600 : return ro->element;
4435 : }
4436 :
4437 : static PyObject *
4438 7 : repeat_repr(repeatobject *ro)
4439 : {
4440 7 : if (ro->cnt == -1)
4441 1 : return PyUnicode_FromFormat("%s(%R)",
4442 : _PyType_Name(Py_TYPE(ro)), ro->element);
4443 : else
4444 6 : return PyUnicode_FromFormat("%s(%R, %zd)",
4445 : _PyType_Name(Py_TYPE(ro)), ro->element,
4446 : ro->cnt);
4447 : }
4448 :
4449 : static PyObject *
4450 25 : repeat_len(repeatobject *ro, PyObject *Py_UNUSED(ignored))
4451 : {
4452 25 : if (ro->cnt == -1) {
4453 1 : PyErr_SetString(PyExc_TypeError, "len() of unsized object");
4454 1 : return NULL;
4455 : }
4456 24 : return PyLong_FromSize_t(ro->cnt);
4457 : }
4458 :
4459 : PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
4460 :
4461 : static PyObject *
4462 14 : repeat_reduce(repeatobject *ro, PyObject *Py_UNUSED(ignored))
4463 : {
4464 : /* unpickle this so that a new repeat iterator is constructed with an
4465 : * object, then call __setstate__ on it to set cnt
4466 : */
4467 14 : if (ro->cnt >= 0)
4468 14 : return Py_BuildValue("O(On)", Py_TYPE(ro), ro->element, ro->cnt);
4469 : else
4470 0 : return Py_BuildValue("O(O)", Py_TYPE(ro), ro->element);
4471 : }
4472 :
4473 : static PyMethodDef repeat_methods[] = {
4474 : {"__length_hint__", (PyCFunction)repeat_len, METH_NOARGS, length_hint_doc},
4475 : {"__reduce__", (PyCFunction)repeat_reduce, METH_NOARGS, reduce_doc},
4476 : {NULL, NULL} /* sentinel */
4477 : };
4478 :
4479 : PyDoc_STRVAR(repeat_doc,
4480 : "repeat(object [,times]) -> create an iterator which returns the object\n\
4481 : for the specified number of times. If not specified, returns the object\n\
4482 : endlessly.");
4483 :
4484 : static PyTypeObject repeat_type = {
4485 : PyVarObject_HEAD_INIT(NULL, 0)
4486 : "itertools.repeat", /* tp_name */
4487 : sizeof(repeatobject), /* tp_basicsize */
4488 : 0, /* tp_itemsize */
4489 : /* methods */
4490 : (destructor)repeat_dealloc, /* tp_dealloc */
4491 : 0, /* tp_vectorcall_offset */
4492 : 0, /* tp_getattr */
4493 : 0, /* tp_setattr */
4494 : 0, /* tp_as_async */
4495 : (reprfunc)repeat_repr, /* tp_repr */
4496 : 0, /* tp_as_number */
4497 : 0, /* tp_as_sequence */
4498 : 0, /* tp_as_mapping */
4499 : 0, /* tp_hash */
4500 : 0, /* tp_call */
4501 : 0, /* tp_str */
4502 : PyObject_GenericGetAttr, /* tp_getattro */
4503 : 0, /* tp_setattro */
4504 : 0, /* tp_as_buffer */
4505 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
4506 : Py_TPFLAGS_BASETYPE, /* tp_flags */
4507 : repeat_doc, /* tp_doc */
4508 : (traverseproc)repeat_traverse, /* tp_traverse */
4509 : 0, /* tp_clear */
4510 : 0, /* tp_richcompare */
4511 : 0, /* tp_weaklistoffset */
4512 : PyObject_SelfIter, /* tp_iter */
4513 : (iternextfunc)repeat_next, /* tp_iternext */
4514 : repeat_methods, /* tp_methods */
4515 : 0, /* tp_members */
4516 : 0, /* tp_getset */
4517 : 0, /* tp_base */
4518 : 0, /* tp_dict */
4519 : 0, /* tp_descr_get */
4520 : 0, /* tp_descr_set */
4521 : 0, /* tp_dictoffset */
4522 : 0, /* tp_init */
4523 : 0, /* tp_alloc */
4524 : repeat_new, /* tp_new */
4525 : PyObject_GC_Del, /* tp_free */
4526 : };
4527 :
4528 :
4529 : /* ziplongest object *********************************************************/
4530 :
4531 : typedef struct {
4532 : PyObject_HEAD
4533 : Py_ssize_t tuplesize;
4534 : Py_ssize_t numactive;
4535 : PyObject *ittuple; /* tuple of iterators */
4536 : PyObject *result;
4537 : PyObject *fillvalue;
4538 : } ziplongestobject;
4539 :
4540 : static PyTypeObject ziplongest_type;
4541 :
4542 : static PyObject *
4543 31789 : zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
4544 : {
4545 : ziplongestobject *lz;
4546 : Py_ssize_t i;
4547 : PyObject *ittuple; /* tuple of iterators */
4548 : PyObject *result;
4549 31789 : PyObject *fillvalue = Py_None;
4550 : Py_ssize_t tuplesize;
4551 :
4552 31789 : if (kwds != NULL && PyDict_CheckExact(kwds) && PyDict_GET_SIZE(kwds) > 0) {
4553 31596 : fillvalue = NULL;
4554 31596 : if (PyDict_GET_SIZE(kwds) == 1) {
4555 31595 : fillvalue = PyDict_GetItemWithError(kwds, &_Py_ID(fillvalue));
4556 : }
4557 31596 : if (fillvalue == NULL) {
4558 2 : if (!PyErr_Occurred()) {
4559 2 : PyErr_SetString(PyExc_TypeError,
4560 : "zip_longest() got an unexpected keyword argument");
4561 : }
4562 2 : return NULL;
4563 : }
4564 : }
4565 :
4566 : /* args must be a tuple */
4567 31787 : assert(PyTuple_Check(args));
4568 31787 : tuplesize = PyTuple_GET_SIZE(args);
4569 :
4570 : /* obtain iterators */
4571 31787 : ittuple = PyTuple_New(tuplesize);
4572 31787 : if (ittuple == NULL)
4573 0 : return NULL;
4574 95320 : for (i=0; i < tuplesize; i++) {
4575 63546 : PyObject *item = PyTuple_GET_ITEM(args, i);
4576 63546 : PyObject *it = PyObject_GetIter(item);
4577 63546 : if (it == NULL) {
4578 13 : Py_DECREF(ittuple);
4579 13 : return NULL;
4580 : }
4581 63533 : PyTuple_SET_ITEM(ittuple, i, it);
4582 : }
4583 :
4584 : /* create a result holder */
4585 31774 : result = PyTuple_New(tuplesize);
4586 31774 : if (result == NULL) {
4587 0 : Py_DECREF(ittuple);
4588 0 : return NULL;
4589 : }
4590 95306 : for (i=0 ; i < tuplesize ; i++) {
4591 63532 : Py_INCREF(Py_None);
4592 63532 : PyTuple_SET_ITEM(result, i, Py_None);
4593 : }
4594 :
4595 : /* create ziplongestobject structure */
4596 31774 : lz = (ziplongestobject *)type->tp_alloc(type, 0);
4597 31774 : if (lz == NULL) {
4598 0 : Py_DECREF(ittuple);
4599 0 : Py_DECREF(result);
4600 0 : return NULL;
4601 : }
4602 31774 : lz->ittuple = ittuple;
4603 31774 : lz->tuplesize = tuplesize;
4604 31774 : lz->numactive = tuplesize;
4605 31774 : lz->result = result;
4606 31774 : Py_INCREF(fillvalue);
4607 31774 : lz->fillvalue = fillvalue;
4608 31774 : return (PyObject *)lz;
4609 : }
4610 :
4611 : static void
4612 31774 : zip_longest_dealloc(ziplongestobject *lz)
4613 : {
4614 31774 : PyObject_GC_UnTrack(lz);
4615 31774 : Py_XDECREF(lz->ittuple);
4616 31774 : Py_XDECREF(lz->result);
4617 31774 : Py_XDECREF(lz->fillvalue);
4618 31774 : Py_TYPE(lz)->tp_free(lz);
4619 31774 : }
4620 :
4621 : static int
4622 30 : zip_longest_traverse(ziplongestobject *lz, visitproc visit, void *arg)
4623 : {
4624 30 : Py_VISIT(lz->ittuple);
4625 30 : Py_VISIT(lz->result);
4626 30 : Py_VISIT(lz->fillvalue);
4627 30 : return 0;
4628 : }
4629 :
4630 : static PyObject *
4631 1094290 : zip_longest_next(ziplongestobject *lz)
4632 : {
4633 : Py_ssize_t i;
4634 1094290 : Py_ssize_t tuplesize = lz->tuplesize;
4635 1094290 : PyObject *result = lz->result;
4636 : PyObject *it;
4637 : PyObject *item;
4638 : PyObject *olditem;
4639 :
4640 1094290 : if (tuplesize == 0)
4641 1 : return NULL;
4642 1094290 : if (lz->numactive == 0)
4643 0 : return NULL;
4644 1094290 : if (Py_REFCNT(result) == 1) {
4645 549112 : Py_INCREF(result);
4646 1620160 : for (i=0 ; i < tuplesize ; i++) {
4647 1098210 : it = PyTuple_GET_ITEM(lz->ittuple, i);
4648 1098210 : if (it == NULL) {
4649 7 : Py_INCREF(lz->fillvalue);
4650 7 : item = lz->fillvalue;
4651 : } else {
4652 1098200 : item = PyIter_Next(it);
4653 1098200 : if (item == NULL) {
4654 55758 : lz->numactive -= 1;
4655 55758 : if (lz->numactive == 0 || PyErr_Occurred()) {
4656 27162 : lz->numactive = 0;
4657 27162 : Py_DECREF(result);
4658 27162 : return NULL;
4659 : } else {
4660 28596 : Py_INCREF(lz->fillvalue);
4661 28596 : item = lz->fillvalue;
4662 28596 : PyTuple_SET_ITEM(lz->ittuple, i, NULL);
4663 28596 : Py_DECREF(it);
4664 : }
4665 : }
4666 : }
4667 1071050 : olditem = PyTuple_GET_ITEM(result, i);
4668 1071050 : PyTuple_SET_ITEM(result, i, item);
4669 1071050 : Py_DECREF(olditem);
4670 : }
4671 : // bpo-42536: The GC may have untracked this result tuple. Since we're
4672 : // recycling it, make sure it's tracked again:
4673 521950 : if (!_PyObject_GC_IS_TRACKED(result)) {
4674 4 : _PyObject_GC_TRACK(result);
4675 : }
4676 : } else {
4677 545174 : result = PyTuple_New(tuplesize);
4678 545174 : if (result == NULL)
4679 0 : return NULL;
4680 1658720 : for (i=0 ; i < tuplesize ; i++) {
4681 1118080 : it = PyTuple_GET_ITEM(lz->ittuple, i);
4682 1118080 : if (it == NULL) {
4683 33112 : Py_INCREF(lz->fillvalue);
4684 33112 : item = lz->fillvalue;
4685 : } else {
4686 1084970 : item = PyIter_Next(it);
4687 1084970 : if (item == NULL) {
4688 7694 : lz->numactive -= 1;
4689 7694 : if (lz->numactive == 0 || PyErr_Occurred()) {
4690 4535 : lz->numactive = 0;
4691 4535 : Py_DECREF(result);
4692 4535 : return NULL;
4693 : } else {
4694 3159 : Py_INCREF(lz->fillvalue);
4695 3159 : item = lz->fillvalue;
4696 3159 : PyTuple_SET_ITEM(lz->ittuple, i, NULL);
4697 3159 : Py_DECREF(it);
4698 : }
4699 : }
4700 : }
4701 1113550 : PyTuple_SET_ITEM(result, i, item);
4702 : }
4703 : }
4704 1062590 : return result;
4705 : }
4706 :
4707 : static PyObject *
4708 48 : zip_longest_reduce(ziplongestobject *lz, PyObject *Py_UNUSED(ignored))
4709 : {
4710 :
4711 : /* Create a new tuple with empty sequences where appropriate to pickle.
4712 : * Then use setstate to set the fillvalue
4713 : */
4714 : int i;
4715 48 : PyObject *args = PyTuple_New(PyTuple_GET_SIZE(lz->ittuple));
4716 :
4717 48 : if (args == NULL)
4718 0 : return NULL;
4719 144 : for (i=0; i<PyTuple_GET_SIZE(lz->ittuple); i++) {
4720 96 : PyObject *elem = PyTuple_GET_ITEM(lz->ittuple, i);
4721 96 : if (elem == NULL) {
4722 6 : elem = PyTuple_New(0);
4723 6 : if (elem == NULL) {
4724 0 : Py_DECREF(args);
4725 0 : return NULL;
4726 : }
4727 : } else
4728 90 : Py_INCREF(elem);
4729 96 : PyTuple_SET_ITEM(args, i, elem);
4730 : }
4731 48 : return Py_BuildValue("ONO", Py_TYPE(lz), args, lz->fillvalue);
4732 : }
4733 :
4734 : static PyObject *
4735 18 : zip_longest_setstate(ziplongestobject *lz, PyObject *state)
4736 : {
4737 18 : Py_INCREF(state);
4738 18 : Py_XSETREF(lz->fillvalue, state);
4739 18 : Py_RETURN_NONE;
4740 : }
4741 :
4742 : static PyMethodDef zip_longest_methods[] = {
4743 : {"__reduce__", (PyCFunction)zip_longest_reduce, METH_NOARGS,
4744 : reduce_doc},
4745 : {"__setstate__", (PyCFunction)zip_longest_setstate, METH_O,
4746 : setstate_doc},
4747 : {NULL, NULL} /* sentinel */
4748 : };
4749 :
4750 : PyDoc_STRVAR(zip_longest_doc,
4751 : "zip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> zip_longest object\n\
4752 : \n\
4753 : Return a zip_longest object whose .__next__() method returns a tuple where\n\
4754 : the i-th element comes from the i-th iterable argument. The .__next__()\n\
4755 : method continues until the longest iterable in the argument sequence\n\
4756 : is exhausted and then it raises StopIteration. When the shorter iterables\n\
4757 : are exhausted, the fillvalue is substituted in their place. The fillvalue\n\
4758 : defaults to None or can be specified by a keyword argument.\n\
4759 : ");
4760 :
4761 : static PyTypeObject ziplongest_type = {
4762 : PyVarObject_HEAD_INIT(NULL, 0)
4763 : "itertools.zip_longest", /* tp_name */
4764 : sizeof(ziplongestobject), /* tp_basicsize */
4765 : 0, /* tp_itemsize */
4766 : /* methods */
4767 : (destructor)zip_longest_dealloc, /* tp_dealloc */
4768 : 0, /* tp_vectorcall_offset */
4769 : 0, /* tp_getattr */
4770 : 0, /* tp_setattr */
4771 : 0, /* tp_as_async */
4772 : 0, /* tp_repr */
4773 : 0, /* tp_as_number */
4774 : 0, /* tp_as_sequence */
4775 : 0, /* tp_as_mapping */
4776 : 0, /* tp_hash */
4777 : 0, /* tp_call */
4778 : 0, /* tp_str */
4779 : PyObject_GenericGetAttr, /* tp_getattro */
4780 : 0, /* tp_setattro */
4781 : 0, /* tp_as_buffer */
4782 : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
4783 : Py_TPFLAGS_BASETYPE, /* tp_flags */
4784 : zip_longest_doc, /* tp_doc */
4785 : (traverseproc)zip_longest_traverse, /* tp_traverse */
4786 : 0, /* tp_clear */
4787 : 0, /* tp_richcompare */
4788 : 0, /* tp_weaklistoffset */
4789 : PyObject_SelfIter, /* tp_iter */
4790 : (iternextfunc)zip_longest_next, /* tp_iternext */
4791 : zip_longest_methods, /* tp_methods */
4792 : 0, /* tp_members */
4793 : 0, /* tp_getset */
4794 : 0, /* tp_base */
4795 : 0, /* tp_dict */
4796 : 0, /* tp_descr_get */
4797 : 0, /* tp_descr_set */
4798 : 0, /* tp_dictoffset */
4799 : 0, /* tp_init */
4800 : 0, /* tp_alloc */
4801 : zip_longest_new, /* tp_new */
4802 : PyObject_GC_Del, /* tp_free */
4803 : };
4804 :
4805 :
4806 : /* module level code ********************************************************/
4807 :
4808 : PyDoc_STRVAR(module_doc,
4809 : "Functional tools for creating and using iterators.\n\
4810 : \n\
4811 : Infinite iterators:\n\
4812 : count(start=0, step=1) --> start, start+step, start+2*step, ...\n\
4813 : cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\
4814 : repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\
4815 : \n\
4816 : Iterators terminating on the shortest input sequence:\n\
4817 : accumulate(p[, func]) --> p0, p0+p1, p0+p1+p2\n\
4818 : chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...\n\
4819 : chain.from_iterable([p, q, ...]) --> p0, p1, ... plast, q0, q1, ...\n\
4820 : compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...\n\
4821 : dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\
4822 : groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n\
4823 : filterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\
4824 : islice(seq, [start,] stop [, step]) --> elements from\n\
4825 : seq[start:stop:step]\n\
4826 : pairwise(s) --> (s[0],s[1]), (s[1],s[2]), (s[2], s[3]), ...\n\
4827 : starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\
4828 : tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n\
4829 : takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\
4830 : zip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...\n\
4831 : \n\
4832 : Combinatoric generators:\n\
4833 : product(p, q, ... [repeat=1]) --> cartesian product\n\
4834 : permutations(p[, r])\n\
4835 : combinations(p, r)\n\
4836 : combinations_with_replacement(p, r)\n\
4837 : ");
4838 :
4839 : static int
4840 2005 : itertoolsmodule_exec(PyObject *m)
4841 : {
4842 2005 : PyTypeObject *typelist[] = {
4843 : &accumulate_type,
4844 : &combinations_type,
4845 : &cwr_type,
4846 : &cycle_type,
4847 : &dropwhile_type,
4848 : &takewhile_type,
4849 : &islice_type,
4850 : &starmap_type,
4851 : &chain_type,
4852 : &compress_type,
4853 : &filterfalse_type,
4854 : &count_type,
4855 : &ziplongest_type,
4856 : &pairwise_type,
4857 : &permutations_type,
4858 : &product_type,
4859 : &repeat_type,
4860 : &groupby_type,
4861 : &_grouper_type,
4862 : &tee_type,
4863 : &teedataobject_type
4864 : };
4865 :
4866 2005 : Py_SET_TYPE(&teedataobject_type, &PyType_Type);
4867 :
4868 44110 : for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) {
4869 42105 : if (PyModule_AddType(m, typelist[i]) < 0) {
4870 0 : return -1;
4871 : }
4872 : }
4873 :
4874 2005 : return 0;
4875 : }
4876 :
4877 : static struct PyModuleDef_Slot itertoolsmodule_slots[] = {
4878 : {Py_mod_exec, itertoolsmodule_exec},
4879 : {0, NULL}
4880 : };
4881 :
4882 : static PyMethodDef module_methods[] = {
4883 : ITERTOOLS_TEE_METHODDEF
4884 : {NULL, NULL} /* sentinel */
4885 : };
4886 :
4887 :
4888 : static struct PyModuleDef itertoolsmodule = {
4889 : PyModuleDef_HEAD_INIT,
4890 : "itertools",
4891 : module_doc,
4892 : 0,
4893 : module_methods,
4894 : itertoolsmodule_slots,
4895 : NULL,
4896 : NULL,
4897 : NULL
4898 : };
4899 :
4900 : PyMODINIT_FUNC
4901 2005 : PyInit_itertools(void)
4902 : {
4903 2005 : return PyModuleDef_Init(&itertoolsmodule);
4904 : }
|