I like using __qualname__
for the return-type annotation of factory-style class methods, because it doesn't hardcode the classname and therefore keeps working subclasses (cf. this answer).
class Foo:
@classmethod
def make(cls) -> __qualname__:
return cls()
Currently this seems to work fine, but I am not sure whether this will still be possible with the postponed evaluation of annotations (PEP 563): the PEP says that
Annotations can only use names present in the module scope as postponed evaluation using local names is not reliable (with the sole exception of class-level names resolved by
typing.get_type_hints()
).
The PEP also says:
The
get_type_hints()
function automatically resolves the correct value ofglobalns
for functions and classes. It also automatically provides the correctlocalns
for classes.
However, the following code
from __future__ import annotations
import typing
class Foo():
@classmethod
def make(cls) -> __qualname__:
return cls()
print(typing.get_type_hints(Foo.make))
fails with
File "qualname_test.py", line 11, in <module>
print(typing.get_type_hints(Foo.make))
File "/var/local/conda/envs/py37/lib/python3.7/typing.py", line 1004, in get_type_hints
value = _eval_type(value, globalns, localns)
File "/var/local/conda/envs/py37/lib/python3.7/typing.py", line 263, in _eval_type
return t._evaluate(globalns, localns)
File "/var/local/conda/envs/py37/lib/python3.7/typing.py", line 467, in _evaluate
eval(self.__forward_code__, globalns, localns),
File "<string>", line 1, in <module>
NameError: name '__qualname__' is not defined
Commenting the __future__
import makes the code work again, in that case it outputs
{'return': <class '__main__.Foo'>}
as expected.
Is my use case __qualname__
supported (which would mean that get_type_hints
is buggy), or is this approach not possible with PEP 563?