es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿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?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El error sugiere que el uso de dataclasses.InitVar como una pista de tipo en una dataclass con from __future__ import annotations está causando problemas. Esto se puede solucionar especificando el tipo de foo como int en lugar de dc.InitVar[int] o eliminando la importación de from __future__ import annotations.

    Sin embargo, si necesitas usar from __future__ import annotations y dc.InitVar en tu código, puedes evitar el problema retrasando la evaluación de la pista de tipo mediante el uso de comillas.

    from __future__ import annotations
    
    import dataclasses as dc
    import typing
    
    @dc.dataclass
    class Test:
        foo: 'dc.InitVar[int]'
    
    print(typing.get_type_hints(Test))
    

    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.

Comments are closed.