我们从Python开源项目中,提取了以下27个代码示例,用于说明如何使用_ast.If()。
def process_ifexpr(self, node): if isinstance(node, _ast.If): test = node.test then = node.body else_ = node.orelse assert len(then) == 1 then = then[0] assert len(else_) == 1 else_ = else_[0] if_exp = _ast.IfExp(test, then, else_, lineno=node.lineno, col_offset=0) return if_exp else: return node
def visitIf(self, node, indent_first=True): self.print('if {:node}:', node.test, level=self.level if indent_first else 0) with self.indenter: if node.body: for expr in node.body: self.visit(expr) else: self.print('pass') if node.orelse and len(node.orelse) == 1 and isinstance(node.orelse[0], _ast.If): self.print('el'); self.visit(node.orelse[0], indent_first=False) elif node.orelse: self.print('else:') with self.indenter: for expr in node.orelse: self.visit(expr) self.print('\n')
def transform_break(item, name=''): if name == '': name = 'tmpbreak{}'.format(randint(0, 2**32)) assignment = ast.parse('{} = Relation(2186646)'.format(name)).body[0] condition = ast.parse('for _ in {}: a()'.format(name)).body[0] body = [assignment, item] new_body = [] for statement in item.body: cond = deepcopy(condition) if isinstance(statement, _ast.If): statement = transform_break(statement, name=name)[1] elif isinstance(statement, _ast.Break): statement = ast.parse('{name} = Way.filter({name})'.format(name=name)).body[0] cond.body = [statement] new_body.append(cond) item.body = new_body if len(item.orelse) > 0: assignment = ast.parse('{}else = Relation(2186646)'.format(name)).body[0] didbreak = ast.parse('for _ in {}: a()'.format(name)).body[0] didbreak.body = ast.parse('{}else = Way.filter({})'.format(name, name)).body condition = ast.parse('for _ in {}else: a()'.format(name)).body[0] condition.body = item.orelse body += [assignment, didbreak, condition] item.orelse = [] return body
def transform_continue(item, name=''): if name == '': name = 'tmpcontinue{}'.format(randint(0, 2**32)) assignment = ast.parse('{} = Relation(2186646)'.format(name)).body[0] condition = ast.parse('for _ in {}: a()'.format(name)).body[0] body = [item] new_body = [assignment] for statement in item.body: cond = deepcopy(condition) if isinstance(statement, _ast.If): statement = transform_continue(statement, name=name)[1] elif isinstance(statement, _ast.Continue): statement = ast.parse('{name} = Way.filter({name})'.format(name=name)).body[0] cond.body = [statement] new_body.append(cond) item.body = new_body return body
def semicolon(self, stmt): if not isinstance(stmt, _ast.If) and not isinstance(stmt, _ast.While) and not isinstance(stmt, _ast.For): return ";" else: return ""
def test_compile_ast(self): fname = __file__ if fname.lower().endswith(('pyc', 'pyo')): fname = fname[:-1] with open(fname, 'r') as f: fcontents = f.read() sample_code = [ ['<assign>', 'x = 5'], ['<ifblock>', """if True:\n pass\n"""], ['<forblock>', """for n in [1, 2, 3]:\n print(n)\n"""], ['<deffunc>', """def foo():\n pass\nfoo()\n"""], [fname, fcontents], ] for fname, code in sample_code: co1 = compile(code, '%s1' % fname, 'exec') ast = compile(code, '%s2' % fname, 'exec', _ast.PyCF_ONLY_AST) self.assertTrue(type(ast) == _ast.Module) co2 = compile(ast, '%s3' % fname, 'exec') self.assertEqual(co1, co2) # the code object's filename comes from the second compilation step self.assertEqual(co2.co_filename, '%s3' % fname) # raise exception when node type doesn't match with compile mode co1 = compile('print(1)', '<string>', 'exec', _ast.PyCF_ONLY_AST) self.assertRaises(TypeError, compile, co1, '<ast>', 'eval') # raise exception when node type is no start node self.assertRaises(TypeError, compile, _ast.If(), '<ast>', 'exec') # raise exception when node has invalid children ast = _ast.Module() ast.body = [_ast.BoolOp()] self.assertRaises(TypeError, compile, ast, '<ast>', 'exec')
def test_compile_ast(self): fname = __file__ if fname.lower().endswith(('pyc', 'pyo')): fname = fname[:-1] with open(fname, 'r') as f: fcontents = f.read() sample_code = [ ['<assign>', 'x = 5'], ['<print1>', 'print 1'], ['<printv>', 'print v'], ['<printTrue>', 'print True'], ['<printList>', 'print []'], ['<ifblock>', """if True:\n pass\n"""], ['<forblock>', """for n in [1, 2, 3]:\n print n\n"""], ['<deffunc>', """def foo():\n pass\nfoo()\n"""], [fname, fcontents], ] for fname, code in sample_code: co1 = compile(code, '%s1' % fname, 'exec') ast = compile(code, '%s2' % fname, 'exec', _ast.PyCF_ONLY_AST) self.assertTrue(type(ast) == _ast.Module) co2 = compile(ast, '%s3' % fname, 'exec') self.assertEqual(co1, co2) # the code object's filename comes from the second compilation step self.assertEqual(co2.co_filename, '%s3' % fname) # raise exception when node type doesn't match with compile mode co1 = compile('print 1', '<string>', 'exec', _ast.PyCF_ONLY_AST) self.assertRaises(TypeError, compile, co1, '<ast>', 'eval') # raise exception when node type is no start node self.assertRaises(TypeError, compile, _ast.If(), '<ast>', 'exec') # raise exception when node has invalid children ast = _ast.Module() ast.body = [_ast.BoolOp()] self.assertRaises(TypeError, compile, ast, '<ast>', 'exec')
def getAlternatives(n): if isinstance(n, (ast.If, ast.TryFinally)): return [n.body] if isinstance(n, ast.TryExcept): return [n.body + n.orelse] + [[hdl] for hdl in n.handlers]
def getAlternatives(n): if isinstance(n, ast.If): return [n.body] if isinstance(n, ast.Try): return [n.body + n.orelse] + [[hdl] for hdl in n.handlers]
def handleNodeDelete(self, node): def on_conditional_branch(): """ Return `True` if node is part of a conditional body. """ current = getattr(node, 'parent', None) while current: if isinstance(current, (ast.If, ast.While, ast.IfExp)): return True current = getattr(current, 'parent', None) return False name = getNodeName(node) if not name: return if on_conditional_branch(): # We cannot predict if this conditional branch is going to # be executed. return if isinstance(self.scope, FunctionScope) and name in self.scope.globals: self.scope.globals.remove(name) else: try: del self.scope[name] except KeyError: self.report(messages.UndefinedName, node, name)
def DICT(self, node): # Complain if there are duplicate keys with different values # If they have the same value it's not going to cause potentially # unexpected behaviour so we'll not complain. keys = [ convert_to_value(key) for key in node.keys ] key_counts = counter(keys) duplicate_keys = [ key for key, count in key_counts.items() if count > 1 ] for key in duplicate_keys: key_indices = [i for i, i_key in enumerate(keys) if i_key == key] values = counter( convert_to_value(node.values[index]) for index in key_indices ) if any(count == 1 for value, count in values.items()): for key_index in key_indices: key_node = node.keys[key_index] if isinstance(key, VariableKey): self.report(messages.MultiValueRepeatedKeyVariable, key_node, key.name) else: self.report( messages.MultiValueRepeatedKeyLiteral, key_node, key, ) self.handleChildren(node)
def ANNASSIGN(self, node): if node.value: # Only bind the *targets* if the assignment has a value. # Otherwise it's not really ast.Store and shouldn't silence # UndefinedLocal warnings. self.handleNode(node.target, node) self.handleNode(node.annotation, node) if node.value: # If the assignment has value, handle the *value* now. self.handleNode(node.value, node)
def handleNodeDelete(self, node): def on_conditional_branch(): """ Return `True` if node is part of a conditional body. """ current = getattr(node, 'parent', None) while current: if isinstance(current, (ast.If, ast.While, ast.IfExp)): return True current = getattr(current, 'parent', None) return False name = getNodeName(node) if not name: return if on_conditional_branch(): # We can not predict if this conditional branch is going to # be executed. return if isinstance(self.scope, FunctionScope) and name in self.scope.globals: self.scope.globals.remove(name) else: try: del self.scope[name] except KeyError: self.report(messages.UndefinedName, node, name)
def make_if(self, instr, left, and_block): block = [instr] + and_block[:-1] maxmax = max(block, key=lambda ins: (0, 0) if (ins.op not in JUMP_OPS) else (self.jump_map.get(ins.oparg, ins.oparg), ins.i)) idx = block.index(maxmax) assert idx is not None hi = self.process_logic(block[:idx + 1]) if hi.right is None and hi.parent is None: if instr.opname == 'POP_JUMP_IF_TRUE': cond = _ast.UnaryOp(op=_ast.Not(), operand=left, lineno=0, col_offset=0) else: cond = left else: cond = self.logic_ast(instr, left, hi) jump = and_block[-1] if jump.opname == 'RETURN_VALUE': body_block = block[idx + 1:] + [jump] else: body_block = block[idx + 1:] body = self.decompile_block(body_block).stmnt() if jump.is_jump: else_block = self.make_block(jump.to, inclusive=False, raise_=False) else: # it is a return else_block = [] if len(else_block): else_ = self.decompile_block(else_block).stmnt() # # if len(else_lst) == 1 and isinstance(else_lst[0], _ast.If): # elif_ = else_lst[0] # tests.extend(elif_.tests) # else_ = elif_.else_ # else: # else_ = else_lst else: else_ = [] if_ = _ast.If(test=cond, body=body, orelse=else_, lineno=instr.lineno, col_offset=0) self.ast_stack.append(if_)
def make_function(code, defaults=None, lineno=0): from ..decompiler.disassemble import disassemble instructions = Instructions(disassemble(code)) stmnts = instructions.stmnt() if code.co_flags & 2: vararg = None kwarg = None varnames = list(code.co_varnames[:code.co_argcount]) co_locals = list(code.co_varnames[code.co_argcount:]) #have var args if code.co_flags & 4: vararg = co_locals.pop(0) #have kw args if code.co_flags & 8: kwarg = co_locals.pop() args = [_ast.Name(id=argname, ctx=_ast.Param(), lineno=lineno, col_offset=0) for argname in varnames] args = _ast.arguments(args=args, defaults=defaults if defaults else [], kwarg=kwarg, vararg=vararg, lineno=lineno, col_offset=0 ) if code.co_name == '<lambda>': if len(stmnts) == 2: if isinstance(stmnts[0], _ast.If) and isinstance(stmnts[1], _ast.Return): assert len(stmnts[0].body) == 1 assert isinstance(stmnts[0].body[0], _ast.Return) stmnts = [_ast.Return(_ast.IfExp(stmnts[0].test, stmnts[0].body[0].value, stmnts[1].value))] assert len(stmnts) == 1, stmnts assert isinstance(stmnts[0], _ast.Return) stmnt = stmnts[0].value ast_obj = _ast.Lambda(args=args, body=stmnt, lineno=lineno, col_offset=0) else: if instructions.seen_yield: return_ = stmnts[-1] assert isinstance(return_, _ast.Return) assert isinstance(return_.value, _ast.Name) assert return_.value.id == 'None' return_.value = None ast_obj = _ast.FunctionDef(name=code.co_name, args=args, body=stmnts, decorator_list=[], lineno=lineno, col_offset=0) return ast_obj