Using metaclasses to make super more beatiful

Michele Simionato mis6 at pitt.edu
Fri Jun 6 11:00:21 EDT 2003


Gerrit Holl <gerrit at nl.linux.org> wrote in message news:<mailman.1054831871.3625.python-list at python.org>...
<snip message on autosuper>

You may want to google for the thread "help on autosuper" date February 3, 
2003. At the time I found that the autosuper metaclass was conflicting
with pydoc:

# try this under Python 2.2

class autosuper(type): #Guido's metaclass
    def __init__(cls, name, bases, dic):
        super(autosuper, cls).__init__(name, bases, dic)
        setattr(cls,"_%s__super" % name, super(cls))

class C(object): #a simple class
    __metaclass__=autosuper
 
help(C) # error because super objects have not __name__

For this reason I abandoned the autosuper approach. However, I have 
checked today with Python 2.3 and now it works! The reason is that now 
private attributes are no more retrieved by pydoc, therefore the 
inconsistency is hidden under the hood. However, it is still there and
if you do

# try this under Python 2.2-2.3
class C(object): pass
C.sup=super(C)
help(C)

you will get

Traceback (most recent call last):
  File "pro.py", line 15, in ?
    help(C)
  File "/usr/local/lib/python2.3/site.py", line 293, in __call__
    return pydoc.help(*args, **kwds)
  File "/usr/local/lib/python2.3/pydoc.py", line 1539, in __call__
    self.help(request)
  File "/usr/local/lib/python2.3/pydoc.py", line 1575, in help
    else: doc(request, 'Help on %s:')
  File "/usr/local/lib/python2.3/pydoc.py", line 1368, in doc
    pager(title % desc + '\n\n' + text.document(object, name))
  File "/usr/local/lib/python2.3/pydoc.py", line 279, in document
    if inspect.isclass(object): return self.docclass(*args)
  File "/usr/local/lib/python2.3/pydoc.py", line 1122, in docclass
    lambda t: t[1] == 'method')
  File "/usr/local/lib/python2.3/pydoc.py", line 1057, in spill
    name, mod, object))
  File "/usr/local/lib/python2.3/pydoc.py", line 280, in document
    if inspect.isroutine(object): return self.docroutine(*args)
  File "/usr/local/lib/python2.3/pydoc.py", line 1145, in docroutine
    realname = object.__name__
AttributeError: 'super' object has no attribute '__name__'

Another reason to use private attributes ;) There is a simple fix, anyway:

class Super(super):
    def __init__(self,C,S=None):
        super(Super,self).__init__(C,S)
        self.__name__="Super(%s)" % C.__name__

To you and to other explorers of the wonders of super, I say "DON'T
USE 2.2!". There were many subtle bugs now mostly solved in 2.3 (except
the one with pydoc, AFAIK).

Cheers,

                            Michele




More information about the Python-list mailing list