diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index b3907143eb9..188ecb8ff98 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -3,7 +3,6 @@ from __future__ import annotations from collections.abc import Iterator from functools import lru_cache -import json import logging import os import pathlib @@ -22,6 +21,7 @@ from homeassistant.const import CONF_MODE, CONF_NAME, EVENT_THEMES_UPDATED from homeassistant.core import HomeAssistant, ServiceCall, callback from homeassistant.helpers import service import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.json import json_dumps_sorted from homeassistant.helpers.storage import Store from homeassistant.helpers.translation import async_get_translations from homeassistant.helpers.typing import ConfigType @@ -135,7 +135,7 @@ class Manifest: return self._serialized def _serialize(self) -> None: - self._serialized = json.dumps(self.manifest, sort_keys=True) + self._serialized = json_dumps_sorted(self.manifest) def update_key(self, key: str, val: str) -> None: """Add a keyval to the manifest.json.""" diff --git a/homeassistant/helpers/json.py b/homeassistant/helpers/json.py index fd1153711ad..dbe3163da08 100644 --- a/homeassistant/helpers/json.py +++ b/homeassistant/helpers/json.py @@ -87,6 +87,15 @@ def json_dumps(data: Any) -> str: ).decode("utf-8") +def json_dumps_sorted(data: Any) -> str: + """Dump json string with keys sorted.""" + return orjson.dumps( + data, + option=orjson.OPT_NON_STR_KEYS | orjson.OPT_SORT_KEYS, + default=json_encoder_default, + ).decode("utf-8") + + json_loads = orjson.loads diff --git a/tests/helpers/test_json.py b/tests/helpers/test_json.py index 4968c872946..17066b682af 100644 --- a/tests/helpers/test_json.py +++ b/tests/helpers/test_json.py @@ -1,10 +1,15 @@ """Test Home Assistant remote methods and classes.""" import datetime +import json import pytest from homeassistant import core -from homeassistant.helpers.json import ExtendedJSONEncoder, JSONEncoder +from homeassistant.helpers.json import ( + ExtendedJSONEncoder, + JSONEncoder, + json_dumps_sorted, +) from homeassistant.util import dt as dt_util @@ -64,3 +69,11 @@ def test_extended_json_encoder(hass): # Default method falls back to repr(o) o = object() assert ha_json_enc.default(o) == {"__type": str(type(o)), "repr": repr(o)} + + +def test_json_dumps_sorted(): + """Test the json dumps sorted function.""" + data = {"c": 3, "a": 1, "b": 2} + assert json_dumps_sorted(data) == json.dumps( + data, sort_keys=True, separators=(",", ":") + )