Skip to content

Commit 0b65f21

Browse files
Admit that Final variables are never redefined (#19083)
Fixes #19080. There is no point applying our heuristics if the variable is declared Final - it is not reassigned anywhere. --------- Co-authored-by: Shantanu <[email protected]>
1 parent 81f6285 commit 0b65f21

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

mypy/checker.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,10 @@ def is_var_redefined_in_outer_context(self, v: Var, after_line: int) -> bool:
15571557
Note that this doesn't do a full CFG analysis but uses a line number based
15581558
heuristic that isn't correct in some (rare) cases.
15591559
"""
1560+
if v.is_final:
1561+
# Final vars are definitely never reassigned.
1562+
return False
1563+
15601564
outers = self.tscope.outer_functions()
15611565
if not outers:
15621566
# Top-level function -- outer context is top level, and we can't reason about

test-data/unit/check-final.test

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,3 +1250,25 @@ def check_final_init() -> None:
12501250
new_instance = FinalInit()
12511251
new_instance.__init__()
12521252
[builtins fixtures/tuple.pyi]
1253+
1254+
[case testNarrowingOfFinalPersistsInFunctions]
1255+
from typing import Final, Union
1256+
1257+
def _init() -> Union[int, None]:
1258+
return 0
1259+
1260+
FOO: Final = _init()
1261+
1262+
class Example:
1263+
1264+
if FOO is not None:
1265+
reveal_type(FOO) # N: Revealed type is "builtins.int"
1266+
1267+
def fn(self) -> int:
1268+
return FOO
1269+
1270+
if FOO is not None:
1271+
reveal_type(FOO) # N: Revealed type is "builtins.int"
1272+
1273+
def func() -> int:
1274+
return FOO

0 commit comments

Comments
 (0)