"""This mixin supports autoloading of "friend" methods."""
__docformat__ = "restructuredtext"
# Created: Mon May 10 15:49:15 PDT 2004
# Author: Shannon -jj Behrens
# Email: jjinux@users.sourceforge.net
#
# Copyright (c) Shannon -jj Behrens. All rights reserved.
from Curry import Curry
class HasFriends:
"""This mixin supports autoloading of "friend" methods.
That means if you have a class like ``aquarium.widget.FormUtil``, and you
try to call a function ``fooBar`` on that class, ``FormUtil`` (assuming it
mixes in this class) will automatically import
``aquarium.widget.formutil.fooBar`` (notice that the ``FormUtil`` class is
automatically associated with the ``formutil`` package) and return the
``fooBar`` function. ``fooBar`` will behave as if it were actually a
method inside ``FormUtil``. ``fooBar`` should be implemented as a normal
method that just happens to receive a ``FormUtil`` instance named ``self``
as its first argument.
"""
def __getattr__(self, attr):
"""Return the desired friend method.
Note, these methods will be cached in ``self._friendCache``.
"""
if attr.startswith("_"):
raise AttributeError("'%s' object has no attribute '%s'" %
(self.__class__.__name__, attr))
if not self.__dict__.has_key("_friendCache"):
self._friendCache = {}
cache = self._friendCache
if not cache.has_key(attr):
pieces = self.__module__.split(".")
pieces[-1] = pieces[-1].lower()
pieces.append(attr)
moduleName = ".".join(pieces)
try:
module = __import__(moduleName, {}, {}, [attr])
except:
raise (AttributeError, """\
%s instance has no attribute '%s', and HasFriends failed too""" %
(self.__class__.__name__, attr))
f = getattr(module, attr)
curry = Curry(f, self)
cache[attr] = curry
return cache[attr]
|