Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

type hints for method annotated with @property

How do you access type hints for methods annotated with the @property decorator?

Normally, this is very straightforward:

>>> class Foo:
...     def bar(self) -> str:
...             pass
... 
>>> import typing
>>> typing.get_type_hints(Foo.bar)
{'return': <class 'str'>}

But once bar is annotated with @property and made into a property object, it's not obvious:

>>> class Foo:
...     @property
...     def bar(self) -> str:
...             pass
... 
>>> import typing
>>> typing.get_type_hints(Foo.bar)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/typing.py", line 1527, in get_type_hints
    'or function.'.format(obj))
TypeError: <property object at 0x1050fcc28> is not a module, class, method, or function.
>>> typing.get_type_hints(Foo.bar.__get__)
{}
like image 316
asp Avatar asked Mar 25 '18 20:03

asp


2 Answers

The __get__ isn't the actual function, but a wrapper around it:

>>> Foo.bar.__get__
<method-wrapper '__get__' of property object at 0x11d6f3b88>

To access the function, you use property.fget:

>>> Foo.bar.fget
<function __main__.Foo.bar>

And of course that has the annotations:

>>> typing.get_type_hints(Foo.bar.fget)
{'return': str}

That isn't exactly obvious or discoverable. IIRC, this came up at some point on python-ideas—it's relatively easy for Mypy or another outside static analyzer to get the annotations for a property, but not for code inside the program—but I assume nobody came up with a good answer, or it would have been implemented (or at least discussed in PEP 526).

like image 109
abarnert Avatar answered Nov 09 '22 17:11

abarnert


The function you defined is Foo.bar.fget, not Foo.bar.__get__:

typing.get_type_hints(Foo.bar.fget)
like image 44
user2357112 supports Monica Avatar answered Nov 09 '22 16:11

user2357112 supports Monica