_PyObject_New / PyObject_Init / PyInstance_New / etc?

Gre7g Luterman hafeliel at yahoo.com
Sat May 19 09:54:32 EDT 2007


(My apologies if this appears twice. It did not post the first time.)

I'm so confuzzled! How do I instantiate my new C Python object from C?

After flailing helplessly with my own code, and searching tirelessly with
Google, I stepped back to the classic noddy2.c example in the Python help
files and tried to modify it to not just define a Noddy object, but to
instantiate one as well. I'm not having any luck.

In noddy2.c, I added some printf statements just after the beginning of the
Noddy_dealloc, Noddy_new, and Noddy_init. I compiled noddy2.c and when
called from Python, it does exactly what I would expect:

>>> import noddy2
>>> n=noddy2.Noddy()
Noddy_new
Noddy_init
>>> ^Z
Noddy_dealloc

Perfect!  Now I wanted to create a Noddy() object from C. The simplest way
to do this was to stick it in the Noddy_name function, since that was easily
called. I tried inserting some code with _PyObject_New and PyObject_Init:

static PyObject *
Noddy_name(Noddy* self)
{
    static PyObject *format = NULL;
    PyObject *args, *result;
printf("Noddy_name\n");
args=_PyObject_New(&NoddyType);
printf("%p\n", args);
PyObject_Init(args, &NoddyType);
printf("init done\n");
Py_DECREF(args);
printf("dec done\n");
... (I left all the original Noddy_name code here) ...

Then I compiled, went into the Python interpreter and tried it.  I would
have expected Noddy_name to create and destroy a Noddy object just like
noddy2.Noddy() does from the interpreter, but it doesn't:

>>> import noddy2
>>> n=noddy2.Noddy()
Noddy_new
Noddy_init
>>> n.name()
Noddy_name
00B1A1B8
init done
Noddy_dealloc

As you can see, calling the name function did my printf of Noddy_name, and
then _PyObject_New returned a pointer to a Python object, but I don't think
it really is a Noddy object (not entirely at least).  After all, Noddy_new
and Noddy_init are never called! The funny thing is that the Py_DECREF
destroys a Noddy object (you can see that Noddy_dealloc got called), but now
something is out of sync. since the construction didn't happen as expected
and Python crashes hard.

I've tried this as above, and with PyInstance_New, with PyObject_New (no
underscore), and PyObject_Call, but none of them work as I would expect. So
what is the *CORRECT* way to do this?  Obviously I'm neglecting something
important.

My modified noddy2.c in case anyone wants to try it: 
http://pastie.textmate.org/62901

Many thanks to anyone who can point me in the correct direction!

Gre7g 





More information about the Python-list mailing list