aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jinja2/asyncfilters.py21
-rw-r--r--tests/test_asyncfilters.py49
2 files changed, 69 insertions, 1 deletions
diff --git a/jinja2/asyncfilters.py b/jinja2/asyncfilters.py
index 2a6eb520..26caccbc 100644
--- a/jinja2/asyncfilters.py
+++ b/jinja2/asyncfilters.py
@@ -77,6 +77,11 @@ async def do_join(eval_ctx, value, d=u'', attribute=None):
return filters.do_join(eval_ctx, await auto_to_seq(value), d, attribute)
+@asyncfiltervariant(filters.do_list)
+async def do_list(value):
+ return await auto_to_seq(value)
+
+
@asyncfiltervariant(filters.do_reject)
async def do_reject(*args, **kwargs):
return async_select_or_reject(args, kwargs, lambda x: not x, False)
@@ -101,14 +106,27 @@ async def do_selectattr(*args, **kwargs):
async def do_map(*args, **kwargs):
seq, func = filters.prepare_map(args, kwargs)
if seq:
- async for item in seq:
+ async for item in auto_aiter(seq):
yield func(item)
+@asyncfiltervariant(filters.do_sum)
+async def do_sum(environment, iterable, attribute=None, start=0):
+ rv = start
+ if attribute is not None:
+ func = filters.make_attrgetter(environment, attribute)
+ else:
+ func = lambda x: x
+ async for item in auto_aiter(iterable):
+ rv += func(item)
+ return rv
+
+
ASYNC_FILTERS = {
'first': do_first,
'groupby': do_groupby,
'join': do_join,
+ 'list': do_list,
# we intentionally do not support do_last because that would be
# ridiculous
'reject': do_reject,
@@ -116,4 +134,5 @@ ASYNC_FILTERS = {
'map': do_map,
'select': do_select,
'selectattr': do_selectattr,
+ 'sum': do_sum,
}
diff --git a/tests/test_asyncfilters.py b/tests/test_asyncfilters.py
index 348a66b7..8732e780 100644
--- a/tests/test_asyncfilters.py
+++ b/tests/test_asyncfilters.py
@@ -165,3 +165,52 @@ def test_simple_select_attr(env_async, users):
'map(attribute="name")|join("|") }}'
)
assert tmpl.render(users=users) == 'john|jane'
+
+
+@mark_dualiter('items', lambda: list('123'))
+def test_simple_map(env_async, items):
+ tmpl = env_async.from_string('{{ items()|map("int")|sum }}')
+ assert tmpl.render(items=items) == '6'
+
+
+@mark_dualiter('users', make_users)
+def test_attribute_map(env_async, users):
+ tmpl = env_async.from_string('{{ users()|map(attribute="name")|join("|") }}')
+ assert tmpl.render(users=users) == 'john|jane|mike'
+
+
+def test_empty_map(env_async):
+ tmpl = env_async.from_string('{{ none|map("upper")|list }}')
+ assert tmpl.render() == '[]'
+
+
+def test_sum(env_async):
+ tmpl = env_async.from_string('''{{ [1, 2, 3, 4, 5, 6]|sum }}''')
+ assert tmpl.render() == '21'
+
+
+def test_sum_attributes(env_async):
+ tmpl = env_async.from_string('''{{ values|sum('value') }}''')
+ assert tmpl.render(values=[
+ {'value': 23},
+ {'value': 1},
+ {'value': 18},
+ ]) == '42'
+
+
+def test_sum_attributes_nested(env_async):
+ tmpl = env_async.from_string('''{{ values|sum('real.value') }}''')
+ assert tmpl.render(values=[
+ {'real': {'value': 23}},
+ {'real': {'value': 1}},
+ {'real': {'value': 18}},
+ ]) == '42'
+
+
+def test_sum_attributes_tuple(env_async):
+ tmpl = env_async.from_string('''{{ values.items()|sum('1') }}''')
+ assert tmpl.render(values={
+ 'foo': 23,
+ 'bar': 1,
+ 'baz': 18,
+ }) == '42'