Skip to content

Commit 3b00002

Browse files
Fix [override] error with no line number when argument node has no line 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).
1 parent eedee20 commit 3b00002

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

mypy/checker.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2367,10 +2367,11 @@ def erase_override(t: Type) -> Type:
23672367
else:
23682368
continue
23692369
if not is_subtype(original_arg_type, erase_override(override_arg_type)):
2370+
context: Context = node
23702371
if isinstance(node, FuncDef) and not node.is_property:
2371-
context: Context = node.arguments[i + len(override.bound_args)]
2372-
else:
2373-
context = node
2372+
arg_node = node.arguments[i + len(override.bound_args)]
2373+
if arg_node.line != -1:
2374+
context = arg_node
23742375
self.msg.argument_incompatible_with_supertype(
23752376
i + 1,
23762377
name,

test-data/unit/check-dataclasses.test

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2523,3 +2523,18 @@ reveal_type(replaced_2) # N: Revealed type is "__main__.Gen[builtins.int]"
25232523
Gen(2).__replace__(x="not an int") # E: Argument "x" to "__replace__" of "Gen" has incompatible type "str"; expected "int"
25242524

25252525
[builtins fixtures/tuple.pyi]
2526+
2527+
[case testDunderReplaceCovariantOverride]
2528+
# flags: --python-version 3.13
2529+
from dataclasses import dataclass
2530+
2531+
@dataclass
2532+
class Base:
2533+
a: object
2534+
2535+
@dataclass
2536+
class Child(Base): # E: Argument 1 of "__replace__" is incompatible with supertype "Base"; supertype defines the argument type as "object" \
2537+
# N: This violates the Liskov substitution principle \
2538+
# N: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides
2539+
a: int
2540+
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)