Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

injecting tokens in filter_stream fails with "expected token end of print statement" #1889

Open
Grollicus opened this issue Sep 20, 2023 · 0 comments

Comments

@Grollicus
Copy link

Grollicus commented Sep 20, 2023

I'm using an extension modifying the token stream via filter_stream to implement autoescape functionality for a latex renderer.

Extension looks like this:

class MyExtension(Extension):
    def filter_stream(self, stream):
        for token in stream:
            if token.type is TOKEN_VARIABLE_BEGIN:
                yield token
                yield Token(token.lineno, 'lparen', '(')
            elif token.type is TOKEN_VARIABLE_END:
                yield Token(token.lineno, 'rparen', ')')
                yield Token(token.lineno, 'pipe', '|')
                yield Token(token.lineno, 'name', 'escape_tex')
                yield token
            else:
                yield token

It pipes every variable through an escape_tex-function, for example {{ thingy }} gets translated to {{ (thingy) | escape_tex }}.

With jinja2==2.11.3 this works as intended. With newer versions, for example jinja2==3.1.2 I get this error:

jinja2.exceptions.TemplateSyntaxError: expected token 'end of print statement', got ')'

The full exception when disabling rewrite_traceback_stack indicates it crashes in parser.py:subparse.

Traceback (most recent call last):
  File "./main.py", line 35, in <module>
    print(env.from_string('Results in {{ foo + "asdf" }}').render(foo='FOO'))
  File ".venv/lib/python3.9/site-packages/jinja2/environment.py", line 1105, in from_string
    return cls.from_code(self, self.compile(source), gs, None)
  File ".venv/lib/python3.9/site-packages/jinja2/environment.py", line 768, in compile
    self.handle_exception(source=source_hint)
  File ".venv/lib/python3.9/site-packages/jinja2/environment.py", line 936, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File ".venv/lib/python3.9/site-packages/jinja2/environment.py", line 760, in compile
    source = self._parse(source, name, filename)
  File ".venv/lib/python3.9/site-packages/jinja2/environment.py", line 617, in _parse
    return Parser(self, source, name, filename).parse()
  File ".venv/lib/python3.9/site-packages/jinja2/parser.py", line 1030, in parse
    result = nodes.Template(self.subparse(), lineno=1)
  File ".venv/lib/python3.9/site-packages/jinja2/parser.py", line 1005, in subparse
    self.stream.expect("variable_end")
  File ".venv/lib/python3.9/site-packages/jinja2/lexer.py", line 416, in expect
    raise TemplateSyntaxError(
jinja2.exceptions.TemplateSyntaxError: expected token 'end of print statement', got ')'
  line 1

On the other hand, directly parsing env.from_string("{{ (foo) | escape_tex }}") works and results in the same token stream, which to me indicates that something in the parsing decisions must go differently to lead to the exception.

variable_begin begin of print statement
lparen (
name foo
rparen )
pipe |
name escape_tex
variable_end end of print statement

I'm unsure if this usage of filter_stream is not supported but the gettext example also rewrites the token stream. If you don't consider this a bug I'd of couse love other suggestions to work around this.

Environment:

  • Python version: 3.9.7
  • Jinja version: 3.1.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant