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.

Herencia de clases genéricas con TypeVar restringido

Considere un par simple de clases genéricas:

T = TypeVar("T", str, int)

class Base(Generic[T]):
    def __init__(self, v: T):
        self.v: T = v

@property
def value(self) -> T:
    return self.v

class Child(Base[T]):
    def __init__(self, v: T):
        super().__init__(v)

x = Child(123)
reveal_type(x.value)

Si bien el uso de T = TypeVar("T") funciona como se esperaba, el TypeVar restringido como se muestra produce los siguientes errores:

error: El argumento 1 de "__init__" de "Base" tiene un tipo incompatible "str"; se esperaba "T"
error: El argumento 1 de "__init__" de "Base" tiene un tipo incompatible "int"; se esperaba "T"
note: El tipo revelado es 'builtins.int*'

Cabe destacar que reveal_type sigue funcionando.

Otra diferencia es que el TypeVar restringido requiere la anotación de tipo para la asignación de self.v, mientras que el no restringido no lo requiere.

En el caso de uso completo, en realidad tengo Callable[[Any], T], pero el problema es el mismo.

Esto se probó con mypy 0.910 y Python 3.9.7.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El fragmento de código proporcionado define dos clases genéricas, Base y Child, utilizando un TypeVar restringido. El parámetro genérico T está limitado a str y int utilizando la función TypeVar. La clase Base toma un parámetro v de tipo T e inicializa su variable de instancia self.v. La clase Child hereda de Base[T] e inicializa su clase padre con el mismo parámetro v.

    Sin embargo, el uso del TypeVar restringido provoca errores de tipo incompatibles al inicializar una instancia de Child con una cadena o un entero en lugar de T. Sin embargo, la función reveal_type sigue funcionando correctamente. Además, el TypeVar restringido requiere una anotación de tipo para la asignación de self.v, mientras que el TypeVar no restringido no lo requiere.

    El problema es el mismo al utilizar Callable [[Any], T] en el caso de uso completo. Esto se probó utilizando mypy 0.910 y Python 3.9.7.

Comments are closed.