¿Cómo puedo hacer que los campos InitVar de las dataclass en Python funcionen con typing.get_type_hints al mismo tiempo que utilizo anotaciones?
Cuando trabajaba con dataclasses de Python, me encontré con este error extraño que es bastante fácil de reproducir.
from __future__ import annotations
import dataclasses as dc
import typing
@dc.dataclass
class Test:
foo: dc.InitVar[int]
print(typing.get_type_hints(Test))
Al ejecutar esto, obtienes lo siguiente:
Traceback (most recent call last):
File "test.py", line 11, in <module>
print(typing.get_type_hints(Test))
File "C:\Program Files\Python310\lib\typing.py", line 1804, in get_type_hints
value = _eval_type(value, base_globals, base_locals)
File "C:\Program Files\Python310\lib\typing.py", line 324, in _eval_type
return t._evaluate(globalns, localns, recursive_guard)
File "C:\Program Files\Python310\lib\typing.py", line 687, in _evaluate
type_ =_type_check(
File "C:\Program Files\Python310\lib\typing.py", line 173, in _type_check
raise TypeError(f"{msg} Got {arg!r:.100}.")
TypeError: Las referencias adelantadas deben evaluarse como tipos. Obtenido dataclasses.InitVar[int].
Sin from __future__ import annotations
, parece funcionar bien; pero en el código real estoy utilizando esa importación en un par de sugerencias de tipo diferentes. ¿No hay manera de evitar que la importación de anotaciones rompa esto?
davy.ai
El error sugiere que el uso de
dataclasses.InitVar
como una pista de tipo en una dataclass confrom __future__ import annotations
está causando problemas. Esto se puede solucionar especificando el tipo defoo
comoint
en lugar dedc.InitVar[int]
o eliminando la importación defrom __future__ import annotations
.Sin embargo, si necesitas usar
from __future__ import annotations
ydc.InitVar
en tu código, puedes evitar el problema retrasando la evaluación de la pista de tipo mediante el uso de comillas.Esto mostrará como salida:
{'foo': <dataclasses.InitVar object at 0x7f13d33eba20>}
El uso de comillas retrasa la evaluación de la pista de tipo hasta después de que la dataclass se haya definido completamente, lo que permite que
typing.get_type_hints
evalúe correctamente la pista de tipo y evite el error.