Exemplo n.º 1
0
 def parse_test(self, node):
     token = next(self.stream)
     if self.stream.current.test('name:not'):
         next(self.stream)
         negated = True
     else:
         negated = False
     name = self.stream.expect('name').value
     while self.stream.current.type == 'dot':
         next(self.stream)
         name += '.' + self.stream.expect('name').value
     dyn_args = dyn_kwargs = None
     kwargs = []
     if self.stream.current.type == 'lparen':
         args, kwargs, dyn_args, dyn_kwargs = self.parse_call(None)
     elif (self.stream.current.type
           in ('name', 'string', 'integer', 'float', 'lparen', 'lbracket',
               'lbrace') and not self.stream.current.test_any(
                   'name:else', 'name:or', 'name:and')):
         if self.stream.current.test('name:is'):
             self.fail('You cannot chain multiple tests with is')
         args = [self.parse_primary()]
     else:
         args = []
     node = nodes.Test(node,
                       name,
                       args,
                       kwargs,
                       dyn_args,
                       dyn_kwargs,
                       lineno=token.lineno)
     if negated:
         node = nodes.Not(node, lineno=token.lineno)
     return node
Exemplo n.º 2
0
def unless(token: "Token", parser: "Parser") -> nodes.Node:
    """The unless tag {% unless ... %} ... {% endunless %}

    Args:
        token: The token matches tag name
        parser: The parser

    Returns:
        The parsed node
    """
    node = result = nodes.If(lineno=token.lineno)
    while True:
        node.test = nodes.Not(
            parser.parse_tuple(with_condexpr=False),
            lineno=token.lineno,
        )
        node.body = parser.parse_statements(
            ("name:elif", "name:elsif", "name:else", "name:endunless")
        )
        node.elif_ = []
        node.else_ = []
        token = next(parser.stream)
        if token.test_any("name:elif", "name:elsif"):
            node = nodes.If(lineno=parser.stream.current.lineno)
            result.elif_.append(node)
            continue
        if token.test("name:else"):
            result.else_ = parser.parse_statements(
                ("name:endunless",), drop_needle=True
            )
        break
    return result
Exemplo n.º 3
0
    def parse(self, parser):
        m = nodes.Macro(lineno=next(parser.stream).lineno)
        name = parser.parse_assign_target(name_only=True).name
        m.name = f"default_{name}"
        parser.parse_signature(m)
        m.body = parser.parse_statements(("name:enddefaultmacro",), drop_needle=True)

        if_stmt = nodes.If(
            nodes.Not(nodes.Name(name, "load")),
            [nodes.Macro(name, m.args, m.defaults, m.body)],
            [],
            [],
        )
        return [m, if_stmt]
Exemplo n.º 4
0
 def parse_unary(self):
     token_type = self.stream.current.type
     lineno = self.stream.current.lineno
     if token_type is 'name' and self.stream.current.value == 'not':
         self.stream.next()
         node = self.parse_unary()
         return nodes.Not(node, lineno=lineno)
     if token_type is 'sub':
         self.stream.next()
         node = self.parse_unary()
         return nodes.Neg(node, lineno=lineno)
     if token_type is 'add':
         self.stream.next()
         node = self.parse_unary()
         return nodes.Pos(node, lineno=lineno)
     return self.parse_primary()
Exemplo n.º 5
0
 def parse_test(self, node):
     token = next(self.stream)
     if self.stream.current.test("name:not"):
         next(self.stream)
         negated = True
     else:
         negated = False
     name = self.stream.expect("name").value
     while self.stream.current.type == "dot":
         next(self.stream)
         name += "." + self.stream.expect("name").value
     dyn_args = dyn_kwargs = None
     kwargs = []
     if self.stream.current.type == "lparen":
         args, kwargs, dyn_args, dyn_kwargs = self.parse_call(None)
     elif self.stream.current.type in (
             "name",
             "string",
             "integer",
             "float",
             "lparen",
             "lbracket",
             "lbrace",
     ) and not self.stream.current.test_any("name:else", "name:or",
                                            "name:and"):
         if self.stream.current.test("name:is"):
             self.fail("You cannot chain multiple tests with is")
         args = [self.parse_primary()]
     else:
         args = []
     node = nodes.Test(node,
                       name,
                       args,
                       kwargs,
                       dyn_args,
                       dyn_kwargs,
                       lineno=token.lineno)
     if negated:
         node = nodes.Not(node, lineno=token.lineno)
     return node
Exemplo n.º 6
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)
Exemplo n.º 7
0
 def parse_not(self):
     if self.stream.current.test('name:not'):
         lineno = next(self.stream).lineno
         return nodes.Not(self.parse_not(), lineno=lineno)
     return self.parse_compare()
Exemplo n.º 8
0

class Builtin(object):
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return self.name


# Fields used by nodes.If().
IF_NODE_FIELDS = {
    'test':
    nodes.Not(
        nodes.Call(nodes.Const(Builtin('isinstance')), [
            nodes.Name(DJEDI_NODE_STORAGE, 'load'),
            nodes.Const(Builtin('dict')),
        ], [], None, None)),
    'body': [
        nodes.Assign(nodes.Name(DJEDI_NODE_STORAGE, 'store'), nodes.Dict([])),
    ],
}

# Construct the Jinja2 AST equivalent of:
#
#   if not isinstance(DJEDI_NODE_STORAGE, dict):
#       DJEDI_NODE_STORAGE = {}
#
if nodes.If.fields == ('test', 'body', 'elif_', 'else_'):
    # Jinja 2.10 added the "elif" field to If()
    DJEDI_NODE_STORAGE_NODE = (