Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

regression in 1.12.0: un-suppressable error with no line number when subtyping dataclass when field has incompatible subtype #18115

Closed
DetachHead opened this issue Nov 7, 2024 · 2 comments
Labels
bug mypy got something wrong topic-dataclasses

Comments

@DetachHead
Copy link
Contributor

DetachHead commented Nov 7, 2024

from dataclasses import dataclass


@dataclass
class Foo:
    a: object


@dataclass
class Bar(Foo):
    a: int
main.py: error: Argument 1 of "__replace__" is incompatible with supertype "Foo"; supertype defines the argument type as "object"  [override]
main.py: note: This violates the Liskov substitution principle
main.py: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides
Found 1 error in 1 file (checked 1 source file)

playground

this error has no line number and therefore cannot be ignored. this is a big problem because not being able to type:ignore the error is preventing us from updating mypy

the error also occurs when the dataclass is frozen, in which case the error is a false positive here because the type of the field should be considered covariant:

from dataclasses import dataclass


@dataclass(frozen=True)
class Foo:
    a: object


@dataclass(frozen=True)
class Bar(Foo):
    a: int

(you could argue that the error is technically still correct because the generated __replace__ method takes the constructor arguments in a contravariant position, but dataclasses.replace is completely untyped anyway, so this additional safety has no benefit).

related issue on pyright: microsoft/pyright#9351

@DetachHead DetachHead added the bug mypy got something wrong label Nov 7, 2024
@brianschubert
Copy link
Collaborator

brianschubert commented Nov 7, 2024

This error seems to only occur when running mypy with Python 3.13. Checking the same code with Python 3.12 produces no error for me (both locally and on the playground).

edit: this only occurring in Python 3.13 seems expected. The dataclass plugin only adds a __replace__ method to dataclass definitions when checking 3.13+:

if self._api.options.python_version >= (3, 13):
self._add_dunder_replace(attributes)

JukkaL pushed a commit that referenced this issue Nov 7, 2024
…ne number (#18122)

Refs #18115

When a parameter type in a method override is incompatible with the
parameter type in the supertype definition, mypy emits an error using
the `Argument` node as the context.

However, sometimes the the `Argument` node doesn't have a line number
set, causing the error message to have no associated line number. This
happens with the `__replace__` methods created in the dataclass plugin,
which have line numbers set on the `FuncDef` nodes, but no line numbers
set on the individual argument nodes.

This PR fixes the missing line number in the error by falling-back to
the FuncDef line number when a line number isn't set on the `Argument`
node.

(As an alternative fix, we could add line numbers to the `Argument`
nodes in the dataclass plugin, but that looks like a more complicated
change since multiple methods would be affected).
@JukkaL
Copy link
Collaborator

JukkaL commented Nov 8, 2024

Fixed by #18122.

@JukkaL JukkaL closed this as completed Nov 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-dataclasses
Projects
None yet
Development

No branches or pull requests

4 participants