From: Armin Ronacher Date: Wed, 28 Dec 2016 23:05:02 +0000 (+0100) Subject: Added reject/rejectattr with basic async support X-Git-Tag: 2.9~51 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=043c954c26fa7bf1c36c53642ed12e57912ff254;p=thirdparty%2Fjinja.git Added reject/rejectattr with basic async support --- diff --git a/jinja2/asyncfilters.py b/jinja2/asyncfilters.py index c621ae41..78fafed8 100644 --- a/jinja2/asyncfilters.py +++ b/jinja2/asyncfilters.py @@ -15,13 +15,23 @@ async def auto_to_seq(value): return seq +async def async_select_or_reject(args, kwargs, modfunc, lookup_attr): + seq, func = filters.prepare_select_or_reject( + args, kwargs, modfunc, lookup_attr) + if seq: + async for item in auto_aiter(seq): + if func(item): + yield item + + def dualfilter(normal_filter, async_filter): wrap_evalctx = False if getattr(normal_filter, 'environmentfilter', False): is_async = lambda args: args[0].is_async wrap_evalctx = False else: - if not getattr(normal_filter, 'evalcontextfilter', False): + if not getattr(normal_filter, 'evalcontextfilter', False) and \ + not getattr(normal_filter, 'contextfilter', False): wrap_evalctx = True is_async = lambda args: args[0].environment.is_async @@ -67,8 +77,22 @@ 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_reject) +async def do_reject(*args, **kwargs): + return async_select_or_reject(args, kwargs, lambda x: not x, False) + + +@asyncfiltervariant(filters.do_rejectattr) +async def do_rejectattr(*args, **kwargs): + return async_select_or_reject(args, kwargs, lambda x: not x, True) + + ASYNC_FILTERS = { 'first': do_first, 'groupby': do_groupby, 'join': do_join, + # we intentionally do not support do_last because that would be + # ridiculous + 'reject': do_reject, + 'rejectattr': do_rejectattr, } diff --git a/jinja2/filters.py b/jinja2/filters.py index b5fa456f..b16e73ee 100644 --- a/jinja2/filters.py +++ b/jinja2/filters.py @@ -860,7 +860,7 @@ def do_select(*args, **kwargs): .. versionadded:: 2.7 """ - return _select_or_reject(args, kwargs, lambda x: x, False) + return select_or_reject(args, kwargs, lambda x: x, False) @contextfilter @@ -878,7 +878,7 @@ def do_reject(*args, **kwargs): .. versionadded:: 2.7 """ - return _select_or_reject(args, kwargs, lambda x: not x, False) + return select_or_reject(args, kwargs, lambda x: not x, False) @contextfilter @@ -899,7 +899,7 @@ def do_selectattr(*args, **kwargs): .. versionadded:: 2.7 """ - return _select_or_reject(args, kwargs, lambda x: x, True) + return select_or_reject(args, kwargs, lambda x: x, True) @contextfilter @@ -918,10 +918,10 @@ def do_rejectattr(*args, **kwargs): .. versionadded:: 2.7 """ - return _select_or_reject(args, kwargs, lambda x: not x, True) + return select_or_reject(args, kwargs, lambda x: not x, True) -def _select_or_reject(args, kwargs, modfunc, lookup_attr): +def prepare_select_or_reject(args, kwargs, modfunc, lookup_attr): context = args[0] seq = args[1] if lookup_attr: @@ -943,9 +943,14 @@ def _select_or_reject(args, kwargs, modfunc, lookup_attr): except LookupError: func = bool + return seq, lambda item: modfunc(func(transfunc(item))) + + +def select_or_reject(args, kwargs, modfunc, lookup_attr): + seq, func = prepare_select_or_reject(args, kwargs, modfunc, lookup_attr) if seq: for item in seq: - if modfunc(func(transfunc(item))): + if func(item): yield item diff --git a/tests/test_asyncfilters.py b/tests/test_asyncfilters.py index 4be25a3a..69f4e924 100644 --- a/tests/test_asyncfilters.py +++ b/tests/test_asyncfilters.py @@ -116,3 +116,15 @@ def make_users(): def test_join_attribute(env_async, users): tmpl = env_async.from_string('''{{ users()|join(', ', 'username') }}''') assert tmpl.render(users=users) == 'foo, bar' + + +def test_simple_reject(env_async): + tmpl = env_async.from_string('{{ [1, 2, 3, 4, 5]|reject("odd")|join("|") }}') + assert tmpl.render() == '2|4' + + +def test_bool_reject(env_async): + tmpl = env_async.from_string( + '{{ [none, false, 0, 1, 2, 3, 4, 5]|reject|join("|") }}' + ) + assert tmpl.render() == 'None|False|0'