def test_walk_field_transform_inspect():
@ast_walker
def names_and_incremented_nums(state, node, walk_field, **kwds):
if isinstance(node, ast.Assign):
state, value_node = walk_field(state, node.value)
new_node = replace_fields(node, targets=node.targets, value=value_node)
new_state = state.update(objs=state.objs.add(node.targets[0].id))
return new_state, new_node
elif isinstance(node, ast.Num):
return state.update(objs=state.objs.add(node.n)), ast.Num(n=node.n + 1)
else:
return state, node
node = get_ast(dummy)
state, new_node = names_and_incremented_nums(dict(objs=immutableset()), node)
assert state.objs == set(['a', 'c', 1, 4])
assert_ast_equal(new_node, get_ast(
"""
def dummy(x, y):
c = 5
a = 2
"""))
python类Assign()的实例源码
def test_skip_fields():
@ast_transformer
def increment(node, skip_fields, **kwds):
if isinstance(node, ast.Assign) and node.targets[0].id == 'c':
skip_fields()
if isinstance(node, ast.Num):
return ast.Num(n=node.n + 1)
else:
return node
node = get_ast(dummy)
new_node = increment(node)
assert_ast_equal(new_node, get_ast(
"""
def dummy(x, y):
c = 4
a = 2
"""))
def translate(self, ctx):
translation = []
scrutinee = ast.Name(id="__typy_with_scrutinee__")
translation.extend(
self.body_block.translate_assign(
ctx, scrutinee))
pat = self.pat
ctx_update = pat.ctx_update
condition, binding_translations = ctx.translate_pat(pat, scrutinee)
if astx.cond_vacuously_true(condition):
for (id, trans) in binding_translations.iteritems():
translation.append(ast.Assign(
targets=[ast.Name(id=ctx_update[id][0])],
value=trans))
else:
translation.append(ast.If(
test=condition,
body=list(_yield_binding_translation_assignments(
binding_translations, ctx_update)),
orelse=astx.expr_Raise_Exception_string("Match failure.")))
return translation
def maybe_assignment(*expr_fns):
if len(expr_fns) == 1:
node0 = expr_fns[0](ast.Load())
stmt = ast.Expr(node0)
else:
lhses = [fn(ast.Store()) for fn in expr_fns[:-1]]
node0 = lhses[0]
stmt = ast.Assign(lhses, expr_fns[-1](ast.Load()))
return ast.copy_location(stmt, node0)
def visit_FunctionDef(self, t):
fn = Function(t.name, t.args, t.body)
for d in reversed(t.decorator_list):
fn = Call(d, [fn])
return ast.Assign([ast.Name(t.name, store)], fn)
def visit_FunctionDef(self, t):
t = self.generic_visit(t)
fn = Function(t.name, t.args, t.body)
for d in reversed(t.decorator_list):
fn = Call(d, [fn])
result = ast.Assign([ast.Name(t.name, store)], fn)
return ast.copy_location(result, t)
def visit_FunctionDef(self, t):
t = self.generic_visit(t)
fn = Function(t.name, t.args, t.body)
for d in reversed(t.decorator_list):
fn = Call(d, [fn])
result = ast.Assign([ast.Name(t.name, store)], fn)
return ast.copy_location(result, t)
def visit_FunctionDef(self, t):
t = self.generic_visit(t)
fn = Function(t.name, t.args, t.body)
for d in reversed(t.decorator_list):
fn = Call(d, [fn])
result = ast.Assign([ast.Name(t.name, store)], fn)
return ast.copy_location(result, t)
def get_version():
filename = os.path.join(os.path.dirname(__file__),
'publicdns', '__init__.py')
version = None
with open(filename, 'r') as f:
tree = ast.parse(f.read(), filename)
for node in ast.iter_child_nodes(tree):
if not isinstance(node, ast.Assign) or len(node.targets) != 1:
continue
target, = node.targets
if (isinstance(target, ast.Name) and
target.id == '__version_info__'):
version = ast.literal_eval(node.value)
return '.'.join([str(x) for x in version])
def assign_multi_target(self, node, right_hand_side_variables):
new_assignment_nodes = list()
for target in node.targets:
label = LabelVisitor()
label.visit(target)
left_hand_side = label.result
label.result += ' = '
label.visit(node.value)
new_assignment_nodes.append(self.append_node(AssignmentNode(label.result, left_hand_side, ast.Assign(target, node.value), right_hand_side_variables, line_number = node.lineno, path=self.filenames[-1])))
self.connect_nodes(new_assignment_nodes)
return ControlFlowNode(new_assignment_nodes[0], [new_assignment_nodes[-1]], []) # return the last added node
def visit_Assign(self, assign):
value_explanation, value_result = self.visit(assign.value)
explanation = "... = %s" % (value_explanation,)
name = ast.Name("__exprinfo_expr", ast.Load(),
lineno=assign.value.lineno,
col_offset=assign.value.col_offset)
new_assign = ast.Assign(assign.targets, name, lineno=assign.lineno,
col_offset=assign.col_offset)
mod = ast.Module([new_assign])
co = self._compile(mod, "exec")
try:
self.frame.exec_(co, __exprinfo_expr=value_result)
except Exception:
raise Failure(explanation)
return explanation, value_result
def assign(self, expr):
"""Give *expr* a name."""
name = self.variable()
self.statements.append(ast.Assign([ast.Name(name, ast.Store())], expr))
return ast.Name(name, ast.Load())
def visit_BoolOp(self, boolop):
res_var = self.variable()
expl_list = self.assign(ast.List([], ast.Load()))
app = ast.Attribute(expl_list, "append", ast.Load())
is_or = int(isinstance(boolop.op, ast.Or))
body = save = self.statements
fail_save = self.on_failure
levels = len(boolop.values) - 1
self.push_format_context()
# Process each operand, short-circuting if needed.
for i, v in enumerate(boolop.values):
if i:
fail_inner = []
# cond is set in a prior loop iteration below
self.on_failure.append(ast.If(cond, fail_inner, [])) # noqa
self.on_failure = fail_inner
self.push_format_context()
res, expl = self.visit(v)
body.append(ast.Assign([ast.Name(res_var, ast.Store())], res))
expl_format = self.pop_format_context(ast.Str(expl))
call = ast_Call(app, [expl_format], [])
self.on_failure.append(ast.Expr(call))
if i < levels:
cond = res
if is_or:
cond = ast.UnaryOp(ast.Not(), cond)
inner = []
self.statements.append(ast.If(cond, inner, []))
self.statements = body = inner
self.statements = save
self.on_failure = fail_save
expl_template = self.helper("format_boolop", expl_list, ast.Num(is_or))
expl = self.pop_format_context(expl_template)
return ast.Name(res_var, ast.Load()), self.explanation_param(expl)
def individualizeVariables(a, variablePairs, idNum, imports):
"""Replace variable names with new individualized ones (for inlining methods)"""
if not isinstance(a, ast.AST):
return
if type(a) == ast.Name:
if a.id not in variablePairs and not (builtInName(a.id) or importedName(a.id, imports)):
name = "_var_" + a.id + "_" + str(idNum[0])
variablePairs[a.id] = name
if a.id in variablePairs:
a.id = variablePairs[a.id]
# Override built-in names when they're assigned to.
elif type(a) == ast.Assign and type(a.targets[0]) == ast.Name:
if a.targets[0].id not in variablePairs:
name = "_var_" + a.targets[0].id + "_" + str(idNum[0])
variablePairs[a.targets[0].id] = name
elif type(a) == ast.arguments:
for arg in a.args:
if type(arg) == ast.arg:
name = "_arg_" + arg.arg + "_" + str(idNum[0])
variablePairs[arg.arg] = name
arg.arg = variablePairs[arg.arg]
return
elif type(a) == ast.Call:
if type(a.func) == ast.Name:
variablePairs[a.func.id] = a.func.id # save the function name!
for child in ast.iter_child_nodes(a):
individualizeVariables(child, variablePairs, idNum, imports)
def allVariableNamesUsed(a):
"""Gathers all the variable names used in the ast"""
if not isinstance(a, ast.AST):
return []
elif type(a) == ast.Name:
return [a.id]
elif type(a) == ast.Assign:
"""In assignments, ignore all pure names used- they're being assigned to, not used"""
variables = allVariableNamesUsed(a.value)
for target in a.targets:
if type(target) == ast.Name:
pass
elif type(target) in [ast.Tuple, ast.List]:
for elt in target.elts:
if type(elt) != ast.Name:
variables += allVariableNamesUsed(elt)
else:
variables += allVariableNamesUsed(target)
return variables
elif type(a) == ast.AugAssign:
variables = allVariableNamesUsed(a.value)
variables += allVariableNamesUsed(a.target)
return variables
variables = []
for child in ast.iter_child_nodes(a):
variables += allVariableNamesUsed(child)
return variables
def staticVars(l, vars):
"""Determines whether the given lines change the given variables"""
# First, if one of the variables can be modified, there might be a problem
mutableVars = []
for var in vars:
if (not (hasattr(var, "type") and (var.type in [int, float, str, bool]))):
mutableVars.append(var)
for i in range(len(l)):
if type(l[i]) == ast.Assign:
for var in vars:
if var.id in allVariableNamesUsed(l[i].targets[0]):
return False
elif type(l[i]) == ast.AugAssign:
for var in vars:
if var.id in allVariableNamesUsed(l[i].target):
return False
elif type(l[i]) in [ast.If, ast.While]:
if not (staticVars(l[i].body, vars) and staticVars(l[i].orelse, vars)):
return False
elif type(l[i]) == ast.For:
for var in vars:
if var.id in allVariableNamesUsed(l[i].target):
return False
if not (staticVars(l[i].body, vars) and staticVars(l[i].orelse, vars)):
return False
elif type(l[i]) in [ast.FunctionDef, ast.ClassDef, ast.Try, ast.With]:
log("transformations\tstaticVars\tMissing type: " + str(type(l[i])), "bug")
# If a mutable variable is used, we can't trust it
for var in mutableVars:
if var.id in allVariableNamesUsed(l[i]):
return False
return True
def isStatement(a):
"""Determine whether the given node is a statement (vs an expression)"""
return type(a) in [ ast.Module, ast.Interactive, ast.Expression, ast.Suite,
ast.FunctionDef, ast.ClassDef, ast.Return, ast.Delete,
ast.Assign, ast.AugAssign, ast.For, ast.While,
ast.If, ast.With, ast.Raise, ast.Try,
ast.Assert, ast.Import, ast.ImportFrom, ast.Global,
ast.Expr, ast.Pass, ast.Break, ast.Continue ]
def gatherAssignedVars(targets):
"""Take a list of assigned variables and extract the names/subscripts/attributes"""
if type(targets) != list:
targets = [targets]
newTargets = []
for target in targets:
if type(target) in [ast.Tuple, ast.List]:
newTargets += gatherAssignedVars(target.elts)
elif type(target) in [ast.Name, ast.Subscript, ast.Attribute]:
newTargets.append(target)
else:
log("astTools\tgatherAssignedVars\tWeird Assign Type: " + str(type(target)),"bug")
return newTargets
def getAllAssignedVarIds(a):
if not isinstance(a, ast.AST):
return []
ids = []
for child in ast.walk(a):
if type(child) == ast.Assign:
ids += gatherAssignedVarIds(child.targets)
elif type(child) == ast.AugAssign:
ids += gatherAssignedVarIds([child.target])
elif type(child) == ast.For:
ids += gatherAssignedVarIds([child.target])
return ids
def getAllAssignedVars(a):
if not isinstance(a, ast.AST):
return []
vars = []
for child in ast.walk(a):
if type(child) == ast.Assign:
vars += gatherAssignedVars(child.targets)
elif type(child) == ast.AugAssign:
vars += gatherAssignedVars([child.target])
elif type(child) == ast.For:
vars += gatherAssignedVars([child.target])
return vars