]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
make unique filter async-aware 1782/head
authorMehdi ABAAKOUK <sileht@sileht.net>
Fri, 23 Dec 2022 08:46:29 +0000 (09:46 +0100)
committerDavid Lord <davidism@gmail.com>
Thu, 19 Dec 2024 15:19:13 +0000 (07:19 -0800)
CHANGES.rst
src/jinja2/filters.py
tests/test_async_filters.py

index 540d5cccbe2adb037e09aa4d4afa92920bdce336..e4bffbfb91d73599b0ba1626048b3c2c4a9c1cdf 100644 (file)
@@ -16,6 +16,8 @@ Unreleased
     :pr:`1960`
 -   The runtime uses the correct ``concat`` function for the current environment
     when calling block references. :issue:`1701`
+-   Make ``|unique`` async-aware, allowing it to be used after another
+    async-aware filter. :issue:`1781`
 
 
 Version 3.1.4
index 4c949cbde7b4299d32941a27079e138264b7a361..af9f6bc0ee9af03b2e526c4befc4443d0acde4b9 100644 (file)
@@ -438,7 +438,7 @@ def do_sort(
 
 
 @pass_environment
-def do_unique(
+def sync_do_unique(
     environment: "Environment",
     value: "t.Iterable[V]",
     case_sensitive: bool = False,
@@ -470,6 +470,18 @@ def do_unique(
             yield item
 
 
+@async_variant(sync_do_unique)  # type: ignore
+async def do_unique(
+    environment: "Environment",
+    value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
+    case_sensitive: bool = False,
+    attribute: t.Optional[t.Union[str, int]] = None,
+) -> "t.Iterator[V]":
+    return sync_do_unique(
+        environment, await auto_to_list(value), case_sensitive, attribute
+    )
+
+
 def _min_or_max(
     environment: "Environment",
     value: "t.Iterable[V]",
index e8cc350d5070d8a1b96a2c2e0946a168b5b07e2d..e9892f1edcdf17fcc502acd5523366dff63d2cf1 100644 (file)
@@ -277,6 +277,13 @@ def test_slice(env_async, items):
     )
 
 
+def test_unique_with_async_gen(env_async):
+    items = ["a", "b", "c", "c", "a", "d", "z"]
+    tmpl = env_async.from_string("{{ items|reject('==', 'z')|unique|list }}")
+    out = tmpl.render(items=items)
+    assert out == "['a', 'b', 'c', 'd']"
+
+
 def test_custom_async_filter(env_async, run_async_fn):
     async def customfilter(val):
         return str(val)