"""Bastionification utility.

A bastion (for another object -- the 'original') is an object that has
the same methods as the original but does not give access to its
instance variables.  Bastions have a number of uses, but the most
obvious one is to provide code executing in restricted mode with a
safe interface to an object implemented in unrestricted mode.

The bastionification routine has an optional second argument which is
a filter function.  Only those methods for which the filter method
(called with the method name as argument) returns true are accessible.
The default filter method returns true unless the method name begins
with an underscore.

There are a number of possible implementations of bastions.  We use a
'lazy' approach where the bastion's __getattr__() discipline does all
the work for a particular method the first time it is used.  This is
usually fastest, especially if the user doesn't call all available
methods.  The retrieved methods are stored as instance variables of
the bastion, so the overhead is only occurred on the first use of each
method.

Detail: the bastion class has a __repr__() discipline which includes
the repr() of the original object.  This is precomputed when the
bastion is created.

"""

__version__ = '$Revision$'
# $Source$


from types import MethodType


class BastionClass:

    """Helper class used by the Bastion() function.

    You could subclass this and pass the subclass as the bastionclass
    argument to the Bastion() function, as long as the constructor has
    the same signature (a get() function and a name for the object).

    """

    def __init__(self, get, name):
	"""Constructor.

	Arguments:

	get - a function that gets the attribute value (by name)
	name - a human-readable name for the original object
	       (suggestion: use repr(object))

	"""
	self._get_ = get
	self._name_ = name

    def __repr__(self):
	"""Return a representation string.

	This includes the name passed in to the constructor, so that
	if you print the bastion during debugging, at least you have
	some idea of what it is.

	"""
	return "<Bastion for %s>" % self._name_

    def __getattr__(self, name):
	"""Get an as-yet undefined attribute value.

	This calls the get() function that was passed to the
	constructor.  The result is stored as an instance variable so
	that the next time the same attribute is requested,
	__getattr__() won't be invoked.

	If the get() function raises an exception, this is simply
	passed on -- exceptions are not cached.

	"""
	attribute = self._get_(name)
	self.__dict__[name] = attribute
	return attribute


def Bastion(object, filter = lambda name: name[:1] != '_',
	    name=None, bastionclass=BastionClass):
    """Create a bastion for an object, using an optional filter.

    See the Bastion module's documentation for background.

    Arguments:

    object - the original object
    filter - a predicate that decides whether a function name is OK;
             by default all names are OK that don't start with '_'
    name - the name of the object; default repr(object)
    bastionclass - class used to create the bastion; default BastionClass

    """

    # Note: we define *two* ad-hoc functions here, get1 and get2.
    # Both are intended to be called in the same way: get(name).
    # It is clear that the real work (getting the attribute
    # from the object and calling the filter) is done in get1.
    # Why can't we pass get1 to the bastion?  Because the user
    # would be able to override the filter argument!  With get2,
    # overriding the default argument is no security loophole:
    # all it does is call it.
    # Also notice that we can't place the object and filter as
    # instance variables on the bastion object itself, since
    # the user has full access to all instance variables!

    def get1(name, object=object, filter=filter):
	"""Internal function for Bastion().  See source comments."""
	if filter(name):
	    attribute = getattr(object, name)
	    if type(attribute) == MethodType:
		return attribute
	raise AttributeError, name

    def get2(name, get1=get1):
	"""Internal function for Bastion().  See source comments."""
	return get1(name)

    if name is None:
	name = `object`
    return bastionclass(get2, name)


def _test():
    """Test the Bastion() function."""
    class Original:
	def __init__(self):
	    self.sum = 0
	def add(self, n):
	    self._add(n)
	def _add(self, n):
	    self.sum = self.sum + n
	def total(self):
	    return self.sum
    o = Original()
    b = Bastion(o)
    b.add(81)
    b.add(18)
    print "b.total() =", b.total()
    try:
	print "b.sum =", b.sum,
    except:
	print "inaccessible"
    else:
	print "accessible"
    try:
	print "b._add =", b._add,
    except:
	print "inaccessible"
    else:
	print "accessible"


if __name__ == '__main__':
    _test()
