From 4213b3c9a1d4ea7213636b67954dfbd95e290e91 Mon Sep 17 00:00:00 2001 From: Jacob Walls Date: Sun, 3 Apr 2022 09:18:21 -0400 Subject: [PATCH] Fix handling of "for x in x" homonyms (#6154) Co-authored-by: Pierre Sassoulas --- ChangeLog | 1 + pylint/checkers/variables.py | 7 +++++-- tests/functional/u/undefined/undefined_variable_py38.py | 2 +- tests/functional/u/undefined/undefined_variable_py38.txt | 1 - tests/functional/u/unused/unused_variable.py | 7 +++++++ 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 972b32afc1..a9027aa8eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,7 @@ Release date: TBA subscripts in comprehensions. Closes #6069 + Closes #6136 * Narrow the scope of the ``unnecessary-ellipsis`` checker to: * functions & classes which contain both a docstring and an ellipsis. diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index bbbb7eb576..ccc17f793e 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -2300,11 +2300,14 @@ def _check_is_unused( if global_names and _import_name_is_global(stmt, global_names): return + # Ignore names in comprehension targets + if name in comprehension_target_names: + return + argnames = node.argnames() # Care about functions with unknown argument (builtins) if name in argnames: - if name not in comprehension_target_names: - self._check_unused_arguments(name, node, stmt, argnames, nonlocal_names) + self._check_unused_arguments(name, node, stmt, argnames, nonlocal_names) else: if stmt.parent and isinstance( stmt.parent, (nodes.Assign, nodes.AnnAssign, nodes.Tuple) diff --git a/tests/functional/u/undefined/undefined_variable_py38.py b/tests/functional/u/undefined/undefined_variable_py38.py index 01e0201a81..93ba1eb2ba 100644 --- a/tests/functional/u/undefined/undefined_variable_py38.py +++ b/tests/functional/u/undefined/undefined_variable_py38.py @@ -123,7 +123,7 @@ def type_annotation_used_after_comprehension(): def type_annotation_unused_after_comprehension(): """https://github.com/PyCQA/pylint/issues/5326""" - my_int: int # [unused-variable] + my_int: int _ = [print(sep=my_int, end=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 4cce67ecc6..e912cbbf98 100644 --- a/tests/functional/u/undefined/undefined_variable_py38.txt +++ b/tests/functional/u/undefined/undefined_variable_py38.txt @@ -2,7 +2,6 @@ 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':INFERENCE undefined-variable:99:6:99:19::Undefined variable 'else_assign_2':INFERENCE -unused-variable:126:4:126:10:type_annotation_unused_after_comprehension:Unused variable 'my_int':UNDEFINED used-before-assignment:134:10:134:16:type_annotation_used_improperly_after_comprehension:Using variable 'my_int' before assignment:HIGH used-before-assignment:141:10:141:16:type_annotation_used_improperly_after_comprehension_2:Using variable 'my_int' before assignment:HIGH used-before-assignment:171:12:171:16:expression_in_ternary_operator_inside_container_wrong_position:Using variable 'val3' before assignment:HIGH diff --git a/tests/functional/u/unused/unused_variable.py b/tests/functional/u/unused/unused_variable.py index d5afd8f2bb..d037a386ee 100644 --- a/tests/functional/u/unused/unused_variable.py +++ b/tests/functional/u/unused/unused_variable.py @@ -172,3 +172,10 @@ def main(lst): print(e) # [undefined-loop-variable] main([]) + + +def func5(): + """No unused-variable for a container if iterated in comprehension""" + x = [] + # Test case requires homonym between "for x" and "in x" + assert [True for x in x]