mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 17:27:52 +00:00
Add template function: shuffle (#140077)
This commit is contained in:
parent
b7094c12f7
commit
d4f205c366
@ -6,7 +6,7 @@ from ast import literal_eval
|
||||
import asyncio
|
||||
import base64
|
||||
import collections.abc
|
||||
from collections.abc import Callable, Generator, Iterable
|
||||
from collections.abc import Callable, Generator, Iterable, MutableSequence
|
||||
from contextlib import AbstractContextManager
|
||||
from contextvars import ContextVar
|
||||
from copy import deepcopy
|
||||
@ -2736,6 +2736,30 @@ def iif(
|
||||
return if_false
|
||||
|
||||
|
||||
def shuffle(*args: Any, seed: Any = None) -> MutableSequence[Any]:
|
||||
"""Shuffle a list, either with a seed or without."""
|
||||
if not args:
|
||||
raise TypeError("shuffle expected at least 1 argument, got 0")
|
||||
|
||||
# If first argument is iterable and more than 1 argument provided
|
||||
# but not a named seed, then use 2nd argument as seed.
|
||||
if isinstance(args[0], Iterable):
|
||||
items = list(args[0])
|
||||
if len(args) > 1 and seed is None:
|
||||
seed = args[1]
|
||||
elif len(args) == 1:
|
||||
raise TypeError(f"'{type(args[0]).__name__}' object is not iterable")
|
||||
else:
|
||||
items = list(args)
|
||||
|
||||
if seed:
|
||||
r = random.Random(seed)
|
||||
r.shuffle(items)
|
||||
else:
|
||||
random.shuffle(items)
|
||||
return items
|
||||
|
||||
|
||||
class TemplateContextManager(AbstractContextManager):
|
||||
"""Context manager to store template being parsed or rendered in a ContextVar."""
|
||||
|
||||
@ -2936,6 +2960,7 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
|
||||
self.filters["bool"] = forgiving_boolean
|
||||
self.filters["version"] = version
|
||||
self.filters["contains"] = contains
|
||||
self.filters["shuffle"] = shuffle
|
||||
self.globals["log"] = logarithm
|
||||
self.globals["sin"] = sine
|
||||
self.globals["cos"] = cosine
|
||||
@ -2973,6 +2998,7 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
|
||||
self.globals["bool"] = forgiving_boolean
|
||||
self.globals["version"] = version
|
||||
self.globals["zip"] = zip
|
||||
self.globals["shuffle"] = shuffle
|
||||
self.tests["is_number"] = is_number
|
||||
self.tests["list"] = _is_list
|
||||
self.tests["set"] = _is_set
|
||||
|
@ -15,6 +15,7 @@ from unittest.mock import patch
|
||||
from freezegun import freeze_time
|
||||
import orjson
|
||||
import pytest
|
||||
from pytest_unordered import unordered
|
||||
from syrupy import SnapshotAssertion
|
||||
import voluptuous as vol
|
||||
|
||||
@ -6672,3 +6673,54 @@ async def test_merge_response_not_mutate_original_object(
|
||||
|
||||
tpl = template.Template(_template, hass)
|
||||
assert tpl.async_render()
|
||||
|
||||
|
||||
def test_shuffle(hass: HomeAssistant) -> None:
|
||||
"""Test the shuffle function and filter."""
|
||||
assert list(
|
||||
template.Template("{{ [1, 2, 3] | shuffle }}", hass).async_render()
|
||||
) == unordered([1, 2, 3])
|
||||
|
||||
assert list(
|
||||
template.Template("{{ shuffle([1, 2, 3]) }}", hass).async_render()
|
||||
) == unordered([1, 2, 3])
|
||||
|
||||
assert list(
|
||||
template.Template("{{ shuffle(1, 2, 3) }}", hass).async_render()
|
||||
) == unordered([1, 2, 3])
|
||||
|
||||
assert list(template.Template("{{ shuffle([]) }}", hass).async_render()) == []
|
||||
|
||||
assert list(template.Template("{{ [] | shuffle }}", hass).async_render()) == []
|
||||
|
||||
# Testing using seed
|
||||
assert list(
|
||||
template.Template("{{ shuffle([1, 2, 3], 'seed') }}", hass).async_render()
|
||||
) == [2, 3, 1]
|
||||
|
||||
assert list(
|
||||
template.Template(
|
||||
"{{ shuffle([1, 2, 3], seed='seed') }}",
|
||||
hass,
|
||||
).async_render()
|
||||
) == [2, 3, 1]
|
||||
|
||||
assert list(
|
||||
template.Template(
|
||||
"{{ [1, 2, 3] | shuffle('seed') }}",
|
||||
hass,
|
||||
).async_render()
|
||||
) == [2, 3, 1]
|
||||
|
||||
assert list(
|
||||
template.Template(
|
||||
"{{ [1, 2, 3] | shuffle(seed='seed') }}",
|
||||
hass,
|
||||
).async_render()
|
||||
) == [2, 3, 1]
|
||||
|
||||
with pytest.raises(TemplateError):
|
||||
template.Template("{{ 1 | shuffle }}", hass).async_render()
|
||||
|
||||
with pytest.raises(TemplateError):
|
||||
template.Template("{{ shuffle() }}", hass).async_render()
|
||||
|
Loading…
x
Reference in New Issue
Block a user