Coverage Report

Created: 2026-10-31 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Modules/clinic/itertoolsmodule.c.h
Line
Count
Source
1
/*[clinic input]
2
preserve
3
[clinic start generated code]*/
4
5
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
6
#  include "pycore_gc.h"          // PyGC_Head
7
#  include "pycore_runtime.h"     // _Py_ID()
8
#endif
9
#include "pycore_abstract.h"      // _PyNumber_Index()
10
#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION()
11
#include "pycore_modsupport.h"    // _PyArg_UnpackKeywords()
12
13
PyDoc_STRVAR(batched_new__doc__,
14
"batched(iterable, n, *, strict=False)\n"
15
"--\n"
16
"\n"
17
"Batch data into tuples of length n. The last batch may be shorter than n.\n"
18
"\n"
19
"Loops over the input iterable and accumulates data into tuples\n"
20
"up to size n.  The input is consumed lazily, just enough to\n"
21
"fill a batch.  The result is yielded as soon as a batch is full\n"
22
"or when the input iterable is exhausted.\n"
23
"\n"
24
"    >>> for batch in batched(\'ABCDEFG\', 3):\n"
25
"    ...     print(batch)\n"
26
"    ...\n"
27
"    (\'A\', \'B\', \'C\')\n"
28
"    (\'D\', \'E\', \'F\')\n"
29
"    (\'G\',)\n"
30
"\n"
31
"If \"strict\" is True, raises a ValueError if the final batch is shorter\n"
32
"than n.");
33
34
static PyObject *
35
batched_new_impl(PyTypeObject *type, PyObject *iterable, Py_ssize_t n,
36
                 int strict);
37
38
static PyObject *
39
batched_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
40
0
{
41
0
    PyObject *return_value = NULL;
42
0
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
43
44
0
    #define NUM_KEYWORDS 3
45
0
    static struct {
46
0
        PyGC_Head _this_is_not_used;
47
0
        PyObject_VAR_HEAD
48
0
        Py_hash_t ob_hash;
49
0
        PyObject *ob_item[NUM_KEYWORDS];
50
0
    } _kwtuple = {
51
0
        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
52
0
        .ob_hash = -1,
53
0
        .ob_item = { &_Py_ID(iterable), _Py_LATIN1_CHR('n'), &_Py_ID(strict), },
54
0
    };
55
0
    #undef NUM_KEYWORDS
56
0
    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
57
58
    #else  // !Py_BUILD_CORE
59
    #  define KWTUPLE NULL
60
    #endif  // !Py_BUILD_CORE
61
62
0
    static const char * const _keywords[] = {"iterable", "n", "strict", NULL};
63
0
    static _PyArg_Parser _parser = {
64
0
        .keywords = _keywords,
65
0
        .fname = "batched",
66
0
        .kwtuple = KWTUPLE,
67
0
    };
68
0
    #undef KWTUPLE
69
0
    PyObject *argsbuf[3];
70
0
    PyObject * const *fastargs;
71
0
    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
72
0
    Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 2;
73
0
    PyObject *iterable;
74
0
    Py_ssize_t n;
75
0
    int strict = 0;
76
77
0
    fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser,
78
0
            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
79
0
    if (!fastargs) {
80
0
        goto exit;
81
0
    }
82
0
    iterable = fastargs[0];
83
0
    {
84
0
        Py_ssize_t ival = -1;
85
0
        PyObject *iobj = _PyNumber_Index(fastargs[1]);
86
0
        if (iobj != NULL) {
87
0
            ival = PyLong_AsSsize_t(iobj);
88
0
            Py_DECREF(iobj);
89
0
        }
90
0
        if (ival == -1 && PyErr_Occurred()) {
91
0
            goto exit;
92
0
        }
93
0
        n = ival;
94
0
    }
95
0
    if (!noptargs) {
96
0
        goto skip_optional_kwonly;
97
0
    }
98
0
    strict = PyObject_IsTrue(fastargs[2]);
99
0
    if (strict < 0) {
100
0
        goto exit;
101
0
    }
102
0
skip_optional_kwonly:
103
0
    return_value = batched_new_impl(type, iterable, n, strict);
104
105
0
exit:
106
0
    return return_value;
107
0
}
108
109
PyDoc_STRVAR(pairwise_new__doc__,
110
"pairwise(iterable, /)\n"
111
"--\n"
112
"\n"
113
"Return an iterator of overlapping pairs taken from the input iterator.\n"
114
"\n"
115
"    s -> (s0,s1), (s1,s2), (s2, s3), ...");
116
117
static PyObject *
118
pairwise_new_impl(PyTypeObject *type, PyObject *iterable);
119
120
static PyObject *
121
pairwise_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
122
4
{
123
4
    PyObject *return_value = NULL;
124
4
    PyTypeObject *base_tp = clinic_state()->pairwise_type;
125
4
    PyObject *iterable;
126
127
4
    if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
128
4
        !_PyArg_NoKeywords("pairwise", kwargs)) {
129
0
        goto exit;
130
0
    }
131
4
    if (!_PyArg_CheckPositional("pairwise", PyTuple_GET_SIZE(args), 1, 1)) {
132
0
        goto exit;
133
0
    }
134
4
    iterable = PyTuple_GET_ITEM(args, 0);
135
4
    return_value = pairwise_new_impl(type, iterable);
136
137
4
exit:
138
4
    return return_value;
139
4
}
140
141
PyDoc_STRVAR(itertools_groupby__doc__,
142
"groupby(iterable, key=None)\n"
143
"--\n"
144
"\n"
145
"make an iterator that returns consecutive keys and groups from the iterable\n"
146
"\n"
147
"  iterable\n"
148
"    Elements to divide into groups according to the key function.\n"
149
"  key\n"
150
"    A function for computing the group category for each element.\n"
151
"    If the key function is not specified or is None, the element itself\n"
152
"    is used for grouping.");
153
154
static PyObject *
155
itertools_groupby_impl(PyTypeObject *type, PyObject *it, PyObject *keyfunc);
156
157
static PyObject *
158
itertools_groupby(PyTypeObject *type, PyObject *args, PyObject *kwargs)
159
0
{
160
0
    PyObject *return_value = NULL;
161
0
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
162
163
0
    #define NUM_KEYWORDS 2
164
0
    static struct {
165
0
        PyGC_Head _this_is_not_used;
166
0
        PyObject_VAR_HEAD
167
0
        Py_hash_t ob_hash;
168
0
        PyObject *ob_item[NUM_KEYWORDS];
169
0
    } _kwtuple = {
170
0
        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
171
0
        .ob_hash = -1,
172
0
        .ob_item = { &_Py_ID(iterable), &_Py_ID(key), },
173
0
    };
174
0
    #undef NUM_KEYWORDS
175
0
    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
176
177
    #else  // !Py_BUILD_CORE
178
    #  define KWTUPLE NULL
179
    #endif  // !Py_BUILD_CORE
180
181
0
    static const char * const _keywords[] = {"iterable", "key", NULL};
182
0
    static _PyArg_Parser _parser = {
183
0
        .keywords = _keywords,
184
0
        .fname = "groupby",
185
0
        .kwtuple = KWTUPLE,
186
0
    };
187
0
    #undef KWTUPLE
188
0
    PyObject *argsbuf[2];
189
0
    PyObject * const *fastargs;
190
0
    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
191
0
    Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1;
192
0
    PyObject *it;
193
0
    PyObject *keyfunc = Py_None;
194
195
0
    fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser,
196
0
            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
197
0
    if (!fastargs) {
198
0
        goto exit;
199
0
    }
200
0
    it = fastargs[0];
201
0
    if (!noptargs) {
202
0
        goto skip_optional_pos;
203
0
    }
204
0
    keyfunc = fastargs[1];
205
0
skip_optional_pos:
206
0
    return_value = itertools_groupby_impl(type, it, keyfunc);
207
208
0
exit:
209
0
    return return_value;
210
0
}
211
212
static PyObject *
213
itertools__grouper_impl(PyTypeObject *type, PyObject *parent,
214
                        PyObject *tgtkey);
215
216
static PyObject *
217
itertools__grouper(PyTypeObject *type, PyObject *args, PyObject *kwargs)
218
0
{
219
0
    PyObject *return_value = NULL;
220
0
    PyTypeObject *base_tp = clinic_state()->_grouper_type;
221
0
    PyObject *parent;
222
0
    PyObject *tgtkey;
223
224
0
    if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
225
0
        !_PyArg_NoKeywords("_grouper", kwargs)) {
226
0
        goto exit;
227
0
    }
228
0
    if (!_PyArg_CheckPositional("_grouper", PyTuple_GET_SIZE(args), 2, 2)) {
229
0
        goto exit;
230
0
    }
231
0
    if (!PyObject_TypeCheck(PyTuple_GET_ITEM(args, 0), clinic_state_by_cls()->groupby_type)) {
232
0
        _PyArg_BadArgument("_grouper", "argument 1", (clinic_state_by_cls()->groupby_type)->tp_name, PyTuple_GET_ITEM(args, 0));
233
0
        goto exit;
234
0
    }
235
0
    parent = PyTuple_GET_ITEM(args, 0);
236
0
    tgtkey = PyTuple_GET_ITEM(args, 1);
237
0
    return_value = itertools__grouper_impl(type, parent, tgtkey);
238
239
0
exit:
240
0
    return return_value;
241
0
}
242
243
PyDoc_STRVAR(itertools_teedataobject__doc__,
244
"teedataobject(iterable, values, next, /)\n"
245
"--\n"
246
"\n"
247
"Data container common to multiple tee objects.");
248
249
static PyObject *
250
itertools_teedataobject_impl(PyTypeObject *type, PyObject *it,
251
                             PyObject *values, PyObject *next);
252
253
static PyObject *
254
itertools_teedataobject(PyTypeObject *type, PyObject *args, PyObject *kwargs)
255
0
{
256
0
    PyObject *return_value = NULL;
257
0
    PyTypeObject *base_tp = clinic_state()->teedataobject_type;
258
0
    PyObject *it;
259
0
    PyObject *values;
260
0
    PyObject *next;
261
262
0
    if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
263
0
        !_PyArg_NoKeywords("teedataobject", kwargs)) {
264
0
        goto exit;
265
0
    }
266
0
    if (!_PyArg_CheckPositional("teedataobject", PyTuple_GET_SIZE(args), 3, 3)) {
267
0
        goto exit;
268
0
    }
269
0
    it = PyTuple_GET_ITEM(args, 0);
270
0
    if (!PyList_Check(PyTuple_GET_ITEM(args, 1))) {
271
0
        _PyArg_BadArgument("teedataobject", "argument 2", "list", PyTuple_GET_ITEM(args, 1));
272
0
        goto exit;
273
0
    }
274
0
    values = PyTuple_GET_ITEM(args, 1);
275
0
    next = PyTuple_GET_ITEM(args, 2);
276
0
    return_value = itertools_teedataobject_impl(type, it, values, next);
277
278
0
exit:
279
0
    return return_value;
280
0
}
281
282
PyDoc_STRVAR(itertools__tee__doc__,
283
"_tee(iterable, /)\n"
284
"--\n"
285
"\n"
286
"Iterator wrapped to make it copyable.");
287
288
static PyObject *
289
itertools__tee_impl(PyTypeObject *type, PyObject *iterable);
290
291
static PyObject *
292
itertools__tee(PyTypeObject *type, PyObject *args, PyObject *kwargs)
293
0
{
294
0
    PyObject *return_value = NULL;
295
0
    PyTypeObject *base_tp = clinic_state()->tee_type;
296
0
    PyObject *iterable;
297
298
0
    if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
299
0
        !_PyArg_NoKeywords("_tee", kwargs)) {
300
0
        goto exit;
301
0
    }
302
0
    if (!_PyArg_CheckPositional("_tee", PyTuple_GET_SIZE(args), 1, 1)) {
303
0
        goto exit;
304
0
    }
305
0
    iterable = PyTuple_GET_ITEM(args, 0);
306
0
    return_value = itertools__tee_impl(type, iterable);
307
308
0
exit:
309
0
    return return_value;
310
0
}
311
312
PyDoc_STRVAR(itertools_tee__doc__,
313
"tee($module, iterable, n=2, /)\n"
314
"--\n"
315
"\n"
316
"Returns a tuple of n independent iterators.");
317
318
#define ITERTOOLS_TEE_METHODDEF    \
319
    {"tee", _PyCFunction_CAST(itertools_tee), METH_FASTCALL, itertools_tee__doc__},
320
321
static PyObject *
322
itertools_tee_impl(PyObject *module, PyObject *iterable, Py_ssize_t n);
323
324
static PyObject *
325
itertools_tee(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
326
0
{
327
0
    PyObject *return_value = NULL;
328
0
    PyObject *iterable;
329
0
    Py_ssize_t n = 2;
330
331
0
    if (!_PyArg_CheckPositional("tee", nargs, 1, 2)) {
332
0
        goto exit;
333
0
    }
334
0
    iterable = args[0];
335
0
    if (nargs < 2) {
336
0
        goto skip_optional;
337
0
    }
338
0
    {
339
0
        Py_ssize_t ival = -1;
340
0
        PyObject *iobj = _PyNumber_Index(args[1]);
341
0
        if (iobj != NULL) {
342
0
            ival = PyLong_AsSsize_t(iobj);
343
0
            Py_DECREF(iobj);
344
0
        }
345
0
        if (ival == -1 && PyErr_Occurred()) {
346
0
            goto exit;
347
0
        }
348
0
        n = ival;
349
0
        if (n < 0) {
350
0
            PyErr_SetString(PyExc_ValueError,
351
0
                            "n cannot be negative");
352
0
            goto exit;
353
0
        }
354
0
    }
355
0
skip_optional:
356
0
    return_value = itertools_tee_impl(module, iterable, n);
357
358
0
exit:
359
0
    return return_value;
360
0
}
361
362
PyDoc_STRVAR(itertools_cycle__doc__,
363
"cycle(iterable, /)\n"
364
"--\n"
365
"\n"
366
"Return elements from the iterable until it is exhausted. Then repeat the sequence indefinitely.");
367
368
static PyObject *
369
itertools_cycle_impl(PyTypeObject *type, PyObject *iterable);
370
371
static PyObject *
372
itertools_cycle(PyTypeObject *type, PyObject *args, PyObject *kwargs)
373
0
{
374
0
    PyObject *return_value = NULL;
375
0
    PyTypeObject *base_tp = clinic_state()->cycle_type;
376
0
    PyObject *iterable;
377
378
0
    if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
379
0
        !_PyArg_NoKeywords("cycle", kwargs)) {
380
0
        goto exit;
381
0
    }
382
0
    if (!_PyArg_CheckPositional("cycle", PyTuple_GET_SIZE(args), 1, 1)) {
383
0
        goto exit;
384
0
    }
385
0
    iterable = PyTuple_GET_ITEM(args, 0);
386
0
    return_value = itertools_cycle_impl(type, iterable);
387
388
0
exit:
389
0
    return return_value;
390
0
}
391
392
PyDoc_STRVAR(itertools_dropwhile__doc__,
393
"dropwhile(predicate, iterable, /)\n"
394
"--\n"
395
"\n"
396
"Drop items from the iterable while predicate(item) is true.\n"
397
"\n"
398
"Afterwards, return every element until the iterable is exhausted.");
399
400
static PyObject *
401
itertools_dropwhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq);
402
403
static PyObject *
404
itertools_dropwhile(PyTypeObject *type, PyObject *args, PyObject *kwargs)
405
0
{
406
0
    PyObject *return_value = NULL;
407
0
    PyTypeObject *base_tp = clinic_state()->dropwhile_type;
408
0
    PyObject *func;
409
0
    PyObject *seq;
410
411
0
    if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
412
0
        !_PyArg_NoKeywords("dropwhile", kwargs)) {
413
0
        goto exit;
414
0
    }
415
0
    if (!_PyArg_CheckPositional("dropwhile", PyTuple_GET_SIZE(args), 2, 2)) {
416
0
        goto exit;
417
0
    }
418
0
    func = PyTuple_GET_ITEM(args, 0);
419
0
    seq = PyTuple_GET_ITEM(args, 1);
420
0
    return_value = itertools_dropwhile_impl(type, func, seq);
421
422
0
exit:
423
0
    return return_value;
424
0
}
425
426
PyDoc_STRVAR(itertools_takewhile__doc__,
427
"takewhile(predicate, iterable, /)\n"
428
"--\n"
429
"\n"
430
"Return successive entries from an iterable as long as the predicate evaluates to true for each entry.");
431
432
static PyObject *
433
itertools_takewhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq);
434
435
static PyObject *
436
itertools_takewhile(PyTypeObject *type, PyObject *args, PyObject *kwargs)
437
0
{
438
0
    PyObject *return_value = NULL;
439
0
    PyTypeObject *base_tp = clinic_state()->takewhile_type;
440
0
    PyObject *func;
441
0
    PyObject *seq;
442
443
0
    if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
444
0
        !_PyArg_NoKeywords("takewhile", kwargs)) {
445
0
        goto exit;
446
0
    }
447
0
    if (!_PyArg_CheckPositional("takewhile", PyTuple_GET_SIZE(args), 2, 2)) {
448
0
        goto exit;
449
0
    }
450
0
    func = PyTuple_GET_ITEM(args, 0);
451
0
    seq = PyTuple_GET_ITEM(args, 1);
452
0
    return_value = itertools_takewhile_impl(type, func, seq);
453
454
0
exit:
455
0
    return return_value;
456
0
}
457
458
PyDoc_STRVAR(itertools_starmap__doc__,
459
"starmap(function, iterable, /)\n"
460
"--\n"
461
"\n"
462
"Return an iterator whose values are returned from the function evaluated with an argument tuple taken from the given sequence.");
463
464
static PyObject *
465
itertools_starmap_impl(PyTypeObject *type, PyObject *func, PyObject *seq);
466
467
static PyObject *
468
itertools_starmap(PyTypeObject *type, PyObject *args, PyObject *kwargs)
469
0
{
470
0
    PyObject *return_value = NULL;
471
0
    PyTypeObject *base_tp = clinic_state()->starmap_type;
472
0
    PyObject *func;
473
0
    PyObject *seq;
474
475
0
    if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
476
0
        !_PyArg_NoKeywords("starmap", kwargs)) {
477
0
        goto exit;
478
0
    }
479
0
    if (!_PyArg_CheckPositional("starmap", PyTuple_GET_SIZE(args), 2, 2)) {
480
0
        goto exit;
481
0
    }
482
0
    func = PyTuple_GET_ITEM(args, 0);
483
0
    seq = PyTuple_GET_ITEM(args, 1);
484
0
    return_value = itertools_starmap_impl(type, func, seq);
485
486
0
exit:
487
0
    return return_value;
488
0
}
489
490
PyDoc_STRVAR(itertools_chain_from_iterable__doc__,
491
"from_iterable($type, iterable, /)\n"
492
"--\n"
493
"\n"
494
"Alternative chain() constructor taking a single iterable argument that evaluates lazily.");
495
496
#define ITERTOOLS_CHAIN_FROM_ITERABLE_METHODDEF    \
497
    {"from_iterable", (PyCFunction)itertools_chain_from_iterable, METH_O|METH_CLASS, itertools_chain_from_iterable__doc__},
498
499
static PyObject *
500
itertools_chain_from_iterable_impl(PyTypeObject *type, PyObject *arg);
501
502
static PyObject *
503
itertools_chain_from_iterable(PyObject *type, PyObject *arg)
504
142
{
505
142
    PyObject *return_value = NULL;
506
507
142
    return_value = itertools_chain_from_iterable_impl((PyTypeObject *)type, arg);
508
509
142
    return return_value;
510
142
}
511
512
static PyObject *
513
chain_next_impl(chainobject *self);
514
515
static PyObject *
516
chain_next(PyObject *self)
517
95.9k
{
518
95.9k
    PyObject *return_value = NULL;
519
520
95.9k
    Py_BEGIN_CRITICAL_SECTION(self);
521
95.9k
    return_value = chain_next_impl((chainobject *)self);
522
95.9k
    Py_END_CRITICAL_SECTION();
523
524
95.9k
    return return_value;
525
95.9k
}
526
527
static PyObject *
528
product_next_impl(productobject *self);
529
530
static PyObject *
531
product_next(PyObject *self)
532
810
{
533
810
    PyObject *return_value = NULL;
534
535
810
    Py_BEGIN_CRITICAL_SECTION(self);
536
810
    return_value = product_next_impl((productobject *)self);
537
810
    Py_END_CRITICAL_SECTION();
538
539
810
    return return_value;
540
810
}
541
542
PyDoc_STRVAR(itertools_combinations__doc__,
543
"combinations(iterable, r)\n"
544
"--\n"
545
"\n"
546
"Return successive r-length combinations of elements in the iterable.\n"
547
"\n"
548
"combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)");
549
550
static PyObject *
551
itertools_combinations_impl(PyTypeObject *type, PyObject *iterable,
552
                            Py_ssize_t r);
553
554
static PyObject *
555
itertools_combinations(PyTypeObject *type, PyObject *args, PyObject *kwargs)
556
0
{
557
0
    PyObject *return_value = NULL;
558
0
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
559
560
0
    #define NUM_KEYWORDS 2
561
0
    static struct {
562
0
        PyGC_Head _this_is_not_used;
563
0
        PyObject_VAR_HEAD
564
0
        Py_hash_t ob_hash;
565
0
        PyObject *ob_item[NUM_KEYWORDS];
566
0
    } _kwtuple = {
567
0
        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
568
0
        .ob_hash = -1,
569
0
        .ob_item = { &_Py_ID(iterable), _Py_LATIN1_CHR('r'), },
570
0
    };
571
0
    #undef NUM_KEYWORDS
572
0
    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
573
574
    #else  // !Py_BUILD_CORE
575
    #  define KWTUPLE NULL
576
    #endif  // !Py_BUILD_CORE
577
578
0
    static const char * const _keywords[] = {"iterable", "r", NULL};
579
0
    static _PyArg_Parser _parser = {
580
0
        .keywords = _keywords,
581
0
        .fname = "combinations",
582
0
        .kwtuple = KWTUPLE,
583
0
    };
584
0
    #undef KWTUPLE
585
0
    PyObject *argsbuf[2];
586
0
    PyObject * const *fastargs;
587
0
    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
588
0
    PyObject *iterable;
589
0
    Py_ssize_t r;
590
591
0
    fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser,
592
0
            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
593
0
    if (!fastargs) {
594
0
        goto exit;
595
0
    }
596
0
    iterable = fastargs[0];
597
0
    {
598
0
        Py_ssize_t ival = -1;
599
0
        PyObject *iobj = _PyNumber_Index(fastargs[1]);
600
0
        if (iobj != NULL) {
601
0
            ival = PyLong_AsSsize_t(iobj);
602
0
            Py_DECREF(iobj);
603
0
        }
604
0
        if (ival == -1 && PyErr_Occurred()) {
605
0
            goto exit;
606
0
        }
607
0
        r = ival;
608
0
        if (r < 0) {
609
0
            PyErr_SetString(PyExc_ValueError,
610
0
                            "r cannot be negative");
611
0
            goto exit;
612
0
        }
613
0
    }
614
0
    return_value = itertools_combinations_impl(type, iterable, r);
615
616
0
exit:
617
0
    return return_value;
618
0
}
619
620
static PyObject *
621
combinations_next_impl(combinationsobject *self);
622
623
static PyObject *
624
combinations_next(PyObject *self)
625
0
{
626
0
    PyObject *return_value = NULL;
627
628
0
    Py_BEGIN_CRITICAL_SECTION(self);
629
0
    return_value = combinations_next_impl((combinationsobject *)self);
630
0
    Py_END_CRITICAL_SECTION();
631
632
0
    return return_value;
633
0
}
634
635
PyDoc_STRVAR(itertools_combinations_with_replacement__doc__,
636
"combinations_with_replacement(iterable, r)\n"
637
"--\n"
638
"\n"
639
"Return successive r-length combinations of elements in the iterable allowing individual elements to have successive repeats.\n"
640
"\n"
641
"combinations_with_replacement(\'ABC\', 2) --> (\'A\',\'A\'), (\'A\',\'B\'), (\'A\',\'C\'), (\'B\',\'B\'), (\'B\',\'C\'), (\'C\',\'C\')");
642
643
static PyObject *
644
itertools_combinations_with_replacement_impl(PyTypeObject *type,
645
                                             PyObject *iterable,
646
                                             Py_ssize_t r);
647
648
static PyObject *
649
itertools_combinations_with_replacement(PyTypeObject *type, PyObject *args, PyObject *kwargs)
650
0
{
651
0
    PyObject *return_value = NULL;
652
0
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
653
654
0
    #define NUM_KEYWORDS 2
655
0
    static struct {
656
0
        PyGC_Head _this_is_not_used;
657
0
        PyObject_VAR_HEAD
658
0
        Py_hash_t ob_hash;
659
0
        PyObject *ob_item[NUM_KEYWORDS];
660
0
    } _kwtuple = {
661
0
        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
662
0
        .ob_hash = -1,
663
0
        .ob_item = { &_Py_ID(iterable), _Py_LATIN1_CHR('r'), },
664
0
    };
665
0
    #undef NUM_KEYWORDS
666
0
    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
667
668
    #else  // !Py_BUILD_CORE
669
    #  define KWTUPLE NULL
670
    #endif  // !Py_BUILD_CORE
671
672
0
    static const char * const _keywords[] = {"iterable", "r", NULL};
673
0
    static _PyArg_Parser _parser = {
674
0
        .keywords = _keywords,
675
0
        .fname = "combinations_with_replacement",
676
0
        .kwtuple = KWTUPLE,
677
0
    };
678
0
    #undef KWTUPLE
679
0
    PyObject *argsbuf[2];
680
0
    PyObject * const *fastargs;
681
0
    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
682
0
    PyObject *iterable;
683
0
    Py_ssize_t r;
684
685
0
    fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser,
686
0
            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
687
0
    if (!fastargs) {
688
0
        goto exit;
689
0
    }
690
0
    iterable = fastargs[0];
691
0
    {
692
0
        Py_ssize_t ival = -1;
693
0
        PyObject *iobj = _PyNumber_Index(fastargs[1]);
694
0
        if (iobj != NULL) {
695
0
            ival = PyLong_AsSsize_t(iobj);
696
0
            Py_DECREF(iobj);
697
0
        }
698
0
        if (ival == -1 && PyErr_Occurred()) {
699
0
            goto exit;
700
0
        }
701
0
        r = ival;
702
0
        if (r < 0) {
703
0
            PyErr_SetString(PyExc_ValueError,
704
0
                            "r cannot be negative");
705
0
            goto exit;
706
0
        }
707
0
    }
708
0
    return_value = itertools_combinations_with_replacement_impl(type, iterable, r);
709
710
0
exit:
711
0
    return return_value;
712
0
}
713
714
static PyObject *
715
cwr_next_impl(cwrobject *self);
716
717
static PyObject *
718
cwr_next(PyObject *self)
719
0
{
720
0
    PyObject *return_value = NULL;
721
722
0
    Py_BEGIN_CRITICAL_SECTION(self);
723
0
    return_value = cwr_next_impl((cwrobject *)self);
724
0
    Py_END_CRITICAL_SECTION();
725
726
0
    return return_value;
727
0
}
728
729
PyDoc_STRVAR(itertools_permutations__doc__,
730
"permutations(iterable, r=None)\n"
731
"--\n"
732
"\n"
733
"Return successive r-length permutations of elements in the iterable.\n"
734
"\n"
735
"permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)");
736
737
static PyObject *
738
itertools_permutations_impl(PyTypeObject *type, PyObject *iterable,
739
                            PyObject *robj);
740
741
static PyObject *
742
itertools_permutations(PyTypeObject *type, PyObject *args, PyObject *kwargs)
743
144
{
744
144
    PyObject *return_value = NULL;
745
144
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
746
747
144
    #define NUM_KEYWORDS 2
748
144
    static struct {
749
144
        PyGC_Head _this_is_not_used;
750
144
        PyObject_VAR_HEAD
751
144
        Py_hash_t ob_hash;
752
144
        PyObject *ob_item[NUM_KEYWORDS];
753
144
    } _kwtuple = {
754
144
        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
755
144
        .ob_hash = -1,
756
144
        .ob_item = { &_Py_ID(iterable), _Py_LATIN1_CHR('r'), },
757
144
    };
758
144
    #undef NUM_KEYWORDS
759
144
    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
760
761
    #else  // !Py_BUILD_CORE
762
    #  define KWTUPLE NULL
763
    #endif  // !Py_BUILD_CORE
764
765
144
    static const char * const _keywords[] = {"iterable", "r", NULL};
766
144
    static _PyArg_Parser _parser = {
767
144
        .keywords = _keywords,
768
144
        .fname = "permutations",
769
144
        .kwtuple = KWTUPLE,
770
144
    };
771
144
    #undef KWTUPLE
772
144
    PyObject *argsbuf[2];
773
144
    PyObject * const *fastargs;
774
144
    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
775
144
    Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1;
776
144
    PyObject *iterable;
777
144
    PyObject *robj = Py_None;
778
779
144
    fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser,
780
144
            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
781
144
    if (!fastargs) {
782
0
        goto exit;
783
0
    }
784
144
    iterable = fastargs[0];
785
144
    if (!noptargs) {
786
144
        goto skip_optional_pos;
787
144
    }
788
0
    robj = fastargs[1];
789
144
skip_optional_pos:
790
144
    return_value = itertools_permutations_impl(type, iterable, robj);
791
792
144
exit:
793
144
    return return_value;
794
144
}
795
796
static PyObject *
797
permutations_next_impl(permutationsobject *self);
798
799
static PyObject *
800
permutations_next(PyObject *self)
801
342
{
802
342
    PyObject *return_value = NULL;
803
804
342
    Py_BEGIN_CRITICAL_SECTION(self);
805
342
    return_value = permutations_next_impl((permutationsobject *)self);
806
342
    Py_END_CRITICAL_SECTION();
807
808
342
    return return_value;
809
342
}
810
811
PyDoc_STRVAR(itertools_accumulate__doc__,
812
"accumulate(iterable, func=None, *, initial=None)\n"
813
"--\n"
814
"\n"
815
"Return series of accumulated sums (or other binary function results).");
816
817
static PyObject *
818
itertools_accumulate_impl(PyTypeObject *type, PyObject *iterable,
819
                          PyObject *binop, PyObject *initial);
820
821
static PyObject *
822
itertools_accumulate(PyTypeObject *type, PyObject *args, PyObject *kwargs)
823
0
{
824
0
    PyObject *return_value = NULL;
825
0
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
826
827
0
    #define NUM_KEYWORDS 3
828
0
    static struct {
829
0
        PyGC_Head _this_is_not_used;
830
0
        PyObject_VAR_HEAD
831
0
        Py_hash_t ob_hash;
832
0
        PyObject *ob_item[NUM_KEYWORDS];
833
0
    } _kwtuple = {
834
0
        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
835
0
        .ob_hash = -1,
836
0
        .ob_item = { &_Py_ID(iterable), &_Py_ID(func), &_Py_ID(initial), },
837
0
    };
838
0
    #undef NUM_KEYWORDS
839
0
    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
840
841
    #else  // !Py_BUILD_CORE
842
    #  define KWTUPLE NULL
843
    #endif  // !Py_BUILD_CORE
844
845
0
    static const char * const _keywords[] = {"iterable", "func", "initial", NULL};
846
0
    static _PyArg_Parser _parser = {
847
0
        .keywords = _keywords,
848
0
        .fname = "accumulate",
849
0
        .kwtuple = KWTUPLE,
850
0
    };
851
0
    #undef KWTUPLE
852
0
    PyObject *argsbuf[3];
853
0
    PyObject * const *fastargs;
854
0
    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
855
0
    Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1;
856
0
    PyObject *iterable;
857
0
    PyObject *binop = Py_None;
858
0
    PyObject *initial = Py_None;
859
860
0
    fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser,
861
0
            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
862
0
    if (!fastargs) {
863
0
        goto exit;
864
0
    }
865
0
    iterable = fastargs[0];
866
0
    if (!noptargs) {
867
0
        goto skip_optional_pos;
868
0
    }
869
0
    if (fastargs[1]) {
870
0
        binop = fastargs[1];
871
0
        if (!--noptargs) {
872
0
            goto skip_optional_pos;
873
0
        }
874
0
    }
875
0
skip_optional_pos:
876
0
    if (!noptargs) {
877
0
        goto skip_optional_kwonly;
878
0
    }
879
0
    initial = fastargs[2];
880
0
skip_optional_kwonly:
881
0
    return_value = itertools_accumulate_impl(type, iterable, binop, initial);
882
883
0
exit:
884
0
    return return_value;
885
0
}
886
887
static PyObject *
888
accumulate_next_impl(accumulateobject *self);
889
890
static PyObject *
891
accumulate_next(PyObject *self)
892
0
{
893
0
    PyObject *return_value = NULL;
894
895
0
    Py_BEGIN_CRITICAL_SECTION(self);
896
0
    return_value = accumulate_next_impl((accumulateobject *)self);
897
0
    Py_END_CRITICAL_SECTION();
898
899
0
    return return_value;
900
0
}
901
902
PyDoc_STRVAR(itertools_compress__doc__,
903
"compress(data, selectors)\n"
904
"--\n"
905
"\n"
906
"Return data elements corresponding to true selector elements.\n"
907
"\n"
908
"Forms a shorter iterator from selected data elements using the selectors\n"
909
"to choose the data elements.");
910
911
static PyObject *
912
itertools_compress_impl(PyTypeObject *type, PyObject *seq1, PyObject *seq2);
913
914
static PyObject *
915
itertools_compress(PyTypeObject *type, PyObject *args, PyObject *kwargs)
916
0
{
917
0
    PyObject *return_value = NULL;
918
0
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
919
920
0
    #define NUM_KEYWORDS 2
921
0
    static struct {
922
0
        PyGC_Head _this_is_not_used;
923
0
        PyObject_VAR_HEAD
924
0
        Py_hash_t ob_hash;
925
0
        PyObject *ob_item[NUM_KEYWORDS];
926
0
    } _kwtuple = {
927
0
        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
928
0
        .ob_hash = -1,
929
0
        .ob_item = { &_Py_ID(data), &_Py_ID(selectors), },
930
0
    };
931
0
    #undef NUM_KEYWORDS
932
0
    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
933
934
    #else  // !Py_BUILD_CORE
935
    #  define KWTUPLE NULL
936
    #endif  // !Py_BUILD_CORE
937
938
0
    static const char * const _keywords[] = {"data", "selectors", NULL};
939
0
    static _PyArg_Parser _parser = {
940
0
        .keywords = _keywords,
941
0
        .fname = "compress",
942
0
        .kwtuple = KWTUPLE,
943
0
    };
944
0
    #undef KWTUPLE
945
0
    PyObject *argsbuf[2];
946
0
    PyObject * const *fastargs;
947
0
    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
948
0
    PyObject *seq1;
949
0
    PyObject *seq2;
950
951
0
    fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser,
952
0
            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
953
0
    if (!fastargs) {
954
0
        goto exit;
955
0
    }
956
0
    seq1 = fastargs[0];
957
0
    seq2 = fastargs[1];
958
0
    return_value = itertools_compress_impl(type, seq1, seq2);
959
960
0
exit:
961
0
    return return_value;
962
0
}
963
964
PyDoc_STRVAR(itertools_filterfalse__doc__,
965
"filterfalse(function, iterable, /)\n"
966
"--\n"
967
"\n"
968
"Return those items of iterable for which function(item) is false.\n"
969
"\n"
970
"If function is None, return the items that are false.");
971
972
static PyObject *
973
itertools_filterfalse_impl(PyTypeObject *type, PyObject *func, PyObject *seq);
974
975
static PyObject *
976
itertools_filterfalse(PyTypeObject *type, PyObject *args, PyObject *kwargs)
977
84
{
978
84
    PyObject *return_value = NULL;
979
84
    PyTypeObject *base_tp = clinic_state()->filterfalse_type;
980
84
    PyObject *func;
981
84
    PyObject *seq;
982
983
84
    if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
984
84
        !_PyArg_NoKeywords("filterfalse", kwargs)) {
985
0
        goto exit;
986
0
    }
987
84
    if (!_PyArg_CheckPositional("filterfalse", PyTuple_GET_SIZE(args), 2, 2)) {
988
0
        goto exit;
989
0
    }
990
84
    func = PyTuple_GET_ITEM(args, 0);
991
84
    seq = PyTuple_GET_ITEM(args, 1);
992
84
    return_value = itertools_filterfalse_impl(type, func, seq);
993
994
84
exit:
995
84
    return return_value;
996
84
}
997
998
PyDoc_STRVAR(itertools_count__doc__,
999
"count(start=0, step=1)\n"
1000
"--\n"
1001
"\n"
1002
"Return a count object whose .__next__() method returns consecutive values.\n"
1003
"\n"
1004
"Equivalent to:\n"
1005
"    def count(firstval=0, step=1):\n"
1006
"        x = firstval\n"
1007
"        while 1:\n"
1008
"            yield x\n"
1009
"            x += step");
1010
1011
static PyObject *
1012
itertools_count_impl(PyTypeObject *type, PyObject *long_cnt,
1013
                     PyObject *long_step);
1014
1015
static PyObject *
1016
itertools_count(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1017
26
{
1018
26
    PyObject *return_value = NULL;
1019
26
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
1020
1021
26
    #define NUM_KEYWORDS 2
1022
26
    static struct {
1023
26
        PyGC_Head _this_is_not_used;
1024
26
        PyObject_VAR_HEAD
1025
26
        Py_hash_t ob_hash;
1026
26
        PyObject *ob_item[NUM_KEYWORDS];
1027
26
    } _kwtuple = {
1028
26
        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
1029
26
        .ob_hash = -1,
1030
26
        .ob_item = { &_Py_ID(start), &_Py_ID(step), },
1031
26
    };
1032
26
    #undef NUM_KEYWORDS
1033
26
    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
1034
1035
    #else  // !Py_BUILD_CORE
1036
    #  define KWTUPLE NULL
1037
    #endif  // !Py_BUILD_CORE
1038
1039
26
    static const char * const _keywords[] = {"start", "step", NULL};
1040
26
    static _PyArg_Parser _parser = {
1041
26
        .keywords = _keywords,
1042
26
        .fname = "count",
1043
26
        .kwtuple = KWTUPLE,
1044
26
    };
1045
26
    #undef KWTUPLE
1046
26
    PyObject *argsbuf[2];
1047
26
    PyObject * const *fastargs;
1048
26
    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
1049
26
    Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0;
1050
26
    PyObject *long_cnt = NULL;
1051
26
    PyObject *long_step = NULL;
1052
1053
26
    fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser,
1054
26
            /*minpos*/ 0, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
1055
26
    if (!fastargs) {
1056
0
        goto exit;
1057
0
    }
1058
26
    if (!noptargs) {
1059
18
        goto skip_optional_pos;
1060
18
    }
1061
8
    if (fastargs[0]) {
1062
8
        long_cnt = fastargs[0];
1063
8
        if (!--noptargs) {
1064
8
            goto skip_optional_pos;
1065
8
        }
1066
8
    }
1067
0
    long_step = fastargs[1];
1068
26
skip_optional_pos:
1069
26
    return_value = itertools_count_impl(type, long_cnt, long_step);
1070
1071
26
exit:
1072
26
    return return_value;
1073
26
}
1074
1075
static PyObject *
1076
zip_longest_next_impl(ziplongestobject *self);
1077
1078
static PyObject *
1079
zip_longest_next(PyObject *self)
1080
0
{
1081
0
    PyObject *return_value = NULL;
1082
1083
0
    Py_BEGIN_CRITICAL_SECTION(self);
1084
0
    return_value = zip_longest_next_impl((ziplongestobject *)self);
1085
0
    Py_END_CRITICAL_SECTION();
1086
1087
0
    return return_value;
1088
0
}
1089
/*[clinic end generated code: output=4b55088ac24582b7 input=a9049054013a1b77]*/