mirror of
https://github.com/bringout/oca-ocb-core.git
synced 2026-04-20 20:32:06 +02:00
18.0 vanilla
This commit is contained in:
parent
d72e748793
commit
0a7ae8db93
337 changed files with 399651 additions and 232598 deletions
|
|
@ -1,28 +1,42 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
__all__ = ['synchronized', 'lazy_classproperty', 'lazy_property',
|
||||
'classproperty', 'conditional', 'lazy']
|
||||
|
||||
import warnings
|
||||
from inspect import getsourcefile, Parameter, signature
|
||||
from functools import wraps
|
||||
from json import JSONEncoder
|
||||
from __future__ import annotations
|
||||
import typing
|
||||
from inspect import Parameter, getsourcefile, signature
|
||||
|
||||
from decorator import decorator
|
||||
|
||||
class lazy_property(object):
|
||||
__all__ = [
|
||||
'classproperty',
|
||||
'conditional',
|
||||
'lazy',
|
||||
'lazy_classproperty',
|
||||
'lazy_property',
|
||||
'synchronized',
|
||||
]
|
||||
|
||||
T = typing.TypeVar("T")
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from collections.abc import Callable
|
||||
|
||||
|
||||
class lazy_property(typing.Generic[T]):
|
||||
""" Decorator for a lazy property of an object, i.e., an object attribute
|
||||
that is determined by the result of a method call evaluated once. To
|
||||
reevaluate the property, simply delete the attribute on the object, and
|
||||
get it again.
|
||||
"""
|
||||
def __init__(self, fget):
|
||||
def __init__(self, fget: Callable[[typing.Any], T]):
|
||||
assert not fget.__name__.startswith('__'),\
|
||||
"lazy_property does not support mangled names"
|
||||
self.fget = fget
|
||||
|
||||
def __get__(self, obj, cls):
|
||||
@typing.overload
|
||||
def __get__(self, obj: None, cls: typing.Any, /) -> typing.Any: ...
|
||||
@typing.overload
|
||||
def __get__(self, obj: object, cls: typing.Any, /) -> T: ...
|
||||
|
||||
def __get__(self, obj, cls, /):
|
||||
if obj is None:
|
||||
return self
|
||||
value = self.fget(obj)
|
||||
|
|
@ -34,7 +48,7 @@ class lazy_property(object):
|
|||
return self.fget.__doc__
|
||||
|
||||
@staticmethod
|
||||
def reset_all(obj):
|
||||
def reset_all(obj) -> None:
|
||||
""" Reset all lazy properties on the instance `obj`. """
|
||||
cls = type(obj)
|
||||
obj_dict = vars(obj)
|
||||
|
|
@ -42,12 +56,6 @@ class lazy_property(object):
|
|||
if isinstance(getattr(cls, name, None), lazy_property):
|
||||
obj_dict.pop(name)
|
||||
|
||||
class lazy_classproperty(lazy_property):
|
||||
""" Similar to :class:`lazy_property`, but for classes. """
|
||||
def __get__(self, obj, cls):
|
||||
val = self.fget(cls)
|
||||
setattr(cls, self.fget.__name__, val)
|
||||
return val
|
||||
|
||||
def conditional(condition, decorator):
|
||||
""" Decorator for a conditionally applied decorator.
|
||||
|
|
@ -63,7 +71,8 @@ def conditional(condition, decorator):
|
|||
else:
|
||||
return lambda fn: fn
|
||||
|
||||
def filter_kwargs(func, kwargs):
|
||||
|
||||
def filter_kwargs(func: Callable, kwargs: dict[str, typing.Any]) -> dict[str, typing.Any]:
|
||||
""" Filter the given keyword arguments to only return the kwargs
|
||||
that binds to the function's signature.
|
||||
"""
|
||||
|
|
@ -80,19 +89,22 @@ def filter_kwargs(func, kwargs):
|
|||
|
||||
return {key: kwargs[key] for key in kwargs if key not in leftovers}
|
||||
|
||||
def synchronized(lock_attr='_lock'):
|
||||
|
||||
def synchronized(lock_attr: str = '_lock'):
|
||||
@decorator
|
||||
def locked(func, inst, *args, **kwargs):
|
||||
with getattr(inst, lock_attr):
|
||||
return func(inst, *args, **kwargs)
|
||||
return locked
|
||||
|
||||
|
||||
locked = synchronized()
|
||||
|
||||
|
||||
def frame_codeinfo(fframe, back=0):
|
||||
""" Return a (filename, line) pair for a previous frame .
|
||||
@return (filename, lineno) where lineno is either int or string==''
|
||||
"""
|
||||
|
||||
try:
|
||||
if not fframe:
|
||||
return "<unknown>", ''
|
||||
|
|
@ -107,33 +119,25 @@ def frame_codeinfo(fframe, back=0):
|
|||
except Exception:
|
||||
return "<unknown>", ''
|
||||
|
||||
def compose(a, b):
|
||||
""" Composes the callables ``a`` and ``b``. ``compose(a, b)(*args)`` is
|
||||
equivalent to ``a(b(*args))``.
|
||||
|
||||
Can be used as a decorator by partially applying ``a``::
|
||||
class classproperty(typing.Generic[T]):
|
||||
def __init__(self, fget: Callable[[typing.Any], T]) -> None:
|
||||
self.fget = classmethod(fget)
|
||||
|
||||
@partial(compose, a)
|
||||
def b():
|
||||
...
|
||||
"""
|
||||
warnings.warn(
|
||||
"Since 16.0, just byo or use a dedicated library like funcy.",
|
||||
DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
@wraps(b)
|
||||
def wrapper(*args, **kwargs):
|
||||
return a(b(*args, **kwargs))
|
||||
return wrapper
|
||||
|
||||
|
||||
class _ClassProperty(property):
|
||||
def __get__(self, cls, owner):
|
||||
def __get__(self, cls, owner: type | None = None, /) -> T:
|
||||
return self.fget.__get__(None, owner)()
|
||||
|
||||
def classproperty(func):
|
||||
return _ClassProperty(classmethod(func))
|
||||
@property
|
||||
def __doc__(self):
|
||||
return self.fget.__doc__
|
||||
|
||||
|
||||
class lazy_classproperty(classproperty[T], typing.Generic[T]):
|
||||
""" Similar to :class:`lazy_property`, but for classes. """
|
||||
def __get__(self, cls, owner: type | None = None, /) -> T:
|
||||
val = super().__get__(cls, owner)
|
||||
setattr(owner, self.fget.__name__, val)
|
||||
return val
|
||||
|
||||
|
||||
class lazy(object):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue