Coverage Report

Created: 2025-09-05 07:10

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