return async_select_or_reject(args, kwargs, lambda x: not x, True)
+@asyncfiltervariant(filters.do_select)
+async def do_select(*args, **kwargs):
+ return async_select_or_reject(args, kwargs, lambda x: x, False)
+
+
+@asyncfiltervariant(filters.do_selectattr)
+async def do_selectattr(*args, **kwargs):
+ return async_select_or_reject(args, kwargs, lambda x: x, True)
+
+
+@asyncfiltervariant(filters.do_map)
+async def do_map(*args, **kwargs):
+ seq, func = filters.prepare_map(args, kwargs)
+ if seq:
+ async for item in seq:
+ yield func(item)
+
+
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,
+ 'reject': do_reject,
+ 'rejectattr': do_rejectattr,
+ 'map': do_map,
+ 'select': do_select,
+ 'selectattr': do_selectattr,
}
.. versionadded:: 2.7
"""
- context = args[0]
- seq = args[1]
-
- if len(args) == 2 and 'attribute' in kwargs:
- attribute = kwargs.pop('attribute')
- if kwargs:
- raise FilterArgumentError('Unexpected keyword argument %r' %
- next(iter(kwargs)))
- func = make_attrgetter(context.environment, attribute)
- else:
- try:
- name = args[2]
- args = args[3:]
- except LookupError:
- raise FilterArgumentError('map requires a filter argument')
- func = lambda item: context.environment.call_filter(
- name, item, args, kwargs, context=context)
-
+ seq, func = prepare_map(args, kwargs)
if seq:
for item in seq:
yield func(item)
return select_or_reject(args, kwargs, lambda x: not x, True)
+def prepare_map(args, kwargs):
+ context = args[0]
+ seq = args[1]
+
+ if len(args) == 2 and 'attribute' in kwargs:
+ attribute = kwargs.pop('attribute')
+ if kwargs:
+ raise FilterArgumentError('Unexpected keyword argument %r' %
+ next(iter(kwargs)))
+ func = make_attrgetter(context.environment, attribute)
+ else:
+ try:
+ name = args[2]
+ args = args[3:]
+ except LookupError:
+ raise FilterArgumentError('map requires a filter argument')
+ func = lambda item: context.environment.call_filter(
+ name, item, args, kwargs, context=context)
+
+ return seq, func
+
+
def prepare_select_or_reject(args, kwargs, modfunc, lookup_attr):
context = args[0]
seq = args[1]
'{{ items()|reject|join("|") }}'
)
assert tmpl.render(items=items) == 'None|False|0'
+
+
+def test_simple_select(env_async):
+ tmpl = env_async.from_string('{{ [1, 2, 3, 4, 5]|select("odd")|join("|") }}')
+ assert tmpl.render() == '1|3|5'
+
+
+def test_bool_select(env_async):
+ tmpl = env_async.from_string(
+ '{{ [none, false, 0, 1, 2, 3, 4, 5]|select|join("|") }}'
+ )
+ assert tmpl.render() == '1|2|3|4|5'
+
+
+def test_simple_select_attr(env_async):
+ class User(object):
+ def __init__(self, name, is_active):
+ self.name = name
+ self.is_active = is_active
+ users = [
+ User('john', True),
+ User('jane', True),
+ User('mike', False),
+ ]
+ tmpl = env_async.from_string(
+ '{{ users|selectattr("is_active")|'
+ 'map(attribute="name")|join("|") }}'
+ )
+ assert tmpl.render(users=users) == 'john|jane'