def _translate_body(self, body, allow_loose_in_edges=False, allow_loose_out_edges=False):
cfg_factory = CfgFactory(self._id_gen)
for child in body:
if isinstance(child, (ast.Assign, ast.AugAssign, ast.Expr)):
cfg_factory.add_stmts(self.visit(child))
elif isinstance(child, ast.If):
cfg_factory.complete_basic_block()
if_cfg = self.visit(child)
cfg_factory.append_cfg(if_cfg)
elif isinstance(child, ast.While):
cfg_factory.complete_basic_block()
while_cfg = self.visit(child)
cfg_factory.append_cfg(while_cfg)
elif isinstance(child, ast.Break):
cfg_factory.complete_basic_block()
break_cfg = self.visit(child)
cfg_factory.append_cfg(break_cfg)
elif isinstance(child, ast.Continue):
cfg_factory.complete_basic_block()
cont_cfg = self.visit(child)
cfg_factory.append_cfg(cont_cfg)
elif isinstance(child, ast.Pass):
if cfg_factory.incomplete_block():
pass
else:
cfg_factory.append_cfg(_dummy_cfg(self._id_gen))
else:
raise NotImplementedError(f"The statement {str(type(child))} is not yet translatable to CFG!")
cfg_factory.complete_basic_block()
if not allow_loose_in_edges and cfg_factory.cfg and cfg_factory.cfg.loose_in_edges:
cfg_factory.prepend_cfg(_dummy_cfg(self._id_gen))
if not allow_loose_out_edges and cfg_factory.cfg and cfg_factory.cfg.loose_out_edges:
cfg_factory.append_cfg(_dummy_cfg(self._id_gen))
return cfg_factory.cfg
python类Pass()的实例源码
def is_stub(node):
"""Check if the function is a stub definition:
For the function to be a stub, it should be fully annotated and should have no body.
The body should be a single `Pass` statement with optional docstring.
"""
if not is_annotated(node):
return False
if len(node.body) == 1 and isinstance(node.body[0], ast.Expr) and isinstance(node.body[0].value, ast.Ellipsis):
return True
return ((len(node.body) == 1 and isinstance(node.body[0], ast.Pass))
or (len(node.body) == 2 and isinstance(node.body[0], ast.Expr) and isinstance(node.body[1], ast.Pass)))
def mutate_ExceptHandler(self, node):
if len(node.body) == 1 and isinstance(node.body[0], ast.Pass):
raise MutationResign()
return ast.ExceptHandler(type=node.type, name=node.name, body=[ast.Pass()])
def mutate_Assign(self, node):
if len(node.targets) > 1:
raise MutationResign()
if isinstance(node.targets[0], ast.Name) and self.is_overridden(node, name=node.targets[0].id):
return ast.Pass()
elif isinstance(node.targets[0], ast.Tuple) and isinstance(node.value, ast.Tuple):
return self.mutate_unpack(node)
else:
raise MutationResign()
def mutate_FunctionDef(self, node):
if self.is_overridden(node):
return ast.Pass()
raise MutationResign()
def mutate_FunctionDef(self, node):
if not self.should_mutate(node):
raise MutationResign()
index, _ = self.get_super_call(node)
if index is None:
raise MutationResign()
node.body[index] = ast.Pass()
return node
def mutate_Return(self, node):
return ast.Pass()
def mutate_Expr(self, node):
if utils.is_docstring(node.value):
raise MutationResign()
return ast.Pass()
def test_funcdef(self):
a = ast.arguments([], None, [], [], None, [])
f = ast.FunctionDef("x", a, [], [], None)
self.stmt(f, "empty body on FunctionDef")
f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
None)
self.stmt(f, "must have Load context")
f = ast.FunctionDef("x", a, [ast.Pass()], [],
ast.Name("x", ast.Store()))
self.stmt(f, "must have Load context")
def fac(args):
return ast.FunctionDef("x", args, [ast.Pass()], [], None)
self._check_arguments(fac, self.stmt)
def test_for(self):
x = ast.Name("x", ast.Store())
y = ast.Name("y", ast.Load())
p = ast.Pass()
self.stmt(ast.For(x, y, [], []), "empty body on For")
self.stmt(ast.For(ast.Name("x", ast.Load()), y, [p], []),
"must have Store context")
self.stmt(ast.For(x, ast.Name("y", ast.Store()), [p], []),
"must have Load context")
e = ast.Expr(ast.Name("x", ast.Store()))
self.stmt(ast.For(x, y, [e], []), "must have Load context")
self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
def test_while(self):
self.stmt(ast.While(ast.Num(3), [], []), "empty body on While")
self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []),
"must have Load context")
self.stmt(ast.While(ast.Num(3), [ast.Pass()],
[ast.Expr(ast.Name("x", ast.Store()))]),
"must have Load context")
def test_if(self):
self.stmt(ast.If(ast.Num(3), [], []), "empty body on If")
i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
self.stmt(i, "must have Load context")
i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], [])
self.stmt(i, "must have Load context")
i = ast.If(ast.Num(3), [ast.Pass()],
[ast.Expr(ast.Name("x", ast.Store()))])
self.stmt(i, "must have Load context")
def visit(self, node):
super().visit(node)
if self.last_node is not None:
fake_node = ast.Pass(lineno=len(self.lines), col_offset=len(self.lines[-1]))
self.generic_visit(fake_node)
def _class_guards(t, x):
t.es6_guard(x, "'class' statement requires ES6")
t.unsupported(x, len(x.bases) > 1, "Multiple inheritance is not supported")
body = x.body
for node in body:
t.unsupported(x, not (isinstance(node, (ast.FunctionDef,
ast.AsyncFunctionDef,
ast.Assign)) or \
_isdoc(node) or isinstance(node, ast.Pass)),
"Class' body members must be functions or assignments")
t.unsupported(x, isinstance(node, ast.Assign) and len(node.targets) > 1,
"Assignments must have only one target")
if len(x.bases) > 0:
assert len(x.bases) == 1
assert not x.keywords, "class '{}', args cannot be keywords".format(x.name)
def get_nontrivial_nodes(self):
# returns ids of nodes that can possibly raise an exception
nodes = []
for node_id, node_obj in self.nodes.items():
node = node_obj.ast_node
if type(node) not in (ast.Break, ast.Continue, ast.Pass, ast.Try):
nodes.append(node_id)
return nodes
def bind_partial(self, *args, **kwds):
"""
Binds the provided positional and keyword arguments
and returns a new ``Function`` object with an updated signature.
"""
# We only need the signature, so clean the function body before eval'ing.
empty_func = self.replace(tree=replace_fields(self.tree, body=[ast.Pass()]))
signature = inspect.signature(empty_func.eval())
bargs = signature.bind_partial(*args, **kwds)
# Remove the bound arguments from the function AST
bound_argnames = set(bargs.arguments.keys())
new_tree = filter_function_def(self.tree, bound_argnames)
# Add assignments for bound parameters
assignments = []
gen_sym = GenSym.for_tree(new_tree)
new_bindings = {}
for name, value in bargs.arguments.items():
node, gen_sym, binding = reify_unwrapped(value, gen_sym)
new_bindings.update(binding)
assignments.append(ast.Assign(
targets=[ast.Name(id=name, ctx=ast.Store())],
value=node))
new_globals = dict(self.globals)
new_globals.update(new_bindings)
new_tree = replace_fields(new_tree, body=assignments + new_tree.body)
return Function(new_tree, new_globals, self.closure_vals, self._compiler_flags)
def test_visit_after():
@ast_transformer
def simplify(node, visit_after, visiting_after, **kwds):
if isinstance(node, ast.If):
if not visiting_after:
visit_after()
return node
# This wouldn't work if we didn't simplify the child nodes first
if (len(node.orelse) == 0 and len(node.body) == 1
and isinstance(node.body[0], ast.Pass)):
return ast.Pass()
else:
return node
else:
return node
node = get_ast(dummy_if)
new_node = simplify(node)
assert_ast_equal(new_node, get_ast(
"""
def dummy_if():
pass
"""))
def _yield_binding_translation_assignments(binding_translations,
ctx_update):
if len(binding_translations) == 0:
yield ast.Pass()
else:
for id, translation in binding_translations.iteritems():
uniq_id = ctx_update[id][0]
yield ast.Assign(
targets=[ast.Name(id=uniq_id)],
value=translation)
def translate_do(self, ctx):
return [ast.Pass()]
def from_definition(cls, code, _sigs=None):
name = code.name
pos = 0
# Determine the arguments, expects something of the form def foo(arg1: num, arg2: num ...
args = []
for arg in code.args.args:
typ = arg.annotation
if not isinstance(arg.arg, str):
raise VariableDeclarationException("Argument name invalid", arg)
if not typ:
raise InvalidTypeException("Argument must have type", arg)
if not is_varname_valid(arg.arg):
raise VariableDeclarationException("Argument name invalid or reserved: " + arg.arg, arg)
if arg.arg in (x.name for x in args):
raise VariableDeclarationException("Duplicate function argument name: " + arg.arg, arg)
parsed_type = parse_type(typ, None, _sigs)
args.append(VariableRecord(arg.arg, pos, parsed_type, False))
if isinstance(parsed_type, ByteArrayType):
pos += 32
else:
pos += get_size_of_type(parsed_type) * 32
# Apply decorators
const, payable, private, public = False, False, False, False
for dec in code.decorator_list:
if isinstance(dec, ast.Name) and dec.id == "constant":
const = True
elif isinstance(dec, ast.Name) and dec.id == "payable":
payable = True
elif isinstance(dec, ast.Name) and dec.id == "private":
private = True
elif isinstance(dec, ast.Name) and dec.id == "public":
public = True
else:
raise StructureException("Bad decorator", dec)
if public and private:
raise StructureException("Cannot use public and private decorators on the same function", code)
if not public and not private and not isinstance(code.body[0], ast.Pass):
raise StructureException("Function visibility must be declared (@public or @private)", code)
# Determine the return type and whether or not it's constant. Expects something
# of the form:
# def foo(): ...
# def foo() -> num: ...
# If there is no return type, ie. it's of the form def foo(): ...
# and NOT def foo() -> type: ..., then it's null
if not code.returns:
output_type = None
elif isinstance(code.returns, (ast.Name, ast.Compare, ast.Subscript, ast.Call, ast.Tuple)):
output_type = parse_type(code.returns, None, _sigs)
else:
raise InvalidTypeException("Output type invalid or unsupported: %r" % parse_type(code.returns, None), code.returns)
# Output type must be canonicalizable
if output_type is not None:
assert isinstance(output_type, TupleType) or canonicalize_type(output_type)
# Get the canonical function signature
sig = name + '(' + ','.join([canonicalize_type(parse_type(arg.annotation, None, _sigs)) for arg in code.args.args]) + ')'
# Take the first 4 bytes of the hash of the sig to get the method ID
method_id = fourbytes_to_int(sha3(bytes(sig, 'utf-8'))[:4])
return cls(name, args, output_type, const, payable, private, sig, method_id)