cinap_lenrekadd hg and python4bb9e2215 years agoHistory
2550 lines · 57.3 KB · C
RawDownload
/*	imap() is an iterator version of __builtins__.map() except that it doesnot have the None fill-in feature.  That was intentionally left out forthe following reasons:   1) Itertools are designed to be easily combined and chained together.     Having all tools stop with the shortest input is a unifying principle     that makes it easier to combine finite iterators (supplying data) with     infinite iterators like count() and repeat() (for supplying sequential     or constant arguments to a function).   2) In typical use cases for combining itertools, having one finite data      supplier run out before another is likely to be an error condition which     should not pass silently by automatically supplying None.   3) The use cases for automatic None fill-in are rare -- not many functions     do something useful when a parameter suddenly switches type and becomes     None.     4) If a need does arise, it can be met by __builtins__.map() or by      writing:  chain(iterable, repeat(None)).   5) Similar toolsets in Haskell and SML do not have automatic None fill-in.*/ static PyObject *imap_next(imapobject *lz){	PyObject *val;	PyObject *argtuple;	PyObject *result;	Py_ssize_t numargs, i; 	numargs = PyTuple_Size(lz->iters);	argtuple = PyTuple_New(numargs);	if (argtuple == NULL)		return NULL; 	for (i=0 ; i<numargs ; i++) {		val = PyIter_Next(PyTuple_GET_ITEM(lz->iters, i));		if (val == NULL) {			Py_DECREF(argtuple);			return NULL;		}		PyTuple_SET_ITEM(argtuple, i, val);	}	if (lz->func == Py_None) 		return argtuple;	result = PyObject_Call(lz->func, argtuple, NULL);	Py_DECREF(argtuple);	return result;} PyDoc_STRVAR(imap_doc,"imap(func, *iterables) --> imap object\n\\n\Make an iterator that computes the function using arguments from\n\each of the iterables.	Like map() except that it returns\n\an iterator instead of a list and that it stops when the shortest\n\iterable is exhausted instead of filling in None for shorter\n\iterables."); static PyTypeObject imap_type = {	PyObject_HEAD_INIT(NULL)	0,				/* ob_size */	"itertools.imap",		/* tp_name */	sizeof(imapobject),		/* tp_basicsize */	0,				/* tp_itemsize */	/* methods */	(destructor)imap_dealloc,	/* tp_dealloc */	0,				/* tp_print */	0,				/* tp_getattr */	0,				/* tp_setattr */	0,				/* tp_compare */	0,				/* tp_repr */	0,				/* tp_as_number */	0,				/* tp_as_sequence */	0,				/* tp_as_mapping */	0,				/* tp_hash */	0,				/* tp_call */	0,				/* tp_str */	PyObject_GenericGetAttr,	/* tp_getattro */	0,				/* tp_setattro */	0,				/* tp_as_buffer */	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |		Py_TPFLAGS_BASETYPE,	/* tp_flags */	imap_doc,			/* tp_doc */	(traverseproc)imap_traverse,	/* tp_traverse */	0,				/* tp_clear */	0,				/* tp_richcompare */	0,				/* tp_weaklistoffset */	PyObject_SelfIter,		/* tp_iter */	(iternextfunc)imap_next,	/* tp_iternext */	0,				/* tp_methods */	0,				/* tp_members */	0,				/* tp_getset */	0,				/* tp_base */	0,				/* tp_dict */	0,				/* tp_descr_get */	0,				/* tp_descr_set */	0,				/* tp_dictoffset */	0,				/* tp_init */	0,				/* tp_alloc */	imap_new,			/* tp_new */	PyObject_GC_Del,		/* tp_free */};  /* chain object ************************************************************/ typedef struct {	PyObject_HEAD	Py_ssize_t tuplesize;	Py_ssize_t iternum;		/* which iterator is active */	PyObject *ittuple;		/* tuple of iterators */} chainobject; static PyTypeObject chain_type; static PyObject *chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds){	chainobject *lz;	Py_ssize_t tuplesize = PySequence_Length(args);	Py_ssize_t i;	PyObject *ittuple; 	if (type == &chain_type && !_PyArg_NoKeywords("chain()", kwds))		return NULL; 	/* obtain iterators */	assert(PyTuple_Check(args));	ittuple = PyTuple_New(tuplesize);	if (ittuple == NULL)		return NULL;	for (i=0; i < tuplesize; ++i) {		PyObject *item = PyTuple_GET_ITEM(args, i);		PyObject *it = PyObject_GetIter(item);		if (it == NULL) {			if (PyErr_ExceptionMatches(PyExc_TypeError))				PyErr_Format(PyExc_TypeError,				    "chain argument #%zd must support iteration",				    i+1);			Py_DECREF(ittuple);			return NULL;		}		PyTuple_SET_ITEM(ittuple, i, it);	} 	/* create chainobject structure */	lz = (chainobject *)type->tp_alloc(type, 0);	if (lz == NULL) {		Py_DECREF(ittuple);		return NULL;	} 	lz->ittuple = ittuple;	lz->iternum = 0;	lz->tuplesize = tuplesize; 	return (PyObject *)lz;} static voidchain_dealloc(chainobject *lz){	PyObject_GC_UnTrack(lz);	Py_XDECREF(lz->ittuple);	lz->ob_type->tp_free(lz);} static intchain_traverse(chainobject *lz, visitproc visit, void *arg){	Py_VISIT(lz->ittuple);	return 0;} static PyObject *chain_next(chainobject *lz){	PyObject *it;	PyObject *item; 	while (lz->iternum < lz->tuplesize) {		it = PyTuple_GET_ITEM(lz->ittuple, lz->iternum);		item = PyIter_Next(it);		if (item != NULL)			return item;		if (PyErr_Occurred()) {			if (PyErr_ExceptionMatches(PyExc_StopIteration))				PyErr_Clear();			else				return NULL;		}		lz->iternum++;	}	return NULL;} PyDoc_STRVAR(chain_doc,"chain(*iterables) --> chain object\n\\n\Return a chain object whose .next() method returns elements from the\n\first iterable until it is exhausted, then elements from the next\n\iterable, until all of the iterables are exhausted."); static PyTypeObject chain_type = {	PyObject_HEAD_INIT(NULL)	0,				/* ob_size */	"itertools.chain",		/* tp_name */	sizeof(chainobject),		/* tp_basicsize */	0,				/* tp_itemsize */	/* methods */	(destructor)chain_dealloc,	/* tp_dealloc */	0,				/* tp_print */	0,				/* tp_getattr */	0,				/* tp_setattr */	0,				/* tp_compare */	0,				/* tp_repr */	0,				/* tp_as_number */	0,				/* tp_as_sequence */	0,				/* tp_as_mapping */	0,				/* tp_hash */	0,				/* tp_call */	0,				/* tp_str */	PyObject_GenericGetAttr,	/* tp_getattro */	0,				/* tp_setattro */	0,				/* tp_as_buffer */	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |		Py_TPFLAGS_BASETYPE,	/* tp_flags */	chain_doc,			/* tp_doc */	(traverseproc)chain_traverse,	/* tp_traverse */	0,				/* tp_clear */	0,				/* tp_richcompare */	0,				/* tp_weaklistoffset */	PyObject_SelfIter,		/* tp_iter */	(iternextfunc)chain_next,	/* tp_iternext */	0,				/* tp_methods */	0,				/* tp_members */	0,				/* tp_getset */	0,				/* tp_base */	0,				/* tp_dict */	0,				/* tp_descr_get */	0,				/* tp_descr_set */	0,				/* tp_dictoffset */	0,				/* tp_init */	0,				/* tp_alloc */	chain_new,			/* tp_new */	PyObject_GC_Del,		/* tp_free */};  /* ifilter object ************************************************************/ typedef struct {	PyObject_HEAD	PyObject *func;	PyObject *it;} ifilterobject; static PyTypeObject ifilter_type; static PyObject *ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds){	PyObject *func, *seq;	PyObject *it;	ifilterobject *lz; 	if (type == &ifilter_type && !_PyArg_NoKeywords("ifilter()", kwds))		return NULL; 	if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq))		return NULL; 	/* Get iterator. */	it = PyObject_GetIter(seq);	if (it == NULL)		return NULL; 	/* create ifilterobject structure */	lz = (ifilterobject *)type->tp_alloc(type, 0);	if (lz == NULL) {		Py_DECREF(it);		return NULL;	}	Py_INCREF(func);	lz->func = func;	lz->it = it; 	return (PyObject *)lz;} static voidifilter_dealloc(ifilterobject *lz){	PyObject_GC_UnTrack(lz);	Py_XDECREF(lz->func);	Py_XDECREF(lz->it);	lz->ob_type->tp_free(lz);} static intifilter_traverse(ifilterobject *lz, visitproc visit, void *arg){	Py_VISIT(lz->it);	Py_VISIT(lz->func);	return 0;} static PyObject *ifilter_next(ifilterobject *lz){	PyObject *item;	PyObject *it = lz->it;	long ok;	PyObject *(*iternext)(PyObject *); 	assert(PyIter_Check(it));	iternext = *it->ob_type->tp_iternext;	for (;;) {		item = iternext(it);		if (item == NULL)			return NULL; 		if (lz->func == Py_None) {			ok = PyObject_IsTrue(item);		} else {			PyObject *good;			good = PyObject_CallFunctionObjArgs(lz->func,							    item, NULL);			if (good == NULL) {				Py_DECREF(item);				return NULL;			}			ok = PyObject_IsTrue(good);			Py_DECREF(good);		}		if (ok)			return item;		Py_DECREF(item);	}} PyDoc_STRVAR(ifilter_doc,"ifilter(function or None, sequence) --> ifilter object\n\\n\Return those items of sequence for which function(item) is true.\n\If function is None, return the items that are true."); static PyTypeObject ifilter_type = {	PyObject_HEAD_INIT(NULL)	0,				/* ob_size */	"itertools.ifilter",		/* tp_name */	sizeof(ifilterobject),		/* tp_basicsize */	0,				/* tp_itemsize */	/* methods */	(destructor)ifilter_dealloc,	/* tp_dealloc */	0,				/* tp_print */	0,				/* tp_getattr */	0,				/* tp_setattr */	0,				/* tp_compare */	0,				/* tp_repr */	0,				/* tp_as_number */	0,				/* tp_as_sequence */	0,				/* tp_as_mapping */	0,				/* tp_hash */	0,				/* tp_call */	0,				/* tp_str */	PyObject_GenericGetAttr,	/* tp_getattro */	0,				/* tp_setattro */	0,				/* tp_as_buffer */	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |		Py_TPFLAGS_BASETYPE,	/* tp_flags */	ifilter_doc,			/* tp_doc */	(traverseproc)ifilter_traverse,	/* tp_traverse */	0,				/* tp_clear */	0,				/* tp_richcompare */	0,				/* tp_weaklistoffset */	PyObject_SelfIter,		/* tp_iter */	(iternextfunc)ifilter_next,	/* tp_iternext */	0,				/* tp_methods */	0,				/* tp_members */	0,				/* tp_getset */	0,				/* tp_base */	0,				/* tp_dict */	0,				/* tp_descr_get */	0,				/* tp_descr_set */	0,				/* tp_dictoffset */	0,				/* tp_init */	0,				/* tp_alloc */	ifilter_new,			/* tp_new */	PyObject_GC_Del,		/* tp_free */};  /* ifilterfalse object ************************************************************/ typedef struct {	PyObject_HEAD	PyObject *func;	PyObject *it;} ifilterfalseobject; static PyTypeObject ifilterfalse_type; static PyObject *ifilterfalse_new(PyTypeObject *type, PyObject *args, PyObject *kwds){	PyObject *func, *seq;	PyObject *it;	ifilterfalseobject *lz; 	if (type == &ifilterfalse_type &&	    !_PyArg_NoKeywords("ifilterfalse()", kwds))		return NULL; 	if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq))		return NULL; 	/* Get iterator. */	it = PyObject_GetIter(seq);	if (it == NULL)		return NULL; 	/* create ifilterfalseobject structure */	lz = (ifilterfalseobject *)type->tp_alloc(type, 0);	if (lz == NULL) {		Py_DECREF(it);		return NULL;	}	Py_INCREF(func);	lz->func = func;	lz->it = it; 	return (PyObject *)lz;} static voidifilterfalse_dealloc(ifilterfalseobject *lz){	PyObject_GC_UnTrack(lz);	Py_XDECREF(lz->func);	Py_XDECREF(lz->it);	lz->ob_type->tp_free(lz);} static intifilterfalse_traverse(ifilterfalseobject *lz, visitproc visit, void *arg){	Py_VISIT(lz->it);	Py_VISIT(lz->func);	return 0;} static PyObject *ifilterfalse_next(ifilterfalseobject *lz){	PyObject *item;	PyObject *it = lz->it;	long ok;	PyObject *(*iternext)(PyObject *); 	assert(PyIter_Check(it));	iternext = *it->ob_type->tp_iternext;	for (;;) {		item = iternext(it);		if (item == NULL)			return NULL; 		if (lz->func == Py_None) {			ok = PyObject_IsTrue(item);		} else {			PyObject *good;			good = PyObject_CallFunctionObjArgs(lz->func,							    item, NULL);			if (good == NULL) {				Py_DECREF(item);				return NULL;			}			ok = PyObject_IsTrue(good);			Py_DECREF(good);		}		if (!ok)			return item;		Py_DECREF(item);	}} PyDoc_STRVAR(ifilterfalse_doc,"ifilterfalse(function or None, sequence) --> ifilterfalse object\n\\n\Return those items of sequence for which function(item) is false.\n\If function is None, return the items that are false."); static PyTypeObject ifilterfalse_type = {	PyObject_HEAD_INIT(NULL)	0,				/* ob_size */	"itertools.ifilterfalse",	/* tp_name */

Lines 1501–2000 of 2550. Previous lines