Extension Question

John Machin sjmachin at lexicon.net
Wed Apr 10 10:29:31 EDT 2002


ics1010 at yahoo.com (sbp) wrote in message news:<cab7ec6a.0204100140.6b141d16 at posting.google.com>...
> In an extension I'm writing, I have a main import module which works
> fine. I'm a little confused about trying to include an object type in
> the same dll. From the import module's init I call an init function
> for the type which calls Py_InitModule with the name and method array
> for the type,

Whoops ... Py_InitModule should be called once, to initialise the
*module*, specifying the name and the table of module-level
functions/methods.
For old-style types, one or more of those functions will be
constructors for instances of the type(s) you have defined in your
module. For the moment, we'll draw a veil over the new-style types
introduced in version 2.2.

For the standard methods, you fill in functions in the slots of the
type's descriptor table. For the methods that you invent, you need a
tp_gettattr slot pointing to a function like the following, where spam
is your type.

static struct PyMethodDef spam_methods[] = {
   {"add_eggs", (PyCFunction)spam_add_eggs, METH_VARARGS,
    spam_add_eggs_doc},
   /* etc */
   {NULL, NULL}         /* sentinel */
};

static PyObject *
spam_getattr(self, name)
   spamobject *self;
   char *name;
{
   return Py_FindMethod(spam_methods, (PyObject *)self, name);
}
/* There are more modern ways of doing this but if you can find the
docs
   tell the world :-)
*/

So what happens when you do this:
 >>> import mymodule
 >>> spobj = mymodule.spam_factory(some_args) # your constructor
 >>> spobj.add_eggs(2)

is that Python finds the type of spobj, looks in the type's tp_getattr
slot, calls your spam_gettatr function looking for "add_eggs"; this
calls Py_FindMethod which rummages in the spam_methods table, finds
that "add_eggs" is implemented by the spam_add_aggs C function, does a
little more magic ("binding the method to the instance"), and then
calls spam_add_eggs ...

> but when I try to call a method from this array, I get
> an exception stating there is no attribute for the method name I'm
> calling. I have functions for the various type protocols (i.e.
> attributes) which work fine.

It is not apparent to me exactly what you mean by "functions for the
various type protocols (i.e. attributes)" nor how this could "work
fine" when you don't seem to be able to invoke a constructor to create
an object.

What source(s) of information have you been using to get so far??? I
don't have any book other than the venerable 1st edition (1996) of
"Programming Python" by Mark Lutz but this technique is in that book
(see example 14-2 stacktyp.c) and I can't see how/why it wouldn't be
in later books that have a serious chapter on extending.

I suggest that you find some practical working examples of extension
modules and follow their lead -- try (1) the Vaults of Parnassus (2)
files in the modules and objects directory of a pre-2.2 Python source
distribution e.g. listobject.c and arraymodule.c (3)
http://object-craft.com.au/projects/csv/ which is a well-written
not-too-large module.

HTH,
John



More information about the Python-list mailing list