def add_parent_info(root_node):
"""
Add parent attribute for all nodes at and under root_node, recursively.
"""
class AddParents(TopDownVisitor):
def generic_visit(self, node):
if not hasattr(node, 'parent'):
node.parent = None
for child in ast.iter_child_nodes(node):
child.parent = node
AddParents().visit(root_node)
python类Add()的实例源码
def get_binary_op_str(bin_op_node):
"""Returns the string representation of the binary operator node (e.g. +, -,
etc.). For some reason astor doesn't implement this???
"""
if isinstance(bin_op_node, ast.Add):
return "+"
elif isinstance(bin_op_node, ast.Sub):
return "-"
elif isinstance(bin_op_node, ast.Mult):
return "*"
elif isinstance(bin_op_node, ast.Div):
return "/"
elif isinstance(bin_op_node, ast.Mod):
return "%"
elif isinstance(bin_op_node, ast.Pow):
return "**"
elif isinstance(bin_op_node, ast.LShift):
return "<<"
elif isinstance(bin_op_node, ast.RShift):
return ">>"
else:
raise ValueError("No string defined for binary operator node %s" % \
bin_op_node.__class__.__name__)
def get_op_string(op_class):
return {
ast.Add: '+',
ast.Sub: '-',
ast.Div: '/',
ast.Mult: '*'
}[op_class.__class__]
# For expr code
def is_add_function(node):
return isinstance(node, ast.BinOp) and isinstance(node.op, ast.Add)
def test_copy_location(self):
src = ast.parse('1 + 1', mode='eval')
src.body.right = ast.copy_location(ast.Num(2), src.body.right)
self.assertEqual(ast.dump(src, include_attributes=True),
'Expression(body=BinOp(left=Num(n=1, lineno=1, col_offset=0), '
'op=Add(), right=Num(n=2, lineno=1, col_offset=4), lineno=1, '
'col_offset=0))'
)
def visit_BinOp(self, node):
if isinstance(node.op, ast.BitOr):
op = operator.or_
elif isinstance(node.op, ast.Add):
op = operator.add
else:
raise BadConst
values = [
self.visit(node.left),
self.visit(node.right),
]
if all(isinstance(v, RegexpFlag) for v in values):
return RegexpFlag(op(*values))
else:
raise BadConst
def test_copy_location(self):
src = ast.parse('1 + 1', mode='eval')
src.body.right = ast.copy_location(ast.Num(2), src.body.right)
self.assertEqual(ast.dump(src, include_attributes=True),
'Expression(body=BinOp(left=Num(n=1, lineno=1, col_offset=0), '
'op=Add(), right=Num(n=2, lineno=1, col_offset=4), lineno=1, '
'col_offset=0))'
)
def test_augassign(self):
aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
ast.Name("y", ast.Load()))
self.stmt(aug, "must have Store context")
aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
ast.Name("y", ast.Store()))
self.stmt(aug, "must have Load context")
def test_copy_location(self):
src = ast.parse('1 + 1', mode='eval')
src.body.right = ast.copy_location(ast.Num(2), src.body.right)
self.assertEqual(ast.dump(src, include_attributes=True),
'Expression(body=BinOp(left=Num(n=1, lineno=1, col_offset=0), '
'op=Add(), right=Num(n=2, lineno=1, col_offset=4), lineno=1, '
'col_offset=0))'
)
def binary_operation_type(left_type, op, right_type, lineno, solver):
"""Infer the type of a binary operation result"""
if isinstance(op, ast.Add):
inference_func = _infer_add
elif isinstance(op, ast.Mult):
inference_func = _infer_mult
elif isinstance(op, ast.Div):
inference_func = _infer_div
elif isinstance(op, (ast.BitOr, ast.BitXor, ast.BitAnd)):
return _infer_bitwise(left_type, right_type, op, lineno, solver)
else:
return _infer_arithmetic(left_type, right_type, op, lineno, solver)
return inference_func(left_type, right_type, lineno, solver)
def mutate_Sub(self, node):
if self.should_mutate(node):
return ast.Add()
raise MutationResign()
def test_copy_location(self):
src = ast.parse('1 + 1', mode='eval')
src.body.right = ast.copy_location(ast.Num(2), src.body.right)
self.assertEqual(ast.dump(src, include_attributes=True),
'Expression(body=BinOp(left=Num(n=1, lineno=1, col_offset=0), '
'op=Add(), right=Num(n=2, lineno=1, col_offset=4), lineno=1, '
'col_offset=0))'
)
def test_augassign(self):
aug = ast.AugAssign(ast.Name("x", ast.Load()), ast.Add(),
ast.Name("y", ast.Load()))
self.stmt(aug, "must have Store context")
aug = ast.AugAssign(ast.Name("x", ast.Store()), ast.Add(),
ast.Name("y", ast.Store()))
self.stmt(aug, "must have Load context")
def pythonast(self, args, tonative=False):
return reduce(lambda x, y: ast.BinOp(x, ast.Add(), y), args)
def add_error(self, node, message=None):
"""Add an error caused by a node to the list of errors for pep8."""
message = message or self.CHECK_DESC
error = (node.lineno, node.col_offset, message, self.__class__)
self._errors.append(error)
def visit_BinOp(self, node):
if isinstance(node.op, ast.Add):
if self._check_call_names(node.left, self.TRANS_FUNC):
self.add_error(node.left)
elif self._check_call_names(node.right, self.TRANS_FUNC):
self.add_error(node.right)
super(CheckForTransAdd, self).generic_visit(node)
def visit_AugAssign(self, node):
if isinstance(node.op, ast.Add):
ref = node.target.id
value = self.visit(node.value)
return Assign(ref, Prim("add#", [Var(ref), value]))
if isinstance(node.op, ast.Mul):
ref = node.target.id
value = self.visit(node.value)
return Assign(ref, Prim("mult#", [Var(ref), value]))
else:
raise NotImplementedError
def syn_BinOp(self, ctx, e):
op = e.op
if isinstance(op, ast.Add):
ctx.ana(e.right, self)
return self
else:
raise _errors.TyError("Invalid binary operator on strings.", e)
def _update(self):
"""update tkk
"""
# we don't need to update the base TKK value when it is still valid
now = math.floor(int(time.time() * 1000) / 3600000.0)
if self.tkk and int(self.tkk.split('.')[0]) == now:
return
r = self.session.get(self.host)
# this will be the same as python code after stripping out a reserved word 'var'
code = unicode(self.RE_TKK.search(r.text).group(1)).replace('var ', '')
# unescape special ascii characters such like a \x3d(=)
if PY3: # pragma: no cover
code = code.encode().decode('unicode-escape')
else: # pragma: no cover
code = code.decode('string_escape')
if code:
tree = ast.parse(code)
visit_return = False
operator = '+'
n, keys = 0, dict(a=0, b=0)
for node in ast.walk(tree):
if isinstance(node, ast.Assign):
name = node.targets[0].id
if name in keys:
if isinstance(node.value, ast.Num):
keys[name] = node.value.n
# the value can sometimes be negative
elif isinstance(node.value, ast.UnaryOp) and \
isinstance(node.value.op, ast.USub): # pragma: nocover
keys[name] = -node.value.operand.n
elif isinstance(node, ast.Return):
# parameters should be set after this point
visit_return = True
elif visit_return and isinstance(node, ast.Num):
n = node.n
elif visit_return and n > 0:
# the default operator is '+' but implement some more for
# all possible scenarios
if isinstance(node, ast.Add): # pragma: nocover
pass
elif isinstance(node, ast.Sub): # pragma: nocover
operator = '-'
elif isinstance(node, ast.Mult): # pragma: nocover
operator = '*'
elif isinstance(node, ast.Pow): # pragma: nocover
operator = '**'
elif isinstance(node, ast.BitXor): # pragma: nocover
operator = '^'
# a safety way to avoid Exceptions
clause = compile('{1}{0}{2}'.format(
operator, keys['a'], keys['b']), '', 'eval')
value = eval(clause, dict(__builtin__={}))
result = '{}.{}'.format(n, value)
self.tkk = result
def parse_for(self):
from .parser import (
parse_body,
)
# Type 0 for, eg. for i in list(): ...
if self._is_list_iter():
return self.parse_for_list()
if not isinstance(self.stmt.iter, ast.Call) or \
not isinstance(self.stmt.iter.func, ast.Name) or \
not isinstance(self.stmt.target, ast.Name) or \
self.stmt.iter.func.id != "range" or \
len(self.stmt.iter.args) not in (1, 2):
raise StructureException("For statements must be of the form `for i in range(rounds): ..` or `for i in range(start, start + rounds): ..`", self.stmt.iter) # noqa
# Type 1 for, eg. for i in range(10): ...
if len(self.stmt.iter.args) == 1:
if not isinstance(self.stmt.iter.args[0], ast.Num):
raise StructureException("Range only accepts literal values", self.stmt.iter)
start = LLLnode.from_list(0, typ='num', pos=getpos(self.stmt))
rounds = self.stmt.iter.args[0].n
elif isinstance(self.stmt.iter.args[0], ast.Num) and isinstance(self.stmt.iter.args[1], ast.Num):
# Type 2 for, eg. for i in range(100, 110): ...
start = LLLnode.from_list(self.stmt.iter.args[0].n, typ='num', pos=getpos(self.stmt))
rounds = LLLnode.from_list(self.stmt.iter.args[1].n - self.stmt.iter.args[0].n, typ='num', pos=getpos(self.stmt))
else:
# Type 3 for, eg. for i in range(x, x + 10): ...
if not isinstance(self.stmt.iter.args[1], ast.BinOp) or not isinstance(self.stmt.iter.args[1].op, ast.Add):
raise StructureException("Two-arg for statements must be of the form `for i in range(start, start + rounds): ...`",
self.stmt.iter.args[1])
if ast.dump(self.stmt.iter.args[0]) != ast.dump(self.stmt.iter.args[1].left):
raise StructureException("Two-arg for statements of the form `for i in range(x, x + y): ...` must have x identical in both places: %r %r" % (ast.dump(self.stmt.iter.args[0]), ast.dump(self.stmt.iter.args[1].left)), self.stmt.iter)
if not isinstance(self.stmt.iter.args[1].right, ast.Num):
raise StructureException("Range only accepts literal values", self.stmt.iter.args[1])
start = Expr.parse_value_expr(self.stmt.iter.args[0], self.context)
rounds = self.stmt.iter.args[1].right.n
varname = self.stmt.target.id
pos = self.context.new_variable(varname, BaseType('num'))
self.context.forvars[varname] = True
o = LLLnode.from_list(['repeat', pos, start, rounds, parse_body(self.stmt.body, self.context)], typ=None, pos=getpos(self.stmt))
del self.context.vars[varname]
del self.context.forvars[varname]
return o