constructor of subclass and base's tp_new() (was: subclassing a new-style (C) extension type: help!)

Maciej Kalisiak mac at die.spammer.die.dgp.toronto.edu
Wed Mar 26 16:30:12 EST 2003


* Carl Banks <imbosol-1048700608 at aerojockey.com>:
>  This function accepts a self argument, which was the newly created
>  object.  However, it doesn't use that argument at all.  Instead, it
>  creates it's own object, by calling PyObject_New, which does not
>  create an instance of the right subclass.  This is what 
>

Oops, something got chopped?

You touch on something that's been bothering me for some time...
In the "noddy" example in the Python docs on adding extension types ("The
Basics") we see this:

     static PyObject*
     noddy_new_noddy(PyObject* self, PyObject* args)
     {
         noddy_NoddyObject* noddy;
     
         if (!PyArg_ParseTuple(args,":new_noddy"))
             return NULL;
     
         noddy = PyObject_New(noddy_NoddyObject, &noddy_NoddyType);
     
         return (PyObject*)noddy;
     }

What is the role of `self' in *this* factory function??  I just copied it
blindly when I wrote the code initially.  From what you say I gather this
example is not very clean either.

>  The immediate solution is to replace the line "st = PyObject_New(...)"
>  with "st = tp->alloc(type,0)".  You'll have to change state_onew to
>  use type instead of self as its first parameter.  Then, delete the
>  line "self = tp->alloc(type,0)" from state_new.

Ah, great, I've fixed everything up along your suggested lines.

Now this brings up a second related question/problem:

,----
| from State import State
| class StateOfSize5(State):
|     def __init__(self):
|         State.__init__(self, 5)
|     
| s = State(5)		# this runs OK
| s = StateOfSize5()	# ERROR
| s = StateOfSize5(5)   # a workaround, but undermines the purpose of subclass
`----

The error I get is:
  TypeError: state_new() takes exactly 1 argument (0 given)

Now, this makes sense, since before StateOfSize5.__init__() can be called,
`self' must be already instantiated... but then, how do I go about achieving
what I want? (i.e., to encapsulate the State initialization arg in the
subclass)

I seem to recall that tp_init() corresponds to FooClass.__init__(), so it's as
if I'm trying to directly frob tp_new() in the subclass...




More information about the Python-list mailing list