Description
Bug Report
When a list contains Union[Foo[Any],Foo[T]]
, there are inconsistent errors when adding the result to a list of Foo[T]
.
To Reproduce
from typing import List, Union, Generic, TypeVar
T = TypeVar("T")
class Tree(Generic[T]):
children: "List[Union[T, Tree[T]]]"
def __init__(self, children: "List[Union[T, Tree[T]]]") -> None:
self.children = children
def all_sub_trees(self) -> None:
sub_trees: "List[Tree[T]]" = [self]
reveal_type(sub_trees)
only_child_trees = [v for v in self.children if isinstance(v, Tree)]
reveal_type(only_child_trees)
# 3 equivalent statements (ignoring that the first mutates instead of replacing)
sub_trees.extend(only_child_trees)
sub_trees = sub_trees + only_child_trees
sub_trees += only_child_trees
Expected Behavior
Initially I was expecting the value of only_child_trees
to be List[Tree[T`1]]
. However, it is possible that T`1
has the type of Tree[str]
. This would mean that the true type of only_child_trees
is List[Union[Tree[str],Tree[Tree[str]]]]
. So the result is accurate.
However, based on that, I would expect that all of the following operations to have consistent behavior.
Actual Behavior
$ mypy typing_example.py
typing_example.py:15: note: Revealed type is "builtins.list[typing_example.Tree[T`1]]"
typing_example.py:17: note: Revealed type is "builtins.list[Union[typing_example.Tree[Any], typing_example.Tree[T`1]]]"
typing_example.py:21: error: Result type of + incompatible in assignment
Found 1 error in 1 file (checked 1 source file)
mypy
doesn't complain about extend()
or explicit add then assign. However, it does show an error with +=
. It isn't clear to me what the correct behavior is as Any
makes things complicated. The fact that +=
raises an error, but explicit add then assign doesn't seems odd.
I was also able to reproduce this with collections.dequeue
, so this is likely general collection issue and not a list
specific issue.
Your Environment
- Mypy version used: 0.910
- Python version used: 3.9