13.4 Calling superclass methods, and why you have to

If your template or pure Python class overrides a standard method or attribute of Template or one of its base classes, you should call the superclass method in your method to prevent various things from breaking. The most common methods to override are .awake and .__init__. .awake is called automatically by Webware early during the web transaction, so it makes a convenient place to put Python initialization code your template needs. You'll definitely want to call the superclass .awake because it sets up many wonderful attributes and methods, such as those to access the CGI input fields.

There's nothing Cheetah-specific to calling superclass methods, but because it's vital, we'll recap the standard Python techniques here. We mention only the solution for old-style classes because Cheetah classes are old-style (in other Python documentation, you will find the technique for new-style classes, but they are not listed here because they cannot be used with Cheetah if you use dynamically-compiled templates).

from Cheetah.Template import Template
class MyClass(Template):
	def awake(self, trans):
		Template.awake(self, trans)
		... great and exciting features written by me ...

[ @@MO: Need to test this. .awake is in Servlet, which is a superclass of Template. Do we really need both imports? Can we call Template.awake? ]

To avoid hardcoding the superclass name, you can use this function callbase(), which emulates super() for older versions of Python. It also works even super() does exist, so you don't have to change your servlets immediately when upgrading. Note that the argument sequence is different than super uses.

===========================================================================
# Place this in a module SOMEWHERE.py .  Contributed by Edmund Lian.
class CallbaseError(AttributeError):
    pass

def callbase(obj, base, methodname='__init__', args=(), kw={},
    raiseIfMissing=None):
    try: method = getattr(base, methodname)
    except AttributeError:
        if raiseIfMissing:
            raise CallbaseError, methodname
        return None
    if args is None: args = ()
    return method(obj, *args, **kw)
===========================================================================
# Place this in your class that's overriding .awake (or any method).
from SOMEWHERE import callbase
class MyMixin:
        def awake(self, trans):
                args = (trans,)
                callbase(self, MyMixin, 'awake', args)
                ... everything else you want to do ...
===========================================================================