示例#1
0
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
示例#2
0
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)
示例#3
0
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
示例#4
0
def lambda_expr(args: List[_ast.expr], body: _ast.stmt) -> _ast.Lambda:
    return _ast.Lambda(args=args, body=body)