Source code for tamarco.core.patterns.proxy

[docs]class Proxy: """Proxy pattern to be used as a pointer. When the value of _obj changes, the reference to the proxy remains. """ __slots__ = ["_obj", "__weakref__"] def __init__(self, obj): """Initialize the Proxy class. Args: obj (object): New object to be used in the proxy. """ object.__setattr__(self, "_obj", obj) # # proxying (special cases) # def __getattribute__(self, name): """Get the value from the _obj attribute `name`. Args: name (string): Attribute name. Returns: Attribute value. """ return getattr(object.__getattribute__(self, "_obj"), name) def __delattr__(self, name): """Delete the attribute `name` from the _obj object. Args: name (string): Attribute name. """ delattr(object.__getattribute__(self, "_obj"), name) def __setattr__(self, name, value): """Set a value to the _obj attribute `name`. Args: name (string): Attribute name. value: Attribute value. """ setattr(object.__getattribute__(self, "_obj"), name, value) def __bool__(self): """Convert an object to boolean. Returns: bool: Returns True when the evaluation of the _obj object is true, False otherwise. """ return bool(object.__getattribute__(self, "_obj")) def __str__(self): """Compute the "informal" or nicely printable string representation of the _obj object. Returns: str: String representation of the _obj object. """ return str(object.__getattribute__(self, "_obj")) def __repr__(self): """Compute the "official" string representation of the _obj object. Returns: str: String representation of the _obj object. """ return repr(object.__getattribute__(self, "_obj")) # # factories # _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", ]
[docs] @staticmethod def make_method(name): """Create a new method to getting the value of the attribute `name`. Args: name (string): Attribute name. Returns: function: New __getattribute__ method to get a value from the _obj object. """ def method(self, *args, **kw): return getattr(object.__getattribute__(self, "_obj"), name)(*args, **kw) return method
@classmethod def _create_class_proxy(cls, the_class): """Create a proxy for the given class. Args: the_class (class): Class type in which we want to use the proxy. Returns: object: New proxy instance referencing the `the_class` class. """ namespace = {} for name in cls._special_names: if hasattr(the_class, name): namespace[name] = cls.make_method(name) return type(f"{cls.__name__}({the_class.__name__})", (cls,), namespace) def __new__(cls, obj, *args, **kwargs): """Create an proxy instance referencing `obj`. (obj, *args, **kwargs) are passed to this class' __init__, so deriving classes can define an __init__ method of their own. _class_proxy_cache is unique per deriving class (each deriving class must hold its own cache). Args: obj (object): Instance of the class in which we want to use the proxy. *args: Variable length argument list. **kwargs: Arbitrary keyword arguments. Returns: object: New proxy instance referencing `obj`. """ try: cache = cls.__dict__["_class_proxy_cache"] except KeyError: cls._class_proxy_cache = cache = {} try: the_class = cache[obj.__class__] except KeyError: cache[obj.__class__] = the_class = cls._create_class_proxy(obj.__class__) instance = object.__new__(the_class) the_class.__init__(instance, obj, *args, **kwargs) return instance