-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make classproperty descriptor work #2563
Comments
It seems to work in this way: from typing import *
T = TypeVar("T")
V = TypeVar("V")
class classproperty(Generic[T, V]):
def __init__(self, getter: Callable[[Type[T]], V]) -> None:
self.getter = getattr(getter, "__func__", getter)
def __get__(self, instance: Any, owner: Type[T]) -> V:
return self.getter(owner)
class C:
@classproperty
@classmethod
def foo(cls) -> int:
return 42
reveal_type(C.foo) I don't think it is ideal to have to use both |
the last example doesn't work with from typing import *
T = TypeVar("T")
V = TypeVar("V")
class classproperty(Generic[T, V]):
def __init__(self, getter: Callable[[Type[T]], V]) -> None:
self.getter = getattr(getter, "__func__", getter)
def __get__(self, instance: Any, owner: Type[T]) -> V:
return self.getter(owner)
F = TypeVar("F", bound='Foo')
class Foo:
@classproperty
@classmethod
def foo(cls: Type[F]) -> F:
return cls()
class Bar(Foo):
pass
reveal_type(Bar.foo)
seems to work if you remove |
Under 3.9, the docs are now recommending the use of If you try to do this and run mypy, however, the class property type is deduced as e.g.
shows Would it be possible to special-case Right now, trying to declare a read-only class property which satisfies the trifecta of
is quite tricky. |
I've been using a from collections.abc import Callable
from typing import TypeVar
PropReturn = TypeVar("PropReturn")
def classproperty(meth: Callable[..., PropReturn]) -> PropReturn:
"""Access a @classmethod like a @property."""
# mypy doesn't understand class properties yet: https://github.com/python/mypy/issues/2563
return classmethod(property(meth)) # type: ignore
class A:
@classproperty
def x(cls) -> int:
return 5
print(A.x) # 5
reveal_type(A.x) # note: Revealed type is "builtins.int"
print(A().x) # 5
reveal_type(A().x) # note: Revealed type is "builtins.int" Rather than muck with |
Workaround for python/mypy#2563
As discussed in #2266, this apparently doesn't work yet:
@gvanrossum reported the following output from mypy:
The text was updated successfully, but these errors were encountered: