Using typing.get_type_hints() on classes returns the wrong value when a class variable has the same name as a type and a default value.
For instance:
from dataclasses import dataclass
from typing import get_type_hints
@dataclass
class DataClassHints:
str: str="asdf"
>>> get_type_hints(DataClassHints)
... NameError: name 'asdf' is not defined
Looks like get_type_hints() is using "asdf" as a type.
This is more clear if we use something like datetime:
from datetime import datetime
class ClassHints:
datetime: datetime=datetime.now()
>>> get_type_hints(ClassHints)
... {'datetime': datetime.datetime(2021, 2, 18, 12, 40, 16, 966502)
If we do the same thing in a method get_type_hints works correctly:
class CorrectHints:
def __init__(self, str: str="asdf", datetime: datetime=datetime.now()):
self.str = str
self.datetime = datetime
>>> ch = CorrectHints()
>>> ch.str
... 'asdf'
>>> ch.datetime
... datetime.datetime(2021, 2, 18, 12, 41, 46, 214844)
>>> get_type_hints(CorrectHints.__init__)
... {'str': str, 'datetime': datetime.datetime}
Also functions work correctly:
def func_type_hints(str: str="asdf", datetime: datetime=datetime.now()):
return f"str: {str}, datetime: {datetime}"
>>> func_type_hints()
... 'str: asdf, datetime: 2021-02-18 12:44:21.102933'
>>> get_type_hints(func_type_hints)
... {'str': str, 'datetime': datetime.datetime}
It looks like get_type_hints is evaluating the default value in a class variable before the type hint.
Here's another way to replicate this issue to make it clearer:
class EvalOrderHints:
datetime = datetime.now()
datetime: datetime
>>> get_type_hints(EvalOrderHints)
... {'datetime': datetime.datetime(2021, 2, 18, 12, 47, 56, 608261)}
>>> EvalOrderHints().datetime
... datetime.datetime(2021, 2, 18, 12, 47, 56, 608261)
|