blob: 453b4a2eb34a72e33307dd4767e4d88210504216 [file] [log] [blame]
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001
2#include "Python.h"
3
4/* Itertools module written and maintained
5 by Raymond D. Hettinger <python@rcn.com>
6 Copyright (c) 2003 Python Software Foundation.
7 All rights reserved.
8*/
9
10/* dropwhile object **********************************************************/
11
12typedef struct {
13 PyObject_HEAD
14 PyObject *func;
15 PyObject *it;
16 long start;
17} dropwhileobject;
18
19PyTypeObject dropwhile_type;
20
21static PyObject *
22dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
23{
24 PyObject *func, *seq;
25 PyObject *it;
26 dropwhileobject *lz;
27
28 if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq))
29 return NULL;
30
31 /* Get iterator. */
32 it = PyObject_GetIter(seq);
33 if (it == NULL)
34 return NULL;
35
36 /* create dropwhileobject structure */
37 lz = (dropwhileobject *)type->tp_alloc(type, 0);
38 if (lz == NULL) {
39 Py_DECREF(it);
40 return NULL;
41 }
42 Py_INCREF(func);
43 lz->func = func;
44 lz->it = it;
45 lz->start = 0;
46
47 return (PyObject *)lz;
48}
49
50static void
51dropwhile_dealloc(dropwhileobject *lz)
52{
53 PyObject_GC_UnTrack(lz);
54 Py_XDECREF(lz->func);
55 Py_XDECREF(lz->it);
56 lz->ob_type->tp_free(lz);
57}
58
59static int
60dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg)
61{
62 int err;
63
64 if (lz->it) {
65 err = visit(lz->it, arg);
66 if (err)
67 return err;
68 }
69 if (lz->func) {
70 err = visit(lz->func, arg);
71 if (err)
72 return err;
73 }
74 return 0;
75}
76
77static PyObject *
78dropwhile_next(dropwhileobject *lz)
79{
80 PyObject *item, *good;
81 long ok;
82
83 for (;;) {
84 item = PyIter_Next(lz->it);
85 if (item == NULL)
86 return NULL;
87 if (lz->start == 1)
88 return item;
89
90 good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
91 if (good == NULL) {
92 Py_DECREF(item);
93 return NULL;
94 }
95 ok = PyObject_IsTrue(good);
96 Py_DECREF(good);
97 if (!ok) {
98 lz->start = 1;
99 return item;
100 }
101 Py_DECREF(item);
102 }
103}
104
105static PyObject *
106dropwhile_getiter(PyObject *lz)
107{
108 Py_INCREF(lz);
109 return lz;
110}
111
112PyDoc_STRVAR(dropwhile_doc,
113"dropwhile(predicate, iterable) --> dropwhile object\n\
114\n\
115Drop items from the iterable while predicate(item) is true.\n\
116Afterwards, return every element until the iterable is exhausted.");
117
118PyTypeObject dropwhile_type = {
119 PyObject_HEAD_INIT(NULL)
120 0, /* ob_size */
121 "itertools.dropwhile", /* tp_name */
122 sizeof(dropwhileobject), /* tp_basicsize */
123 0, /* tp_itemsize */
124 /* methods */
125 (destructor)dropwhile_dealloc, /* tp_dealloc */
126 0, /* tp_print */
127 0, /* tp_getattr */
128 0, /* tp_setattr */
129 0, /* tp_compare */
130 0, /* tp_repr */
131 0, /* tp_as_number */
132 0, /* tp_as_sequence */
133 0, /* tp_as_mapping */
134 0, /* tp_hash */
135 0, /* tp_call */
136 0, /* tp_str */
137 PyObject_GenericGetAttr, /* tp_getattro */
138 0, /* tp_setattro */
139 0, /* tp_as_buffer */
140 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
141 Py_TPFLAGS_BASETYPE, /* tp_flags */
142 dropwhile_doc, /* tp_doc */
143 (traverseproc)dropwhile_traverse, /* tp_traverse */
144 0, /* tp_clear */
145 0, /* tp_richcompare */
146 0, /* tp_weaklistoffset */
147 (getiterfunc)dropwhile_getiter, /* tp_iter */
148 (iternextfunc)dropwhile_next, /* tp_iternext */
149 0, /* tp_methods */
150 0, /* tp_members */
151 0, /* tp_getset */
152 0, /* tp_base */
153 0, /* tp_dict */
154 0, /* tp_descr_get */
155 0, /* tp_descr_set */
156 0, /* tp_dictoffset */
157 0, /* tp_init */
158 PyType_GenericAlloc, /* tp_alloc */
159 dropwhile_new, /* tp_new */
160 PyObject_GC_Del, /* tp_free */
161};
162
163
164/* takewhile object **********************************************************/
165
166typedef struct {
167 PyObject_HEAD
168 PyObject *func;
169 PyObject *it;
170 long stop;
171} takewhileobject;
172
173PyTypeObject takewhile_type;
174
175static PyObject *
176takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
177{
178 PyObject *func, *seq;
179 PyObject *it;
180 takewhileobject *lz;
181
182 if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq))
183 return NULL;
184
185 /* Get iterator. */
186 it = PyObject_GetIter(seq);
187 if (it == NULL)
188 return NULL;
189
190 /* create takewhileobject structure */
191 lz = (takewhileobject *)type->tp_alloc(type, 0);
192 if (lz == NULL) {
193 Py_DECREF(it);
194 return NULL;
195 }
196 Py_INCREF(func);
197 lz->func = func;
198 lz->it = it;
199 lz->stop = 0;
200
201 return (PyObject *)lz;
202}
203
204static void
205takewhile_dealloc(takewhileobject *lz)
206{
207 PyObject_GC_UnTrack(lz);
208 Py_XDECREF(lz->func);
209 Py_XDECREF(lz->it);
210 lz->ob_type->tp_free(lz);
211}
212
213static int
214takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg)
215{
216 int err;
217
218 if (lz->it) {
219 err = visit(lz->it, arg);
220 if (err)
221 return err;
222 }
223 if (lz->func) {
224 err = visit(lz->func, arg);
225 if (err)
226 return err;
227 }
228 return 0;
229}
230
231static PyObject *
232takewhile_next(takewhileobject *lz)
233{
234 PyObject *item, *good;
235 long ok;
236
237 if (lz->stop == 1)
238 return NULL;
239
240 item = PyIter_Next(lz->it);
241 if (item == NULL)
242 return NULL;
243
244 good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
245 if (good == NULL) {
246 Py_DECREF(item);
247 return NULL;
248 }
249 ok = PyObject_IsTrue(good);
250 Py_DECREF(good);
251 if (ok)
252 return item;
253 Py_DECREF(item);
254 lz->stop = 1;
255 return NULL;
256}
257
258static PyObject *
259takewhile_getiter(PyObject *lz)
260{
261 Py_INCREF(lz);
262 return lz;
263}
264
265PyDoc_STRVAR(takewhile_doc,
266"takewhile(predicate, iterable) --> takewhile object\n\
267\n\
268Return successive entries from an iterable as long as the \n\
269predicate evaluates to true for each entry.");
270
271PyTypeObject takewhile_type = {
272 PyObject_HEAD_INIT(NULL)
273 0, /* ob_size */
274 "itertools.takewhile", /* tp_name */
275 sizeof(takewhileobject), /* tp_basicsize */
276 0, /* tp_itemsize */
277 /* methods */
278 (destructor)takewhile_dealloc, /* tp_dealloc */
279 0, /* tp_print */
280 0, /* tp_getattr */
281 0, /* tp_setattr */
282 0, /* tp_compare */
283 0, /* tp_repr */
284 0, /* tp_as_number */
285 0, /* tp_as_sequence */
286 0, /* tp_as_mapping */
287 0, /* tp_hash */
288 0, /* tp_call */
289 0, /* tp_str */
290 PyObject_GenericGetAttr, /* tp_getattro */
291 0, /* tp_setattro */
292 0, /* tp_as_buffer */
293 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
294 Py_TPFLAGS_BASETYPE, /* tp_flags */
295 takewhile_doc, /* tp_doc */
296 (traverseproc)takewhile_traverse, /* tp_traverse */
297 0, /* tp_clear */
298 0, /* tp_richcompare */
299 0, /* tp_weaklistoffset */
300 (getiterfunc)takewhile_getiter, /* tp_iter */
301 (iternextfunc)takewhile_next, /* tp_iternext */
302 0, /* tp_methods */
303 0, /* tp_members */
304 0, /* tp_getset */
305 0, /* tp_base */
306 0, /* tp_dict */
307 0, /* tp_descr_get */
308 0, /* tp_descr_set */
309 0, /* tp_dictoffset */
310 0, /* tp_init */
311 PyType_GenericAlloc, /* tp_alloc */
312 takewhile_new, /* tp_new */
313 PyObject_GC_Del, /* tp_free */
314};
315
316
317/* islice object ************************************************************/
318
319typedef struct {
320 PyObject_HEAD
321 PyObject *it;
322 long next;
323 long stop;
324 long step;
325 long cnt;
326} isliceobject;
327
328PyTypeObject islice_type;
329
330static PyObject *
331islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
332{
333 PyObject *seq;
334 long a1=0, a2=0, a3=0, start=0, stop=0, step=1;
335 PyObject *it;
336 int numargs;
337 isliceobject *lz;
338
339 numargs = PyTuple_Size(args);
340 if (!PyArg_ParseTuple(args, "Ol|ll:islice", &seq, &a1, &a2, &a3))
341 return NULL;
342
343 if (numargs == 2) {
344 stop = a1;
345 } else if (numargs == 3) {
346 start = a1;
347 stop = a2;
348 } else {
349 start = a1;
350 stop = a2;
351 step = a3;
352 }
353
354 if (start<0 || stop<0) {
355 PyErr_SetString(PyExc_ValueError,
356 "Indices for islice() must be positive.");
357 return NULL;
358 }
359
360 if (step<1) {
361 PyErr_SetString(PyExc_ValueError,
362 "Step must be one or larger for islice().");
363 return NULL;
364 }
365
366 /* Get iterator. */
367 it = PyObject_GetIter(seq);
368 if (it == NULL)
369 return NULL;
370
371 /* create isliceobject structure */
372 lz = (isliceobject *)type->tp_alloc(type, 0);
373 if (lz == NULL) {
374 Py_DECREF(it);
375 return NULL;
376 }
377 lz->it = it;
378 lz->next = start;
379 lz->stop = stop;
380 lz->step = step;
381 lz->cnt = 0L;
382
383 return (PyObject *)lz;
384}
385
386static void
387islice_dealloc(isliceobject *lz)
388{
389 PyObject_GC_UnTrack(lz);
390 Py_XDECREF(lz->it);
391 lz->ob_type->tp_free(lz);
392}
393
394static int
395islice_traverse(isliceobject *lz, visitproc visit, void *arg)
396{
397 if (lz->it)
398 return visit(lz->it, arg);
399 return 0;
400}
401
402static PyObject *
403islice_next(isliceobject *lz)
404{
405 PyObject *item;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000406 long oldnext;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000407
408 while (lz->cnt < lz->next) {
409 item = PyIter_Next(lz->it);
410 if (item == NULL)
411 return NULL;
412 Py_DECREF(item);
413 lz->cnt++;
414 }
415 if (lz->cnt >= lz->stop)
416 return NULL;
417 item = PyIter_Next(lz->it);
418 if (item == NULL)
419 return NULL;
420 lz->cnt++;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000421 oldnext = lz->next;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000422 lz->next += lz->step;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000423 if (lz->next < oldnext) /* Check for overflow */
424 lz->next = lz->stop;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000425 return item;
426}
427
428static PyObject *
429islice_getiter(PyObject *lz)
430{
431 Py_INCREF(lz);
432 return lz;
433}
434
435PyDoc_STRVAR(islice_doc,
436"islice(iterable, [start,] stop [, step]) --> islice object\n\
437\n\
438Return an iterator whose next() method returns selected values from an\n\
439iterable. If start is specified, will skip all preceding elements;\n\
440otherwise, start defaults to zero. Step defaults to one. If\n\
441specified as another value, step determines how many values are \n\
442skipped between successive calls. Works like a slice() on a list\n\
443but returns an iterator.");
444
445PyTypeObject islice_type = {
446 PyObject_HEAD_INIT(NULL)
447 0, /* ob_size */
448 "itertools.islice", /* tp_name */
449 sizeof(isliceobject), /* tp_basicsize */
450 0, /* tp_itemsize */
451 /* methods */
452 (destructor)islice_dealloc, /* tp_dealloc */
453 0, /* tp_print */
454 0, /* tp_getattr */
455 0, /* tp_setattr */
456 0, /* tp_compare */
457 0, /* tp_repr */
458 0, /* tp_as_number */
459 0, /* tp_as_sequence */
460 0, /* tp_as_mapping */
461 0, /* tp_hash */
462 0, /* tp_call */
463 0, /* tp_str */
464 PyObject_GenericGetAttr, /* tp_getattro */
465 0, /* tp_setattro */
466 0, /* tp_as_buffer */
467 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
468 Py_TPFLAGS_BASETYPE, /* tp_flags */
469 islice_doc, /* tp_doc */
470 (traverseproc)islice_traverse, /* tp_traverse */
471 0, /* tp_clear */
472 0, /* tp_richcompare */
473 0, /* tp_weaklistoffset */
474 (getiterfunc)islice_getiter, /* tp_iter */
475 (iternextfunc)islice_next, /* tp_iternext */
476 0, /* tp_methods */
477 0, /* tp_members */
478 0, /* tp_getset */
479 0, /* tp_base */
480 0, /* tp_dict */
481 0, /* tp_descr_get */
482 0, /* tp_descr_set */
483 0, /* tp_dictoffset */
484 0, /* tp_init */
485 PyType_GenericAlloc, /* tp_alloc */
486 islice_new, /* tp_new */
487 PyObject_GC_Del, /* tp_free */
488};
489
490
491/* starmap object ************************************************************/
492
493typedef struct {
494 PyObject_HEAD
495 PyObject *func;
496 PyObject *it;
497} starmapobject;
498
499PyTypeObject starmap_type;
500
501static PyObject *
502starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
503{
504 PyObject *func, *seq;
505 PyObject *it;
506 starmapobject *lz;
507
508 if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq))
509 return NULL;
510
511 /* Get iterator. */
512 it = PyObject_GetIter(seq);
513 if (it == NULL)
514 return NULL;
515
516 /* create starmapobject structure */
517 lz = (starmapobject *)type->tp_alloc(type, 0);
518 if (lz == NULL) {
519 Py_DECREF(it);
520 return NULL;
521 }
522 Py_INCREF(func);
523 lz->func = func;
524 lz->it = it;
525
526 return (PyObject *)lz;
527}
528
529static void
530starmap_dealloc(starmapobject *lz)
531{
532 PyObject_GC_UnTrack(lz);
533 Py_XDECREF(lz->func);
534 Py_XDECREF(lz->it);
535 lz->ob_type->tp_free(lz);
536}
537
538static int
539starmap_traverse(starmapobject *lz, visitproc visit, void *arg)
540{
541 int err;
542
543 if (lz->it) {
544 err = visit(lz->it, arg);
545 if (err)
546 return err;
547 }
548 if (lz->func) {
549 err = visit(lz->func, arg);
550 if (err)
551 return err;
552 }
553 return 0;
554}
555
556static PyObject *
557starmap_next(starmapobject *lz)
558{
559 PyObject *args;
560 PyObject *result;
561
562 args = PyIter_Next(lz->it);
563 if (args == NULL)
564 return NULL;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000565 if (!PyTuple_CheckExact(args)) {
566 Py_DECREF(args);
567 PyErr_SetString(PyExc_TypeError,
568 "iterator must return a tuple");
569 return NULL;
570 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000571 result = PyObject_Call(lz->func, args, NULL);
572 Py_DECREF(args);
573 return result;
574}
575
576static PyObject *
577starmap_getiter(PyObject *lz)
578{
579 Py_INCREF(lz);
580 return lz;
581}
582
583PyDoc_STRVAR(starmap_doc,
584"starmap(function, sequence) --> starmap object\n\
585\n\
586Return an iterator whose values are returned from the function evaluated\n\
587with a argument tuple taken from the given sequence.");
588
589PyTypeObject starmap_type = {
590 PyObject_HEAD_INIT(NULL)
591 0, /* ob_size */
592 "itertools.starmap", /* tp_name */
593 sizeof(starmapobject), /* tp_basicsize */
594 0, /* tp_itemsize */
595 /* methods */
596 (destructor)starmap_dealloc, /* tp_dealloc */
597 0, /* tp_print */
598 0, /* tp_getattr */
599 0, /* tp_setattr */
600 0, /* tp_compare */
601 0, /* tp_repr */
602 0, /* tp_as_number */
603 0, /* tp_as_sequence */
604 0, /* tp_as_mapping */
605 0, /* tp_hash */
606 0, /* tp_call */
607 0, /* tp_str */
608 PyObject_GenericGetAttr, /* tp_getattro */
609 0, /* tp_setattro */
610 0, /* tp_as_buffer */
611 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
612 Py_TPFLAGS_BASETYPE, /* tp_flags */
613 starmap_doc, /* tp_doc */
614 (traverseproc)starmap_traverse, /* tp_traverse */
615 0, /* tp_clear */
616 0, /* tp_richcompare */
617 0, /* tp_weaklistoffset */
618 (getiterfunc)starmap_getiter, /* tp_iter */
619 (iternextfunc)starmap_next, /* tp_iternext */
620 0, /* tp_methods */
621 0, /* tp_members */
622 0, /* tp_getset */
623 0, /* tp_base */
624 0, /* tp_dict */
625 0, /* tp_descr_get */
626 0, /* tp_descr_set */
627 0, /* tp_dictoffset */
628 0, /* tp_init */
629 PyType_GenericAlloc, /* tp_alloc */
630 starmap_new, /* tp_new */
631 PyObject_GC_Del, /* tp_free */
632};
633
634
635/* imap object ************************************************************/
636
637typedef struct {
638 PyObject_HEAD
639 PyObject *iters;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000640 PyObject *func;
641} imapobject;
642
643PyTypeObject imap_type;
644
645static PyObject *
646imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
647{
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000648 PyObject *it, *iters, *func;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000649 imapobject *lz;
650 int numargs, i;
651
652 numargs = PyTuple_Size(args);
653 if (numargs < 2) {
654 PyErr_SetString(PyExc_TypeError,
655 "imap() must have at least two arguments.");
656 return NULL;
657 }
658
659 iters = PyTuple_New(numargs-1);
660 if (iters == NULL)
661 return NULL;
662
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000663 for (i=1 ; i<numargs ; i++) {
664 /* Get iterator. */
665 it = PyObject_GetIter(PyTuple_GET_ITEM(args, i));
666 if (it == NULL) {
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000667 Py_DECREF(iters);
668 return NULL;
669 }
670 PyTuple_SET_ITEM(iters, i-1, it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000671 }
672
673 /* create imapobject structure */
674 lz = (imapobject *)type->tp_alloc(type, 0);
675 if (lz == NULL) {
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000676 Py_DECREF(iters);
677 return NULL;
678 }
679 lz->iters = iters;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000680 func = PyTuple_GET_ITEM(args, 0);
681 Py_INCREF(func);
682 lz->func = func;
683
684 return (PyObject *)lz;
685}
686
687static void
688imap_dealloc(imapobject *lz)
689{
690 PyObject_GC_UnTrack(lz);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000691 Py_XDECREF(lz->iters);
692 Py_XDECREF(lz->func);
693 lz->ob_type->tp_free(lz);
694}
695
696static int
697imap_traverse(imapobject *lz, visitproc visit, void *arg)
698{
699 int err;
700
701 if (lz->iters) {
702 err = visit(lz->iters, arg);
703 if (err)
704 return err;
705 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000706 if (lz->func) {
707 err = visit(lz->func, arg);
708 if (err)
709 return err;
710 }
711 return 0;
712}
713
Raymond Hettinger2012f172003-02-07 05:32:58 +0000714/*
715imap() is an iterator version of __builtins__.map() except that it does
716not have the None fill-in feature. That was intentionally left out for
717the following reasons:
718
719 1) Itertools are designed to be easily combined and chained together.
720 Having all tools stop with the shortest input is a unifying principle
721 that makes it easier to combine finite iterators (supplying data) with
722 infinite iterators like count() and repeat() (for supplying sequential
723 or constant arguments to a function).
724
725 2) In typical use cases for combining itertools, having one finite data
726 supplier run out before another is likely to be an error condition which
727 should not pass silently by automatically supplying None.
728
729 3) The use cases for automatic None fill-in are rare -- not many functions
730 do something useful when a parameter suddenly switches type and becomes
731 None.
732
733 4) If a need does arise, it can be met by __builtins__.map() or by
734 writing a generator.
735
736 5) Similar toolsets in Haskell and SML do not have automatic None fill-in.
737*/
738
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000739static PyObject *
740imap_next(imapobject *lz)
741{
742 PyObject *val;
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000743 PyObject *argtuple;
744 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000745 int numargs, i;
746
747 numargs = PyTuple_Size(lz->iters);
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000748 argtuple = PyTuple_New(numargs);
749 if (argtuple == NULL)
750 return NULL;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000751
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000752 for (i=0 ; i<numargs ; i++) {
753 val = PyIter_Next(PyTuple_GET_ITEM(lz->iters, i));
754 if (val == NULL) {
755 Py_DECREF(argtuple);
756 return NULL;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000757 }
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000758 PyTuple_SET_ITEM(argtuple, i, val);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000759 }
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000760 if (lz->func == Py_None)
761 return argtuple;
762 result = PyObject_Call(lz->func, argtuple, NULL);
763 Py_DECREF(argtuple);
764 return result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000765}
766
767static PyObject *
768imap_getiter(PyObject *lz)
769{
770 Py_INCREF(lz);
771 return lz;
772}
773
774PyDoc_STRVAR(imap_doc,
775"imap(func, *iterables) --> imap object\n\
776\n\
777Make an iterator that computes the function using arguments from\n\
778each of the iterables. Like map() except that it returns\n\
779an iterator instead of a list and that it stops when the shortest\n\
780iterable is exhausted instead of filling in None for shorter\n\
781iterables.");
782
783PyTypeObject imap_type = {
784 PyObject_HEAD_INIT(NULL)
785 0, /* ob_size */
786 "itertools.imap", /* tp_name */
787 sizeof(imapobject), /* tp_basicsize */
788 0, /* tp_itemsize */
789 /* methods */
790 (destructor)imap_dealloc, /* tp_dealloc */
791 0, /* tp_print */
792 0, /* tp_getattr */
793 0, /* tp_setattr */
794 0, /* tp_compare */
795 0, /* tp_repr */
796 0, /* tp_as_number */
797 0, /* tp_as_sequence */
798 0, /* tp_as_mapping */
799 0, /* tp_hash */
800 0, /* tp_call */
801 0, /* tp_str */
802 PyObject_GenericGetAttr, /* tp_getattro */
803 0, /* tp_setattro */
804 0, /* tp_as_buffer */
805 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
806 Py_TPFLAGS_BASETYPE, /* tp_flags */
807 imap_doc, /* tp_doc */
808 (traverseproc)imap_traverse, /* tp_traverse */
809 0, /* tp_clear */
810 0, /* tp_richcompare */
811 0, /* tp_weaklistoffset */
812 (getiterfunc)imap_getiter, /* tp_iter */
813 (iternextfunc)imap_next, /* tp_iternext */
814 0, /* tp_methods */
815 0, /* tp_members */
816 0, /* tp_getset */
817 0, /* tp_base */
818 0, /* tp_dict */
819 0, /* tp_descr_get */
820 0, /* tp_descr_set */
821 0, /* tp_dictoffset */
822 0, /* tp_init */
823 PyType_GenericAlloc, /* tp_alloc */
824 imap_new, /* tp_new */
825 PyObject_GC_Del, /* tp_free */
826};
827
828
829/* times object ************************************************************/
830
831typedef struct {
832 PyObject_HEAD
833 PyObject *obj;
834 long cnt;
835} timesobject;
836
837PyTypeObject times_type;
838
839static PyObject *
840times_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
841{
842 timesobject *lz;
843 PyObject *obj = Py_None;
844 long cnt;
845
846 if (!PyArg_ParseTuple(args, "l|O:times", &cnt, &obj))
847 return NULL;
848
849 if (cnt < 0) {
850 PyErr_SetString(PyExc_ValueError,
Raymond Hettinger2012f172003-02-07 05:32:58 +0000851 "count for times() cannot be negative.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000852 return NULL;
853 }
854
855 /* create timesobject structure */
856 lz = (timesobject *)type->tp_alloc(type, 0);
857 if (lz == NULL)
858 return NULL;
859 lz->cnt = cnt;
860 Py_INCREF(obj);
861 lz->obj = obj;
862
863 return (PyObject *)lz;
864}
865
866static void
867times_dealloc(timesobject *lz)
868{
869 PyObject_GC_UnTrack(lz);
870 Py_XDECREF(lz->obj);
871 lz->ob_type->tp_free(lz);
872}
873
Raymond Hettinger2012f172003-02-07 05:32:58 +0000874static int
875times_traverse(timesobject *lz, visitproc visit, void *arg)
876{
877 if (lz->obj)
878 return visit(lz->obj, arg);
879 return 0;
880}
881
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000882static PyObject *
883times_next(timesobject *lz)
884{
885 PyObject *obj = lz->obj;
886
887 if (lz->cnt > 0) {
888 lz->cnt--;
889 Py_INCREF(obj);
890 return obj;
891 }
892 return NULL;
893}
894
895static PyObject *
896times_getiter(PyObject *lz)
897{
898 Py_INCREF(lz);
899 return lz;
900}
901
902PyDoc_STRVAR(times_doc,
903"times(n [,obj]) --> times object\n\
904\n\
905Return a times object whose .next() method returns n consecutive\n\
906instances of obj (default is None).");
907
908PyTypeObject times_type = {
909 PyObject_HEAD_INIT(NULL)
910 0, /* ob_size */
911 "itertools.times", /* tp_name */
912 sizeof(timesobject), /* tp_basicsize */
913 0, /* tp_itemsize */
914 /* methods */
915 (destructor)times_dealloc, /* tp_dealloc */
916 0, /* tp_print */
917 0, /* tp_getattr */
918 0, /* tp_setattr */
919 0, /* tp_compare */
920 0, /* tp_repr */
921 0, /* tp_as_number */
922 0, /* tp_as_sequence */
923 0, /* tp_as_mapping */
924 0, /* tp_hash */
925 0, /* tp_call */
926 0, /* tp_str */
927 PyObject_GenericGetAttr, /* tp_getattro */
928 0, /* tp_setattro */
929 0, /* tp_as_buffer */
930 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
931 Py_TPFLAGS_BASETYPE, /* tp_flags */
932 times_doc, /* tp_doc */
Raymond Hettinger2012f172003-02-07 05:32:58 +0000933 (traverseproc)times_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000934 0, /* tp_clear */
935 0, /* tp_richcompare */
936 0, /* tp_weaklistoffset */
937 (getiterfunc)times_getiter, /* tp_iter */
938 (iternextfunc)times_next, /* tp_iternext */
939 0, /* tp_methods */
940 0, /* tp_members */
941 0, /* tp_getset */
942 0, /* tp_base */
943 0, /* tp_dict */
944 0, /* tp_descr_get */
945 0, /* tp_descr_set */
946 0, /* tp_dictoffset */
947 0, /* tp_init */
948 PyType_GenericAlloc, /* tp_alloc */
949 times_new, /* tp_new */
950 PyObject_GC_Del, /* tp_free */
951};
952
953
954/* ifilter object ************************************************************/
955
956typedef struct {
957 PyObject_HEAD
958 PyObject *func;
959 PyObject *it;
960 long invert;
961} ifilterobject;
962
963PyTypeObject ifilter_type;
964
965static PyObject *
966ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
967{
968 PyObject *func, *seq, *invert=NULL;
969 PyObject *it;
970 ifilterobject *lz;
971 long inv=0;
972
973 if (!PyArg_UnpackTuple(args, "ifilter", 2, 3, &func, &seq, &invert))
974 return NULL;
975
976 if (invert != NULL && PyObject_IsTrue(invert))
977 inv = 1;
978
979 /* Get iterator. */
980 it = PyObject_GetIter(seq);
981 if (it == NULL)
982 return NULL;
983
984 /* create ifilterobject structure */
985 lz = (ifilterobject *)type->tp_alloc(type, 0);
986 if (lz == NULL) {
987 Py_DECREF(it);
988 return NULL;
989 }
990 Py_INCREF(func);
991 lz->func = func;
992 lz->it = it;
993 lz->invert = inv;
994
995 return (PyObject *)lz;
996}
997
998static void
999ifilter_dealloc(ifilterobject *lz)
1000{
1001 PyObject_GC_UnTrack(lz);
1002 Py_XDECREF(lz->func);
1003 Py_XDECREF(lz->it);
1004 lz->ob_type->tp_free(lz);
1005}
1006
1007static int
1008ifilter_traverse(ifilterobject *lz, visitproc visit, void *arg)
1009{
1010 int err;
1011
1012 if (lz->it) {
1013 err = visit(lz->it, arg);
1014 if (err)
1015 return err;
1016 }
1017 if (lz->func) {
1018 err = visit(lz->func, arg);
1019 if (err)
1020 return err;
1021 }
1022 return 0;
1023}
1024
1025static PyObject *
1026ifilter_next(ifilterobject *lz)
1027{
1028 PyObject *item;
1029 long ok;
1030
1031 for (;;) {
1032 item = PyIter_Next(lz->it);
1033 if (item == NULL)
1034 return NULL;
1035
1036 if (lz->func == Py_None) {
1037 ok = PyObject_IsTrue(item);
1038 } else {
1039 PyObject *good;
1040 good = PyObject_CallFunctionObjArgs(lz->func,
1041 item, NULL);
1042 if (good == NULL) {
1043 Py_DECREF(item);
1044 return NULL;
1045 }
1046 ok = PyObject_IsTrue(good);
1047 Py_DECREF(good);
1048 }
1049 if (ok ^ lz->invert)
1050 return item;
1051 Py_DECREF(item);
1052 }
1053}
1054
1055static PyObject *
1056ifilter_getiter(PyObject *lz)
1057{
1058 Py_INCREF(lz);
1059 return lz;
1060}
1061
1062PyDoc_STRVAR(ifilter_doc,
1063"ifilter(function or None, sequence [, invert]) --> ifilter object\n\
1064\n\
1065Return those items of sequence for which function(item) is true. If\n\
1066invert is set to True, return items for which function(item) if False.\n\
1067If function is None, return the items that are true (unless invert is set).");
1068
1069PyTypeObject ifilter_type = {
1070 PyObject_HEAD_INIT(NULL)
1071 0, /* ob_size */
1072 "itertools.ifilter", /* tp_name */
1073 sizeof(ifilterobject), /* tp_basicsize */
1074 0, /* tp_itemsize */
1075 /* methods */
1076 (destructor)ifilter_dealloc, /* tp_dealloc */
1077 0, /* tp_print */
1078 0, /* tp_getattr */
1079 0, /* tp_setattr */
1080 0, /* tp_compare */
1081 0, /* tp_repr */
1082 0, /* tp_as_number */
1083 0, /* tp_as_sequence */
1084 0, /* tp_as_mapping */
1085 0, /* tp_hash */
1086 0, /* tp_call */
1087 0, /* tp_str */
1088 PyObject_GenericGetAttr, /* tp_getattro */
1089 0, /* tp_setattro */
1090 0, /* tp_as_buffer */
1091 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1092 Py_TPFLAGS_BASETYPE, /* tp_flags */
1093 ifilter_doc, /* tp_doc */
1094 (traverseproc)ifilter_traverse, /* tp_traverse */
1095 0, /* tp_clear */
1096 0, /* tp_richcompare */
1097 0, /* tp_weaklistoffset */
1098 (getiterfunc)ifilter_getiter, /* tp_iter */
1099 (iternextfunc)ifilter_next, /* tp_iternext */
1100 0, /* tp_methods */
1101 0, /* tp_members */
1102 0, /* tp_getset */
1103 0, /* tp_base */
1104 0, /* tp_dict */
1105 0, /* tp_descr_get */
1106 0, /* tp_descr_set */
1107 0, /* tp_dictoffset */
1108 0, /* tp_init */
1109 PyType_GenericAlloc, /* tp_alloc */
1110 ifilter_new, /* tp_new */
1111 PyObject_GC_Del, /* tp_free */
1112};
1113
1114
1115/* count object ************************************************************/
1116
1117typedef struct {
1118 PyObject_HEAD
1119 long cnt;
1120} countobject;
1121
1122PyTypeObject count_type;
1123
1124static PyObject *
1125count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1126{
1127 countobject *lz;
1128 long cnt = 0;
1129
1130 if (!PyArg_ParseTuple(args, "|l:count", &cnt))
1131 return NULL;
1132
1133 /* create countobject structure */
1134 lz = (countobject *)PyObject_New(countobject, &count_type);
1135 if (lz == NULL)
1136 return NULL;
1137 lz->cnt = cnt;
1138
1139 return (PyObject *)lz;
1140}
1141
1142static PyObject *
1143count_next(countobject *lz)
1144{
1145 return PyInt_FromLong(lz->cnt++);
1146}
1147
1148static PyObject *
1149count_getiter(PyObject *lz)
1150{
1151 Py_INCREF(lz);
1152 return lz;
1153}
1154
1155PyDoc_STRVAR(count_doc,
1156"count([firstval]) --> count object\n\
1157\n\
1158Return a count object whose .next() method returns consecutive\n\
1159integers starting from zero or, if specified, from firstval.");
1160
1161PyTypeObject count_type = {
1162 PyObject_HEAD_INIT(NULL)
1163 0, /* ob_size */
1164 "itertools.count", /* tp_name */
1165 sizeof(countobject), /* tp_basicsize */
1166 0, /* tp_itemsize */
1167 /* methods */
1168 (destructor)PyObject_Del, /* tp_dealloc */
1169 0, /* tp_print */
1170 0, /* tp_getattr */
1171 0, /* tp_setattr */
1172 0, /* tp_compare */
1173 0, /* tp_repr */
1174 0, /* tp_as_number */
1175 0, /* tp_as_sequence */
1176 0, /* tp_as_mapping */
1177 0, /* tp_hash */
1178 0, /* tp_call */
1179 0, /* tp_str */
1180 PyObject_GenericGetAttr, /* tp_getattro */
1181 0, /* tp_setattro */
1182 0, /* tp_as_buffer */
1183 Py_TPFLAGS_DEFAULT, /* tp_flags */
1184 count_doc, /* tp_doc */
1185 0, /* tp_traverse */
1186 0, /* tp_clear */
1187 0, /* tp_richcompare */
1188 0, /* tp_weaklistoffset */
1189 (getiterfunc)count_getiter, /* tp_iter */
1190 (iternextfunc)count_next, /* tp_iternext */
1191 0, /* tp_methods */
1192 0, /* tp_members */
1193 0, /* tp_getset */
1194 0, /* tp_base */
1195 0, /* tp_dict */
1196 0, /* tp_descr_get */
1197 0, /* tp_descr_set */
1198 0, /* tp_dictoffset */
1199 0, /* tp_init */
1200 PyType_GenericAlloc, /* tp_alloc */
1201 count_new, /* tp_new */
1202};
1203
1204
1205/* izip object ************************************************************/
1206
1207#include "Python.h"
1208
1209typedef struct {
1210 PyObject_HEAD
1211 long tuplesize;
1212 PyObject *ittuple; /* tuple of iterators */
Raymond Hettinger2012f172003-02-07 05:32:58 +00001213 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001214} izipobject;
1215
1216PyTypeObject izip_type;
1217
1218static PyObject *
1219izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1220{
1221 izipobject *lz;
1222 int i;
1223 PyObject *ittuple; /* tuple of iterators */
Raymond Hettinger2012f172003-02-07 05:32:58 +00001224 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001225 int tuplesize = PySequence_Length(args);
1226
1227 if (tuplesize < 1) {
1228 PyErr_SetString(PyExc_TypeError,
1229 "izip() requires at least one sequence");
1230 return NULL;
1231 }
1232
1233 /* args must be a tuple */
1234 assert(PyTuple_Check(args));
1235
1236 /* obtain iterators */
1237 ittuple = PyTuple_New(tuplesize);
1238 if(ittuple == NULL)
1239 return NULL;
1240 for (i=0; i < tuplesize; ++i) {
1241 PyObject *item = PyTuple_GET_ITEM(args, i);
1242 PyObject *it = PyObject_GetIter(item);
1243 if (it == NULL) {
1244 if (PyErr_ExceptionMatches(PyExc_TypeError))
1245 PyErr_Format(PyExc_TypeError,
1246 "izip argument #%d must support iteration",
1247 i+1);
1248 Py_DECREF(ittuple);
1249 return NULL;
1250 }
1251 PyTuple_SET_ITEM(ittuple, i, it);
1252 }
1253
Raymond Hettinger2012f172003-02-07 05:32:58 +00001254 /* create a result holder */
1255 result = PyTuple_New(tuplesize);
1256 if (result == NULL) {
1257 Py_DECREF(ittuple);
1258 return NULL;
1259 }
1260 for (i=0 ; i < tuplesize ; i++) {
1261 Py_INCREF(Py_None);
1262 PyTuple_SET_ITEM(result, i, Py_None);
1263 }
1264
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001265 /* create izipobject structure */
1266 lz = (izipobject *)type->tp_alloc(type, 0);
1267 if (lz == NULL) {
1268 Py_DECREF(ittuple);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001269 Py_DECREF(result);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001270 return NULL;
1271 }
1272 lz->ittuple = ittuple;
1273 lz->tuplesize = tuplesize;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001274 lz->result = result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001275
1276 return (PyObject *)lz;
1277}
1278
1279static void
1280izip_dealloc(izipobject *lz)
1281{
1282 PyObject_GC_UnTrack(lz);
1283 Py_XDECREF(lz->ittuple);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001284 Py_XDECREF(lz->result);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001285 lz->ob_type->tp_free(lz);
1286}
1287
1288static int
1289izip_traverse(izipobject *lz, visitproc visit, void *arg)
1290{
1291 if (lz->ittuple)
1292 return visit(lz->ittuple, arg);
1293 return 0;
1294}
1295
1296static PyObject *
1297izip_next(izipobject *lz)
1298{
1299 int i;
1300 long tuplesize = lz->tuplesize;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001301 PyObject *result = lz->result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001302 PyObject *it;
1303 PyObject *item;
1304
Raymond Hettinger2012f172003-02-07 05:32:58 +00001305 if (result->ob_refcnt == 1) {
1306 for (i=0 ; i < tuplesize ; i++) {
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001307 it = PyTuple_GET_ITEM(lz->ittuple, i);
1308 item = PyIter_Next(it);
1309 if (item == NULL)
1310 return NULL;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001311 Py_DECREF(PyTuple_GET_ITEM(result, i));
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001312 PyTuple_SET_ITEM(result, i, item);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001313 }
1314 Py_INCREF(result);
1315 } else {
Raymond Hettinger2012f172003-02-07 05:32:58 +00001316 result = PyTuple_New(tuplesize);
1317 if (result == NULL)
1318 return NULL;
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001319 for (i=0 ; i < tuplesize ; i++) {
1320 it = PyTuple_GET_ITEM(lz->ittuple, i);
1321 item = PyIter_Next(it);
1322 if (item == NULL) {
1323 Py_DECREF(result);
1324 return NULL;
1325 }
1326 PyTuple_SET_ITEM(result, i, item);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001327 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001328 }
1329 return result;
1330}
1331
1332static PyObject *
1333izip_getiter(PyObject *lz)
1334{
1335 Py_INCREF(lz);
1336 return lz;
1337}
1338
1339PyDoc_STRVAR(izip_doc,
1340"izip(iter1 [,iter2 [...]]) --> izip object\n\
1341\n\
1342Return a izip object whose .next() method returns a tuple where\n\
1343the i-th element comes from the i-th iterable argument. The .next()\n\
1344method continues until the shortest iterable in the argument sequence\n\
1345is exhausted and then it raises StopIteration. Works like the zip()\n\
1346function but consumes less memory by returning an iterator instead of\n\
1347a list.");
1348
1349PyTypeObject izip_type = {
1350 PyObject_HEAD_INIT(NULL)
1351 0, /* ob_size */
1352 "itertools.izip", /* tp_name */
1353 sizeof(izipobject), /* tp_basicsize */
1354 0, /* tp_itemsize */
1355 /* methods */
1356 (destructor)izip_dealloc, /* tp_dealloc */
1357 0, /* tp_print */
1358 0, /* tp_getattr */
1359 0, /* tp_setattr */
1360 0, /* tp_compare */
1361 0, /* tp_repr */
1362 0, /* tp_as_number */
1363 0, /* tp_as_sequence */
1364 0, /* tp_as_mapping */
1365 0, /* tp_hash */
1366 0, /* tp_call */
1367 0, /* tp_str */
1368 PyObject_GenericGetAttr, /* tp_getattro */
1369 0, /* tp_setattro */
1370 0, /* tp_as_buffer */
1371 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1372 Py_TPFLAGS_BASETYPE, /* tp_flags */
1373 izip_doc, /* tp_doc */
1374 (traverseproc)izip_traverse, /* tp_traverse */
1375 0, /* tp_clear */
1376 0, /* tp_richcompare */
1377 0, /* tp_weaklistoffset */
1378 (getiterfunc)izip_getiter, /* tp_iter */
1379 (iternextfunc)izip_next, /* tp_iternext */
1380 0, /* tp_methods */
1381 0, /* tp_members */
1382 0, /* tp_getset */
1383 0, /* tp_base */
1384 0, /* tp_dict */
1385 0, /* tp_descr_get */
1386 0, /* tp_descr_set */
1387 0, /* tp_dictoffset */
1388 0, /* tp_init */
1389 PyType_GenericAlloc, /* tp_alloc */
1390 izip_new, /* tp_new */
1391 PyObject_GC_Del, /* tp_free */
1392};
1393
1394
1395/* repeat object ************************************************************/
1396
1397typedef struct {
1398 PyObject_HEAD
1399 PyObject *element;
1400} repeatobject;
1401
1402PyTypeObject repeat_type;
1403
1404static PyObject *
1405repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1406{
1407 repeatobject *ro;
1408 PyObject *element;
1409
1410 if (!PyArg_UnpackTuple(args, "repeat", 1, 1, &element))
1411 return NULL;
1412
1413 ro = (repeatobject *)type->tp_alloc(type, 0);
1414 if (ro == NULL)
1415 return NULL;
1416 Py_INCREF(element);
1417 ro->element = element;
1418 return (PyObject *)ro;
1419}
1420
1421static void
1422repeat_dealloc(repeatobject *ro)
1423{
1424 PyObject_GC_UnTrack(ro);
1425 Py_XDECREF(ro->element);
1426 ro->ob_type->tp_free(ro);
1427}
1428
1429static int
1430repeat_traverse(repeatobject *ro, visitproc visit, void *arg)
1431{
1432 if (ro->element)
1433 return visit(ro->element, arg);
1434 return 0;
1435}
1436
1437static PyObject *
1438repeat_next(repeatobject *ro)
1439{
1440 Py_INCREF(ro->element);
1441 return ro->element;
1442}
1443
1444static PyObject *
1445repeat_getiter(PyObject *ro)
1446{
1447 Py_INCREF(ro);
1448 return ro;
1449}
1450
1451PyDoc_STRVAR(repeat_doc,
1452"repeat(element) -> create an iterator which returns the element endlessly.");
1453
1454PyTypeObject repeat_type = {
1455 PyObject_HEAD_INIT(NULL)
1456 0, /* ob_size */
1457 "itertools.repeat", /* tp_name */
1458 sizeof(repeatobject), /* tp_basicsize */
1459 0, /* tp_itemsize */
1460 /* methods */
1461 (destructor)repeat_dealloc, /* tp_dealloc */
1462 0, /* tp_print */
1463 0, /* tp_getattr */
1464 0, /* tp_setattr */
1465 0, /* tp_compare */
1466 0, /* tp_repr */
1467 0, /* tp_as_number */
1468 0, /* tp_as_sequence */
1469 0, /* tp_as_mapping */
1470 0, /* tp_hash */
1471 0, /* tp_call */
1472 0, /* tp_str */
1473 PyObject_GenericGetAttr, /* tp_getattro */
1474 0, /* tp_setattro */
1475 0, /* tp_as_buffer */
1476 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1477 Py_TPFLAGS_BASETYPE, /* tp_flags */
1478 repeat_doc, /* tp_doc */
1479 (traverseproc)repeat_traverse, /* tp_traverse */
1480 0, /* tp_clear */
1481 0, /* tp_richcompare */
1482 0, /* tp_weaklistoffset */
1483 (getiterfunc)repeat_getiter, /* tp_iter */
1484 (iternextfunc)repeat_next, /* tp_iternext */
1485 0, /* tp_methods */
1486 0, /* tp_members */
1487 0, /* tp_getset */
1488 0, /* tp_base */
1489 0, /* tp_dict */
1490 0, /* tp_descr_get */
1491 0, /* tp_descr_set */
1492 0, /* tp_dictoffset */
1493 0, /* tp_init */
1494 PyType_GenericAlloc, /* tp_alloc */
1495 repeat_new, /* tp_new */
1496 PyObject_GC_Del, /* tp_free */
1497};
1498
1499
1500/* module level code ********************************************************/
1501
1502PyDoc_STRVAR(module_doc,
1503"Functional tools for creating and using iterators.\n\
1504\n\
1505Infinite iterators:\n\
1506count([n]) --> n, n+1, n+2, ...\n\
1507repeat(elem) --> elem, elem, elem, ...\n\
1508\n\
1509Iterators terminating on the shortest input sequence:\n\
1510izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
1511ifilter(pred, seq, invert=False) --> elements of seq where\n\
1512 pred(elem) is True (or False if invert is set)\n\
1513islice(seq, [start,] stop [, step]) --> elements from\n\
1514 seq[start:stop:step]\n\
1515imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\
1516starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\
1517times(n, [obj]) --> obj, obj, ... for n times. obj defaults to None\n\
1518takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\
1519dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\
1520");
1521
1522
1523PyMODINIT_FUNC
1524inititertools(void)
1525{
1526 PyObject *m;
1527 m = Py_InitModule3("itertools", NULL, module_doc);
1528
1529 PyModule_AddObject(m, "dropwhile", (PyObject *)&dropwhile_type);
1530 if (PyType_Ready(&dropwhile_type) < 0)
1531 return;
1532 Py_INCREF(&dropwhile_type);
1533
1534 PyModule_AddObject(m, "takewhile", (PyObject *)&takewhile_type);
1535 if (PyType_Ready(&takewhile_type) < 0)
1536 return;
1537 Py_INCREF(&takewhile_type);
1538
1539 PyModule_AddObject(m, "islice", (PyObject *)&islice_type);
1540 if (PyType_Ready(&islice_type) < 0)
1541 return;
1542 Py_INCREF(&islice_type);
1543
1544 PyModule_AddObject(m, "starmap", (PyObject *)&starmap_type);
1545 if (PyType_Ready(&starmap_type) < 0)
1546 return;
1547 Py_INCREF(&starmap_type);
1548
1549 PyModule_AddObject(m, "imap", (PyObject *)&imap_type);
1550 if (PyType_Ready(&imap_type) < 0)
1551 return;
1552 Py_INCREF(&imap_type);
1553
1554 PyModule_AddObject(m, "times", (PyObject *)&times_type);
1555 if (PyType_Ready(&times_type) < 0)
1556 return;
1557 Py_INCREF(&times_type);
1558
1559 if (PyType_Ready(&ifilter_type) < 0)
1560 return;
1561 Py_INCREF(&ifilter_type);
1562 PyModule_AddObject(m, "ifilter", (PyObject *)&ifilter_type);
1563
1564 if (PyType_Ready(&count_type) < 0)
1565 return;
1566 Py_INCREF(&count_type);
1567 PyModule_AddObject(m, "count", (PyObject *)&count_type);
1568
1569 if (PyType_Ready(&izip_type) < 0)
1570 return;
1571 Py_INCREF(&izip_type);
1572 PyModule_AddObject(m, "izip", (PyObject *)&izip_type);
1573
1574 if (PyType_Ready(&repeat_type) < 0)
1575 return;
1576 Py_INCREF(&repeat_type);
1577 PyModule_AddObject(m, "repeat", (PyObject *)&repeat_type);
1578}