From bc9f15fda2e85facb230b3372cddb9ae40b4f3d5 Mon Sep 17 00:00:00 2001 From: Jacob Walls Date: Mon, 12 Dec 2022 03:23:25 -0500 Subject: [PATCH] Prevent `used-before-assignment` in pattern matching with a guard (#7922) --- doc/whatsnew/fragments/5327.false_positive | 4 ++++ pylint/checkers/variables.py | 3 +++ tests/functional/u/used/used_before_assignment_py310.py | 7 +++++++ tests/functional/u/used/used_before_assignment_py310.rc | 2 ++ 4 files changed, 16 insertions(+) create mode 100644 doc/whatsnew/fragments/5327.false_positive create mode 100644 tests/functional/u/used/used_before_assignment_py310.py create mode 100644 tests/functional/u/used/used_before_assignment_py310.rc diff --git a/doc/whatsnew/fragments/5327.false_positive b/doc/whatsnew/fragments/5327.false_positive new file mode 100644 index 0000000000..0cac649f80 --- /dev/null +++ b/doc/whatsnew/fragments/5327.false_positive @@ -0,0 +1,4 @@ +Fix false-positive for ``used-before-assignment`` in pattern matching +with a guard. + +Closes #5327 diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index 58a2216c0b..602dd54141 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -2139,6 +2139,7 @@ def _is_variable_violation( nodes.AugAssign, nodes.Expr, nodes.Return, + nodes.Match, ), ) and VariablesChecker._maybe_used_and_assigned_at_once(defstmt) @@ -2239,6 +2240,8 @@ def _maybe_used_and_assigned_at_once(defstmt: nodes.Statement) -> bool: """Check if `defstmt` has the potential to use and assign a name in the same statement. """ + if isinstance(defstmt, nodes.Match): + return any(case.guard for case in defstmt.cases) if isinstance(defstmt.value, nodes.BaseContainer) and defstmt.value.elts: # The assignment must happen as part of the first element # e.g. "assert (x:= True), x" diff --git a/tests/functional/u/used/used_before_assignment_py310.py b/tests/functional/u/used/used_before_assignment_py310.py new file mode 100644 index 0000000000..14f46b61e9 --- /dev/null +++ b/tests/functional/u/used/used_before_assignment_py310.py @@ -0,0 +1,7 @@ +"""Tests for used-before-assignment with python 3.10's pattern matching""" + +match ("example", "one"): + case (x, y) if x == "example": + print("x used to cause used-before-assignment!") + case _: + print("good thing it doesn't now!") diff --git a/tests/functional/u/used/used_before_assignment_py310.rc b/tests/functional/u/used/used_before_assignment_py310.rc new file mode 100644 index 0000000000..68a8c8ef15 --- /dev/null +++ b/tests/functional/u/used/used_before_assignment_py310.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.10