diff options
author | Jacob Walls <jacobtylerwalls@gmail.com> | 2022-05-01 09:56:08 -0400 |
---|---|---|
committer | Pierre Sassoulas <pierre.sassoulas@gmail.com> | 2022-05-02 16:38:19 +0200 |
commit | 135477af5331f11981d1ffeb3b4adc3a6878669a (patch) | |
tree | 8f10f70e1f8c4646c9cf13a20c46f688e05bee01 | |
parent | 33a9aba4321f4b3fef8e9aefcfc9aa10abed1836 (diff) | |
download | pylint-git-135477af5331f11981d1ffeb3b4adc3a6878669a.tar.gz |
Fix a false positive for `undefined-loop-variable` when a loop else raises or returns (#6480)
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | doc/whatsnew/2.13.rst | 5 | ||||
-rw-r--r-- | pylint/checkers/variables.py | 8 | ||||
-rw-r--r-- | tests/functional/u/undefined/undefined_loop_variable.py | 16 |
4 files changed, 33 insertions, 1 deletions
@@ -34,6 +34,11 @@ Release date: TBA Closes #5930 +* Fix a false positive for ``undefined-loop-variable`` when the ``else`` of a ``for`` + loop raises or returns. + + Closes #5971 + * Fix false positive for ``unused-variable`` for classes inside functions and where a metaclass is provided via a call. diff --git a/doc/whatsnew/2.13.rst b/doc/whatsnew/2.13.rst index 1d86a6fd9..5f3c86673 100644 --- a/doc/whatsnew/2.13.rst +++ b/doc/whatsnew/2.13.rst @@ -607,6 +607,11 @@ Other Changes Closes #5769 +* Fix a false positive for ``undefined-loop-variable`` when the ``else`` of a ``for`` + loop raises or returns. + + Closes #5971 + * Fix false positive for ``unused-variable`` for classes inside functions and where a metaclass is provided via a call. diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index 2e4f4d70f..807e031e6 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -2207,6 +2207,7 @@ class VariablesChecker(BaseChecker): scope = node.scope() # FunctionDef subclasses Lambda due to a curious ontology. Check both. # See https://github.com/PyCQA/astroid/issues/291 + # pylint: disable-next=fixme # TODO: Revisit when astroid 3.0 includes the change if isinstance(scope, nodes.Lambda) and any( asmt.scope().parent_of(scope) for asmt in astmts @@ -2252,11 +2253,16 @@ class VariablesChecker(BaseChecker): ): return - # For functions we can do more by inferring the length of the itered object if not isinstance(assign, nodes.For): self.add_message("undefined-loop-variable", args=node.name, node=node) return + if any( + isinstance(else_stmt, (nodes.Return, nodes.Raise)) + for else_stmt in assign.orelse + ): + return + # For functions we can do more by inferring the length of the itered object try: inferred = next(assign.iter.infer()) except astroid.InferenceError: diff --git a/tests/functional/u/undefined/undefined_loop_variable.py b/tests/functional/u/undefined/undefined_loop_variable.py index 0270c6b53..6bcf6103d 100644 --- a/tests/functional/u/undefined/undefined_loop_variable.py +++ b/tests/functional/u/undefined/undefined_loop_variable.py @@ -91,6 +91,22 @@ def test(content): handle_line(layne) +def for_else_returns(iterable): + for thing in iterable: + break + else: + return + print(thing) + + +def for_else_raises(iterable): + for thing in iterable: + break + else: + raise Exception + print(thing) + + lst = [] lst2 = [1, 2, 3] |