Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion parser-Python/uast/visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,10 @@ def visit_FunctionDef(self, node):
if node.name == '__init__':
function_def._meta.isConstructor = True
# function_def.body.body.append(UNode.ReturnStatement(UNode.SourceLocation(), UNode.Meta(), UNode.Identifier(UNode.SourceLocation(), UNode.Meta(), 'self')))
if len(body) > 0:
last_stmt = body[-1]
if not isinstance(last_stmt, UNode.ReturnStatement):
function_def.body.body.append(UNode.ReturnStatement(UNode.SourceLocation(), UNode.Meta(), UNode.Identifier(UNode.SourceLocation(), UNode.Meta(), 'self')))
decorator_list = []
for decorator in node.decorator_list:
decorator_list.append(self.packPos(decorator, self.visit(decorator)))
Expand Down Expand Up @@ -1093,12 +1097,15 @@ def visit_Compare(self, node):

def visit_keyword(self, node):
# todo 当函数调用使用 **kwargs 展开一个字典时,node.arg 的值为 None
return self.packPos(node, UNode.VariableDeclaration(UNode.SourceLocation(), UNode.Meta(),
keyword = self.packPos(node, UNode.VariableDeclaration(UNode.SourceLocation(), UNode.Meta(),
UNode.Identifier(UNode.SourceLocation(), UNode.Meta(),
node.arg),
self.packPos(node.value, self.visit(node.value)),
False,
UNode.DynamicType(UNode.SourceLocation(), UNode.Meta())))
if keyword.id.name is None:
keyword.id.name = "kwargs"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keyword expansion loses argument identity

Medium Severity

When node.arg is None, visit_keyword rewrites every expanded keyword to the fixed name kwargs. This makes distinct ** expansions and real kwargs= arguments indistinguishable in CallExpression.arguments, so downstream argument binding can merge or misattribute parameters.

Fix in Cursor Fix in Web

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Hardcoding the name to "kwargs" for ** expansions can be problematic. It loses the actual name of the dictionary being expanded and can cause name collisions if a function call uses multiple ** expansions (e.g., f(**dict1, **dict2)), which is valid in Python 3.5+. A better approach is to use the name of the variable being expanded if it's a simple name, and fall back to "kwargs" for more complex expressions.

Suggested change
keyword.id.name = "kwargs"
if isinstance(node.value, ast.Name):
keyword.id.name = node.value.id
else:
keyword.id.name = "kwargs"

return keyword

def visit_Starred(self, node):
return self.packPos(node, UNode.DereferenceExpression(UNode.SourceLocation(), UNode.Meta(),
Expand Down