problem in using metaclasses to inspect Python code

Greg Chapman glc at well.com
Thu Dec 12 10:16:20 EST 2002


On 11 Dec 2002 09:08:31 -0800, mis6 at pitt.edu (Michele Simionato) wrote:

>As you see, there is an error in retriving the source code for the static
>method, whereas the plain method works fine. Since the version without
>metaclasses works fine, the inconsistency seems to me more similar to
>a bug. What's the origin of this strange behavior ? Can it be fixed ?

Actually, the metaclass is something of a red herring here.  Using your original
definition of C (without the metaclass), if you do this:

print 'source of staticmeth:\n', getsource(C.__dict__['staticmeth'])

you will get the same error.

To model what a class does when it retrieves attributes from its dict, you have
to check to see if the attribute is a descriptor (if it has a __get__ method).
If so, then you should call the __get__ method, passing the instance of the
object (or None if accessing a class) plus a reference to the class. I.e.,
something like:

def getclassattrfromdict(cls, name, default=None):
    if not name in cls.__dict__:
        return default
    maybedescr = cls.__dict__[name]
    descrget = getattr(maybedescr, '__get__', None)
    if descrget:
        return descrget(None, cls)
    else:
        return maybedescr

Using the above to retrieve staticmeth will return a function object compatible
with inspect.getsource.

By the way, I probably should have suggested using something like the above in
my response in the "another question on metaclasses" thread.  If you use the
above function to retrieve "__init__" from a class's dict, you'll get back an
unbound method object which wraps the actual __init__ function.  The unbound
method object and the __init__ function both have the same call signature (they
both expect an instance of the the class as the first parameter), but the method
object will do a typecheck to make sure that the first parameter is correct
before dispatching the call to the function object.

---
Greg Chapman




More information about the Python-list mailing list