def node_defines_name(node, name):
"""
Check if the specified statement node defines symbol *name*.
:param node: The node to check.
:param name: The symbol name to check.
:return: Whether or not the node defines the symbole specified.
:rtype: bool
"""
if isinstance(name, ast.Name):
name = name.id
if isinstance(node, ast.Assign):
if node_targets_name(node, name):
return True
if isinstance(node.value, (ast.DictComp, ast.ListComp, ast.SetComp)):
return node_defines_name(node.value, name)
elif isinstance(node, ast.ClassDef):
return node.name == name
# these ones all assume the iterable will be executed at least once
elif isinstance(node, (ast.DictComp, ast.GeneratorExp, ast.ListComp, ast.SetComp)):
for generator in node.generators:
target = generator.target
if isinstance(target, ast.Name):
if target.id == name:
return True
continue
for child_node in iter_child_expr_nodes(target):
if isinstance(child_node, ast.Name) and child_node.id == name:
return True
return False
elif isinstance(node, ast.ExceptHandler):
if isinstance(node.name, ast.Name):
return node.name.id == name
elif isinstance(node.name, str):
return node.name == name
elif isinstance(node, ast.Expr):
if isinstance(node.value, (ast.DictComp, ast.GeneratorExp, ast.ListComp, ast.SetComp)):
return node_defines_name(node.value, name)
elif isinstance(node, ast.For):
return isinstance(node.target, ast.Name) and node.target.id == name
elif isinstance(node, ast.FunctionDef):
return node.name == name
elif isinstance(node, (ast.Import, ast.ImportFrom)):
return next((alias for alias in node.names if (alias.asname or alias.name) == name), None) is not None
return False
评论列表
文章目录