Skip to content

Commit 10ea945

Browse files
authored
Prevent assignment to None for non-Optional class variables (python#20054)
Python 3.5 has been dead for a long time. This is just a correct thing to do.
1 parent e7f6044 commit 10ea945

5 files changed

Lines changed: 8 additions & 22 deletions

File tree

mypy/checker.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3283,7 +3283,7 @@ def visit_assignment_stmt(self, s: AssignmentStmt) -> None:
32833283
# as X | Y.
32843284
if not (s.is_alias_def and self.is_stub):
32853285
with self.enter_final_context(s.is_final_def):
3286-
self.check_assignment(s.lvalues[-1], s.rvalue, s.type is None, s.new_syntax)
3286+
self.check_assignment(s.lvalues[-1], s.rvalue, s.type is None)
32873287

32883288
if s.is_alias_def:
32893289
self.check_type_alias_rvalue(s)
@@ -3331,11 +3331,7 @@ def check_type_alias_rvalue(self, s: AssignmentStmt) -> None:
33313331
self.store_type(s.lvalues[-1], alias_type)
33323332

33333333
def check_assignment(
3334-
self,
3335-
lvalue: Lvalue,
3336-
rvalue: Expression,
3337-
infer_lvalue_type: bool = True,
3338-
new_syntax: bool = False,
3334+
self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type: bool = True
33393335
) -> None:
33403336
"""Type check a single assignment: lvalue = rvalue."""
33413337
if isinstance(lvalue, (TupleExpr, ListExpr)):
@@ -3413,15 +3409,6 @@ def check_assignment(
34133409
# We are replacing partial<None> now, so the variable type
34143410
# should remain optional.
34153411
self.set_inferred_type(var, lvalue, make_optional_type(fallback))
3416-
elif (
3417-
is_literal_none(rvalue)
3418-
and isinstance(lvalue, NameExpr)
3419-
and isinstance(lvalue.node, Var)
3420-
and lvalue.node.is_initialized_in_class
3421-
and not new_syntax
3422-
):
3423-
# Allow None's to be assigned to class variables with non-Optional types.
3424-
rvalue_type = lvalue_type
34253412
elif (
34263413
isinstance(lvalue, MemberExpr) and lvalue.kind is None
34273414
): # Ignore member access to modules
@@ -5303,9 +5290,7 @@ def visit_operator_assignment_stmt(self, s: OperatorAssignmentStmt) -> None:
53035290
# There is no __ifoo__, treat as x = x <foo> y
53045291
expr = OpExpr(s.op, s.lvalue, s.rvalue)
53055292
expr.set_line(s)
5306-
self.check_assignment(
5307-
lvalue=s.lvalue, rvalue=expr, infer_lvalue_type=True, new_syntax=False
5308-
)
5293+
self.check_assignment(lvalue=s.lvalue, rvalue=expr, infer_lvalue_type=True)
53095294
self.check_final(s)
53105295

53115296
def visit_assert_stmt(self, s: AssertStmt) -> None:

mypyc/test-data/irbuild-classes.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,7 @@ class B(A):
10571057
y = LOL
10581058
z: Optional[str] = None
10591059
b = True
1060-
bogus = None # type: int
1060+
bogus = None # type: int # type: ignore
10611061
[out]
10621062
def A.lol(self):
10631063
self :: __main__.A

mypyc/test-data/run-classes.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1159,7 +1159,7 @@ class B(A):
11591159
y = LOL
11601160
z = None # type: Optional[str]
11611161
b = True
1162-
bogus = None # type: int
1162+
bogus = None # type: int # type: ignore
11631163

11641164
def g() -> None:
11651165
a = A()

test-data/unit/check-optional.test

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,8 @@ class C:
236236
[case testMultipleAssignmentNoneClassVariableInInit]
237237
from typing import Optional
238238
class C:
239-
x, y = None, None # type: int, str
239+
x, y = None, None # type: int, str # E: Incompatible types in assignment (expression has type "None", variable has type "int") \
240+
# E: Incompatible types in assignment (expression has type "None", variable has type "str")
240241
def __init__(self) -> None:
241242
self.x = None # E: Incompatible types in assignment (expression has type "None", variable has type "int")
242243
self.y = None # E: Incompatible types in assignment (expression has type "None", variable has type "str")

test-data/unit/deps.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ class A:
516516
from n import A
517517

518518
class B:
519-
x = None # type: A
519+
x = None # type: A # type: ignore
520520
[file n.py]
521521
class A: pass
522522
[out]

0 commit comments

Comments
 (0)