classA:
@cached_propertydeff(self) ->int: # f is `cached_property[int]`, f.__get__() -> int
...
@propertydefg(self) ->int: # f is `property[Any]`, g.__get__() -> Any
...
This makes sense to me. It might even make sense to use two type variables for setting and getting. On the other hand, I don't know what the impact on type checkers is, since I think they usually hard-code properties.
I seriously doubt this is idea is supported, but I'll ask anyway.... Is it possible to @overload a class like you can for a function/method? The reason I thought of that is it would allow property with one or two TypeVars. I suspect that the vast majority of uses is for the getter and setter of property to use the same type. However, for those cases where they use different types, there needs to be some way to express that.
Also I think the title of this issue is pretty misleading ("class properties" were deprecated in Python 3.11). I will await feedback and possibly make a PR, since the ecosystem must have changed a lot in the five years since the last PR, but there is still sure to be much breakage.
An exploratory PR would certainly be welcome. Type var defaults should also make the implementation backwards-compatible nowadays. But I would seriously consider using separate output and an input type vars. (Unfortunately, the type systems doesn't supports defaulting one type var to another, as far as I know.)
PEP 696 does support having one TypeVar default to another.
To fully represent the possible states of a property, we'd also need to represent whether or not there is a deleter, and also whether there is a setter and getter. Though for the latter two, there is little practical difference between "setter that accepts Never" and "no setter", so we could just use Never for the setter type. And as for the deleter, that very rarely matters.
Activity
srittau commented on Nov 3, 2020
This makes sense to me. It might even make sense to use two type variables for setting and getting. On the other hand, I don't know what the impact on type checkers is, since I think they usually hard-code properties.
jp-larose commented on May 18, 2021
I was going to open a new issue in response to python/typing#758, but found this one already opened :)
jp-larose commented on May 18, 2021
I seriously doubt this is idea is supported, but I'll ask anyway.... Is it possible to @overload a class like you can for a function/method? The reason I thought of that is it would allow property with one or two TypeVars. I suspect that the vast majority of uses is for the getter and setter of property to use the same type. However, for those cases where they use different types, there needs to be some way to express that.
JelleZijlstra commented on May 18, 2021
You can overloads its __init__ or __new__ method.
JelleZijlstra commented on May 18, 2021
Though I guess that wouldn't give you a way to vary the number of type parameters.
davidhalter commented on Mar 9, 2023
How about something like this?
_C = TypeVar("_C", contravariant=True) _R = TypeVar("_R", covariant=True) _R2 = TypeVar("_R2", covariant=True) _V = TypeVar("_V", contravariant=True) _V2 = TypeVar("_V2", contravariant=True) class property(Generic[_C, _R, _V]): fget: Callable[[_C], _R] | None fset: Callable[[_C, _V], None] | None fdel: Callable[[_C], None] | None __isabstractmethod__: bool def __init__( self, fget: Callable[[_C], _R] | None = ..., fset: Callable[[_C, _V], None] | None = ..., fdel: Callable[[_C], None] | None = ..., doc: str | None = ..., ) -> None: ... def getter(self, __fget: Callable[[_C], _R2]) -> property[_C, _R2, _V]: ... def setter(self, __fset: Callable[[_C, _V2], None]) -> property[_C, _R, _V2]: ... def deleter(self, __fdel: Callable[[_C], None]) -> property: ... def __get__(self, __obj: _C | None, __type: Type[_C] | None = ...) -> Any: ... def __set__(self, __obj: _C, __value: _V) -> None: ... def __delete__(self, __obj: _C) -> None: ...Since the undefined type vars default to Never when they are not provided, this should work fine.
I'm happy to create a pull request if this is something that would potentially be accepted. What do you guys think?
Edit: After writing this, I realized that @erictraut has written something similar
jonathandung commented on Jul 7, 2026
Perhaps add overloads for __get__?
Also I think the title of this issue is pretty misleading ("class properties" were deprecated in Python 3.11). I will await feedback and possibly make a PR, since the ecosystem must have changed a lot in the five years since the last PR, but there is still sure to be much breakage.
msullivan commented on Oct 23, 2026
I think that we are going to need this in PEP 827 - Type Manipulation (https://peps.python.org/pep-0827/), for representing the types of properties.
srittau commented on Oct 23, 2026
An exploratory PR would certainly be welcome. Type var defaults should also make the implementation backwards-compatible nowadays. But I would seriously consider using separate output and an input type vars. (Unfortunately, the type systems doesn't supports defaulting one type var to another, as far as I know.)
JelleZijlstra commented on Oct 24, 2026
PEP 696 does support having one TypeVar default to another.
To fully represent the possible states of a property, we'd also need to represent whether or not there is a deleter, and also whether there is a setter and getter. Though for the latter two, there is little practical difference between "setter that accepts Never" and "no setter", so we could just use Never for the setter type. And as for the deleter, that very rarely matters.