From 44b8e6c79d10a89c6db4ab742047f7e83498e6cf Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Wed, 7 Apr 2021 00:37:16 +0200 Subject: [PATCH] Fix false-positive used-before-assignment in function returns --- ChangeLog | 4 ++++ pylint/checkers/variables.py | 7 +++++- tests/functional/a/assignment_expression.py | 25 +++++++++++++------- tests/functional/a/assignment_expression.txt | 7 +++--- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 354e0ea0da..92d6fef5a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,10 @@ Release date: Undefined only contain ``__version__`` (also accessible with ``pylint.__version__``), other meta-information are still accessible with ``import importlib;metadata.metadata('pylint')``. +* Fix false-positive ``used-before-assignment`` in function returns. + + Closes #4301 + What's New in Pylint 2.7.5? =========================== diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index 3ad0ab8837..66bd4fdd47 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -1457,7 +1457,12 @@ def _is_variable_violation( and defnode.lineno == node.lineno and isinstance( defstmt, - (astroid.Assign, astroid.AnnAssign, astroid.AugAssign), + ( + astroid.Assign, + astroid.AnnAssign, + astroid.AugAssign, + astroid.Return, + ), ) and isinstance(defstmt.value, astroid.JoinedStr) ) diff --git a/tests/functional/a/assignment_expression.py b/tests/functional/a/assignment_expression.py index aa6a27874f..a2a586e536 100644 --- a/tests/functional/a/assignment_expression.py +++ b/tests/functional/a/assignment_expression.py @@ -1,5 +1,6 @@ """Test assignment expressions""" -# pylint: disable=missing-docstring,unused-argument,unused-import,invalid-name,blacklisted-name,unused-variable +# pylint: disable=missing-docstring,unused-argument,unused-import,invalid-name +# pylint: disable=blacklisted-name,unused-variable,pointless-statement import re if (a := True): @@ -16,6 +17,15 @@ c = [text for el in a if (text := el.strip()) == "b"] +# check wrong usage +assert err_a, (err_a := 2) # [used-before-assignment] +print(err_b and (err_b := 2)) # [used-before-assignment] +values = ( + err_c := err_d, # [used-before-assignment] + err_d := 2, +) + + # https://github.com/PyCQA/pylint/issues/3347 s = 'foo' if (fval := lambda: 1) is None else fval @@ -53,7 +63,7 @@ def func(): # https://github.com/PyCQA/pylint/issues/3763 -foo if (foo := 3 - 2) > 0 else 0 # [pointless-statement] +foo if (foo := 3 - 2) > 0 else 0 # https://github.com/PyCQA/pylint/issues/4238 @@ -70,10 +80,7 @@ def func(): ) -# check wrong usage -assert err_a, (err_a := 2) # [used-before-assignment] -print(err_b and (err_b := 2)) # [used-before-assignment] -values = ( - err_c := err_d, # [used-before-assignment] - err_d := 2, -) +# https://github.com/PyCQA/pylint/issues/4301 +def func2(): + return f'The number {(count := 4)} ' \ + f'is equal to {count}' diff --git a/tests/functional/a/assignment_expression.txt b/tests/functional/a/assignment_expression.txt index 1be4c1389d..c4b8da483c 100644 --- a/tests/functional/a/assignment_expression.txt +++ b/tests/functional/a/assignment_expression.txt @@ -1,4 +1,3 @@ -pointless-statement:56:0::Statement seems to have no effect -used-before-assignment:74:7::Using variable 'err_a' before assignment -used-before-assignment:75:6::Using variable 'err_b' before assignment -used-before-assignment:77:13::Using variable 'err_d' before assignment +used-before-assignment:21:7::Using variable 'err_a' before assignment +used-before-assignment:22:6::Using variable 'err_b' before assignment +used-before-assignment:24:13::Using variable 'err_d' before assignment