The Don Beaudry/Jim Fulton hack

Dave Abrahams abrahams at mediaone.net
Thu Dec 30 06:50:29 EST 1999


Hi,

I've recently been crawling through the source code (trying to understand
what all those fields in PyTypeObject really do), and stumbled across an
explanation for what I had read about being able to subclass a type
extension in Python: there's special code to make this possible!

Looking at the comment and code which follows...

   /* Call the base's *type*, if it is callable.
      This code is a hook for Donald Beaudry's
      and Jim Fulton's type extensions.  In
      unexended Python it will never be triggered
      since its types are not callable.
      Ditto: call the bases's *class*, if it has
      one.  This makes the same thing possible
      without writing C code.  A true meta-object
      protocol! */
   PyObject *basetype = (PyObject *)base->ob_type;
   PyObject *callable = NULL;
   if (PyCallable_Check(basetype))
    callable = basetype;
   else
    callable = PyObject_GetAttrString(
     base, "__class__");
   if (callable) {
    PyObject *args;
    PyObject *newclass = NULL;
    args = Py_BuildValue(
     "(OOO)", name, bases, methods);
    if (args != NULL) {
     newclass = PyEval_CallObject(
      callable, args);

I think: it would be cool to experiment with this before writing any C code,
just to make sure I understand it. So I fire up Python. Since the special
code is never entered if the base is a real class (not shown), I figure it
has to be an instance: otherwise, how could it have an attribute called
"__class__"?

>>> class Empty: pass
...
>>> base = Empty()
>>> base.__class__ = stupid_class
Traceback (innermost last):
  File "<input>", line 1, in ?
TypeError: __class__ must be set to a class
>>>

But as you can see, you can't set the __class__ attribute of an instance to
anything other than a class. So what have I missed? How am I supposed to get
this to work "without writing C code"?

Finally, another point. It is now possible to make extension classes which
walk, talk, and smell just like built-in classes except for one important
detail: as far as I can tell, there's no way to make is_instance work so
that it returns TRUE for base classes. In other words, if I have an
extension type "A" which is a "subclass" of another extension type "B", and
an instance of "A", "a", is_instance(a, B) should be true. I don't think
ther's any way to do that without a change to the Python source.

-Dave



More information about the Python-list mailing list