def make_function(code, defaults=None, lineno=0): from meta.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
def Lambda(body, args=None): """Creates an _ast.Lambda object. Args: body: {_ast.AST} args: {_ast.arguments} Raises: ValueError: If body is a list or tuple. Returns: {_ast.Lambda} """ if isinstance(args, (list, tuple)): raise ValueError( 'Body should be a single element, not a list or tuple') if not args: args = arguments() return _ast.Lambda(args=args, body=body)
def make_function(code, defaults=None, annotations=(), kw_defaults=(), 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]) kwonly_varnames = list(code.co_varnames[code.co_argcount:code.co_argcount + code.co_kwonlyargcount]) co_locals = list(code.co_varnames[code.co_argcount + code.co_kwonlyargcount:]) assert (len(kw_defaults) % 2) == 0 kw_defaults = list(kw_defaults) kw_default_dict = {} while kw_defaults: name = kw_defaults.pop(0) value = kw_defaults.pop(0) kw_default_dict[name.s] = value kw_defaults = [] for argname in kwonly_varnames: kw_defaults.append(kw_default_dict.pop(argname)) #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 = [] annotation_names = [annotation.arg for annotation in annotations] for argname in varnames: if argname in annotation_names: arg = [ annotation for annotation in annotations if annotation.arg == argname ][0] else: arg = _ast.arg(annotation=None, arg=argname, lineno=lineno, col_offset=0) #@UndefinedVariable args.append(arg) kwonlyargs = [] for argname in kwonly_varnames: if argname in annotation_names: arg = [ annotation for annotation in annotations if annotation.arg == argname ][0] else: arg = _ast.arg(annotation=None, arg=argname, lineno=lineno, col_offset=0) #@UndefinedVariable kwonlyargs.append(arg) if 'return' in annotation_names: arg = [ annotation for annotation in annotations if annotation.arg == 'return' ][0] returns = arg.annotation else: returns = None if vararg in annotation_names: arg = [ annotation for annotation in annotations if annotation.arg == vararg ][0] varargannotation = arg.annotation else: varargannotation = None if kwarg in annotation_names: arg = [ annotation for annotation in annotations if annotation.arg == kwarg ][0] kwargannotation = arg.annotation else: kwargannotation = None args = _ast.arguments(args=args, defaults=defaults if defaults else [], kwarg=kwarg, vararg=vararg, kw_defaults=kw_defaults, kwonlyargs=kwonlyargs, kwargannotation=kwargannotation, varargannotation=varargannotation, 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 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=[], returns=returns, lineno=lineno, col_offset=0) return ast_obj
def lambda_expr(args: List[_ast.expr], body: _ast.stmt) -> _ast.Lambda: return _ast.Lambda(args=args, body=body)