Skip to content
Draft
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
21 changes: 3 additions & 18 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -3208,7 +3208,7 @@ def visit_assignment_stmt(self, s: AssignmentStmt) -> None:
# as X | Y.
if not (s.is_alias_def and self.is_stub):
with self.enter_final_context(s.is_final_def):
self.check_assignment(s.lvalues[-1], s.rvalue, s.type is None, s.new_syntax)
self.check_assignment(s.lvalues[-1], s.rvalue, s.type is None)

if s.is_alias_def:
self.check_type_alias_rvalue(s)
Expand Down Expand Up @@ -3256,11 +3256,7 @@ def check_type_alias_rvalue(self, s: AssignmentStmt) -> None:
self.store_type(s.lvalues[-1], alias_type)

def check_assignment(
self,
lvalue: Lvalue,
rvalue: Expression,
infer_lvalue_type: bool = True,
new_syntax: bool = False,
self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type: bool = True
) -> None:
"""Type check a single assignment: lvalue = rvalue."""
if isinstance(lvalue, (TupleExpr, ListExpr)):
Expand Down Expand Up @@ -3338,15 +3334,6 @@ def check_assignment(
# We are replacing partial<None> now, so the variable type
# should remain optional.
self.set_inferred_type(var, lvalue, make_optional_type(fallback))
elif (
is_literal_none(rvalue)
and isinstance(lvalue, NameExpr)
and isinstance(lvalue.node, Var)
and lvalue.node.is_initialized_in_class
and not new_syntax
):
# Allow None's to be assigned to class variables with non-Optional types.
rvalue_type = lvalue_type
elif (
isinstance(lvalue, MemberExpr) and lvalue.kind is None
): # Ignore member access to modules
Expand Down Expand Up @@ -5107,9 +5094,7 @@ def visit_operator_assignment_stmt(self, s: OperatorAssignmentStmt) -> None:
# There is no __ifoo__, treat as x = x <foo> y
expr = OpExpr(s.op, s.lvalue, s.rvalue)
expr.set_line(s)
self.check_assignment(
lvalue=s.lvalue, rvalue=expr, infer_lvalue_type=True, new_syntax=False
)
self.check_assignment(lvalue=s.lvalue, rvalue=expr, infer_lvalue_type=True)
self.check_final(s)

def visit_assert_stmt(self, s: AssertStmt) -> None:
Expand Down
2 changes: 1 addition & 1 deletion mypyc/test-data/irbuild-classes.test
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,7 @@ class B(A):
y = LOL
z: Optional[str] = None
b = True
bogus = None # type: int
bogus = None # type: int # type: ignore
[out]
def A.lol(self):
self :: __main__.A
Expand Down
2 changes: 1 addition & 1 deletion mypyc/test-data/run-classes.test
Original file line number Diff line number Diff line change
Expand Up @@ -1126,7 +1126,7 @@ class B(A):
y = LOL
z = None # type: Optional[str]
b = True
bogus = None # type: int
bogus = None # type: int # type: ignore

def g() -> None:
a = A()
Expand Down
3 changes: 2 additions & 1 deletion test-data/unit/check-optional.test
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,8 @@ class C:
[case testMultipleAssignmentNoneClassVariableInInit]
from typing import Optional
class C:
x, y = None, None # type: int, str
x, y = None, None # type: int, str # E: Incompatible types in assignment (expression has type "None", variable has type "int") \
# E: Incompatible types in assignment (expression has type "None", variable has type "str")
def __init__(self) -> None:
self.x = None # E: Incompatible types in assignment (expression has type "None", variable has type "int")
self.y = None # E: Incompatible types in assignment (expression has type "None", variable has type "str")
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/deps.test
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ class A:
from n import A

class B:
x = None # type: A
x = None # type: A # type: ignore
[file n.py]
class A: pass
[out]
Expand Down