Skip to content

Commit c6b40df

Browse files
authored
Prevent final reassignment in match case (#19496)
Fixes #19507 This PR adds a check to prevent reassignment of final variables in a match statement. Currently, the following passes without an error: ```Python from typing import Final FOO: Final = 8 a = 10 match a: case FOO: pass print(FOO) # FOO is reassigned, prints 10 ``` MyPy already checks that the type of FOO isn't changed if used like this. I added a check in the same place that makes sure it's not `Final` either. Since this tests the match syntax, I put the test where I did. If it's not the appropriate place for it I will move it as instructed :)
1 parent 31adfb4 commit c6b40df

File tree

2 files changed

+12
-0
lines changed

2 files changed

+12
-0
lines changed

mypy/checker.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5577,6 +5577,8 @@ def infer_variable_types_from_type_maps(
55775577
previous_type, _, _ = self.check_lvalue(expr)
55785578
if previous_type is not None:
55795579
already_exists = True
5580+
if isinstance(expr.node, Var) and expr.node.is_final:
5581+
self.msg.cant_assign_to_final(expr.name, False, expr)
55805582
if self.check_subtype(
55815583
typ,
55825584
previous_type,

test-data/unit/check-python310.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2839,3 +2839,13 @@ match value_type:
28392839
case _:
28402840
assert_never(value_type)
28412841
[builtins fixtures/tuple.pyi]
2842+
2843+
[case testAssignmentToFinalInMatchCaseNotAllowed]
2844+
from typing import Final
2845+
2846+
FOO: Final[int] = 10
2847+
2848+
val: int = 8
2849+
match val:
2850+
case FOO: # E: Cannot assign to final name "FOO"
2851+
pass

0 commit comments

Comments
 (0)