summaryrefslogtreecommitdiff
path: root/pyflakes/checker.py
diff options
context:
space:
mode:
authorFlorent Xicluna <florent.xicluna@gmail.com>2013-03-30 16:57:14 +0100
committerFlorent Xicluna <florent.xicluna@gmail.com>2013-03-30 16:57:14 +0100
commit9f1b092c3ac759aee3243801eb5218d4101dd67b (patch)
treea3a808aa0ffbdc4b7f9dd3ba87ae6c94d0c68c73 /pyflakes/checker.py
parent72449cccd9a1cadd6f41718cbbd6c38bd1cf2709 (diff)
downloadpyflakes-9f1b092c3ac759aee3243801eb5218d4101dd67b.tar.gz
Do not report undefined name if the code is protected with a NameError handler.
Diffstat (limited to 'pyflakes/checker.py')
-rw-r--r--pyflakes/checker.py43
1 files changed, 35 insertions, 8 deletions
diff --git a/pyflakes/checker.py b/pyflakes/checker.py
index c8c4082..1de8661 100644
--- a/pyflakes/checker.py
+++ b/pyflakes/checker.py
@@ -211,6 +211,7 @@ class Checker(object):
if builtins:
self.builtIns = self.builtIns.union(builtins)
self.scopeStack = [ModuleScope()]
+ self.exceptHandlers = [()]
self.futuresAllowed = True
self.root = tree
self.handleChildren(tree)
@@ -391,7 +392,6 @@ class Checker(object):
if not name:
return
# try local scope
- importStarred = self.scope.importStarred
try:
self.scope[name].used = (self.scope, node.lineno)
except KeyError:
@@ -400,6 +400,7 @@ class Checker(object):
return
# try enclosing function scopes
+ importStarred = self.scope.importStarred
for scope in self.scopeStack[-2:0:-1]:
importStarred = importStarred or scope.importStarred
if not isinstance(scope, FunctionScope):
@@ -416,12 +417,20 @@ class Checker(object):
try:
self.scopeStack[0][name].used = (self.scope, node.lineno)
except KeyError:
- if not importStarred and name not in self.builtIns:
- if (os.path.basename(self.filename) == '__init__.py' and name == '__path__'):
- # the special name __path__ is valid only in packages
- pass
- else:
- self.report(messages.UndefinedName, node.lineno, name)
+ pass
+ else:
+ return
+
+ # look in the built-ins
+ if importStarred or name in self.builtIns:
+ return
+ if name == '__path__' and os.path.basename(self.filename) == '__init__.py':
+ # the special name __path__ is valid only in packages
+ return
+
+ # protected with a NameError handler?
+ if 'NameError' not in self.exceptHandlers[-1]:
+ self.report(messages.UndefinedName, node.lineno, name)
def handleNodeStore(self, node):
name = getNodeName(node)
@@ -500,7 +509,7 @@ class Checker(object):
# "stmt" type nodes
RETURN = DELETE = PRINT = WHILE = IF = WITH = WITHITEM = RAISE = \
- TRYEXCEPT = TRYFINALLY = TRY = ASSERT = EXEC = EXPR = handleChildren
+ TRYFINALLY = ASSERT = EXEC = EXPR = handleChildren
CONTINUE = BREAK = PASS = ignore
@@ -728,6 +737,24 @@ class Checker(object):
importation.used = (self.scope, node.lineno)
self.addBinding(node, importation)
+ def TRY(self, node):
+ handler_names = []
+ for handler in node.handlers:
+ if isinstance(handler.type, ast.Tuple):
+ for exc_type in handler.type.elts:
+ handler_names.append(exc_type.id)
+ elif handler.type:
+ handler_names.append(handler.type.id)
+ self.exceptHandlers.append(handler_names)
+ for child in node.body:
+ self.handleNode(child, node)
+ self.exceptHandlers.pop()
+ for child in iter_child_nodes(node):
+ if child not in node.body:
+ self.handleNode(child, node)
+
+ TRYEXCEPT = TRY
+
def EXCEPTHANDLER(self, node):
# 3.x: in addition to handling children, we must handle the name of
# the exception, which is not a Name node, but a simple string.