C/API Clarification

Jeremy Moles jeremy at emperorlinux.com
Fri Oct 7 07:27:28 EDT 2005


First of all, let me say I really do appreciate--and frequently use--the
ample and easy to read Python documentation. However, there are a few
things I'm still unclear on, even after asking multiple questions here
on the list (thanks everyone!) and reading the "Extending" and
"Reference" docs from start to finish. I'm new to Python extension
writing--but I'm learning fast. Still, I have a few questions that would
make my weekend so much better if I had some guidance on them or,
better, examples of other people's working code. :) (Real code, not
over-simplified examples that don't ever make sense in the real
world) :) 

Most of my woes are the result of trying to wrap some highly dynamic C++
code. People, of course, are quick to say "use Boost"--which I'm sure is
great--but doesn't actually teach me anything about Python. :)

1. Nowhere in the docs was I able to see an example of a custom object
using anything but a METH_NOARGS method. This is pretty silly since I
would assume that most class methods take a few arguments. I'm using:

	PyObject* foo(cstruct* self, PyObject* args, PyObject* kargs)

...and it works, but I'm not even really sure if this is right or where
in the world I got the idea from! According to the docs, METH_VARARGS is
(PyObject*, PyObject*)? My prototype shouldn't even compile... but it
does, even at -Wall. This is an area I really feel like the docs should
elaborate on. All of the tp_* functions are infinitely easier to
implement as they have very specific purposes. However, very little
attention is given to just general type methods, though it could be just
me missing something. :)

2. No where in the docs does it show how to "correctly" create an
instance of your custom PyTypeObject in C (rather than in the
interpreter). I'm using:

	PyObject* newobject = _PyObject_New(&PyType_myType);
        PyObject* nulltuple = Py_BuildValue("()");
        myType_init((cstruct*)(newobject), nulltuple, NULL);

...and it works (or appears to so far), but I really doubt this is how
it's done. I'm guessing I'm not supposed to go anywhere near the
_PyObject_New function. :)

3. I'm not able to return the "self" argument (useful, for instance,
when you want to chain a group of method calls) without screwing things
up really, really bad. For example:

PyObject* somefunc(cstruct* self, PyObject* args, PyObject* kargs) {
	self->pointerToData->doSomeStuff();
	
	return (PyObject*)(self);
}

...returns "something"; it has the methods you would expect, but trying
to use the object when it gets back to the interpreter is pretty much
undefined behavior. :) It's seen as a "<refcnt...>" instance in the
interpreter, even though a dir() shows it still has the methods you
would expect.

I'm sorry if I come off as a newb or sound preachy--it certainly isn't
my intention. I love Python and will continue using it even if I never
quite grok it's C API. :)

Weeeeeeeeeee.




More information about the Python-list mailing list