diff --git a/ChangeLog b/ChangeLog index 2bf37a089a..d045358385 100644 --- a/ChangeLog +++ b/ChangeLog @@ -80,6 +80,11 @@ Release date: TBA Closes #5461 +* Fix false positive for ``unused-variable`` for a comprehension variable matching + an outer scope type annotation. + + Closes #5326 + * Some files in ``pylint.testutils`` were deprecated. In the future imports should be done from the ``pylint.testutils.functional`` namespace directly. diff --git a/doc/whatsnew/2.13.rst b/doc/whatsnew/2.13.rst index c1b5922378..ec65a5c902 100644 --- a/doc/whatsnew/2.13.rst +++ b/doc/whatsnew/2.13.rst @@ -116,6 +116,11 @@ Other Changes Closes #5461 +* Fix false positive for ``unused-variable`` for a comprehension variable matching + an outer scope type annotation. + + Closes #5326 + * Require Python ``3.6.2`` to run pylint. Closes #5065 diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index ae01a65d18..a95b2167d8 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -1803,7 +1803,7 @@ def _is_only_type_assignment(node: nodes.Name, defstmt: nodes.Statement) -> bool # Local refs are ordered, so we break. # print(var) # var = 1 # <- irrelevant - if defstmt_frame == node_frame and not ref_node.lineno < node.lineno: + if defstmt_frame == node_frame and ref_node.lineno > node.lineno: break # If the parent of the local reference is anything but an AnnAssign diff --git a/tests/functional/u/undefined/undefined_variable_py38.py b/tests/functional/u/undefined/undefined_variable_py38.py index 81fa19f527..4ecc251336 100644 --- a/tests/functional/u/undefined/undefined_variable_py38.py +++ b/tests/functional/u/undefined/undefined_variable_py38.py @@ -11,10 +11,10 @@ def typing_and_assignment_expression(): print(var) -def typing_and_self_referncing_assignment_expression(): +def typing_and_self_referencing_assignment_expression(): """The variable gets assigned in an assignment expression that references itself""" var: int - if (var := var ** 2): # [undefined-variable] + if (var := var ** 2): # false negative--walrus operator! print(var) @@ -108,3 +108,20 @@ def no_parameters_in_function_default() -> None: if (x_0 := thing.this_value) < (x_1 := thing.that_value) else x_1, ) + + +# Tests for type annotation reused in comprehension + +def type_annotation_used_after_comprehension(): + """https://github.com/PyCQA/pylint/issues/5326#issuecomment-982635371""" + my_int: int + ints = [my_int + 1 for my_int in range(5)] + + for my_int in ints: + print(my_int) + + +def type_annotation_unused_after_comprehension(): + """https://github.com/PyCQA/pylint/issues/5326""" + my_int: int + _ = [print(kwarg1=my_int, kwarg2=my_int) for my_int in range(10)] diff --git a/tests/functional/u/undefined/undefined_variable_py38.txt b/tests/functional/u/undefined/undefined_variable_py38.txt index 6d7035ee11..da69ce0099 100644 --- a/tests/functional/u/undefined/undefined_variable_py38.txt +++ b/tests/functional/u/undefined/undefined_variable_py38.txt @@ -1,4 +1,3 @@ -undefined-variable:17:15:17:18:typing_and_self_referncing_assignment_expression:Undefined variable 'var':UNDEFINED undefined-variable:42:6:42:16::Undefined variable 'no_default':UNDEFINED undefined-variable:50:6:50:22::Undefined variable 'again_no_default':UNDEFINED undefined-variable:76:6:76:19::Undefined variable 'else_assign_1':UNDEFINED