示例#1
0
def make_lambda(expression, args, env=None):
    # type: (ast.Expression, List[str], Dict[str, Any]) -> types.FunctionType
    """
    Create an lambda function from a expression AST.

    Parameters
    ----------
    expression : ast.Expression
        The body of the lambda.
    args : List[str]
        A list of positional argument names
    env : Optional[Dict[str, Any]]
        Extra environment to capture in the lambda's closure.

    Returns
    -------
    func : types.FunctionType
    """
    # lambda *{args}* : EXPRESSION
    lambda_ = ast.Lambda(
        args=ast.arguments(
            posonlyargs=[],
            args=[ast.arg(arg=arg, annotation=None) for arg in args],
            varargs=None,
            varargannotation=None,
            kwonlyargs=[],
            kwarg=None,
            kwargannotation=None,
            defaults=[],
            kw_defaults=[]),
        body=expression.body,
    )
    lambda_ = ast.copy_location(lambda_, expression.body)
    # lambda **{env}** : lambda *{args}*: EXPRESSION
    outer = ast.Lambda(
        args=ast.arguments(
            posonlyargs=[],
            args=[ast.arg(arg=name, annotation=None) for name in (env or {})],
            varargs=None,
            varargannotation=None,
            kwonlyargs=[],
            kwarg=None,
            kwargannotation=None,
            defaults=[],
            kw_defaults=[],
        ),
        body=lambda_,
    )
    exp = ast.Expression(body=outer, lineno=1, col_offset=0)
    ast.fix_missing_locations(exp)
    GLOBALS = __GLOBALS.copy()
    GLOBALS["__builtins__"] = {}
    # pylint: disable=eval-used
    fouter = eval(compile(exp, "<lambda>", "eval"), GLOBALS)
    assert isinstance(fouter, types.FunctionType)
    finner = fouter(**env)
    assert isinstance(finner, types.FunctionType)
    return finner
示例#2
0
def parse_function(tp: ast.Tuple, tail: Node) -> ast.Function:
    lmd = ast.Lambda(None, tail)
    while True:
        elements = tp.elements
        lmd.params = expand_formals(elements[1:])
        if isinstance(elements[0], ast.Name):
            return ast.Function(elements[0], lmd)
        elif isinstance(elements[0], ast.Tuple):
            tp = elements[0]
            lmd = ast.Lambda(None, lmd)
        else:
            raise ParseError(f'Unsupported ast node type {elements[0]}')
示例#3
0
    def generate(self, element:Element, GC:GenerationContext):

        assert GC.domain == ExDom

        acode = element.code
        #assert len(acode) == 3

        with GC.let(domain=ExDom):
            expression_code = GC.generate(acode[2])


        # INCOMPLETE:
        # vararg, kwarg, defaults, kw_defaults
        #
        # - This whole arg section might be way off-track
        # - since anything could be an argument, we might need to check
        #   when generating any expression if we actually need to return an ast.arg object
        #   ..or, could we convert everything (e.g. ast.Name, ast.BoolOp, anything)
        #   to an ast.arg after it's been generated

        args_codes = []
        #with GC.let(domain=ArgDom):
            # for a in acode[1]:
            #     # args_code should be a list of ast.arg objects!
            #     args_codes.append(GC.generate(a))




        arguments_code = ast.arguments(args_codes, )


        return ast.Lambda(arguments_code, expression_code)
示例#4
0
 def visit_Return(self, node):
     newnode = ast.Return(value=ast.Lambda(args=ast.arguments(args=[],
                                                              vararg=None,
                                                              kwarg=None,
                                                              defaults=[]),
                                           body=node.value), )
     return ast.copy_location(newnode, node)
示例#5
0
def make_lambda(expression, args, values):
    def make_arg(name):
        if sys.version_info >= (3, 0):
            return ast.arg(arg=name, annotation=None)
        else:
            return ast.Name(id=arg, ctx=ast.Param(), lineno=1, col_offset=0)

    lambda_ = ast.Lambda(
        args=ast.arguments(
            args=[make_arg(arg) for arg in args + values],
            varargs=None,
            varargannotation=None,
            kwonlyargs=[],
            kwarg=None,
            kwargannotation=None,
            defaults=[ast.Num(i) for i in range(len(values))],
            kw_defaults=[]),
        body=expression.body,
    )
    lambda_ = ast.copy_location(lambda_, expression.body)
    exp = ast.Expression(body=lambda_, lineno=1, col_offset=0)
    ast.dump(exp)
    ast.fix_missing_locations(exp)
    GLOBALS = __GLOBALS.copy()
    GLOBALS["__builtins__"] = {}
    return eval(compile(exp, "<lambda>", "eval"), GLOBALS)
示例#6
0
 def wrap_callable(self, node):
     return ast.Lambda(
         args=ast.arguments(
             args=[ast.Name(id=CVAR_NAME, ctx=ast.Param())], vararg=None, kwarg=None, defaults=[]
         ),
         body=node,
     )
示例#7
0
def _create_ast_lambda(names, body):
    if sys.version_info >= (3, 0):  # change in AST structure for Python 3
        inner_args = [ast.arg(arg=name, annotation=None) for name in names]
        if sys.version_info >= (3, 8):
            args = ast.arguments(
                args=inner_args,
                posonlyargs=[],
                vararg=None,
                kwonlyargs=[],
                kw_defaults=[],
                kwarg=None,
                defaults=[],
            )
        else:
            args = ast.arguments(
                args=inner_args,
                vararg=None,
                kwonlyargs=[],
                kw_defaults=[],
                kwarg=None,
                defaults=[],
            )
    else:
        args = ast.arguments(
            [ast.Name(id=name, ctx=ast.Load()) for name in names])

    return ast.Lambda(args=args, body=body)
示例#8
0
def show_bindings(tree, *, syntax, expander, **kw):
    """[syntax, name] Show all bindings of the macro expander.

    Syntax::

        show_bindings

    This can appear in any expression position, and at run-time evaluates to `None`.

    At macro expansion time, for each macro binding, this prints to `sys.stderr`
    the macro name, and the fully qualified name of the corresponding macro function.

    Any bindings that have an uuid as part of the name are hygienically
    unquoted macros. Those make a per-process global binding across all modules
    and all expander instances.
    """
    if syntax != "name":
        raise SyntaxError("`show_bindings` is an identifier macro only")
    print(format_bindings(expander), file=stderr)
    # Can't just delete the node (return None) if it's in an Expr(value=...).
    #
    # For correct coverage reporting, we can't return a `Constant`, because CPython
    # optimizes away do-nothing constants. So trick the compiler into thinking
    # this is important, by making the expansion result call a no-op function.
    lam = ast.Lambda(args=ast.arguments(posonlyargs=[], args=[], vararg=None,
                                        kwonlyargs=[], kw_defaults=[], kwarg=None,
                                        defaults=[]),
                     body=ast.Constant(value=None))
    return ast.Call(func=lam, args=[], keywords=[])
示例#9
0
def parse_lambda(tp: ast.Tuple) -> ast.Lambda:
    elements = tp.elements
    if len(elements) < 3:
        raise ParseError(f'lambda: bad syntax: {tp}')
    pattern = elements[1]
    body = ast.Block(parse_list(elements[2:]))
    if isinstance(pattern, ast.Name):
        return ast.Lambda(pattern, body)
    elif isinstance(pattern, ast.Tuple):
        formals = expand_formals(pattern.elements)
        if isinstance(formals, ast.Pair) or formals is ast.NULL_PAIR:
            return ast.Lambda(formals, body)
        else:
            raise ParseError('lambda: illegal use of \'.\'')
    else:
        raise ParseError(f'Unsupported ast node type: {pattern}')
示例#10
0
def rewrite_func_as_lambda(f: ast.FunctionDef) -> ast.Lambda:
    '''Rewrite a function definition as a lambda. The function can contain only
    a single return statement. ValueError is throw otherwise.

    Args:
        f (ast.FunctionDef): The ast pointing to the function definition.

    Raises:
        ValueError: An error occurred during the conversion:

    Returns:
        ast.Lambda: A lambda that is the equivalent.

    Notes:

        - It is assumed that the ast passed in won't be altered in place - no deep copy is
          done of the statement or args - they are just re-used.
    '''
    if len(f.body) != 1:
        raise ValueError(
            f'Can handle simple functions of only one line - "{f.name}"'
            f' has {len(f.body)}.')
    if not isinstance(f.body[0], ast.Return):
        raise ValueError(
            f'Simple function must use return statement - "{f.name}" does '
            'not seem to.')

    # the arguments
    args = f.args
    ret = cast(ast.Return, f.body[0])
    return ast.Lambda(args, ret.value)

    return f
示例#11
0
    def lambda_build(args: Union[str, List[str]],
                     l_expr: ast.AST) -> ast.Lambda:
        """
        Given a named argument(s), and an expression, build a `Lambda` AST node.

        Args:
            args:       the string names of the arguments to the lambda. May be a list or a
                        single name
            l_expr:     An AST node that is the body of the lambda.

        Returns:
            The `Lambda` AST node.
        """
        if type(args) is str:
            args = [args]

        ast_args = ast.arguments(
            vararg=None,
            args=[ast.arg(arg=x, annotation=None) for x in args],
            kwonlyargs=[],
            kw_defaults=[],
            kwarg=None,
            defaults=[],
        )
        call_lambda = ast.Lambda(args=ast_args, body=l_expr)

        return call_lambda
示例#12
0
文件: astutil.py 项目: iCodeIN/deco
 def visit_Expr(self, node):
     if type(node.value) is ast.Call:
         call = node.value
         if self.is_concurrent_call(call):
             self.encounter_call(call)
             return node
         elif any([self.is_concurrent_call(arg) for arg in call.args]):
             conc_args = [(i, arg) for i, arg in enumerate(call.args) if self.is_concurrent_call(arg)]
             if len(conc_args) > 1:
                 raise self.not_implemented_error(call, "Functions with multiple @concurrent parameters are unsupported")
             conc_call = conc_args[0][1]
             if isinstance(call.func, ast.Attribute):
                 self.arguments.add(SchedulerRewriter.top_level_name(call.func.value))
             self.encounter_call(conc_call)
             call.args[conc_args[0][0]] = ast.Name("__value__", ast.Load())
             if sys.version_info >= (3, 0):
                 args = [ast.arg("__value__", None)]
             else:
                 args = [ast.Name("__value__", ast.Param())]
             call_lambda = ast.Lambda(ast.arguments(args = args, defaults = [], kwonlyargs = [], kw_defaults = []), call)
             copy_location_kwargs = {
                 "func": ast.Attribute(conc_call.func, 'call', ast.Load()),
                 "args": [call_lambda] + conc_call.args,
                 "keywords": conc_call.keywords
             }
             if(sys.version_info < (3, 0)):
                 copy_location_kwargs["kwargs"] = conc_call.kwargs
             return copy_location(ast.Expr(ast.Call(**copy_location_kwargs)), node)
     return self.generic_visit(node)
示例#13
0
 def make_lazy_arg_node(body):
     args = make_node(
         ast.arguments(args=[],
                       vararg=None,
                       kwarg=None,
                       defaults=[]))
     return make_node(ast.Lambda(args=args, body=body))
示例#14
0
    def __call__(self, selection):
        if not self.is_initialized:
            self._initialize()

        try:
            parse_result = self.expression.parseString(selection, parseAll=True)
        except ParseException as e:
            msg = str(e)
            lines = ["%s: %s" % (msg, selection),
                     " " * (12 + len("%s: " % msg) + (e.loc)) + "^^^"]
            raise ValueError('\n'.join(lines))


        # Change __ATOM__ in function bodies. It must bind to the arg
        # name specified below (i.e. 'atom')
        astnode = self.transformer.visit(deepcopy(parse_result[0].ast()))

        if PY2:
            args = [ast.Name(id='atom', ctx=ast.Param())]
            signature = ast.arguments(args=args, vararg=None, kwarg=None,
                                      defaults=[])
        else:
            args = [ast.arg(arg='atom', annotation=None)]
            signature = ast.arguments(args=args, vararg=None, kwarg=None,
                                      kwonlyargs=[], defaults=[],
                                      kw_defaults=[])

        func = ast.Expression(body=ast.Lambda(signature, astnode))
        source = codegen.to_source(astnode)

        expr = eval(
            compile(ast.fix_missing_locations(func), '<string>', mode='eval'),
            SELECTION_GLOBALS)
        return _ParsedSelection(expr, source, astnode)
 def test_ast_call_with_lambda_results_in_function_call(self):
     ret, _ = self.run_expr(
         ast.Call(func=ast.Lambda(args=[], body=ast.Num(n=1)), args=[], keywords=[]),
         var(),
         env=[],
     )
     self.assertEqual(ret[0], 1)
示例#16
0
    def visit_GeneratorExp(self, node):

        if node in self.optimizable_comprehension:

            self.generic_visit(node)

            iters = [self.make_Iterator(gen) for gen in node.generators]
            variables = [ast.Name(gen.target.id, ast.Param())
                         for gen in node.generators]

            # If dim = 1, product is useless
            if len(iters) == 1:
                iterAST = iters[0]
                varAST = ast.arguments([variables[0]], None, None, [])
            else:
                prodName = ast.Attribute(
                    value=ast.Name(id='itertools', ctx=ast.Load()),
                    attr='product', ctx=ast.Load())

                iterAST = ast.Call(prodName, iters, [], None, None)
                varAST = ast.arguments([ast.Tuple(variables, ast.Store())],
                                       None, None, [])

            imapName = ast.Attribute(
                value=ast.Name(id='itertools', ctx=ast.Load()),
                attr='imap', ctx=ast.Load())

            ldBodyimap = node.elt
            ldimap = ast.Lambda(varAST, ldBodyimap)

            return ast.Call(imapName, [ldimap, iterAST], [], None, None)

        else:
            return self.generic_visit(node)
示例#17
0
 def makeLambda(self, args, call):
     return ast.Lambda(
         ast.arguments(posonlyargs=[],
                       args=args,
                       defaults=[],
                       kwonlyargs=[],
                       kw_defaults=[]), call)
示例#18
0
 def test_lambda(self):
     a = ast.arguments([], None, [], [], None, [])
     self.expr(ast.Lambda(a, ast.Name("x", ast.Store())),
               "must have Load context")
     def fac(args):
         return ast.Lambda(args, ast.Name("x", ast.Load()))
     self._check_arguments(fac, self.expr)
示例#19
0
 def visit_FunctionDef(self, node):
     """Return a lambda instead of a function if the body is only a Return
     node, there are no decorators, and no annotations."""
     # Can't have decorators or a returns annotation.
     if node.decorator_list or node.returns:
         return node
     # Body must be of length 1 and consist of a Return node;
     # can't translate a body consisting of only an Expr node as that would
     # lead to an improper return value (i.e., something other than None
     # potentially).
     if len(node.body) > 1 or not isinstance(node.body[0], ast.Return):
         return node
     args = node.args
     # No annotations for *args or **kwargs.
     if ((args.vararg and args.vararg.annotation)
             or (args.kwarg and args.kwarg.annotation)):
         return node
     # No annotations on any other parameters.
     if any(arg.annotation for arg in args.args):
         return node
     # In the clear!
     return_ = node.body[0].value
     if return_ is None:
         return_ = ast.Name('None', ast.Load())
     lambda_ = ast.Lambda(args, return_)
     return ast.Assign([ast.Name(node.name, ast.Store())], lambda_)
示例#20
0
 def parse_lambda_expression(self):
   self.expect_word('fn')
   if self.at_word('on'):
     self.expect_word('on')
   subject = [self.get_functino_subject()]
   signature = self.parse_functino_signature(subject, False)
   methods = self.parse_functino_tail(signature, subject)
   return ast.Lambda(methods)
示例#21
0
    def visitLambda(self, node):
        body = self.visit(node.body)

        args = ast.arguments(args=[], vararg=None, kwarg=None, defaults=[])

        for var_id in sorted(self.locls.keys()):
            args.args.append(ast.Name(var_id, ast.Param(), **n(node)))
        return ast.Lambda(args, body, **n(node))
    def visit_Lambda(self, node: Lambda, *args, **kwargs) -> C.Lambda:
        defargs = self.visit(node.args, *args, **kwargs)
        body = self.visit(node.body, *args, **kwargs)

        return C.Lambda(
            args=defargs,
            body=body,
        )
示例#23
0
    def composite(self, children):
        fields = []
        for child in children:
            if isinstance(child, lark.Token):
                if child.type == 'NODE_TYPE':
                    node_type = child.value
                else:
                    pass
            elif isinstance(child, ast.AST):
                fields.append(child)
            else:
                pass

        if node_type == 'list':
            return ast.List(elts=fields, ctx=ast.Load())

        elif node_type == 'attr':
            if len(fields) != 2:
                raise SyntaxError('Attribute node must have two fields; found ' + len(fields))
            if not isinstance(fields[1], ast.Str):
                raise SyntaxError('Attribute name must be a string; found ' + type(fields[1]))
            return ast.Attribute(value=fields[0], attr=fields[1].s, ctx=ast.Load())

        elif node_type == 'call':
            if len(fields) < 1:
                raise SyntaxError('Call node must have at least one field; found ' + len(fields))
            return ast.Call(func=fields[0], args=fields[1:], keywords=[])

        elif node_type == 'lambda':
            if len(fields) != 2:
                raise SyntaxError('Lambda node must have two fields; found ' + len(fields))
            if not isinstance(fields[0], ast.List):
                raise SyntaxError('Lambda arguments must be in a list; found ' + type(fields[0]))
            for arg in fields[0].elts:
                if not isinstance(arg, ast.Name):
                    raise SyntaxError('Lambda arguments must variable names; found ' + type(arg))
            return ast.Lambda(args=ast.arguments(args=[ast.arg(arg=name.id, annotation=None)
                                                       for name in fields[0].elts],
                                                 vararg=None,
                                                 kwonlyargs=[],
                                                 kw_defaults=[],
                                                 kwarg=None,
                                                 defaults=[]),
                              body=fields[1])

        elif node_type == 'Select':
            if len(fields) != 2:
                raise SyntaxError('Select node must have two fields; found ' + len(fields))
            if not isinstance(fields[1], ast.Lambda):
                raise SyntaxError('Select selector must be a lambda; found ' + type(fields[1]))
            if len(fields[1].args.args) != 1:
                raise SyntaxError('Select selector must have exactly one argument; found '
                                  + len(fields[1].args.args))
            return linq_util.Select(source=fields[0], selector=fields[1])

        else:
            raise SyntaxError('Unknown composite node type: ' + node_type)
示例#24
0
文件: compiler.py 项目: lijie96/auk
def define_lambda(name, args, body):
    """
    Construct AST lambda assignment with specified name, args and 
    body. Because lambdas are anonymous, we must assign them to some 
    variable in order to reference them. This variable is returned to 
    end-user.
    """
    return ast.Assign(targets=[ast.Name(id=name, ctx=ast.Store())],
                      value=ast.Lambda(args=args, body=body))
示例#25
0
 def _wrap_lambda(self, body):
     node = ast.Lambda(args=ast.arguments(args=[],
                                          vararg=None,
                                          kwonlyargs=[],
                                          kw_defaults=[],
                                          kwarg=None,
                                          defaults=[]),
                       body=body)
     return ast.copy_location(node, body)
示例#26
0
文件: parse.py 项目: GreyAlien502/lam
 def Lambda(argument):
     return ast.Lambda(args=ast.arguments(
         args=[ast.arg(arg=argument, annotation=None)],
         vararg=None,
         kwonlyargs=[],
         kw_defaults=[],
         kwarg=None,
         defaults=[]),
                       body=None)
示例#27
0
def make_lambda(call):
    """Wrap an AST Call node to lambda expression node.
    call: ast.Call node
    """
    assert type(
        call
    ) is ast.Call, 'Argument of nni.function_choice is not function call'
    empty_args = ast.arguments(args=[], vararg=None, kwarg=None, defaults=[])
    return ast.Lambda(args=empty_args, body=call)
def eval_expro(expr, env, value, depth=0, maxdepth=3):
    # logger.debug("Evaluating expr {} to {} with env {}".format(expr, value, env))
    uuid = str(uuid4())[:4]
    if isinstance(expr, ast.AST):
        logger.info("Found AST for expr -> {}".format(
            ast_dump_if_possible(expr)))
    if isinstance(value, ast.AST):
        logger.info("Found AST for value -> {}".format(
            ast_dump_if_possible(value)))

    if depth >= maxdepth:
        return fail
    # fmt: off
    return conde(
        (eq(expr, ast.Name(id=var('name_' + uuid), ctx=ast.Load())),
         lookupo(var('name_' + uuid), env, value)),
        # (lany(
        #     typeo(value, int),
        #     typeo(value, str),
        #  ),
        #  eq(expr, ast.Constant(value=value)),),
        (eq(expr, ast.Str(s=var('str_e_' + uuid))), typeo(
            value, str), eq(var('str_e_' + uuid), value)),
        (eq(expr, ast.Num(n=value)), membero(value, [_ for _ in range(5)])),
        (eq(
            expr,
            ast.BinOp(left=var('e1_' + uuid),
                      op=var('op_e_' + uuid),
                      right=var('e2_' + uuid))), typeo(var('v1_' + uuid), int),
         typeo(var('v2_' + uuid), int),
         eval_expro(var('e1_' + uuid), env, var('v1_' + uuid), depth + 1,
                    maxdepth),
         eval_expro(var('e2_' + uuid), env, var('v2_' + uuid), depth + 1,
                    maxdepth),
         eval_opo(var('op_e_' + uuid), var('op_v_' + uuid), var('v1_' + uuid),
                  var('v2_' + uuid), value),
         binopo(var('v1_' + uuid),
                var('v2_' + uuid),
                value,
                op=var('op_v_' + uuid))),

        # Lists
        (eq(expr, ast.List(elts=var("list_elements_" + uuid), ctx=ast.Load())),
         eval_expr_listo(var("list_elements_" + uuid), env, value, depth,
                         maxdepth)),

        # Functions
        (eq(expr, ast.Lambda(body=var('body_' + uuid),
                             args=[])), typeo(value, FunctionType),
         eval_expro(var('body_' + uuid), env, var('body_v_' + uuid), depth + 1,
                    maxdepth), eq(lambda: var('body_v_' + uuid), value)),
        (eq(expr, ast.Call(func=var('func_' + uuid), args=[], keywords=[])),
         typeo(var('func_v_' + uuid), FunctionType),
         eval_expro(var('func_' + uuid), env, var('func_v_' + uuid), depth + 1,
                    maxdepth), applyo(var('func_v_' + uuid), [], value)),
    )
示例#29
0
 def to_right_hand_value(parameter_name: str,
                         is_callable: bool) -> ast.expr:
     return (ast.Call(
         ast.Attribute(
             _to_loaded_name(TYPES_MODULE_ALIAS), 'MethodType',
             ast.Load()), [
                 ast.Lambda(_to_unit_signature(instance_object_name),
                            _to_loaded_name(parameter_name)),
                 _to_loaded_name(instance_object_name)
             ], []) if is_callable else _to_loaded_name(parameter_name))
示例#30
0
 def visit_Return(self, el):
     el.value = ast.Lambda(args=ast.arguments(
         args=[],
         varargs=None,
         kwargs=None,
         kwonlyargs=[],
         defaults=[],
         kw_defaults=[],
     ),
                           body=el.value)
     return el