diff --git a/doc/whatsnew/fragments/7222.bugfix b/doc/whatsnew/fragments/7222.bugfix new file mode 100644 index 00000000000..0d18e73da4a --- /dev/null +++ b/doc/whatsnew/fragments/7222.bugfix @@ -0,0 +1,3 @@ +Fix `undefined-loop-variable` from walrus in comprehension test. + +Closes #7222 diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index e6af22689bf..27d3d7b17e6 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -2249,6 +2249,22 @@ def _loopvar_name(self, node: astroid.Name) -> None: ): return + maybe_walrus = utils.get_node_first_ancestor_of_type(node, nodes.NamedExpr) + if maybe_walrus: + maybe_comprehension = utils.get_node_first_ancestor_of_type( + maybe_walrus, nodes.Comprehension + ) + if maybe_comprehension: + comprehension_scope = utils.get_node_first_ancestor_of_type( + maybe_comprehension, nodes.ComprehensionScope + ) + assert comprehension_scope is not None + if ( + comprehension_scope.parent.scope() is scope + and node.name in comprehension_scope.locals + ): + return + # For functions we can do more by inferring the length of the itered object try: inferred = next(assign.iter.infer()) diff --git a/tests/functional/u/undefined/undefined_loop_variable_py38.py b/tests/functional/u/undefined/undefined_loop_variable_py38.py new file mode 100644 index 00000000000..fad10291b96 --- /dev/null +++ b/tests/functional/u/undefined/undefined_loop_variable_py38.py @@ -0,0 +1,5 @@ +def walrus_in_comprehension_test(container): + """https://github.com/PyCQA/pylint/issues/7222""" + for something in container: + print(something) + print([my_test for something in container if (my_test := something)])