Determining what superclass supplies a method in Python

May 17, 2007

It turns out that there are some situations in Python where it is useful to know what your superclass is. In particular, it would be nice for mixin classes to be able to know when they are about to call methods on object() instead of on some actual user class.

It would be nice if the objects returned by super() directly exposed a way of determining this. Unfortunately they do not, and they don't even directly expose what the next superclass is, although given a super object you can recover the information. The code to do it is even reasonably short:

def getsuper(kls, rkls):
    mro = rkls.__mro__
    i = list(mro).index(kls)
    return mro[i+1]

def getprovider(so, meth):
    s = getsuper(so.__thisclass__,
                 so.__self_class__)
    r = getattr(s, meth)
    if hasattr(r, "im_class"):
        return r.im_class
    elif hasattr(r, "__objclass__"):
        return r.__objclass__
    else:
        return None

The getprovider function is called with the object you get from super() and the name of the method you want to look up (the method is assumed to exist somewhere). You get back the class that provides it, provided that I've found all of the little twisty special cases, and provided that we can actually tell. Fortunately we can tell for __init__, although we cannot always tell for other methods.

(Python is sometimes irritatingly inconsistent about this sort of introspection, so I am probably still missing some special cases. I believe that any return of None means you are dealing with a built-in class or method.)

Written on 17 May 2007.
« My rules of thumb for picking conference talks
The difficulty of throwing things away »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Thu May 17 23:02:00 2007
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.