Skip to content

Commit c3e32e3

Browse files
authored
Fix crash on redefined class variable annotated with Final[<type>] (#12951)
1 parent 7e38877 commit c3e32e3

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

mypy/checker.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2715,13 +2715,14 @@ def check_final(self,
27152715
if is_final_decl and self.scope.active_class():
27162716
lv = lvs[0]
27172717
assert isinstance(lv, RefExpr)
2718-
assert isinstance(lv.node, Var)
2719-
if (lv.node.final_unset_in_class and not lv.node.final_set_in_init and
2720-
not self.is_stub and # It is OK to skip initializer in stub files.
2721-
# Avoid extra error messages, if there is no type in Final[...],
2722-
# then we already reported the error about missing r.h.s.
2723-
isinstance(s, AssignmentStmt) and s.type is not None):
2724-
self.msg.final_without_value(s)
2718+
if lv.node is not None:
2719+
assert isinstance(lv.node, Var)
2720+
if (lv.node.final_unset_in_class and not lv.node.final_set_in_init and
2721+
not self.is_stub and # It is OK to skip initializer in stub files.
2722+
# Avoid extra error messages, if there is no type in Final[...],
2723+
# then we already reported the error about missing r.h.s.
2724+
isinstance(s, AssignmentStmt) and s.type is not None):
2725+
self.msg.final_without_value(s)
27252726
for lv in lvs:
27262727
if isinstance(lv, RefExpr) and isinstance(lv.node, Var):
27272728
name = lv.node.name

test-data/unit/check-final.test

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,3 +1109,11 @@ class A(ABC):
11091109
@final # E: Method B is both abstract and final
11101110
@abstractmethod
11111111
def B(self) -> None: ...
1112+
1113+
[case testFinalClassVariableRedefinitionDoesNotCrash]
1114+
# This used to crash -- see #12950
1115+
from typing import Final
1116+
1117+
class MyClass:
1118+
a: None
1119+
a: Final[int] = 1 # E: Cannot redefine an existing name as final # E: Name "a" already defined on line 5

0 commit comments

Comments
 (0)