Skip to content

Commit

Permalink
Improve typing for under_cached_property decorator (#38)
Browse files Browse the repository at this point in the history
* Improve typing for under_cached_property decorator

* changelog
  • Loading branch information
bdraco authored Oct 7, 2024
1 parent 825020d commit 416a3b2
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGES/38.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improved typing for the :func:`propcache.api.under_cached_property` decorator -- by :user:`bdraco`.
51 changes: 39 additions & 12 deletions src/propcache/_helpers_py.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
"""Various helper functions."""

import sys
from functools import cached_property
from typing import Any, Callable, Dict, Generic, Optional, Protocol, Type, TypeVar
from typing import (
Any,
Callable,
Dict,
Generic,
Optional,
Protocol,
Type,
TypeVar,
Union,
overload,
)

__all__ = ("under_cached_property", "cached_property")


if sys.version_info >= (3, 11):
from typing import Self
else:
Self = Any

_T = TypeVar("_T")


Expand All @@ -27,18 +45,27 @@ def __init__(self, wrapped: Callable[..., _T]) -> None:
self.__doc__ = wrapped.__doc__
self.name = wrapped.__name__

def __get__(self, inst: _TSelf[_T], owner: Optional[Type[Any]] = None) -> _T:
@overload
def __get__( # pragma: no cover
self, inst: None, owner: Optional[Type[Any]] = None
) -> Self: ... # pragma: no cover

@overload
def __get__( # pragma: no cover
self, inst: _TSelf[_T], owner: Optional[Type[Any]] = None
) -> _T: ... # pragma: no cover

def __get__(
self, inst: Optional[_TSelf[_T]], owner: Optional[Type[Any]] = None
) -> Union[_T, Self]:
if inst is None:
return self
try:
try:
return inst._cache[self.name]
except KeyError:
val = self.wrapped(inst)
inst._cache[self.name] = val
return val
except AttributeError:
if inst is None:
return self
raise
return inst._cache[self.name]
except KeyError:
val = self.wrapped(inst)
inst._cache[self.name] = val
return val

def __set__(self, inst: _TSelf[_T], value: _T) -> None:
raise AttributeError("cached property is read-only")

0 comments on commit 416a3b2

Please sign in to comment.