|
|
|
@ -5847,14 +5847,23 @@ def cached_method(f):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class classproperty:
|
|
|
|
|
"""property access for class methods"""
|
|
|
|
|
"""property access for class methods with optional caching"""
|
|
|
|
|
def __new__(cls, func=None, *args, **kwargs):
|
|
|
|
|
if not func:
|
|
|
|
|
return functools.partial(cls, *args, **kwargs)
|
|
|
|
|
return super().__new__(cls)
|
|
|
|
|
|
|
|
|
|
def __init__(self, func):
|
|
|
|
|
def __init__(self, func, *, cache=False):
|
|
|
|
|
functools.update_wrapper(self, func)
|
|
|
|
|
self.func = func
|
|
|
|
|
self._cache = {} if cache else None
|
|
|
|
|
|
|
|
|
|
def __get__(self, _, cls):
|
|
|
|
|
if self._cache is None:
|
|
|
|
|
return self.func(cls)
|
|
|
|
|
elif cls not in self._cache:
|
|
|
|
|
self._cache[cls] = self.func(cls)
|
|
|
|
|
return self._cache[cls]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Namespace(types.SimpleNamespace):
|
|
|
|
|