You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
List concatenation problems with type context and different operand item types #5492
test.py:22: error: Incompatible types in assignment (expression has type "List[B1]", variable has type "List[A]")
test.py:22: error: List item 0 has incompatible type "B2"; expected "B1"
test.py:24: error: List item 0 has incompatible type "B2"; expected "B1"
The covariance of Sequence helps eliminate the first error. But I can never add two lists of objects of different classes without existing annotation, even the classes have same base.
In my opinion, cast takes place when downcasting is necessary. So it should not be used in this way.
t.py:2: error: Incompatible types in assignment (expression has type "List[int]", variable has type "List[Optional[int]]")
t.py:2: error: List item 0 has incompatible type "None"; expected "int"
Issues like these seem somewhat frequent. There are also similar examples in the mypy codebase.
The errors have two causes:
list concatenation cannot vary the return type based on context
the types of the list items must match in concatenation.
A quick way to fix this particular example would be to change the signature of list.__add__ to something like this:
This signature might cause other problems, though. This wouldn't solve the problem in general. For example, if the annotation would say # type: List[Union[int, str, None]] the error would persist, even though the code would be safe.
With some type system extensions we could fix this more generally. We'd need type variable lower bounds (we currently only have upper bounds), and to allow type variable bounds to refer to other type variables. I think that this would be a good signature:
Instead, we could special case list.__add__ in the type checker, since it's a very common operation. This would be ugly and potentially confusing, since the effective signature wouldn't match typeshed.
changed the title [-]Concatenating lists of different derived classes' objects does not result in type upcast[/-][+]List concatenation problems with type context and different operand item types[/+]on Oct 12, 2018
python/typeshed#2404 caused regressions (see #5971 and #5874). I'm going to propose reverting it, since there seems to be no easy way to avoid the regressions in mypy. In summary, the PR fixed some issues but introduced others, which looks like a significant regression for existing mypy users.
If we want to fix the original issue, the simplest way would likely be to special case list.__add__ using a plugin, while preserving the old signature in typeshed. Not sure whether this is a big enough issue for a plugin to be worth it.
There doesn't appear to be a good way to say add lists and pass as an argument to a function all in one go. Instead we either have to break this apart into a few lines and use append/extend OR use unpacking like [list1, *list2] to make things work. The former gets very verbose the more lists you have, and the latter seems a less natural way to add lists together
Understood limitations that caused this to be reverted in the first place; wanted to voice support for this issue in case someone has a good idea on how to make it work going forward!
I was going to open an issue after getting an issue with list concatenation, but but I think it is a variation of this.
from typing import Iterable, Union
aa: Iterable[str] = ["a"]
bb: Iterable[Union[str, int]] = [1]
def strs_and_ints(xx: Iterable[Union[str, int]]):
print(list(xx))
strs_and_ints(aa)
strs_and_ints(list(aa))
strs_and_ints(list(bb) + list(aa))
# False positives. The argument type of strs_and_ints should be used to determine validity of list concatenation.
strs_and_ints(list(aa) + list(bb))
strs_and_ints(["a"] + list(bb))
mypy list_arg.py
list_arg.py:11: error: Argument 1 to "list" has incompatible type "Iterable[Union[str, int]]"; expected "Iterable[str]"
Found 1 error in 1 file (checked 1 source file)
``
Activity
ilevkivskyi commentedon Aug 17, 2018
I think this is a consequence of how
list.__add__is typed in typeshed. I am however not sure what would be a better signature.JelleZijlstra commentedon Aug 19, 2018
python/typeshed#2404 fixes this.
JukkaL commentedon Oct 12, 2018
(This comment is copied from #5778, which is a duplicate issue.)
Code like this doesn't type check correctly (Python 2 example):
It generates these errors:
Issues like these seem somewhat frequent. There are also similar examples in the mypy codebase.
The errors have two causes:
A quick way to fix this particular example would be to change the signature of
list.__add__to something like this:This signature might cause other problems, though. This wouldn't solve the problem in general. For example, if the annotation would say
# type: List[Union[int, str, None]]the error would persist, even though the code would be safe.With some type system extensions we could fix this more generally. We'd need type variable lower bounds (we currently only have upper bounds), and to allow type variable bounds to refer to other type variables. I think that this would be a good signature:
Implementing this could be difficult.
Instead, we could special case
list.__add__in the type checker, since it's a very common operation. This would be ugly and potentially confusing, since the effective signature wouldn't match typeshed.[-]Concatenating lists of different derived classes' objects does not result in type upcast[/-][+]List concatenation problems with type context and different operand item types[/+]JukkaL commentedon Oct 12, 2018
Increasing priority to high since we have several independent sightings of this issue.
fix list concatenation (#2404)
JukkaL commentedon Nov 29, 2018
python/typeshed#2404 caused regressions (see #5971 and #5874). I'm going to propose reverting it, since there seems to be no easy way to avoid the regressions in mypy. In summary, the PR fixed some issues but introduced others, which looks like a significant regression for existing mypy users.
If we want to fix the original issue, the simplest way would likely be to special case
list.__add__using a plugin, while preserving the old signature in typeshed. Not sure whether this is a big enough issue for a plugin to be worth it.Revert "fix list concatenation (python#2404)"
Revert "fix list concatenation (#2404)" (#2653)
fix list concatenation (python#2404)
Revert "fix list concatenation (python#2404)" (python#2653)
WillAyd commentedon Oct 24, 2019
Just wanted to comment here as we run into this issue a lot in pandas. Here's a specific example:
pandas-dev/pandas#29205 (comment)
There doesn't appear to be a good way to say add lists and pass as an argument to a function all in one go. Instead we either have to break this apart into a few lines and use append/extend OR use unpacking like
[list1, *list2]to make things work. The former gets very verbose the more lists you have, and the latter seems a less natural way to add lists togetherUnderstood limitations that caused this to be reverted in the first place; wanted to voice support for this issue in case someone has a good idea on how to make it work going forward!
lhupfeldt commentedon Feb 26, 2021
I was going to open an issue after getting an issue with list concatenation, but but I think it is a variation of this.
twoertwein commentedon Sep 28, 2022
seems like mypy 0.981 might have (accidentally?) fix this issue.
AlexWaygood commentedon Sep 28, 2022
Well, not exactly an accident, given how long we spent discussing it in python/typeshed#8293 ;)
But yup, this is fixed now! 🎉