def property_factory(n: int) -> property:
getter = lambda self: return n
return property(getter)
class Foo:
number: int = property_factory(1)
The above code gives me the errror (line 6)
Expression of type "property" cannot be assigned to declared type int
How do I go about type hinting dynamically created properties?
CodePudding user response:
One possible option is to use Protocol
:
from typing import Protocol, TypeVar, overload
T_co = TypeVar('T_co', covariant=True)
class ReadonlyProperty(Protocol[T_co]):
@overload
def __get__(self, instance: None, owner) -> property: ...
@overload
def __get__(self, instance, owner) -> T_co: ...
def __get__(self, instance, owner) -> T_co | property: ...
def property_factory(n: int) -> ReadonlyProperty[int]:
return property(lambda self: n)
class Foo:
number: ReadonlyProperty[int] = property_factory(1)
n: int = Foo().number # mypy pass
prop: property = Foo.number # mypy pass
s: str = Foo().number # Incompatible types in assignment (expression has type "int", variable has type "str") (28:9)
val: int = Foo.number # Incompatible types in assignment (expression has type "property", variable has type "int") (29:11)
CodePudding user response:
Just change the return type to int
instead of property
.
But I suggest you to follow the classic approach:
class Foo:
def __init__(self) -> None:
self._property_factory: int = 0
self.property_factory = 1
number: int = self.property_factory
@property # getter
def property_factory(self) -> int:
return self._property_factory
@property_factory.setter
def property_factory(self, value: int) -> None:
self._property_factory = value