I'm looking for a way to extract the return type annotation of a property from a class, e.g.:
class Test:
@property
def foo(self) -> int:
return 1
print(return_type_extract(Test, 'foo')) # <class 'int'>
For standard methods this can be done like so:
import inspect
class Test:
def foo(self) -> int:
return 1
def return_type_extract(cls: type, method_name: str) -> type:
method = getattr(cls, method_name)
return inspect.signature(method).return_annotation
print(return_type_extract(Test, 'foo')) # <class 'int'>
This method however does not work for the @property
decorator, as it raises an error inside inspect.signature
. I've looked at an equivalent for properties in the inspect
library, but so far no luck.
I hit the same issue and managed to find an answer, the key observation is here: https://docs.python.org/3/library/functions.html#property
fget is a function for getting an attribute value
This means signature return_annotation works, but we must apply it to properties' fget functions instead of directly to properties (as they encapsulate multiple functions)
import dataclasses
import inspect
@dataclasses.dataclass
class PropertyTest:
a: int
@property
def b(self) -> float:
return float(self.a)
def test_property_return_type_from_class():
property_return_type = prop_return_type_from_class(
cls=PropertyTest,
prop_name="b",
)
assert property_return_type is float
def prop_return_type_from_class(
*,
prop_name: str,
cls: type,
) -> type:
prop = getattr(cls, prop_name)
return_type = inspect.signature(prop.fget).return_annotation
return return_type