From efd3c8b11361913c96eeb1450490aa6b489be952 Mon Sep 17 00:00:00 2001 From: david-sarah Date: Sun, 9 Oct 2011 04:50:23 +0000 Subject: [PATCH] check-miscaptures.py: handle corner cases around default arguments correctly. Also make a minor optimization when there are no assigned variables to consider. refs #1555 --- misc/coding_tools/check-miscaptures.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/misc/coding_tools/check-miscaptures.py b/misc/coding_tools/check-miscaptures.py index b6c9f71e..f2637f09 100644 --- a/misc/coding_tools/check-miscaptures.py +++ b/misc/coding_tools/check-miscaptures.py @@ -49,7 +49,7 @@ def check_loop(ast, results): for funcnode in nested: # Check for captured variables in this function. captured = set() - collect_captured(funcnode, assigned, captured) + collect_captured(funcnode, assigned, captured, False) for name in captured: # We want to report the outermost capturing function # (since that is where the workaround will need to be @@ -87,7 +87,7 @@ def collect_assigned_and_nested(ast, assigned, nested): if isinstance(ast, Node): collect_assigned_and_nested(child, assigned, nested) -def collect_captured(ast, assigned, captured): +def collect_captured(ast, assigned, captured, in_function_yet): """Collect any captured variables that are also in assigned.""" if isinstance(ast, Name): if ast.name in assigned: @@ -100,17 +100,20 @@ def collect_captured(ast, assigned, captured): new_assigned = assigned.copy() remove_argnames(ast.argnames, new_assigned) - for child in childnodes[len(ast.defaults):]: - collect_captured(child, assigned, captured) + if len(new_assigned) > 0: + for child in childnodes[len(ast.defaults):]: + collect_captured(child, new_assigned, captured, True) - # The default argument expressions are "outside" the - # function, even though they are children of the - # Lambda or Function node. + # The default argument expressions are "outside" *this* + # function, even though they are children of the Lambda or + # Function node. + if not in_function_yet: + return childnodes = childnodes[:len(ast.defaults)] for child in childnodes: if isinstance(ast, Node): - collect_captured(child, assigned, captured) + collect_captured(child, assigned, captured, True) def remove_argnames(names, fromset): -- 2.45.2