python-objectbroker/objectbroker/aquisition.py

162 lines
4.9 KiB
Python

import collections
__doc__ = """Einfache Objekt Aquisition für Python."""
class Aquisition:
"""Markiert ein Objekt als Ziel von Aquisition durch AquisitionProxy"""
pass
def caller(inst,a):
return lambda *args,**kwargs: a.__func__(inst,*args,**kwargs)
def call(self,method,*args,**kwargs):
m = getattr(object.__getattribute__( self, "_o"), method)
if hasattr(m,"__func__"):
return m.__func__(self,*args,**kwargs)
else:
return m(*args,**kwargs)
def getter(attrib):
return lambda self, *args, **kwargs: call(self,attrib,*args, **kwargs)
if hasattr(m, "__func__"):
return lambda self, *args, **kwargs: m.__func__(self, *args, **kwargs)
else:
return lambda self, *args, **kwargs: m(*args, **kwargs)
class AquisitionProxy:
"""Basisobjekt für Aquisition."""
_special_names=[
'__abs__', '__add__', '__and__', '__call__', '__cmp__', '__coerce__',
'__contains__', '__delitem__', '__delslice__', '__div__', '__divmod__',
'__eq__', '__float__', '__floordiv__', '__ge__', '__getitem__',
'__getslice__', '__gt__', '__hash__', '__hex__', '__iadd__', '__iand__',
'__idiv__', '__idivmod__', '__ifloordiv__', '__ilshift__', '__imod__',
'__imul__', '__int__', '__invert__', '__ior__', '__ipow__', '__irshift__',
'__isub__', '__iter__', '__itruediv__', '__ixor__', '__le__', '__len__',
'__long__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__',
'__neg__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__',
'__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__',
'__repr__', '__reversed__', '__rfloorfiv__', '__rlshift__', '__rmod__',
'__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__',
'__rtruediv__', '__rxor__', '__setitem__', '__setslice__', '__sub__',
'__truediv__', '__xor__', 'next',
]
def _get_proxy_cls(cls,obj):
ocls = obj.__class__
ns = {}
_methods = {}
for n in AquisitionProxy._special_names:
if (hasattr(ocls, n)):
ns[n] = getter(n)
return type( "AProxy(%s)" % (ocls.__name__,), (cls,), ns )
def __new__(cls,obj,p = None,aq_name=None,aq_root=None):
pcls = AquisitionProxy._get_proxy_cls(cls,obj)
inst = object.__new__( pcls )
_methods = {}
for n in dir(obj):
# print("AQ_ATTR: %s" % (n,))
a = getattr(obj,n)
if isinstance( a, collections.Callable ) and hasattr( a, "__func__" ): # and not hasattr( AquisitionProxy, n ):
# print("AQ_METHOD: %s = %s" % (n,a))
_methods[n] = caller(inst,a)
object.__setattr__( inst, "_methods", _methods )
object.__setattr__( inst, "_o", obj)
object.__setattr__( inst, "_p", p)
object.__setattr__( inst, "_aq_name", aq_name)
if (aq_root is None):
aq_root = inst
object.__setattr__( inst, "_aq_root", aq_root)
return inst
def __getattribute__(self,name):
v = None
# print("AQN: %s" % (name,))
if name.startswith("_aq_"):
if (name == "_aq_parent"):
return object.__getattribute__( self, "_p")
# return AquisitionProxy( p, self, aq_name=p._aq_name, aq_root=self._aq_root )
if (name == "_aq_name"):
n = object.__getattribute__( self, "_aq_name")
if n is None:
return "/"
return n
if (name == "_aq_object"):
return object.__getattribute__( self, "_o")
return object.__getattribute__( self, name )
_methods = object.__getattribute__(self,"_methods")
if name in _methods:
return _methods[name]
try:
v = getattr( object.__getattribute__( self, "_o"), name )
except AttributeError as ae:
try:
print("AQN_PARENT: %s %s" % (object.__getattribute__( self, "_p"), name))
v = getattr( object.__getattribute__( self, "_p"), name)
if (isinstance(v, AquisitionProxy)):
v = object.__getattribute__( v, "_o" )
except AttributeError as ae2:
raise ae2
if isinstance( v, Aquisition ):
v = AquisitionProxy( v, self, aq_name=name, aq_root=self._aq_root )
return v
def __setattr__(self,name,value):
setattr( object.__getattribute__( self, "_o"), name, value )
def __delattr__(self,name):
delattr( object.__getattribute__( self, "_o"), name )
def __nonzero__(self):
return bool(object.__getattribute__(self, "_o"))
def __str__(self):
return str(object.__getattribute__(self, "_o"))
def __repr__(self):
return repr(object.__getattribute__(self, "_o"))
def __dir__(self):
return dir( object.__getattribute__(self, "_o") )
def dir(self,cls):
realcls = object.__getattribute__( self, "__class__" )
ls = []
for an in dir(self):
if issubclass( getattr( self, an ).__class__, cls):
ls.append(an)
if issubclass(realcls,AquisitionProxy):
p = object.__getattribute__( self, "_p")
if not p is None:
for an in AquisitionProxy.dir(p, cls):
if not an in ls:
ls.append( an )
return ls
def _aq_path(self):
if (self._aq_name is None) or (self._aq_parent is None):
return ""
return "%s/%s" % (self._aq_parent._aq_path(),self._aq_name)