def AsyncFunctionDef(draw, statements) -> ast.AsyncFunctionDef: n = draw(name()) args = draw(arguments()) body = draw(lists(statements, min_size=1, max_size=3)) decorator_list = draw(lists(Name(), min_size=0, max_size=2)) returns = draw(none() | expression()) return ast.AsyncFunctionDef(n, args, body, decorator_list, returns)
def parse(text): """Parses henrio text and returns an ast.Module instance""" psr = prep() sequence = psr.parse(text) walk_tree(sequence) if sequence is None: raise SyntaxError("Failed to parse!") for i, item in enumerate(sequence): if isinstance(item, list): sequence[i:i + 1] = item nseq = [] nseq.extend(runner) nseq.append( ast.AsyncFunctionDef( "__run_file__", ast.arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), sequence, [], None)) nseq.extend(ast.parse("hio.run(__run_file__)").body) mod = ast.Module(nseq) ast.fix_missing_locations(mod) return mod
def p_async_funcdef1(self, p): ''' async_funcdef : ASYNC funcdef ''' async_funcdef = ast.AsyncFunctionDef() funcdef = p[2] for attr in tuple(funcdef._fields) + ('lineno', 'col_offset'): setattr(async_funcdef, attr, getattr(funcdef, attr)) p[0] = async_funcdef
def async_funcdef_statement_visitor( node: concat.parse.AsyncFuncdefStatementNode, ) -> ast.AsyncFunctionDef: """This converts an AsyncFuncdefStatementNode to a Python statement. The statement takes the form of '@... @(lambda f: lambda s,t: s.append(f(s[:],t[:]))) async def name(stack, stash) -> ...: ...'.""" py_func_def = cast( ast.FunctionDef, visitors['funcdef-statement'].visit(node) ) py_node = ast.AsyncFunctionDef( name=node.name, args=py_func_def.args, body=py_func_def.body, decorator_list=py_func_def.decorator_list, returns=py_func_def.returns, ) # NOTE: The stacks passed into the function are copies. coroutine_decorator_string = ( 'lambda f:lambda s,t:s.append(f(s[:],t[:]))' ) coroutine_decorator = cast( ast.Expression, ast.parse(coroutine_decorator_string, mode='eval') ).body py_node.decorator_list.append(coroutine_decorator) return py_node
def make_async(cursor_trail, tree): definition = core_logic.get_node_at_cursor(cursor_trail, tree) if type(definition) == ast.FunctionDef: return ast.AsyncFunctionDef(name=definition.name, args=definition.args, body=definition.body, decorator_list=definition.decorator_list, returns=definition.returns, type_comment=definition.type_comment) if type(definition) == ast.AsyncFunctionDef: return ast.FunctionDef(name=definition.name, args=definition.args, body=definition.body, decorator_list=definition.decorator_list, returns=definition.returns, type_comment=definition.type_comment) if type(definition) == ast.With: return ast.AsyncWith(items=definition.items, body=definition.body, type_comment=definition.type_comment) if type(definition) == ast.AsyncWith: return ast.With(items=definition.items, body=definition.body, type_comment=definition.type_comment) if isinstance(definition, ast.comprehension): # Toggle the async definition.is_async = 0 if definition.is_async == 1 else 1 return definition
def visit_AsyncFunctionDef(self, node): new_node = ast.AsyncFunctionDef( self._visit(node.name), self._visit(node.args), self._visit(node.body), self._visit(node.decorator_list), self._visit(node.returns), ) return ast.copy_location(new_node, node)
def _gf(body): # args: c, client, m, message, executing, r, reply, _ueri func = ast.AsyncFunctionDef('ex', ast.arguments([], [ast.arg(i, None, None) for i in ['c', 'client', 'm', 'message', 'executing', 'r', 'reply', '_ueri']], None, [], [], None, []), body, [], None, None) ast.fix_missing_locations(func) mod = ast.parse('') mod.body = [func] fl = locals().copy() exec(compile(mod, '<ast>', 'exec'), globals(), fl) return fl['ex']
async def meval(code, **kwargs): # This function is released in the public domain. Feel free to kang it (although I like credit) # Note to self: please don't set globals here as they will be lost. # Don't clutter locals locs = {} # Restore globals later globs = globals().copy() # This code saves __name__ and __package into a kwarg passed to the function. # It is set before the users code runs to make sure relative imports work global_args = "_globs" while global_args in globs.keys(): # Make sure there's no name collision, just keep prepending _s global_args = "_" + global_args kwargs[global_args] = {} for glob in ["__name__", "__package__"]: # Copy data to args we are sending kwargs[global_args][glob] = globs[glob] root = ast.parse(code, "exec") code = root.body if isinstance(code[-1], ast.Expr): # If we can use it as a lambda return (but multiline) code[-1] = ast.copy_location(ast.Return(code[-1].value), code[-1]) # Change it to a return statement # globals().update(**<global_args>) glob_copy = ast.Expr(ast.Call(func=ast.Attribute(value=ast.Call(func=ast.Name(id="globals", ctx=ast.Load()), args=[], keywords=[]), attr="update", ctx=ast.Load()), args=[], keywords=[ast.keyword(arg=None, value=ast.Name(id=global_args, ctx=ast.Load()))])) ast.fix_missing_locations(glob_copy) code.insert(0, glob_copy) args = [] for a in list(map(lambda x: ast.arg(x, None), kwargs.keys())): ast.fix_missing_locations(a) args += [a] args = ast.arguments(args=[], vararg=None, kwonlyargs=args, kwarg=None, defaults=[], kw_defaults=[None for i in range(len(args))]) if int.from_bytes(importlib.util.MAGIC_NUMBER[:-2], 'little') >= 3410: args.posonlyargs = [] fun = ast.AsyncFunctionDef(name="tmp", args=args, body=code, decorator_list=[], returns=None) ast.fix_missing_locations(fun) mod = ast.parse("") mod.body = [fun] comp = compile(mod, "<string>", "exec") exec(comp, {}, locs) r = await locs["tmp"](**kwargs) if isinstance(r, types.CoroutineType): r = await r # workaround for 3.5 try: globals().clear() # Inconsistent state finally: globals().update(**globs) return r
async def meval(code, **kwargs): # Note to self: please don't set globals here as they will be lost. # Don't clutter locals locs = {} # Restore globals later globs = globals().copy() # This code saves __name__ and __package into a kwarg passed to the function. # It is set before the users code runs to make sure relative imports work global_args = "_globs" while global_args in globs.keys(): # Make sure there's no name collision, just keep prepending _s global_args = "_" + global_args kwargs[global_args] = {} for glob in ["__name__", "__package__"]: # Copy data to args we are sending kwargs[global_args][glob] = globs[glob] root = ast.parse(code, "exec") code = root.body if isinstance(code[-1], ast.Expr): # If we can use it as a lambda return (but multiline) code[-1] = ast.copy_location(ast.Return(code[-1].value), code[-1]) # Change it to a return statement # globals().update(**<global_args>) glob_copy = ast.Expr(ast.Call(func=ast.Attribute(value=ast.Call(func=ast.Name(id="globals", ctx=ast.Load()), args=[], keywords=[]), attr="update", ctx=ast.Load()), args=[], keywords=[ast.keyword(arg=None, value=ast.Name(id=global_args, ctx=ast.Load()))])) glob_copy.lineno = 0 glob_copy.col_offset = 0 ast.fix_missing_locations(glob_copy) code.insert(0, glob_copy) args = [] for a in list(map(lambda x: ast.arg(x, None), kwargs.keys())): a.lineno = 0 a.col_offset = 0 args += [a] fun = ast.AsyncFunctionDef("tmp", ast.arguments(args=[], vararg=None, kwonlyargs=args, kwarg=None, defaults=[], kw_defaults=[None for i in range(len(args))]), code, [], None) fun.lineno = 0 fun.col_offset = 0 mod = ast.parse("") mod.body = [fun] comp = compile(mod, "<string>", "exec") exec(comp, {}, locs) r = await locs["tmp"](**kwargs) try: globals().clear() # Inconsistent state finally: globals().update(**globs) return r
def generate_async_function_def(max_depth=None): from control_flow import generate_block name = generate_variable_name() args = _generate_arguments(max_depth=max_depth) body = generate_block(max_depth=max_depth) num_decorators = random.choice([0, 0, 0, 0, 0, 1, 1, 2]) decorator_list = [generate_variable() for _ in range(num_decorators)] returns = random.choice([generate_variable()] + [None] * 4) return ast.AsyncFunctionDef(name, args, body, decorator_list, returns)
def test_docstring(self): body = [] # AST nodes having docstring must accept empty body x = ast.Module(body, "module docstring") self.assertEqual(x.docstring, "module docstring") a = ast.arguments() x = ast.FunctionDef("x", a, body, [], None, "func docstring") self.assertEqual(x.docstring, "func docstring") x = ast.AsyncFunctionDef("x", a, body, [], None, "async func docstring") self.assertEqual(x.docstring, "async func docstring") x = ast.ClassDef("x", [], [], body, [], "class docstring") self.assertEqual(x.docstring, "class docstring")
def p_async_decl_funcdef(self, p): ''' async_decl_funcdef : ASYNC decl_funcdef ''' decl_funcdef = p[2] funcdef = decl_funcdef.funcdef async_funcdef = ast.AsyncFunctionDef() for attr in tuple(funcdef._fields) + ('lineno', 'col_offset'): setattr(async_funcdef, attr, getattr(funcdef, attr)) ast.fix_missing_locations(async_funcdef) # Skip validate because the original function was already validated async_decl_funcdef = enaml_ast.AsyncFuncDef() async_decl_funcdef.funcdef = async_funcdef async_decl_funcdef.lineno = decl_funcdef.lineno async_decl_funcdef.is_override = decl_funcdef.is_override p[0] = async_decl_funcdef
def visit_AsyncFunctionDef(self, node: AsyncFunctionDef, *args, **kwargs) -> C.AsyncFunctionDef: name = self.visit(node.name, *args, **kwargs) defargs = self.visit(node.args, *args, **kwargs) body = self.visit(node.body, *args, **kwargs) decorators = self.visit(node.decorators, *args, **kwargs) returns = self.visit(node.returns, *args, **kwargs) type_comment = self.visit(node.type_comment, *args, **kwargs) return C.AsyncFunctionDef( name=name, args=defargs, body=body, decorator_list=decorators, returns=returns, type_comment=type_comment, )
def visit_FunctionDef(self, node): args = node.args.args if PY2: # pragma: no cover first_arg_name = args and args[0].id else: # pragma: no cover first_arg_name = args and args[0].arg if first_arg_name and first_arg_name.startswith('__async__'): if self.params[get_fn_param(first_arg_name)]: # pragma: no cover if ASYNC_AWAIT: node = ast.AsyncFunctionDef(**vars(node)) else: node.decorator_list.append( ast.Name(id='coroutine', ctx=ast.Load(), lineno=node.lineno - 1, col_offset=node.col_offset)) args.pop(0) return self.generic_visit(node)
class Ast(): def __init__(self, compiled_proto_path, class_name): self.module = ast.Module(body=[ ast.Import( names=[ast.alias(name=compiled_proto_path, asname=class_name) ]), ast.Import(names=[ast.alias(name='asyncio', asname=None)]) ]) self.root_class = ast.ClassDef(name=class_name, body=[], bases=[], decorator_list=[]) def create_service(self, service_name, body): self.root_class.body.append( ast.ClassDef(name=service_name, body=body, bases=[], decorator_list=[])) def create_method_handler(self, method, request, response, async=False): function_expressions = [] if async: return ast.AsyncFunctionDef(name=method.name, decorator_list=[], args=ast.arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[ast.Pass()]) else: return ast.FunctionDef(name=method.name, decorator_list=[], args=ast.arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[ast.Pass()])
def p_funcdef(p): '''funcdef : FXN VAR fargs body''' if p[2].startswith("__") and p[2].endswith("__"): p[0] = ast.FunctionDef( p[2], ast.arguments(args=[ast.arg(arg=x, annotation=None) for x in p[3]], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), p[4], [], None) else: p[0] = ast.AsyncFunctionDef( p[2], ast.arguments(args=[ast.arg(arg=x, annotation=None) for x in p[3]], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), p[4], [], None)
def visit_FunctionDef(self, node): change_node = False decorator_list = [] for decorator in node.decorator_list: if (isinstance(decorator, ast.Attribute) and decorator.value.id == 'asyncio' and decorator.attr == 'coroutine'): change_node = True else: decorator_list.append(decorator.id) if not change_node: return node return ast.AsyncFunctionDef( name=node.name, args=node.args, body=node.body, decorator_list=decorator_list, returns=node.returns, )
def visit_FunctionDef(self, node): # Ignore special functions like __init__ if node.name.startswith('__') and node.name.endswith('__'): return node magic = False for child in ast.walk(node): if self.is_magic_call(child): magic = True break if not magic: return node node = ast.copy_location( ast.AsyncFunctionDef(name=node.name, args=node.args, body=node.body, decorator_list=node.decorator_list, returns=node.returns), node) node = self.generic_visit(node) return node
def build_method_def( method: ast.FunctionDef ) -> Tuple[ast.FunctionDef, ast.AsyncFunctionDef]: orig = method method = deepcopy(method) rtype_arg = method.decorator_list[0].args[0] # type: ignore method.decorator_list = [] method.returns = rtype_arg # method.returns.id = rtype # type: ignore call, async_call = build_ret(method, rtype_arg) docstring = ast.get_docstring(orig) method.body = [call] if docstring: method.body.insert(0, orig.body[0]) async_method = deepcopy(method) async_method = ast.AsyncFunctionDef( # type: ignore **async_method.__dict__ ) async_method.body[-1] = async_call return method, async_method # type: ignore
def _translate_all_expression_to_a_module( generator_exp: ast.GeneratorExp, generated_function_name: str, name_to_value: Mapping[str, Any]) -> ast.Module: """ Generate the AST of the module to trace an all quantifier on an generator expression. :param generator_exp: generator expression to be translated :param generated_function_name: UUID of the tracing function to be used in the code :param name_to_value: mapping of all resolved values to the variable names (passed as arguments to the function so that the generation can access them) :return: translation to a module """ assert generated_function_name not in name_to_value assert not hasattr(builtins, generated_function_name) # Collect all the names involved in the generation relevant_names = _collect_stored_names( generator.target for generator in generator_exp.generators) assert generated_function_name not in relevant_names # Work backwards, from the most-inner block outwards result_id = 'icontract_tracing_all_result_{}'.format(uuid.uuid4().hex) result_assignment = ast.Assign( targets=[ast.Name(id=result_id, ctx=ast.Store())], value=generator_exp.elt) exceptional_return = ast.Return( ast.Tuple(elts=[ ast.Name(id=result_id, ctx=ast.Load()), ast.Tuple(elts=[ ast.Tuple(elts=[ ast.Constant(value=relevant_name, kind=None), ast.Name(id=relevant_name, ctx=ast.Load()) ], ctx=ast.Load()) for relevant_name in relevant_names ], ctx=ast.Load()) ], ctx=ast.Load())) # While happy return shall not be executed, we add it here for robustness in case # future refactorings forget to check for that edge case. happy_return = ast.Return( ast.Tuple(elts=[ ast.Name(id=result_id, ctx=ast.Load()), ast.Constant(value=None, kind=None) ], ctx=ast.Load())) critical_if: If = ast.If(test=ast.Name(id=result_id, ctx=ast.Load()), body=[ast.Pass()], orelse=[exceptional_return]) # Previous inner block to be added as body to the next outer block block = None # type: Optional[List[ast.stmt]] for i, comprehension in enumerate(reversed(generator_exp.generators)): if i == 0: # This is the inner-most comprehension. block = [result_assignment, critical_if] assert block is not None for condition in reversed(comprehension.ifs): block = [ast.If(test=condition, body=block, orelse=[])] if not comprehension.is_async: block = [ ast.For(target=comprehension.target, iter=comprehension.iter, body=block, orelse=[]) ] else: block = [ ast.AsyncFor(target=comprehension.target, iter=comprehension.iter, body=block, orelse=[]) ] assert block is not None block.append(happy_return) # Now we are ready to generate the function. is_async = any(comprehension.is_async for comprehension in generator_exp.generators) args = [ ast.arg(arg=name, annotation=None) for name in sorted(name_to_value.keys()) ] if sys.version_info < (3, 5): raise NotImplementedError( "Python versions below 3.5 not supported, got: {}".format( sys.version_info)) if not is_async: if sys.version_info < (3, 8): func_def_node = ast.FunctionDef( name=generated_function_name, args=ast.arguments(args=args, kwonlyargs=[], kw_defaults=[], defaults=[], vararg=None, kwarg=None), decorator_list=[], body=block ) # type: Union[ast.FunctionDef, ast.AsyncFunctionDef] module_node = ast.Module(body=[func_def_node]) else: func_def_node = ast.FunctionDef(name=generated_function_name, args=ast.arguments(args=args, posonlyargs=[], kwonlyargs=[], kw_defaults=[], defaults=[], vararg=None, kwarg=None), decorator_list=[], body=block) module_node = ast.Module(body=[func_def_node], type_ignores=[]) else: if sys.version_info < (3, 8): async_func_def_node = ast.AsyncFunctionDef( name=generated_function_name, args=ast.arguments(args=args, kwonlyargs=[], kw_defaults=[], defaults=[], vararg=None, kwarg=None), decorator_list=[], body=block) module_node = ast.Module(body=[async_func_def_node]) else: async_func_def_node = ast.AsyncFunctionDef( name=generated_function_name, args=ast.arguments(args=args, posonlyargs=[], kwonlyargs=[], kw_defaults=[], defaults=[], vararg=None, kwarg=None), decorator_list=[], body=block) module_node = ast.Module(body=[async_func_def_node], type_ignores=[]) ast.fix_missing_locations(module_node) return module_node
async def meval(code, globs, **kwargs): # Note to self: please don't set globals here as they will be lost. # Don't clutter locals locs = {} # Restore globals later globs = globs.copy() # This code saves __name__ and __package into a kwarg passed to the func. # It is set before the users code runs to make sure relative imports work global_args = "_globs" while global_args in globs.keys(): # Make sure there's no name collision, just keep prepending _s global_args = "_" + global_args kwargs[global_args] = {} for glob in ["__name__", "__package__"]: # Copy data to args we are sending kwargs[global_args][glob] = globs[glob] root = ast.parse(code, "exec") code = root.body ret_name = "_ret" ok = False while True: if ret_name in globs.keys(): ret_name = "_" + ret_name continue for node in ast.walk(root): if isinstance(node, ast.Name) and node.id == ret_name: ret_name = "_" + ret_name break ok = True if ok: break if not code: return None if not any(isinstance(node, ast.Return) for node in code): for i in range(len(code)): if isinstance(code[i], ast.Expr): if i == len(code) - 1 or not isinstance( code[i].value, ast.Call): code[i] = ast.copy_location( ast.Expr( ast.Call( func=ast.Attribute( value=ast.Name(id=ret_name, ctx=ast.Load()), attr="append", ctx=ast.Load(), ), args=[code[i].value], keywords=[], )), code[-1], ) else: for node in code: if isinstance(node, ast.Return): node.value = ast.List(elts=[node.value], ctx=ast.Load()) code.append( ast.copy_location( ast.Return(value=ast.Name(id=ret_name, ctx=ast.Load())), code[-1])) # globals().update(**<global_args>) glob_copy = ast.Expr( ast.Call( func=ast.Attribute( value=ast.Call(func=ast.Name(id="globals", ctx=ast.Load()), args=[], keywords=[]), attr="update", ctx=ast.Load(), ), args=[], keywords=[ ast.keyword(arg=None, value=ast.Name(id=global_args, ctx=ast.Load())) ], )) ast.fix_missing_locations(glob_copy) code.insert(0, glob_copy) ret_decl = ast.Assign( targets=[ast.Name(id=ret_name, ctx=ast.Store())], value=ast.List(elts=[], ctx=ast.Load()), ) ast.fix_missing_locations(ret_decl) code.insert(1, ret_decl) args = [] for a in list(map(lambda x: ast.arg(x, None), kwargs.keys())): ast.fix_missing_locations(a) args += [a] args = ast.arguments( args=[], vararg=None, kwonlyargs=args, kwarg=None, defaults=[], kw_defaults=[None for i in range(len(args))], ) args.posonlyargs = [] fun = ast.AsyncFunctionDef(name="tmp", args=args, body=code, decorator_list=[], returns=None) ast.fix_missing_locations(fun) mod = ast.parse("") mod.body = [fun] comp = compile(mod, "<string>", "exec") exec(comp, {}, locs) r = await locs["tmp"](**kwargs) for i in range(len(r)): if hasattr(r[i], "__await__"): r[i] = await r[i] # workaround for 3.5 i = 0 while i < len(r) - 1: if r[i] is None: del r[i] else: i += 1 if len(r) == 1: [r] = r elif not r: r = None return r
async def meval(code, local_vars): locs = {} globs = globals().copy() global_args = "_globs" while global_args in globs.keys(): global_args = "_" + global_args local_vars[global_args] = {} for glob in ["__name__", "__package__"]: local_vars[global_args][glob] = globs[glob] root = ast.parse(code, "exec") code = root.body if isinstance(code[-1], ast.Expr): code[-1] = ast.copy_location(ast.Return(code[-1].value), code[-1]) glob_copy = ast.Expr( ast.Call( func=ast.Attribute( value=ast.Call(func=ast.Name(id="globals", ctx=ast.Load()), args=[], keywords=[]), attr="update", ctx=ast.Load(), ), args=[], keywords=[ ast.keyword(arg=None, value=ast.Name(id=global_args, ctx=ast.Load())) ], )) ast.fix_missing_locations(glob_copy) code.insert(0, glob_copy) args = [] for a in list(map(lambda x: ast.arg(x, None), local_vars.keys())): ast.fix_missing_locations(a) args += [a] args = ast.arguments( args=[], vararg=None, kwonlyargs=args, kwarg=None, defaults=[], kw_defaults=[None for i in range(len(args))], ) if int.from_bytes(importlib.util.MAGIC_NUMBER[:-2], "little") >= 3410: args.posonlyargs = [] fun = ast.AsyncFunctionDef(name="tmp", args=args, body=code, decorator_list=[], returns=None) ast.fix_missing_locations(fun) mod = ast.parse("") mod.body = [fun] comp = compile(mod, "<string>", "exec") exec(comp, {}, locs) r = await locs["tmp"](**local_vars) if isinstance(r, types.CoroutineType) or isinstance(r, Future): r = await r try: globals().clear() finally: globals().update(**globs) return r
import ast import pytest from astvalidate.validators.simple import SimpleASTValidator @pytest.mark.parametrize( "node", [ ast.FunctionDef(body=[]), ast.AsyncFunctionDef(body=[]), ast.arguments( defaults=[1], posonlyargs=[], args=[], kw_defaults=[], kwonlyargs=[], ), ast.arguments( defaults=[], posonlyargs=[], args=[], kw_defaults=[1], kwonlyargs=[], ), ast.AnnAssign(simple=True, target=ast.Tuple(ast.Name("a", ast.Load()))), ast.With(items=[]), ast.Raise(exc=None, cause=1), ast.Try(body=[]),
def test_bad_ast_type(self): err = 'Line 1 : S1- Illegal contracting syntax type used : AsyncFunctionDef' t = ast.AsyncFunctionDef() self.l.ast_types(t, 1) self.l.dump_violations() self.assertMultiLineEqual(err, self.l._violations[0])
import ast import pytest from astvalidate.validators.contextual import ContextualASTValidator @pytest.mark.parametrize( "node, message", [ (ast.Return(), "inside of a function"), ( ast.AsyncFunctionDef(body=[ast.Yield(), ast.Return(1)]), "can't be part of async gen", ), (ast.Continue(), "inside of a loop"), (ast.Break(), "inside of a loop"), (ast.AsyncFor(), "inside of a coroutine"), ( ast.Try(handlers=[ ast.ExceptHandler(type=None), ast.ExceptHandler(type=1), ]), "must be placed last", ), ( ast.Module([1, 2, ast.ImportFrom("__future__")]), "must occur at the top", ), ( ast.Module(