"""application level support module for transparent proxies. """from__pypy__importtproxyfromtypesimportMethodType_dummy=object()origtype=typedefmake_proxy(controller,type=_dummy,obj=_dummy):""" return a tranparent proxy controlled by the given 'controller' callable. The proxy will appear as a completely regular instance of the given type but all operations on it are send to the specified controller - which receives on ProxyOperation instance on each such call. A non-specified type will default to type(obj) if obj is specified. """iftypeis_dummy:ifobjis_dummy:raiseTypeError("you must specify a type or an instance obj of it")type=origtype(obj)defperform(opname,*args,**kwargs):operation=ProxyOperation(tp,obj,opname,args,kwargs)returncontroller(operation)tp=tproxy(type,perform)returntpclassProxyOperation(object):def__init__(self,proxyobj,obj,opname,args,kwargs):self.proxyobj=proxyobjself.opname=opnameself.args=argsself.kwargs=kwargsifobjisnot_dummy:self.obj=objdefdelegate(self):""" return result from delegating this operation to the underyling self.obj - which must exist and is usually provided through the initial make_proxy(..., obj=...) creation. """try:obj=getattr(self,'obj')exceptAttributeError:raiseTypeError("proxy does not have an underlying 'obj', ""cannot delegate")objattr=getattr(obj,self.opname)res=objattr(*self.args,**self.kwargs)ifself.opname=="__getattribute__":if(isinstance(res,MethodType)andres.im_selfisself.instance):res=MethodType(res.im_func,self.proxyobj,res.im_class)ifresisself.obj:res=self.proxyobjreturnresdef__repr__(self):args=", ".join([repr(x)forxinself.args])args="<0x%x>, "%id(self.proxyobj)+argsifself.kwargs:args+=", ".join(["%s=%r"%itemforiteminself.kwargs.items()])return"<ProxyOperation %s.%s(%s)>"%(type(self.proxyobj).__name__,self.opname,args)