Exemplo n.º 1
0
    def parse(self, parser):
        lineno = next(parser.stream).lineno
        url = parser.parse_expression(with_condexpr=False)
        url_var = nodes.Name('checked_url', 'store')
        args = None
        if parser.stream.current.type != 'block_end':
            parser.stream.expect('comma')
            args = parser.parse_expression(with_condexpr=False)

        fun_var = parser.free_identifier()
        body = parser.parse_statements(('name:endauth', 'name:else'))
        token = next(parser.stream)
        if token.test('name:else'):
            else_ = parser.parse_statements(
                ('name:endauth', ), drop_needle=True)
        else:
            else_ = None
        url_fun_tuple = nodes.Tuple([url_var, fun_var], 'store')
        # The url goes in the dyn_args (its not visited otherwise).
        # To be in the dyn_args, it must be wrapped in a Tuple.
        assignment = nodes.Assign(url_fun_tuple,
                                  self.call_method(
                                      'template_if_auth_url_for',
                                      dyn_args=nodes.Tuple([url], 'load'),
                                      dyn_kwargs=args)).set_lineno(lineno)

        returned_ast = [assignment]
        if_node = nodes.If()
        if_node.test = nodes.Name('checked_url', 'load')
        if_node.body = body
        if_node.else_ = else_
        if_node.elif_ = []
        returned_ast.append(if_node.set_lineno(lineno))
        return returned_ast
Exemplo n.º 2
0
 def parse_subscript(self, node):
     token = next(self.stream)
     if token.type == 'dot':
         attr_token = self.stream.current
         next(self.stream)
         if attr_token.type == 'name':
             return nodes.Getattr(node,
                                  attr_token.value,
                                  'load',
                                  lineno=token.lineno)
         elif attr_token.type != 'integer':
             self.fail('expected name or number', attr_token.lineno)
         arg = nodes.Const(attr_token.value, lineno=attr_token.lineno)
         return nodes.Getitem(node, arg, 'load', lineno=token.lineno)
     if token.type == 'lbracket':
         args = []
         while self.stream.current.type != 'rbracket':
             if args:
                 self.stream.expect('comma')
             args.append(self.parse_subscribed())
         self.stream.expect('rbracket')
         if len(args) == 1:
             arg = args[0]
         else:
             arg = nodes.Tuple(args, 'load', lineno=token.lineno)
         return nodes.Getitem(node, arg, 'load', lineno=token.lineno)
     self.fail('expected subscript expression', self.lineno)
Exemplo n.º 3
0
    def parse_tuple(self,
                    simplified=False,
                    with_condexpr=True,
                    extra_end_rules=None,
                    explicit_parentheses=False):
        lineno = self.stream.current.lineno
        if simplified:
            parse = self.parse_primary
        elif with_condexpr:
            parse = self.parse_expression
        else:
            parse = lambda: self.parse_expression(with_condexpr=False)
        args = []
        is_tuple = False
        while 1:
            if args:
                self.stream.expect('comma')
            if self.is_tuple_end(extra_end_rules):
                break
            args.append(parse())
            if self.stream.current.type == 'comma':
                is_tuple = True
            else:
                break
            lineno = self.stream.current.lineno

        if not is_tuple:
            if args:
                return args[0]
            if not explicit_parentheses:
                self.fail("Expected an expression, got '%s'" %
                          describe_token(self.stream.current))
        return nodes.Tuple(args, 'load', lineno=lineno)
Exemplo n.º 4
0
 def parse_subscript(self, node):
     token = next(self.stream)
     if token.type == "dot":
         attr_token = self.stream.current
         next(self.stream)
         if attr_token.type == "name":
             return nodes.Getattr(node,
                                  attr_token.value,
                                  "load",
                                  lineno=token.lineno)
         elif attr_token.type != "integer":
             self.fail("expected name or number", attr_token.lineno)
         arg = nodes.Const(attr_token.value, lineno=attr_token.lineno)
         return nodes.Getitem(node, arg, "load", lineno=token.lineno)
     if token.type == "lbracket":
         args = []
         while self.stream.current.type != "rbracket":
             if args:
                 self.stream.expect("comma")
             args.append(self.parse_subscribed())
         self.stream.expect("rbracket")
         if len(args) == 1:
             arg = args[0]
         else:
             arg = nodes.Tuple(args, "load", lineno=token.lineno)
         return nodes.Getitem(node, arg, "load", lineno=token.lineno)
     self.fail("expected subscript expression", self.lineno)
Exemplo n.º 5
0
    def parse_tuple(
        self,
        simplified=False,
        with_condexpr=True,
        extra_end_rules=None,
        explicit_parentheses=False,
    ):
        """Works like `parse_expression` but if multiple expressions are
        delimited by a comma a :class:`~jinja2.nodes.Tuple` node is created.
        This method could also return a regular expression instead of a tuple
        if no commas where found.

        The default parsing mode is a full tuple.  If `simplified` is `True`
        only names and literals are parsed.  The `no_condexpr` parameter is
        forwarded to :meth:`parse_expression`.

        Because tuples do not require delimiters and may end in a bogus comma
        an extra hint is needed that marks the end of a tuple.  For example
        for loops support tuples between `for` and `in`.  In that case the
        `extra_end_rules` is set to ``['name:in']``.

        `explicit_parentheses` is true if the parsing was triggered by an
        expression in parentheses.  This is used to figure out if an empty
        tuple is a valid expression or not.
        """
        lineno = self.stream.current.lineno
        if simplified:
            parse = self.parse_primary
        elif with_condexpr:
            parse = self.parse_expression
        else:
            parse = lambda: self.parse_expression(with_condexpr=False)
        args = []
        is_tuple = False
        while 1:
            if args:
                self.stream.expect("comma")
            if self.is_tuple_end(extra_end_rules):
                break
            args.append(parse())
            if self.stream.current.type == "comma":
                is_tuple = True
            else:
                break
            lineno = self.stream.current.lineno

        if not is_tuple:
            if args:
                return args[0]

            # if we don't have explicit parentheses, an empty tuple is
            # not a valid expression.  This would mean nothing (literally
            # nothing) in the spot of an expression would be an empty
            # tuple.
            if not explicit_parentheses:
                self.fail("Expected an expression, got '%s'" %
                          describe_token(self.stream.current))

        return nodes.Tuple(args, "load", lineno=lineno)
Exemplo n.º 6
0
 def create_tuple(self, *values, **kwargs):
     ctx = kwargs.get('ctx', 'local')
     node = kwargs.get('node', nodes.Const)
     node_args = kwargs.get('node_args', [])
     values = [
         node(v, *node_args) if isinstance(v, str) else v for v in values
     ]
     return nodes.Tuple(values, ctx)
Exemplo n.º 7
0
    def parse_tuple(self,
                    simplified=False,
                    with_condexpr=True,
                    extra_end_rules=None):
        """Works like `parse_expression` but if multiple expressions are
        delimited by a comma a :class:`~jinja2.nodes.Tuple` node is created.
        This method could also return a regular expression instead of a tuple
        if no commas where found.

        The default parsing mode is a full tuple.  If `simplified` is `True`
        only names and literals are parsed.  The `no_condexpr` parameter is
        forwarded to :meth:`parse_expression`.

        Because tuples do not require delimiters and may end in a bogus comma
        an extra hint is needed that marks the end of a tuple.  For example
        for loops support tuples between `for` and `in`.  In that case the
        `extra_end_rules` is set to ``['name:in']``.
        """
        lineno = self.stream.current.lineno
        if simplified:
            parse = lambda: self.parse_primary(with_postfix=False)
        elif with_condexpr:
            parse = self.parse_expression
        else:
            parse = lambda: self.parse_expression(with_condexpr=False)
        args = []
        is_tuple = False
        while 1:
            if args:
                self.stream.expect('comma')
            if self.is_tuple_end(extra_end_rules):
                break
            args.append(parse())
            if self.stream.current.type == 'comma':
                is_tuple = True
            else:
                break
            lineno = self.stream.current.lineno
        if not is_tuple and args:
            return args[0]
        return nodes.Tuple(args, 'load', lineno=lineno)
Exemplo n.º 8
0
    def parse(self, parser):
        lineno = next(parser.stream).lineno

        # Get the block selection from the tag argument.
        block_selection = parser.parse_expression()

        # Make "Name" node for "For" node target.
        block_name = nodes.Name('_ext_ob_blknm', 'store')

        # For each block, add an "If" node checking if it matches the target.
        # Also record the original "default" ordering of the blocks.
        blocks = []
        block_names = []
        for node in parser.parse_statements(['name:endorderblocks'],
                                            drop_needle=True):
            if isinstance(node, nodes.Block):
                blocks.append(nodes.If(
                    nodes.Compare(
                        block_name,
                        [nodes.Operand('eq', nodes.Const(node.name))]),
                    [node], []))

                block_names.append(node.name)

        # Make a "For" node iterating over the given block selection.  If the
        # block selection is undefined or None then use the original ordering.
        return nodes.For(
            block_name,
            nodes.CondExpr(
                nodes.And(
                    nodes.Test(block_selection, 'defined',
                               [], [], None, None),
                    nodes.Not(
                        nodes.Test(block_selection, 'none',
                                   [], [], None, None)),
                ),
                block_selection,
                nodes.Tuple([nodes.Const(x) for x in block_names], 'store')),
            blocks, [], None, False)