detect custom async filters in as_const

This commit is contained in:
Richard Gibson 2020-10-22 19:26:01 -04:00 committed by David Lord
parent 27c65757b2
commit e1d0131a7f
No known key found for this signature in database
GPG Key ID: 7A1C87E3F5BC42A8
3 changed files with 39 additions and 4 deletions

View File

@ -14,6 +14,9 @@ Unreleased
- Fix a bug that caused imported macros to not have access to the
current template's globals. :issue:`688`
- Add ability to ignore ``trim_blocks`` using ``+%}``. :issue:`1036`
- Fix a bug that caused custom async-only filters to fail with
constant input. :issue:`1279`
Version 2.11.2
--------------

View File

@ -2,6 +2,7 @@
some node tree helper functions used by the parser and compiler in order
to normalize nodes.
"""
import inspect
import operator
from collections import deque
from typing import Any
@ -649,10 +650,12 @@ class Filter(Expr):
if filter_ is None or getattr(filter_, "contextfilter", False) is True:
raise Impossible()
# We cannot constant handle async filters, so we need to make sure
# to not go down this path.
if eval_ctx.environment.is_async and getattr(
filter_, "asyncfiltervariant", False
# We cannot constant handle async filters, so we need to make
# sure to not go down this path. Account for both sync/async and
# pure-async filters.
if eval_ctx.environment.is_async and (
getattr(filter_, "asyncfiltervariant", False)
or inspect.iscoroutinefunction(filter_)
):
raise Impossible()

View File

@ -3,6 +3,7 @@ from collections import namedtuple
import pytest
from jinja2 import Environment
from jinja2.asyncsupport import auto_aiter
from jinja2.utils import Markup
@ -222,3 +223,31 @@ def test_slice(env_async, items):
"[[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]]|"
"[[0, 1, 2, 3], [4, 5, 6, 'X'], [7, 8, 9, 'X']]"
)
def test_custom_async_filter(env_async):
async def customfilter(val):
return str(val)
env_async.filters["customfilter"] = customfilter
tmpl = env_async.from_string("{{ 'static'|customfilter }} {{ arg|customfilter }}")
out = tmpl.render(arg="dynamic")
assert out == "static dynamic"
@mark_dualiter("items", lambda: range(10))
def test_custom_async_iteratable_filter(env_async, items):
async def customfilter(iterable):
items = []
async for item in auto_aiter(iterable):
items.append(str(item))
if len(items) == 3:
break
return ",".join(items)
env_async.filters["customfilter"] = customfilter
tmpl = env_async.from_string(
"{{ items()|customfilter }} .. {{ [3, 4, 5, 6]|customfilter }}"
)
out = tmpl.render(items=items)
assert out == "0,1,2 .. 3,4,5"