diff --git a/ChangeLog b/ChangeLog index 72ac6c80e6..6bb04cc7a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -353,6 +353,10 @@ Release date: TBA Closes #6539 +* Fix a false positive for ``undefined-loop-variable`` when using ``enumerate()``. + + Closes #6593 + What's New in Pylint 2.13.8? ============================ diff --git a/doc/whatsnew/2.13.rst b/doc/whatsnew/2.13.rst index fd5ce73f6f..0f3ca0b24b 100644 --- a/doc/whatsnew/2.13.rst +++ b/doc/whatsnew/2.13.rst @@ -661,3 +661,7 @@ Other Changes * Fix a crash in ``unnecessary-dict-index-lookup`` when subscripting an attribute. Closes #6557 + +* Fix a false positive for ``undefined-loop-variable`` when using ``enumerate()``. + + Closes #6593 diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index cc103e894a..16bd11b53a 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -2220,6 +2220,13 @@ def _loopvar_name(self, node: astroid.Name) -> None: # For functions we can do more by inferring the length of the itered object try: inferred = next(assign.iter.infer()) + # Prefer the target of enumerate() rather than the enumerate object itself + if ( + isinstance(inferred, astroid.Instance) + and inferred.qname() == "builtins.enumerate" + and assign.iter.args + ): + inferred = next(assign.iter.args[0].infer()) except astroid.InferenceError: self.add_message("undefined-loop-variable", args=node.name, node=node) else: diff --git a/tests/functional/u/undefined/undefined_loop_variable.py b/tests/functional/u/undefined/undefined_loop_variable.py index b34635c88a..fc8640f7a0 100644 --- a/tests/functional/u/undefined/undefined_loop_variable.py +++ b/tests/functional/u/undefined/undefined_loop_variable.py @@ -139,3 +139,10 @@ def variable_name_assigned_in_body_of_second_loop(): alias = True if alias: print(alias) + + +def use_enumerate(): + """https://github.com/PyCQA/pylint/issues/6593""" + for i, num in enumerate(range(3)): + pass + print(i, num)