Coverage Report

Created: 2022-07-08 09:39

/home/mdboom/Work/builds/cpython/Modules/itertoolsmodule.c
Line
Count
Source (jump to first uncovered line)
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
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
    it = PyObject_GetIter(iterable);
81
    if (it == NULL) {
  Branch (81:9): [True: 11, False: 41]
82
        return NULL;
83
    }
84
    po = (pairwiseobject *)type->tp_alloc(type, 0);
85
    if (po == NULL) {
  Branch (85:9): [True: 0, False: 41]
86
        Py_DECREF(it);
87
        return NULL;
88
    }
89
    po->it = it;
90
    po->old = NULL;
91
    return (PyObject *)po;
92
}
93
94
static void
95
pairwise_dealloc(pairwiseobject *po)
96
{
97
    PyObject_GC_UnTrack(po);
98
    Py_XDECREF(po->it);
99
    Py_XDECREF(po->old);
100
    Py_TYPE(po)->tp_free(po);
101
}
102
103
static int
104
pairwise_traverse(pairwiseobject *po, visitproc visit, void *arg)
105
{
106
    Py_VISIT(po->it);
107
    Py_VISIT(po->old);
108
    return 0;
109
}
110
111
static PyObject *
112
pairwise_next(pairwiseobject *po)
113
{
114
    PyObject *it = po->it;
115
    PyObject *old = po->old;
116
    PyObject *new, *result;
117
118
    if (it == NULL) {
  Branch (118:9): [True: 0, False: 15.2k]
119
        return NULL;
120
    }
121
    if (old == NULL) {
  Branch (121:9): [True: 41, False: 15.2k]
122
        po->old = old = (*Py_TYPE(it)->tp_iternext)(it);
123
        if (old == NULL) {
  Branch (123:13): [True: 16, False: 25]
124
            Py_CLEAR(po->it);
125
            return NULL;
126
        }
127
    }
128
    new = (*Py_TYPE(it)->tp_iternext)(it);
129
    if (new == NULL) {
  Branch (129:9): [True: 24, False: 15.2k]
130
        Py_CLEAR(po->it);
131
        Py_CLEAR(po->old);
132
        return NULL;
133
    }
134
    /* Future optimization: Reuse the result tuple as we do in enumerate() */
135
    result = PyTuple_Pack(2, old, new);
136
    Py_SETREF(po->old, new);
137
    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
itertools_groupby_impl(PyTypeObject *type, PyObject *it, PyObject *keyfunc)
215
/*[clinic end generated code: output=cbb1ae3a90fd4141 input=6b3d123e87ff65a1]*/
216
{
217
    groupbyobject *gbo;
218
219
    gbo = (groupbyobject *)type->tp_alloc(type, 0);
220
    if (gbo == NULL)
  Branch (220:9): [True: 0, False: 3.02k]
221
        return NULL;
222
    gbo->tgtkey = NULL;
223
    gbo->currkey = NULL;
224
    gbo->currvalue = NULL;
225
    gbo->keyfunc = keyfunc;
226
    Py_INCREF(keyfunc);
227
    gbo->it = PyObject_GetIter(it);
228
    if (gbo->it == NULL) {
  Branch (228:9): [True: 31, False: 2.99k]
229
        Py_DECREF(gbo);
230
        return NULL;
231
    }
232
    return (PyObject *)gbo;
233
}
234
235
static void
236
groupby_dealloc(groupbyobject *gbo)
237
{
238
    PyObject_GC_UnTrack(gbo);
239
    Py_XDECREF(gbo->it);
240
    Py_XDECREF(gbo->keyfunc);
241
    Py_XDECREF(gbo->tgtkey);
242
    Py_XDECREF(gbo->currkey);
243
    Py_XDECREF(gbo->currvalue);
244
    Py_TYPE(gbo)->tp_free(gbo);
245
}
246
247
static int
248
groupby_traverse(groupbyobject *gbo, visitproc visit, void *arg)
249
{
250
    Py_VISIT(gbo->it);
251
    Py_VISIT(gbo->keyfunc);
252
    Py_VISIT(gbo->tgtkey);
253
    Py_VISIT(gbo->currkey);
254
    Py_VISIT(gbo->currvalue);
255
    return 0;
256
}
257
258
Py_LOCAL_INLINE(int)
259
groupby_step(groupbyobject *gbo)
260
{
261
    PyObject *newvalue, *newkey, *oldvalue;
262
263
    newvalue = PyIter_Next(gbo->it);
264
    if (newvalue == NULL)
  Branch (264:9): [True: 3.40k, False: 226k]
265
        return -1;
266
267
    if (gbo->keyfunc == Py_None) {
  Branch (267:9): [True: 18.5k, False: 207k]
268
        newkey = newvalue;
269
        Py_INCREF(newvalue);
270
    } else {
271
        newkey = PyObject_CallOneArg(gbo->keyfunc, newvalue);
272
        if (newkey == NULL) {
  Branch (272:13): [True: 3, False: 207k]
273
            Py_DECREF(newvalue);
274
            return -1;
275
        }
276
    }
277
278
    oldvalue = gbo->currvalue;
279
    gbo->currvalue = newvalue;
280
    Py_XSETREF(gbo->currkey, newkey);
281
    Py_XDECREF(oldvalue);
282
    return 0;
283
}
284
285
static PyObject *
286
groupby_next(groupbyobject *gbo)
287
{
288
    PyObject *r, *grouper;
289
290
    gbo->currgrouper = NULL;
291
    /* skip to next iteration group */
292
    for (;;) {
293
        if (gbo->currkey == NULL)
  Branch (293:13): [True: 3.41k, False: 133k]
294
            /* pass */;
295
        else if (gbo->tgtkey == NULL)
  Branch (295:18): [True: 2.88k, False: 130k]
296
            break;
297
        else {
298
            int rcmp;
299
300
            rcmp = PyObject_RichCompareBool(gbo->tgtkey, gbo->currkey, Py_EQ);
301
            if (rcmp == -1)
  Branch (301:17): [True: 1, False: 130k]
302
                return NULL;
303
            else if (rcmp == 0)
  Branch (303:22): [True: 112k, False: 18.6k]
304
                break;
305
        }
306
307
        if (groupby_step(gbo) < 0)
  Branch (307:13): [True: 2.90k, False: 19.1k]
308
            return NULL;
309
    }
310
    Py_INCREF(gbo->currkey);
311
    Py_XSETREF(gbo->tgtkey, gbo->currkey);
312
313
    grouper = _grouper_create(gbo, gbo->tgtkey);
314
    if (grouper == NULL)
  Branch (314:9): [True: 0, False: 115k]
315
        return NULL;
316
317
    r = PyTuple_Pack(2, gbo->currkey, grouper);
318
    Py_DECREF(grouper);
319
    return r;
320
}
321
322
static PyObject *
323
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
    if (lz->tgtkey && 
lz->currkey24
&&
lz->currvalue24
)
  Branch (329:9): [True: 24, False: 36]
  Branch (329:23): [True: 24, False: 0]
  Branch (329:38): [True: 24, False: 0]
330
        value = Py_BuildValue("O(OO)(OOO)", Py_TYPE(lz),
331
            lz->it, lz->keyfunc, lz->currkey, lz->currvalue, lz->tgtkey);
332
    else
333
        value = Py_BuildValue("O(OO)", Py_TYPE(lz),
334
            lz->it, lz->keyfunc);
335
336
    return value;
337
}
338
339
PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
340
341
static PyObject *
342
groupby_setstate(groupbyobject *lz, PyObject *state)
343
{
344
    PyObject *currkey, *currvalue, *tgtkey;
345
    if (!PyTuple_Check(state)) {
  Branch (345:9): [True: 0, False: 24]
346
        PyErr_SetString(PyExc_TypeError, "state is not a tuple");
347
        return NULL;
348
    }
349
    if (!PyArg_ParseTuple(state, "OOO", &currkey, &currvalue, &tgtkey)) {
  Branch (349:9): [True: 0, False: 24]
350
        return NULL;
351
    }
352
    Py_INCREF(currkey);
353
    Py_XSETREF(lz->currkey, currkey);
354
    Py_INCREF(currvalue);
355
    Py_XSETREF(lz->currvalue, currvalue);
356
    Py_INCREF(tgtkey);
357
    Py_XSETREF(lz->tgtkey, tgtkey);
358
    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
itertools__grouper_impl(PyTypeObject *type, PyObject *parent,
435
                        PyObject *tgtkey)
436
/*[clinic end generated code: output=462efb1cdebb5914 input=dc180d7771fc8c59]*/
437
{
438
    return _grouper_create((groupbyobject*) parent, tgtkey);
439
}
440
441
static PyObject *
442
_grouper_create(groupbyobject *parent, PyObject *tgtkey)
443
{
444
    _grouperobject *igo;
445
446
    igo = PyObject_GC_New(_grouperobject, &_grouper_type);
447
    if (igo == NULL)
  Branch (447:9): [True: 0, False: 115k]
448
        return NULL;
449
    igo->parent = (PyObject *)parent;
450
    Py_INCREF(parent);
451
    igo->tgtkey = tgtkey;
452
    Py_INCREF(tgtkey);
453
    parent->currgrouper = igo;  /* borrowed reference */
454
455
    PyObject_GC_Track(igo);
456
    return (PyObject *)igo;
457
}
458
459
static void
460
_grouper_dealloc(_grouperobject *igo)
461
{
462
    PyObject_GC_UnTrack(igo);
463
    Py_DECREF(igo->parent);
464
    Py_DECREF(igo->tgtkey);
465
    PyObject_GC_Del(igo);
466
}
467
468
static int
469
_grouper_traverse(_grouperobject *igo, visitproc visit, void *arg)
470
{
471
    Py_VISIT(igo->parent);
472
    Py_VISIT(igo->tgtkey);
473
    return 0;
474
}
475
476
static PyObject *
477
_grouper_next(_grouperobject *igo)
478
{
479
    groupbyobject *gbo = (groupbyobject *)igo->parent;
480
    PyObject *r;
481
    int rcmp;
482
483
    if (gbo->currgrouper != igo)
  Branch (483:9): [True: 3, False: 310k]
484
        return NULL;
485
    if (gbo->currvalue == NULL) {
  Branch (485:9): [True: 207k, False: 102k]
486
        if (groupby_step(gbo) < 0)
  Branch (486:13): [True: 501, False: 206k]
487
            return NULL;
488
    }
489
490
    assert(gbo->currkey != NULL);
491
    rcmp = PyObject_RichCompareBool(igo->tgtkey, gbo->currkey, Py_EQ);
492
    if (rcmp <= 0)
  Branch (492:9): [True: 102k, False: 207k]
493
        /* got any error or current group is end */
494
        return NULL;
495
496
    r = gbo->currvalue;
497
    gbo->currvalue = NULL;
498
    Py_CLEAR(gbo->currkey);
499
500
    return r;
501
}
502
503
static PyObject *
504
_grouper_reduce(_grouperobject *lz, PyObject *Py_UNUSED(ignored))
505
{
506
    if (((groupbyobject *)lz->parent)->currgrouper != lz) {
  Branch (506:9): [True: 6, False: 24]
507
        return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter)));
508
    }
509
    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
teedataobject_newinternal(PyObject *it)
593
{
594
    teedataobject *tdo;
595
596
    tdo = PyObject_GC_New(teedataobject, &teedataobject_type);
597
    if (tdo == NULL)
  Branch (597:9): [True: 0, False: 352k]
598
        return NULL;
599
600
    tdo->running = 0;
601
    tdo->numread = 0;
602
    tdo->nextlink = NULL;
603
    Py_INCREF(it);
604
    tdo->it = it;
605
    PyObject_GC_Track(tdo);
606
    return (PyObject *)tdo;
607
}
608
609
static PyObject *
610
teedataobject_jumplink(teedataobject *tdo)
611
{
612
    if (tdo->nextlink == NULL)
  Branch (612:9): [True: 352k, False: 1.24k]
613
        tdo->nextlink = teedataobject_newinternal(tdo->it);
614
    Py_XINCREF(tdo->nextlink);
615
    return tdo->nextlink;
616
}
617
618
static PyObject *
619
teedataobject_getitem(teedataobject *tdo, int i)
620
{
621
    PyObject *value;
622
623
    assert(i < LINKCELLS);
624
    if (i < tdo->numread)
  Branch (624:9): [True: 72.2k, False: 20.0M]
625
        value = tdo->values[i];
626
    else {
627
        /* this is the lead iterator, so fetch more data */
628
        assert(i == tdo->numread);
629
        if (tdo->running) {
  Branch (629:13): [True: 2, False: 20.0M]
630
            PyErr_SetString(PyExc_RuntimeError,
631
                            "cannot re-enter the tee iterator");
632
            return NULL;
633
        }
634
        tdo->running = 1;
635
        value = PyIter_Next(tdo->it);
636
        tdo->running = 0;
637
        if (value == NULL)
  Branch (637:13): [True: 215, False: 20.0M]
638
            return NULL;
639
        tdo->numread++;
640
        tdo->values[i] = value;
641
    }
642
    Py_INCREF(value);
643
    return value;
644
}
645
646
static int
647
teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg)
648
{
649
    int i;
650
651
    Py_VISIT(tdo->it);
652
    
for (i = 0; 2.44M
i < tdo->numread;
i++139M
)
  Branch (652:17): [True: 139M, False: 2.44M]
653
        Py_VISIT(tdo->values[i]);
654
    Py_VISIT(tdo->nextlink);
655
    return 0;
656
}
657
658
static void
659
teedataobject_safe_decref(PyObject *obj)
660
{
661
    while (obj && 
Py_IS_TYPE352k
(obj, &teedataobject_type) &&
  Branch (661:12): [True: 352k, False: 351k]
662
           
Py_REFCNT352k
(obj) == 1352k
) {
  Branch (662:12): [True: 351k, False: 1.39k]
663
        PyObject *nextlink = ((teedataobject *)obj)->nextlink;
664
        ((teedataobject *)obj)->nextlink = NULL;
665
        Py_DECREF(obj);
666
        obj = nextlink;
667
    }
668
    Py_XDECREF(obj);
669
}
670
671
static int
672
teedataobject_clear(teedataobject *tdo)
673
{
674
    int i;
675
    PyObject *tmp;
676
677
    Py_CLEAR(tdo->it);
678
    for (i=0 ; i<tdo->numread ; 
i++20.0M
)
  Branch (678:16): [True: 20.0M, False: 352k]
679
        Py_CLEAR(tdo->values[i]);
680
    tmp = tdo->nextlink;
681
    tdo->nextlink = NULL;
682
    teedataobject_safe_decref(tmp);
683
    return 0;
684
}
685
686
static void
687
teedataobject_dealloc(teedataobject *tdo)
688
{
689
    PyObject_GC_UnTrack(tdo);
690
    teedataobject_clear(tdo);
691
    PyObject_GC_Del(tdo);
692
}
693
694
static PyObject *
695
teedataobject_reduce(teedataobject *tdo, PyObject *Py_UNUSED(ignored))
696
{
697
    int i;
698
    /* create a temporary list of already iterated values */
699
    PyObject *values = PyList_New(tdo->numread);
700
701
    if (!values)
  Branch (701:9): [True: 0, False: 44]
702
        return NULL;
703
    
for (i=0 ; 44
i<tdo->numread ;
i++132
) {
  Branch (703:16): [True: 132, False: 44]
704
        Py_INCREF(tdo->values[i]);
705
        PyList_SET_ITEM(values, i, tdo->values[i]);
706
    }
707
    return Py_BuildValue("O(ONO)", Py_TYPE(tdo), tdo->it,
708
                         values,
709
                         tdo->nextlink ? 
tdo->nextlink0
: Py_None);
  Branch (709:26): [True: 0, False: 44]
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
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
    assert(type == &teedataobject_type);
731
732
    tdo = (teedataobject *)teedataobject_newinternal(it);
733
    if (!tdo)
  Branch (733:9): [True: 0, False: 62]
734
        return NULL;
735
736
    len = PyList_GET_SIZE(values);
737
    if (len > LINKCELLS)
  Branch (737:9): [True: 0, False: 62]
738
        goto err;
739
    
for (i=0; 62
i<len;
i++150
) {
  Branch (739:15): [True: 150, False: 62]
740
        tdo->values[i] = PyList_GET_ITEM(values, i);
741
        Py_INCREF(tdo->values[i]);
742
    }
743
    /* len <= LINKCELLS < INT_MAX */
744
    tdo->numread = Py_SAFE_DOWNCAST(len, Py_ssize_t, int);
745
746
    if (len == LINKCELLS) {
  Branch (746:9): [True: 0, False: 62]
747
        if (next != Py_None) {
  Branch (747:13): [True: 0, False: 0]
748
            if (!Py_IS_TYPE(next, &teedataobject_type))
  Branch (748:17): [True: 0, False: 0]
749
                goto err;
750
            assert(tdo->nextlink == NULL);
751
            Py_INCREF(next);
752
            tdo->nextlink = next;
753
        }
754
    } else {
755
        if (next != Py_None)
  Branch (755:13): [True: 0, False: 62]
756
            goto err; /* shouldn't have a next if we are not full */
757
    }
758
    return (PyObject*)tdo;
759
760
err:
761
    Py_XDECREF(tdo);
762
    PyErr_SetString(PyExc_ValueError, "Invalid arguments");
763
    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
tee_next(teeobject *to)
818
{
819
    PyObject *value, *link;
820
821
    if (to->index >= LINKCELLS) {
  Branch (821:9): [True: 353k, False: 19.8M]
822
        link = teedataobject_jumplink(to->dataobj);
823
        if (link == NULL)
  Branch (823:13): [True: 0, False: 353k]
824
            return NULL;
825
        Py_SETREF(to->dataobj, (teedataobject *)link);
826
        to->index = 0;
827
    }
828
    value = teedataobject_getitem(to->dataobj, to->index);
829
    if (value == NULL)
  Branch (829:9): [True: 217, False: 20.1M]
830
        return NULL;
831
    to->index++;
832
    return value;
833
}
834
835
static int
836
tee_traverse(teeobject *to, visitproc visit, void *arg)
837
{
838
    Py_VISIT((PyObject *)to->dataobj);
839
    return 0;
840
}
841
842
static PyObject *
843
tee_copy(teeobject *to, PyObject *Py_UNUSED(ignored))
844
{
845
    teeobject *newto;
846
847
    newto = PyObject_GC_New(teeobject, &tee_type);
848
    if (newto == NULL)
  Branch (848:9): [True: 0, False: 106]
849
        return NULL;
850
    Py_INCREF(to->dataobj);
851
    newto->dataobj = to->dataobj;
852
    newto->index = to->index;
853
    newto->weakreflist = NULL;
854
    PyObject_GC_Track(newto);
855
    return (PyObject *)newto;
856
}
857
858
PyDoc_STRVAR(teecopy_doc, "Returns an independent iterator.");
859
860
static PyObject *
861
tee_fromiterable(PyObject *iterable)
862
{
863
    teeobject *to;
864
    PyObject *it;
865
866
    it = PyObject_GetIter(iterable);
867
    if (it == NULL)
  Branch (867:9): [True: 1, False: 172]
868
        return NULL;
869
    if (PyObject_TypeCheck(it, &tee_type)) {
870
        to = (teeobject *)tee_copy((teeobject *)it, NULL);
871
        goto done;
872
    }
873
874
    PyObject *dataobj = teedataobject_newinternal(it);
875
    if (!dataobj) {
  Branch (875:9): [True: 0, False: 171]
876
        to = NULL;
877
        goto done;
878
    }
879
    to = PyObject_GC_New(teeobject, &tee_type);
880
    if (to == NULL) {
  Branch (880:9): [True: 0, False: 171]
881
        Py_DECREF(dataobj);
882
        goto done;
883
    }
884
    to->dataobj = (teedataobject *)dataobj;
885
    to->index = 0;
886
    to->weakreflist = NULL;
887
    PyObject_GC_Track(to);
888
done:
889
    Py_DECREF(it);
890
    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
itertools__tee_impl(PyTypeObject *type, PyObject *iterable)
903
/*[clinic end generated code: output=b02d3fd26c810c3f input=adc0779d2afe37a2]*/
904
{
905
    return tee_fromiterable(iterable);
906
}
907
908
static int
909
tee_clear(teeobject *to)
910
{
911
    if (to->weakreflist != NULL)
  Branch (911:9): [True: 1, False: 276]
912
        PyObject_ClearWeakRefs((PyObject *) to);
913
    Py_CLEAR(to->dataobj);
914
    return 0;
915
}
916
917
static void
918
tee_dealloc(teeobject *to)
919
{
920
    PyObject_GC_UnTrack(to);
921
    tee_clear(to);
922
    PyObject_GC_Del(to);
923
}
924
925
static PyObject *
926
tee_reduce(teeobject *to, PyObject *Py_UNUSED(ignored))
927
{
928
    return Py_BuildValue("O(())(Oi)", Py_TYPE(to), to->dataobj, to->index);
929
}
930
931
static PyObject *
932
tee_setstate(teeobject *to, PyObject *state)
933
{
934
    teedataobject *tdo;
935
    int index;
936
    if (!PyTuple_Check(state)) {
  Branch (936:9): [True: 0, False: 80]
937
        PyErr_SetString(PyExc_TypeError, "state is not a tuple");
938
        return NULL;
939
    }
940
    if (!PyArg_ParseTuple(state, "O!i", &teedataobject_type, &tdo, &index)) {
  Branch (940:9): [True: 0, False: 80]
941
        return NULL;
942
    }
943
    if (index < 0 || index > LINKCELLS) {
  Branch (943:9): [True: 0, False: 80]
  Branch (943:22): [True: 0, False: 80]
944
        PyErr_SetString(PyExc_ValueError, "Index out of range");
945
        return NULL;
946
    }
947
    Py_INCREF(tdo);
948
    Py_XSETREF(to->dataobj, tdo);
949
    to->index = index;
950
    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
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
    if (n < 0) {
  Branch (1018:9): [True: 1, False: 103]
1019
        PyErr_SetString(PyExc_ValueError, "n must be >= 0");
1020
        return NULL;
1021
    }
1022
    result = PyTuple_New(n);
1023
    if (result == NULL)
  Branch (1023:9): [True: 0, False: 103]
1024
        return NULL;
1025
    if (n == 0)
  Branch (1025:9): [True: 1, False: 102]
1026
        return result;
1027
    it = PyObject_GetIter(iterable);
1028
    if (it == NULL) {
  Branch (1028:9): [True: 11, False: 91]
1029
        Py_DECREF(result);
1030
        return NULL;
1031
    }
1032
1033
    if (_PyObject_LookupAttr(it, &_Py_ID(__copy__), &copyfunc) < 0) {
  Branch (1033:9): [True: 0, False: 91]
1034
        Py_DECREF(it);
1035
        Py_DECREF(result);
1036
        return NULL;
1037
    }
1038
    if (copyfunc != NULL) {
  Branch (1038:9): [True: 1, False: 90]
1039
        copyable = it;
1040
    }
1041
    else {
1042
        copyable = tee_fromiterable(it);
1043
        Py_DECREF(it);
1044
        if (copyable == NULL) {
  Branch (1044:13): [True: 0, False: 90]
1045
            Py_DECREF(result);
1046
            return NULL;
1047
        }
1048
        copyfunc = PyObject_GetAttr(copyable, &_Py_ID(__copy__));
1049
        if (copyfunc == NULL) {
  Branch (1049:13): [True: 0, False: 90]
1050
            Py_DECREF(copyable);
1051
            Py_DECREF(result);
1052
            return NULL;
1053
        }
1054
    }
1055
1056
    PyTuple_SET_ITEM(result, 0, copyable);
1057
    for (i = 1; i < n; 
i++97
) {
  Branch (1057:17): [True: 97, False: 91]
1058
        copyable = _PyObject_CallNoArgs(copyfunc);
1059
        if (copyable == NULL) {
  Branch (1059:13): [True: 0, False: 97]
1060
            Py_DECREF(copyfunc);
1061
            Py_DECREF(result);
1062
            return NULL;
1063
        }
1064
        PyTuple_SET_ITEM(result, i, copyable);
1065
    }
1066
    Py_DECREF(copyfunc);
1067
    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
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
    it = PyObject_GetIter(iterable);
1099
    if (it == NULL)
  Branch (1099:9): [True: 11, False: 121]
1100
        return NULL;
1101
1102
    saved = PyList_New(0);
1103
    if (saved == NULL) {
  Branch (1103:9): [True: 0, False: 121]
1104
        Py_DECREF(it);
1105
        return NULL;
1106
    }
1107
1108
    /* create cycleobject structure */
1109
    lz = (cycleobject *)type->tp_alloc(type, 0);
1110
    if (lz == NULL) {
  Branch (1110:9): [True: 0, False: 121]
1111
        Py_DECREF(it);
1112
        Py_DECREF(saved);
1113
        return NULL;
1114
    }
1115
    lz->it = it;
1116
    lz->saved = saved;
1117
    lz->index = 0;
1118
    lz->firstpass = 0;
1119
1120
    return (PyObject *)lz;
1121
}
1122
1123
static void
1124
cycle_dealloc(cycleobject *lz)
1125
{
1126
    PyObject_GC_UnTrack(lz);
1127
    Py_XDECREF(lz->it);
1128
    Py_XDECREF(lz->saved);
1129
    Py_TYPE(lz)->tp_free(lz);
1130
}
1131
1132
static int
1133
cycle_traverse(cycleobject *lz, visitproc visit, void *arg)
1134
{
1135
    Py_VISIT(lz->it);
1136
    Py_VISIT(lz->saved);
1137
    return 0;
1138
}
1139
1140
static PyObject *
1141
cycle_next(cycleobject *lz)
1142
{
1143
    PyObject *item;
1144
1145
    if (lz->it != NULL) {
  Branch (1145:9): [True: 5.58k, False: 6.01M]
1146
        item = PyIter_Next(lz->it);
1147
        if (item != NULL) {
  Branch (1147:13): [True: 5.48k, False: 104]
1148
            if (lz->firstpass)
  Branch (1148:17): [True: 37, False: 5.44k]
1149
                return item;
1150
            if (PyList_Append(lz->saved, item)) {
  Branch (1150:17): [True: 0, False: 5.44k]
1151
                Py_DECREF(item);
1152
                return NULL;
1153
            }
1154
            return item;
1155
        }
1156
        /* Note:  StopIteration is already cleared by PyIter_Next() */
1157
        if (PyErr_Occurred())
  Branch (1157:13): [True: 6, False: 98]
1158
            return NULL;
1159
        Py_CLEAR(lz->it);
1160
    }
1161
    if (PyList_GET_SIZE(lz->saved) == 0)
  Branch (1161:9): [True: 7, False: 6.01M]
1162
        return NULL;
1163
    item = PyList_GET_ITEM(lz->saved, lz->index);
1164
    lz->index++;
1165
    if (lz->index >= PyList_GET_SIZE(lz->saved))
  Branch (1165:9): [True: 600k, False: 5.41M]
1166
        lz->index = 0;
1167
    Py_INCREF(item);
1168
    return item;
1169
}
1170
1171
static PyObject *
1172
cycle_reduce(cycleobject *lz, PyObject *Py_UNUSED(ignored))
1173
{
1174
    /* Create a new cycle with the iterator tuple, then set the saved state */
1175
    if (lz->it == NULL) {
  Branch (1175:9): [True: 16, False: 21]
1176
        PyObject *it = PyObject_GetIter(lz->saved);
1177
        if (it == NULL)
  Branch (1177:13): [True: 0, False: 16]
1178
            return NULL;
1179
        if (lz->index != 0) {
  Branch (1179:13): [True: 16, False: 0]
1180
            PyObject *res = _PyObject_CallMethod(it, &_Py_ID(__setstate__),
1181
                                                 "n", lz->index);
1182
            if (res == NULL) {
  Branch (1182:17): [True: 0, False: 16]
1183
                Py_DECREF(it);
1184
                return NULL;
1185
            }
1186
            Py_DECREF(res);
1187
        }
1188
        return Py_BuildValue("O(N)(OO)", Py_TYPE(lz), it, lz->saved, Py_True);
1189
    }
1190
    return Py_BuildValue("O(O)(OO)", Py_TYPE(lz), lz->it, lz->saved,
1191
                         lz->firstpass ? Py_True : Py_False);
  Branch (1191:26): [True: 0, False: 21]
1192
}
1193
1194
static PyObject *
1195
cycle_setstate(cycleobject *lz, PyObject *state)
1196
{
1197
    PyObject *saved=NULL;
1198
    int firstpass;
1199
    if (!PyTuple_Check(state)) {
  Branch (1199:9): [True: 1, False: 49]
1200
        PyErr_SetString(PyExc_TypeError, "state is not a tuple");
1201
        return NULL;
1202
    }
1203
    if (!PyArg_ParseTuple(state, "O!i", &PyList_Type, &saved, &firstpass)) {
  Branch (1203:9): [True: 4, False: 45]
1204
        return NULL;
1205
    }
1206
    Py_INCREF(saved);
1207
    Py_XSETREF(lz->saved, saved);
1208
    lz->firstpass = firstpass != 0;
1209
    lz->index = 0;
1210
    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
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
    it = PyObject_GetIter(seq);
1295
    if (it == NULL)
  Branch (1295:9): [True: 10, False: 74]
1296
        return NULL;
1297
1298
    /* create dropwhileobject structure */
1299
    lz = (dropwhileobject *)type->tp_alloc(type, 0);
1300
    if (lz == NULL) {
  Branch (1300:9): [True: 0, False: 74]
1301
        Py_DECREF(it);
1302
        return NULL;
1303
    }
1304
    Py_INCREF(func);
1305
    lz->func = func;
1306
    lz->it = it;
1307
    lz->start = 0;
1308
1309
    return (PyObject *)lz;
1310
}
1311
1312
static void
1313
dropwhile_dealloc(dropwhileobject *lz)
1314
{
1315
    PyObject_GC_UnTrack(lz);
1316
    Py_XDECREF(lz->func);
1317
    Py_XDECREF(lz->it);
1318
    Py_TYPE(lz)->tp_free(lz);
1319
}
1320
1321
static int
1322
dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg)
1323
{
1324
    Py_VISIT(lz->it);
1325
    Py_VISIT(lz->func);
1326
    return 0;
1327
}
1328
1329
static PyObject *
1330
dropwhile_next(dropwhileobject *lz)
1331
{
1332
    PyObject *item, *good;
1333
    PyObject *it = lz->it;
1334
    long ok;
1335
    PyObject *(*iternext)(PyObject *);
1336
1337
    iternext = *Py_TYPE(it)->tp_iternext;
1338
    for (;;) {
1339
        item = iternext(it);
1340
        if (item == NULL)
  Branch (1340:13): [True: 45, False: 5.45k]
1341
            return NULL;
1342
        if (lz->start == 1)
  Branch (1342:13): [True: 5.33k, False: 121]
1343
            return item;
1344
1345
        good = PyObject_CallOneArg(lz->func, item);
1346
        if (good == NULL) {
  Branch (1346:13): [True: 2, False: 119]
1347
            Py_DECREF(item);
1348
            return NULL;
1349
        }
1350
        ok = PyObject_IsTrue(good);
1351
        Py_DECREF(good);
1352
        if (ok == 0) {
  Branch (1352:13): [True: 41, False: 78]
1353
            lz->start = 1;
1354
            return item;
1355
        }
1356
        Py_DECREF(item);
1357
        if (ok < 0)
  Branch (1357:13): [True: 0, False: 78]
1358
            return NULL;
1359
    }
1360
}
1361
1362
static PyObject *
1363
dropwhile_reduce(dropwhileobject *lz, PyObject *Py_UNUSED(ignored))
1364
{
1365
    return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->start);
1366
}
1367
1368
static PyObject *
1369
dropwhile_setstate(dropwhileobject *lz, PyObject *state)
1370
{
1371
    int start = PyObject_IsTrue(state);
1372
    if (start < 0)
  Branch (1372:9): [True: 0, False: 20]
1373
        return NULL;
1374
    lz->start = start;
1375
    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
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
    it = PyObject_GetIter(seq);
1458
    if (it == NULL)
  Branch (1458:9): [True: 10, False: 76]
1459
        return NULL;
1460
1461
    /* create takewhileobject structure */
1462
    lz = (takewhileobject *)type->tp_alloc(type, 0);
1463
    if (lz == NULL) {
  Branch (1463:9): [True: 0, False: 76]
1464
        Py_DECREF(it);
1465
        return NULL;
1466
    }
1467
    Py_INCREF(func);
1468
    lz->func = func;
1469
    lz->it = it;
1470
    lz->stop = 0;
1471
1472
    return (PyObject *)lz;
1473
}
1474
1475
static void
1476
takewhile_dealloc(takewhileobject *lz)
1477
{
1478
    PyObject_GC_UnTrack(lz);
1479
    Py_XDECREF(lz->func);
1480
    Py_XDECREF(lz->it);
1481
    Py_TYPE(lz)->tp_free(lz);
1482
}
1483
1484
static int
1485
takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg)
1486
{
1487
    Py_VISIT(lz->it);
1488
    Py_VISIT(lz->func);
1489
    return 0;
1490
}
1491
1492
static PyObject *
1493
takewhile_next(takewhileobject *lz)
1494
{
1495
    PyObject *item, *good;
1496
    PyObject *it = lz->it;
1497
    long ok;
1498
1499
    if (lz->stop == 1)
  Branch (1499:9): [True: 1, False: 173]
1500
        return NULL;
1501
1502
    item = (*Py_TYPE(it)->tp_iternext)(it);
1503
    if (item == NULL)
  Branch (1503:9): [True: 18, False: 155]
1504
        return NULL;
1505
1506
    good = PyObject_CallOneArg(lz->func, item);
1507
    if (good == NULL) {
  Branch (1507:9): [True: 2, False: 153]
1508
        Py_DECREF(item);
1509
        return NULL;
1510
    }
1511
    ok = PyObject_IsTrue(good);
1512
    Py_DECREF(good);
1513
    if (ok > 0)
  Branch (1513:9): [True: 100, False: 53]
1514
        return item;
1515
    Py_DECREF(item);
1516
    if (ok == 0)
  Branch (1516:9): [True: 53, False: 0]
1517
        lz->stop = 1;
1518
    return NULL;
1519
}
1520
1521
static PyObject *
1522
takewhile_reduce(takewhileobject *lz, PyObject *Py_UNUSED(ignored))
1523
{
1524
    return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->stop);
1525
}
1526
1527
static PyObject *
1528
takewhile_reduce_setstate(takewhileobject *lz, PyObject *state)
1529
{
1530
    int stop = PyObject_IsTrue(state);
1531
1532
    if (stop < 0)
  Branch (1532:9): [True: 0, False: 20]
1533
        return NULL;
1534
    lz->stop = stop;
1535
    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
islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1606
{
1607
    PyObject *seq;
1608
    Py_ssize_t start=0, stop=-1, step=1;
1609
    PyObject *it, *a1=NULL, *a2=NULL, *a3=NULL;
1610
    Py_ssize_t numargs;
1611
    isliceobject *lz;
1612
1613
    if ((type == &islice_type || 
type->tp_init == islice_type.tp_init4
) &&
  Branch (1613:10): [True: 176k, False: 4]
  Branch (1613:34): [True: 3, False: 1]
1614
        
!176k
_PyArg_NoKeywords176k
("islice", kwds))
1615
        return NULL;
1616
1617
    if (!PyArg_UnpackTuple(args, "islice", 2, 4, &seq, &a1, &a2, &a3))
  Branch (1617:9): [True: 2, False: 176k]
1618
        return NULL;
1619
1620
    numargs = PyTuple_Size(args);
1621
    if (numargs == 2) {
  Branch (1621:9): [True: 150k, False: 26.3k]
1622
        if (a1 != Py_None) {
  Branch (1622:13): [True: 150k, False: 108]
1623
            stop = PyNumber_AsSsize_t(a1, PyExc_OverflowError);
1624
            if (stop == -1) {
  Branch (1624:17): [True: 1, False: 150k]
1625
                if (PyErr_Occurred())
  Branch (1625:21): [True: 1, False: 0]
1626
                    PyErr_Clear();
1627
                PyErr_SetString(PyExc_ValueError,
1628
                   "Stop argument for islice() must be None or "
1629
                   "an integer: 0 <= x <= sys.maxsize.");
1630
                return NULL;
1631
            }
1632
        }
1633
    } else {
1634
        if (a1 != Py_None)
  Branch (1634:13): [True: 26.3k, False: 2]
1635
            start = PyNumber_AsSsize_t(a1, PyExc_OverflowError);
1636
        if (start == -1 && 
PyErr_Occurred()2
)
  Branch (1636:13): [True: 2, False: 26.3k]
  Branch (1636:28): [True: 2, False: 0]
1637
            PyErr_Clear();
1638
        if (a2 != Py_None) {
  Branch (1638:13): [True: 182, False: 26.1k]
1639
            stop = PyNumber_AsSsize_t(a2, PyExc_OverflowError);
1640
            if (stop == -1) {
  Branch (1640:17): [True: 2, False: 180]
1641
                if (PyErr_Occurred())
  Branch (1641:21): [True: 2, False: 0]
1642
                    PyErr_Clear();
1643
                PyErr_SetString(PyExc_ValueError,
1644
                   "Stop argument for islice() must be None or "
1645
                   "an integer: 0 <= x <= sys.maxsize.");
1646
                return NULL;
1647
            }
1648
        }
1649
    }
1650
    if (start<0 || 
stop<-1176k
) {
  Branch (1650:9): [True: 3, False: 176k]
  Branch (1650:20): [True: 1, False: 176k]
1651
        PyErr_SetString(PyExc_ValueError,
1652
           "Indices for islice() must be None or "
1653
           "an integer: 0 <= x <= sys.maxsize.");
1654
        return NULL;
1655
    }
1656
1657
    if (a3 != NULL) {
  Branch (1657:9): [True: 213, False: 176k]
1658
        if (a3 != Py_None)
  Branch (1658:13): [True: 212, False: 1]
1659
            step = PyNumber_AsSsize_t(a3, PyExc_OverflowError);
1660
        if (step == -1 && 
PyErr_Occurred()1
)
  Branch (1660:13): [True: 1, False: 212]
  Branch (1660:27): [True: 0, False: 1]
1661
            PyErr_Clear();
1662
    }
1663
    if (step<1) {
  Branch (1663:9): [True: 2, False: 176k]
1664
        PyErr_SetString(PyExc_ValueError,
1665
           "Step for islice() must be a positive integer or None.");
1666
        return NULL;
1667
    }
1668
1669
    /* Get iterator. */
1670
    it = PyObject_GetIter(seq);
1671
    if (it == NULL)
  Branch (1671:9): [True: 23.0k, False: 153k]
1672
        return NULL;
1673
1674
    /* create isliceobject structure */
1675
    lz = (isliceobject *)type->tp_alloc(type, 0);
1676
    if (lz == NULL) {
  Branch (1676:9): [True: 0, False: 153k]
1677
        Py_DECREF(it);
1678
        return NULL;
1679
    }
1680
    lz->it = it;
1681
    lz->next = start;
1682
    lz->stop = stop;
1683
    lz->step = step;
1684
    lz->cnt = 0L;
1685
1686
    return (PyObject *)lz;
1687
}
1688
1689
static void
1690
islice_dealloc(isliceobject *lz)
1691
{
1692
    PyObject_GC_UnTrack(lz);
1693
    Py_XDECREF(lz->it);
1694
    Py_TYPE(lz)->tp_free(lz);
1695
}
1696
1697
static int
1698
islice_traverse(isliceobject *lz, visitproc visit, void *arg)
1699
{
1700
    Py_VISIT(lz->it);
1701
    return 0;
1702
}
1703
1704
static PyObject *
1705
islice_next(isliceobject *lz)
1706
{
1707
    PyObject *item;
1708
    PyObject *it = lz->it;
1709
    Py_ssize_t stop = lz->stop;
1710
    Py_ssize_t oldnext;
1711
    PyObject *(*iternext)(PyObject *);
1712
1713
    if (it == NULL)
  Branch (1713:9): [True: 12, False: 9.23M]
1714
        return NULL;
1715
1716
    iternext = *Py_TYPE(it)->tp_iternext;
1717
    while (lz->cnt < lz->next) {
  Branch (1717:12): [True: 544k, False: 9.23M]
1718
        item = iternext(it);
1719
        if (item == NULL)
  Branch (1719:13): [True: 61, False: 543k]
1720
            goto empty;
1721
        Py_DECREF(item);
1722
        lz->cnt++;
1723
    }
1724
    if (stop != -1 && 
lz->cnt >= stop8.91M
)
  Branch (1724:9): [True: 8.91M, False: 319k]
  Branch (1724:23): [True: 38.3k, False: 8.87M]
1725
        goto empty;
1726
    item = iternext(it);
1727
    if (item == NULL)
  Branch (1727:9): [True: 108k, False: 9.08M]
1728
        goto empty;
1729
    lz->cnt++;
1730
    oldnext = lz->next;
1731
    /* The (size_t) cast below avoids the danger of undefined
1732
       behaviour from signed integer overflow. */
1733
    lz->next += (size_t)lz->step;
1734
    if (lz->next < oldnext || 
(9.08M
stop != -19.08M
&&
lz->next > stop8.78M
))
  Branch (1734:9): [True: 1, False: 9.08M]
  Branch (1734:32): [True: 8.78M, False: 299k]
  Branch (1734:46): [True: 28, False: 8.78M]
1735
        lz->next = stop;
1736
    return item;
1737
1738
empty:
1739
    Py_CLEAR(lz->it);
1740
    return NULL;
1741
}
1742
1743
static PyObject *
1744
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
    if (lz->it == NULL) {
  Branch (1751:9): [True: 12, False: 58]
1752
        PyObject *empty_list;
1753
        PyObject *empty_it;
1754
        empty_list = PyList_New(0);
1755
        if (empty_list == NULL)
  Branch (1755:13): [True: 0, False: 12]
1756
            return NULL;
1757
        empty_it = PyObject_GetIter(empty_list);
1758
        Py_DECREF(empty_list);
1759
        if (empty_it == NULL)
  Branch (1759:13): [True: 0, False: 12]
1760
            return NULL;
1761
        return Py_BuildValue("O(Nn)n", Py_TYPE(lz), empty_it, 0, 0);
1762
    }
1763
    if (lz->stop == -1) {
  Branch (1763:9): [True: 0, False: 58]
1764
        stop = Py_None;
1765
        Py_INCREF(stop);
1766
    } else {
1767
        stop = PyLong_FromSsize_t(lz->stop);
1768
        if (stop == NULL)
  Branch (1768:13): [True: 0, False: 58]
1769
            return NULL;
1770
    }
1771
    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
islice_setstate(isliceobject *lz, PyObject *state)
1778
{
1779
    Py_ssize_t cnt = PyLong_AsSsize_t(state);
1780
1781
    if (cnt == -1 && 
PyErr_Occurred()0
)
  Branch (1781:9): [True: 0, False: 100]
  Branch (1781:22): [True: 0, False: 0]
1782
        return NULL;
1783
    lz->cnt = cnt;
1784
    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
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
    it = PyObject_GetIter(seq);
1877
    if (it == NULL)
  Branch (1877:9): [True: 10, False: 9.00k]
1878
        return NULL;
1879
1880
    /* create starmapobject structure */
1881
    lz = (starmapobject *)type->tp_alloc(type, 0);
1882
    if (lz == NULL) {
  Branch (1882:9): [True: 0, False: 9.00k]
1883
        Py_DECREF(it);
1884
        return NULL;
1885
    }
1886
    Py_INCREF(func);
1887
    lz->func = func;
1888
    lz->it = it;
1889
1890
    return (PyObject *)lz;
1891
}
1892
1893
static void
1894
starmap_dealloc(starmapobject *lz)
1895
{
1896
    PyObject_GC_UnTrack(lz);
1897
    Py_XDECREF(lz->func);
1898
    Py_XDECREF(lz->it);
1899
    Py_TYPE(lz)->tp_free(lz);
1900
}
1901
1902
static int
1903
starmap_traverse(starmapobject *lz, visitproc visit, void *arg)
1904
{
1905
    Py_VISIT(lz->it);
1906
    Py_VISIT(lz->func);
1907
    return 0;
1908
}
1909
1910
static PyObject *
1911
starmap_next(starmapobject *lz)
1912
{
1913
    PyObject *args;
1914
    PyObject *result;
1915
    PyObject *it = lz->it;
1916
1917
    args = (*Py_TYPE(it)->tp_iternext)(it);
1918
    if (args == NULL)
  Branch (1918:9): [True: 8.99k, False: 25.3k]
1919
        return NULL;
1920
    if (!PyTuple_CheckExact(args)) {
  Branch (1920:9): [True: 26, False: 25.2k]
1921
        PyObject *newargs = PySequence_Tuple(args);
1922
        Py_DECREF(args);
1923
        if (newargs == NULL)
  Branch (1923:13): [True: 1, False: 25]
1924
            return NULL;
1925
        args = newargs;
1926
    }
1927
    result = PyObject_Call(lz->func, args, NULL);
1928
    Py_DECREF(args);
1929
    return result;
1930
}
1931
1932
static PyObject *
1933
starmap_reduce(starmapobject *lz, PyObject *Py_UNUSED(ignored))
1934
{
1935
    /* Just pickle the iterator */
1936
    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
chain_new_internal(PyTypeObject *type, PyObject *source)
2002
{
2003
    chainobject *lz;
2004
2005
    lz = (chainobject *)type->tp_alloc(type, 0);
2006
    if (lz == NULL) {
  Branch (2006:9): [True: 0, False: 31.2k]
2007
        Py_DECREF(source);
2008
        return NULL;
2009
    }
2010
2011
    lz->source = source;
2012
    lz->active = NULL;
2013
    return (PyObject *)lz;
2014
}
2015
2016
static PyObject *
2017
chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2018
{
2019
    PyObject *source;
2020
2021
    if ((type == &chain_type || 
type->tp_init == chain_type.tp_init4
) &&
  Branch (2021:10): [True: 21.6k, False: 4]
  Branch (2021:33): [True: 3, False: 1]
2022
        
!21.6k
_PyArg_NoKeywords21.6k
("chain", kwds))
2023
        return NULL;
2024
2025
    source = PyObject_GetIter(args);
2026
    if (source == NULL)
  Branch (2026:9): [True: 0, False: 21.6k]
2027
        return NULL;
2028
2029
    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
itertools_chain_from_iterable(PyTypeObject *type, PyObject *arg)
2042
/*[clinic end generated code: output=667ae7a7f7b68654 input=72c39e3a2ca3be85]*/
2043
{
2044
    PyObject *source;
2045
2046
    source = PyObject_GetIter(arg);
2047
    if (source == NULL)
  Branch (2047:9): [True: 0, False: 9.65k]
2048
        return NULL;
2049
2050
    return chain_new_internal(type, source);
2051
}
2052
2053
static void
2054
chain_dealloc(chainobject *lz)
2055
{
2056
    PyObject_GC_UnTrack(lz);
2057
    Py_XDECREF(lz->active);
2058
    Py_XDECREF(lz->source);
2059
    Py_TYPE(lz)->tp_free(lz);
2060
}
2061
2062
static int
2063
chain_traverse(chainobject *lz, visitproc visit, void *arg)
2064
{
2065
    Py_VISIT(lz->source);
2066
    Py_VISIT(lz->active);
2067
    return 0;
2068
}
2069
2070
static PyObject *
2071
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
    while (lz->source != NULL) {
  Branch (2078:12): [True: 11.0M, False: 5]
2079
        if (lz->active == NULL) {
  Branch (2079:13): [True: 10.1M, False: 900k]
2080
            PyObject *iterable = PyIter_Next(lz->source);
2081
            if (iterable == NULL) {
  Branch (2081:17): [True: 28.8k, False: 10.1M]
2082
                Py_CLEAR(lz->source);
2083
                return NULL;            /* no more input sources */
2084
            }
2085
            lz->active = PyObject_GetIter(iterable);
2086
            Py_DECREF(iterable);
2087
            if (lz->active == NULL) {
  Branch (2087:17): [True: 19, False: 10.1M]
2088
                Py_CLEAR(lz->source);
2089
                return NULL;            /* input not iterable */
2090
            }
2091
        }
2092
        item = (*Py_TYPE(lz->active)->tp_iternext)(lz->active);
2093
        if (item != NULL)
  Branch (2093:13): [True: 902k, False: 10.1M]
2094
            return item;
2095
        if (PyErr_Occurred()) {
  Branch (2095:13): [True: 40, False: 10.1M]
2096
            if (PyErr_ExceptionMatches(PyExc_StopIteration))
  Branch (2096:17): [True: 32, False: 8]
2097
                PyErr_Clear();
2098
            else
2099
                return NULL;            /* input raised an exception */
2100
        }
2101
        /* lz->active is consumed, try with the next iterable. */
2102
        Py_CLEAR(lz->active);
2103
    }
2104
    /* Everything had been consumed already. */
2105
    return NULL;
2106
}
2107
2108
static PyObject *
2109
chain_reduce(chainobject *lz, PyObject *Py_UNUSED(ignored))
2110
{
2111
    if (lz->source) {
  Branch (2111:9): [True: 66, False: 0]
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
        if (lz->active) {
  Branch (2116:13): [True: 19, False: 47]
2117
            return Py_BuildValue("O()(OO)", Py_TYPE(lz), lz->source, lz->active);
2118
        } else {
2119
            return Py_BuildValue("O()(O)", Py_TYPE(lz), lz->source);
2120
        }
2121
    } else {
2122
        return Py_BuildValue("O()", Py_TYPE(lz)); /* exhausted */
2123
    }
2124
    return NULL;
2125
}
2126
2127
static PyObject *
2128
chain_setstate(chainobject *lz, PyObject *state)
2129
{
2130
    PyObject *source, *active=NULL;
2131
2132
    if (!PyTuple_Check(state)) {
  Branch (2132:9): [True: 2, False: 83]
2133
        PyErr_SetString(PyExc_TypeError, "state is not a tuple");
2134
        return NULL;
2135
    }
2136
    if (!PyArg_ParseTuple(state, "O|O", &source, &active)) {
  Branch (2136:9): [True: 1, False: 82]
2137
        return NULL;
2138
    }
2139
    if (!PyIter_Check(source) || 
(81
active != NULL81
&&
!PyIter_Check(active)21
)) {
  Branch (2139:9): [True: 1, False: 81]
  Branch (2139:35): [True: 21, False: 60]
  Branch (2139:53): [True: 1, False: 20]
2140
        PyErr_SetString(PyExc_TypeError, "Arguments must be iterators.");
2141
        return NULL;
2142
    }
2143
2144
    Py_INCREF(source);
2145
    Py_XSETREF(lz->source, source);
2146
    Py_XINCREF(active);
2147
    Py_XSETREF(lz->active, active);
2148
    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
product_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2228
{
2229
    productobject *lz;
2230
    Py_ssize_t nargs, npools, repeat=1;
2231
    PyObject *pools = NULL;
2232
    Py_ssize_t *indices = NULL;
2233
    Py_ssize_t i;
2234
2235
    if (kwds != NULL) {
  Branch (2235:9): [True: 529, False: 23.1k]
2236
        char *kwlist[] = {"repeat", 0};
2237
        PyObject *tmpargs = PyTuple_New(0);
2238
        if (tmpargs == NULL)
  Branch (2238:13): [True: 0, False: 529]
2239
            return NULL;
2240
        if (!PyArg_ParseTupleAndKeywords(tmpargs, kwds, "|n:product",
  Branch (2240:13): [True: 1, False: 528]
2241
                                         kwlist, &repeat)) {
2242
            Py_DECREF(tmpargs);
2243
            return NULL;
2244
        }
2245
        Py_DECREF(tmpargs);
2246
        if (repeat < 0) {
  Branch (2246:13): [True: 0, False: 528]
2247
            PyErr_SetString(PyExc_ValueError,
2248
                            "repeat argument cannot be negative");
2249
            return NULL;
2250
        }
2251
    }
2252
2253
    assert(PyTuple_CheckExact(args));
2254
    if (repeat == 0) {
  Branch (2254:9): [True: 26, False: 23.6k]
2255
        nargs = 0;
2256
    } else {
2257
        nargs = PyTuple_GET_SIZE(args);
2258
        if ((size_t)nargs > PY_SSIZE_T_MAX/sizeof(Py_ssize_t)/repeat) {
  Branch (2258:13): [True: 0, False: 23.6k]
2259
            PyErr_SetString(PyExc_OverflowError, "repeat argument too large");
2260
            return NULL;
2261
        }
2262
    }
2263
    npools = nargs * repeat;
2264
2265
    indices = PyMem_New(Py_ssize_t, npools);
2266
    if (indices == NULL) {
  Branch (2266:9): [True: 0, False: 23.7k]
2267
        PyErr_NoMemory();
2268
        goto error;
2269
    }
2270
2271
    pools = PyTuple_New(npools);
2272
    if (pools == NULL)
  Branch (2272:9): [True: 0, False: 23.7k]
2273
        goto error;
2274
2275
    
for (i=0; 23.7k
i < nargs ;
++i37.0k
) {
  Branch (2275:15): [True: 37.0k, False: 23.6k]
2276
        PyObject *item = PyTuple_GET_ITEM(args, i);
2277
        PyObject *pool = PySequence_Tuple(item);
2278
        if (pool == NULL)
  Branch (2278:13): [True: 16, False: 37.0k]
2279
            goto error;
2280
        PyTuple_SET_ITEM(pools, i, pool);
2281
        indices[i] = 0;
2282
    }
2283
    
for ( ; 23.6k
i < npools;
++i991
) {
  Branch (2283:13): [True: 991, False: 23.6k]
2284
        PyObject *pool = PyTuple_GET_ITEM(pools, i - nargs);
2285
        Py_INCREF(pool);
2286
        PyTuple_SET_ITEM(pools, i, pool);
2287
        indices[i] = 0;
2288
    }
2289
2290
    /* create productobject structure */
2291
    lz = (productobject *)type->tp_alloc(type, 0);
2292
    if (lz == NULL)
  Branch (2292:9): [True: 0, False: 23.6k]
2293
        goto error;
2294
2295
    lz->pools = pools;
2296
    lz->indices = indices;
2297
    lz->result = NULL;
2298
    lz->stopped = 0;
2299
2300
    return (PyObject *)lz;
2301
2302
error:
2303
    if (indices != NULL)
  Branch (2303:9): [True: 16, False: 0]
2304
        PyMem_Free(indices);
2305
    Py_XDECREF(pools);
2306
    return NULL;
2307
}
2308
2309
static void
2310
product_dealloc(productobject *lz)
2311
{
2312
    PyObject_GC_UnTrack(lz);
2313
    Py_XDECREF(lz->pools);
2314
    Py_XDECREF(lz->result);
2315
    if (lz->indices != NULL)
  Branch (2315:9): [True: 23.6k, False: 0]
2316
        PyMem_Free(lz->indices);
2317
    Py_TYPE(lz)->tp_free(lz);
2318
}
2319
2320
static PyObject *
2321
product_sizeof(productobject *lz, void *unused)
2322
{
2323
    Py_ssize_t res;
2324
2325
    res = _PyObject_SIZE(Py_TYPE(lz));
2326
    res += PyTuple_GET_SIZE(lz->pools) * sizeof(Py_ssize_t);
2327
    return PyLong_FromSsize_t(res);
2328
}
2329
2330
PyDoc_STRVAR(sizeof_doc, "Returns size in memory, in bytes.");
2331
2332
static int
2333
product_traverse(productobject *lz, visitproc visit, void *arg)
2334
{
2335
    Py_VISIT(lz->pools);
2336
    Py_VISIT(lz->result);
2337
    return 0;
2338
}
2339
2340
static PyObject *
2341
product_next(productobject *lz)
2342
{
2343
    PyObject *pool;
2344
    PyObject *elem;
2345
    PyObject *oldelem;
2346
    PyObject *pools = lz->pools;
2347
    PyObject *result = lz->result;
2348
    Py_ssize_t npools = PyTuple_GET_SIZE(pools);
2349
    Py_ssize_t i;
2350
2351
    if (lz->stopped)
  Branch (2351:9): [True: 19, False: 1.43M]
2352
        return NULL;
2353
2354
    if (result == NULL) {
  Branch (2354:9): [True: 23.6k, False: 1.40M]
2355
        /* On the first pass, return an initial tuple filled with the
2356
           first element from each pool. */
2357
        result = PyTuple_New(npools);
2358
        if (result == NULL)
  Branch (2358:13): [True: 0, False: 23.6k]
2359
            goto empty;
2360
        lz->result = result;
2361
        for (i=0; i < npools; 
i++37.3k
) {
  Branch (2361:19): [True: 37.6k, False: 23.3k]
2362
            pool = PyTuple_GET_ITEM(pools, i);
2363
            if (PyTuple_GET_SIZE(pool) == 0)
  Branch (2363:17): [True: 272, False: 37.3k]
2364
                goto empty;
2365
            elem = PyTuple_GET_ITEM(pool, 0);
2366
            Py_INCREF(elem);
2367
            PyTuple_SET_ITEM(result, i, elem);
2368
        }
2369
    } else {
2370
        Py_ssize_t *indices = lz->indices;
2371
2372
        /* Copy the previous result tuple or re-use it if available */
2373
        if (Py_REFCNT(result) > 1) {
  Branch (2373:13): [True: 1.30M, False: 104k]
2374
            PyObject *old_result = result;
2375
            result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), npools);
2376
            if (result == NULL)
  Branch (2376:17): [True: 0, False: 1.30M]
2377
                goto empty;
2378
            lz->result = result;
2379
            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
        else if (!_PyObject_GC_IS_TRACKED(result)) {
  Branch (2383:18): [True: 2, False: 104k]
2384
            _PyObject_GC_TRACK(result);
2385
        }
2386
        /* Now, we've got the only copy so we can update it in-place */
2387
        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
        for (i=npools-1 ; i >= 0 ; 
i--278k
) {
  Branch (2391:27): [True: 1.66M, False: 22.8k]
2392
            pool = PyTuple_GET_ITEM(pools, i);
2393
            indices[i]++;
2394
            if (indices[i] == PyTuple_GET_SIZE(pool)) {
  Branch (2394:17): [True: 278k, False: 1.38M]
2395
                /* Roll-over and advance to next pool */
2396
                indices[i] = 0;
2397
                elem = PyTuple_GET_ITEM(pool, 0);
2398
                Py_INCREF(elem);
2399
                oldelem = PyTuple_GET_ITEM(result, i);
2400
                PyTuple_SET_ITEM(result, i, elem);
2401
                Py_DECREF(oldelem);
2402
            } else {
2403
                /* No rollover. Just increment and stop here. */
2404
                elem = PyTuple_GET_ITEM(pool, indices[i]);
2405
                Py_INCREF(elem);
2406
                oldelem = PyTuple_GET_ITEM(result, i);
2407
                PyTuple_SET_ITEM(result, i, elem);
2408
                Py_DECREF(oldelem);
2409
                break;
2410
            }
2411
        }
2412
2413
        /* If i is negative, then the indices have all rolled-over
2414
           and we're done. */
2415
        if (i < 0)
  Branch (2415:13): [True: 22.8k, False: 1.38M]
2416
            goto empty;
2417
    }
2418
2419
    Py_INCREF(result);
2420
    return result;
2421
2422
empty:
2423
    lz->stopped = 1;
2424
    return NULL;
2425
}
2426
2427
static PyObject *
2428
product_reduce(productobject *lz, PyObject *Py_UNUSED(ignored))
2429
{
2430
    if (lz->stopped) {
  Branch (2430:9): [True: 18, False: 66]
2431
        return Py_BuildValue("O(())", Py_TYPE(lz));
2432
    } else if (lz->result == NULL) {
  Branch (2432:16): [True: 48, False: 18]
2433
        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
        n = PyTuple_GET_SIZE(lz->pools);
2442
        indices = PyTuple_New(n);
2443
        if (indices == NULL)
  Branch (2443:13): [True: 0, False: 18]
2444
            return NULL;
2445
        
for (i=0; 18
i<n;
i++18
){
  Branch (2445:19): [True: 18, False: 18]
2446
            PyObject* index = PyLong_FromSsize_t(lz->indices[i]);
2447
            if (!index) {
  Branch (2447:17): [True: 0, False: 18]
2448
                Py_DECREF(indices);
2449
                return NULL;
2450
            }
2451
            PyTuple_SET_ITEM(indices, i, index);
2452
        }
2453
        return Py_BuildValue("OON", Py_TYPE(lz), lz->pools, indices);
2454
    }
2455
}
2456
2457
static PyObject *
2458
product_setstate(productobject *lz, PyObject *state)
2459
{
2460
    PyObject *result;
2461
    Py_ssize_t n, i;
2462
2463
    n = PyTuple_GET_SIZE(lz->pools);
2464
    if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != n) {
  Branch (2464:9): [True: 0, False: 20]
  Branch (2464:34): [True: 0, False: 20]
2465
        PyErr_SetString(PyExc_ValueError, "invalid arguments");
2466
        return NULL;
2467
    }
2468
    
for (i=0; 20
i<n;
i++21
)
  Branch (2468:15): [True: 22, False: 19]
2469
    {
2470
        PyObject* indexObject = PyTuple_GET_ITEM(state, i);
2471
        Py_ssize_t index = PyLong_AsSsize_t(indexObject);
2472
        PyObject* pool;
2473
        Py_ssize_t poolsize;
2474
        if (index < 0 && 
PyErr_Occurred()0
)
  Branch (2474:13): [True: 0, False: 22]
  Branch (2474:26): [True: 0, False: 0]
2475
            return NULL; /* not an integer */
2476
        pool = PyTuple_GET_ITEM(lz->pools, i);
2477
        poolsize = PyTuple_GET_SIZE(pool);
2478
        if (poolsize == 0) {
  Branch (2478:13): [True: 1, False: 21]
2479
            lz->stopped = 1;
2480
            Py_RETURN_NONE;
2481
        }
2482
        /* clamp the index */
2483
        if (index < 0)
  Branch (2483:13): [True: 0, False: 21]
2484
            index = 0;
2485
        else if (index > poolsize-1)
  Branch (2485:18): [True: 1, False: 20]
2486
            index = poolsize-1;
2487
        lz->indices[i] = index;
2488
    }
2489
2490
    result = PyTuple_New(n);
2491
    if (!result)
  Branch (2491:9): [True: 0, False: 19]
2492
        return NULL;
2493
    
for (i=0; 19
i<n;
i++20
) {
  Branch (2493:15): [True: 20, False: 19]
2494
        PyObject *pool = PyTuple_GET_ITEM(lz->pools, i);
2495
        PyObject *element = PyTuple_GET_ITEM(pool, lz->indices[i]);
2496
        Py_INCREF(element);
2497
        PyTuple_SET_ITEM(result, i, element);
2498
    }
2499
    Py_XSETREF(lz->result, result);
2500
    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
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
    PyObject *pool = NULL;
2602
    Py_ssize_t *indices = NULL;
2603
    Py_ssize_t i;
2604
2605
    pool = PySequence_Tuple(iterable);
2606
    if (pool == NULL)
  Branch (2606:9): [True: 0, False: 6.01k]
2607
        goto error;
2608
    n = PyTuple_GET_SIZE(pool);
2609
    if (r < 0) {
  Branch (2609:9): [True: 1, False: 6.01k]
2610
        PyErr_SetString(PyExc_ValueError, "r must be non-negative");
2611
        goto error;
2612
    }
2613
2614
    indices = PyMem_New(Py_ssize_t, r);
2615
    if (indices == NULL) {
  Branch (2615:9): [True: 0, False: 6.01k]
2616
        PyErr_NoMemory();
2617
        goto error;
2618
    }
2619
2620
    
for (i=0 ; 6.01k
i<r ;
i++17.5k
)
  Branch (2620:16): [True: 17.5k, False: 6.01k]
2621
        indices[i] = i;
2622
2623
    /* create combinationsobject structure */
2624
    co = (combinationsobject *)type->tp_alloc(type, 0);
2625
    if (co == NULL)
  Branch (2625:9): [True: 0, False: 6.01k]
2626
        goto error;
2627
2628
    co->pool = pool;
2629
    co->indices = indices;
2630
    co->result = NULL;
2631
    co->r = r;
2632
    co->stopped = r > n ? 
1222
:
05.78k
;
  Branch (2632:19): [True: 222, False: 5.78k]
2633
2634
    return (PyObject *)co;
2635
2636
error:
2637
    if (indices != NULL)
  Branch (2637:9): [True: 0, False: 1]
2638
        PyMem_Free(indices);
2639
    Py_XDECREF(pool);
2640
    return NULL;
2641
}
2642
2643
static void
2644
combinations_dealloc(combinationsobject *co)
2645
{
2646
    PyObject_GC_UnTrack(co);
2647
    Py_XDECREF(co->pool);
2648
    Py_XDECREF(co->result);
2649
    if (co->indices != NULL)
  Branch (2649:9): [True: 6.01k, False: 0]
2650
        PyMem_Free(co->indices);
2651
    Py_TYPE(co)->tp_free(co);
2652
}
2653
2654
static PyObject *
2655
combinations_sizeof(combinationsobject *co, void *unused)
2656
{
2657
    Py_ssize_t res;
2658
2659
    res = _PyObject_SIZE(Py_TYPE(co));
2660
    res += co->r * sizeof(Py_ssize_t);
2661
    return PyLong_FromSsize_t(res);
2662
}
2663
2664
static int
2665
combinations_traverse(combinationsobject *co, visitproc visit, void *arg)
2666
{
2667
    Py_VISIT(co->pool);
2668
    Py_VISIT(co->result);
2669
    return 0;
2670
}
2671
2672
static PyObject *
2673
combinations_next(combinationsobject *co)
2674
{
2675
    PyObject *elem;
2676
    PyObject *oldelem;
2677
    PyObject *pool = co->pool;
2678
    Py_ssize_t *indices = co->indices;
2679
    PyObject *result = co->result;
2680
    Py_ssize_t n = PyTuple_GET_SIZE(pool);
2681
    Py_ssize_t r = co->r;
2682
    Py_ssize_t i, j, index;
2683
2684
    if (co->stopped)
  Branch (2684:9): [True: 258, False: 1.07M]
2685
        return NULL;
2686
2687
    if (result == NULL) {
  Branch (2687:9): [True: 5.59k, False: 1.07M]
2688
        /* On the first pass, initialize result tuple using the indices */
2689
        result = PyTuple_New(r);
2690
        if (result == NULL)
  Branch (2690:13): [True: 0, False: 5.59k]
2691
            goto empty;
2692
        co->result = result;
2693
        for (i=0; i<r ; 
i++15.8k
) {
  Branch (2693:19): [True: 15.8k, False: 5.59k]
2694
            index = indices[i];
2695
            elem = PyTuple_GET_ITEM(pool, index);
2696
            Py_INCREF(elem);
2697
            PyTuple_SET_ITEM(result, i, elem);
2698
        }
2699
    } else {
2700
        /* Copy the previous result tuple or re-use it if available */
2701
        if (Py_REFCNT(result) > 1) {
  Branch (2701:13): [True: 24.7k, False: 1.04M]
2702
            PyObject *old_result = result;
2703
            result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r);
2704
            if (result == NULL)
  Branch (2704:17): [True: 0, False: 24.7k]
2705
                goto empty;
2706
            co->result = result;
2707
            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
        else if (!_PyObject_GC_IS_TRACKED(result)) {
  Branch (2711:18): [True: 1, False: 1.04M]
2712
            _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
        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
        for (i=r-1 ; i >= 0 && 
indices[i] == i+n-r2.14M
;
i--1.07M
)
  Branch (2722:22): [True: 2.14M, False: 5.49k]
  Branch (2722:32): [True: 1.07M, False: 1.06M]
2723
            ;
2724
2725
        /* If i is negative, then the indices are all at
2726
           their maximum value and we're done. */
2727
        if (i < 0)
  Branch (2727:13): [True: 5.49k, False: 1.06M]
2728
            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
        indices[i]++;
2735
        for (j=i+1 ; j<r ; 
j++1.05M
)
  Branch (2735:22): [True: 1.05M, False: 1.06M]
2736
            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
        for ( ; i<r ; 
i++2.12M
) {
  Branch (2740:17): [True: 2.12M, False: 1.06M]
2741
            index = indices[i];
2742
            elem = PyTuple_GET_ITEM(pool, index);
2743
            Py_INCREF(elem);
2744
            oldelem = PyTuple_GET_ITEM(result, i);
2745
            PyTuple_SET_ITEM(result, i, elem);
2746
            Py_DECREF(oldelem);
2747
        }
2748
    }
2749
2750
    Py_INCREF(result);
2751
    return result;
2752
2753
empty:
2754
    co->stopped = 1;
2755
    return NULL;
2756
}
2757
2758
static PyObject *
2759
combinations_reduce(combinationsobject *lz, PyObject *Py_UNUSED(ignored))
2760
{
2761
    if (lz->result == NULL) {
  Branch (2761:9): [True: 270, False: 180]
2762
        return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r);
2763
    } else 
if (180
lz->stopped180
) {
  Branch (2763:16): [True: 0, False: 180]
2764
        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
        indices = PyTuple_New(lz->r);
2771
        if (!indices)
  Branch (2771:13): [True: 0, False: 180]
2772
            return NULL;
2773
        
for (i=0; 180
i<lz->r;
i++366
)
  Branch (2773:19): [True: 366, False: 180]
2774
        {
2775
            PyObject* index = PyLong_FromSsize_t(lz->indices[i]);
2776
            if (!index) {
  Branch (2776:17): [True: 0, False: 366]
2777
                Py_DECREF(indices);
2778
                return NULL;
2779
            }
2780
            PyTuple_SET_ITEM(indices, i, index);
2781
        }
2782
2783
        return Py_BuildValue("O(On)N", Py_TYPE(lz), lz->pool, lz->r, indices);
2784
    }
2785
}
2786
2787
static PyObject *
2788
combinations_setstate(combinationsobject *lz, PyObject *state)
2789
{
2790
    PyObject *result;
2791
    Py_ssize_t i;
2792
    Py_ssize_t n = PyTuple_GET_SIZE(lz->pool);
2793
2794
    if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r) {
  Branch (2794:9): [True: 0, False: 180]
  Branch (2794:34): [True: 0, False: 180]
2795
        PyErr_SetString(PyExc_ValueError, "invalid arguments");
2796
        return NULL;
2797
    }
2798
2799
    
for (i=0; 180
i<lz->r;
i++366
) {
  Branch (2799:15): [True: 366, False: 180]
2800
        Py_ssize_t max;
2801
        PyObject* indexObject = PyTuple_GET_ITEM(state, i);
2802
        Py_ssize_t index = PyLong_AsSsize_t(indexObject);
2803
2804
        if (index == -1 && 
PyErr_Occurred()0
)
  Branch (2804:13): [True: 0, False: 366]
  Branch (2804:28): [True: 0, False: 0]
2805
            return NULL; /* not an integer */
2806
        max = i + n - lz->r;
2807
        /* clamp the index (beware of negative max) */
2808
        if (index > max)
  Branch (2808:13): [True: 0, False: 366]
2809
            index = max;
2810
        if (index < 0)
  Branch (2810:13): [True: 0, False: 366]
2811
            index = 0;
2812
        lz->indices[i] = index;
2813
    }
2814
2815
    result = PyTuple_New(lz->r);
2816
    if (result == NULL)
  Branch (2816:9): [True: 0, False: 180]
2817
        return NULL;
2818
    
for (i=0; 180
i<lz->r;
i++366
) {
  Branch (2818:15): [True: 366, False: 180]
2819
        PyObject *element = PyTuple_GET_ITEM(lz->pool, lz->indices[i]);
2820
        Py_INCREF(element);
2821
        PyTuple_SET_ITEM(result, i, element);
2822
    }
2823
2824
    Py_XSETREF(lz->result, result);
2825
    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
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
    PyObject *pool = NULL;
2939
    Py_ssize_t *indices = NULL;
2940
    Py_ssize_t i;
2941
2942
    pool = PySequence_Tuple(iterable);
2943
    if (pool == NULL)
  Branch (2943:9): [True: 0, False: 992]
2944
        goto error;
2945
    n = PyTuple_GET_SIZE(pool);
2946
    if (r < 0) {
  Branch (2946:9): [True: 1, False: 991]
2947
        PyErr_SetString(PyExc_ValueError, "r must be non-negative");
2948
        goto error;
2949
    }
2950
2951
    indices = PyMem_New(Py_ssize_t, r);
2952
    if (indices == NULL) {
  Branch (2952:9): [True: 0, False: 991]
2953
        PyErr_NoMemory();
2954
        goto error;
2955
    }
2956
2957
    
for (i=0 ; 991
i<r ;
i++2.42k
)
  Branch (2957:16): [True: 2.42k, False: 991]
2958
        indices[i] = 0;
2959
2960
    /* create cwrobject structure */
2961
    co = (cwrobject *)type->tp_alloc(type, 0);
2962
    if (co == NULL)
  Branch (2962:9): [True: 0, False: 991]
2963
        goto error;
2964
2965
    co->pool = pool;
2966
    co->indices = indices;
2967
    co->result = NULL;
2968
    co->r = r;
2969
    co->stopped = !n && 
r60
;
  Branch (2969:19): [True: 60, False: 931]
  Branch (2969:25): [True: 33, False: 27]
2970
2971
    return (PyObject *)co;
2972
2973
error:
2974
    if (indices != NULL)
  Branch (2974:9): [True: 0, False: 1]
2975
        PyMem_Free(indices);
2976
    Py_XDECREF(pool);
2977
    return NULL;
2978
}
2979
2980
static void
2981
cwr_dealloc(cwrobject *co)
2982
{
2983
    PyObject_GC_UnTrack(co);
2984
    Py_XDECREF(co->pool);
2985
    Py_XDECREF(co->result);
2986
    if (co->indices != NULL)
  Branch (2986:9): [True: 991, False: 0]
2987
        PyMem_Free(co->indices);
2988
    Py_TYPE(co)->tp_free(co);
2989
}
2990
2991
static PyObject *
2992
cwr_sizeof(cwrobject *co, void *unused)
2993
{
2994
    Py_ssize_t res;
2995
2996
    res = _PyObject_SIZE(Py_TYPE(co));
2997
    res += co->r * sizeof(Py_ssize_t);
2998
    return PyLong_FromSsize_t(res);
2999
}
3000
3001
static int
3002
cwr_traverse(cwrobject *co, visitproc visit, void *arg)
3003
{
3004
    Py_VISIT(co->pool);
3005
    Py_VISIT(co->result);
3006
    return 0;
3007
}
3008
3009
static PyObject *
3010
cwr_next(cwrobject *co)
3011
{
3012
    PyObject *elem;
3013
    PyObject *oldelem;
3014
    PyObject *pool = co->pool;
3015
    Py_ssize_t *indices = co->indices;
3016
    PyObject *result = co->result;
3017
    Py_ssize_t n = PyTuple_GET_SIZE(pool);
3018
    Py_ssize_t r = co->r;
3019
    Py_ssize_t i, index;
3020
3021
    if (co->stopped)
  Branch (3021:9): [True: 39, False: 9.15k]
3022
        return NULL;
3023
3024
    if (result == NULL) {
  Branch (3024:9): [True: 740, False: 8.41k]
3025
        /* On the first pass, initialize result tuple with pool[0] */
3026
        result = PyTuple_New(r);
3027
        if (result == NULL)
  Branch (3027:13): [True: 0, False: 740]
3028
            goto empty;
3029
        co->result = result;
3030
        if (n > 0) {
  Branch (3030:13): [True: 719, False: 21]
3031
            elem = PyTuple_GET_ITEM(pool, 0);
3032
            for (i=0; i<r ; 
i++1.84k
) {
  Branch (3032:23): [True: 1.84k, False: 719]
3033
                assert(indices[i] == 0);
3034
                Py_INCREF(elem);
3035
                PyTuple_SET_ITEM(result, i, elem);
3036
            }
3037
        }
3038
    } else {
3039
        /* Copy the previous result tuple or re-use it if available */
3040
        if (Py_REFCNT(result) > 1) {
  Branch (3040:13): [True: 8.04k, False: 367]
3041
            PyObject *old_result = result;
3042
            result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r);
3043
            if (result == NULL)
  Branch (3043:17): [True: 0, False: 8.04k]
3044
                goto empty;
3045
            co->result = result;
3046
            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
        else if (!_PyObject_GC_IS_TRACKED(result)) {
  Branch (3050:18): [True: 1, False: 366]
3051
            _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
        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
        for (i=r-1 ; i >= 0 && 
indices[i] == n-114.9k
;
i--6.94k
)
  Branch (3059:22): [True: 14.9k, False: 438]
  Branch (3059:32): [True: 6.94k, False: 7.97k]
3060
            ;
3061
3062
        /* If i is negative, then the indices are all at
3063
           their maximum value and we're done. */
3064
        if (i < 0)
  Branch (3064:13): [True: 438, False: 7.97k]
3065
            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
        index = indices[i] + 1;
3070
        assert(index < n);
3071
        elem = PyTuple_GET_ITEM(pool, index);
3072
        for ( ; i<r ; 
i++14.3k
) {
  Branch (3072:17): [True: 14.3k, False: 7.97k]
3073
            indices[i] = index;
3074
            Py_INCREF(elem);
3075
            oldelem = PyTuple_GET_ITEM(result, i);
3076
            PyTuple_SET_ITEM(result, i, elem);
3077
            Py_DECREF(oldelem);
3078
        }
3079
    }
3080
3081
    Py_INCREF(result);
3082
    return result;
3083
3084
empty:
3085
    co->stopped = 1;
3086
    return NULL;
3087
}
3088
3089
static PyObject *
3090
cwr_reduce(cwrobject *lz, PyObject *Py_UNUSED(ignored))
3091
{
3092
    if (lz->result == NULL) {
  Branch (3092:9): [True: 222, False: 210]
3093
        return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r);
3094
    } else 
if (210
lz->stopped210
) {
  Branch (3094:16): [True: 0, False: 210]
3095
        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
        indices = PyTuple_New(lz->r);
3102
        if (!indices)
  Branch (3102:13): [True: 0, False: 210]
3103
            return NULL;
3104
        
for (i=0; 210
i<lz->r;
i++510
) {
  Branch (3104:19): [True: 510, False: 210]
3105
            PyObject* index = PyLong_FromSsize_t(lz->indices[i]);
3106
            if (!index) {
  Branch (3106:17): [True: 0, False: 510]
3107
                Py_DECREF(indices);
3108
                return NULL;
3109
            }
3110
            PyTuple_SET_ITEM(indices, i, index);
3111
        }
3112
3113
        return Py_BuildValue("O(On)N", Py_TYPE(lz), lz->pool, lz->r, indices);
3114
    }
3115
}
3116
3117
static PyObject *
3118
cwr_setstate(cwrobject *lz, PyObject *state)
3119
{
3120
    PyObject *result;
3121
    Py_ssize_t n, i;
3122
3123
    if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r)
  Branch (3123:9): [True: 0, False: 210]
  Branch (3123:34): [True: 0, False: 210]
3124
    {
3125
        PyErr_SetString(PyExc_ValueError, "invalid arguments");
3126
        return NULL;
3127
    }
3128
3129
    n = PyTuple_GET_SIZE(lz->pool);
3130
    for (i=0; i<lz->r; 
i++510
) {
  Branch (3130:15): [True: 510, False: 210]
3131
        PyObject* indexObject = PyTuple_GET_ITEM(state, i);
3132
        Py_ssize_t index = PyLong_AsSsize_t(indexObject);
3133
3134
        if (index < 0 && 
PyErr_Occurred()0
)
  Branch (3134:13): [True: 0, False: 510]
  Branch (3134:26): [True: 0, False: 0]
3135
            return NULL; /* not an integer */
3136
        /* clamp the index */
3137
        if (index < 0)
  Branch (3137:13): [True: 0, False: 510]
3138
            index = 0;
3139
        else if (index > n-1)
  Branch (3139:18): [True: 0, False: 510]
3140
            index = n-1;
3141
        lz->indices[i] = index;
3142
    }
3143
    result = PyTuple_New(lz->r);
3144
    if (result == NULL)
  Branch (3144:9): [True: 0, False: 210]
3145
        return NULL;
3146
    
for (i=0; 210
i<lz->r;
i++510
) {
  Branch (3146:15): [True: 510, False: 210]
3147
        PyObject *element = PyTuple_GET_ITEM(lz->pool, lz->indices[i]);
3148
        Py_INCREF(element);
3149
        PyTuple_SET_ITEM(result, i, element);
3150
    }
3151
    Py_XSETREF(lz->result, result);
3152
    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
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
    PyObject *pool = NULL;
3267
    Py_ssize_t *indices = NULL;
3268
    Py_ssize_t *cycles = NULL;
3269
    Py_ssize_t i;
3270
3271
    pool = PySequence_Tuple(iterable);
3272
    if (pool == NULL)
  Branch (3272:9): [True: 1, False: 1.32k]
3273
        goto error;
3274
    n = PyTuple_GET_SIZE(pool);
3275
3276
    r = n;
3277
    if (robj != Py_None) {
  Branch (3277:9): [True: 973, False: 347]
3278
        if (!PyLong_Check(robj)) {
  Branch (3278:13): [True: 1, False: 972]
3279
            PyErr_SetString(PyExc_TypeError, "Expected int as r");
3280
            goto error;
3281
        }
3282
        r = PyLong_AsSsize_t(robj);
3283
        if (r == -1 && 
PyErr_Occurred()0
)
  Branch (3283:13): [True: 0, False: 972]
  Branch (3283:24): [True: 0, False: 0]
3284
            goto error;
3285
    }
3286
    if (r < 0) {
  Branch (3286:9): [True: 1, False: 1.31k]
3287
        PyErr_SetString(PyExc_ValueError, "r must be non-negative");
3288
        goto error;
3289
    }
3290
3291
    indices = PyMem_New(Py_ssize_t, n);
3292
    cycles = PyMem_New(Py_ssize_t, r);
3293
    if (indices == NULL || cycles == NULL) {
  Branch (3293:9): [True: 0, False: 1.31k]
  Branch (3293:28): [True: 0, False: 1.31k]
3294
        PyErr_NoMemory();
3295
        goto error;
3296
    }
3297
3298
    
for (i=0 ; 1.31k
i<n ;
i++4.13k
)
  Branch (3298:16): [True: 4.13k, False: 1.31k]
3299
        indices[i] = i;
3300
    for (i=0 ; i<r ; 
i++2.92k
)
  Branch (3300:16): [True: 2.92k, False: 1.31k]
3301
        cycles[i] = n - i;
3302
3303
    /* create permutationsobject structure */
3304
    po = (permutationsobject *)type->tp_alloc(type, 0);
3305
    if (po == NULL)
  Branch (3305:9): [True: 0, False: 1.31k]
3306
        goto error;
3307
3308
    po->pool = pool;
3309
    po->indices = indices;
3310
    po->cycles = cycles;
3311
    po->result = NULL;
3312
    po->r = r;
3313
    po->stopped = r > n ? 
1210
:
01.10k
;
  Branch (3313:19): [True: 210, False: 1.10k]
3314
3315
    return (PyObject *)po;
3316
3317
error:
3318
    if (indices != NULL)
  Branch (3318:9): [True: 0, False: 3]
3319
        PyMem_Free(indices);
3320
    if (cycles != NULL)
  Branch (3320:9): [True: 0, False: 3]
3321
        PyMem_Free(cycles);
3322
    Py_XDECREF(pool);
3323
    return NULL;
3324
}
3325
3326
static void
3327
permutations_dealloc(permutationsobject *po)
3328
{
3329
    PyObject_GC_UnTrack(po);
3330
    Py_XDECREF(po->pool);
3331
    Py_XDECREF(po->result);
3332
    PyMem_Free(po->indices);
3333
    PyMem_Free(po->cycles);
3334
    Py_TYPE(po)->tp_free(po);
3335
}
3336
3337
static PyObject *
3338
permutations_sizeof(permutationsobject *po, void *unused)
3339
{
3340
    Py_ssize_t res;
3341
3342
    res = _PyObject_SIZE(Py_TYPE(po));
3343
    res += PyTuple_GET_SIZE(po->pool) * sizeof(Py_ssize_t);
3344
    res += po->r * sizeof(Py_ssize_t);
3345
    return PyLong_FromSsize_t(res);
3346
}
3347
3348
static int
3349
permutations_traverse(permutationsobject *po, visitproc visit, void *arg)
3350
{
3351
    Py_VISIT(po->pool);
3352
    Py_VISIT(po->result);
3353
    return 0;
3354
}
3355
3356
static PyObject *
3357
permutations_next(permutationsobject *po)
3358
{
3359
    PyObject *elem;
3360
    PyObject *oldelem;
3361
    PyObject *pool = po->pool;
3362
    Py_ssize_t *indices = po->indices;
3363
    Py_ssize_t *cycles = po->cycles;
3364
    PyObject *result = po->result;
3365
    Py_ssize_t n = PyTuple_GET_SIZE(pool);
3366
    Py_ssize_t r = po->r;
3367
    Py_ssize_t i, j, k, index;
3368
3369
    if (po->stopped)
  Branch (3369:9): [True: 252, False: 10.4k]
3370
        return NULL;
3371
3372
    if (result == NULL) {
  Branch (3372:9): [True: 936, False: 9.49k]
3373
        /* On the first pass, initialize result tuple using the indices */
3374
        result = PyTuple_New(r);
3375
        if (result == NULL)
  Branch (3375:13): [True: 0, False: 936]
3376
            goto empty;
3377
        po->result = result;
3378
        for (i=0; i<r ; 
i++1.67k
) {
  Branch (3378:19): [True: 1.67k, False: 936]
3379
            index = indices[i];
3380
            elem = PyTuple_GET_ITEM(pool, index);
3381
            Py_INCREF(elem);
3382
            PyTuple_SET_ITEM(result, i, elem);
3383
        }
3384
    } else {
3385
        if (n == 0)
  Branch (3385:13): [True: 29, False: 9.46k]
3386
            goto empty;
3387
3388
        /* Copy the previous result tuple or re-use it if available */
3389
        if (Py_REFCNT(result) > 1) {
  Branch (3389:13): [True: 9.15k, False: 313]
3390
            PyObject *old_result = result;
3391
            result = _PyTuple_FromArray(_PyTuple_ITEMS(old_result), r);
3392
            if (result == NULL)
  Branch (3392:17): [True: 0, False: 9.15k]
3393
                goto empty;
3394
            po->result = result;
3395
            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
        else if (!_PyObject_GC_IS_TRACKED(result)) {
  Branch (3399:18): [True: 1, False: 312]
3400
            _PyObject_GC_TRACK(result);
3401
        }
3402
        /* Now, we've got the only copy so we can update it in-place */
3403
        assert(r == 0 || Py_REFCNT(result) == 1);
3404
3405
        /* Decrement rightmost cycle, moving leftward upon zero rollover */
3406
        for (i=r-1 ; i>=0 ; 
i--9.98k
) {
  Branch (3406:22): [True: 18.7k, False: 677]
3407
            cycles[i] -= 1;
3408
            if (cycles[i] == 0) {
  Branch (3408:17): [True: 9.98k, False: 8.79k]
3409
                /* rotatation: indices[i:] = indices[i+1:] + indices[i:i+1] */
3410
                index = indices[i];
3411
                for (j=i ; j<n-1 ; 
j++7.91k
)
  Branch (3411:28): [True: 7.91k, False: 9.98k]
3412
                    indices[j] = indices[j+1];
3413
                indices[n-1] = index;
3414
                cycles[i] = n - i;
3415
            } else {
3416
                j = cycles[i];
3417
                index = indices[i];
3418
                indices[i] = indices[n-j];
3419
                indices[n-j] = index;
3420
3421
                for (k=i; k<r ; 
k++17.9k
) {
  Branch (3421:27): [True: 17.9k, False: 8.79k]
3422
                    /* start with i, the leftmost element that changed */
3423
                    /* yield tuple(pool[k] for k in indices[:r]) */
3424
                    index = indices[k];
3425
                    elem = PyTuple_GET_ITEM(pool, index);
3426
                    Py_INCREF(elem);
3427
                    oldelem = PyTuple_GET_ITEM(result, k);
3428
                    PyTuple_SET_ITEM(result, k, elem);
3429
                    Py_DECREF(oldelem);
3430
                }
3431
                break;
3432
            }
3433
        }
3434
        /* If i is negative, then the cycles have all
3435
           rolled-over and we're done. */
3436
        if (i < 0)
  Branch (3436:13): [True: 677, False: 8.79k]
3437
            goto empty;
3438
    }
3439
    Py_INCREF(result);
3440
    return result;
3441
3442
empty:
3443
    po->stopped = 1;
3444
    return NULL;
3445
}
3446
3447
static PyObject *
3448
permutations_reduce(permutationsobject *po, PyObject *Py_UNUSED(ignored))
3449
{
3450
    if (po->result == NULL) {
  Branch (3450:9): [True: 252, False: 168]
3451
        return Py_BuildValue("O(On)", Py_TYPE(po), po->pool, po->r);
3452
    } else 
if (168
po->stopped168
) {
  Branch (3452:16): [True: 0, False: 168]
3453
        return Py_BuildValue("O(()n)", Py_TYPE(po), po->r);
3454
    } else {
3455
        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
        n = PyTuple_GET_SIZE(po->pool);
3460
        indices = PyTuple_New(n);
3461
        if (indices == NULL)
  Branch (3461:13): [True: 0, False: 168]
3462
            goto err;
3463
        
for (i=0; 168
i<n;
i++672
) {
  Branch (3463:19): [True: 672, False: 168]
3464
            PyObject* index = PyLong_FromSsize_t(po->indices[i]);
3465
            if (!index)
  Branch (3465:17): [True: 0, False: 672]
3466
                goto err;
3467
            PyTuple_SET_ITEM(indices, i, index);
3468
        }
3469
3470
        cycles = PyTuple_New(po->r);
3471
        if (cycles == NULL)
  Branch (3471:13): [True: 0, False: 168]
3472
            goto err;
3473
        
for (i=0 ; 168
i<po->r ;
i++336
) {
  Branch (3473:20): [True: 336, False: 168]
3474
            PyObject* index = PyLong_FromSsize_t(po->cycles[i]);
3475
            if (!index)
  Branch (3475:17): [True: 0, False: 336]
3476
                goto err;
3477
            PyTuple_SET_ITEM(cycles, i, index);
3478
        }
3479
        return Py_BuildValue("O(On)(NN)", Py_TYPE(po),
3480
                             po->pool, po->r,
3481
                             indices, cycles);
3482
    err:
3483
        Py_XDECREF(indices);
3484
        Py_XDECREF(cycles);
3485
        return NULL;
3486
    }
3487
}
3488
3489
static PyObject *
3490
permutations_setstate(permutationsobject *po, PyObject *state)
3491
{
3492
    PyObject *indices, *cycles, *result;
3493
    Py_ssize_t n, i;
3494
3495
    if (!PyTuple_Check(state)) {
  Branch (3495:9): [True: 0, False: 168]
3496
        PyErr_SetString(PyExc_TypeError, "state is not a tuple");
3497
        return NULL;
3498
    }
3499
    if (!PyArg_ParseTuple(state, "O!O!",
  Branch (3499:9): [True: 0, False: 168]
3500
                          &PyTuple_Type, &indices,
3501
                          &PyTuple_Type, &cycles)) {
3502
        return NULL;
3503
    }
3504
3505
    n = PyTuple_GET_SIZE(po->pool);
3506
    if (PyTuple_GET_SIZE(indices) != n || PyTuple_GET_SIZE(cycles) != po->r) {
  Branch (3506:9): [True: 0, False: 168]
  Branch (3506:43): [True: 0, False: 168]
3507
        PyErr_SetString(PyExc_ValueError, "invalid arguments");
3508
        return NULL;
3509
    }
3510
3511
    
for (i=0; 168
i<n;
i++672
) {
  Branch (3511:15): [True: 672, False: 168]
3512
        PyObject* indexObject = PyTuple_GET_ITEM(indices, i);
3513
        Py_ssize_t index = PyLong_AsSsize_t(indexObject);
3514
        if (index < 0 && 
PyErr_Occurred()0
)
  Branch (3514:13): [True: 0, False: 672]
  Branch (3514:26): [True: 0, False: 0]
3515
            return NULL; /* not an integer */
3516
        /* clamp the index */
3517
        if (index < 0)
  Branch (3517:13): [True: 0, False: 672]
3518
            index = 0;
3519
        else if (index > n-1)
  Branch (3519:18): [True: 0, False: 672]
3520
            index = n-1;
3521
        po->indices[i] = index;
3522
    }
3523
3524
    
for (i=0; 168
i<po->r;
i++336
) {
  Branch (3524:15): [True: 336, False: 168]
3525
        PyObject* indexObject = PyTuple_GET_ITEM(cycles, i);
3526
        Py_ssize_t index = PyLong_AsSsize_t(indexObject);
3527
        if (index < 0 && 
PyErr_Occurred()0
)
  Branch (3527:13): [True: 0, False: 336]
  Branch (3527:26): [True: 0, False: 0]
3528
            return NULL; /* not an integer */
3529
        if (index < 1)
  Branch (3529:13): [True: 0, False: 336]
3530
            index = 1;
3531
        else if (index > n-i)
  Branch (3531:18): [True: 0, False: 336]
3532
            index = n-i;
3533
        po->cycles[i] = index;
3534
    }
3535
    result = PyTuple_New(po->r);
3536
    if (result == NULL)
  Branch (3536:9): [True: 0, False: 168]
3537
        return NULL;
3538
    
for (i=0; 168
i<po->r;
i++336
) {
  Branch (3538:15): [True: 336, False: 168]
3539
        PyObject *element = PyTuple_GET_ITEM(po->pool, po->indices[i]);
3540
        Py_INCREF(element);
3541
        PyTuple_SET_ITEM(result, i, element);
3542
    }
3543
    Py_XSETREF(po->result, result);
3544
    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
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
    it = PyObject_GetIter(iterable);
3632
    if (it == NULL)
  Branch (3632:9): [True: 6, False: 176]
3633
        return NULL;
3634
3635
    /* create accumulateobject structure */
3636
    lz = (accumulateobject *)type->tp_alloc(type, 0);
3637
    if (lz == NULL) {
  Branch (3637:9): [True: 0, False: 176]
3638
        Py_DECREF(it);
3639
        return NULL;
3640
    }
3641
3642
    if (binop != Py_None) {
  Branch (3642:9): [True: 21, False: 155]
3643
        Py_XINCREF(binop);
3644
        lz->binop = binop;
3645
    }
3646
    lz->total = NULL;
3647
    lz->it = it;
3648
    Py_XINCREF(initial);
3649
    lz->initial = initial;
3650
    return (PyObject *)lz;
3651
}
3652
3653
static void
3654
accumulate_dealloc(accumulateobject *lz)
3655
{
3656
    PyObject_GC_UnTrack(lz);
3657
    Py_XDECREF(lz->binop);
3658
    Py_XDECREF(lz->total);
3659
    Py_XDECREF(lz->it);
3660
    Py_XDECREF(lz->initial);
3661
    Py_TYPE(lz)->tp_free(lz);
3662
}
3663
3664
static int
3665
accumulate_traverse(accumulateobject *lz, visitproc visit, void *arg)
3666
{
3667
    Py_VISIT(lz->binop);
3668
    Py_VISIT(lz->it);
3669
    Py_VISIT(lz->total);
3670
    Py_VISIT(lz->initial);
3671
    return 0;
3672
}
3673
3674
static PyObject *
3675
accumulate_next(accumulateobject *lz)
3676
{
3677
    PyObject *val, *newtotal;
3678
3679
    if (lz->initial != Py_None) {
  Branch (3679:9): [True: 8, False: 105k]
3680
        lz->total = lz->initial;
3681
        Py_INCREF(Py_None);
3682
        lz->initial = Py_None;
3683
        Py_INCREF(lz->total);
3684
        return lz->total;
3685
    }
3686
    val = (*Py_TYPE(lz->it)->tp_iternext)(lz->it);
3687
    if (val == NULL)
  Branch (3687:9): [True: 107, False: 105k]
3688
        return NULL;
3689
3690
    if (lz->total == NULL) {
  Branch (3690:9): [True: 136, False: 105k]
3691
        Py_INCREF(val);
3692
        lz->total = val;
3693
        return lz->total;
3694
    }
3695
3696
    if (lz->binop == NULL)
  Branch (3696:9): [True: 105k, False: 45]
3697
        newtotal = PyNumber_Add(lz->total, val);
3698
    else
3699
        newtotal = PyObject_CallFunctionObjArgs(lz->binop, lz->total, val, NULL);
3700
    Py_DECREF(val);
3701
    if (newtotal == NULL)
  Branch (3701:9): [True: 5, False: 105k]
3702
        return NULL;
3703
3704
    Py_INCREF(newtotal);
3705
    Py_SETREF(lz->total, newtotal);
3706
    return newtotal;
3707
}
3708
3709
static PyObject *
3710
accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored))
3711
{
3712
    if (lz->initial != Py_None) {
  Branch (3712:9): [True: 6, False: 47]
3713
        PyObject *it;
3714
3715
        assert(lz->total == NULL);
3716
        if (PyType_Ready(&chain_type) < 0)
  Branch (3716:13): [True: 0, False: 6]
3717
            return NULL;
3718
        it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O",
3719
                                   lz->initial, lz->it);
3720
        if (it == NULL)
  Branch (3720:13): [True: 0, False: 6]
3721
            return NULL;
3722
        return Py_BuildValue("O(NO)O", Py_TYPE(lz),
3723
                            it, lz->binop?
lz->binop0
:Py_None, Py_None);
  Branch (3723:33): [True: 0, False: 6]
3724
    }
3725
    if (lz->total == Py_None) {
  Branch (3725:9): [True: 8, False: 39]
3726
        PyObject *it;
3727
3728
        if (PyType_Ready(&chain_type) < 0)
  Branch (3728:13): [True: 0, False: 8]
3729
            return NULL;
3730
        if (PyType_Ready(&islice_type) < 0)
  Branch (3730:13): [True: 0, False: 8]
3731
            return NULL;
3732
        it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O",
3733
                                   lz->total, lz->it);
3734
        if (it == NULL)
  Branch (3734:13): [True: 0, False: 8]
3735
            return NULL;
3736
        it = PyObject_CallFunction((PyObject *)Py_TYPE(lz), "NO",
3737
                                   it, lz->binop ? lz->binop : 
Py_None0
);
  Branch (3737:40): [True: 8, False: 0]
3738
        if (it == NULL)
  Branch (3738:13): [True: 0, False: 8]
3739
            return NULL;
3740
        return Py_BuildValue("O(NiO)", &islice_type, it, 1, Py_None);
3741
    }
3742
    return Py_BuildValue("O(OO)O", Py_TYPE(lz),
3743
                            lz->it, lz->binop?
lz->binop7
:
Py_None32
,
  Branch (3743:37): [True: 7, False: 32]
3744
                            lz->total?
lz->total20
:
Py_None19
);
  Branch (3744:29): [True: 20, False: 19]
3745
}
3746
3747
static PyObject *
3748
accumulate_setstate(accumulateobject *lz, PyObject *state)
3749
{
3750
    Py_INCREF(state);
3751
    Py_XSETREF(lz->total, state);
3752
    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
itertools_compress_impl(PyTypeObject *type, PyObject *seq1, PyObject *seq2)
3836
/*[clinic end generated code: output=7e67157212ed09e0 input=79596d7cd20c77e5]*/
3837
{
3838
    PyObject *data=NULL, *selectors=NULL;
3839
    compressobject *lz;
3840
3841
    data = PyObject_GetIter(seq1);
3842
    if (data == NULL)
  Branch (3842:9): [True: 11, False: 280]
3843
        goto fail;
3844
    selectors = PyObject_GetIter(seq2);
3845
    if (selectors == NULL)
  Branch (3845:9): [True: 2, False: 278]
3846
        goto fail;
3847
3848
    /* create compressobject structure */
3849
    lz = (compressobject *)type->tp_alloc(type, 0);
3850
    if (lz == NULL)
  Branch (3850:9): [True: 0, False: 278]
3851
        goto fail;
3852
    lz->data = data;
3853
    lz->selectors = selectors;
3854
    return (PyObject *)lz;
3855
3856
fail:
3857
    Py_XDECREF(data);
3858
    Py_XDECREF(selectors);
3859
    return NULL;
3860
}
3861
3862
static void
3863
compress_dealloc(compressobject *lz)
3864
{
3865
    PyObject_GC_UnTrack(lz);
3866
    Py_XDECREF(lz->data);
3867
    Py_XDECREF(lz->selectors);
3868
    Py_TYPE(lz)->tp_free(lz);
3869
}
3870
3871
static int
3872
compress_traverse(compressobject *lz, visitproc visit, void *arg)
3873
{
3874
    Py_VISIT(lz->data);
3875
    Py_VISIT(lz->selectors);
3876
    return 0;
3877
}
3878
3879
static PyObject *
3880
compress_next(compressobject *lz)
3881
{
3882
    PyObject *data = lz->data, *selectors = lz->selectors;
3883
    PyObject *datum, *selector;
3884
    PyObject *(*datanext)(PyObject *) = *Py_TYPE(data)->tp_iternext;
3885
    PyObject *(*selectornext)(PyObject *) = *Py_TYPE(selectors)->tp_iternext;
3886
    int ok;
3887
3888
    while (1) {
  Branch (3888:12): [Folded - Ignored]
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
        datum = datanext(data);
3896
        if (datum == NULL)
  Branch (3896:13): [True: 132, False: 65.8k]
3897
            return NULL;
3898
3899
        selector = selectornext(selectors);
3900
        if (selector == NULL) {
  Branch (3900:13): [True: 25, False: 65.7k]
3901
            Py_DECREF(datum);
3902
            return NULL;
3903
        }
3904
3905
        ok = PyObject_IsTrue(selector);
3906
        Py_DECREF(selector);
3907
        if (ok > 0)
  Branch (3907:13): [True: 35.5k, False: 30.2k]
3908
            return datum;
3909
        Py_DECREF(datum);
3910
        if (ok < 0)
  Branch (3910:13): [True: 0, False: 30.2k]
3911
            return NULL;
3912
    }
3913
}
3914
3915
static PyObject *
3916
compress_reduce(compressobject *lz, PyObject *Py_UNUSED(ignored))
3917
{
3918
    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
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
    it = PyObject_GetIter(seq);
4001
    if (it == NULL)
  Branch (4001:9): [True: 11, False: 346]
4002
        return NULL;
4003
4004
    /* create filterfalseobject structure */
4005
    lz = (filterfalseobject *)type->tp_alloc(type, 0);
4006
    if (lz == NULL) {
  Branch (4006:9): [True: 0, False: 346]
4007
        Py_DECREF(it);
4008
        return NULL;
4009
    }
4010
    Py_INCREF(func);
4011
    lz->func = func;
4012
    lz->it = it;
4013
4014
    return (PyObject *)lz;
4015
}
4016
4017
static void
4018
filterfalse_dealloc(filterfalseobject *lz)
4019
{
4020
    PyObject_GC_UnTrack(lz);
4021
    Py_XDECREF(lz->func);
4022
    Py_XDECREF(lz->it);
4023
    Py_TYPE(lz)->tp_free(lz);
4024
}
4025
4026
static int
4027
filterfalse_traverse(filterfalseobject *lz, visitproc visit, void *arg)
4028
{
4029
    Py_VISIT(lz->it);
4030
    Py_VISIT(lz->func);
4031
    return 0;
4032
}
4033
4034
static PyObject *
4035
filterfalse_next(filterfalseobject *lz)
4036
{
4037
    PyObject *item;
4038
    PyObject *it = lz->it;
4039
    long ok;
4040
    PyObject *(*iternext)(PyObject *);
4041
4042
    iternext = *Py_TYPE(it)->tp_iternext;
4043
    for (;;) {
4044
        item = iternext(it);
4045
        if (item == NULL)
  Branch (4045:13): [True: 343, False: 295k]
4046
            return NULL;
4047
4048
        if (lz->func == Py_None || 
lz->func == (PyObject *)&PyBool_Type295k
) {
  Branch (4048:13): [True: 11, False: 295k]
  Branch (4048:36): [True: 5, False: 295k]
4049
            ok = PyObject_IsTrue(item);
4050
        } else {
4051
            PyObject *good;
4052
            good = PyObject_CallOneArg(lz->func, item);
4053
            if (good == NULL) {
  Branch (4053:17): [True: 1, False: 295k]
4054
                Py_DECREF(item);
4055
                return NULL;
4056
            }
4057
            ok = PyObject_IsTrue(good);
4058
            Py_DECREF(good);
4059
        }
4060
        if (ok == 0)
  Branch (4060:13): [True: 292k, False: 3.36k]
4061
            return item;
4062
        Py_DECREF(item);
4063
        if (ok < 0)
  Branch (4063:13): [True: 0, False: 3.36k]
4064
            return NULL;
4065
    }
4066
}
4067
4068
static PyObject *
4069
filterfalse_reduce(filterfalseobject *lz, PyObject *Py_UNUSED(ignored))
4070
{
4071
    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
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
    Py_ssize_t cnt = 0;
4174
    long step;
4175
4176
    if ((long_cnt != NULL && 
!PyNumber_Check(long_cnt)5.25k
) ||
  Branch (4176:10): [True: 5.25k, False: 99]
  Branch (4176:30): [True: 2, False: 5.25k]
4177
        
(5.35k
long_step != NULL5.35k
&&
!PyNumber_Check(long_step)1.73k
)) {
  Branch (4177:10): [True: 1.73k, False: 3.61k]
  Branch (4177:31): [True: 0, False: 1.73k]
4178
                    PyErr_SetString(PyExc_TypeError, "a number is required");
4179
                    return NULL;
4180
    }
4181
4182
    fast_mode = (long_cnt == NULL || PyLong_Check(long_cnt)) &&
  Branch (4182:18): [True: 99, False: 5.25k]
4183
                
(5.34k
long_step == NULL5.34k
||
PyLong_Check5.34k
(long_step));
  Branch (4183:18): [True: 3.61k, False: 1.73k]
4184
4185
    /* If not specified, start defaults to 0 */
4186
    if (long_cnt != NULL) {
  Branch (4186:9): [True: 5.25k, False: 99]
4187
        if (fast_mode) {
  Branch (4187:13): [True: 5.24k, False: 17]
4188
            assert(PyLong_Check(long_cnt));
4189
            cnt = PyLong_AsSsize_t(long_cnt);
4190
            if (cnt == -1 && 
PyErr_Occurred()715
) {
  Branch (4190:17): [True: 715, False: 4.52k]
  Branch (4190:30): [True: 530, False: 185]
4191
                PyErr_Clear();
4192
                fast_mode = 0;
4193
            }
4194
        }
4195
    } else {
4196
        cnt = 0;
4197
        long_cnt = _PyLong_GetZero();
4198
    }
4199
    Py_INCREF(long_cnt);
4200
4201
    /* If not specified, step defaults to 1 */
4202
    if (long_step == NULL) {
  Branch (4202:9): [True: 3.61k, False: 1.73k]
4203
        long_step = _PyLong_GetOne();
4204
    }
4205
    Py_INCREF(long_step);
4206
4207
    assert(long_cnt != NULL && long_step != NULL);
4208
4209
    /* Fast mode only works when the step is 1 */
4210
    if (fast_mode) {
  Branch (4210:9): [True: 4.80k, False: 547]
4211
        assert(PyLong_Check(long_step));
4212
        step = PyLong_AsLong(long_step);
4213
        if (step != 1) {
  Branch (4213:13): [True: 1.16k, False: 3.64k]
4214
            fast_mode = 0;
4215
            if (step == -1 && 
PyErr_Occurred()418
)
  Branch (4215:17): [True: 418, False: 746]
  Branch (4215:31): [True: 267, False: 151]
4216
                PyErr_Clear();
4217
        }
4218
    }
4219
4220
    if (fast_mode)
  Branch (4220:9): [True: 3.64k, False: 1.71k]
4221
        Py_CLEAR(long_cnt);
4222
    else
4223
        cnt = PY_SSIZE_T_MAX;
4224
4225
    assert((cnt != PY_SSIZE_T_MAX && long_cnt == NULL && fast_mode) ||
4226
           (cnt == PY_SSIZE_T_MAX && long_cnt != NULL && !fast_mode));
4227
    assert(!fast_mode ||
4228
           (PyLong_Check(long_step) && PyLong_AS_LONG(long_step) == 1));
4229
4230
    /* create countobject structure */
4231
    lz = (countobject *)type->tp_alloc(type, 0);
4232
    if (lz == NULL) {
  Branch (4232:9): [True: 0, False: 5.35k]
4233
        Py_XDECREF(long_cnt);
4234
        Py_DECREF(long_step);
4235
        return NULL;
4236
    }
4237
    lz->cnt = cnt;
4238
    lz->long_cnt = long_cnt;
4239
    lz->long_step = long_step;
4240
4241
    return (PyObject *)lz;
4242
}
4243
4244
static void
4245
count_dealloc(countobject *lz)
4246
{
4247
    PyObject_GC_UnTrack(lz);
4248
    Py_XDECREF(lz->long_cnt);
4249
    Py_XDECREF(lz->long_step);
4250
    Py_TYPE(lz)->tp_free(lz);
4251
}
4252
4253
static int
4254
count_traverse(countobject *lz, visitproc visit, void *arg)
4255
{
4256
    Py_VISIT(lz->long_cnt);
4257
    Py_VISIT(lz->long_step);
4258
    return 0;
4259
}
4260
4261
static PyObject *
4262
count_nextlong(countobject *lz)
4263
{
4264
    PyObject *long_cnt;
4265
    PyObject *stepped_up;
4266
4267
    long_cnt = lz->long_cnt;
4268
    if (long_cnt == NULL) {
  Branch (4268:9): [True: 1, False: 6.94k]
4269
        /* Switch to slow_mode */
4270
        long_cnt = PyLong_FromSsize_t(PY_SSIZE_T_MAX);
4271
        if (long_cnt == NULL)
  Branch (4271:13): [True: 0, False: 1]
4272
            return NULL;
4273
    }
4274
    assert(lz->cnt == PY_SSIZE_T_MAX && long_cnt != NULL);
4275
4276
    stepped_up = PyNumber_Add(long_cnt, lz->long_step);
4277
    if (stepped_up == NULL)
  Branch (4277:9): [True: 0, False: 6.94k]
4278
        return NULL;
4279
    lz->long_cnt = stepped_up;
4280
    return long_cnt;
4281
}
4282
4283
static PyObject *
4284
count_next(countobject *lz)
4285
{
4286
    if (lz->cnt == PY_SSIZE_T_MAX)
  Branch (4286:9): [True: 6.94k, False: 1.18M]
4287
        return count_nextlong(lz);
4288
    return PyLong_FromSsize_t(lz->cnt++);
4289
}
4290
4291
static PyObject *
4292
count_repr(countobject *lz)
4293
{
4294
    if (lz->cnt != PY_SSIZE_T_MAX)
  Branch (4294:9): [True: 15, False: 81]
4295
        return PyUnicode_FromFormat("%s(%zd)",
4296
                                    _PyType_Name(Py_TYPE(lz)), lz->cnt);
4297
4298
    if (PyLong_Check(lz->long_step)) {
4299
        long step = PyLong_AsLong(lz->long_step);
4300
        if (step == -1 && 
PyErr_Occurred()24
) {
  Branch (4300:13): [True: 24, False: 54]
  Branch (4300:27): [True: 16, False: 8]
4301
            PyErr_Clear();
4302
        }
4303
        if (step == 1) {
  Branch (4303:13): [True: 7, False: 71]
4304
            /* Don't display step when it is an integer equal to 1 */
4305
            return PyUnicode_FromFormat("%s(%R)",
4306
                                        _PyType_Name(Py_TYPE(lz)),
4307
                                        lz->long_cnt);
4308
        }
4309
    }
4310
    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
count_reduce(countobject *lz, PyObject *Py_UNUSED(ignored))
4317
{
4318
    if (lz->cnt == PY_SSIZE_T_MAX)
  Branch (4318:9): [True: 806, False: 152]
4319
        return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->long_cnt, lz->long_step);
4320
    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
repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
4386
{
4387
    repeatobject *ro;
4388
    PyObject *element;
4389
    Py_ssize_t cnt = -1, n_args;
4390
    static char *kwargs[] = {"object", "times", NULL};
4391
4392
    n_args = PyTuple_GET_SIZE(args);
4393
    if (kwds != NULL)
  Branch (4393:9): [True: 16, False: 43.2k]
4394
        n_args += PyDict_GET_SIZE(kwds);
4395
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:repeat", kwargs,
  Branch (4395:9): [True: 6, False: 43.2k]
4396
                                     &element, &cnt))
4397
        return NULL;
4398
    /* Does user supply times argument? */
4399
    if (n_args == 2 && 
cnt < 041.0k
)
  Branch (4399:9): [True: 41.0k, False: 2.16k]
  Branch (4399:24): [True: 13, False: 41.0k]
4400
        cnt = 0;
4401
4402
    ro = (repeatobject *)type->tp_alloc(type, 0);
4403
    if (ro == NULL)
  Branch (4403:9): [True: 0, False: 43.2k]
4404
        return NULL;
4405
    Py_INCREF(element);
4406
    ro->element = element;
4407
    ro->cnt = cnt;
4408
    return (PyObject *)ro;
4409
}
4410
4411
static void
4412
repeat_dealloc(repeatobject *ro)
4413
{
4414
    PyObject_GC_UnTrack(ro);
4415
    Py_XDECREF(ro->element);
4416
    Py_TYPE(ro)->tp_free(ro);
4417
}
4418
4419
static int
4420
repeat_traverse(repeatobject *ro, visitproc visit, void *arg)
4421
{
4422
    Py_VISIT(ro->element);
4423
    return 0;
4424
}
4425
4426
static PyObject *
4427
repeat_next(repeatobject *ro)
4428
{
4429
    if (ro->cnt == 0)
  Branch (4429:9): [True: 41.0k, False: 28.3M]
4430
        return NULL;
4431
    if (ro->cnt > 0)
  Branch (4431:9): [True: 28.3M, False: 37.0k]
4432
        ro->cnt--;
4433
    Py_INCREF(ro->element);
4434
    return ro->element;
4435
}
4436
4437
static PyObject *
4438
repeat_repr(repeatobject *ro)
4439
{
4440
    if (ro->cnt == -1)
  Branch (4440:9): [True: 1, False: 6]
4441
        return PyUnicode_FromFormat("%s(%R)",
4442
                                    _PyType_Name(Py_TYPE(ro)), ro->element);
4443
    else
4444
        return PyUnicode_FromFormat("%s(%R, %zd)",
4445
                                    _PyType_Name(Py_TYPE(ro)), ro->element,
4446
                                    ro->cnt);
4447
}
4448
4449
static PyObject *
4450
repeat_len(repeatobject *ro, PyObject *Py_UNUSED(ignored))
4451
{
4452
    if (ro->cnt == -1) {
  Branch (4452:9): [True: 1, False: 24]
4453
        PyErr_SetString(PyExc_TypeError, "len() of unsized object");
4454
        return NULL;
4455
    }
4456
    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
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
    if (ro->cnt >= 0)
  Branch (4467:9): [True: 14, False: 0]
4468
        return Py_BuildValue("O(On)", Py_TYPE(ro), ro->element, ro->cnt);
4469
    else
4470
        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
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
    PyObject *fillvalue = Py_None;
4550
    Py_ssize_t tuplesize;
4551
4552
    if (kwds != NULL && PyDict_CheckExact(kwds) && 
PyDict_GET_SIZE31.6k
(kwds) > 031.6k
) {
  Branch (4552:9): [True: 31.6k, False: 175]
  Branch (4552:52): [True: 31.5k, False: 18]
4553
        fillvalue = NULL;
4554
        if (PyDict_GET_SIZE(kwds) == 1) {
  Branch (4554:13): [True: 31.5k, False: 1]
4555
            fillvalue = PyDict_GetItemWithError(kwds, &_Py_ID(fillvalue));
4556
        }
4557
        if (fillvalue == NULL) {
  Branch (4557:13): [True: 2, False: 31.5k]
4558
            if (!PyErr_Occurred()) {
  Branch (4558:17): [True: 2, False: 0]
4559
                PyErr_SetString(PyExc_TypeError,
4560
                    "zip_longest() got an unexpected keyword argument");
4561
            }
4562
            return NULL;
4563
        }
4564
    }
4565
4566
    /* args must be a tuple */
4567
    assert(PyTuple_Check(args));
4568
    tuplesize = PyTuple_GET_SIZE(args);
4569
4570
    /* obtain iterators */
4571
    ittuple = PyTuple_New(tuplesize);
4572
    if (ittuple == NULL)
  Branch (4572:9): [True: 0, False: 31.7k]
4573
        return NULL;
4574
    
for (i=0; 31.7k
i < tuplesize;
i++63.5k
) {
  Branch (4574:15): [True: 63.5k, False: 31.7k]
4575
        PyObject *item = PyTuple_GET_ITEM(args, i);
4576
        PyObject *it = PyObject_GetIter(item);
4577
        if (it == NULL) {
  Branch (4577:13): [True: 13, False: 63.5k]
4578
            Py_DECREF(ittuple);
4579
            return NULL;
4580
        }
4581
        PyTuple_SET_ITEM(ittuple, i, it);
4582
    }
4583
4584
    /* create a result holder */
4585
    result = PyTuple_New(tuplesize);
4586
    if (result == NULL) {
  Branch (4586:9): [True: 0, False: 31.7k]
4587
        Py_DECREF(ittuple);
4588
        return NULL;
4589
    }
4590
    
for (i=0 ; 31.7k
i < tuplesize ;
i++63.5k
) {
  Branch (4590:16): [True: 63.5k, False: 31.7k]
4591
        Py_INCREF(Py_None);
4592
        PyTuple_SET_ITEM(result, i, Py_None);
4593
    }
4594
4595
    /* create ziplongestobject structure */
4596
    lz = (ziplongestobject *)type->tp_alloc(type, 0);
4597
    if (lz == NULL) {
  Branch (4597:9): [True: 0, False: 31.7k]
4598
        Py_DECREF(ittuple);
4599
        Py_DECREF(result);
4600
        return NULL;
4601
    }
4602
    lz->ittuple = ittuple;
4603
    lz->tuplesize = tuplesize;
4604
    lz->numactive = tuplesize;
4605
    lz->result = result;
4606
    Py_INCREF(fillvalue);
4607
    lz->fillvalue = fillvalue;
4608
    return (PyObject *)lz;
4609
}
4610
4611
static void
4612
zip_longest_dealloc(ziplongestobject *lz)
4613
{
4614
    PyObject_GC_UnTrack(lz);
4615
    Py_XDECREF(lz->ittuple);
4616
    Py_XDECREF(lz->result);
4617
    Py_XDECREF(lz->fillvalue);
4618
    Py_TYPE(lz)->tp_free(lz);
4619
}
4620
4621
static int
4622
zip_longest_traverse(ziplongestobject *lz, visitproc visit, void *arg)
4623
{
4624
    Py_VISIT(lz->ittuple);
4625
    Py_VISIT(lz->result);
4626
    Py_VISIT(lz->fillvalue);
4627
    return 0;
4628
}
4629
4630
static PyObject *
4631
zip_longest_next(ziplongestobject *lz)
4632
{
4633
    Py_ssize_t i;
4634
    Py_ssize_t tuplesize = lz->tuplesize;
4635
    PyObject *result = lz->result;
4636
    PyObject *it;
4637
    PyObject *item;
4638
    PyObject *olditem;
4639
4640
    if (tuplesize == 0)
  Branch (4640:9): [True: 1, False: 1.09M]
4641
        return NULL;
4642
    if (lz->numactive == 0)
  Branch (4642:9): [True: 0, False: 1.09M]
4643
        return NULL;
4644
    if (Py_REFCNT(result) == 1) {
  Branch (4644:9): [True: 549k, False: 545k]
4645
        Py_INCREF(result);
4646
        for (i=0 ; i < tuplesize ; 
i++1.07M
) {
  Branch (4646:20): [True: 1.09M, False: 521k]
4647
            it = PyTuple_GET_ITEM(lz->ittuple, i);
4648
            if (it == NULL) {
  Branch (4648:17): [True: 7, False: 1.09M]
4649
                Py_INCREF(lz->fillvalue);
4650
                item = lz->fillvalue;
4651
            } else {
4652
                item = PyIter_Next(it);
4653
                if (item == NULL) {
  Branch (4653:21): [True: 55.7k, False: 1.04M]
4654
                    lz->numactive -= 1;
4655
                    if (lz->numactive == 0 || 
PyErr_Occurred()28.5k
) {
  Branch (4655:25): [True: 27.1k, False: 28.5k]
  Branch (4655:47): [True: 1, False: 28.5k]
4656
                        lz->numactive = 0;
4657
                        Py_DECREF(result);
4658
                        return NULL;
4659
                    } else {
4660
                        Py_INCREF(lz->fillvalue);
4661
                        item = lz->fillvalue;
4662
                        PyTuple_SET_ITEM(lz->ittuple, i, NULL);
4663
                        Py_DECREF(it);
4664
                    }
4665
                }
4666
            }
4667
            olditem = PyTuple_GET_ITEM(result, i);
4668
            PyTuple_SET_ITEM(result, i, item);
4669
            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
        if (!_PyObject_GC_IS_TRACKED(result)) {
  Branch (4673:13): [True: 2, False: 521k]
4674
            _PyObject_GC_TRACK(result);
4675
        }
4676
    } else {
4677
        result = PyTuple_New(tuplesize);
4678
        if (result == NULL)
  Branch (4678:13): [True: 0, False: 545k]
4679
            return NULL;
4680
        
for (i=0 ; 545k
i < tuplesize ;
i++1.11M
) {
  Branch (4680:20): [True: 1.11M, False: 540k]
4681
            it = PyTuple_GET_ITEM(lz->ittuple, i);
4682
            if (it == NULL) {
  Branch (4682:17): [True: 33.1k, False: 1.08M]
4683
                Py_INCREF(lz->fillvalue);
4684
                item = lz->fillvalue;
4685
            } else {
4686
                item = PyIter_Next(it);
4687
                if (item == NULL) {
  Branch (4687:21): [True: 7.69k, False: 1.07M]
4688
                    lz->numactive -= 1;
4689
                    if (lz->numactive == 0 || 
PyErr_Occurred()3.15k
) {
  Branch (4689:25): [True: 4.53k, False: 3.15k]
  Branch (4689:47): [True: 0, False: 3.15k]
4690
                        lz->numactive = 0;
4691
                        Py_DECREF(result);
4692
                        return NULL;
4693
                    } else {
4694
                        Py_INCREF(lz->fillvalue);
4695
                        item = lz->fillvalue;
4696
                        PyTuple_SET_ITEM(lz->ittuple, i, NULL);
4697
                        Py_DECREF(it);
4698
                    }
4699
                }
4700
            }
4701
            PyTuple_SET_ITEM(result, i, item);
4702
        }
4703
    }
4704
    return result;
4705
}
4706
4707
static PyObject *
4708
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
    PyObject *args = PyTuple_New(PyTuple_GET_SIZE(lz->ittuple));
4716
4717
    if (args == NULL)
  Branch (4717:9): [True: 0, False: 48]
4718
        return NULL;
4719
    
for (i=0; 48
i<PyTuple_GET_SIZE(lz->ittuple);
i++96
) {
  Branch (4719:15): [True: 96, False: 48]
4720
        PyObject *elem = PyTuple_GET_ITEM(lz->ittuple, i);
4721
        if (elem == NULL) {
  Branch (4721:13): [True: 6, False: 90]
4722
            elem = PyTuple_New(0);
4723
            if (elem == NULL) {
  Branch (4723:17): [True: 0, False: 6]
4724
                Py_DECREF(args);
4725
                return NULL;
4726
            }
4727
        } else
4728
            Py_INCREF(elem);
4729
        PyTuple_SET_ITEM(args, i, elem);
4730
    }
4731
    return Py_BuildValue("ONO", Py_TYPE(lz), args, lz->fillvalue);
4732
}
4733
4734
static PyObject *
4735
zip_longest_setstate(ziplongestobject *lz, PyObject *state)
4736
{
4737
    Py_INCREF(state);
4738
    Py_XSETREF(lz->fillvalue, state);
4739
    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
itertoolsmodule_exec(PyObject *m)
4841
{
4842
    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
    Py_SET_TYPE(&teedataobject_type, &PyType_Type);
4867
4868
    for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); 
i++1.84k
) {
  Branch (4868:24): [True: 1.84k, False: 88]
4869
        if (PyModule_AddType(m, typelist[i]) < 0) {
  Branch (4869:13): [True: 0, False: 1.84k]
4870
            return -1;
4871
        }
4872
    }
4873
4874
    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
PyInit_itertools(void)
4902
{
4903
    return PyModuleDef_Init(&itertoolsmodule);
4904
}