Skip to content

Commit a076db8

Browse files
committed
fix(filter): unique with async generator
unique() filter doesn't work chained after a filter that return an async generator. This introduces a async variant of the filter transform the async generator into a list to be able to apply the unique filter. Fixes #1781
1 parent ae53ea5 commit a076db8

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

src/jinja2/filters.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ def do_sort(
410410

411411

412412
@pass_environment
413-
def do_unique(
413+
def sync_do_unique(
414414
environment: "Environment",
415415
value: "t.Iterable[V]",
416416
case_sensitive: bool = False,
@@ -442,6 +442,18 @@ def do_unique(
442442
yield item
443443

444444

445+
@async_variant(sync_do_unique) # type: ignore
446+
async def do_unique(
447+
environment: "Environment",
448+
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
449+
case_sensitive: bool = False,
450+
attribute: t.Optional[t.Union[str, int]] = None,
451+
) -> "t.Iterator[V]":
452+
return sync_do_unique(
453+
environment, await auto_to_list(value), case_sensitive, attribute
454+
)
455+
456+
445457
def _min_or_max(
446458
environment: "Environment",
447459
value: "t.Iterable[V]",

tests/test_async_filters.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,13 @@ def test_slice(env_async, items):
245245
)
246246

247247

248+
def test_unique_with_async_gen(env_async):
249+
items = ["a", "b", "c", "c", "a", "d", "z"]
250+
tmpl = env_async.from_string("{{ items|reject('==', 'z')|unique|list }}")
251+
out = tmpl.render(items=items)
252+
assert out == "['a', 'b', 'c', 'd']"
253+
254+
248255
def test_custom_async_filter(env_async):
249256
async def customfilter(val):
250257
return str(val)

0 commit comments

Comments
 (0)