Add workaround for orjson not handling subclasses of str (#105314)

Co-authored-by: Franck Nijhof <git@frenck.dev>
This commit is contained in:
Erik Montnemery 2023-12-08 18:13:34 +01:00 committed by Franck Nijhof
parent d9b31e9841
commit 35954128ad
No known key found for this signature in database
GPG key ID: D62583BA8AB11CA3
2 changed files with 30 additions and 3 deletions

View file

@ -33,9 +33,17 @@ class SerializationError(HomeAssistantError):
"""Error serializing the data to JSON."""
json_loads: Callable[[bytes | bytearray | memoryview | str], JsonValueType]
json_loads = orjson.loads
"""Parse JSON data."""
def json_loads(__obj: bytes | bytearray | memoryview | str) -> JsonValueType:
"""Parse JSON data.
This adds a workaround for orjson not handling subclasses of str,
https://github.com/ijl/orjson/issues/445.
"""
if type(__obj) in (bytes, bytearray, memoryview, str):
return orjson.loads(__obj) # type:ignore[no-any-return]
if isinstance(__obj, str):
return orjson.loads(str(__obj)) # type:ignore[no-any-return]
return orjson.loads(__obj) # type:ignore[no-any-return]
def json_loads_array(__obj: bytes | bytearray | memoryview | str) -> JsonArrayType:

View file

@ -1,10 +1,12 @@
"""Test Home Assistant json utility functions."""
from pathlib import Path
import orjson
import pytest
from homeassistant.exceptions import HomeAssistantError
from homeassistant.util.json import (
json_loads,
json_loads_array,
json_loads_object,
load_json,
@ -153,3 +155,20 @@ async def test_deprecated_save_json(
save_json(fname, TEST_JSON_A)
assert "uses save_json from homeassistant.util.json" in caplog.text
assert "should be updated to use homeassistant.helpers.json module" in caplog.text
async def test_loading_derived_class():
"""Test loading data from classes derived from str."""
class MyStr(str):
pass
class MyBytes(bytes):
pass
assert json_loads('"abc"') == "abc"
assert json_loads(MyStr('"abc"')) == "abc"
assert json_loads(b'"abc"') == "abc"
with pytest.raises(orjson.JSONDecodeError):
assert json_loads(MyBytes(b'"abc"')) == "abc"