Python 3.6.5 and mypy 0.600
I wrote the code:
from typing import List
class Animal():
pass
class Dog(Animal):
def __init__(self) -> None:
super()
def bark(self) -> None:
pass
class Cat(Animal):
def __init__(self) -> None:
super()
def meow(self) -> None:
pass
arr1: List[Dog] = [Dog(), Dog()]
arr2: List[Animal] = [Dog(), Dog()]
# error: Incompatible types in assignment (expression has type "List[Dog]", variable has type "List[Animal]")
arr3: List[Animal] = arr1
I don't understand, why I have an error 'Incompatible types in assignment ' with a variable 'arr3'. Dog is a class which inherits from a Animal. For example, I don't have an error with variable 'arr2'.
Mypy runs are slow If your mypy runs feel slow, you should probably use the mypy daemon, which can speed up incremental mypy runtimes by a factor of 10 or more. Remote caching can make cold mypy runs several times faster.
You can use a special comment # type: ignore[code, ...] to only ignore errors with a specific error code (or codes) on a particular line. This can be used even if you have not configured mypy to show error codes. Currently it's only possible to disable arbitrary error codes on individual lines using this comment.
In Python as all classes inherit from object, potentially multiple copies of object are inherited whenever multiple inheritance is used. That is, the diamond problem occurs even in the simplest of multiple inheritance.
Imagine that this would be possible:
arr3: List[Animal] = arr1
Now you think you have list of animals, but this is actually a list of dogs (note that arr3
is not a copy of arr1
, they are the same list).
And because you think this is the list of animals you can add a Cat
to it.
However, because this is actually list of dogs, you cannot add a Cat
to it. Otherwise you will fail on AttributeError
after trying to use dog-specific attribute.
More generally, list is invariant - List[Animal]
cannot be assigned to List[Dog]
(because it can already contain cats) and List[Dog]
cannot be assigned to List[Animal]
(because you can add cat later)
This might not be obvious in Python, but you can make simple test:
arr3: List[Animal] = arr1
arr3.append(Cat())
for dog in arr1:
print(dog.bark())
Mypy does not allow this because this assignment might break your code logic
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With