mirror of
https://github.com/bringout/oca-ocb-core.git
synced 2026-04-21 14:12:06 +02:00
Initial commit: Core packages
This commit is contained in:
commit
12c29a983b
9512 changed files with 8379910 additions and 0 deletions
123
odoo-bringout-oca-ocb-base/odoo/tools/facade.py
Normal file
123
odoo-bringout-oca-ocb-base/odoo/tools/facade.py
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
import functools
|
||||
import inspect
|
||||
|
||||
|
||||
class ProxyAttr:
|
||||
"""
|
||||
Descriptor class for wrapping attributes of the wrapped instance.
|
||||
|
||||
Used with the `Proxy` class, this class is used to set exposed attributes of the wrapped instance while providing
|
||||
optional type casting.
|
||||
"""
|
||||
def __init__(self, cast=False):
|
||||
self._cast__ = cast
|
||||
|
||||
def __set_name__(self, owner, name):
|
||||
cast = self._cast__
|
||||
if cast:
|
||||
def getter(self):
|
||||
value = getattr(self._wrapped__, name)
|
||||
return cast(value) if value is not None else None
|
||||
else:
|
||||
def getter(self):
|
||||
return getattr(self._wrapped__, name)
|
||||
|
||||
def setter(self, value):
|
||||
return setattr(self._wrapped__, name, value)
|
||||
|
||||
setattr(owner, name, property(getter, setter))
|
||||
|
||||
|
||||
class ProxyFunc:
|
||||
"""
|
||||
Descriptor class for wrapping functions of the wrapped instance.
|
||||
|
||||
Used with the `Proxy` class, this class is used to set exposed functions of the wrapped instance
|
||||
while also allowing optional type casting on return values.
|
||||
"""
|
||||
def __init__(self, cast=False):
|
||||
self._cast__ = cast
|
||||
|
||||
def __set_name__(self, owner, name):
|
||||
func = getattr(owner._wrapped__, name)
|
||||
descriptor = inspect.getattr_static(owner._wrapped__, name)
|
||||
cast = self._cast__
|
||||
|
||||
if isinstance(descriptor, staticmethod):
|
||||
if cast:
|
||||
def wrap_func(*args, **kwargs):
|
||||
result = func(*args, **kwargs)
|
||||
return cast(result) if result is not None else None
|
||||
elif cast is None:
|
||||
def wrap_func(*args, **kwargs):
|
||||
func(*args, **kwargs)
|
||||
else:
|
||||
def wrap_func(*args, **kwargs):
|
||||
return func(*args, **kwargs)
|
||||
|
||||
functools.update_wrapper(wrap_func, func)
|
||||
wrap_func = staticmethod(wrap_func)
|
||||
|
||||
elif isinstance(descriptor, classmethod):
|
||||
if cast:
|
||||
def wrap_func(cls, *args, **kwargs):
|
||||
result = func(*args, **kwargs)
|
||||
return cast(result) if result is not None else None
|
||||
elif cast is None:
|
||||
def wrap_func(cls, *args, **kwargs):
|
||||
func(*args, **kwargs)
|
||||
else:
|
||||
def wrap_func(cls, *args, **kwargs):
|
||||
return func(*args, **kwargs)
|
||||
|
||||
functools.update_wrapper(wrap_func, func)
|
||||
wrap_func = classmethod(wrap_func)
|
||||
|
||||
else:
|
||||
if cast:
|
||||
def wrap_func(self, *args, **kwargs):
|
||||
result = func(self._wrapped__, *args, **kwargs)
|
||||
return cast(result) if result is not None else None
|
||||
elif cast is None:
|
||||
def wrap_func(self, *args, **kwargs):
|
||||
func(self._wrapped__, *args, **kwargs)
|
||||
else:
|
||||
def wrap_func(self, *args, **kwargs):
|
||||
return func(self._wrapped__, *args, **kwargs)
|
||||
|
||||
functools.update_wrapper(wrap_func, func)
|
||||
|
||||
setattr(owner, name, wrap_func)
|
||||
|
||||
|
||||
class ProxyMeta(type):
|
||||
def __new__(cls, clsname, bases, attrs):
|
||||
attrs.update({func: ProxyFunc() for func in ("__repr__", "__str__") if func not in attrs})
|
||||
proxy_class = super().__new__(cls, clsname, bases, attrs)
|
||||
# To preserve the docstring, signature, code of the wrapped class
|
||||
# `updated` to an emtpy list so it doesn't copy the `__dict__`
|
||||
# See `functools.WRAPPER_ASSIGNMENTS` and `functools.WRAPPER_UPDATES`
|
||||
functools.update_wrapper(proxy_class, proxy_class._wrapped__, updated=[])
|
||||
return proxy_class
|
||||
|
||||
|
||||
class Proxy(metaclass=ProxyMeta):
|
||||
"""
|
||||
A proxy class implementing the Facade pattern.
|
||||
|
||||
This class delegates to an underlying instance while exposing a curated subset of its attributes and methods.
|
||||
Useful for controlling access, simplifying interfaces, or adding cross-cutting concerns.
|
||||
"""
|
||||
_wrapped__ = object
|
||||
|
||||
def __init__(self, instance):
|
||||
"""
|
||||
Initializes the proxy by setting the wrapped instance.
|
||||
|
||||
:param instance: The instance of the class to be wrapped.
|
||||
"""
|
||||
object.__setattr__(self, "_wrapped__", instance)
|
||||
|
||||
@property
|
||||
def __class__(self):
|
||||
return type(self)._wrapped__
|
||||
Loading…
Add table
Add a link
Reference in a new issue