Description
- problem:
list.__iadd__
type model appears to be wrong - Python version: CPython 3.6.6 and 3.7.1
- mypy version: 0.650
Examples:
from typing import List
class MyList1(list): pass
l1 = MyList1([1, 2, 3])
l1 += [4, 5, 6]
l1.extend([7, 8, 9])
print(type(l1), isinstance(l1, MyList1), l1)
class MyList2(List[int]): pass
l2 = MyList2([1, 2, 3])
l2 += [4, 5, 6]
l2.extend([7, 8, 9])
print(type(l2), isinstance(l2, MyList2), l2)
Note that both MyList1
and MyList2
are list
subclasses, and all I'm attempting to do is initialize instances and use += (.__iadd__)
and .extend
to extend them.
Running the above code results in the following mostly unsurprising output in Python 3.6.6:
<class '__main__.MyList1'> True [1, 2, 3, 4, 5, 6, 7, 8, 9]
__main__.MyList2 True [1, 2, 3, 4, 5, 6, 7, 8, 9]
and in Python 3.7.1:
<class '__main__.MyList1'> True [1, 2, 3, 4, 5, 6, 7, 8, 9]
<class '__main__.MyList2'> True [1, 2, 3, 4, 5, 6, 7, 8, 9]
Let's ignore the disparate type representations in Python 3.6.6 -- my concern is that mypy
complains that the in-place extensions using __iadd__
result in invalid result types in both cases and both versions:
test.py:5: error: Result type of + incompatible in assignment
test.py:11: error: Result type of + incompatible in assignment
My first reaction was that I am doing something wrong. However, after scouring the internet, this problem doesn't appear to be an instance of one of the common typing pitfalls. The mypy
result simply does not match the actual runtime types produced by CPython, which suggests to me that the mypy
type model for list.__iadd__
is incorrect and resulting in a spurious error.
I'm reporting this potential bug here, rather than in the typeshed
repository, since this deals with a built-in type, assumptions about the core type model, and not the standard library. Apologies in advance if I'm wrong about any of the above.