Closed as not planned
Description
Bug Report
mypy permits overriding attributes of parent class if the child attribute is compatible with the parent attribute. This breaks Liskov Substitution Principle.
To Reproduce
from typing import Literal
class Parent:
x: Literal["a", "b", "c"]
def __init__(self, x: Literal["a", "b", "c"]) -> None:
self.x = x
class Child(Parent):
x: Literal["a"]
def foo(self) -> Literal["a"]:
return self.x
child = Child("c") # no error from mypy
x = child.foo()
# reveal_type(x) # Revealed type is "Literal['a']
print(x) # outputs "c"
https://mypy-play.net/?mypy=latest&python=3.11&gist=37e7f5a43c649a9ea5d6f0a9253d7e07
Expected Behavior
I believe mypy shouldn't allow overriding class attributes in child class, even with a type that is "compatible" with the parent attribute. Otherwise we can get into funny cases such as:
my_list: list[Parent] = [Child("a")]
my_list[0].x = "c"
Actual Behavior
I got no error from mypy. Running python -m mypy --strict main.py
printed:
Success: no issues found in 1 source file
Your Environment
- Mypy version used:
1.3.0
- Mypy command-line flags:
--strict
- Mypy configuration options from
mypy.ini
(and other config files):None
- Python version used:
3.10.6