Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > PyObject_New not running tp_new for iterators?

Reply
Thread Tools

PyObject_New not running tp_new for iterators?

 
 
Gregory Bond
Guest
Posts: n/a
 
      04-20-2005
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?
 
Reply With Quote
 
 
 
 
Gregory Bond
Guest
Posts: n/a
 
      04-21-2005
I wrote:

[snip]

> What am I missing?


The fundamental problem is that this:

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


is really only a malloc() - it doesn't call the tp_new function at all.
This is not really clear in the 2.3 version of the C API document that
I was consulting - the 2.4 version is much clearer.

I have no idea how to do in C all the things that calling a class
constructor in Python does. Am I supposed to be calling tp_new &
tp_init directly?

In the end, this particular class really only needs to be created from a
factory function, so I removed the tp_new member altogether and just
wrote a C function to initialise the object, and called that from the C
factory function.

[The above is not particular to the fact that my class is an iterator -
all C classes have the same behaviour. My test of a plain-old class
probably looked like it worked due to lucky memory patterns.]


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
tp_new, tp_alloc, tp_init Michael Hennebry Python 1 12-08-2011 09:33 PM
Creating a Python Type in C - tp_init and tp_new ajayre@gmail.com Python 1 05-18-2007 01:16 AM
PyObject_New Jeremy Moles Python 2 10-07-2005 11:30 AM
Re: PyObject_New =?ISO-8859-1?Q?Gerhard_H=E4ring?= Python 0 10-07-2005 06:28 AM
I'm trying to network a deasktop running 98SE and a laptop running XP. Marc Computer Support 8 11-19-2003 03:01 AM



Advertisments