Extension Question

GuySmiley kermit at thefrog.org
Wed Apr 10 15:59:01 EDT 2002


Hi John,

Thanks for the hierarchy explanation. That's the bit I was missing. After
reading the example module and the example type, I had the impression a
central method dictionary was necessary for all types. DOH!

Thanks again,
sbp

"John Machin" <sjmachin at lexicon.net> wrote in message
news:c76ff6fc.0204100629.55b2b2 at posting.google.com...
> 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