Workaround to_json template filter in parsing dict key (#105327)

* Work-a-round orjson for `to_json` fiter in case dict key is str subclass

* Add option instead

* Remove json.dumps work-a-round

* Update homeassistant/helpers/template.py

* Fix test

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
Jan Bouwhuis 2023-12-08 20:57:53 +01:00 committed by Franck Nijhof
parent 629731e2dd
commit 5220afa856
No known key found for this signature in database
GPG key ID: D62583BA8AB11CA3
2 changed files with 20 additions and 0 deletions

View file

@ -2125,6 +2125,10 @@ def to_json(
option = (
ORJSON_PASSTHROUGH_OPTIONS
# OPT_NON_STR_KEYS is added as a workaround to
# ensure subclasses of str are allowed as dict keys
# See: https://github.com/ijl/orjson/issues/445
| orjson.OPT_NON_STR_KEYS
| (orjson.OPT_INDENT_2 if pretty_print else 0)
| (orjson.OPT_SORT_KEYS if sort_keys else 0)
)

View file

@ -1233,6 +1233,22 @@ def test_to_json(hass: HomeAssistant) -> None:
with pytest.raises(TemplateError):
template.Template("{{ {'Foo': now()} | to_json }}", hass).async_render()
# Test special case where substring class cannot be rendered
# See: https://github.com/ijl/orjson/issues/445
class MyStr(str):
pass
expected_result = '{"mykey1":11.0,"mykey2":"myvalue2","mykey3":["opt3b","opt3a"]}'
test_dict = {
MyStr("mykey2"): "myvalue2",
MyStr("mykey1"): 11.0,
MyStr("mykey3"): ["opt3b", "opt3a"],
}
actual_result = template.Template(
"{{ test_dict | to_json(sort_keys=True) }}", hass
).async_render(parse_result=False, variables={"test_dict": test_dict})
assert actual_result == expected_result
def test_to_json_ensure_ascii(hass: HomeAssistant) -> None:
"""Test the object to JSON string filter."""