def separate_assing_nodes(self, node: _ast.Assign, variables_names, variables): if isinstance(node.targets[0], _ast.Tuple): tuple_key = meta.values_for_ast_type[type(node.targets[0])] for num, target_node in enumerate( getattr(node.targets[0], tuple_key)): if isinstance(node.value, _ast.Tuple): inner_value = getattr(node.value, tuple_key)[num] else: node_value = self.get_value(node.value, variables_names, variables) if isinstance(node_value, dict): inner_value = _ast.Subscript( value=node.value, slice=_ast.Index(value=_ast.Num(n=num))) else: inner_value = node_value var = _ast.Assign(targets=[target_node], value=inner_value) yield var elif isinstance(node.value, _ast.List): for target in node.targets: for elem in node.value.elts: # for items var = _ast.Assign(targets=[target], value=elem) yield var elif isinstance(node.value, _ast.Call): value = self.get_value(node.value, variables_names, variables) for target in node.targets: # for items in call result var = _ast.Assign(targets=[target], value=value) yield var
def visit_AnnAssign(self, node, stmts, direct_assign): assert not direct_assign node.value = self.flatten(node.value, stmts, True) if isinstance(node.target, _ast.Name): return _ast.Assign(targets=[node.target], value=node.value) cur_id = self.new_temp_id() stmts.append(_ast.Assign(targets[cur_id], value=node.value)) return _ast.Assign(targets[node.target], value=cur_id)
def visit_AugAssign(self, node, stmts, direct_assign): assert not direct_assign value = self.flatten( _ast.BinOp(left=node.target, right=node.value, op=node.op), stmts, True) if isinstance(node.target, _ast.Name): return _ast.Assign(targets=[node.target], value=value) cur_id = self.new_temp_id() stmts.append(_ast.Assign(targets=[cur_id], value=value)) return _ast.Assign(targets=[node.target], value=cur_id)
def transform(node): # transform the targets in for/with clauses to assignment nodes if isinstance(node, _ast.For): a = _ast.Assign() a.targets = [node.target] yield a elif isinstance(node, _ast.With) and node.optional_vars: a = _ast.Assign() a.targets = [node.optional_vars] yield a yield node
class ConstructorNonAttribsValueLineNumberFixture: definition_is_none = None definition__is_not_a_function = _ast.Pass definitions_is_not_a_constructor = _ast.FunctionDef(name='test', body=[_ast.Expr(lineno=1)]) definitions_consist_of_assign_with_attribute = _ast.FunctionDef( name='__init__', body=[_ast.Assign(targets=[_ast.Attribute(lineno=2)], lineno=1)], ) definitions_consist_of_assign_without_attribute = _ast.FunctionDef( name='__init__', body=[_ast.Assign(targets=[_ast.Expr(lineno=2)], lineno=1)], ) definitions_consist_of_any_but_not_a_assign = _ast.FunctionDef(name='__init__', body=[_ast.Pass(lineno=3)])
def STORE_NAME(self, instr): value = self.ast_stack.pop() value = self.process_ifexpr(value) if isinstance(value, _ast.Import): if value.from_: assert isinstance(self.ast_stack[-1], _ast.ImportFrom) from_ = self.ast_stack.pop() as_name = instr.arg name = from_.names[0].name if as_name != name: from_.names[0].asname = as_name self.ast_stack.append(from_) else: as_name = instr.arg if value.names[0].asname is None: base_name = value.names[0].name.split('.')[0] if base_name != as_name: value.names[0].asname = as_name self.ast_stack.append(value) elif isinstance(value, (_ast.Attribute)) and isinstance( value.value, (_ast.Import)): asname = instr.arg value = value.value value.names[0].asname = asname self.ast_stack.append(value) elif isinstance(value, (_ast.ClassDef, _ast.FunctionDef)): as_name = instr.arg value.name = as_name self.ast_stack.append(value) elif isinstance(value, _ast.AugAssign): self.ast_stack.append(value) elif isinstance(value, _ast.Assign): _ = self.ast_stack.pop() assname = _ast.Name(instr.arg, _ast.Store(), lineno=instr.lineno, col_offset=0) value.targets.append(assname) self.ast_stack.append(value) else: assname = _ast.Name(instr.arg, _ast.Store(), lineno=instr.lineno, col_offset=0) assign = _ast.Assign(targets=[assname], value=value, lineno=instr.lineno, col_offset=0) self.ast_stack.append(assign)
def ROT_TWO(self, instr): one = self.ast_stack.pop() two = self.ast_stack.pop() if self.ilst[0].opname == 'STORE_NAME': kw = dict(lineno=instr.lineno, col_offset=0) stores = [] while self.ilst[0].opname == 'STORE_NAME': stores.append(self.ilst.pop(0)) assert len(stores) <= 3, stores elts_load = [one, two] if len(stores) == 3: elts_load.insert(0, self.ast_stack.pop()) tup_load = _ast.Tuple(elts=elts_load[::-1], ctx=_ast.Load(), **kw) elts_store = [ _ast.Name(id=store.arg, ctx=_ast.Store(), **kw) for store in stores ] tup_store = _ast.Tuple(elts=elts_store, ctx=_ast.Store(), **kw) assgn = _ast.Assign(value=tup_load, targets=[tup_store], **kw) self.ast_stack.append(assgn) # self.ast_stack.append(tup_store) else: self.ast_stack.append(one) self.ast_stack.append(two)
def UNPACK_SEQUENCE(self, instr): nargs = instr.oparg nodes = [] ast_tuple = _ast.Tuple(elts=nodes, ctx=_ast.Store(), lineno=instr.lineno, col_offset=0) for i in range(nargs): nex_instr = self.ilst.pop(0) self.ast_stack.append(None) self.visit(nex_instr) node = self.ast_stack.pop() nodes.append(node.targets[0]) expr = self.ast_stack.pop() if isinstance(expr, _ast.Assign): assgn = expr assgn.targets.append(ast_tuple) value_dup = self.ast_stack.pop() assert cmp_ast(assgn.value, value_dup) else: assgn = _ast.Assign(targets=[ast_tuple], value=expr, lineno=instr.lineno, col_offset=0) self.ast_stack.append(assgn)
def make_assign_unpack(i, bytecode, unpack_num=-1): if unpack_num < 1: logger.error("Could not find the number of unpacked items. ") return i, None store_exprs = [] value_exprs = [] store_state, value_state = True, False while i >= 0: op, arg = bytecode[i][2], bytecode[i][3] if store_state: if op == UNPACK_SEQUENCE: store_state = False prev_op = bytecode[i - 1][2] if i > 0 else -1 if prev_op == BUILD_TUPLE: value_state = True else: i, value_exprs = Statement.make_expr(i - 1, bytecode) break elif op in STORE_OPCODES: i, store_stmt = Statement.make_expr(i, bytecode, context=_ast.Store()) store_exprs.insert(0, store_stmt) elif value_state: i, value_stmt = Statement.make_expr(i, bytecode) value_exprs.insert(0, value_stmt) i -= 1 store_exprs = _ast.Tuple(store_exprs, _ast.Store()) if not isinstance(value_exprs, _ast.AST): value_exprs = _ast.Tuple(value_exprs, _ast.Load()) return i, _ast.Assign([store_exprs], value_exprs)
def make_assign_opt_unpack(i, bytecode): store_exprs = [] value_exprs = [] store_state, value_state = True, False while i >= 0: op, arg = bytecode[i][2], bytecode[i][3] if store_state: if op == ROT_TWO: prev_op = bytecode[i - 1][2] if i > 0 else -1 if prev_op == ROT_THREE: i -= 1 value_state = True store_state = False elif op in STORE_OPCODES: i, store_stmt = Statement.make_expr(i, bytecode, context=_ast.Store()) store_exprs.insert(0, store_stmt) elif value_state: i, value_stmt = Statement.make_expr(i, bytecode) value_exprs.insert(0, value_stmt) i -= 1 store_exprs = _ast.Tuple(store_exprs, _ast.Store()) if not isinstance(value_exprs, _ast.AST): value_exprs = _ast.Tuple(value_exprs, _ast.Load()) return i, _ast.Assign([store_exprs], value_exprs)
def new_assign(self, node, stmts): node = self.flatten(node, stmts, True) if isinstance(node, SINGLETON_TYPES): return node new_id = self.new_temp_id() stmts.append(_ast.Assign([new_id], node)) return new_id
def to_assign(self, value): """Takes a value, creates a random temporary identifier for it, and creates an Assign node, assigning the value to the identifier. Parameters ---------- value : ast.AST node that is to be the value of the Assign node Returns ------- out : tuple of string, _ast.Assign the string is the identifier of the node, and the _ast.Assign is the node that was created """ if not isinstance(value, _ast.AST): raise ValueError, "value is not an instance of _ast.AST" iden = self._gen_iden(value) node = _ast.Assign(targets=[ast.parse(iden).body[0].value], value=value) return iden, node
class SetEncapsulatedAttribsLineNumbersFixture: definition_is_none = None definition_is_pass = _ast.Pass() is_constructor = _ast.FunctionDef(name='__init__') without_assign = _ast.FunctionDef(name='test', body=[_ast.Pass()]) with_assign_without_self = _ast.FunctionDef( name='test', body=[ _ast.Pass(), _ast.Assign(targets=[_ast.Attribute(value=(_ast.Name(id='test')), lineno=1)]), ], ) with_assign_with_self = _ast.FunctionDef( name='test', body=[ _ast.Pass(), _ast.Assign(targets=[_ast.Attribute(value=(_ast.Name(id='self')), lineno=1)]), ], )
class ConstructorMutableAttribsLineNumberFixture: definition_is_none = None definition_is_not_a_function = _ast.Pass constructor_with_empty_body = _ast.FunctionDef(name='__init__', body=[]) try: constructor_with_immutable = _ast.FunctionDef( name='__init__', body=[ _ast.Assign(lineno=1, value=_ast.Tuple(elts=[1, 2, 3])), _ast.Assign(lineno=2, value=_ast.Str(s='a')), ], ) except (AttributeError): constructor_with_immutable = _ast.FunctionDef( name='__init__', body=[ _ast.Assign(lineno=1, value=_ast.Tuple(elts=[1, 2, 3])), _ast.Assign(lineno=3, value=_ast.JoinedStr(values=None)), ], ) constructor_with_mutable = _ast.FunctionDef( name='__init__', body=[ _ast.Assign(lineno=1, value=_ast.List(elts=[1, 2, 3])), _ast.Assign(lineno=2, value=_ast.Set(elts=[1, 2, 3])), _ast.Assign(lineno=3, value=_ast.Dict(keys=['a'])), ], )
def process_for_node(self, node, variables_names, variables): for var in self.separate_assing_nodes(_ast.Assign(targets=[node.target], value=node.iter), variables_names, variables): variables.append(var) _index = len(variables) - 1 variables_names[var.targets[0].id] = _index for inner_node in node.body: self.process_body_node(inner_node, variables_names, variables) return variables
class ReturnedValueFixture: node_is_none = None assign_expression_as_input = _ast.Assign(lineno=1) pass_expression_as_input = _ast.Pass(lineno=1) plain_expression_as_input = _ast.Expr(lineno=1) function_body_is_empty = _ast.FunctionDef(lineno=1, body=[]) function_body_without_return_expression = _ast.FunctionDef( lineno=1, body=[_ast.Pass(), _ast.Expr(), _ast.Assign], ) function_body_with_return_expression = _ast.FunctionDef( lineno=1, body=[ _ast.Pass(), _ast.Expr(), _ast.Assign(), _ast.Return(lineno=1, value=None) ], )
def STORE_ATTR(self, instr): attrname = instr.arg node = self.ast_stack.pop() expr = self.ast_stack.pop() expr = self.process_ifexpr(expr) assattr = _ast.Attribute(value=node, attr=attrname, ctx=_ast.Store(), lineno=instr.lineno, col_offset=0) set_attr = _ast.Assign(targets=[assattr], value=expr, lineno=instr.lineno, col_offset=0) self.ast_stack.append(set_attr)
def STORE_SLICE_0(self, instr): 'obj[:] = expr' value = self.ast_stack.pop() expr = self.ast_stack.pop() kw = dict(lineno=instr.lineno, col_offset=0) slice = _ast.Slice(lower=None, step=None, upper=None, **kw) subscr = _ast.Subscript(value=value, slice=slice, ctx=_ast.Store(), **kw) assign = _ast.Assign(targets=[subscr], value=expr, **kw) self.ast_stack.append(assign)
class StaticOrPrivateFixture: definition_is_assign = _ast.Assign() definition_is_pass = _ast.Pass() definition_is_expr = _ast.Expr() empty_decorator_list_and_name = _ast.FunctionDef() empty_decorator_list = _ast.FunctionDef(name='test') is_private = _ast.FunctionDef(name='_test') is_protected = _ast.FunctionDef(name='__test') is_magic = _ast.FunctionDef(name='__test__') decorated = _ast.FunctionDef(name='test', decorator_list=['any_decorator']) is_static = _ast.FunctionDef( name='test', decorator_list=[_ast.FunctionDef(id='staticmethod')], )
def make_assign(i, bytecode): op = bytecode[i][2] if op == STORE_SUBSCR: return Statement.make_subscript(i, bytecode) prev_op = bytecode[i - 1][2] if i > 0 else -1 if prev_op in INPLACE_OPCODES: in_cls = Statement.INPLACE_OPERATORS[prev_op] i -= 1 i, rhs = Statement.make_expr(i - 1, bytecode, context=_ast.AugStore()) i, lhs = Statement.make_expr(i - 1, bytecode, context=_ast.AugLoad()) return i, _ast.AugAssign(lhs, in_cls(), rhs) else: # We can either have multiple assignments: a = b = c = 1 # or unpacked sequences: a, b = 1, foo() # the compiler does some optimization so that: a, b = c, d # does not rely on UNPACK_SEQUENCE, but a ROT_TWO (or ROT_THREE & ROT_TWO for 3 elements). # This happens for 2 or 3 elements to unpack targets = [] value = None has_unpack, has_ROT_2_3, has_multiple = False, False, 0 num_unpack = -1 j = i while j >= 0: op = bytecode[j][2] if op == UNPACK_SEQUENCE: has_unpack = True num_unpack = bytecode[j][3] break elif op in (ROT_TWO, ROT_THREE): has_ROT_2_3 = True break if op == DUP_TOP: has_multiple += 1 j -= 1 if has_unpack: return Statement.make_assign_unpack(i, bytecode, unpack_num=num_unpack) elif has_ROT_2_3: return Statement.make_assign_opt_unpack(i, bytecode) elif has_multiple > 0: return Statement.make_assign_chained(i, bytecode) else: # A simple assignment i, store_expr = Statement.make_expr(i, bytecode) i, value_expr = Statement.make_expr(i - 1, bytecode) return i, _ast.Assign([store_expr], value_expr) return i, None
def STORE_SLICE_2(self, instr): 'obj[:upper] = expr' upper = self.pop_ast_item() value = self.pop_ast_item() expr = self.pop_ast_item() kw = dict(lineno=instr.lineno, col_offset=0) slice = _ast.Slice(lower=None, step=None, upper=upper, **kw) subscr = _ast.Subscript(value=value, slice=slice, ctx=_ast.Store(), **kw) assign = _ast.Assign(targets=[subscr], value=expr, **kw) self.push_ast_item(assign)
def visit_Expr(self, expression_node): value = expression_node.value if not isinstance(value, _ast.BinOp) or not (isinstance( value.op, _ast.RShift) or isinstance(value.op, _ast.LShift)): return expression_node mock_attribute = 'return_value' if isinstance(value.op, _ast.LShift): mock_attribute = 'side_effect' return _ast.Assign(targets=[ _ast.Attribute(attr=mock_attribute, ctx=_ast.Store(), value=value.left.func) ], value=value.right)
def _assign_list_form_variables(self, where_function_ast_node): copy_of_body = copy.deepcopy(where_function_ast_node.body) where_function_ast_node.body = [] for assignment_expression in copy_of_body: variable_name = assignment_expression.targets[0].id self.spec_metadata.add_feature_variable(self.feature_name, variable_name) variable_values = assignment_expression.value where_function_ast_node.body.append( _ast.Assign(targets=[ _ast.Subscript( value=_ast.Name(id='injectable_values', ctx=_ast.Load()), slice=_ast.Index(value=_ast.Str(s=variable_name)), ctx=_ast.Store()) ], value=variable_values))
def make_subscript(i, bytecode, context=None): op = bytecode[i][2] if op == STORE_SUBSCR: # TOS1[TOS] = TOS2 i, index_expr = Statement.make_expr(i - 1, bytecode) i, arr_expr = Statement.make_expr(i - 1, bytecode, context=_ast.Store()) i, rhs_expr = Statement.make_expr(i - 1, bytecode) lhs_expr = _ast.Subscript(arr_expr, index_expr, _ast.Store()) return i, _ast.Assign([lhs_expr], rhs_expr) else: if context is None: context = _ast.Load() # BINARY_SUBSCR: TOS1[TOS] and DELETE_SUBSCR TOS1[TOS] i, index_expr = Statement.make_expr(i - 1, bytecode) i, arr_expr = Statement.make_expr(i - 1, bytecode) return i, _ast.Subscript(arr_expr, index_expr, context)
def STORE_SUBSCR(self, instr): index = self.ast_stack.pop() value = self.ast_stack.pop() expr = self.ast_stack.pop() expr = self.process_ifexpr(expr) if isinstance(expr, _ast.AugAssign): self.ast_stack.append(expr) else: kw = dict(lineno=instr.lineno, col_offset=0) index = self.format_slice(index, kw) subscr = _ast.Subscript(value=value, slice=index, ctx=_ast.Store(), **kw) assign = _ast.Assign(targets=[subscr], value=expr, **kw) self.ast_stack.append(assign)
def test_list_syncing(self): ast = self.ast mod = ast.Module([ast.Lt()]) raises(TypeError, compile, mod, "<string>", "exec") mod = self.get_ast("x = y = 3") assign = mod.body[0] assert len(assign.targets) == 2 assign.targets[1] = ast.Name("lemon", ast.Store(), lineno=0, col_offset=0) name = ast.Name("apple", ast.Store(), lineno=0, col_offset=0) mod.body.append(ast.Assign([name], ast.Num(4, lineno=0, col_offset=0), lineno=0, col_offset=0)) co = compile(mod, "<test>", "exec") ns = {} exec co in ns assert "y" not in ns assert ns["x"] == ns["lemon"] == 3 assert ns["apple"] == 4
def _assign_matrix_form_variables(self, where_function_ast_node): copy_of_body = copy.deepcopy(where_function_ast_node.body) where_function_ast_node.body = [] variables_and_values = WhereBlockFunctions._get_variables_and_values(copy_of_body) # We might be screwing with line numbers here for variable_name, variable_values in variables_and_values.items(): self.spec_metadata.add_feature_variable(self.feature_name, variable_name) where_function_ast_node.body.append( _ast.Assign( targets=[ _ast.Subscript( value=_ast.Name(id='injectable_values', ctx=_ast.Load()), slice=_ast.Index(value=ast_proxy.ast_str(s=variable_name)), ctx=_ast.Store() ) ], value=_ast.List(elts=variable_values, ctx=_ast.Load()) ))
def visit_Assign(self, node, stmts, direct_assign): assert not direct_assign node.value = self.flatten(node.value, stmts, True) if len(node.targets) == 1 and isinstance(node.targets[0], _ast.Name): return node cur_id = None for target in node.targets: if isinstance(target, _ast.Name): cur_id = target break if cur_id is None: cur_id = self.new_temp_id() node.targets.append(cur_id) stmts.append(_ast.Assign(targets=[cur_id], value=node.value)) node.value = cur_id node.targets.remove(cur_id) return node
def STORE_SLICE_3(self, instr): 'obj[lower:upper] = expr' upper = self.ast_stack.pop() lower = self.ast_stack.pop() value = self.ast_stack.pop() expr = self.ast_stack.pop() kw = dict(lineno=instr.lineno, col_offset=0) slice = _ast.Slice(lower=lower, step=None, upper=upper, **kw) subscr = _ast.Subscript(value=value, slice=slice, ctx=_ast.Store(), **kw) if isinstance(expr, _ast.AugAssign): assign = expr result = cmp_ast(expr.target, subscr) assert result else: assign = _ast.Assign(targets=[subscr], value=expr, **kw) self.ast_stack.append(assign)
def make_store_delete_slice(i, bytecode, context=None): op = bytecode[i][2] is_delete = op in DELETE_SLICE_OPCODES if context is None: context = _ast.Store() if not is_delete else _ast.Del() lhs_expr = None if op in (STORE_SLICE_0, DELETE_SLICE_0): i, lhs_expr = Statement.make_expr(i - 1, bytecode, context=context) lhs_expr = _ast.Subscript(lhs_expr, _ast.Slice(None, None, None), _ast.Store()) elif op in (STORE_SLICE_1, STORE_SLICE_2, DELETE_SLICE_1, DELETE_SLICE_2): i, index_expr = Statement.make_expr(i - 1, bytecode) i, arr_expr = Statement.make_expr(i - 1, bytecode, context=context) args = [None] * 3 index_index = 0 if op in (STORE_SLICE_1, DELETE_SLICE_1) else 1 args[index_index] = index_expr lhs_expr = _ast.Subscript(arr_expr, _ast.Slice(*args), _ast.Store()) else: i, end_index_expr = Statement.make_expr(i - 1, bytecode) i, start_index_expr = Statement.make_expr(i - 1, bytecode) i, arr_expr = Statement.make_expr(i - 1, bytecode, context=context) lhs_expr = _ast.Subscript(arr_expr, _ast.Slice(start_index_expr, end_index_expr, None), _ast.Store()) if is_delete: return i, _ast.Delete([lhs_expr]) else: i, rhs_expr = Statement.make_expr(i - 1, bytecode) return i, _ast.Assign([lhs_expr], rhs_expr)