diff options
Diffstat (limited to 'pyflakes/checker.py')
-rw-r--r-- | pyflakes/checker.py | 56 |
1 files changed, 37 insertions, 19 deletions
diff --git a/pyflakes/checker.py b/pyflakes/checker.py index 8d1887b..d8f093a 100644 --- a/pyflakes/checker.py +++ b/pyflakes/checker.py @@ -1322,34 +1322,52 @@ class Checker(object): self.handleChildren(node) return - # 3.x: the name of the exception, which is not a Name node, but - # a simple string, creates a local that is only bound within the scope - # of the except: block. + # If the name already exists in the scope, modify state of existing + # binding. + if node.name in self.scope: + self.handleNodeStore(node) + + # 3.x: the name of the exception, which is not a Name node, but a + # simple string, creates a local that is only bound within the scope of + # the except: block. As such, temporarily remove the existing binding + # to more accurately determine if the name is used in the except: + # block. for scope in self.scopeStack[::-1]: - if node.name in scope: - is_name_previously_defined = True + try: + binding = scope.pop(node.name) + except KeyError: + pass + else: + prev_definition = scope, binding break else: - is_name_previously_defined = False + prev_definition = None self.handleNodeStore(node) self.handleChildren(node) - if not is_name_previously_defined: - # See discussion on https://github.com/PyCQA/pyflakes/pull/59 - # We're removing the local name since it's being unbound - # after leaving the except: block and it's always unbound - # if the except: block is never entered. This will cause an - # "undefined name" error raised if the checked code tries to - # use the name afterwards. - # - # Unless it's been removed already. Then do nothing. + # See discussion on https://github.com/PyCQA/pyflakes/pull/59 - try: - del self.scope[node.name] - except KeyError: - pass + # We're removing the local name since it's being unbound after leaving + # the except: block and it's always unbound if the except: block is + # never entered. This will cause an "undefined name" error raised if + # the checked code tries to use the name afterwards. + # + # Unless it's been removed already. Then do nothing. + + try: + binding = self.scope.pop(node.name) + except KeyError: + pass + else: + if not binding.used: + self.report(messages.UnusedVariable, node, node.name) + + # Restore. + if prev_definition: + scope, binding = prev_definition + scope[node.name] = binding def ANNASSIGN(self, node): if node.value: |