简体   繁体   中英

Incompatible return value type of python generic property usage that returns self

Trying to implement nodes and trees inheritance hierarchy that respects mypy , I have next classes:

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

But mypy returns 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")

Is there any way I can implement my logic using python typing?

The trick is to add an annotation to the self argument. For example:

T = TypeVar('T')
V = TypeVar('V', bound='BaseNode')

@dataclasses.dataclass
class BaseNode(Generic[T]):
    value: T
    parent: Optional[BaseNode[T]] = None
    left: Optional[BaseNode[T]] = None
    right: Optional[BaseNode[T]] = None

    @property
    def dummy(self: V) -> V:
        return self

    @property
    def dummy_parent(self: V) -> V:
        assert isinstance(self.parent, type(self))
        return self.parent

By the way, you should add the type argument to the optional properties so they don't become BaseNode[Any] , losing the benefit of generics!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM