jinja icon indicating copy to clipboard operation
jinja copied to clipboard

Accessing a variable has unexpected side effects on visit_Name for custom Extension

Open 502E532E opened this issue 7 months ago • 1 comments

I am trying to write a custom Jinja extension. Doing so, I noticed that accessing a variable in the template influences whether visit_Name is successful. I do not know if this is intentional, but I would assume not. If you access a variable, you do not expect this to have consequences for later statements.

Example code:

from jinja2 import nodes, Environment, BaseLoader
from jinja2.ext import Extension


class ContextExtension(Extension):
    tags = set(["context"])

    def parse(self, parser):
        node = nodes.OverlayScope(lineno=next(parser.stream).lineno)
        context_dict = parser.parse_expression()
        node.context = context_dict
        node.body = parser.parse_statements(("name:endcontext",), drop_needle=True)
        return node


env = Environment(loader=BaseLoader(), extensions=[ContextExtension])

template_content_0 = """
{{- a -}}
{%- context a -%}
    {{- x -}}
{%- endcontext -%}
"""
template0 = env.from_string(template_content_0)
print(template0.render(a={"x": 5}))  # prints "{'x': 5}5"

template_content_1 = """
{%- context a -%}
    {{- x -}}
{%- endcontext -%}
"""
# Next statement raises AssertionError: Tried to resolve a name to a reference that was unknown to the frame ('a')
# template1 = env.from_string(template_content_1)
# print(template1.render(a={"x": 5}))

Ideally, both examples would work (at least that is what I would expect). However, the more important thing is that they succeed or fail consistently.

Environment:

  • Python version: 3.13
  • Jinja version: 3.1.6

502E532E avatar May 01 '25 11:05 502E532E

node.context = context is probably incorrect, but I have not looked at the context internals in a long time, so I can't tell you what you should be doing instead.

davidism avatar May 01 '25 15:05 davidism