Skip to content

Commit aed496a

Browse files
github-actions[bot]jacobtylerwallsPierre-Sassoulas
authored
Fix FP for possibly-used-before-assignment with assert_never() (#9645) (#9647)
(cherry picked from commit 117be95) Co-authored-by: Jacob Walls <jacobtylerwalls@gmail.com> Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
1 parent 9dae975 commit aed496a

File tree

5 files changed

+38
-7
lines changed

5 files changed

+38
-7
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix a false positive for `possibly-used-before-assignment` when using
2+
`typing.assert_never()` (3.11+) to indicate exhaustiveness.
3+
4+
Closes #9643

pylint/checkers/variables.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
is_sys_guard,
3333
overridden_method,
3434
)
35-
from pylint.constants import PY39_PLUS, TYPING_NEVER, TYPING_NORETURN
35+
from pylint.constants import PY39_PLUS, PY311_PLUS, TYPING_NEVER, TYPING_NORETURN
3636
from pylint.interfaces import CONTROL_FLOW, HIGH, INFERENCE, INFERENCE_FAILURE
3737
from pylint.typing import MessageDefinitionTuple
3838

@@ -940,12 +940,15 @@ def _uncertain_nodes_in_except_blocks(
940940
def _defines_name_raises_or_returns(name: str, node: nodes.NodeNG) -> bool:
941941
if isinstance(node, (nodes.Raise, nodes.Assert, nodes.Return, nodes.Continue)):
942942
return True
943-
if (
944-
isinstance(node, nodes.Expr)
945-
and isinstance(node.value, nodes.Call)
946-
and utils.is_terminating_func(node.value)
947-
):
948-
return True
943+
if isinstance(node, nodes.Expr) and isinstance(node.value, nodes.Call):
944+
if utils.is_terminating_func(node.value):
945+
return True
946+
if (
947+
PY311_PLUS
948+
and isinstance(node.value.func, nodes.Name)
949+
and node.value.func.name == "assert_never"
950+
):
951+
return True
949952
if (
950953
isinstance(node, nodes.AnnAssign)
951954
and node.value

pylint/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
PY38_PLUS = sys.version_info[:2] >= (3, 8)
1818
PY39_PLUS = sys.version_info[:2] >= (3, 9)
1919
PY310_PLUS = sys.version_info[:2] >= (3, 10)
20+
PY311_PLUS = sys.version_info[:2] >= (3, 11)
2021
PY312_PLUS = sys.version_info[:2] >= (3, 12)
2122

2223
IS_PYPY = platform.python_implementation() == "PyPy"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""assert_never() introduced in 3.11"""
2+
from enum import Enum
3+
from typing import assert_never
4+
5+
6+
class MyEnum(Enum):
7+
"""A lovely enum."""
8+
VAL1 = 1
9+
VAL2 = 2
10+
11+
12+
def do_thing(val: MyEnum) -> None:
13+
"""Do a thing."""
14+
if val is MyEnum.VAL1:
15+
note = 'got 1'
16+
elif val is MyEnum.VAL2:
17+
note = 'got 2'
18+
else:
19+
assert_never(val)
20+
21+
print('Note:', note)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[testoptions]
2+
min_pyver=3.11

0 commit comments

Comments
 (0)