blob: a341a6630a2e9fa01ddbad2126958e3780cf66d9 [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 Hettingerad983e72003-11-12 14:32:26 +000010/* tee object and with supporting function and objects ***************/
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000011
Raymond Hettingerad983e72003-11-12 14:32:26 +000012/* The teedataobject pre-allocates space for LINKCELLS number of objects.
13 To help the object fit neatly inside cache lines (space for 16 to 32
14 pointers), the value should be a multiple of 16 minus space for
15 the other structure members including PyHEAD overhead. The larger the
16 value, the less memory overhead per object and the less time spent
17 allocating/deallocating new links. The smaller the number, the less
18 wasted space and the more rapid freeing of older data.
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000019*/
Raymond Hettingerad983e72003-11-12 14:32:26 +000020#define LINKCELLS 57
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000021
22typedef struct {
23 PyObject_HEAD
24 PyObject *it;
Raymond Hettingerad983e72003-11-12 14:32:26 +000025 int numread;
26 PyObject *nextlink;
27 PyObject *(values[LINKCELLS]);
28} teedataobject;
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000029
30typedef struct {
31 PyObject_HEAD
Raymond Hettingerad983e72003-11-12 14:32:26 +000032 teedataobject *dataobj;
33 int index;
34} teeobject;
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000035
Raymond Hettingerad983e72003-11-12 14:32:26 +000036static PyTypeObject teedataobject_type;
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000037
38static PyObject *
Raymond Hettingerad983e72003-11-12 14:32:26 +000039teedataobject_new(PyObject *it)
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000040{
Raymond Hettingerad983e72003-11-12 14:32:26 +000041 teedataobject *tdo;
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000042
Raymond Hettingerad983e72003-11-12 14:32:26 +000043 tdo = PyObject_New(teedataobject, &teedataobject_type);
44 if (tdo == NULL)
Raymond Hettinger45143692003-10-25 06:37:47 +000045 return NULL;
Raymond Hettingerad983e72003-11-12 14:32:26 +000046
47 tdo->numread = 0;
48 tdo->nextlink = NULL;
49 Py_INCREF(it);
50 tdo->it = it;
51 return (PyObject *)tdo;
52}
53
54static PyObject *
55teedataobject_jumplink(teedataobject *tdo)
56{
57 if (tdo->nextlink == NULL)
58 tdo->nextlink = teedataobject_new(tdo->it);
59 Py_INCREF(tdo->nextlink);
60 return tdo->nextlink;
61}
62
63static PyObject *
64teedataobject_getitem(teedataobject *tdo, int i)
65{
66 PyObject *value;
67
68 assert(i < LINKCELLS);
69 if (i < tdo->numread)
70 value = tdo->values[i];
71 else {
72 /* this is the lead iterator, so fetch more data */
73 assert(i == tdo->numread);
74 value = PyIter_Next(tdo->it);
75 if (value == NULL)
76 return NULL;
77 tdo->numread++;
78 tdo->values[i] = value;
Raymond Hettinger45143692003-10-25 06:37:47 +000079 }
Raymond Hettingerad983e72003-11-12 14:32:26 +000080 Py_INCREF(value);
81 return value;
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000082}
83
84static void
Raymond Hettingerad983e72003-11-12 14:32:26 +000085teedataobject_dealloc(teedataobject *tdo)
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000086{
Raymond Hettingerad983e72003-11-12 14:32:26 +000087 int i;
Raymond Hettinger45143692003-10-25 06:37:47 +000088
Raymond Hettingerad983e72003-11-12 14:32:26 +000089 for (i=0 ; i<tdo->numread ; i++)
90 Py_DECREF(tdo->values[i]);
91 Py_XDECREF(tdo->it);
92 Py_XDECREF(tdo->nextlink);
93 PyObject_Del(tdo);
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000094}
95
Raymond Hettingerad983e72003-11-12 14:32:26 +000096PyDoc_STRVAR(teedataobject_doc, "Data container common to multiple tee objects.");
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000097
Raymond Hettingerad983e72003-11-12 14:32:26 +000098static PyTypeObject teedataobject_type = {
Raymond Hettinger6a5b0272003-10-24 08:45:23 +000099 PyObject_HEAD_INIT(&PyType_Type)
100 0, /* ob_size */
Raymond Hettingerad983e72003-11-12 14:32:26 +0000101 "itertools.tee_dataobject", /* tp_name */
102 sizeof(teedataobject), /* tp_basicsize */
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000103 0, /* tp_itemsize */
104 /* methods */
Raymond Hettingerad983e72003-11-12 14:32:26 +0000105 (destructor)teedataobject_dealloc, /* tp_dealloc */
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000106 0, /* tp_print */
107 0, /* tp_getattr */
108 0, /* tp_setattr */
109 0, /* tp_compare */
110 0, /* tp_repr */
111 0, /* tp_as_number */
112 0, /* tp_as_sequence */
113 0, /* tp_as_mapping */
114 0, /* tp_hash */
115 0, /* tp_call */
116 0, /* tp_str */
117 PyObject_GenericGetAttr, /* tp_getattro */
118 0, /* tp_setattro */
119 0, /* tp_as_buffer */
Raymond Hettingerad983e72003-11-12 14:32:26 +0000120 Py_TPFLAGS_DEFAULT, /* tp_flags */
121 teedataobject_doc, /* tp_doc */
122 0, /* tp_traverse */
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000123};
124
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000125
126static PyTypeObject tee_type;
127
128static PyObject *
Raymond Hettingerad983e72003-11-12 14:32:26 +0000129tee_next(teeobject *to)
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000130{
Raymond Hettingerad983e72003-11-12 14:32:26 +0000131 PyObject *value, *link;
132
133 if (to->index >= LINKCELLS) {
134 link = teedataobject_jumplink(to->dataobj);
135 Py_XDECREF(to->dataobj);
136 to->dataobj = (teedataobject *)link;
137 to->index = 0;
138 }
139 value = teedataobject_getitem(to->dataobj, to->index);
140 if (value == NULL)
141 return NULL;
142 to->index++;
143 return value;
144}
145
146static PyObject *
147tee_copy(teeobject *to)
148{
149 teeobject *newto;
150
151 newto = PyObject_New(teeobject, &tee_type);
152 if (newto == NULL)
153 return NULL;
154 Py_INCREF(to->dataobj);
155 newto->dataobj = to->dataobj;
156 newto->index = to->index;
157 return (PyObject *)newto;
158}
159
160PyDoc_STRVAR(teecopy_doc, "Returns an independent iterator.");
161
162static PyObject *
163tee_fromiterable(PyObject *iterable)
164{
165 teeobject *to;
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000166 PyObject *it = NULL;
Raymond Hettingerad983e72003-11-12 14:32:26 +0000167
168 it = PyObject_GetIter(iterable);
169 if (it == NULL)
170 return NULL;
171 if (PyObject_TypeCheck(it, &tee_type)) {
172 to = (teeobject *)tee_copy((teeobject *)it);
173 goto done;
174 }
175
176 to = PyObject_New(teeobject, &tee_type);
177 if (to == NULL)
178 goto done;
179 to->dataobj = (teedataobject *)teedataobject_new(it);
180 to->index = 0;
181done:
182 Py_XDECREF(it);
183 return (PyObject *)to;
184}
185
186static PyObject *
187tee_new(PyTypeObject *type, PyObject *args, PyObject *kw)
188{
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000189 PyObject *iterable;
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000190
191 if (!PyArg_UnpackTuple(args, "tee", 1, 1, &iterable))
192 return NULL;
Raymond Hettingerad983e72003-11-12 14:32:26 +0000193 return tee_fromiterable(iterable);
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000194}
195
196static void
197tee_dealloc(teeobject *to)
198{
Raymond Hettingerad983e72003-11-12 14:32:26 +0000199 Py_XDECREF(to->dataobj);
200 PyObject_Del(to);
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000201}
202
Raymond Hettingerad983e72003-11-12 14:32:26 +0000203PyDoc_STRVAR(teeobject_doc,
204"Iterator wrapped to make it copyable");
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000205
Raymond Hettingerad983e72003-11-12 14:32:26 +0000206static PyMethodDef tee_methods[] = {
207 {"__copy__", (PyCFunction)tee_copy, METH_NOARGS, teecopy_doc},
208 {NULL, NULL} /* sentinel */
209};
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000210
211static PyTypeObject tee_type = {
212 PyObject_HEAD_INIT(NULL)
213 0, /* ob_size */
214 "itertools.tee", /* tp_name */
215 sizeof(teeobject), /* tp_basicsize */
216 0, /* tp_itemsize */
217 /* methods */
218 (destructor)tee_dealloc, /* tp_dealloc */
219 0, /* tp_print */
220 0, /* tp_getattr */
221 0, /* tp_setattr */
222 0, /* tp_compare */
223 0, /* tp_repr */
224 0, /* tp_as_number */
225 0, /* tp_as_sequence */
226 0, /* tp_as_mapping */
227 0, /* tp_hash */
228 0, /* tp_call */
229 0, /* tp_str */
Raymond Hettingerf0c5aec2003-10-26 14:25:56 +0000230 0, /* tp_getattro */
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000231 0, /* tp_setattro */
232 0, /* tp_as_buffer */
Raymond Hettingerad983e72003-11-12 14:32:26 +0000233 Py_TPFLAGS_DEFAULT, /* tp_flags */
234 teeobject_doc, /* tp_doc */
235 0, /* tp_traverse */
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000236 0, /* tp_clear */
237 0, /* tp_richcompare */
238 0, /* tp_weaklistoffset */
Raymond Hettingerad983e72003-11-12 14:32:26 +0000239 PyObject_SelfIter, /* tp_iter */
240 (iternextfunc)tee_next, /* tp_iternext */
241 tee_methods, /* tp_methods */
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000242 0, /* tp_members */
243 0, /* tp_getset */
244 0, /* tp_base */
245 0, /* tp_dict */
246 0, /* tp_descr_get */
247 0, /* tp_descr_set */
248 0, /* tp_dictoffset */
249 0, /* tp_init */
250 0, /* tp_alloc */
251 tee_new, /* tp_new */
Raymond Hettingerad983e72003-11-12 14:32:26 +0000252 PyObject_Del, /* tp_free */
Raymond Hettinger6a5b0272003-10-24 08:45:23 +0000253};
254
Raymond Hettingerad983e72003-11-12 14:32:26 +0000255static PyObject *
256tee(PyObject *self, PyObject *args)
257{
258 int i, n=2;
259 PyObject *it, *iterable, *copyable, *result;
260
261 if (!PyArg_ParseTuple(args, "O|i", &iterable, &n))
262 return NULL;
263 result = PyTuple_New(n);
264 if (result == NULL)
265 return NULL;
266 if (n == 0)
267 return result;
268 it = PyObject_GetIter(iterable);
269 if (it == NULL) {
270 Py_DECREF(result);
271 return NULL;
272 }
273 if (!PyObject_HasAttrString(it, "__copy__")) {
274 copyable = tee_fromiterable(it);
275 Py_DECREF(it);
276 if (copyable == NULL) {
277 Py_DECREF(result);
278 return NULL;
279 }
280 } else
281 copyable = it;
282 PyTuple_SET_ITEM(result, 0, copyable);
283 for (i=1 ; i<n ; i++) {
284 copyable = PyObject_CallMethod(copyable, "__copy__", NULL);
285 if (copyable == NULL) {
286 Py_DECREF(result);
287 return NULL;
288 }
289 PyTuple_SET_ITEM(result, i, copyable);
290 }
291 return result;
292}
293
294PyDoc_STRVAR(tee_doc,
295"tee(iterable, n=2) --> tuple of n independent iterators.");
296
297
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000298/* cycle object **********************************************************/
299
300typedef struct {
301 PyObject_HEAD
302 PyObject *it;
303 PyObject *saved;
304 int firstpass;
305} cycleobject;
306
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000307static PyTypeObject cycle_type;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000308
309static PyObject *
310cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
311{
312 PyObject *it;
313 PyObject *iterable;
314 PyObject *saved;
315 cycleobject *lz;
316
317 if (!PyArg_UnpackTuple(args, "cycle", 1, 1, &iterable))
318 return NULL;
319
320 /* Get iterator. */
321 it = PyObject_GetIter(iterable);
322 if (it == NULL)
323 return NULL;
324
325 saved = PyList_New(0);
326 if (saved == NULL) {
327 Py_DECREF(it);
328 return NULL;
329 }
330
331 /* create cycleobject structure */
332 lz = (cycleobject *)type->tp_alloc(type, 0);
333 if (lz == NULL) {
334 Py_DECREF(it);
335 Py_DECREF(saved);
336 return NULL;
337 }
338 lz->it = it;
339 lz->saved = saved;
340 lz->firstpass = 0;
341
342 return (PyObject *)lz;
343}
344
345static void
346cycle_dealloc(cycleobject *lz)
347{
348 PyObject_GC_UnTrack(lz);
349 Py_XDECREF(lz->saved);
350 Py_XDECREF(lz->it);
351 lz->ob_type->tp_free(lz);
352}
353
354static int
355cycle_traverse(cycleobject *lz, visitproc visit, void *arg)
356{
357 int err;
358
359 if (lz->it) {
360 err = visit(lz->it, arg);
361 if (err)
362 return err;
363 }
364 if (lz->saved) {
365 err = visit(lz->saved, arg);
366 if (err)
367 return err;
368 }
369 return 0;
370}
371
372static PyObject *
373cycle_next(cycleobject *lz)
374{
375 PyObject *item;
376 PyObject *it;
377
378 while (1) {
379 item = PyIter_Next(lz->it);
380 if (item != NULL) {
381 if (!lz->firstpass)
382 PyList_Append(lz->saved, item);
383 return item;
384 }
385 if (PyList_Size(lz->saved) == 0)
386 return NULL;
387 it = PyObject_GetIter(lz->saved);
388 if (it == NULL)
389 return NULL;
390 Py_DECREF(lz->it);
391 lz->it = it;
392 lz->firstpass = 1;
393 }
394}
395
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000396PyDoc_STRVAR(cycle_doc,
397"cycle(iterable) --> cycle object\n\
398\n\
399Return elements from the iterable until it is exhausted.\n\
400Then repeat the sequence indefinitely.");
401
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000402static PyTypeObject cycle_type = {
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000403 PyObject_HEAD_INIT(NULL)
404 0, /* ob_size */
405 "itertools.cycle", /* tp_name */
406 sizeof(cycleobject), /* tp_basicsize */
407 0, /* tp_itemsize */
408 /* methods */
409 (destructor)cycle_dealloc, /* tp_dealloc */
410 0, /* tp_print */
411 0, /* tp_getattr */
412 0, /* tp_setattr */
413 0, /* tp_compare */
414 0, /* tp_repr */
415 0, /* tp_as_number */
416 0, /* tp_as_sequence */
417 0, /* tp_as_mapping */
418 0, /* tp_hash */
419 0, /* tp_call */
420 0, /* tp_str */
421 PyObject_GenericGetAttr, /* tp_getattro */
422 0, /* tp_setattro */
423 0, /* tp_as_buffer */
424 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
425 Py_TPFLAGS_BASETYPE, /* tp_flags */
426 cycle_doc, /* tp_doc */
427 (traverseproc)cycle_traverse, /* tp_traverse */
428 0, /* tp_clear */
429 0, /* tp_richcompare */
430 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000431 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000432 (iternextfunc)cycle_next, /* tp_iternext */
433 0, /* tp_methods */
434 0, /* tp_members */
435 0, /* tp_getset */
436 0, /* tp_base */
437 0, /* tp_dict */
438 0, /* tp_descr_get */
439 0, /* tp_descr_set */
440 0, /* tp_dictoffset */
441 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +0000442 0, /* tp_alloc */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +0000443 cycle_new, /* tp_new */
444 PyObject_GC_Del, /* tp_free */
445};
446
447
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000448/* dropwhile object **********************************************************/
449
450typedef struct {
451 PyObject_HEAD
452 PyObject *func;
453 PyObject *it;
454 long start;
455} dropwhileobject;
456
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000457static PyTypeObject dropwhile_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000458
459static PyObject *
460dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
461{
462 PyObject *func, *seq;
463 PyObject *it;
464 dropwhileobject *lz;
465
466 if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq))
467 return NULL;
468
469 /* Get iterator. */
470 it = PyObject_GetIter(seq);
471 if (it == NULL)
472 return NULL;
473
474 /* create dropwhileobject structure */
475 lz = (dropwhileobject *)type->tp_alloc(type, 0);
476 if (lz == NULL) {
477 Py_DECREF(it);
478 return NULL;
479 }
480 Py_INCREF(func);
481 lz->func = func;
482 lz->it = it;
483 lz->start = 0;
484
485 return (PyObject *)lz;
486}
487
488static void
489dropwhile_dealloc(dropwhileobject *lz)
490{
491 PyObject_GC_UnTrack(lz);
492 Py_XDECREF(lz->func);
493 Py_XDECREF(lz->it);
494 lz->ob_type->tp_free(lz);
495}
496
497static int
498dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg)
499{
500 int err;
501
502 if (lz->it) {
503 err = visit(lz->it, arg);
504 if (err)
505 return err;
506 }
507 if (lz->func) {
508 err = visit(lz->func, arg);
509 if (err)
510 return err;
511 }
512 return 0;
513}
514
515static PyObject *
516dropwhile_next(dropwhileobject *lz)
517{
518 PyObject *item, *good;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000519 PyObject *it = lz->it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000520 long ok;
521
522 for (;;) {
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000523 assert(PyIter_Check(it));
524 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000525 if (item == NULL)
526 return NULL;
527 if (lz->start == 1)
528 return item;
529
530 good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
531 if (good == NULL) {
532 Py_DECREF(item);
533 return NULL;
534 }
535 ok = PyObject_IsTrue(good);
536 Py_DECREF(good);
537 if (!ok) {
538 lz->start = 1;
539 return item;
540 }
541 Py_DECREF(item);
542 }
543}
544
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000545PyDoc_STRVAR(dropwhile_doc,
546"dropwhile(predicate, iterable) --> dropwhile object\n\
547\n\
548Drop items from the iterable while predicate(item) is true.\n\
549Afterwards, return every element until the iterable is exhausted.");
550
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000551static PyTypeObject dropwhile_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000552 PyObject_HEAD_INIT(NULL)
553 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000554 "itertools.dropwhile", /* tp_name */
555 sizeof(dropwhileobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000556 0, /* tp_itemsize */
557 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000558 (destructor)dropwhile_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000559 0, /* tp_print */
560 0, /* tp_getattr */
561 0, /* tp_setattr */
562 0, /* tp_compare */
563 0, /* tp_repr */
564 0, /* tp_as_number */
565 0, /* tp_as_sequence */
566 0, /* tp_as_mapping */
567 0, /* tp_hash */
568 0, /* tp_call */
569 0, /* tp_str */
570 PyObject_GenericGetAttr, /* tp_getattro */
571 0, /* tp_setattro */
572 0, /* tp_as_buffer */
573 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
574 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000575 dropwhile_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000576 (traverseproc)dropwhile_traverse, /* tp_traverse */
577 0, /* tp_clear */
578 0, /* tp_richcompare */
579 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000580 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000581 (iternextfunc)dropwhile_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000582 0, /* tp_methods */
583 0, /* tp_members */
584 0, /* tp_getset */
585 0, /* tp_base */
586 0, /* tp_dict */
587 0, /* tp_descr_get */
588 0, /* tp_descr_set */
589 0, /* tp_dictoffset */
590 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +0000591 0, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000592 dropwhile_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000593 PyObject_GC_Del, /* tp_free */
594};
595
596
597/* takewhile object **********************************************************/
598
599typedef struct {
600 PyObject_HEAD
601 PyObject *func;
602 PyObject *it;
603 long stop;
604} takewhileobject;
605
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000606static PyTypeObject takewhile_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000607
608static PyObject *
609takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
610{
611 PyObject *func, *seq;
612 PyObject *it;
613 takewhileobject *lz;
614
615 if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq))
616 return NULL;
617
618 /* Get iterator. */
619 it = PyObject_GetIter(seq);
620 if (it == NULL)
621 return NULL;
622
623 /* create takewhileobject structure */
624 lz = (takewhileobject *)type->tp_alloc(type, 0);
625 if (lz == NULL) {
626 Py_DECREF(it);
627 return NULL;
628 }
629 Py_INCREF(func);
630 lz->func = func;
631 lz->it = it;
632 lz->stop = 0;
633
634 return (PyObject *)lz;
635}
636
637static void
638takewhile_dealloc(takewhileobject *lz)
639{
640 PyObject_GC_UnTrack(lz);
641 Py_XDECREF(lz->func);
642 Py_XDECREF(lz->it);
643 lz->ob_type->tp_free(lz);
644}
645
646static int
647takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg)
648{
649 int err;
650
651 if (lz->it) {
652 err = visit(lz->it, arg);
653 if (err)
654 return err;
655 }
656 if (lz->func) {
657 err = visit(lz->func, arg);
658 if (err)
659 return err;
660 }
661 return 0;
662}
663
664static PyObject *
665takewhile_next(takewhileobject *lz)
666{
667 PyObject *item, *good;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000668 PyObject *it = lz->it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000669 long ok;
670
671 if (lz->stop == 1)
672 return NULL;
673
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000674 assert(PyIter_Check(it));
675 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000676 if (item == NULL)
677 return NULL;
678
679 good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
680 if (good == NULL) {
681 Py_DECREF(item);
682 return NULL;
683 }
684 ok = PyObject_IsTrue(good);
685 Py_DECREF(good);
686 if (ok)
687 return item;
688 Py_DECREF(item);
689 lz->stop = 1;
690 return NULL;
691}
692
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000693PyDoc_STRVAR(takewhile_doc,
694"takewhile(predicate, iterable) --> takewhile object\n\
695\n\
696Return successive entries from an iterable as long as the \n\
697predicate evaluates to true for each entry.");
698
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000699static PyTypeObject takewhile_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000700 PyObject_HEAD_INIT(NULL)
701 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000702 "itertools.takewhile", /* tp_name */
703 sizeof(takewhileobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000704 0, /* tp_itemsize */
705 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000706 (destructor)takewhile_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000707 0, /* tp_print */
708 0, /* tp_getattr */
709 0, /* tp_setattr */
710 0, /* tp_compare */
711 0, /* tp_repr */
712 0, /* tp_as_number */
713 0, /* tp_as_sequence */
714 0, /* tp_as_mapping */
715 0, /* tp_hash */
716 0, /* tp_call */
717 0, /* tp_str */
718 PyObject_GenericGetAttr, /* tp_getattro */
719 0, /* tp_setattro */
720 0, /* tp_as_buffer */
721 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
722 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000723 takewhile_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000724 (traverseproc)takewhile_traverse, /* tp_traverse */
725 0, /* tp_clear */
726 0, /* tp_richcompare */
727 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000728 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000729 (iternextfunc)takewhile_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000730 0, /* tp_methods */
731 0, /* tp_members */
732 0, /* tp_getset */
733 0, /* tp_base */
734 0, /* tp_dict */
735 0, /* tp_descr_get */
736 0, /* tp_descr_set */
737 0, /* tp_dictoffset */
738 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +0000739 0, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000740 takewhile_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000741 PyObject_GC_Del, /* tp_free */
742};
743
744
745/* islice object ************************************************************/
746
747typedef struct {
748 PyObject_HEAD
749 PyObject *it;
750 long next;
751 long stop;
752 long step;
753 long cnt;
754} isliceobject;
755
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000756static PyTypeObject islice_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000757
758static PyObject *
759islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
760{
761 PyObject *seq;
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000762 long start=0, stop=-1, step=1;
763 PyObject *it, *a1=NULL, *a2=NULL;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000764 int numargs;
765 isliceobject *lz;
766
767 numargs = PyTuple_Size(args);
Raymond Hettinger341deb72003-05-02 19:44:20 +0000768 if (!PyArg_ParseTuple(args, "OO|Ol:islice", &seq, &a1, &a2, &step))
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000769 return NULL;
770
771 if (numargs == 2) {
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000772 if (a1 != Py_None) {
773 stop = PyInt_AsLong(a1);
774 if (stop == -1) {
775 if (PyErr_Occurred())
776 PyErr_Clear();
777 PyErr_SetString(PyExc_ValueError,
Raymond Hettinger0e4f7642003-10-28 07:32:28 +0000778 "Stop argument must be a non-negative integer or None.");
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000779 return NULL;
780 }
781 }
Raymond Hettinger341deb72003-05-02 19:44:20 +0000782 } else {
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000783 start = PyInt_AsLong(a1);
784 if (start == -1 && PyErr_Occurred()) {
785 PyErr_Clear();
786 PyErr_SetString(PyExc_ValueError,
Raymond Hettinger0e4f7642003-10-28 07:32:28 +0000787 "Start argument must be a non-negative integer.");
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000788 return NULL;
789 }
790 if (a2 != Py_None) {
791 stop = PyInt_AsLong(a2);
792 if (stop == -1) {
793 if (PyErr_Occurred())
794 PyErr_Clear();
795 PyErr_SetString(PyExc_ValueError,
Raymond Hettinger0e4f7642003-10-28 07:32:28 +0000796 "Stop argument must be a non-negative integer or None.");
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000797 return NULL;
798 }
799 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000800 }
801
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000802 if (start<0 || stop<-1) {
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000803 PyErr_SetString(PyExc_ValueError,
Raymond Hettinger0e4f7642003-10-28 07:32:28 +0000804 "Indices for islice() must be non-negative integers.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000805 return NULL;
806 }
807
808 if (step<1) {
809 PyErr_SetString(PyExc_ValueError,
810 "Step must be one or larger for islice().");
811 return NULL;
812 }
813
814 /* Get iterator. */
815 it = PyObject_GetIter(seq);
816 if (it == NULL)
817 return NULL;
818
819 /* create isliceobject structure */
820 lz = (isliceobject *)type->tp_alloc(type, 0);
821 if (lz == NULL) {
822 Py_DECREF(it);
823 return NULL;
824 }
825 lz->it = it;
826 lz->next = start;
827 lz->stop = stop;
828 lz->step = step;
829 lz->cnt = 0L;
830
831 return (PyObject *)lz;
832}
833
834static void
835islice_dealloc(isliceobject *lz)
836{
837 PyObject_GC_UnTrack(lz);
838 Py_XDECREF(lz->it);
839 lz->ob_type->tp_free(lz);
840}
841
842static int
843islice_traverse(isliceobject *lz, visitproc visit, void *arg)
844{
845 if (lz->it)
846 return visit(lz->it, arg);
847 return 0;
848}
849
850static PyObject *
851islice_next(isliceobject *lz)
852{
853 PyObject *item;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000854 PyObject *it = lz->it;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000855 long oldnext;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000856
857 while (lz->cnt < lz->next) {
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000858 assert(PyIter_Check(it));
859 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000860 if (item == NULL)
861 return NULL;
862 Py_DECREF(item);
863 lz->cnt++;
864 }
Raymond Hettinger14ef54c2003-05-02 19:04:37 +0000865 if (lz->stop != -1 && lz->cnt >= lz->stop)
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000866 return NULL;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +0000867 assert(PyIter_Check(it));
868 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000869 if (item == NULL)
870 return NULL;
871 lz->cnt++;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000872 oldnext = lz->next;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000873 lz->next += lz->step;
Raymond Hettinger2012f172003-02-07 05:32:58 +0000874 if (lz->next < oldnext) /* Check for overflow */
875 lz->next = lz->stop;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000876 return item;
877}
878
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000879PyDoc_STRVAR(islice_doc,
880"islice(iterable, [start,] stop [, step]) --> islice object\n\
881\n\
882Return an iterator whose next() method returns selected values from an\n\
883iterable. If start is specified, will skip all preceding elements;\n\
884otherwise, start defaults to zero. Step defaults to one. If\n\
885specified as another value, step determines how many values are \n\
886skipped between successive calls. Works like a slice() on a list\n\
887but returns an iterator.");
888
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000889static PyTypeObject islice_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000890 PyObject_HEAD_INIT(NULL)
891 0, /* ob_size */
892 "itertools.islice", /* tp_name */
893 sizeof(isliceobject), /* tp_basicsize */
894 0, /* tp_itemsize */
895 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000896 (destructor)islice_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000897 0, /* tp_print */
898 0, /* tp_getattr */
899 0, /* tp_setattr */
900 0, /* tp_compare */
901 0, /* tp_repr */
902 0, /* tp_as_number */
903 0, /* tp_as_sequence */
904 0, /* tp_as_mapping */
905 0, /* tp_hash */
906 0, /* tp_call */
907 0, /* tp_str */
908 PyObject_GenericGetAttr, /* tp_getattro */
909 0, /* tp_setattro */
910 0, /* tp_as_buffer */
911 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
912 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000913 islice_doc, /* tp_doc */
914 (traverseproc)islice_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000915 0, /* tp_clear */
916 0, /* tp_richcompare */
917 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +0000918 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +0000919 (iternextfunc)islice_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000920 0, /* tp_methods */
921 0, /* tp_members */
922 0, /* tp_getset */
923 0, /* tp_base */
924 0, /* tp_dict */
925 0, /* tp_descr_get */
926 0, /* tp_descr_set */
927 0, /* tp_dictoffset */
928 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +0000929 0, /* tp_alloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000930 islice_new, /* tp_new */
931 PyObject_GC_Del, /* tp_free */
932};
933
934
935/* starmap object ************************************************************/
936
937typedef struct {
938 PyObject_HEAD
939 PyObject *func;
940 PyObject *it;
941} starmapobject;
942
Raymond Hettinger1d7a3482003-07-14 07:07:12 +0000943static PyTypeObject starmap_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +0000944
945static PyObject *
946starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
947{
948 PyObject *func, *seq;
949 PyObject *it;
950 starmapobject *lz;
951
952 if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq))
953 return NULL;
954
955 /* Get iterator. */
956 it = PyObject_GetIter(seq);
957 if (it == NULL)
958 return NULL;
959
960 /* create starmapobject structure */
961 lz = (starmapobject *)type->tp_alloc(type, 0);
962 if (lz == NULL) {
963 Py_DECREF(it);
964 return NULL;
965 }
966 Py_INCREF(func);
967 lz->func = func;
968 lz->it = it;
969
970 return (PyObject *)lz;
971}
972
973static void
974starmap_dealloc(starmapobject *lz)
975{
976 PyObject_GC_UnTrack(lz);
977 Py_XDECREF(lz->func);
978 Py_XDECREF(lz->it);
979 lz->ob_type->tp_free(lz);
980}
981
982static int
983starmap_traverse(starmapobject *lz, visitproc visit, void *arg)
984{
985 int err;
986
987 if (lz->it) {
988 err = visit(lz->it, arg);
989 if (err)
990 return err;
991 }
992 if (lz->func) {
993 err = visit(lz->func, arg);
994 if (err)
995 return err;
996 }
997 return 0;
998}
999
1000static PyObject *
1001starmap_next(starmapobject *lz)
1002{
1003 PyObject *args;
1004 PyObject *result;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001005 PyObject *it = lz->it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001006
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001007 assert(PyIter_Check(it));
1008 args = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001009 if (args == NULL)
1010 return NULL;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001011 if (!PyTuple_CheckExact(args)) {
1012 Py_DECREF(args);
1013 PyErr_SetString(PyExc_TypeError,
1014 "iterator must return a tuple");
1015 return NULL;
1016 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001017 result = PyObject_Call(lz->func, args, NULL);
1018 Py_DECREF(args);
1019 return result;
1020}
1021
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001022PyDoc_STRVAR(starmap_doc,
1023"starmap(function, sequence) --> starmap object\n\
1024\n\
1025Return an iterator whose values are returned from the function evaluated\n\
1026with a argument tuple taken from the given sequence.");
1027
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001028static PyTypeObject starmap_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001029 PyObject_HEAD_INIT(NULL)
1030 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001031 "itertools.starmap", /* tp_name */
1032 sizeof(starmapobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001033 0, /* tp_itemsize */
1034 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001035 (destructor)starmap_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001036 0, /* tp_print */
1037 0, /* tp_getattr */
1038 0, /* tp_setattr */
1039 0, /* tp_compare */
1040 0, /* tp_repr */
1041 0, /* tp_as_number */
1042 0, /* tp_as_sequence */
1043 0, /* tp_as_mapping */
1044 0, /* tp_hash */
1045 0, /* tp_call */
1046 0, /* tp_str */
1047 PyObject_GenericGetAttr, /* tp_getattro */
1048 0, /* tp_setattro */
1049 0, /* tp_as_buffer */
1050 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1051 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001052 starmap_doc, /* tp_doc */
1053 (traverseproc)starmap_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001054 0, /* tp_clear */
1055 0, /* tp_richcompare */
1056 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001057 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001058 (iternextfunc)starmap_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001059 0, /* tp_methods */
1060 0, /* tp_members */
1061 0, /* tp_getset */
1062 0, /* tp_base */
1063 0, /* tp_dict */
1064 0, /* tp_descr_get */
1065 0, /* tp_descr_set */
1066 0, /* tp_dictoffset */
1067 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +00001068 0, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001069 starmap_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001070 PyObject_GC_Del, /* tp_free */
1071};
1072
1073
1074/* imap object ************************************************************/
1075
1076typedef struct {
1077 PyObject_HEAD
1078 PyObject *iters;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001079 PyObject *func;
1080} imapobject;
1081
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001082static PyTypeObject imap_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001083
1084static PyObject *
1085imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1086{
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001087 PyObject *it, *iters, *func;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001088 imapobject *lz;
1089 int numargs, i;
1090
1091 numargs = PyTuple_Size(args);
1092 if (numargs < 2) {
1093 PyErr_SetString(PyExc_TypeError,
1094 "imap() must have at least two arguments.");
1095 return NULL;
1096 }
1097
1098 iters = PyTuple_New(numargs-1);
1099 if (iters == NULL)
1100 return NULL;
1101
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001102 for (i=1 ; i<numargs ; i++) {
1103 /* Get iterator. */
1104 it = PyObject_GetIter(PyTuple_GET_ITEM(args, i));
1105 if (it == NULL) {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001106 Py_DECREF(iters);
1107 return NULL;
1108 }
1109 PyTuple_SET_ITEM(iters, i-1, it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001110 }
1111
1112 /* create imapobject structure */
1113 lz = (imapobject *)type->tp_alloc(type, 0);
1114 if (lz == NULL) {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001115 Py_DECREF(iters);
1116 return NULL;
1117 }
1118 lz->iters = iters;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001119 func = PyTuple_GET_ITEM(args, 0);
1120 Py_INCREF(func);
1121 lz->func = func;
1122
1123 return (PyObject *)lz;
1124}
1125
1126static void
1127imap_dealloc(imapobject *lz)
1128{
1129 PyObject_GC_UnTrack(lz);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001130 Py_XDECREF(lz->iters);
1131 Py_XDECREF(lz->func);
1132 lz->ob_type->tp_free(lz);
1133}
1134
1135static int
1136imap_traverse(imapobject *lz, visitproc visit, void *arg)
1137{
1138 int err;
1139
1140 if (lz->iters) {
1141 err = visit(lz->iters, arg);
1142 if (err)
1143 return err;
1144 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001145 if (lz->func) {
1146 err = visit(lz->func, arg);
1147 if (err)
1148 return err;
1149 }
1150 return 0;
1151}
1152
Raymond Hettinger2012f172003-02-07 05:32:58 +00001153/*
1154imap() is an iterator version of __builtins__.map() except that it does
1155not have the None fill-in feature. That was intentionally left out for
1156the following reasons:
1157
1158 1) Itertools are designed to be easily combined and chained together.
1159 Having all tools stop with the shortest input is a unifying principle
1160 that makes it easier to combine finite iterators (supplying data) with
1161 infinite iterators like count() and repeat() (for supplying sequential
1162 or constant arguments to a function).
1163
1164 2) In typical use cases for combining itertools, having one finite data
1165 supplier run out before another is likely to be an error condition which
1166 should not pass silently by automatically supplying None.
1167
1168 3) The use cases for automatic None fill-in are rare -- not many functions
1169 do something useful when a parameter suddenly switches type and becomes
1170 None.
1171
1172 4) If a need does arise, it can be met by __builtins__.map() or by
Raymond Hettingerbefa37d2003-06-18 19:25:37 +00001173 writing: chain(iterable, repeat(None)).
Raymond Hettinger2012f172003-02-07 05:32:58 +00001174
1175 5) Similar toolsets in Haskell and SML do not have automatic None fill-in.
1176*/
1177
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001178static PyObject *
1179imap_next(imapobject *lz)
1180{
1181 PyObject *val;
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001182 PyObject *argtuple;
1183 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001184 int numargs, i;
1185
1186 numargs = PyTuple_Size(lz->iters);
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001187 argtuple = PyTuple_New(numargs);
1188 if (argtuple == NULL)
1189 return NULL;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001190
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001191 for (i=0 ; i<numargs ; i++) {
1192 val = PyIter_Next(PyTuple_GET_ITEM(lz->iters, i));
1193 if (val == NULL) {
1194 Py_DECREF(argtuple);
1195 return NULL;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001196 }
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001197 PyTuple_SET_ITEM(argtuple, i, val);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001198 }
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001199 if (lz->func == Py_None)
1200 return argtuple;
1201 result = PyObject_Call(lz->func, argtuple, NULL);
1202 Py_DECREF(argtuple);
1203 return result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001204}
1205
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001206PyDoc_STRVAR(imap_doc,
1207"imap(func, *iterables) --> imap object\n\
1208\n\
1209Make an iterator that computes the function using arguments from\n\
1210each of the iterables. Like map() except that it returns\n\
1211an iterator instead of a list and that it stops when the shortest\n\
1212iterable is exhausted instead of filling in None for shorter\n\
1213iterables.");
1214
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001215static PyTypeObject imap_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001216 PyObject_HEAD_INIT(NULL)
1217 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001218 "itertools.imap", /* tp_name */
1219 sizeof(imapobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001220 0, /* tp_itemsize */
1221 /* methods */
1222 (destructor)imap_dealloc, /* tp_dealloc */
1223 0, /* tp_print */
1224 0, /* tp_getattr */
1225 0, /* tp_setattr */
1226 0, /* tp_compare */
1227 0, /* tp_repr */
1228 0, /* tp_as_number */
1229 0, /* tp_as_sequence */
1230 0, /* tp_as_mapping */
1231 0, /* tp_hash */
1232 0, /* tp_call */
1233 0, /* tp_str */
1234 PyObject_GenericGetAttr, /* tp_getattro */
1235 0, /* tp_setattro */
1236 0, /* tp_as_buffer */
1237 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1238 Py_TPFLAGS_BASETYPE, /* tp_flags */
1239 imap_doc, /* tp_doc */
1240 (traverseproc)imap_traverse, /* tp_traverse */
1241 0, /* tp_clear */
1242 0, /* tp_richcompare */
1243 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001244 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001245 (iternextfunc)imap_next, /* tp_iternext */
1246 0, /* tp_methods */
1247 0, /* tp_members */
1248 0, /* tp_getset */
1249 0, /* tp_base */
1250 0, /* tp_dict */
1251 0, /* tp_descr_get */
1252 0, /* tp_descr_set */
1253 0, /* tp_dictoffset */
1254 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +00001255 0, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001256 imap_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001257 PyObject_GC_Del, /* tp_free */
1258};
1259
1260
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001261/* chain object ************************************************************/
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001262
1263typedef struct {
1264 PyObject_HEAD
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001265 long tuplesize;
1266 long iternum; /* which iterator is active */
1267 PyObject *ittuple; /* tuple of iterators */
1268} chainobject;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001269
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001270static PyTypeObject chain_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001271
1272static PyObject *
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001273chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001274{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001275 chainobject *lz;
1276 int tuplesize = PySequence_Length(args);
1277 int i;
1278 PyObject *ittuple;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001279
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001280 /* obtain iterators */
1281 assert(PyTuple_Check(args));
1282 ittuple = PyTuple_New(tuplesize);
1283 if(ittuple == NULL)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001284 return NULL;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001285 for (i=0; i < tuplesize; ++i) {
1286 PyObject *item = PyTuple_GET_ITEM(args, i);
1287 PyObject *it = PyObject_GetIter(item);
1288 if (it == NULL) {
1289 if (PyErr_ExceptionMatches(PyExc_TypeError))
1290 PyErr_Format(PyExc_TypeError,
1291 "chain argument #%d must support iteration",
1292 i+1);
1293 Py_DECREF(ittuple);
1294 return NULL;
1295 }
1296 PyTuple_SET_ITEM(ittuple, i, it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001297 }
1298
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001299 /* create chainobject structure */
1300 lz = (chainobject *)type->tp_alloc(type, 0);
Raymond Hettinger7d98fb92003-06-17 23:14:40 +00001301 if (lz == NULL) {
1302 Py_DECREF(ittuple);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001303 return NULL;
Raymond Hettinger7d98fb92003-06-17 23:14:40 +00001304 }
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001305
1306 lz->ittuple = ittuple;
1307 lz->iternum = 0;
1308 lz->tuplesize = tuplesize;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001309
1310 return (PyObject *)lz;
1311}
1312
1313static void
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001314chain_dealloc(chainobject *lz)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001315{
1316 PyObject_GC_UnTrack(lz);
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001317 Py_XDECREF(lz->ittuple);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001318 lz->ob_type->tp_free(lz);
1319}
1320
Raymond Hettinger2012f172003-02-07 05:32:58 +00001321static int
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001322chain_traverse(chainobject *lz, visitproc visit, void *arg)
Raymond Hettinger2012f172003-02-07 05:32:58 +00001323{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001324 if (lz->ittuple)
1325 return visit(lz->ittuple, arg);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001326 return 0;
1327}
1328
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001329static PyObject *
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001330chain_next(chainobject *lz)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001331{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001332 PyObject *it;
1333 PyObject *item;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001334
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001335 while (lz->iternum < lz->tuplesize) {
1336 it = PyTuple_GET_ITEM(lz->ittuple, lz->iternum);
1337 item = PyIter_Next(it);
1338 if (item != NULL)
1339 return item;
1340 lz->iternum++;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001341 }
1342 return NULL;
1343}
1344
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001345PyDoc_STRVAR(chain_doc,
1346"chain(*iterables) --> chain object\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001347\n\
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001348Return a chain object whose .next() method returns elements from the\n\
1349first iterable until it is exhausted, then elements from the next\n\
1350iterable, until all of the iterables are exhausted.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001351
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001352static PyTypeObject chain_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001353 PyObject_HEAD_INIT(NULL)
1354 0, /* ob_size */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001355 "itertools.chain", /* tp_name */
1356 sizeof(chainobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001357 0, /* tp_itemsize */
1358 /* methods */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001359 (destructor)chain_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001360 0, /* tp_print */
1361 0, /* tp_getattr */
1362 0, /* tp_setattr */
1363 0, /* tp_compare */
1364 0, /* tp_repr */
1365 0, /* tp_as_number */
1366 0, /* tp_as_sequence */
1367 0, /* tp_as_mapping */
1368 0, /* tp_hash */
1369 0, /* tp_call */
1370 0, /* tp_str */
1371 PyObject_GenericGetAttr, /* tp_getattro */
1372 0, /* tp_setattro */
1373 0, /* tp_as_buffer */
1374 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1375 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001376 chain_doc, /* tp_doc */
1377 (traverseproc)chain_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001378 0, /* tp_clear */
1379 0, /* tp_richcompare */
1380 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001381 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001382 (iternextfunc)chain_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001383 0, /* tp_methods */
1384 0, /* tp_members */
1385 0, /* tp_getset */
1386 0, /* tp_base */
1387 0, /* tp_dict */
1388 0, /* tp_descr_get */
1389 0, /* tp_descr_set */
1390 0, /* tp_dictoffset */
1391 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +00001392 0, /* tp_alloc */
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001393 chain_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001394 PyObject_GC_Del, /* tp_free */
1395};
1396
1397
1398/* ifilter object ************************************************************/
1399
1400typedef struct {
1401 PyObject_HEAD
1402 PyObject *func;
1403 PyObject *it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001404} ifilterobject;
1405
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001406static PyTypeObject ifilter_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001407
1408static PyObject *
1409ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1410{
Raymond Hettinger60eca932003-02-09 06:40:58 +00001411 PyObject *func, *seq;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001412 PyObject *it;
1413 ifilterobject *lz;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001414
Raymond Hettinger60eca932003-02-09 06:40:58 +00001415 if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq))
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001416 return NULL;
1417
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001418 /* Get iterator. */
1419 it = PyObject_GetIter(seq);
1420 if (it == NULL)
1421 return NULL;
1422
1423 /* create ifilterobject structure */
1424 lz = (ifilterobject *)type->tp_alloc(type, 0);
1425 if (lz == NULL) {
1426 Py_DECREF(it);
1427 return NULL;
1428 }
1429 Py_INCREF(func);
1430 lz->func = func;
1431 lz->it = it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001432
1433 return (PyObject *)lz;
1434}
1435
1436static void
1437ifilter_dealloc(ifilterobject *lz)
1438{
1439 PyObject_GC_UnTrack(lz);
1440 Py_XDECREF(lz->func);
1441 Py_XDECREF(lz->it);
1442 lz->ob_type->tp_free(lz);
1443}
1444
1445static int
1446ifilter_traverse(ifilterobject *lz, visitproc visit, void *arg)
1447{
1448 int err;
1449
1450 if (lz->it) {
1451 err = visit(lz->it, arg);
1452 if (err)
1453 return err;
1454 }
1455 if (lz->func) {
1456 err = visit(lz->func, arg);
1457 if (err)
1458 return err;
1459 }
1460 return 0;
1461}
1462
1463static PyObject *
1464ifilter_next(ifilterobject *lz)
1465{
1466 PyObject *item;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001467 PyObject *it = lz->it;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001468 long ok;
1469
1470 for (;;) {
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001471 assert(PyIter_Check(it));
1472 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001473 if (item == NULL)
1474 return NULL;
1475
1476 if (lz->func == Py_None) {
1477 ok = PyObject_IsTrue(item);
1478 } else {
1479 PyObject *good;
1480 good = PyObject_CallFunctionObjArgs(lz->func,
1481 item, NULL);
1482 if (good == NULL) {
1483 Py_DECREF(item);
1484 return NULL;
1485 }
1486 ok = PyObject_IsTrue(good);
1487 Py_DECREF(good);
1488 }
Raymond Hettinger60eca932003-02-09 06:40:58 +00001489 if (ok)
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001490 return item;
1491 Py_DECREF(item);
1492 }
1493}
1494
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001495PyDoc_STRVAR(ifilter_doc,
Raymond Hettinger60eca932003-02-09 06:40:58 +00001496"ifilter(function or None, sequence) --> ifilter object\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001497\n\
Raymond Hettinger60eca932003-02-09 06:40:58 +00001498Return those items of sequence for which function(item) is true.\n\
1499If function is None, return the items that are true.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001500
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001501static PyTypeObject ifilter_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001502 PyObject_HEAD_INIT(NULL)
1503 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001504 "itertools.ifilter", /* tp_name */
1505 sizeof(ifilterobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001506 0, /* tp_itemsize */
1507 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001508 (destructor)ifilter_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001509 0, /* tp_print */
1510 0, /* tp_getattr */
1511 0, /* tp_setattr */
1512 0, /* tp_compare */
1513 0, /* tp_repr */
1514 0, /* tp_as_number */
1515 0, /* tp_as_sequence */
1516 0, /* tp_as_mapping */
1517 0, /* tp_hash */
1518 0, /* tp_call */
1519 0, /* tp_str */
1520 PyObject_GenericGetAttr, /* tp_getattro */
1521 0, /* tp_setattro */
1522 0, /* tp_as_buffer */
1523 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1524 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001525 ifilter_doc, /* tp_doc */
1526 (traverseproc)ifilter_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001527 0, /* tp_clear */
1528 0, /* tp_richcompare */
1529 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001530 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001531 (iternextfunc)ifilter_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001532 0, /* tp_methods */
1533 0, /* tp_members */
1534 0, /* tp_getset */
1535 0, /* tp_base */
1536 0, /* tp_dict */
1537 0, /* tp_descr_get */
1538 0, /* tp_descr_set */
1539 0, /* tp_dictoffset */
1540 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +00001541 0, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001542 ifilter_new, /* tp_new */
1543 PyObject_GC_Del, /* tp_free */
1544};
1545
1546
1547/* ifilterfalse object ************************************************************/
1548
1549typedef struct {
1550 PyObject_HEAD
1551 PyObject *func;
1552 PyObject *it;
1553} ifilterfalseobject;
1554
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001555static PyTypeObject ifilterfalse_type;
Raymond Hettinger60eca932003-02-09 06:40:58 +00001556
1557static PyObject *
1558ifilterfalse_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1559{
Guido van Rossumd58f3fc2003-02-09 17:19:18 +00001560 PyObject *func, *seq;
Raymond Hettinger60eca932003-02-09 06:40:58 +00001561 PyObject *it;
1562 ifilterfalseobject *lz;
1563
1564 if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq))
1565 return NULL;
1566
1567 /* Get iterator. */
1568 it = PyObject_GetIter(seq);
1569 if (it == NULL)
1570 return NULL;
1571
1572 /* create ifilterfalseobject structure */
1573 lz = (ifilterfalseobject *)type->tp_alloc(type, 0);
1574 if (lz == NULL) {
1575 Py_DECREF(it);
1576 return NULL;
1577 }
1578 Py_INCREF(func);
1579 lz->func = func;
1580 lz->it = it;
1581
1582 return (PyObject *)lz;
1583}
1584
1585static void
1586ifilterfalse_dealloc(ifilterfalseobject *lz)
1587{
1588 PyObject_GC_UnTrack(lz);
1589 Py_XDECREF(lz->func);
1590 Py_XDECREF(lz->it);
1591 lz->ob_type->tp_free(lz);
1592}
1593
1594static int
1595ifilterfalse_traverse(ifilterfalseobject *lz, visitproc visit, void *arg)
1596{
1597 int err;
1598
1599 if (lz->it) {
1600 err = visit(lz->it, arg);
1601 if (err)
1602 return err;
1603 }
1604 if (lz->func) {
1605 err = visit(lz->func, arg);
1606 if (err)
1607 return err;
1608 }
1609 return 0;
1610}
1611
1612static PyObject *
1613ifilterfalse_next(ifilterfalseobject *lz)
1614{
1615 PyObject *item;
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001616 PyObject *it = lz->it;
Raymond Hettinger60eca932003-02-09 06:40:58 +00001617 long ok;
1618
1619 for (;;) {
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001620 assert(PyIter_Check(it));
1621 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettinger60eca932003-02-09 06:40:58 +00001622 if (item == NULL)
1623 return NULL;
1624
1625 if (lz->func == Py_None) {
1626 ok = PyObject_IsTrue(item);
1627 } else {
1628 PyObject *good;
1629 good = PyObject_CallFunctionObjArgs(lz->func,
1630 item, NULL);
1631 if (good == NULL) {
1632 Py_DECREF(item);
1633 return NULL;
1634 }
1635 ok = PyObject_IsTrue(good);
1636 Py_DECREF(good);
1637 }
1638 if (!ok)
1639 return item;
1640 Py_DECREF(item);
1641 }
1642}
1643
Raymond Hettinger60eca932003-02-09 06:40:58 +00001644PyDoc_STRVAR(ifilterfalse_doc,
1645"ifilterfalse(function or None, sequence) --> ifilterfalse object\n\
1646\n\
1647Return those items of sequence for which function(item) is false.\n\
1648If function is None, return the items that are false.");
1649
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001650static PyTypeObject ifilterfalse_type = {
Raymond Hettinger60eca932003-02-09 06:40:58 +00001651 PyObject_HEAD_INIT(NULL)
1652 0, /* ob_size */
1653 "itertools.ifilterfalse", /* tp_name */
1654 sizeof(ifilterfalseobject), /* tp_basicsize */
1655 0, /* tp_itemsize */
1656 /* methods */
1657 (destructor)ifilterfalse_dealloc, /* tp_dealloc */
1658 0, /* tp_print */
1659 0, /* tp_getattr */
1660 0, /* tp_setattr */
1661 0, /* tp_compare */
1662 0, /* tp_repr */
1663 0, /* tp_as_number */
1664 0, /* tp_as_sequence */
1665 0, /* tp_as_mapping */
1666 0, /* tp_hash */
1667 0, /* tp_call */
1668 0, /* tp_str */
1669 PyObject_GenericGetAttr, /* tp_getattro */
1670 0, /* tp_setattro */
1671 0, /* tp_as_buffer */
1672 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1673 Py_TPFLAGS_BASETYPE, /* tp_flags */
1674 ifilterfalse_doc, /* tp_doc */
1675 (traverseproc)ifilterfalse_traverse, /* tp_traverse */
1676 0, /* tp_clear */
1677 0, /* tp_richcompare */
1678 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001679 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001680 (iternextfunc)ifilterfalse_next, /* tp_iternext */
1681 0, /* tp_methods */
1682 0, /* tp_members */
1683 0, /* tp_getset */
1684 0, /* tp_base */
1685 0, /* tp_dict */
1686 0, /* tp_descr_get */
1687 0, /* tp_descr_set */
1688 0, /* tp_dictoffset */
1689 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +00001690 0, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001691 ifilterfalse_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001692 PyObject_GC_Del, /* tp_free */
1693};
1694
1695
1696/* count object ************************************************************/
1697
1698typedef struct {
1699 PyObject_HEAD
1700 long cnt;
1701} countobject;
1702
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001703static PyTypeObject count_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001704
1705static PyObject *
1706count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1707{
1708 countobject *lz;
1709 long cnt = 0;
1710
1711 if (!PyArg_ParseTuple(args, "|l:count", &cnt))
1712 return NULL;
1713
1714 /* create countobject structure */
1715 lz = (countobject *)PyObject_New(countobject, &count_type);
1716 if (lz == NULL)
1717 return NULL;
1718 lz->cnt = cnt;
1719
1720 return (PyObject *)lz;
1721}
1722
1723static PyObject *
1724count_next(countobject *lz)
1725{
1726 return PyInt_FromLong(lz->cnt++);
1727}
1728
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001729PyDoc_STRVAR(count_doc,
1730"count([firstval]) --> count object\n\
1731\n\
1732Return a count object whose .next() method returns consecutive\n\
1733integers starting from zero or, if specified, from firstval.");
1734
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001735static PyTypeObject count_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001736 PyObject_HEAD_INIT(NULL)
1737 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001738 "itertools.count", /* tp_name */
1739 sizeof(countobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001740 0, /* tp_itemsize */
1741 /* methods */
1742 (destructor)PyObject_Del, /* tp_dealloc */
1743 0, /* tp_print */
1744 0, /* tp_getattr */
1745 0, /* tp_setattr */
1746 0, /* tp_compare */
1747 0, /* tp_repr */
1748 0, /* tp_as_number */
1749 0, /* tp_as_sequence */
1750 0, /* tp_as_mapping */
1751 0, /* tp_hash */
1752 0, /* tp_call */
1753 0, /* tp_str */
1754 PyObject_GenericGetAttr, /* tp_getattro */
1755 0, /* tp_setattro */
1756 0, /* tp_as_buffer */
1757 Py_TPFLAGS_DEFAULT, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001758 count_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001759 0, /* tp_traverse */
1760 0, /* tp_clear */
1761 0, /* tp_richcompare */
1762 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001763 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001764 (iternextfunc)count_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001765 0, /* tp_methods */
1766 0, /* tp_members */
1767 0, /* tp_getset */
1768 0, /* tp_base */
1769 0, /* tp_dict */
1770 0, /* tp_descr_get */
1771 0, /* tp_descr_set */
1772 0, /* tp_dictoffset */
1773 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +00001774 0, /* tp_alloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001775 count_new, /* tp_new */
1776};
1777
1778
1779/* izip object ************************************************************/
1780
1781#include "Python.h"
1782
1783typedef struct {
1784 PyObject_HEAD
1785 long tuplesize;
1786 PyObject *ittuple; /* tuple of iterators */
Raymond Hettinger2012f172003-02-07 05:32:58 +00001787 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001788} izipobject;
1789
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001790static PyTypeObject izip_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001791
1792static PyObject *
1793izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1794{
1795 izipobject *lz;
1796 int i;
1797 PyObject *ittuple; /* tuple of iterators */
Raymond Hettinger2012f172003-02-07 05:32:58 +00001798 PyObject *result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001799 int tuplesize = PySequence_Length(args);
1800
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001801 /* args must be a tuple */
1802 assert(PyTuple_Check(args));
1803
1804 /* obtain iterators */
1805 ittuple = PyTuple_New(tuplesize);
1806 if(ittuple == NULL)
1807 return NULL;
1808 for (i=0; i < tuplesize; ++i) {
1809 PyObject *item = PyTuple_GET_ITEM(args, i);
1810 PyObject *it = PyObject_GetIter(item);
1811 if (it == NULL) {
1812 if (PyErr_ExceptionMatches(PyExc_TypeError))
1813 PyErr_Format(PyExc_TypeError,
1814 "izip argument #%d must support iteration",
1815 i+1);
1816 Py_DECREF(ittuple);
1817 return NULL;
1818 }
1819 PyTuple_SET_ITEM(ittuple, i, it);
1820 }
1821
Raymond Hettinger2012f172003-02-07 05:32:58 +00001822 /* create a result holder */
1823 result = PyTuple_New(tuplesize);
1824 if (result == NULL) {
1825 Py_DECREF(ittuple);
1826 return NULL;
1827 }
1828 for (i=0 ; i < tuplesize ; i++) {
1829 Py_INCREF(Py_None);
1830 PyTuple_SET_ITEM(result, i, Py_None);
1831 }
1832
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001833 /* create izipobject structure */
1834 lz = (izipobject *)type->tp_alloc(type, 0);
1835 if (lz == NULL) {
1836 Py_DECREF(ittuple);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001837 Py_DECREF(result);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001838 return NULL;
1839 }
1840 lz->ittuple = ittuple;
1841 lz->tuplesize = tuplesize;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001842 lz->result = result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001843
1844 return (PyObject *)lz;
1845}
1846
1847static void
1848izip_dealloc(izipobject *lz)
1849{
1850 PyObject_GC_UnTrack(lz);
1851 Py_XDECREF(lz->ittuple);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001852 Py_XDECREF(lz->result);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001853 lz->ob_type->tp_free(lz);
1854}
1855
1856static int
1857izip_traverse(izipobject *lz, visitproc visit, void *arg)
1858{
Raymond Hettingerbefa37d2003-06-18 19:25:37 +00001859 int err;
1860
1861 if (lz->ittuple) {
1862 err = visit(lz->ittuple, arg);
1863 if (err)
1864 return err;
1865 }
1866 if (lz->result) {
1867 err = visit(lz->result, arg);
1868 if (err)
1869 return err;
1870 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001871 return 0;
1872}
1873
1874static PyObject *
1875izip_next(izipobject *lz)
1876{
1877 int i;
1878 long tuplesize = lz->tuplesize;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001879 PyObject *result = lz->result;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001880 PyObject *it;
1881 PyObject *item;
Raymond Hettinger4f01f892003-08-30 00:10:06 +00001882 PyObject *olditem;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001883
Raymond Hettingerb5a42082003-08-08 05:10:41 +00001884 if (tuplesize == 0)
1885 return NULL;
Raymond Hettinger2012f172003-02-07 05:32:58 +00001886 if (result->ob_refcnt == 1) {
Raymond Hettingera56f6b62003-08-29 23:09:58 +00001887 Py_INCREF(result);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001888 for (i=0 ; i < tuplesize ; i++) {
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001889 it = PyTuple_GET_ITEM(lz->ittuple, i);
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001890 assert(PyIter_Check(it));
1891 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettingera56f6b62003-08-29 23:09:58 +00001892 if (item == NULL) {
1893 Py_DECREF(result);
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001894 return NULL;
Raymond Hettingera56f6b62003-08-29 23:09:58 +00001895 }
Raymond Hettinger4f01f892003-08-30 00:10:06 +00001896 olditem = PyTuple_GET_ITEM(result, i);
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001897 PyTuple_SET_ITEM(result, i, item);
Raymond Hettinger4f01f892003-08-30 00:10:06 +00001898 Py_DECREF(olditem);
Raymond Hettinger2012f172003-02-07 05:32:58 +00001899 }
Raymond Hettinger2012f172003-02-07 05:32:58 +00001900 } else {
Raymond Hettinger2012f172003-02-07 05:32:58 +00001901 result = PyTuple_New(tuplesize);
1902 if (result == NULL)
1903 return NULL;
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001904 for (i=0 ; i < tuplesize ; i++) {
1905 it = PyTuple_GET_ITEM(lz->ittuple, i);
Raymond Hettingerd1a283b2003-03-01 01:48:24 +00001906 assert(PyIter_Check(it));
1907 item = (*it->ob_type->tp_iternext)(it);
Raymond Hettingerf0c00242003-02-07 07:26:25 +00001908 if (item == NULL) {
1909 Py_DECREF(result);
1910 return NULL;
1911 }
1912 PyTuple_SET_ITEM(result, i, item);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001913 }
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001914 }
1915 return result;
1916}
1917
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001918PyDoc_STRVAR(izip_doc,
1919"izip(iter1 [,iter2 [...]]) --> izip object\n\
1920\n\
1921Return a izip object whose .next() method returns a tuple where\n\
1922the i-th element comes from the i-th iterable argument. The .next()\n\
1923method continues until the shortest iterable in the argument sequence\n\
1924is exhausted and then it raises StopIteration. Works like the zip()\n\
1925function but consumes less memory by returning an iterator instead of\n\
1926a list.");
1927
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001928static PyTypeObject izip_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001929 PyObject_HEAD_INIT(NULL)
1930 0, /* ob_size */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001931 "itertools.izip", /* tp_name */
1932 sizeof(izipobject), /* tp_basicsize */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001933 0, /* tp_itemsize */
1934 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001935 (destructor)izip_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001936 0, /* tp_print */
1937 0, /* tp_getattr */
1938 0, /* tp_setattr */
1939 0, /* tp_compare */
1940 0, /* tp_repr */
1941 0, /* tp_as_number */
1942 0, /* tp_as_sequence */
1943 0, /* tp_as_mapping */
1944 0, /* tp_hash */
1945 0, /* tp_call */
1946 0, /* tp_str */
1947 PyObject_GenericGetAttr, /* tp_getattro */
1948 0, /* tp_setattro */
1949 0, /* tp_as_buffer */
1950 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1951 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001952 izip_doc, /* tp_doc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001953 (traverseproc)izip_traverse, /* tp_traverse */
1954 0, /* tp_clear */
1955 0, /* tp_richcompare */
1956 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00001957 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001958 (iternextfunc)izip_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001959 0, /* tp_methods */
1960 0, /* tp_members */
1961 0, /* tp_getset */
1962 0, /* tp_base */
1963 0, /* tp_dict */
1964 0, /* tp_descr_get */
1965 0, /* tp_descr_set */
1966 0, /* tp_dictoffset */
1967 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +00001968 0, /* tp_alloc */
Raymond Hettinger60eca932003-02-09 06:40:58 +00001969 izip_new, /* tp_new */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001970 PyObject_GC_Del, /* tp_free */
1971};
1972
1973
1974/* repeat object ************************************************************/
1975
1976typedef struct {
1977 PyObject_HEAD
1978 PyObject *element;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001979 long cnt;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001980} repeatobject;
1981
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00001982static PyTypeObject repeat_type;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001983
1984static PyObject *
1985repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1986{
1987 repeatobject *ro;
1988 PyObject *element;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001989 long cnt = -1;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001990
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00001991 if (!PyArg_ParseTuple(args, "O|l:repeat", &element, &cnt))
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001992 return NULL;
1993
Raymond Hettinger7c2bb5b2003-05-03 05:59:48 +00001994 if (PyTuple_Size(args) == 2 && cnt < 0)
1995 cnt = 0;
1996
Raymond Hettinger96ef8112003-02-01 00:10:11 +00001997 ro = (repeatobject *)type->tp_alloc(type, 0);
1998 if (ro == NULL)
1999 return NULL;
2000 Py_INCREF(element);
2001 ro->element = element;
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00002002 ro->cnt = cnt;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002003 return (PyObject *)ro;
2004}
2005
2006static void
2007repeat_dealloc(repeatobject *ro)
2008{
2009 PyObject_GC_UnTrack(ro);
2010 Py_XDECREF(ro->element);
2011 ro->ob_type->tp_free(ro);
2012}
2013
2014static int
2015repeat_traverse(repeatobject *ro, visitproc visit, void *arg)
2016{
2017 if (ro->element)
2018 return visit(ro->element, arg);
2019 return 0;
2020}
2021
2022static PyObject *
2023repeat_next(repeatobject *ro)
2024{
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00002025 if (ro->cnt == 0)
2026 return NULL;
2027 if (ro->cnt > 0)
2028 ro->cnt--;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002029 Py_INCREF(ro->element);
2030 return ro->element;
2031}
2032
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002033PyDoc_STRVAR(repeat_doc,
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00002034"repeat(element [,times]) -> create an iterator which returns the element\n\
2035for the specified number of times. If not specified, returns the element\n\
2036endlessly.");
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002037
Raymond Hettinger1d7a3482003-07-14 07:07:12 +00002038static PyTypeObject repeat_type = {
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002039 PyObject_HEAD_INIT(NULL)
2040 0, /* ob_size */
2041 "itertools.repeat", /* tp_name */
2042 sizeof(repeatobject), /* tp_basicsize */
2043 0, /* tp_itemsize */
2044 /* methods */
Raymond Hettinger60eca932003-02-09 06:40:58 +00002045 (destructor)repeat_dealloc, /* tp_dealloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002046 0, /* tp_print */
2047 0, /* tp_getattr */
2048 0, /* tp_setattr */
2049 0, /* tp_compare */
2050 0, /* tp_repr */
2051 0, /* tp_as_number */
2052 0, /* tp_as_sequence */
2053 0, /* tp_as_mapping */
2054 0, /* tp_hash */
2055 0, /* tp_call */
2056 0, /* tp_str */
2057 PyObject_GenericGetAttr, /* tp_getattro */
2058 0, /* tp_setattro */
2059 0, /* tp_as_buffer */
2060 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2061 Py_TPFLAGS_BASETYPE, /* tp_flags */
Raymond Hettinger60eca932003-02-09 06:40:58 +00002062 repeat_doc, /* tp_doc */
2063 (traverseproc)repeat_traverse, /* tp_traverse */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002064 0, /* tp_clear */
2065 0, /* tp_richcompare */
2066 0, /* tp_weaklistoffset */
Raymond Hettinger1da1dbf2003-03-17 19:46:11 +00002067 PyObject_SelfIter, /* tp_iter */
Raymond Hettinger60eca932003-02-09 06:40:58 +00002068 (iternextfunc)repeat_next, /* tp_iternext */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002069 0, /* tp_methods */
2070 0, /* tp_members */
2071 0, /* tp_getset */
2072 0, /* tp_base */
2073 0, /* tp_dict */
2074 0, /* tp_descr_get */
2075 0, /* tp_descr_set */
2076 0, /* tp_dictoffset */
2077 0, /* tp_init */
Raymond Hettingerbfef18c2003-05-23 03:55:42 +00002078 0, /* tp_alloc */
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002079 repeat_new, /* tp_new */
2080 PyObject_GC_Del, /* tp_free */
2081};
2082
2083
2084/* module level code ********************************************************/
2085
2086PyDoc_STRVAR(module_doc,
2087"Functional tools for creating and using iterators.\n\
2088\n\
2089Infinite iterators:\n\
2090count([n]) --> n, n+1, n+2, ...\n\
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00002091cycle(p) --> p0, p1, ... plast, p0, p1, ...\n\
Andrew M. Kuchlingdff694b2003-04-14 15:31:27 +00002092repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002093\n\
2094Iterators terminating on the shortest input sequence:\n\
2095izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\
Raymond Hettinger60eca932003-02-09 06:40:58 +00002096ifilter(pred, seq) --> elements of seq where pred(elem) is True\n\
2097ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002098islice(seq, [start,] stop [, step]) --> elements from\n\
2099 seq[start:stop:step]\n\
2100imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n\
2101starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n\
Raymond Hettingerad983e72003-11-12 14:32:26 +00002102tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n\
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00002103chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... \n\
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002104takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\
2105dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\
2106");
2107
2108
Raymond Hettingerad983e72003-11-12 14:32:26 +00002109static PyMethodDef module_methods[] = {
2110 {"tee", (PyCFunction)tee, METH_VARARGS, tee_doc},
2111 {NULL, NULL} /* sentinel */
2112};
2113
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002114PyMODINIT_FUNC
2115inititertools(void)
2116{
Raymond Hettinger60eca932003-02-09 06:40:58 +00002117 int i;
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002118 PyObject *m;
Raymond Hettinger60eca932003-02-09 06:40:58 +00002119 char *name;
2120 PyTypeObject *typelist[] = {
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00002121 &cycle_type,
Raymond Hettinger60eca932003-02-09 06:40:58 +00002122 &dropwhile_type,
2123 &takewhile_type,
2124 &islice_type,
2125 &starmap_type,
2126 &imap_type,
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00002127 &chain_type,
Raymond Hettinger60eca932003-02-09 06:40:58 +00002128 &ifilter_type,
2129 &ifilterfalse_type,
2130 &count_type,
2131 &izip_type,
2132 &repeat_type,
2133 NULL
2134 };
2135
Raymond Hettingerad983e72003-11-12 14:32:26 +00002136 m = Py_InitModule3("itertools", module_methods, module_doc);
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002137
Raymond Hettinger60eca932003-02-09 06:40:58 +00002138 for (i=0 ; typelist[i] != NULL ; i++) {
2139 if (PyType_Ready(typelist[i]) < 0)
2140 return;
Raymond Hettingerd449eab2003-05-22 16:32:58 +00002141 name = strchr(typelist[i]->tp_name, '.');
Raymond Hettinger61fe64d2003-02-23 04:40:07 +00002142 assert (name != NULL);
Raymond Hettinger60eca932003-02-09 06:40:58 +00002143 Py_INCREF(typelist[i]);
Raymond Hettingerd449eab2003-05-22 16:32:58 +00002144 PyModule_AddObject(m, name+1, (PyObject *)typelist[i]);
Raymond Hettinger60eca932003-02-09 06:40:58 +00002145 }
Raymond Hettingerad983e72003-11-12 14:32:26 +00002146
2147 if (PyType_Ready(&teedataobject_type) < 0)
2148 return;
2149 if (PyType_Ready(&tee_type) < 0)
2150 return;
2151
Raymond Hettinger96ef8112003-02-01 00:10:11 +00002152}