Skip to content

mypy incorrectly allows overriding parent attribute #15455

Closed as not planned
Closed as not planned
@jfgauron

Description

@jfgauron

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions