mirror of
https://github.com/home-assistant/core.git
synced 2025-11-09 10:59:40 +00:00
Add typed helpers and improve type hints in util/json (#88534)
* Add type hints to load_json * Adjust ios * Adjust nest * Add use of load_json_array * Add tests * Adjust test patch * Add test_load_json_os_error
This commit is contained in:
@@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
from collections.abc import Callable
|
||||
import json
|
||||
import logging
|
||||
from os import PathLike
|
||||
from typing import Any
|
||||
|
||||
import orjson
|
||||
@@ -12,6 +13,7 @@ from homeassistant.exceptions import HomeAssistantError
|
||||
|
||||
from .file import WriteError # pylint: disable=unused-import # noqa: F401
|
||||
|
||||
_SENTINEL = object()
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
JsonValueType = (
|
||||
@@ -54,8 +56,10 @@ def json_loads_object(__obj: bytes | bytearray | memoryview | str) -> JsonObject
|
||||
raise ValueError(f"Expected JSON to be parsed as a dict got {type(value)}")
|
||||
|
||||
|
||||
def load_json(filename: str, default: list | dict | None = None) -> list | dict:
|
||||
"""Load JSON data from a file and return as dict or list.
|
||||
def load_json(
|
||||
filename: str | PathLike, default: JsonValueType = _SENTINEL # type: ignore[assignment]
|
||||
) -> JsonValueType:
|
||||
"""Load JSON data from a file.
|
||||
|
||||
Defaults to returning empty dict if file is not found.
|
||||
"""
|
||||
@@ -71,7 +75,45 @@ def load_json(filename: str, default: list | dict | None = None) -> list | dict:
|
||||
except OSError as error:
|
||||
_LOGGER.exception("JSON file reading failed: %s", filename)
|
||||
raise HomeAssistantError(error) from error
|
||||
return {} if default is None else default
|
||||
return {} if default is _SENTINEL else default
|
||||
|
||||
|
||||
def load_json_array(
|
||||
filename: str | PathLike, default: JsonArrayType = _SENTINEL # type: ignore[assignment]
|
||||
) -> JsonArrayType:
|
||||
"""Load JSON data from a file and return as list.
|
||||
|
||||
Defaults to returning empty list if file is not found.
|
||||
"""
|
||||
if default is _SENTINEL:
|
||||
default = []
|
||||
value: JsonValueType = load_json(filename, default=default)
|
||||
# Avoid isinstance overhead as we are not interested in list subclasses
|
||||
if type(value) is list: # pylint: disable=unidiomatic-typecheck
|
||||
return value
|
||||
_LOGGER.exception(
|
||||
"Expected JSON to be parsed as a list got %s in: %s", {type(value)}, filename
|
||||
)
|
||||
raise HomeAssistantError(f"Expected JSON to be parsed as a list got {type(value)}")
|
||||
|
||||
|
||||
def load_json_object(
|
||||
filename: str | PathLike, default: JsonObjectType = _SENTINEL # type: ignore[assignment]
|
||||
) -> JsonObjectType:
|
||||
"""Load JSON data from a file and return as dict.
|
||||
|
||||
Defaults to returning empty dict if file is not found.
|
||||
"""
|
||||
if default is _SENTINEL:
|
||||
default = {}
|
||||
value: JsonValueType = load_json(filename, default=default)
|
||||
# Avoid isinstance overhead as we are not interested in dict subclasses
|
||||
if type(value) is dict: # pylint: disable=unidiomatic-typecheck
|
||||
return value
|
||||
_LOGGER.exception(
|
||||
"Expected JSON to be parsed as a dict got %s in: %s", {type(value)}, filename
|
||||
)
|
||||
raise HomeAssistantError(f"Expected JSON to be parsed as a dict got {type(value)}")
|
||||
|
||||
|
||||
def save_json(
|
||||
|
||||
Reference in New Issue
Block a user