Skip to content

Commit

Permalink
Give arguments a more reasonable location
Browse files Browse the repository at this point in the history
Modifies arguments parsed from the AST to use the AST's row and
column information. Modifies function definitions to not overwrite
their arguments' locations. Modifies incorrect override messages to
use the locations of arguments instead of the method itself.
Modifies tests to expect the new locations.
  • Loading branch information
koogoro committed Jan 30, 2023
1 parent 0665ce9 commit 1b607e4
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 22 deletions.
8 changes: 7 additions & 1 deletion mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2067,15 +2067,21 @@ def erase_override(t: Type) -> Type:
if not is_subtype(
original.arg_types[i], erase_override(override.arg_types[i])
):

arg_type_in_super = original.arg_types[i]

if isinstance(node, FuncDef):
context: Context = node.arguments[i + len(override.bound_args)]
else:
context = node
self.msg.argument_incompatible_with_supertype(
i + 1,
name,
type_name,
name_in_super,
arg_type_in_super,
supertype,
node,
context,
)
emitted_msg = True

Expand Down
4 changes: 3 additions & 1 deletion mypy/fastparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1081,7 +1081,9 @@ def make_argument(
if argument_elide_name(arg.arg):
pos_only = True

return Argument(Var(arg.arg), arg_type, self.visit(default), kind, pos_only)
argument = Argument(Var(arg.arg), arg_type, self.visit(default), kind, pos_only)
argument.set_line(arg.lineno, arg.col_offset, arg.end_lineno, arg.end_col_offset)
return argument

def fail_arg(self, msg: str, arg: ast3.arg) -> None:
self.fail(msg, arg.lineno, arg.col_offset)
Expand Down
12 changes: 0 additions & 12 deletions mypy/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -704,18 +704,6 @@ def __init__(
def max_fixed_argc(self) -> int:
return self.max_pos

def set_line(
self,
target: Context | int,
column: int | None = None,
end_line: int | None = None,
end_column: int | None = None,
) -> None:
super().set_line(target, column, end_line, end_column)
for arg in self.arguments:
# TODO: set arguments line/column to their precise locations.
arg.set_line(self.line, self.column, self.end_line, end_column)

def is_dynamic(self) -> bool:
return self.type is None

Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-abstract.test
Original file line number Diff line number Diff line change
Expand Up @@ -382,10 +382,10 @@ class A(I):
def g(self, a: 'A') -> 'A':
return A()
[out]
main:11: error: Return type "I" of "h" incompatible with return type "A" in supertype "I"
main:11: error: Argument 1 of "h" is incompatible with supertype "I"; supertype defines the argument type as "I"
main:11: note: This violates the Liskov substitution principle
main:11: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides
main:11: error: Return type "I" of "h" incompatible with return type "A" in supertype "I"


-- Accessing abstract members
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-classes.test
Original file line number Diff line number Diff line change
Expand Up @@ -2626,10 +2626,10 @@ class D(A):
def __iadd__(self, x: 'A') -> 'B': pass
[out]
main:6: error: Return type "A" of "__iadd__" incompatible with return type "B" in "__add__" of supertype "A"
main:8: error: Signatures of "__iadd__" and "__add__" are incompatible
main:8: error: Argument 1 of "__iadd__" is incompatible with "__add__" of supertype "A"; supertype defines the argument type as "A"
main:8: note: This violates the Liskov substitution principle
main:8: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides
main:8: error: Signatures of "__iadd__" and "__add__" are incompatible

[case testGetattribute]

Expand Down
6 changes: 3 additions & 3 deletions test-data/unit/check-columns.test
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,9 @@ if int():
class A:
def f(self, x: int) -> None: pass
class B(A):
def f(self, x: str) -> None: pass # E:5: Argument 1 of "f" is incompatible with supertype "A"; supertype defines the argument type as "int" \
# N:5: This violates the Liskov substitution principle \
# N:5: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides
def f(self, x: str) -> None: pass # E:17: Argument 1 of "f" is incompatible with supertype "A"; supertype defines the argument type as "int" \
# N:17: This violates the Liskov substitution principle \
# N:17: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides
class C(A):
def f(self, x: int) -> int: pass # E:5: Return type "int" of "f" incompatible with return type "None" in supertype "A"
class D(A):
Expand Down
6 changes: 3 additions & 3 deletions test-data/unit/fine-grained-inspect.test
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ def foo(arg: T) -> T:
return arg
[out]
==
foo.py:7:1:arg
foo.py:7:9:arg
foo.py:4:5:x

[case testInspectTypeVarValuesDef]
Expand Down Expand Up @@ -219,7 +219,7 @@ class C(Generic[T]):
[out]
==
foo.py:5:5:z, tmp/foo.py:9:5:z
foo.py:12:1:arg
foo.py:12:9:arg
foo.py:5:5:z, tmp/foo.py:9:5:z

[case testInspectModuleAttrs]
Expand Down Expand Up @@ -266,4 +266,4 @@ def foo(arg: int) -> int:

[out]
==
4:12:4:14 -> tmp/foo.py:1:1:arg
4:12:4:14 -> tmp/foo.py:1:9:arg

0 comments on commit 1b607e4

Please sign in to comment.