[Python-Dev] a bit confused about the new type/class stuff

Guido van Rossum guido@python.org
Wed, 03 Oct 2001 21:28:19 -0400


> I have a class hierarchy I'm trying to migrate to 2.2 using the latest stuff
> from CVS on both the Gtk and Python sides of the fence.  Conceptually its
> skeleton looks like
> 
>     class Object:
>         ...
> 
>     class Widget(Object):
>         ...
> 
>     class Button(Widget):
>         ...
> 
> (It's a bunch of wrappers around Gtk widgets.  The wrappers happen to use
> delegation instead of instantiation, so my Button class is not subclassed
> from gtk.Button.  In particular, it's *not* one of the new subclassable
> types.)
> 
> At one point in my code I test to see if one of my Button instances is in a
> list of Widget instances and I get a TypeError:
> 
>     TypeError: Button.__cmp__(x,y) requires y to be a 'Button', not a 'instance'

This error comes from wrap_cmpfunc() in typeobject.c.  It should only
happen when you are somehow comparing new-style objects.

> If I test for b's inclusion in l, even if I draw b from l:
> 
>     >>> l
>     [<Button object (GtkButton) at 0x8293134>, <Button object (GtkButton) at 0x8296ac4>, <Button object (GtkButton) at 0x8397fb4>]
>     >>> b = l[0]
>     >>> b in l
>     Traceback (most recent call last):
>       File "<stdin>", line 1, in ?
>     TypeError: Button.__cmp__(x,y) requires y to be a 'Button', not a 'instance'
> 
> I get an error.

What do you get when you ask for (b == l)?

> I don't define a __cmp__ method for the Button class or any of its
> ancestors, but if I print b.__cmp__ something is definitely there:
> 
>     >>> b.__cmp__
>     <method-wrapper object at 0x83aae78>

That's truly bizarre.  A <method-wrapper object> is an *unbound*
__cmp__ method that wraps the tp_compare slot of a built-in type.  I
have no explanation for how it would show up in your instance.

Can you check whether b.__cmp__ is the same as b.__dict__['__cmp__']
or whether it is the same as b.__class__.__cmp__?  It should be either
one of those.  Then, if it's in b.__class__, try to find out in which
class's __dict__ it lives.

> This was all working using Python 2.1.  I haven't changed anything so far in
> my code other than to adapt to the new PyGtk naming scheme (e.g., gtk.Button
> vs. gtk.GtkButton) and recompile/install Gtk, PyGtk, Python and friends.  In
> particular, I believe I have a hierarchy of so-called "classic" classes.
> 
> I'm going to toddle off an reread the various PEPs, but would appreciate an
> insight or two on where this error is coming from.

I have zero experience with Gtk, but I heard somewhere that it uses
the Don Beaudry hook.  This is enabled in recent 2.2, but it might act
slightly different than expected.  This is the first thing I'd
investigate.

Good luck!  (If you can mail me step-by-step instructions for
reproducing your situation on Linux, including URLs of specific Gtk
source tarballs etc., I might play with this a bit...)

--Guido van Rossum (home page: http://www.python.org/~guido/)