Skip to content

Point incompatible assignment errors to rvalue instead of lvalue #7569

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

Merged
merged 3 commits into from
Sep 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -1986,7 +1986,7 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type
new_syntax: bool = False) -> None:
"""Type check a single assignment: lvalue = rvalue."""
if isinstance(lvalue, TupleExpr) or isinstance(lvalue, ListExpr):
self.check_assignment_to_multiple_lvalues(lvalue.items, rvalue, lvalue,
self.check_assignment_to_multiple_lvalues(lvalue.items, rvalue, rvalue,
infer_lvalue_type)
else:
lvalue_type, index_lvalue, inferred = self.check_lvalue(lvalue)
Expand Down Expand Up @@ -2056,9 +2056,9 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type
lvalue.kind is None): # Ignore member access to modules
instance_type = self.expr_checker.accept(lvalue.expr)
rvalue_type, lvalue_type, infer_lvalue_type = self.check_member_assignment(
instance_type, lvalue_type, rvalue, lvalue)
instance_type, lvalue_type, rvalue, context=rvalue)
else:
rvalue_type = self.check_simple_assignment(lvalue_type, rvalue, lvalue,
rvalue_type = self.check_simple_assignment(lvalue_type, rvalue, context=rvalue,
code=codes.ASSIGNMENT)

# Special case: only non-abstract non-protocol classes can be assigned to
Expand Down Expand Up @@ -2196,7 +2196,7 @@ def check_compatibility_super(self, lvalue: RefExpr, lvalue_type: Optional[Type]
if base_static and compare_static:
lvalue_node.is_staticmethod = True

return self.check_subtype(compare_type, base_type, lvalue,
return self.check_subtype(compare_type, base_type, rvalue,
message_registry.INCOMPATIBLE_TYPES_IN_ASSIGNMENT,
'expression has type',
'base class "%s" defined the type as' % base.name(),
Expand Down
5 changes: 4 additions & 1 deletion mypy/fastparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -729,11 +729,14 @@ def visit_Assign(self, n: ast3.Assign) -> AssignmentStmt:

# AnnAssign(expr target, expr annotation, expr? value, int simple)
def visit_AnnAssign(self, n: ast3.AnnAssign) -> AssignmentStmt:
line = n.lineno
if n.value is None: # always allow 'x: int'
rvalue = TempNode(AnyType(TypeOfAny.special_form), no_rhs=True) # type: Expression
rvalue.line = line
rvalue.column = n.col_offset
else:
rvalue = self.visit(n.value)
typ = TypeConverter(self.errors, line=n.lineno).visit(n.annotation)
typ = TypeConverter(self.errors, line=line).visit(n.annotation)
assert typ is not None
typ.column = n.annotation.col_offset
s = AssignmentStmt([self.visit(n.target)], rvalue, type=typ, new_syntax=True)
Expand Down
42 changes: 34 additions & 8 deletions test-data/unit/check-columns.test
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,44 @@ y = 'hello'
if int():
x = 2; y = x; y += 1
[out]
main:4:12: error: Incompatible types in assignment (expression has type "int", variable has type "str")
main:4:16: error: Incompatible types in assignment (expression has type "int", variable has type "str")
main:4:24: error: Unsupported operand types for + ("str" and "int")

[case testColumnsAssignment]
class A:
x = 0

A().x = '' # E:9: Incompatible types in assignment (expression has type "str", variable has type "int")
a = [0]
a[0] = '' # E:8: Incompatible types in assignment (expression has type "str", target has type "int")
b = 0
c = 0
b, c = 0, '' # E:11: Incompatible types in assignment (expression has type "str", variable has type "int")
b, c = '', 0 # E:8: Incompatible types in assignment (expression has type "str", variable has type "int")

t = 0, ''
b, c = t # E:8: Incompatible types in assignment (expression has type "str", variable has type "int")

class B(A):
x = '' # E:9: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int")
[builtins fixtures/list.pyi]

[case testColumnsAttributeIncompatibleWithBaseClassUsingAnnotation]
class A:
x: str

class B(A):
x: int # E:5: Incompatible types in assignment (expression has type "int", base class "A" defined the type as "str")

[case testColumnsSimpleIsinstance]
import typing
def f(x: object, n: int, s: str) -> None:
if int():
n = x # E:9: Incompatible types in assignment (expression has type "object", variable has type "int")
n = x # E:13: Incompatible types in assignment (expression has type "object", variable has type "int")
if isinstance(x, int):
n = x
s = x # E:13: Incompatible types in assignment (expression has type "int", variable has type "str")
n = x # E:9: Incompatible types in assignment (expression has type "object", variable has type "int")
s = x # E:17: Incompatible types in assignment (expression has type "int", variable has type "str")
n = x # E:13: Incompatible types in assignment (expression has type "object", variable has type "int")
[builtins fixtures/isinstance.pyi]

[case testColumnHasNoAttribute]
Expand Down Expand Up @@ -247,9 +273,9 @@ class C:

p: P
if int():
p = C() # E:5: Incompatible types in assignment (expression has type "C", variable has type "P") \
# N:5: 'C' is missing following 'P' protocol member: \
# N:5: y
p = C() # E:9: Incompatible types in assignment (expression has type "C", variable has type "P") \
# N:9: 'C' is missing following 'P' protocol member: \
# N:9: y

[case testColumnRedundantCast]
# flags: --warn-redundant-casts
Expand Down Expand Up @@ -354,6 +380,6 @@ def f(x: T) -> T:
# XXX: Disabled because the column differs in 3.8
# aa: List[int] = ['' for x in [1]] # :22: List comprehension has incompatible type List[str]; expected List[int]
cc = (1).bad # E:11: "int" has no attribute "bad"
n: int = '' # E:5: Incompatible types in assignment (expression has type "str", variable has type "int")
n: int = '' # E:14: Incompatible types in assignment (expression has type "str", variable has type "int")
return x
[builtins fixtures/list.pyi]
4 changes: 2 additions & 2 deletions test-data/unit/check-inference-context.test
Original file line number Diff line number Diff line change
Expand Up @@ -656,10 +656,10 @@ f = lambda x: A() # type: Callable[[], A]
f2 = lambda: A() # type: Callable[[A], A]
class A: pass
[out]
main:2: error: Incompatible types in assignment (expression has type "Callable[[Any], A]", variable has type "Callable[[], A]")
main:2: error: Cannot infer type of lambda
main:3: error: Incompatible types in assignment (expression has type "Callable[[], A]", variable has type "Callable[[A], A]")
main:2: error: Incompatible types in assignment (expression has type "Callable[[Any], A]", variable has type "Callable[[], A]")
main:3: error: Cannot infer type of lambda
main:3: error: Incompatible types in assignment (expression has type "Callable[[], A]", variable has type "Callable[[A], A]")

[case testEllipsisContextForLambda]
from typing import Callable
Expand Down
5 changes: 3 additions & 2 deletions test-data/unit/check-literal.test
Original file line number Diff line number Diff line change
Expand Up @@ -2582,8 +2582,9 @@ class Foo:
self.instancevar3: Final[Literal[False]] = True # E: Incompatible types in assignment (expression has type "Literal[True]", variable has type "Literal[False]")

# TODO: Fix the order in which these error messages are shown to be more consistent.
var1 = 10 # E: Incompatible types in assignment (expression has type "Literal[10]", variable has type "Literal[4]") \
# E: Cannot assign to final name "var1"
var1 = 10 # E: Cannot assign to final name "var1" \
# E: Incompatible types in assignment (expression has type "Literal[10]", variable has type "Literal[4]")


Foo.classvar1 = 10 # E: Cannot assign to final attribute "classvar1" \
# E: Incompatible types in assignment (expression has type "Literal[10]", variable has type "Literal[4]")
Expand Down
4 changes: 2 additions & 2 deletions test-data/unit/cmdline.test
Original file line number Diff line number Diff line change
Expand Up @@ -1408,8 +1408,8 @@ some_file.py:3: error: Unsupported operand types for + ("int" and "str")
^
some_file.py:11: error: Incompatible types in assignment (expression has type
"AnotherCustomClassDefinedBelow", variable has type "OneCustomClassName")
self.very_important_attribute_with_long_name: OneCustomClassNa...
^
...t_attribute_with_long_name: OneCustomClassName = OneCustomClassName()....
^
some_file.py:11: error: Argument 1 to "some_interesting_method" of
"OneCustomClassName" has incompatible type "Union[int, str, float]"; expected
"AnotherCustomClassDefinedBelow"
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/semanal-typeddict.test
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,6 @@ MypyFile:1(
StrExpr(foo))
AssignmentStmt:4(
NameExpr(x)
TempNode:-1(
TempNode:4(
Any)
str?)))
4 changes: 2 additions & 2 deletions test-data/unit/semenal-literal.test
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ MypyFile:1(
ImportFrom:1(typing_extensions, [Literal])
AssignmentStmt:2(
NameExpr(foo [__main__.foo])
TempNode:-1(
TempNode:2(
Any)
Literal[3]))

[case testLiteralSemenalInFunction]
[case testLiteralSemanalInFunction]
from typing_extensions import Literal
def foo(a: Literal[1], b: Literal[" foo "]) -> Literal[True]: pass
[builtins fixtures/bool.pyi]
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy