Пример #1
0
def test_if_branching_multi_scope():
    for_loop = nodes.For(
        nodes.Name("item", "store"),
        nodes.Name("seq", "load"),
        [
            nodes.If(
                nodes.Name("expression", "load"),
                [nodes.Assign(nodes.Name("x", "store"), nodes.Const(42))],
                [],
                [],
            ),
            nodes.Include(nodes.Const("helper.html"), True, False),
        ],
        [],
        None,
        False,
    )

    tmpl = nodes.Template(
        [nodes.Assign(nodes.Name("x", "store"), nodes.Const(23)), for_loop])

    tmpl_sym = symbols_for_node(tmpl)
    for_sym = symbols_for_node(for_loop, tmpl_sym)
    assert for_sym.stores == set(["item", "x"])
    assert for_sym.loads == {
        "l_1_x": ("alias", "l_0_x"),
        "l_1_item": ("param", None),
        "l_1_expression": ("resolve", "expression"),
    }
Пример #2
0
        def parse_formrow(self, parser, tag):
            lineno = tag.lineno
            field = parser.parse_expression()
            template_name = None
            if not parser.stream.current.test('block_end'):
                template_name = parser.parse_expression()
            else:
                template_name = nodes.Call(
                    nodes.Name('get_formrow_template', 'load'),
                    [],
                    [
                        nodes.Keyword('caller_template',
                                      nodes.Const(parser.name)),
                        nodes.Keyword('form',
                                      nodes.Name('form_utils_form', 'load'))
                    ],
                    None,
                    None,
                )
            if not parser.stream.current.test('block_end'):
                raise TemplateSyntaxError("Too many arguments", lineno)

            node = nodes.Scope(lineno=lineno)
            assignments = [nodes.Assign(nodes.Name('field', 'store'), field)]
            node.body = assignments + [
                nodes.Include(template_name, True, False)
            ]
            return node.set_lineno(lineno)
Пример #3
0
    def parse(self, parser):
        """
        Parse the referred template and the namespace.
        """
        token = next(parser.stream)
        lineno = token.lineno
        parser.stream.expect('name:to')
        template = parser.parse_expression()
        parser.stream.expect('name:as')
        namespace = next(parser.stream).value
        includeNode = nodes.Include(lineno=lineno)
        includeNode.with_context = True
        includeNode.ignore_missing = False
        includeNode.template = template

        temp = parser.free_identifier(lineno)

        return [
            nodes.Assign(
                nodes.Name(temp.name, 'store'),
                nodes.Name(MARKINGS, 'load')
            ).set_lineno(lineno),
            nodes.Assign(
                nodes.Name(MARKINGS, 'store'),
                nodes.Const({})).set_lineno(lineno),
            nodes.Assign(
                nodes.Name(namespace, 'store'),
                nodes.Const({})).set_lineno(lineno),
            nodes.CallBlock(
                self.call_method('_push_resource',
                                 args=[
                                     nodes.Name(namespace, 'load'),
                                     nodes.Name('site', 'load'),
                                     nodes.Name('resource', 'load'),
                                     template]),
                [], [], []).set_lineno(lineno),
            nodes.Assign(
                nodes.Name('resource', 'store'),
                nodes.Getitem(nodes.Name(namespace, 'load'),
                              nodes.Const('resource'), 'load')
            ).set_lineno(lineno),
            nodes.CallBlock(
                self.call_method('_assign_reference',
                                 args=[
                                     nodes.Name(MARKINGS, 'load'),
                                     nodes.Name(namespace, 'load')]),
                [], [], [includeNode]).set_lineno(lineno),
            nodes.Assign(nodes.Name('resource', 'store'),
                         nodes.Getitem(nodes.Name(namespace, 'load'),
                                       nodes.Const('parent_resource'), 'load')
                         ).set_lineno(lineno),
            nodes.Assign(
                nodes.Name(MARKINGS, 'store'),
                nodes.Name(temp.name, 'load')
            ).set_lineno(lineno),
        ]
Пример #4
0
 def parse_include(self):
     node = nodes.Include(lineno=next(self.stream).lineno)
     node.template = self.parse_expression()
     if self.stream.current.test('name:ignore') and \
        self.stream.look().test('name:missing'):
         node.ignore_missing = True
         self.stream.skip(2)
     else:
         node.ignore_missing = False
     return self.parse_import_context(node, True)
Пример #5
0
    def parse(self, parser):
        token = next(parser.stream)
        template = parser.parse_expression()

        # Create an include node for Jinja to parse it and properly import the
        # template. It won't interpret it if we just use an output node instead.
        node = nodes.Include(lineno=token.lineno)
        node.template = nodes.Const(f"{token.value[8:]}::{template.value}")
        node.ignore_missing = False
        node.with_context = True

        return node
Пример #6
0
    def parse(self, parser):
        stream = parser.stream
        lineno = stream.next().lineno
        print(lineno)

        name = parser.parse_expression()
        objvar = nodes.Name('obj', 'load', lineno=lineno)

        print name
        assignments = []
        has_property_details_kwargs = {}
        property_stack = self.get_property_stack(name)
        if property_stack:
            print('property_stack', property_stack)
            property_var = nodes.Name('property', 'store', lineno=lineno)
            property_node = nodes.Const(property_stack[-1])
            property_details_node = self.call_method(
                'get_property_details', args=[objvar, property_node])
            assignments.append(
                nodes.Assign(property_var,
                             property_details_node,
                             lineno=lineno))
            has_property_details_kwargs['property'] = property_var

        get_template_args = [objvar]
        properties_args = [name]
        if stream.next_if('name:as'):
            as_type = parser.parse_expression()
            get_template_args.append(as_type)
        if stream.next_if('name:with'):
            with_node = parser.parse_expression()
            print("with_node", with_node)
            properties_args.append(with_node)

        properties_var = nodes.Name('properties', 'store', lineno=lineno)
        properties_node = self.call_method('get_properties',
                                           args=properties_args,
                                           kwargs=has_property_details_kwargs)
        assignments.append(
            nodes.Assign(properties_var, properties_node, lineno=lineno))

        call_node = self.call_method('get_template_list',
                                     args=get_template_args,
                                     kwargs=has_property_details_kwargs)
        scope = nodes.Scope(lineno=lineno)
        assign_obj = nodes.Assign(objvar, name, lineno=lineno)
        assignments.append(assign_obj)

        scope.body = assignments + [
            nodes.Include(call_node, True, False, lineno=lineno)
        ]
        print(scope)
        return scope
Пример #7
0
def include_relative(token: Token, parser: Parser) -> nodes.Node:
    """The {% include_relative ... %} tag"""
    node = nodes.Include(lineno=token.lineno)
    path = parser.parse_expression()
    if parser.stream.filename:
        node.template = nodes.Add(
            nodes.Add(
                nodes.Const(os.path.dirname(parser.stream.filename)),
                nodes.Const(os.path.sep),
            ),
            path,
        )
    else:
        node.template = path

    node.ignore_missing = False
    return parser.parse_import_context(node, True)
Пример #8
0
def test_if_branching_multi_scope():
    for_loop = nodes.For(nodes.Name('item', 'store'), nodes.Name('seq', 'load'), [
        nodes.If(nodes.Name('expression', 'load'), [
            nodes.Assign(nodes.Name('x', 'store'), nodes.Const(42))], []),
        nodes.Include(nodes.Const('helper.html'), True, False)
    ], [], None, False)

    tmpl = nodes.Template([
        nodes.Assign(nodes.Name('x', 'store'), nodes.Const(23)),
        for_loop
    ])

    tmpl_sym = symbols_for_node(tmpl)
    for_sym = symbols_for_node(for_loop, tmpl_sym)
    assert for_sym.stores == set(['item', 'x'])
    assert for_sym.loads == {
        'l_1_x': ('alias', 'l_0_x'),
        'l_1_item': ('param', None),
        'l_1_expression': ('resolve', 'expression'),
    }
Пример #9
0
        def parse_form(self, parser, tag):
            lineno = tag.lineno
            form_instance = parser.parse_expression()
            template_name = nodes.Call(
                nodes.Name('get_formlayout_template', 'load'),
                [],
                [
                    nodes.Keyword('caller_template', nodes.Const(parser.name)),
                    nodes.Keyword('form', form_instance),
                ],
                None,
                None,
            )
            has_body = False
            if not parser.stream.current.test('block_end'):
                parser.stream.expect('name:using')
                if parser.stream.current.test('block_end'):
                    has_body = True
            if not parser.stream.current.test('block_end'):
                template_name = parser.parse_expression()
            if not parser.stream.current.test('block_end'):
                raise TemplateSyntaxError("Too many arguments", lineno)

            body = None
            if has_body:
                body = parser.parse_statements(['name:endform'],
                                               drop_needle=True)
            else:
                body = nodes.Include(template_name, True, False)
                body = [body]

            node = nodes.Scope(lineno=lineno)
            assignments = [
                nodes.Assign(nodes.Name('form_utils_form', 'store'),
                             form_instance)
            ]
            node.body = assignments + body
            return node.set_lineno(lineno)
Пример #10
0
def test_complex():
    title_block = nodes.Block(
        "title", [nodes.Output([nodes.TemplateData(u"Page Title")])], False)

    render_title_macro = nodes.Macro(
        "render_title",
        [nodes.Name("title", "param")],
        [],
        [
            nodes.Output([
                nodes.TemplateData(u'\n  <div class="title">\n    <h1>'),
                nodes.Name("title", "load"),
                nodes.TemplateData(u"</h1>\n    <p>"),
                nodes.Name("subtitle", "load"),
                nodes.TemplateData(u"</p>\n    "),
            ]),
            nodes.Assign(nodes.Name("subtitle", "store"),
                         nodes.Const("something else")),
            nodes.Output([
                nodes.TemplateData(u"\n    <p>"),
                nodes.Name("subtitle", "load"),
                nodes.TemplateData(u"</p>\n  </div>\n"),
                nodes.If(
                    nodes.Name("something", "load"),
                    [
                        nodes.Assign(
                            nodes.Name("title_upper", "store"),
                            nodes.Filter(
                                nodes.Name("title", "load"),
                                "upper",
                                [],
                                [],
                                None,
                                None,
                            ),
                        ),
                        nodes.Output([
                            nodes.Name("title_upper", "load"),
                            nodes.Call(
                                nodes.Name("render_title", "load"),
                                [nodes.Const("Aha")],
                                [],
                                None,
                                None,
                            ),
                        ]),
                    ],
                    [],
                    [],
                ),
            ]),
        ],
    )

    for_loop = nodes.For(
        nodes.Name("item", "store"),
        nodes.Name("seq", "load"),
        [
            nodes.Output([
                nodes.TemplateData(u"\n    <li>"),
                nodes.Name("item", "load"),
                nodes.TemplateData(u"</li>\n    <span>"),
            ]),
            nodes.Include(nodes.Const("helper.html"), True, False),
            nodes.Output([nodes.TemplateData(u"</span>\n  ")]),
        ],
        [],
        None,
        False,
    )

    body_block = nodes.Block(
        "body",
        [
            nodes.Output([
                nodes.TemplateData(u"\n  "),
                nodes.Call(
                    nodes.Name("render_title", "load"),
                    [nodes.Name("item", "load")],
                    [],
                    None,
                    None,
                ),
                nodes.TemplateData(u"\n  <ul>\n  "),
            ]),
            for_loop,
            nodes.Output([nodes.TemplateData(u"\n  </ul>\n")]),
        ],
        False,
    )

    tmpl = nodes.Template([
        nodes.Extends(nodes.Const("layout.html")),
        title_block,
        render_title_macro,
        body_block,
    ])

    tmpl_sym = symbols_for_node(tmpl)
    assert tmpl_sym.refs == {
        "render_title": "l_0_render_title",
    }
    assert tmpl_sym.loads == {
        "l_0_render_title": ("undefined", None),
    }
    assert tmpl_sym.stores == set(["render_title"])
    assert tmpl_sym.dump_stores() == {
        "render_title": "l_0_render_title",
    }

    macro_sym = symbols_for_node(render_title_macro, tmpl_sym)
    assert macro_sym.refs == {
        "subtitle": "l_1_subtitle",
        "something": "l_1_something",
        "title": "l_1_title",
        "title_upper": "l_1_title_upper",
    }
    assert macro_sym.loads == {
        "l_1_subtitle": ("resolve", "subtitle"),
        "l_1_something": ("resolve", "something"),
        "l_1_title": ("param", None),
        "l_1_title_upper": ("resolve", "title_upper"),
    }
    assert macro_sym.stores == set(["title", "title_upper", "subtitle"])
    assert macro_sym.find_ref("render_title") == "l_0_render_title"
    assert macro_sym.dump_stores() == {
        "title": "l_1_title",
        "title_upper": "l_1_title_upper",
        "subtitle": "l_1_subtitle",
        "render_title": "l_0_render_title",
    }

    body_sym = symbols_for_node(body_block)
    assert body_sym.refs == {
        "item": "l_0_item",
        "seq": "l_0_seq",
        "render_title": "l_0_render_title",
    }
    assert body_sym.loads == {
        "l_0_item": ("resolve", "item"),
        "l_0_seq": ("resolve", "seq"),
        "l_0_render_title": ("resolve", "render_title"),
    }
    assert body_sym.stores == set([])

    for_sym = symbols_for_node(for_loop, body_sym)
    assert for_sym.refs == {
        "item": "l_1_item",
    }
    assert for_sym.loads == {
        "l_1_item": ("param", None),
    }
    assert for_sym.stores == set(["item"])
    assert for_sym.dump_stores() == {
        "item": "l_1_item",
    }
Пример #11
0
 def parse_include(self):
     node = nodes.Include(lineno=self.stream.next().lineno)
     node.template = self.parse_expression()
     return self.parse_import_context(node, True)
Пример #12
0
    def parse(self, parser):
        # Get the component for the tag name that we matched on
        tag_name = parser.stream.current[2]
        component_class = self.environment.components[tag_name]
        field_names = [f.name for f in dataclasses.fields(component_class)]
        has_children = CHILDREN_FIELD_NAME in field_names

        lineno = next(parser.stream).lineno

        node = nodes.Scope(lineno=lineno)

        # list of `Pair` nodes for tag properties to update "component" dictionary
        component_dict_update_items = []

        while parser.stream.current.type != 'block_end':
            lineno = parser.stream.current.lineno
            if component_dict_update_items:
                parser.stream.expect('comma')
            name = parser.stream.expect('name')
            parser.stream.expect('assign')
            value = parser.parse_expression()
            component_dict_update_items.append(
                nodes.Pair(nodes.Const(name.value), value))

        # dictionary initialization in the "component" name
        prepare_component_dict = [
            self._initialize_component_dict(component_class, lineno)
        ]

        if component_dict_update_items:
            component_dict_delta = nodes.Dict(component_dict_update_items)
            # `Getattr` for "update" function of the dictionary "component"
            update_component_dict_fun = nodes.Getattr(
                nodes.Name(TMP_COMPONENT_DICT_NAME, 'load'), 'update', 'load')
            # `Call` for `component.update(<prop name>, <prop value>)`
            call_component_dict_update = nodes.Call(update_component_dict_fun,
                                                    [component_dict_delta], [],
                                                    None, None)
            prepare_component_dict.append(
                nodes.ExprStmt(call_component_dict_update))

        # assign `component = __component` and `__component = None`
        prepare_component_dict.extend([
            nodes.Assign(nodes.Name(COMPONENT_DICT_NAME,
                                    'store',
                                    lineno=lineno),
                         nodes.Name(TMP_COMPONENT_DICT_NAME,
                                    'load',
                                    lineno=lineno),
                         lineno=lineno),
            nodes.Assign(nodes.Name(TMP_COMPONENT_DICT_NAME,
                                    'store',
                                    lineno=lineno),
                         nodes.Const(None, lineno=lineno),
                         lineno=lineno)
        ])

        if has_children:
            inner_block = list(
                parser.parse_statements(('name:end' + tag_name, ),
                                        drop_needle=True))
            # create children() macro
            children_macro = nodes.Macro()
            children_macro.name = CHILDREN_MACRO_NAME
            children_macro.args = []
            children_macro.defaults = []
            children_macro.body = inner_block
            children_macro_nodes = [children_macro]
        else:
            children_macro_nodes = []

        # include tag template
        include_tag = nodes.Include()
        # use `template` item of the "component" dictionary for template path
        include_tag.template = nodes.Getitem(nodes.Name(COMPONENT_DICT_NAME,
                                                        'load',
                                                        lineno=lineno),
                                             nodes.Const(TEMPLATE_FIELD_NAME,
                                                         lineno=lineno),
                                             'load',
                                             lineno=lineno)
        include_tag.ignore_missing = False
        include_tag.with_context = True

        node.body = prepare_component_dict + children_macro_nodes + [
            include_tag,
        ]

        return node
Пример #13
0
def test_complex():
    title_block = nodes.Block('title', [
        nodes.Output([nodes.TemplateData(u'Page Title')])
    ], False)

    render_title_macro = nodes.Macro('render_title', [nodes.Name('title', 'param')], [], [
        nodes.Output([
            nodes.TemplateData(u'\n  <div class="title">\n    <h1>'),
            nodes.Name('title', 'load'),
            nodes.TemplateData(u'</h1>\n    <p>'),
            nodes.Name('subtitle', 'load'),
            nodes.TemplateData(u'</p>\n    ')]),
        nodes.Assign(
            nodes.Name('subtitle', 'store'), nodes.Const('something else')),
        nodes.Output([
            nodes.TemplateData(u'\n    <p>'),
            nodes.Name('subtitle', 'load'),
            nodes.TemplateData(u'</p>\n  </div>\n'),
            nodes.If(
                nodes.Name('something', 'load'), [
                    nodes.Assign(nodes.Name('title_upper', 'store'),
                                 nodes.Filter(nodes.Name('title', 'load'),
                                              'upper', [], [], None, None)),
                    nodes.Output([
                        nodes.Name('title_upper', 'load'),
                        nodes.Call(nodes.Name('render_title', 'load'), [
                            nodes.Const('Aha')], [], None, None)])], [])])])

    for_loop = nodes.For(
        nodes.Name('item', 'store'),
        nodes.Name('seq', 'load'), [
            nodes.Output([
                nodes.TemplateData(u'\n    <li>'),
                nodes.Name('item', 'load'),
                nodes.TemplateData(u'</li>\n    <span>')]),
            nodes.Include(nodes.Const('helper.html'), True, False),
            nodes.Output([
                nodes.TemplateData(u'</span>\n  ')])], [], None, False)

    body_block = nodes.Block('body', [
        nodes.Output([
            nodes.TemplateData(u'\n  '),
            nodes.Call(nodes.Name('render_title', 'load'), [
                nodes.Name('item', 'load')], [], None, None),
            nodes.TemplateData(u'\n  <ul>\n  ')]),
        for_loop,
        nodes.Output([nodes.TemplateData(u'\n  </ul>\n')])],
        False)

    tmpl = nodes.Template([
        nodes.Extends(nodes.Const('layout.html')),
        title_block,
        render_title_macro,
        body_block,
    ])

    tmpl_sym = symbols_for_node(tmpl)
    assert tmpl_sym.refs == {
        'render_title': 'l_0_render_title',
    }
    assert tmpl_sym.loads == {
        'l_0_render_title': ('undefined', None),
    }
    assert tmpl_sym.stores == set(['render_title'])
    assert tmpl_sym.dump_stores() == {
        'render_title': 'l_0_render_title',
    }

    macro_sym = symbols_for_node(render_title_macro, tmpl_sym)
    assert macro_sym.refs == {
        'subtitle': 'l_1_subtitle',
        'something': 'l_1_something',
        'title': 'l_1_title',
        'title_upper': 'l_1_title_upper',
    }
    assert macro_sym.loads == {
        'l_1_subtitle': ('resolve', 'subtitle'),
        'l_1_something': ('resolve','something'),
        'l_1_title': ('param', None),
        'l_1_title_upper': ('resolve', 'title_upper'),
    }
    assert macro_sym.stores == set(['title', 'title_upper', 'subtitle'])
    assert macro_sym.find_ref('render_title') == 'l_0_render_title'
    assert macro_sym.dump_stores() == {
        'title': 'l_1_title',
        'title_upper': 'l_1_title_upper',
        'subtitle': 'l_1_subtitle',
        'render_title': 'l_0_render_title',
    }

    body_sym = symbols_for_node(body_block)
    assert body_sym.refs == {
        'item': 'l_0_item',
        'seq': 'l_0_seq',
        'render_title': 'l_0_render_title',
    }
    assert body_sym.loads == {
        'l_0_item': ('resolve', 'item'),
        'l_0_seq': ('resolve', 'seq'),
        'l_0_render_title': ('resolve', 'render_title'),
    }
    assert body_sym.stores == set([])

    for_sym = symbols_for_node(for_loop, body_sym)
    assert for_sym.refs == {
        'item': 'l_1_item',
    }
    assert for_sym.loads == {
        'l_1_item': ('param', None),
    }
    assert for_sym.stores == set(['item'])
    assert for_sym.dump_stores() == {
        'item': 'l_1_item',
    }