Beta/venv/lib/python3.12/site-packages/propcache/_helpers_py.py

65 lines
1.9 KiB
Python
Raw Normal View History

2026-02-06 22:23:20 +01:00
"""Various helper functions."""
2026-06-16 17:09:34 +00:00
from __future__ import annotations
2026-02-06 22:23:20 +01:00
import sys
2026-06-16 17:09:34 +00:00
from collections.abc import Callable, Mapping
2026-02-06 22:23:20 +01:00
from functools import cached_property
2026-06-16 17:09:34 +00:00
from typing import Any, Generic, Protocol, TypeVar, overload
2026-02-06 22:23:20 +01:00
__all__ = ("under_cached_property", "cached_property")
if sys.version_info >= (3, 11):
from typing import Self
else:
Self = Any
_T = TypeVar("_T")
# We use Mapping to make it possible to use TypedDict, but this isn't
# technically type safe as we need to assign into the dict.
_Cache = TypeVar("_Cache", bound=Mapping[str, Any])
class _CacheImpl(Protocol[_Cache]):
_cache: _Cache
class under_cached_property(Generic[_T]):
"""Use as a class method decorator.
It operates almost exactly like
the Python `@property` decorator, but it puts the result of the
method it decorates into the instance dict after the first call,
effectively replacing the function it decorates with an instance
variable. It is, in Python parlance, a data descriptor.
"""
def __init__(self, wrapped: Callable[[Any], _T]) -> None:
self.wrapped = wrapped
self.__doc__ = wrapped.__doc__
self.name = wrapped.__name__
@overload
2026-06-16 17:09:34 +00:00
def __get__(self, inst: None, owner: type[object] | None = None) -> Self: ...
2026-02-06 22:23:20 +01:00
@overload
def __get__(
2026-06-16 17:09:34 +00:00
self, inst: _CacheImpl[Any], owner: type[object] | None = None
2026-02-06 22:23:20 +01:00
) -> _T: ...
def __get__(
2026-06-16 17:09:34 +00:00
self, inst: _CacheImpl[Any] | None, owner: type[object] | None = None
) -> _T | Self:
2026-02-06 22:23:20 +01:00
if inst is None:
return self
try:
return inst._cache[self.name] # type: ignore[no-any-return]
except KeyError:
val = self.wrapped(inst)
inst._cache[self.name] = val
return val
def __set__(self, inst: _CacheImpl[Any], value: _T) -> None:
raise AttributeError("cached property is read-only")