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_AugAssign(self): for cls, op in self.operators.items(): aug_assign = ast.AugAssign(ast.Name('X', ast.Store()), cls(), ast.Num(1)) self.verify(aug_assign, 'X{}=1'.format(op)) self.verify( ast.AugAssign(ast.Name('X', ast.Store()), ast.Add(), ast.Tuple([ast.Num(1), ast.Num(2)], ast.Load())), 'X+=1,2')
def isl2py_for(n): assert n.get_type() == isl.ast_node_type.for_ for_var = n.for_get_iterator() assert for_var.get_type() == isl.ast_expr_type.id for_var_name = for_var.get_id().name # Initialize loop variable py_asign = pyast.Assign( targets=[pyast.Name(for_var_name, pyast.Store())], value=isl2py_exp(n.for_get_init()), ) # Increment statement py_inc = pyast.AugAssign( target=pyast.Name(for_var_name, pyast.Store()), op=pyast.Add(), value=isl2py_exp(n.for_get_inc()), ) # python loop body py_body = isl2py_ast(n.for_get_body()) + [py_inc] ret = [ py_asign, pyast.While(test=isl2py_exp(n.for_get_cond()), body=py_body, orelse=[]), ] return ret
def p_expr_stmt(p): '''expr_stmt : testlist augassign yield_expr | testlist augassign testlist | testlist expr_stmt_bottom | testlist''' if len(p) == 2: p[0] = ast.Expr(p[1], lineno=p[1].lineno, col_offset=p[1].col_offset) elif len(p) == 3: values = p[2].pop() targets = [ p[1], ] targets.extend(p[2]) item = p[1] while isinstance(item, list): item = item[0] set_context(targets, ast.Store()) p[0] = ast.Assign(targets=targets, value=values, lineno=item.lineno, col_offset=item.col_offset) elif len(p) == 4: set_context(p[1], ast.Store()) p[0] = ast.AugAssign(target=p[1], value=p[3], op=p[2], lineno=p[1].lineno, col_offset=p[1].col_offset) return
def p_statement_unary_aug_assign(self, p): '''statement : NAME unaryaugassign SEMICOLON''' bin_op = p[2] bin_op.left = ast.Name(id=p[1], ctx=ast.Load()) p[0] = ast.AugAssign(target=ast.Name(id=p[1], ctx=ast.Store()), op=bin_op.op, value=bin_op.right)
def compile_augassign_expression(self, expression): ops = { "+=": ast.Add, "/=": ast.Div, "//=": ast.FloorDiv, "*=": ast.Mult, "_=": ast.Sub, "%=": ast.Mod, "**=": ast.Pow, "<<=": ast.LShift, ">>=": ast.RShift, "|=": ast.BitOr, "^=": ast.BitXor, "&=": ast.BitAnd } op = ops[expression[0]] target = self._storeize(self.compile(expression[1])) value = self.compile(expression[2]) return ast.AugAssign(target=target, value=value, op=op(), lineno=expression.start_line, col_offset=expression.start_column)
def _as_add_to(self, expr, leftname, *leftpath): value = self._sympy_as_ast(expr) return ast.AugAssign( target=self._path_as_ast(leftname, *leftpath, as_store=True), value=value, op=ast.Add(), )
def process_assign_node(target_nodes, g, var_def, value_ast, na, targets): if len(target_nodes) > 1: target_ast = [] for target_node in target_nodes: target_ast.append( node_to_ast(target_node[1], g, var_def, read=False)) targets.append(target_node[1]) ast_assign = ast.Assign(targets=[ ast.Tuple(elts=target_ast, lineno=0, col_offset=0, ctx=ast.Store()) ], value=value_ast, lineno=0, col_offset=0) return ast_assign else: target_node = target_nodes[0][1] target_ast = node_to_ast(target_node, g, var_def, read=False) if value_ast and target_ast: if na == ast.Assign or target_node not in targets: targets.append(target_node) ast_assign = ast.Assign(targets=[target_ast], value=value_ast, lineno=0, col_offset=0) else: ast_assign = ast.AugAssign(target=target_ast, value=value_ast, lineno=0, col_offset=0, op=ast.Add()) return ast_assign
def generate_augmented_assign(max_depth=None): value = generate_expression(max_depth=max_depth) target = generate_variable(max_depth=max_depth, ctx=ast.Store()) op = random.choice(binary_ops)() return ast.AugAssign(target, op, value)
def visit_ListComp(self, node): listvar = self.id_factory("listcomp") self.execute(mk_assign(listvar, mk_list([]))) self.start_frame() add = ast.AugAssign() add.target = ast.Name(id=listvar, ctx=ast.Store()) add.value = self.make_primitive( mk_list([self.make_primitive(node.elt)])) add.op = ast.Add() body = self.end_frame() body.append(add) for generator in reversed(node.generators): loop = self.build_comprehension(generator, body) body = [loop] outermost_loop = body[0] # Now simplify all expressions inside the generator. # We can do this now as we have a proper function outermost_loop = self.visit(outermost_loop) self.execute(outermost_loop) return mk_name(listvar)
def create_finally_block(self, node): # Increments the total # of tests inc_statement = ast.AugAssign(target=ast.Name(id=self.test_counter, ctx=ast.Store()), op=ast.Add(), value=ast.Num(n=1)) return [inc_statement]
def create_try_block(self, node): # Does the asserted action, then increments the passed test counter inc_statement = ast.AugAssign(target=ast.Name(id=self.pass_counter, ctx=ast.Store()), op=ast.Add(), value=ast.Num(n=1)) return [node, inc_statement]
def expr_stmt(self, p): augassign = p.augassign name = p.testlist_star_expr assign = ast.AugAssign(target=ast.Name(id=name.id, ctx=ast.Store()), op=augassign.op, value=p.testlist) return assign
def visit_For(self, n): orelse = n.orelse if orelse: raise InvalidOperationError( "else clauses on for loops are not supported.", n) # This is a fairly limited form of the for-loop, not even the # complete xrange syntax (negative steps will blow your code up) # so we probably want to expand on this somehow. I'm open to # ideas. Or just wait till I implement full-blown range support. # # In the meantime, you can use while loops instead. # insert missing iteration bounds if not specified iter = n.iter if isinstance(iter, _ast.Tuple): elts = iter.elts n_elts = len(elts) if n_elts == 1: start = _ast.Num(n=0) stop = elts[0] step = _ast.Num(n=1) elif n_elts == 2: start = elts[0] stop = elts[1] step = _ast.Num(n=1) elif n_elts == 3: start = elts[0] stop = elts[1] step = elts[2] else: raise InvalidOperationError( "Invalid number of elements specified in for-loop index.", n) else: start = _ast.Num(n=0) stop = iter step = _ast.Num(n=1) target_store = n.target init = self.visit(_ast.Assign(targets=[target_store], value=start)) # to create the guard operation, we need a Load version of the target target_load = astx.copy_node(target_store, ctx=self._Load) guard = self.visit( _ast.Compare(left=target_load, comparators=[stop], ops=[_ast.Lt()])) update_stmt = self.visit( _ast.AugAssign(target=target_store, op=_ast.Add(), value=step)) return astx.copy_node(n, init=init, guard=guard, update_stmt=update_stmt, body=[self.visit(stmt) for stmt in n.body], orelse=[])
def visit_AugAssign(self, node: ast.AugAssign) -> ast.AST: """AugAssign is ``-=, +=, /=, *=`` for augmented assignment.""" self.generic_visit(node) log_header = f"visit_AugAssign: {self.src_file}:" # custom mapping of string keys to ast operations that can be used # in the nodes since these overlap with BinOp types aug_mappings = { "AugAssign_Add": ast.Add, "AugAssign_Sub": ast.Sub, "AugAssign_Mult": ast.Mult, "AugAssign_Div": ast.Div, } rev_mappings = {v: k for k, v in aug_mappings.items()} idx_op = rev_mappings.get(type(node.op), None) # edge case protection in case the mapping isn't known for substitution # in that instance, return the node and take no action if not idx_op: LOGGER.debug( "%s (%s, %s): unknown aug_assignment: %s", log_header, node.lineno, node.col_offset, type(node.op), ) return node node_span = NodeSpan(node) idx = LocIndex( ast_class="AugAssign", lineno=node_span.lineno, col_offset=node_span.col_offset, op_type=idx_op, end_lineno=node_span.end_lineno, end_col_offset=node_span.end_col_offset, ) self.locs.add(idx) if idx == self.target_idx and self.mutation in aug_mappings and not self.readonly: LOGGER.debug("%s mutating idx: %s with %s", log_header, self.target_idx, self.mutation) return ast.copy_location( ast.AugAssign( target=node.target, op=aug_mappings[self.mutation] (), # awkward syntax to call type from mapping value=node.value, ), node, ) LOGGER.debug("%s (%s, %s): no mutations applied.", log_header, node.lineno, node.col_offset) return node
def visit_BinOp(self, node): op_count_incr = self._count_increasement_each_time(node) for i in range(4): node.parent.parent.body.append(ast.AugAssign(\ target=ast.Subscript(value=ast.Name(id='_count', ctx=ast.Load()), \ slice=ast.Index(value=ast.Num(n=i)), ctx=ast.Store()),op=ast.Add(), \ value=ast.Num(n=int(op_count_incr[i])))) return node
def visit_AugAssign(self, node: AugAssign, *args, **kwargs) -> C.AugAssign: target = self.visit(node.target, *args, **kwargs) op = self.visit(node.op, *args, **kwargs) value = self.visit(node.value, *args, **kwargs) return C.AugAssign( target=target, op=op, value=value, )
def visit_Expr(self, node): if self._get_template_type() is not None: node = self.generic_visit(node) # Instead of discarding objects on the stack, call # "_q_output += obj". lval = ast.Name(id='_q_output', ctx=ast.Store()) ast.copy_location(lval, node) aug = ast.AugAssign(target=lval, op=ast.Add(), value=node.value) return ast.copy_location(aug, node) else: return node
def visit_Assert(self, node): """Replace assertions with augmented assignments.""" self.max_score += 1 return ast.AugAssign(op=ast.Add(), target=ast.Name(id=self.score_var_name, ctx=ast.Store()), value=ast.Call(args=[node.test], func=ast.Name(id='bool', ctx=ast.Load()), keywords=[], kwargs=None, starargs=None))
def _make_for_loops_while(parent_node, names_in_use): """Converts for loops into while loops. Creates an index variable and a call to the len() function as a test for the while loop. All for loop iterators must be indexable. DOES NOT SUPPOT NONINDEXABLE ITERATORS. Parameters: parent_node: ast node Returns: parent node with updates""" #get every index of for loop objects in the body of parent node. Could be done cleaner with a numpy .where, #but we'd have to import numpy pretty much just for that. try: indices_of_for_loops = list(filter(lambda index: isinstance(parent_node.body[index], ast.For), range(len(parent_node.body)))) except: #node has no body. No for loops in it. return parent_node, names_in_use for for_loop_index in indices_of_for_loops: for_loop = parent_node.body[for_loop_index] #make loop incrementor variable name_incrementor_variable = _new_name('loop_index', names_in_use) names_in_use[name_incrementor_variable] = 1 #make a call to built in len() function with the iterator provided in the for loop len_builtin_function = ast.Name(id='len', ctx=ast.Load) len_function_call = ast.Call(func=len_builtin_function, args=[for_loop.iter], keywords=[]) #test for while loop compare_op = ast.Compare(ast.Name(name_incrementor_variable, ctx=ast.Load), ops=[ast.Lt()], comparators=[len_function_call]) #assign current value of loop to for loop target assign_to_for_loop_target = ast.Assign([for_loop.target], ast.Subscript(for_loop.iter, ast.Index(ast.Name(id=name_incrementor_variable, ctx=ast.Load)))) #increment index variable add_1_to_index_variable = ast.AugAssign(ast.Name(id=name_incrementor_variable), ast.Add(), ast.Num(1)) #construct while loop while_loop_body = [assign_to_for_loop_target] + \ for_loop.body + [add_1_to_index_variable] while_loop = ast.While(test=compare_op, body= while_loop_body, orelse=[]) #replace for with while loop parent_node.body[for_loop_index] = while_loop #insert loop incrementor variabel before while loop and set to 0 parent_node.body.insert(for_loop_index - 1, ast.Assign([ast.Name(id=name_incrementor_variable, ctx=ast.Store)], ast.Num(0))) return parent_node, names_in_use
def r_AugAssign(node: ast.Compare, ctx: Context, targets, value): if len(targets) != 1: return target = targets[0] if not isinstance(target, ast.BinOp) or not (isinstance( target.right, ast.Name) and target.right.id == '_'): return target, op = target.left, target.op ctx.assert_lvalue(target) cast_to_ctx(target) return copy_lineinfo(node, ast.AugAssign(target=target, op=op, value=value))
def astconv_expr(expr_astc, ctx, prefix_stmts): children = list(expr_astc.get_children()) if expr_astc.kind.name in ('BINARY_OPERATOR', 'COMPOUND_ASSIGNMENT_OPERATOR'): decl_ref_astc, val_astc = children lvalue_astpy = astconv_expr(decl_ref_astc, ctx, prefix_stmts) lval_val_astpy = ast.Attribute(value=lvalue_astpy, attr='val', ctx=ast.Store()) if expr_astc.kind.name == 'BINARY_OPERATOR': assert expr_astc.operator_kind.name == 'ASSIGN' prefix_stmts.append( ast.Assign(targets=[lval_val_astpy], value=astconv_expr(val_astc, ctx, prefix_stmts))) else: assert expr_astc.operator_kind.name == 'SUB_ASSIGN' prefix_stmts.append( ast.AugAssign(target=lval_val_astpy, op=ast.Sub(), value=astconv_expr(val_astc, ctx, prefix_stmts))) return lvalue_astpy elif expr_astc.kind.name == 'INTEGER_LITERAL': int_tok_astc = expr_astc.get_tokens().next() int_astpy = ast.Num(n=int(int_tok_astc.spelling)) return call(attr('__globals__', 'int'), int_astpy) elif expr_astc.kind.name == 'UNEXPOSED_EXPR': [sub_astc] = children return astconv_expr(sub_astc, ctx, prefix_stmts) elif expr_astc.kind.name == 'DECL_REF_EXPR': if ctx.local_names is not None and \ expr_astc.spelling in ctx.local_names: return attr(expr_astc.spelling) else: return attr('__globals__', expr_astc.spelling) elif expr_astc.kind.name == 'MEMBER_REF_EXPR': struct_astpy = astconv_expr(children[0], ctx, prefix_stmts) return attr(struct_astpy, expr_astc.spelling) elif expr_astc.kind.name == 'INIT_LIST_EXPR': # only valid for initializing lists/struct variables return ast.Tuple(elts=[ astconv_expr(child, ctx, prefix_stmts) for child in children ], ctx=ast.Load()) elif expr_astc.kind.name == 'CALL_EXPR': ctx.enforce_expr_exec = True return call( astconv_expr(children[0], ctx, prefix_stmts), *[astconv_expr(c, ctx, prefix_stmts) for c in children[1:]]) else: raise CompileError('Unsupportet Expression {!r}'.format( expr_astc.kind.name))
def p_statement_assign(self, p): '''statement : NAME EQUALS expr SEMICOLON | NAME augassign expr SEMICOLON ''' name = p[1] value = p[3] target = ast.Name(id=name, ctx=ast.Store()) if p[2] == '=': p[0] = ast.Assign(targets=[ target, ], value=value) else: p[0] = ast.AugAssign(target=target, op=p[2], value=value) p[0].declaration = False
def to_logpdf(self): return ast.AugAssign( target=ast.Name(id="logpdf", ctx=ast.Store()), op=ast.Add(), value=ast.Call( func=ast.Attribute( value=self.distribution, attr="logpdf_sum", ctx=ast.Load(), ), args=[ast.Name(id=self.name, ctx=ast.Load())], keywords=[], ), )
def visit_Assign(self, node): """Replace if possible 'x =' by 'x ?=' XXX Bug for illegal Python code: (a, b) = (a, b) + 5 f(x) = f(x) + 5 """ self.generic_visit(node) if len(node.targets) != 1: return node if not isinstance(node.value, ast.BinOp): return node target = ast.dump(node.targets[0], annotate_fields=False).replace('Store()', 'Load()') if target == ast.dump(node.value.left, annotate_fields=False): # x = x .... return ast.AugAssign(target=node.targets[0], op=node.value.op, value=node.value.right) else: if target == ast.dump(node.value.right, annotate_fields=False): if isinstance(node.value.op, ast.Add): # x = .... + x return ast.AugAssign(target=node.targets[0], op=node.value.op, value=node.value.left) if isinstance(node.value.op, ast.Mult): # x = .... * x return ast.AugAssign(target=node.targets[0], op=node.value.op, value=node.value.left) return node
def visit_Expr(self, node): r = node if isinstance(node.value, ast.Call): funcname = node.value.func.id if funcname == "delay_mu": r = ast.copy_location( ast.AugAssign(target=ast.Name("now", ast.Store()), op=ast.Add(), value=node.value.args[0]), node) elif funcname == "at_mu": r = ast.copy_location( ast.Assign(targets=[ast.Name("now", ast.Store())], value=node.value.args[0]), node) self.generic_visit(r) return r
def visit_Assign(self, node): if isinstance(node.value, ast.Call) \ and isinstance(node.value.func, ast.Name) \ and node.value.func.id in _noise_functions: node.value.func.id = 'havoc' change_v_epsilon = ast.AugAssign(target=ast.Name(id='__V_epsilon', ctx=ast.Store()), op=ast.Add(), value=ast.BinOp( left=ast.Num(1.0), op=ast.Div(), right=node.value.args[0])) return change_v_epsilon, node else: return node
def visit_For(self, node): """ for x in range(a, b, c) is equal to: x := a while (x < b): #x > b in case c < 0 ... x += c """ var_name = node.target.id assert node.iter.func.id == "range", "for doesn't use range()" [a, b, s], comparison = self.visit_range(node.iter.args, var_name) if isinstance(comparison, (ast.Lt, ast.Gt)): test = ast.Compare( left=ast.Name(id=var_name, ctx=ast.Load()), ops=[comparison], comparators=[ast.Constant(value=b, kind=None)], ) else: test = comparison increment_ast = ast.AugAssign( target=ast.Name(id=var_name, ctx=ast.Store()), op=ast.Add(), value=ast.Constant(value=s, kind=None), ) while_translation = [ ast.Assign( targets=[ast.Name(id=var_name, ctx=ast.Store())], value=ast.Constant(value=a, kind=None), type_comment=None, ), ast.While( test=test, body=node.body + [increment_ast], orelse=[], ), ] for cmd in while_translation: self.update_counter() self.print("\t", end="") self.visit(cmd)
def _aug_assign(self, v_type, v1, op, v2, r): assert self.run( [ ast.Assign( [ast_store('test')], v_type(v1), ), ast.AugAssign( ast_store('test'), op(), v_type(v2), ) ], 'test', type(r) ) == r
def visit_Call(self, node): _id = get_call_names_as_string(node.func) local_definitions = self.module_definitions_stack[-1] alias = handle_aliases_in_calls(_id, local_definitions.import_alias_mapping) if alias: definition = local_definitions.get_definition(alias) else: definition = local_definitions.get_definition(_id) # e.g. "request.args.get" -> "get" last_attribute = _id.rpartition('.')[-1] if definition: if definition in self.function_definition_stack: log.debug("Recursion encountered in function %s", _id) return self.add_blackbox_or_builtin_call(node, blackbox=True) if isinstance(definition.node, ast.ClassDef): self.add_blackbox_or_builtin_call(node, blackbox=False) elif isinstance(definition.node, ast.FunctionDef): self.undecided = False self.function_return_stack.append(_id) self.function_definition_stack.append(definition) return self.process_function(node, definition) else: raise Exception('Definition was neither FunctionDef or ' + 'ClassDef, cannot add the function ') elif (not self._within_mutating_call and last_attribute in MUTATORS and isinstance(node.func, ast.Attribute)): # Change list.append(x) ---> list += list.append(x) # This does in fact propagate as we don't know that append returns None fake_aug_assign = ast.AugAssign( target=node.func.value, op=ast.Add, value=node, ) ast.copy_location(fake_aug_assign, node) self._within_mutating_call = True # Don't do this recursively result = self.visit(fake_aug_assign) self._within_mutating_call = False return result elif last_attribute not in BUILTINS: # Mark the call as a blackbox because we don't have the definition return self.add_blackbox_or_builtin_call(node, blackbox=True) return self.add_blackbox_or_builtin_call(node, blackbox=False)