From 00d2ee08de4fa21d36e7eba1cc321b19d9d83eb6 Mon Sep 17 00:00:00 2001 From: Mark Byrne <31762852+mbyrnepr2@users.noreply.github.com> Date: Tue, 4 Jun 2024 23:54:57 +0200 Subject: [PATCH] Fix a false positive for ``redefined-outer-name`` (#9678) When there is a name defined in an exception-handling block which shares the same name as a local variable that has been defined in a function body. Check if the outer node is in the scope of an exception assignment and do not emit ``redefined-outer-name`` if that is the case. Closes #9671 (cherry picked from commit 57ae027efcd9bc19d793459fc15904cb9c45578a) --- doc/whatsnew/fragments/9671.false_positive | 3 +++ pylint/checkers/variables.py | 9 ++++++++ .../r/redefined/redefined_except_handler.py | 22 +++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 doc/whatsnew/fragments/9671.false_positive diff --git a/doc/whatsnew/fragments/9671.false_positive b/doc/whatsnew/fragments/9671.false_positive new file mode 100644 index 0000000000..23dafff10f --- /dev/null +++ b/doc/whatsnew/fragments/9671.false_positive @@ -0,0 +1,3 @@ +Fix a false positive for ``redefined-outer-name`` when there is a name defined in an exception-handling block which shares the same name as a local variable that has been defined in a function body. + +Closes #9671 diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py index 6c33a05556..8447320b89 100644 --- a/pylint/checkers/variables.py +++ b/pylint/checkers/variables.py @@ -1519,6 +1519,15 @@ def visit_functiondef(self, node: nodes.FunctionDef) -> None: ): continue + # Suppress emitting the message if the outer name is in the + # scope of an exception assignment. + # For example: the `e` in `except ValueError as e` + global_node = globs[name][0] + if isinstance(global_node, nodes.AssignName) and isinstance( + global_node.parent, nodes.ExceptHandler + ): + continue + line = definition.fromlineno if not self._is_name_ignored(stmt, name): self.add_message( diff --git a/tests/functional/r/redefined/redefined_except_handler.py b/tests/functional/r/redefined/redefined_except_handler.py index b774e32f2f..d621496263 100644 --- a/tests/functional/r/redefined/redefined_except_handler.py +++ b/tests/functional/r/redefined/redefined_except_handler.py @@ -70,3 +70,25 @@ def func(): # pylint:disable-next=invalid-name, unused-variable except IOError as CustomException: # [redefined-outer-name] pass + + +# https://github.com/pylint-dev/pylint/issues/9671 +def function_before_exception(): + """The local variable `e` should not trigger `redefined-outer-name` + when `e` is also defined in the subsequent exception handling block. + """ + e = 42 + return e + +try: + raise ValueError('outer') +except ValueError as e: + print(e) + + +def function_after_exception(): + """The local variable `e` should not trigger `redefined-outer-name` + when `e` is also defined in the preceding exception handling block. + """ + e = 42 + return e