Skip to content

Commit 5b50922

Browse files
bcallerBen Caller
authored andcommitted
Iterate over args and kwargs with care
ast.Call.args is [argument node] ast.Call.keywords however is [ast.keyword] You need to do isinstance(keyword_node.value, X) otherwise handling of args and kwargs will be different.
1 parent 70257a7 commit 5b50922

File tree

3 files changed

+14
-5
lines changed

3 files changed

+14
-5
lines changed

pyt/cfg/stmt_visitor.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,8 @@ def add_blackbox_or_builtin_call(self, node, blackbox):
615615
rhs_vars = list()
616616
last_return_value_of_nested_call = None
617617

618-
for arg in itertools.chain(node.args, node.keywords):
618+
for arg_node in itertools.chain(node.args, node.keywords):
619+
arg = arg_node.value if isinstance(arg_node, ast.keyword) else arg_node
619620
if isinstance(arg, ast.Call):
620621
return_value_of_nested_call = self.visit(arg)
621622

@@ -634,15 +635,18 @@ def add_blackbox_or_builtin_call(self, node, blackbox):
634635
call_node.inner_most_call = return_value_of_nested_call
635636
last_return_value_of_nested_call = return_value_of_nested_call
636637

637-
visual_args.append(return_value_of_nested_call.left_hand_side)
638+
if isinstance(arg_node, ast.keyword) and arg_node.arg is not None:
639+
visual_args.append(arg_node.arg + '=' + return_value_of_nested_call.left_hand_side)
640+
else:
641+
visual_args.append(return_value_of_nested_call.left_hand_side)
638642
rhs_vars.append(return_value_of_nested_call.left_hand_side)
639643
else:
640644
label = LabelVisitor()
641-
label.visit(arg)
645+
label.visit(arg_node)
642646
visual_args.append(label.result)
643647

644648
vv = VarsVisitor()
645-
vv.visit(arg)
649+
vv.visit(arg_node)
646650
rhs_vars.extend(vv.result)
647651
if last_return_value_of_nested_call:
648652
# connect other_inner to outer in e.g.

pyt/helper_visitors/vars_visitor.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ def visit_Call(self, node):
8484
# This will not visit Flask in Flask(__name__) but it will visit request in `request.args.get()
8585
if not isinstance(node.func, ast.Name):
8686
self.visit(node.func)
87-
for arg in itertools.chain(node.args, node.keywords):
87+
for arg_node in itertools.chain(node.args, node.keywords):
88+
arg = arg_node.value if isinstance(arg_node, ast.keyword) else arg_node
8889
if isinstance(arg, ast.Call):
8990
if isinstance(arg.func, ast.Name):
9091
# We can't just visit because we need to add 'ret_'

tests/helper_visitors/vars_visitor_test.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ def test_call5(self):
4545
self.assertEqual(vars.result, ['resp', 'ret_replace'])
4646

4747
def test_call6(self):
48+
vars = self.perform_vars_on_expression("resp = f(kw=g(a, b))")
49+
self.assertEqual(vars.result, ['resp', 'ret_g'])
50+
51+
def test_call7(self):
4852
vars = self.perform_vars_on_expression("resp = make_response(html.replace.bar('{{ param }}', param))")
4953
self.assertEqual(vars.result, ['resp', 'ret_bar'])
5054

0 commit comments

Comments
 (0)