blob: a76d8c2e00926dd8b6b90474eb3592e0e185faff [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
Raymond Hettinger61fe64d2003-02-23 04:40:07 +000010/* cycle object **********************************************************/
11
12typedef struct {
13 PyObject_HEAD
14 PyObject *it;
15 PyObject *saved;
16 int firstpass;
17} cycleobject;
18
19PyTypeObject cycle_type;
20
21static PyObject *
22cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
23{
24 PyObject *it;
25 PyObject *iterable;
26 PyObject *saved;
27 cycleobject *lz;
28
29 if (!PyArg_UnpackTuple(args, "cycle", 1, 1, &iterable))
30 return NULL;
31
32 /* Get iterator. */
33 it = PyObject_GetIter(iterable);
34 if (it == NULL)
35 return NULL;
36
37 saved = PyList_New(0);
38 if (saved == NULL) {
39 Py_DECREF(it);
40 return NULL;
41 }
42
43 /* create cycleobject structure */
44 lz = (cycleobject *)type->tp_alloc(type, 0);
45 if (lz == NULL) {
46 Py_DECREF(it);
47 Py_DECREF(saved);
48 return NULL;
49 }
50 lz->it = it;
51 lz->saved = saved;
52 lz->firstpass = 0;
53
54 return (PyObject *)lz;
55}
56
57static void
58cycle_dealloc(cycleobject *lz)
59{
60 PyObject_GC_UnTrack(lz);
61 Py_XDECREF(lz->saved);
62 Py_XDECREF(lz->it);
63 lz->ob_type->tp_free(lz);
64}
65
66static int
67cycle_traverse(cycleobject *lz, visitproc visit, void *arg)
68{
69 int err;
70
71 if (lz->it) {
72 err = visit(lz->it, arg);
73 if (err)
74 return err;
75 }
76 if (lz->saved) {
77 err = visit(lz->saved, arg);
78 if (err)
79 return err;
80 }
81 return 0;
82}
83
84static PyObject *
85cycle_next(cycleobject *lz)
86{
87 PyObject *item;
88 PyObject *it;
89
90 while (1) {
91 item = PyIter_Next(lz->it);
92 if (item != NULL) {
93 if (!lz->firstpass)
94 PyList_Append(lz->saved, item);
95 return item;
96 }
97 if (PyList_Size(lz->saved) == 0)
98 return NULL;
99 it = PyObject_GetIter(lz->saved);
100 if (it == NULL)
101 return NULL;
102 Py_DECREF(lz->it);
103 lz->it = it;
104 lz->firstpass = 1;
105 }
106}
107
108static PyObject *
109cycle_getiter(PyObject *lz)
110{
111 Py_INCREF(lz);
112 return lz;
113}
114
115PyDoc_STRVAR(cycle_doc,
116"cycle(iterable) --> cycle object\n\
117\n\
118Return elements from the iterable until it is exhausted.\n\
119Then repeat the sequence indefinitely.");
120
121PyTypeObject cycle_type = {
122 PyObject_HEAD_INIT(NULL)
123 0, /* ob_size */
124 "itertools.cycle", /* tp_name */
125 sizeof(cycleobject), /* tp_basicsize */
126 0, /* tp_itemsize */
127 /* methods */
128 (destructor)cycle_dealloc, /* tp_dealloc */
129 0, /* tp_print */
130 0, /* tp_getattr */
131 0, /* tp_setattr */
132 0, /* tp_compare */
133 0, /* tp_repr */
134 0, /* tp_as_number */
135 0, /* tp_as_sequence */
136 0, /* tp_as_mapping */
137 0, /* tp_hash */
138 0, /* tp_call */
139 0, /* tp_str */
140 PyObject_GenericGetAttr, /* tp_getattro */
141 0, /* tp_setattro */
142 0, /* tp_as_buffer */
143 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
144 Py_TPFLAGS_BASETYPE, /* tp_flags */
145 cycle_doc, /* tp_doc */
146 (traverseproc)cycle_traverse, /* tp_traverse */
147 0, /* tp_clear */
148 0, /* tp_richcompare */
149 0, /* tp_weaklistoffset */
150 (getiterfunc)cycle_getiter, /* tp_iter */
151 (iternextfunc)cycle_next, /* tp_iternext */
152 0, /* tp_methods */
153 0, /* tp_members */
154 0, /* tp_getset */
155 0, /* tp_base */
156 0, /* tp_dict */
157 0, /* tp_descr_get */
158 0, /* tp_descr_set */
159 0, /* tp_dictoffset */
160 0, /* tp_init */
161 PyType_GenericAlloc, /* tp_alloc */
162 cycle_new, /* tp_new */
163 PyObject_GC_Del, /* tp_free */
164};
165
166
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000167/* dropwhile object **********************************************************/
168
169typedef struct {
170 PyObject_HEAD
171 PyObject *func;
172 PyObject *it;
173 long start;
174} dropwhileobject;
175
176PyTypeObject dropwhile_type;
177
178static PyObject *
179dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
180{
181 PyObject *func, *seq;
182 PyObject *it;
183 dropwhileobject *lz;
184
185 if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq))
186 return NULL;
187
188 /* Get iterator. */
189 it = PyObject_GetIter(seq);
190 if (it == NULL)
191 return NULL;
192
193 /* create dropwhileobject structure */
194 lz = (dropwhileobject *)type->tp_alloc(type, 0);
195 if (lz == NULL) {
196 Py_DECREF(it);
197 return NULL;
198 }
199 Py_INCREF(func);
200 lz->func = func;
201 lz->it = it;
202 lz->start = 0;
203
204 return (PyObject *)lz;
205}
206
207static void
208dropwhile_dealloc(dropwhileobject *lz)
209{
210 PyObject_GC_UnTrack(lz);
211 Py_XDECREF(lz->func);
212 Py_XDECREF(lz->it);
213 lz->ob_type->tp_free(lz);
214}
215
216static int
217dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg)
218{
219 int err;
220
221 if (lz->it) {
222 err = visit(lz->it, arg);
223 if (err)
224 return err;
225 }
226 if (lz->func) {
227 err = visit(lz->func, arg);
228 if (err)
229 return err;
230 }
231 return 0;
232}
233
234static PyObject *
235dropwhile_next(dropwhileobject *lz)
236{
237 PyObject *item, *good;
238 long ok;
239
240 for (;;) {
241 item = PyIter_Next(lz->it);
242 if (item == NULL)
243 return NULL;
244 if (lz->start == 1)
245 return item;
246
247 good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
248 if (good == NULL) {
249 Py_DECREF(item);
250 return NULL;
251 }
252 ok = PyObject_IsTrue(good);
253 Py_DECREF(good);
254 if (!ok) {
255 lz->start = 1;
256 return item;
257 }
258 Py_DECREF(item);
259 }
260}
261
262static PyObject *
263dropwhile_getiter(PyObject *lz)
264{
265 Py_INCREF(lz);
266 return lz;
267}
268
269PyDoc_STRVAR(dropwhile_doc,
270"dropwhile(predicate, iterable) --> dropwhile object\n\
271\n\
272Drop items from the iterable while predicate(item) is true.\n\
273Afterwards, return every element until the iterable is exhausted.");
274
275PyTypeObject dropwhile_type = {
276 PyObject_HEAD_INIT(NULL)
277 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000278 "itertools.dropwhile", /* tp_name */
279 sizeof(dropwhileobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000280 0, /* tp_itemsize */
281 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000282 (destructor)dropwhile_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000283 0, /* tp_print */
284 0, /* tp_getattr */
285 0, /* tp_setattr */
286 0, /* tp_compare */
287 0, /* tp_repr */
288 0, /* tp_as_number */
289 0, /* tp_as_sequence */
290 0, /* tp_as_mapping */
291 0, /* tp_hash */
292 0, /* tp_call */
293 0, /* tp_str */
294 PyObject_GenericGetAttr, /* tp_getattro */
295 0, /* tp_setattro */
296 0, /* tp_as_buffer */
297 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
298 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000299 dropwhile_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000300 (traverseproc)dropwhile_traverse, /* tp_traverse */
301 0, /* tp_clear */
302 0, /* tp_richcompare */
303 0, /* tp_weaklistoffset */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000304 (getiterfunc)dropwhile_getiter, /* tp_iter */
305 (iternextfunc)dropwhile_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000306 0, /* tp_methods */
307 0, /* tp_members */
308 0, /* tp_getset */
309 0, /* tp_base */
310 0, /* tp_dict */
311 0, /* tp_descr_get */
312 0, /* tp_descr_set */
313 0, /* tp_dictoffset */
314 0, /* tp_init */
315 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000316 dropwhile_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000317 PyObject_GC_Del, /* tp_free */
318};
319
320
321/* takewhile object **********************************************************/
322
323typedef struct {
324 PyObject_HEAD
325 PyObject *func;
326 PyObject *it;
327 long stop;
328} takewhileobject;
329
330PyTypeObject takewhile_type;
331
332static PyObject *
333takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
334{
335 PyObject *func, *seq;
336 PyObject *it;
337 takewhileobject *lz;
338
339 if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq))
340 return NULL;
341
342 /* Get iterator. */
343 it = PyObject_GetIter(seq);
344 if (it == NULL)
345 return NULL;
346
347 /* create takewhileobject structure */
348 lz = (takewhileobject *)type->tp_alloc(type, 0);
349 if (lz == NULL) {
350 Py_DECREF(it);
351 return NULL;
352 }
353 Py_INCREF(func);
354 lz->func = func;
355 lz->it = it;
356 lz->stop = 0;
357
358 return (PyObject *)lz;
359}
360
361static void
362takewhile_dealloc(takewhileobject *lz)
363{
364 PyObject_GC_UnTrack(lz);
365 Py_XDECREF(lz->func);
366 Py_XDECREF(lz->it);
367 lz->ob_type->tp_free(lz);
368}
369
370static int
371takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg)
372{
373 int err;
374
375 if (lz->it) {
376 err = visit(lz->it, arg);
377 if (err)
378 return err;
379 }
380 if (lz->func) {
381 err = visit(lz->func, arg);
382 if (err)
383 return err;
384 }
385 return 0;
386}
387
388static PyObject *
389takewhile_next(takewhileobject *lz)
390{
391 PyObject *item, *good;
392 long ok;
393
394 if (lz->stop == 1)
395 return NULL;
396
397 item = PyIter_Next(lz->it);
398 if (item == NULL)
399 return NULL;
400
401 good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
402 if (good == NULL) {
403 Py_DECREF(item);
404 return NULL;
405 }
406 ok = PyObject_IsTrue(good);
407 Py_DECREF(good);
408 if (ok)
409 return item;
410 Py_DECREF(item);
411 lz->stop = 1;
412 return NULL;
413}
414
415static PyObject *
416takewhile_getiter(PyObject *lz)
417{
418 Py_INCREF(lz);
419 return lz;
420}
421
422PyDoc_STRVAR(takewhile_doc,
423"takewhile(predicate, iterable) --> takewhile object\n\
424\n\
425Return successive entries from an iterable as long as the \n\
426predicate evaluates to true for each entry.");
427
428PyTypeObject takewhile_type = {
429 PyObject_HEAD_INIT(NULL)
430 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000431 "itertools.takewhile", /* tp_name */
432 sizeof(takewhileobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000433 0, /* tp_itemsize */
434 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000435 (destructor)takewhile_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000436 0, /* tp_print */
437 0, /* tp_getattr */
438 0, /* tp_setattr */
439 0, /* tp_compare */
440 0, /* tp_repr */
441 0, /* tp_as_number */
442 0, /* tp_as_sequence */
443 0, /* tp_as_mapping */
444 0, /* tp_hash */
445 0, /* tp_call */
446 0, /* tp_str */
447 PyObject_GenericGetAttr, /* tp_getattro */
448 0, /* tp_setattro */
449 0, /* tp_as_buffer */
450 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
451 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000452 takewhile_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000453 (traverseproc)takewhile_traverse, /* tp_traverse */
454 0, /* tp_clear */
455 0, /* tp_richcompare */
456 0, /* tp_weaklistoffset */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000457 (getiterfunc)takewhile_getiter, /* tp_iter */
458 (iternextfunc)takewhile_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000459 0, /* tp_methods */
460 0, /* tp_members */
461 0, /* tp_getset */
462 0, /* tp_base */
463 0, /* tp_dict */
464 0, /* tp_descr_get */
465 0, /* tp_descr_set */
466 0, /* tp_dictoffset */
467 0, /* tp_init */
468 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000469 takewhile_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000470 PyObject_GC_Del, /* tp_free */
471};
472
473
474/* islice object ************************************************************/
475
476typedef struct {
477 PyObject_HEAD
478 PyObject *it;
479 long next;
480 long stop;
481 long step;
482 long cnt;
483} isliceobject;
484
485PyTypeObject islice_type;
486
487static PyObject *
488islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
489{
490 PyObject *seq;
491 long a1=0, a2=0, a3=0, start=0, stop=0, step=1;
492 PyObject *it;
493 int numargs;
494 isliceobject *lz;
495
496 numargs = PyTuple_Size(args);
497 if (!PyArg_ParseTuple(args, "Ol|ll:islice", &seq, &a1, &a2, &a3))
498 return NULL;
499
500 if (numargs == 2) {
501 stop = a1;
502 } else if (numargs == 3) {
503 start = a1;
504 stop = a2;
505 } else {
506 start = a1;
507 stop = a2;
508 step = a3;
509 }
510
511 if (start<0 || stop<0) {
512 PyErr_SetString(PyExc_ValueError,
513 "Indices for islice() must be positive.");
514 return NULL;
515 }
516
517 if (step<1) {
518 PyErr_SetString(PyExc_ValueError,
519 "Step must be one or larger for islice().");
520 return NULL;
521 }
522
523 /* Get iterator. */
524 it = PyObject_GetIter(seq);
525 if (it == NULL)
526 return NULL;
527
528 /* create isliceobject structure */
529 lz = (isliceobject *)type->tp_alloc(type, 0);
530 if (lz == NULL) {
531 Py_DECREF(it);
532 return NULL;
533 }
534 lz->it = it;
535 lz->next = start;
536 lz->stop = stop;
537 lz->step = step;
538 lz->cnt = 0L;
539
540 return (PyObject *)lz;
541}
542
543static void
544islice_dealloc(isliceobject *lz)
545{
546 PyObject_GC_UnTrack(lz);
547 Py_XDECREF(lz->it);
548 lz->ob_type->tp_free(lz);
549}
550
551static int
552islice_traverse(isliceobject *lz, visitproc visit, void *arg)
553{
554 if (lz->it)
555 return visit(lz->it, arg);
556 return 0;
557}
558
559static PyObject *
560islice_next(isliceobject *lz)
561{
562 PyObject *item;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000563 long oldnext;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000564
565 while (lz->cnt < lz->next) {
566 item = PyIter_Next(lz->it);
567 if (item == NULL)
568 return NULL;
569 Py_DECREF(item);
570 lz->cnt++;
571 }
572 if (lz->cnt >= lz->stop)
573 return NULL;
574 item = PyIter_Next(lz->it);
575 if (item == NULL)
576 return NULL;
577 lz->cnt++;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000578 oldnext = lz->next;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000579 lz->next += lz->step;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000580 if (lz->next < oldnext) /* Check for overflow */
581 lz->next = lz->stop;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000582 return item;
583}
584
585static PyObject *
586islice_getiter(PyObject *lz)
587{
588 Py_INCREF(lz);
589 return lz;
590}
591
592PyDoc_STRVAR(islice_doc,
593"islice(iterable, [start,] stop [, step]) --> islice object\n\
594\n\
595Return an iterator whose next() method returns selected values from an\n\
596iterable. If start is specified, will skip all preceding elements;\n\
597otherwise, start defaults to zero. Step defaults to one. If\n\
598specified as another value, step determines how many values are \n\
599skipped between successive calls. Works like a slice() on a list\n\
600but returns an iterator.");
601
602PyTypeObject islice_type = {
603 PyObject_HEAD_INIT(NULL)
604 0, /* ob_size */
605 "itertools.islice", /* tp_name */
606 sizeof(isliceobject), /* tp_basicsize */
607 0, /* tp_itemsize */
608 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000609 (destructor)islice_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000610 0, /* tp_print */
611 0, /* tp_getattr */
612 0, /* tp_setattr */
613 0, /* tp_compare */
614 0, /* tp_repr */
615 0, /* tp_as_number */
616 0, /* tp_as_sequence */
617 0, /* tp_as_mapping */
618 0, /* tp_hash */
619 0, /* tp_call */
620 0, /* tp_str */
621 PyObject_GenericGetAttr, /* tp_getattro */
622 0, /* tp_setattro */
623 0, /* tp_as_buffer */
624 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
625 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000626 islice_doc, /* tp_doc */
627 (traverseproc)islice_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000628 0, /* tp_clear */
629 0, /* tp_richcompare */
630 0, /* tp_weaklistoffset */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000631 (getiterfunc)islice_getiter, /* tp_iter */
632 (iternextfunc)islice_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000633 0, /* tp_methods */
634 0, /* tp_members */
635 0, /* tp_getset */
636 0, /* tp_base */
637 0, /* tp_dict */
638 0, /* tp_descr_get */
639 0, /* tp_descr_set */
640 0, /* tp_dictoffset */
641 0, /* tp_init */
642 PyType_GenericAlloc, /* tp_alloc */
643 islice_new, /* tp_new */
644 PyObject_GC_Del, /* tp_free */
645};
646
647
648/* starmap object ************************************************************/
649
650typedef struct {
651 PyObject_HEAD
652 PyObject *func;
653 PyObject *it;
654} starmapobject;
655
656PyTypeObject starmap_type;
657
658static PyObject *
659starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
660{
661 PyObject *func, *seq;
662 PyObject *it;
663 starmapobject *lz;
664
665 if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq))
666 return NULL;
667
668 /* Get iterator. */
669 it = PyObject_GetIter(seq);
670 if (it == NULL)
671 return NULL;
672
673 /* create starmapobject structure */
674 lz = (starmapobject *)type->tp_alloc(type, 0);
675 if (lz == NULL) {
676 Py_DECREF(it);
677 return NULL;
678 }
679 Py_INCREF(func);
680 lz->func = func;
681 lz->it = it;
682
683 return (PyObject *)lz;
684}
685
686static void
687starmap_dealloc(starmapobject *lz)
688{
689 PyObject_GC_UnTrack(lz);
690 Py_XDECREF(lz->func);
691 Py_XDECREF(lz->it);
692 lz->ob_type->tp_free(lz);
693}
694
695static int
696starmap_traverse(starmapobject *lz, visitproc visit, void *arg)
697{
698 int err;
699
700 if (lz->it) {
701 err = visit(lz->it, arg);
702 if (err)
703 return err;
704 }
705 if (lz->func) {
706 err = visit(lz->func, arg);
707 if (err)
708 return err;
709 }
710 return 0;
711}
712
713static PyObject *
714starmap_next(starmapobject *lz)
715{
716 PyObject *args;
717 PyObject *result;
718
719 args = PyIter_Next(lz->it);
720 if (args == NULL)
721 return NULL;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000722 if (!PyTuple_CheckExact(args)) {
723 Py_DECREF(args);
724 PyErr_SetString(PyExc_TypeError,
725 "iterator must return a tuple");
726 return NULL;
727 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000728 result = PyObject_Call(lz->func, args, NULL);
729 Py_DECREF(args);
730 return result;
731}
732
733static PyObject *
734starmap_getiter(PyObject *lz)
735{
736 Py_INCREF(lz);
737 return lz;
738}
739
740PyDoc_STRVAR(starmap_doc,
741"starmap(function, sequence) --> starmap object\n\
742\n\
743Return an iterator whose values are returned from the function evaluated\n\
744with a argument tuple taken from the given sequence.");
745
746PyTypeObject starmap_type = {
747 PyObject_HEAD_INIT(NULL)
748 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000749 "itertools.starmap", /* tp_name */
750 sizeof(starmapobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000751 0, /* tp_itemsize */
752 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000753 (destructor)starmap_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000754 0, /* tp_print */
755 0, /* tp_getattr */
756 0, /* tp_setattr */
757 0, /* tp_compare */
758 0, /* tp_repr */
759 0, /* tp_as_number */
760 0, /* tp_as_sequence */
761 0, /* tp_as_mapping */
762 0, /* tp_hash */
763 0, /* tp_call */
764 0, /* tp_str */
765 PyObject_GenericGetAttr, /* tp_getattro */
766 0, /* tp_setattro */
767 0, /* tp_as_buffer */
768 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
769 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000770 starmap_doc, /* tp_doc */
771 (traverseproc)starmap_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000772 0, /* tp_clear */
773 0, /* tp_richcompare */
774 0, /* tp_weaklistoffset */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000775 (getiterfunc)starmap_getiter, /* tp_iter */
776 (iternextfunc)starmap_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000777 0, /* tp_methods */
778 0, /* tp_members */
779 0, /* tp_getset */
780 0, /* tp_base */
781 0, /* tp_dict */
782 0, /* tp_descr_get */
783 0, /* tp_descr_set */
784 0, /* tp_dictoffset */
785 0, /* tp_init */
786 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000787 starmap_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000788 PyObject_GC_Del, /* tp_free */
789};
790
791
792/* imap object ************************************************************/
793
794typedef struct {
795 PyObject_HEAD
796 PyObject *iters;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000797 PyObject *func;
798} imapobject;
799
800PyTypeObject imap_type;
801
802static PyObject *
803imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
804{
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000805 PyObject *it, *iters, *func;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000806 imapobject *lz;
807 int numargs, i;
808
809 numargs = PyTuple_Size(args);
810 if (numargs < 2) {
811 PyErr_SetString(PyExc_TypeError,
812 "imap() must have at least two arguments.");
813 return NULL;
814 }
815
816 iters = PyTuple_New(numargs-1);
817 if (iters == NULL)
818 return NULL;
819
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000820 for (i=1 ; i<numargs ; i++) {
821 /* Get iterator. */
822 it = PyObject_GetIter(PyTuple_GET_ITEM(args, i));
823 if (it == NULL) {
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000824 Py_DECREF(iters);
825 return NULL;
826 }
827 PyTuple_SET_ITEM(iters, i-1, it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000828 }
829
830 /* create imapobject structure */
831 lz = (imapobject *)type->tp_alloc(type, 0);
832 if (lz == NULL) {
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000833 Py_DECREF(iters);
834 return NULL;
835 }
836 lz->iters = iters;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000837 func = PyTuple_GET_ITEM(args, 0);
838 Py_INCREF(func);
839 lz->func = func;
840
841 return (PyObject *)lz;
842}
843
844static void
845imap_dealloc(imapobject *lz)
846{
847 PyObject_GC_UnTrack(lz);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000848 Py_XDECREF(lz->iters);
849 Py_XDECREF(lz->func);
850 lz->ob_type->tp_free(lz);
851}
852
853static int
854imap_traverse(imapobject *lz, visitproc visit, void *arg)
855{
856 int err;
857
858 if (lz->iters) {
859 err = visit(lz->iters, arg);
860 if (err)
861 return err;
862 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000863 if (lz->func) {
864 err = visit(lz->func, arg);
865 if (err)
866 return err;
867 }
868 return 0;
869}
870
Raymond Hettinger2012f172003-02-07 05:32:58 +0000871/*
872imap() is an iterator version of __builtins__.map() except that it does
873not have the None fill-in feature. That was intentionally left out for
874the following reasons:
875
876 1) Itertools are designed to be easily combined and chained together.
877 Having all tools stop with the shortest input is a unifying principle
878 that makes it easier to combine finite iterators (supplying data) with
879 infinite iterators like count() and repeat() (for supplying sequential
880 or constant arguments to a function).
881
882 2) In typical use cases for combining itertools, having one finite data
883 supplier run out before another is likely to be an error condition which
884 should not pass silently by automatically supplying None.
885
886 3) The use cases for automatic None fill-in are rare -- not many functions
887 do something useful when a parameter suddenly switches type and becomes
888 None.
889
890 4) If a need does arise, it can be met by __builtins__.map() or by
891 writing a generator.
892
893 5) Similar toolsets in Haskell and SML do not have automatic None fill-in.
894*/
895
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000896static PyObject *
897imap_next(imapobject *lz)
898{
899 PyObject *val;
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000900 PyObject *argtuple;
901 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000902 int numargs, i;
903
904 numargs = PyTuple_Size(lz->iters);
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000905 argtuple = PyTuple_New(numargs);
906 if (argtuple == NULL)
907 return NULL;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000908
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000909 for (i=0 ; i<numargs ; i++) {
910 val = PyIter_Next(PyTuple_GET_ITEM(lz->iters, i));
911 if (val == NULL) {
912 Py_DECREF(argtuple);
913 return NULL;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000914 }
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000915 PyTuple_SET_ITEM(argtuple, i, val);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000916 }
Raymond Hettingerf0c00242003-02-07 07:26:25 +0000917 if (lz->func == Py_None)
918 return argtuple;
919 result = PyObject_Call(lz->func, argtuple, NULL);
920 Py_DECREF(argtuple);
921 return result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000922}
923
924static PyObject *
925imap_getiter(PyObject *lz)
926{
927 Py_INCREF(lz);
928 return lz;
929}
930
931PyDoc_STRVAR(imap_doc,
932"imap(func, *iterables) --> imap object\n\
933\n\
934Make an iterator that computes the function using arguments from\n\
935each of the iterables. Like map() except that it returns\n\
936an iterator instead of a list and that it stops when the shortest\n\
937iterable is exhausted instead of filling in None for shorter\n\
938iterables.");
939
940PyTypeObject imap_type = {
941 PyObject_HEAD_INIT(NULL)
942 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000943 "itertools.imap", /* tp_name */
944 sizeof(imapobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000945 0, /* tp_itemsize */
946 /* methods */
947 (destructor)imap_dealloc, /* tp_dealloc */
948 0, /* tp_print */
949 0, /* tp_getattr */
950 0, /* tp_setattr */
951 0, /* tp_compare */
952 0, /* tp_repr */
953 0, /* tp_as_number */
954 0, /* tp_as_sequence */
955 0, /* tp_as_mapping */
956 0, /* tp_hash */
957 0, /* tp_call */
958 0, /* tp_str */
959 PyObject_GenericGetAttr, /* tp_getattro */
960 0, /* tp_setattro */
961 0, /* tp_as_buffer */
962 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
963 Py_TPFLAGS_BASETYPE, /* tp_flags */
964 imap_doc, /* tp_doc */
965 (traverseproc)imap_traverse, /* tp_traverse */
966 0, /* tp_clear */
967 0, /* tp_richcompare */
968 0, /* tp_weaklistoffset */
969 (getiterfunc)imap_getiter, /* tp_iter */
970 (iternextfunc)imap_next, /* tp_iternext */
971 0, /* tp_methods */
972 0, /* tp_members */
973 0, /* tp_getset */
974 0, /* tp_base */
975 0, /* tp_dict */
976 0, /* tp_descr_get */
977 0, /* tp_descr_set */
978 0, /* tp_dictoffset */
979 0, /* tp_init */
980 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000981 imap_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000982 PyObject_GC_Del, /* tp_free */
983};
984
985
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000986/* chain object ************************************************************/
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000987
988typedef struct {
989 PyObject_HEAD
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000990 long tuplesize;
991 long iternum; /* which iterator is active */
992 PyObject *ittuple; /* tuple of iterators */
993} chainobject;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000994
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000995PyTypeObject chain_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000996
997static PyObject *
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000998chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000999{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001000 chainobject *lz;
1001 int tuplesize = PySequence_Length(args);
1002 int i;
1003 PyObject *ittuple;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001004
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001005 /* obtain iterators */
1006 assert(PyTuple_Check(args));
1007 ittuple = PyTuple_New(tuplesize);
1008 if(ittuple == NULL)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001009 return NULL;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001010 for (i=0; i < tuplesize; ++i) {
1011 PyObject *item = PyTuple_GET_ITEM(args, i);
1012 PyObject *it = PyObject_GetIter(item);
1013 if (it == NULL) {
1014 if (PyErr_ExceptionMatches(PyExc_TypeError))
1015 PyErr_Format(PyExc_TypeError,
1016 "chain argument #%d must support iteration",
1017 i+1);
1018 Py_DECREF(ittuple);
1019 return NULL;
1020 }
1021 PyTuple_SET_ITEM(ittuple, i, it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001022 }
1023
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001024 /* create chainobject structure */
1025 lz = (chainobject *)type->tp_alloc(type, 0);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001026 if (lz == NULL)
1027 return NULL;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001028
1029 lz->ittuple = ittuple;
1030 lz->iternum = 0;
1031 lz->tuplesize = tuplesize;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001032
1033 return (PyObject *)lz;
1034}
1035
1036static void
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001037chain_dealloc(chainobject *lz)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001038{
1039 PyObject_GC_UnTrack(lz);
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001040 Py_XDECREF(lz->ittuple);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001041 lz->ob_type->tp_free(lz);
1042}
1043
Raymond Hettinger2012f172003-02-07 05:32:58 +00001044static int
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001045chain_traverse(chainobject *lz, visitproc visit, void *arg)
Raymond Hettinger2012f172003-02-07 05:32:58 +00001046{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001047 if (lz->ittuple)
1048 return visit(lz->ittuple, arg);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001049 return 0;
1050}
1051
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001052static PyObject *
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001053chain_next(chainobject *lz)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001054{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001055 PyObject *it;
1056 PyObject *item;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001057
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001058 while (lz->iternum < lz->tuplesize) {
1059 it = PyTuple_GET_ITEM(lz->ittuple, lz->iternum);
1060 item = PyIter_Next(it);
1061 if (item != NULL)
1062 return item;
1063 lz->iternum++;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001064 }
1065 return NULL;
1066}
1067
1068static PyObject *
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001069chain_getiter(PyObject *lz)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001070{
1071 Py_INCREF(lz);
1072 return lz;
1073}
1074
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001075PyDoc_STRVAR(chain_doc,
1076"chain(*iterables) --> chain object\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001077\n\
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001078Return a chain object whose .next() method returns elements from the\n\
1079first iterable until it is exhausted, then elements from the next\n\
1080iterable, until all of the iterables are exhausted.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001081
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001082PyTypeObject chain_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001083 PyObject_HEAD_INIT(NULL)
1084 0, /* ob_size */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001085 "itertools.chain", /* tp_name */
1086 sizeof(chainobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001087 0, /* tp_itemsize */
1088 /* methods */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001089 (destructor)chain_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001090 0, /* tp_print */
1091 0, /* tp_getattr */
1092 0, /* tp_setattr */
1093 0, /* tp_compare */
1094 0, /* tp_repr */
1095 0, /* tp_as_number */
1096 0, /* tp_as_sequence */
1097 0, /* tp_as_mapping */
1098 0, /* tp_hash */
1099 0, /* tp_call */
1100 0, /* tp_str */
1101 PyObject_GenericGetAttr, /* tp_getattro */
1102 0, /* tp_setattro */
1103 0, /* tp_as_buffer */
1104 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1105 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001106 chain_doc, /* tp_doc */
1107 (traverseproc)chain_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001108 0, /* tp_clear */
1109 0, /* tp_richcompare */
1110 0, /* tp_weaklistoffset */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001111 (getiterfunc)chain_getiter, /* tp_iter */
1112 (iternextfunc)chain_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001113 0, /* tp_methods */
1114 0, /* tp_members */
1115 0, /* tp_getset */
1116 0, /* tp_base */
1117 0, /* tp_dict */
1118 0, /* tp_descr_get */
1119 0, /* tp_descr_set */
1120 0, /* tp_dictoffset */
1121 0, /* tp_init */
1122 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001123 chain_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001124 PyObject_GC_Del, /* tp_free */
1125};
1126
1127
1128/* ifilter object ************************************************************/
1129
1130typedef struct {
1131 PyObject_HEAD
1132 PyObject *func;
1133 PyObject *it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001134} ifilterobject;
1135
1136PyTypeObject ifilter_type;
1137
1138static PyObject *
1139ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1140{
Raymond Hettinger60eca932003-02-09 06:40:58 +00001141 PyObject *func, *seq;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001142 PyObject *it;
1143 ifilterobject *lz;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001144
Raymond Hettinger60eca932003-02-09 06:40:58 +00001145 if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq))
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001146 return NULL;
1147
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001148 /* Get iterator. */
1149 it = PyObject_GetIter(seq);
1150 if (it == NULL)
1151 return NULL;
1152
1153 /* create ifilterobject structure */
1154 lz = (ifilterobject *)type->tp_alloc(type, 0);
1155 if (lz == NULL) {
1156 Py_DECREF(it);
1157 return NULL;
1158 }
1159 Py_INCREF(func);
1160 lz->func = func;
1161 lz->it = it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001162
1163 return (PyObject *)lz;
1164}
1165
1166static void
1167ifilter_dealloc(ifilterobject *lz)
1168{
1169 PyObject_GC_UnTrack(lz);
1170 Py_XDECREF(lz->func);
1171 Py_XDECREF(lz->it);
1172 lz->ob_type->tp_free(lz);
1173}
1174
1175static int
1176ifilter_traverse(ifilterobject *lz, visitproc visit, void *arg)
1177{
1178 int err;
1179
1180 if (lz->it) {
1181 err = visit(lz->it, arg);
1182 if (err)
1183 return err;
1184 }
1185 if (lz->func) {
1186 err = visit(lz->func, arg);
1187 if (err)
1188 return err;
1189 }
1190 return 0;
1191}
1192
1193static PyObject *
1194ifilter_next(ifilterobject *lz)
1195{
1196 PyObject *item;
1197 long ok;
1198
1199 for (;;) {
1200 item = PyIter_Next(lz->it);
1201 if (item == NULL)
1202 return NULL;
1203
1204 if (lz->func == Py_None) {
1205 ok = PyObject_IsTrue(item);
1206 } else {
1207 PyObject *good;
1208 good = PyObject_CallFunctionObjArgs(lz->func,
1209 item, NULL);
1210 if (good == NULL) {
1211 Py_DECREF(item);
1212 return NULL;
1213 }
1214 ok = PyObject_IsTrue(good);
1215 Py_DECREF(good);
1216 }
Raymond Hettinger60eca932003-02-09 06:40:58 +00001217 if (ok)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001218 return item;
1219 Py_DECREF(item);
1220 }
1221}
1222
1223static PyObject *
1224ifilter_getiter(PyObject *lz)
1225{
1226 Py_INCREF(lz);
1227 return lz;
1228}
1229
1230PyDoc_STRVAR(ifilter_doc,
Raymond Hettinger60eca932003-02-09 06:40:58 +00001231"ifilter(function or None, sequence) --> ifilter object\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001232\n\
Raymond Hettinger60eca932003-02-09 06:40:58 +00001233Return those items of sequence for which function(item) is true.\n\
1234If function is None, return the items that are true.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001235
1236PyTypeObject ifilter_type = {
1237 PyObject_HEAD_INIT(NULL)
1238 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001239 "itertools.ifilter", /* tp_name */
1240 sizeof(ifilterobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001241 0, /* tp_itemsize */
1242 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001243 (destructor)ifilter_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001244 0, /* tp_print */
1245 0, /* tp_getattr */
1246 0, /* tp_setattr */
1247 0, /* tp_compare */
1248 0, /* tp_repr */
1249 0, /* tp_as_number */
1250 0, /* tp_as_sequence */
1251 0, /* tp_as_mapping */
1252 0, /* tp_hash */
1253 0, /* tp_call */
1254 0, /* tp_str */
1255 PyObject_GenericGetAttr, /* tp_getattro */
1256 0, /* tp_setattro */
1257 0, /* tp_as_buffer */
1258 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1259 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001260 ifilter_doc, /* tp_doc */
1261 (traverseproc)ifilter_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001262 0, /* tp_clear */
1263 0, /* tp_richcompare */
1264 0, /* tp_weaklistoffset */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001265 (getiterfunc)ifilter_getiter, /* tp_iter */
1266 (iternextfunc)ifilter_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001267 0, /* tp_methods */
1268 0, /* tp_members */
1269 0, /* tp_getset */
1270 0, /* tp_base */
1271 0, /* tp_dict */
1272 0, /* tp_descr_get */
1273 0, /* tp_descr_set */
1274 0, /* tp_dictoffset */
1275 0, /* tp_init */
1276 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001277 ifilter_new, /* tp_new */
1278 PyObject_GC_Del, /* tp_free */
1279};
1280
1281
1282/* ifilterfalse object ************************************************************/
1283
1284typedef struct {
1285 PyObject_HEAD
1286 PyObject *func;
1287 PyObject *it;
1288} ifilterfalseobject;
1289
1290PyTypeObject ifilterfalse_type;
1291
1292static PyObject *
1293ifilterfalse_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1294{
Guido van Rossumd58f3fc2003-02-09 17:19:18 +00001295 PyObject *func, *seq;
Raymond Hettinger60eca932003-02-09 06:40:58 +00001296 PyObject *it;
1297 ifilterfalseobject *lz;
1298
1299 if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq))
1300 return NULL;
1301
1302 /* Get iterator. */
1303 it = PyObject_GetIter(seq);
1304 if (it == NULL)
1305 return NULL;
1306
1307 /* create ifilterfalseobject structure */
1308 lz = (ifilterfalseobject *)type->tp_alloc(type, 0);
1309 if (lz == NULL) {
1310 Py_DECREF(it);
1311 return NULL;
1312 }
1313 Py_INCREF(func);
1314 lz->func = func;
1315 lz->it = it;
1316
1317 return (PyObject *)lz;
1318}
1319
1320static void
1321ifilterfalse_dealloc(ifilterfalseobject *lz)
1322{
1323 PyObject_GC_UnTrack(lz);
1324 Py_XDECREF(lz->func);
1325 Py_XDECREF(lz->it);
1326 lz->ob_type->tp_free(lz);
1327}
1328
1329static int
1330ifilterfalse_traverse(ifilterfalseobject *lz, visitproc visit, void *arg)
1331{
1332 int err;
1333
1334 if (lz->it) {
1335 err = visit(lz->it, arg);
1336 if (err)
1337 return err;
1338 }
1339 if (lz->func) {
1340 err = visit(lz->func, arg);
1341 if (err)
1342 return err;
1343 }
1344 return 0;
1345}
1346
1347static PyObject *
1348ifilterfalse_next(ifilterfalseobject *lz)
1349{
1350 PyObject *item;
1351 long ok;
1352
1353 for (;;) {
1354 item = PyIter_Next(lz->it);
1355 if (item == NULL)
1356 return NULL;
1357
1358 if (lz->func == Py_None) {
1359 ok = PyObject_IsTrue(item);
1360 } else {
1361 PyObject *good;
1362 good = PyObject_CallFunctionObjArgs(lz->func,
1363 item, NULL);
1364 if (good == NULL) {
1365 Py_DECREF(item);
1366 return NULL;
1367 }
1368 ok = PyObject_IsTrue(good);
1369 Py_DECREF(good);
1370 }
1371 if (!ok)
1372 return item;
1373 Py_DECREF(item);
1374 }
1375}
1376
1377static PyObject *
1378ifilterfalse_getiter(PyObject *lz)
1379{
1380 Py_INCREF(lz);
1381 return lz;
1382}
1383
1384PyDoc_STRVAR(ifilterfalse_doc,
1385"ifilterfalse(function or None, sequence) --> ifilterfalse object\n\
1386\n\
1387Return those items of sequence for which function(item) is false.\n\
1388If function is None, return the items that are false.");
1389
1390PyTypeObject ifilterfalse_type = {
1391 PyObject_HEAD_INIT(NULL)
1392 0, /* ob_size */
1393 "itertools.ifilterfalse", /* tp_name */
1394 sizeof(ifilterfalseobject), /* tp_basicsize */
1395 0, /* tp_itemsize */
1396 /* methods */
1397 (destructor)ifilterfalse_dealloc, /* tp_dealloc */
1398 0, /* tp_print */
1399 0, /* tp_getattr */
1400 0, /* tp_setattr */
1401 0, /* tp_compare */
1402 0, /* tp_repr */
1403 0, /* tp_as_number */
1404 0, /* tp_as_sequence */
1405 0, /* tp_as_mapping */
1406 0, /* tp_hash */
1407 0, /* tp_call */
1408 0, /* tp_str */
1409 PyObject_GenericGetAttr, /* tp_getattro */
1410 0, /* tp_setattro */
1411 0, /* tp_as_buffer */
1412 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1413 Py_TPFLAGS_BASETYPE, /* tp_flags */
1414 ifilterfalse_doc, /* tp_doc */
1415 (traverseproc)ifilterfalse_traverse, /* tp_traverse */
1416 0, /* tp_clear */
1417 0, /* tp_richcompare */
1418 0, /* tp_weaklistoffset */
1419 (getiterfunc)ifilterfalse_getiter, /* tp_iter */
1420 (iternextfunc)ifilterfalse_next, /* tp_iternext */
1421 0, /* tp_methods */
1422 0, /* tp_members */
1423 0, /* tp_getset */
1424 0, /* tp_base */
1425 0, /* tp_dict */
1426 0, /* tp_descr_get */
1427 0, /* tp_descr_set */
1428 0, /* tp_dictoffset */
1429 0, /* tp_init */
1430 PyType_GenericAlloc, /* tp_alloc */
1431 ifilterfalse_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001432 PyObject_GC_Del, /* tp_free */
1433};
1434
1435
1436/* count object ************************************************************/
1437
1438typedef struct {
1439 PyObject_HEAD
1440 long cnt;
1441} countobject;
1442
1443PyTypeObject count_type;
1444
1445static PyObject *
1446count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1447{
1448 countobject *lz;
1449 long cnt = 0;
1450
1451 if (!PyArg_ParseTuple(args, "|l:count", &cnt))
1452 return NULL;
1453
1454 /* create countobject structure */
1455 lz = (countobject *)PyObject_New(countobject, &count_type);
1456 if (lz == NULL)
1457 return NULL;
1458 lz->cnt = cnt;
1459
1460 return (PyObject *)lz;
1461}
1462
1463static PyObject *
1464count_next(countobject *lz)
1465{
1466 return PyInt_FromLong(lz->cnt++);
1467}
1468
1469static PyObject *
1470count_getiter(PyObject *lz)
1471{
1472 Py_INCREF(lz);
1473 return lz;
1474}
1475
1476PyDoc_STRVAR(count_doc,
1477"count([firstval]) --> count object\n\
1478\n\
1479Return a count object whose .next() method returns consecutive\n\
1480integers starting from zero or, if specified, from firstval.");
1481
1482PyTypeObject count_type = {
1483 PyObject_HEAD_INIT(NULL)
1484 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001485 "itertools.count", /* tp_name */
1486 sizeof(countobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001487 0, /* tp_itemsize */
1488 /* methods */
1489 (destructor)PyObject_Del, /* tp_dealloc */
1490 0, /* tp_print */
1491 0, /* tp_getattr */
1492 0, /* tp_setattr */
1493 0, /* tp_compare */
1494 0, /* tp_repr */
1495 0, /* tp_as_number */
1496 0, /* tp_as_sequence */
1497 0, /* tp_as_mapping */
1498 0, /* tp_hash */
1499 0, /* tp_call */
1500 0, /* tp_str */
1501 PyObject_GenericGetAttr, /* tp_getattro */
1502 0, /* tp_setattro */
1503 0, /* tp_as_buffer */
1504 Py_TPFLAGS_DEFAULT, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001505 count_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001506 0, /* tp_traverse */
1507 0, /* tp_clear */
1508 0, /* tp_richcompare */
1509 0, /* tp_weaklistoffset */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001510 (getiterfunc)count_getiter, /* tp_iter */
1511 (iternextfunc)count_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001512 0, /* tp_methods */
1513 0, /* tp_members */
1514 0, /* tp_getset */
1515 0, /* tp_base */
1516 0, /* tp_dict */
1517 0, /* tp_descr_get */
1518 0, /* tp_descr_set */
1519 0, /* tp_dictoffset */
1520 0, /* tp_init */
1521 PyType_GenericAlloc, /* tp_alloc */
1522 count_new, /* tp_new */
1523};
1524
1525
1526/* izip object ************************************************************/
1527
1528#include "Python.h"
1529
1530typedef struct {
1531 PyObject_HEAD
1532 long tuplesize;
1533 PyObject *ittuple; /* tuple of iterators */
Raymond Hettinger2012f172003-02-07 05:32:58 +00001534 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001535} izipobject;
1536
1537PyTypeObject izip_type;
1538
1539static PyObject *
1540izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1541{
1542 izipobject *lz;
1543 int i;
1544 PyObject *ittuple; /* tuple of iterators */
Raymond Hettinger2012f172003-02-07 05:32:58 +00001545 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001546 int tuplesize = PySequence_Length(args);
1547
1548 if (tuplesize < 1) {
1549 PyErr_SetString(PyExc_TypeError,
1550 "izip() requires at least one sequence");
1551 return NULL;
1552 }
1553
1554 /* args must be a tuple */
1555 assert(PyTuple_Check(args));
1556
1557 /* obtain iterators */
1558 ittuple = PyTuple_New(tuplesize);
1559 if(ittuple == NULL)
1560 return NULL;
1561 for (i=0; i < tuplesize; ++i) {
1562 PyObject *item = PyTuple_GET_ITEM(args, i);
1563 PyObject *it = PyObject_GetIter(item);
1564 if (it == NULL) {
1565 if (PyErr_ExceptionMatches(PyExc_TypeError))
1566 PyErr_Format(PyExc_TypeError,
1567 "izip argument #%d must support iteration",
1568 i+1);
1569 Py_DECREF(ittuple);
1570 return NULL;
1571 }
1572 PyTuple_SET_ITEM(ittuple, i, it);
1573 }
1574
Raymond Hettinger2012f172003-02-07 05:32:58 +00001575 /* create a result holder */
1576 result = PyTuple_New(tuplesize);
1577 if (result == NULL) {
1578 Py_DECREF(ittuple);
1579 return NULL;
1580 }
1581 for (i=0 ; i < tuplesize ; i++) {
1582 Py_INCREF(Py_None);
1583 PyTuple_SET_ITEM(result, i, Py_None);
1584 }
1585
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001586 /* create izipobject structure */
1587 lz = (izipobject *)type->tp_alloc(type, 0);
1588 if (lz == NULL) {
1589 Py_DECREF(ittuple);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001590 Py_DECREF(result);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001591 return NULL;
1592 }
1593 lz->ittuple = ittuple;
1594 lz->tuplesize = tuplesize;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001595 lz->result = result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001596
1597 return (PyObject *)lz;
1598}
1599
1600static void
1601izip_dealloc(izipobject *lz)
1602{
1603 PyObject_GC_UnTrack(lz);
1604 Py_XDECREF(lz->ittuple);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001605 Py_XDECREF(lz->result);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001606 lz->ob_type->tp_free(lz);
1607}
1608
1609static int
1610izip_traverse(izipobject *lz, visitproc visit, void *arg)
1611{
1612 if (lz->ittuple)
1613 return visit(lz->ittuple, arg);
1614 return 0;
1615}
1616
1617static PyObject *
1618izip_next(izipobject *lz)
1619{
1620 int i;
1621 long tuplesize = lz->tuplesize;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001622 PyObject *result = lz->result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001623 PyObject *it;
1624 PyObject *item;
1625
Raymond Hettinger2012f172003-02-07 05:32:58 +00001626 if (result->ob_refcnt == 1) {
1627 for (i=0 ; i < tuplesize ; i++) {
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001628 it = PyTuple_GET_ITEM(lz->ittuple, i);
1629 item = PyIter_Next(it);
1630 if (item == NULL)
1631 return NULL;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001632 Py_DECREF(PyTuple_GET_ITEM(result, i));
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001633 PyTuple_SET_ITEM(result, i, item);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001634 }
1635 Py_INCREF(result);
1636 } else {
Raymond Hettinger2012f172003-02-07 05:32:58 +00001637 result = PyTuple_New(tuplesize);
1638 if (result == NULL)
1639 return NULL;
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001640 for (i=0 ; i < tuplesize ; i++) {
1641 it = PyTuple_GET_ITEM(lz->ittuple, i);
1642 item = PyIter_Next(it);
1643 if (item == NULL) {
1644 Py_DECREF(result);
1645 return NULL;
1646 }
1647 PyTuple_SET_ITEM(result, i, item);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001648 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001649 }
1650 return result;
1651}
1652
1653static PyObject *
1654izip_getiter(PyObject *lz)
1655{
1656 Py_INCREF(lz);
1657 return lz;
1658}
1659
1660PyDoc_STRVAR(izip_doc,
1661"izip(iter1 [,iter2 [...]]) --> izip object\n\
1662\n\
1663Return a izip object whose .next() method returns a tuple where\n\
1664the i-th element comes from the i-th iterable argument. The .next()\n\
1665method continues until the shortest iterable in the argument sequence\n\
1666is exhausted and then it raises StopIteration. Works like the zip()\n\
1667function but consumes less memory by returning an iterator instead of\n\
1668a list.");
1669
1670PyTypeObject izip_type = {
1671 PyObject_HEAD_INIT(NULL)
1672 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001673 "itertools.izip", /* tp_name */
1674 sizeof(izipobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001675 0, /* tp_itemsize */
1676 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001677 (destructor)izip_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001678 0, /* tp_print */
1679 0, /* tp_getattr */
1680 0, /* tp_setattr */
1681 0, /* tp_compare */
1682 0, /* tp_repr */
1683 0, /* tp_as_number */
1684 0, /* tp_as_sequence */
1685 0, /* tp_as_mapping */
1686 0, /* tp_hash */
1687 0, /* tp_call */
1688 0, /* tp_str */
1689 PyObject_GenericGetAttr, /* tp_getattro */
1690 0, /* tp_setattro */
1691 0, /* tp_as_buffer */
1692 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1693 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001694 izip_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001695 (traverseproc)izip_traverse, /* tp_traverse */
1696 0, /* tp_clear */
1697 0, /* tp_richcompare */
1698 0, /* tp_weaklistoffset */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001699 (getiterfunc)izip_getiter, /* tp_iter */
1700 (iternextfunc)izip_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001701 0, /* tp_methods */
1702 0, /* tp_members */
1703 0, /* tp_getset */
1704 0, /* tp_base */
1705 0, /* tp_dict */
1706 0, /* tp_descr_get */
1707 0, /* tp_descr_set */
1708 0, /* tp_dictoffset */
1709 0, /* tp_init */
1710 PyType_GenericAlloc, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001711 izip_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001712 PyObject_GC_Del, /* tp_free */
1713};
1714
1715
1716/* repeat object ************************************************************/
1717
1718typedef struct {
1719 PyObject_HEAD
1720 PyObject *element;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001721 long cnt;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001722} repeatobject;
1723
1724PyTypeObject repeat_type;
1725
1726static PyObject *
1727repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1728{
1729 repeatobject *ro;
1730 PyObject *element;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001731 long cnt = -1;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001732
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001733 if (!PyArg_ParseTuple(args, "O|l:repeat", &element, &cnt))
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001734 return NULL;
1735
1736 ro = (repeatobject *)type->tp_alloc(type, 0);
1737 if (ro == NULL)
1738 return NULL;
1739 Py_INCREF(element);
1740 ro->element = element;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001741 ro->cnt = cnt;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001742 return (PyObject *)ro;
1743}
1744
1745static void
1746repeat_dealloc(repeatobject *ro)
1747{
1748 PyObject_GC_UnTrack(ro);
1749 Py_XDECREF(ro->element);
1750 ro->ob_type->tp_free(ro);
1751}
1752
1753static int
1754repeat_traverse(repeatobject *ro, visitproc visit, void *arg)
1755{
1756 if (ro->element)
1757 return visit(ro->element, arg);
1758 return 0;
1759}
1760
1761static PyObject *
1762repeat_next(repeatobject *ro)
1763{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001764 if (ro->cnt == 0)
1765 return NULL;
1766 if (ro->cnt > 0)
1767 ro->cnt--;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001768 Py_INCREF(ro->element);
1769 return ro->element;
1770}
1771
1772static PyObject *
1773repeat_getiter(PyObject *ro)
1774{
1775 Py_INCREF(ro);
1776 return ro;
1777}
1778
1779PyDoc_STRVAR(repeat_doc,
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001780"repeat(element [,times]) -> create an iterator which returns the element\n\
1781for the specified number of times. If not specified, returns the element\n\
1782endlessly.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001783
1784PyTypeObject repeat_type = {
1785 PyObject_HEAD_INIT(NULL)
1786 0, /* ob_size */
1787 "itertools.repeat", /* tp_name */
1788 sizeof(repeatobject), /* tp_basicsize */
1789 0, /* tp_itemsize */
1790 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001791 (destructor)repeat_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001792 0, /* tp_print */
1793 0, /* tp_getattr */
1794 0, /* tp_setattr */
1795 0, /* tp_compare */
1796 0, /* tp_repr */
1797 0, /* tp_as_number */
1798 0, /* tp_as_sequence */
1799 0, /* tp_as_mapping */
1800 0, /* tp_hash */
1801 0, /* tp_call */
1802 0, /* tp_str */
1803 PyObject_GenericGetAttr, /* tp_getattro */
1804 0, /* tp_setattro */
1805 0, /* tp_as_buffer */
1806 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1807 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001808 repeat_doc, /* tp_doc */
1809 (traverseproc)repeat_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001810 0, /* tp_clear */
1811 0, /* tp_richcompare */
1812 0, /* tp_weaklistoffset */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001813 (getiterfunc)repeat_getiter, /* tp_iter */
1814 (iternextfunc)repeat_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001815 0, /* tp_methods */
1816 0, /* tp_members */
1817 0, /* tp_getset */
1818 0, /* tp_base */
1819 0, /* tp_dict */
1820 0, /* tp_descr_get */
1821 0, /* tp_descr_set */
1822 0, /* tp_dictoffset */
1823 0, /* tp_init */
1824 PyType_GenericAlloc, /* tp_alloc */
1825 repeat_new, /* tp_new */
1826 PyObject_GC_Del, /* tp_free */
1827};
1828
1829
1830/* module level code ********************************************************/
1831
1832PyDoc_STRVAR(module_doc,
1833"Functional tools for creating and using iterators.\n\
1834\n\
1835Infinite iterators:\n\
1836count([n]) --> n, n+1, n+2, ...\n\
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001837cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\
1838repeat(elem [,n]) --> elem, elem, elem, ... endlessly or upto n times\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001839\n\
1840Iterators terminating on the shortest input sequence:\n\
1841izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
Raymond Hettinger60eca932003-02-09 06:40:58 +00001842ifilter(pred, seq) --> elements of seq where pred(elem) is True\n\
1843ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001844islice(seq, [start,] stop [, step]) --> elements from\n\
1845 seq[start:stop:step]\n\
1846imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\
1847starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001848chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001849takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\
1850dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\
1851");
1852
1853
1854PyMODINIT_FUNC
1855inititertools(void)
1856{
Raymond Hettinger60eca932003-02-09 06:40:58 +00001857 int i;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001858 PyObject *m;
Raymond Hettinger60eca932003-02-09 06:40:58 +00001859 char *name;
1860 PyTypeObject *typelist[] = {
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001861 &cycle_type,
Raymond Hettinger60eca932003-02-09 06:40:58 +00001862 &dropwhile_type,
1863 &takewhile_type,
1864 &islice_type,
1865 &starmap_type,
1866 &imap_type,
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001867 &chain_type,
Raymond Hettinger60eca932003-02-09 06:40:58 +00001868 &ifilter_type,
1869 &ifilterfalse_type,
1870 &count_type,
1871 &izip_type,
1872 &repeat_type,
1873 NULL
1874 };
1875
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001876 m = Py_InitModule3("itertools", NULL, module_doc);
1877
Raymond Hettinger60eca932003-02-09 06:40:58 +00001878 for (i=0 ; typelist[i] != NULL ; i++) {
1879 if (PyType_Ready(typelist[i]) < 0)
1880 return;
1881 name = strchr(typelist[i]->tp_name, '.') + 1;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001882 assert (name != NULL);
Raymond Hettinger60eca932003-02-09 06:40:58 +00001883 Py_INCREF(typelist[i]);
1884 PyModule_AddObject(m, name, (PyObject *)typelist[i]);
1885 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001886}