Tipo de valor de retorno incompatible en el uso genérico de propiedades de Python que devuelve self.
Tratando de implementar una jerarquía de herencia de nodos y árboles que respete “mypy”, tengo las siguientes clases:
from __future__ import annotations
import dataclasses
from typing import Generic, TypeVar, Optional
GenericNodeValue = TypeVar('GenericNodeValue')
@dataclasses.dataclass
class BaseNode(Generic[GenericNodeValue]):
value: GenericNodeValue
parent: Optional[BaseNode] = None
left: Optional[BaseNode] = None
right: Optional[BaseNode] = None
@property
def dummy(self) -> BaseNode:
return self
GenericNode = TypeVar('GenericNode', bound=BaseNode)
class BaseTree(Generic[GenericNode]):
def __init__(self):
self.root: Optional[GenericNode] = None
def get_dummy(self, node: GenericNode) -> GenericNode:
return node.dummy
@dataclasses.dataclass
class RedBlackTreeNode(BaseNode[int]):
red: bool = False
class RedBlackTree(BaseTree[RedBlackTreeNode]):
def get_dummy2(self, node: RedBlackTreeNode) -> RedBlackTreeNode:
return node.dummy
Pero “mypy” devuelve un error:
test.py:29: error: Incompatible return value type (got "BaseNode[Any]", expected "GenericNode")
test.py:39: error: Incompatible return value type (got "BaseNode[Any]", expected "RedBlackTreeNode")
¿Hay alguna manera de implementar mi lógica utilizando la escritura de tipos de Python?
davy.ai
Sí, hay algunos cambios que puedes hacer en el código para satisfacer
mypy
.En primer lugar, debes agregar una restricción de tipo a la clase
BaseNode
para que sus hijos sean del mismo tipo que ella. Esto permitirá amypy
inferir correctamente el tipo de retorno de la propiedaddummy
. Puedes hacer esto agregando una variable de tipoChildNode
aBaseNode
:Aquí se usa
ChildNode
como restricción para el tipo de los atributosparent
,left
yright
deBaseNode
. Este cambio permite amypy
inferir el tipo de retorno correcto para la propiedaddummy
.A continuación, debes agregar una restricción de tipo a
BaseTree
para especificar el tipo de su atributoroot
. Puedes hacer esto agregando otra variable de tipo aBaseTree
, como en el siguiente ejemplo:Aquí,
RootNode
se utiliza como restricción de tipo para el atributoroot
, lo que permite amypy
inferir el tipo correcto paranode
en el métodoget_dummy
.Finalmente, debes agregar una restricción de tipo a
RedBlackTree
para especificar el tipo de su métodoget_dummy2
. Puedes hacer esto especificando el tipo de retorno esperado para este método, como en el siguiente ejemplo:Aquí,
RedBlackTreeNode
se utiliza para restringir el tipo de retorno deget_dummy2
, lo que satisface los requisitos demypy
.Con estos cambios, tu código ahora debería pasar las verificaciones de
mypy
.