check-miscaptures.py: check while loops and list comprehensions as well as for loops. Also fix a pyflakes warning. refs #1555

This commit is contained in:
david-sarah 2011-10-09 04:40:22 +00:00
parent be1c94893f
commit d2f3ef9714

View File

@ -1,7 +1,7 @@
#! /usr/bin/python #! /usr/bin/python
import os, sys, compiler, traceback import os, sys, compiler
from compiler.ast import Node, For, AssName, Name, Lambda, Function from compiler.ast import Node, For, While, ListComp, AssName, Name, Lambda, Function
def check_source(source): def check_source(source):
@ -21,16 +21,25 @@ def check_thing(parser, thing):
return results return results
def check_ast(ast, results): def check_ast(ast, results):
"""Check a node outside a 'for' loop.""" """Check a node outside a loop."""
if isinstance(ast, For): if isinstance(ast, (For, While, ListComp)):
check_for(ast, results) check_loop(ast, results)
else: else:
for child in ast.getChildNodes(): for child in ast.getChildNodes():
if isinstance(ast, Node): if isinstance(ast, Node):
check_ast(child, results) check_ast(child, results)
def check_for(ast, results): def check_loop(ast, results):
"""Check a particular outer 'for' loop.""" """Check a particular outer loop."""
# List comprehensions have a poorly designed AST of the form
# ListComp(exprNode, [ListCompFor(...), ...]), in which the
# result expression is outside the ListCompFor node even though
# it is logically inside the loop(s).
# There may be multiple ListCompFor nodes (in cases such as
# [lambda: (a,b) for a in ... for b in ...]
# ), and that case they are not nested in the AST. But these
# warts (nonobviously) happen not to matter for our analysis.
declared = {} # maps name to lineno of declaration declared = {} # maps name to lineno of declaration
nested = set() nested = set()