Avoid de/recode of bytes to string to bytes when writing json files (#109348)

This commit is contained in:
J. Nick Koston 2024-02-02 02:02:26 -06:00 committed by GitHub
parent 9204e85b61
commit 582d6968b2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 23 additions and 17 deletions

View file

@ -148,12 +148,17 @@ JSON_DUMP: Final = json_dumps
def _orjson_default_encoder(data: Any) -> str:
"""JSON encoder that uses orjson with hass defaults."""
"""JSON encoder that uses orjson with hass defaults and returns a str."""
return _orjson_bytes_default_encoder(data).decode("utf-8")
def _orjson_bytes_default_encoder(data: Any) -> bytes:
"""JSON encoder that uses orjson with hass defaults and returns bytes."""
return orjson.dumps(
data,
option=orjson.OPT_INDENT_2 | orjson.OPT_NON_STR_KEYS,
default=json_encoder_default,
).decode("utf-8")
)
def save_json(
@ -173,11 +178,13 @@ def save_json(
if encoder and encoder is not JSONEncoder:
# If they pass a custom encoder that is not the
# default JSONEncoder, we use the slow path of json.dumps
mode = "w"
dump = json.dumps
json_data = json.dumps(data, indent=2, cls=encoder)
json_data: str | bytes = json.dumps(data, indent=2, cls=encoder)
else:
mode = "wb"
dump = _orjson_default_encoder
json_data = _orjson_default_encoder(data)
json_data = _orjson_bytes_default_encoder(data)
except TypeError as error:
formatted_data = format_unserializable_data(
find_paths_unserializable_data(data, dump=dump)
@ -186,10 +193,8 @@ def save_json(
_LOGGER.error(msg)
raise SerializationError(msg) from error
if atomic_writes:
write_utf8_file_atomic(filename, json_data, private)
else:
write_utf8_file(filename, json_data, private)
method = write_utf8_file_atomic if atomic_writes else write_utf8_file
method(filename, json_data, private, mode=mode)
def find_paths_unserializable_data(