By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,586 Members | 1,719 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,586 IT Pros & Developers. It's quick & easy.

PyObject_New not running tp_new for iterators?

P: n/a
I'm trying to extend Python with an iterator class that should be
returned from a factory function.

For some reason the iterator object is not being properly initialised if
the iterator is created in a C function. It works just fine if the
object is created using the class contructor

Trying to minimise the cut-n-paste, but:
typedef struct {
PyObject_HEAD

int i;

} MyIter;
static PyObject *
MyIter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
MyIter *self;

self = (MyIter *)type->tp_alloc(type, 0);
if (self) {
self->i = 0;
}

return (PyObject *)self;
}

static PyObject *
MyIter_Iter(PyObject *self)
{
Py_INCREF(self);
return self;
}

static PyObject *
MyIter_Next(PyObject *self)
{
MyIter *ep = (MyIter *) self;
return Py_BuildValue("i", ep->i++);
}

plus the usual type stucture. This simple iterator returns the integers
from 0 to (programmer's) infinity.

This works fine if I create the object directly:
Python 2.3.1 (#3, Oct 1 2003, 16:18:11)
[GCC 3.3] on sunos5
Type "help", "copyright", "credits" or "license" for more information.
import myiter
e = myiter.MyIter()
str(e) '<myiter.MyIter object at 0x184050>' e.next() 0 e.next() 1 e.next() 2 e.next() 3
However, if I create the MyIter object from a C factory function:
static PyObject *
FromFile(PyObject *self, PyObject *args)
{
MyIter *ro;

if (!PyArg_ParseTuple(args, ""))
return NULL;

if (!(ro = PyObject_New(MyIter, &MyIterType)))
return NULL;

return (PyObject *)ro;
}

static PyMethodDef My_methods[] = {
{"FromFile", FromFile, METH_VARARGS,
"Return an iterator."},
{NULL} /* Sentinel */
};


then the MyIter object is not properly initialised!
f = myiter.FromFile()
f <myiter.MyIter object at 0x184070> f.next() -2080374694 f.next() -2080374693 f.next() -2080374692


I tried a similar problem with a plane-old-object using tp_members
(rather than an iterator object) and that worked fine, even from a
factory function.

I've looked long and hard at the API doc, but I'm stumped..... I've
checked a couple of examples and they just do what I'm doing!

What am I missing?
Jul 19 '05 #1
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.