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.

MiPy, estrechamiento de tipo desde valores de retorno.

Estoy analizando el siguiente ejemplo de Python escrito:

from future import annotations
from typing import Optional

class Thing:

    def does_intersect(self, other: Thing) -> bool:
        return True

    def intersect(self, other: Thing) -> Optional[Thing]:
        if self.does_intersect(other):
            return self
        else:
            return None

def my_function() -> Thing:
    thing = Thing()
    other_thing = Thing()
    if not thing.does_intersect(other_thing):
        return thing
    return thing.intersect(other_thing)

Y la documentación de mypy establece:

Mypy comprende las implicaciones que la devolución o el lanzamiento de excepciones puede tener en el tipo que puede ser un objeto.

Sin embargo, al ejecutar mypy en este ejemplo se obtiene el siguiente error:

error: Tipo de valor de devolución incompatible (se obtuvo "Optional[Thing]", se esperaba "Thing")
Se encontró 1 error en 1 archivo (se verificó 1 archivo fuente)

Entiendo que mypy puede utilizar TypeGuards, pero no parecen resolver naturalmente este problema: necesitamos una forma de enseñar a mypy a reducir el tipo de devolución de un método, en lugar de reducir el tipo de una variable. Tal vez pueda aplicar algún tipo de TypeGuard a la función en sí, pero… no veo un enfoque claro.

Entiendo por qué mypy no puede hacer inferencias en casos como este. Por ejemplo, si la implementación de does_intersect fuera en cambio return random.choice([True, False]), entonces el valor que pretendo utilizar como guardia en la línea 18 sería diferente del valor que intersect ve en la línea 8.

¿Qué tipo de inferencia de tipo es capaz de hacer mypy y hay un enfoque razonable para enseñar a Mypy a manejar este tipo de ejemplo? Se agradece la paciencia, soy totalmente nuevo en mypy aunque he leído la documentación y no encontré una respuesta a este tipo de pregunta.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Mypy es capaz de inferir tipos fuertes y estáticos. Puede entender las implicaciones de la devolución o la generación de excepciones en los posibles tipos de objetos. Sin embargo, en el ejemplo proporcionado, mypy devuelve un error indicando que los tipos de valores de retorno son incompatibles. Esto se debe a que mypy espera que el tipo de valor de retorno de my_function() sea Thing, pero el método intersect() devuelve un Optional[Thing].

    Enseñar a mypy a manejar este tipo de ejemplo puede ser un desafío. Una solución podría ser usar un TypeGuard en el valor de retorno del método intersect(). Esto permitiría a mypy reducir el tipo de retorno a Thing. Sin embargo, este enfoque puede ser confuso, ya que requiere crear múltiples condiciones para el valor de retorno.

    Otro enfoque podría ser usar tipos Union. Esto permitiría que el tipo de retorno de intersect() fuera tanto Thing como None. Luego, en my_function(), podemos indicar explícitamente que el tipo de retorno es Optional[Thing].

    En general, mypy es una herramienta poderosa para inferir tipos fuertes y estáticos, pero manejar situaciones complejas como la proporcionada requiere una cuidadosa consideración de la estructura del código y las anotaciones de tipo.

Comments are closed.