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

_PyObject_New / PyObject_Init / PyInstance_New / etc?

P: n/a
(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
May 19 '07 #1
Share this Question
Share on Google+
2 Replies


P: n/a
En Sat, 19 May 2007 10:54:32 -0300, Gre7g Luterman <ha******@yahoo.com>
escribió:
I'm so confuzzled! How do I instantiate my new C Python object from C?
I tried inserting some code with _PyObject_New and PyObject_Init:

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:
From Python, you create a Noddy object by *calling* its type. Do the same
in C:

return PyObject_CallObject((PyObject *) &NoddyType, NULL);

Or any other suitable variant of PyObject_CallXXX. (I've answered this
same question yesterday, when I was not sure about this; then I've tried
it and it appears to be working. But I've not read any docs telling this
is *the* right way to create an object).
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.
PyInstance_New is for old style classes. PyObject_New only initializes the
object structure, and this is enough for most builtin types that usually
don't define __init__ (or tp_init). You were right with PyObject_Call, but
maybe you didn't invoke it correctly.

--
Gabriel Genellina

May 19 '07 #2

P: n/a
From Python, you create a Noddy object by *calling* its type. Do the same
in C:

return PyObject_CallObject((PyObject *) &NoddyType, NULL);

Or any other suitable variant of PyObject_CallXXX. (I've answered this
same question yesterday, when I was not sure about this; then I've tried
it and it appears to be working. But I've not read any docs telling this
is *the* right way to create an object).
Many thanks. That seems to work now.

It turns out that my previous problems stemmed from defining my type as a
static, so I was ending up with multiple copies of it and of course only one
type was getting fully initialized when the module was launched!
May 20 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.