-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
Sorry about the bland title -- I think I lack the vocabulary to concisely describe what exactly is going on and to determine if this is a duplicate issue or not. Feel free to change it to something more descriptive.
Here's a somewhat boiled down snippit of code:
from typing import Generic, TypeVar, Set, List, Iterable
T = TypeVar('T')
class Node:
def __init__(self, children: List['Node']) -> None:
self.children = children
def accept(self, visitor: 'Visitor[T]') -> T:
pass
class NodeChild(Node):
def accept(self, visitor: 'Visitor[T]') -> T:
return visitor.visit_node_child(self)
class Visitor(Generic[T]):
def visit_node_child(self, node: NodeChild) -> T:
pass
class ExampleVisitor(Visitor[Set[str]]):
def _visit(self, nodes: List[Node]) -> Set[str]:
output = set() # type: Set[str]
for node in nodes:
output.update(node.accept(self)) # Error here
return output
def visit_node_child(self, node: NodeChild) -> Set[str]:
return {'a'} | self._visit(node.children)When I try running this snippit of code, I get the following unexpected error:
test.py: note: In member "_visit" of class "ExampleVisitor":
test.py:24: error: Argument 1 to "accept" of "Node" has incompatible type "ExampleVisitor"; expected Visitor[Iterable[str]]
However, when I try modifying the definition of _visit to look like the following:
def _visit(self, nodes: List[Node]) -> Set[str]:
output = set() # type: Set[str]
for node in nodes:
data = node.accept(self) # Extract this into a separate variable
output.update(data)
return output...mypy behaves as expected and does not report any errors.
I think this bug is also related to the type signature of set.update -- the type signature is update(self, *x: Iterable[_T]) -> None. The same bug still exists if I try swapping out the call to output.update(...) with a dummy function with a signature of fake_update(x: Iterable[T]) -> None, but goes away if I try changing the dummy signature to look like fake_update(x: Set[T]) -> None.