def dualfilter(normal_filter, async_filter):
wrap_evalctx = False
- if getattr(normal_filter, 'environmentfilter'):
+ if getattr(normal_filter, 'environmentfilter', False):
is_async = lambda args: args[0].is_async
wrap_evalctx = False
else:
- if not getattr(normal_filter, 'evalcontextfilter'):
+ if not getattr(normal_filter, 'evalcontextfilter', False):
wrap_evalctx = True
is_async = lambda args: args[0].environment.is_async
await auto_to_seq(value), key=expr), expr)]
+@asyncfiltervariant(filters.do_join)
+async def do_join(eval_ctx, value, d=u'', attribute=None):
+ return filters.do_join(eval_ctx, await auto_to_seq(value), d, attribute)
+
+
ASYNC_FILTERS = {
'first': do_first,
'groupby': do_groupby,
+ 'join': do_join,
}
import pytest
from jinja2 import Environment
+from jinja2.utils import Markup
async def make_aiter(iter):
'1971[totally not]',
''
]
+
+
+@mark_dualiter('int_items', lambda: [1, 2, 3])
+def test_join(env_async, int_items):
+ tmpl = env_async.from_string('{{ items()|join("|") }}')
+ out = tmpl.render(items=int_items)
+ assert out == '1|2|3'
+
+
+@mark_dualiter('string_items', lambda: ["<foo>", Markup("<span>foo</span>")])
+def test_join(string_items):
+ env2 = Environment(autoescape=True, enable_async=True)
+ tmpl = env2.from_string(
+ '{{ ["<foo>", "<span>foo</span>"|safe]|join }}')
+ assert tmpl.render(items=string_items) == '<foo><span>foo</span>'
+
+
+def make_users():
+ class User(object):
+ def __init__(self, username):
+ self.username = username
+ return map(User, ['foo', 'bar'])
+
+
+@mark_dualiter('users', make_users)
+def test_join_attribute(env_async, users):
+ tmpl = env_async.from_string('''{{ users()|join(', ', 'username') }}''')
+ assert tmpl.render(users=users) == 'foo, bar'