Files
2026-10-05 16:46:28 +03:00

63 lines
2.2 KiB
Python

"""Shared strict scalar and object readers for configuration codecs."""
from __future__ import annotations
import math
from typing import Any
def json_object(value: Any, context: str) -> dict[str, Any]:
"""Read an object; a missing or null section keeps its defaults."""
if value is None:
return {}
if not isinstance(value, dict):
raise ValueError(f"{context} must be a JSON object")
return value
def _value(payload: dict[str, Any], key: str, default: Any) -> Any:
value = payload.get(key, default)
return default if value is None else value
def read_int(payload: dict[str, Any], key: str, default: int) -> int:
"""Read a JSON integer without truncation or boolean coercion."""
value = _value(payload, key, default)
if isinstance(value, bool) or not isinstance(value, int):
raise ValueError(f"{key} must be a JSON integer")
return value
def read_str(payload: dict[str, Any], key: str, default: str) -> str:
"""Read a JSON string without converting other scalar types."""
value = _value(payload, key, default)
if not isinstance(value, str):
raise ValueError(f"{key} must be a JSON string")
return value
def read_bool(payload: dict[str, Any], key: str, default: bool) -> bool:
"""Read a JSON boolean."""
value = _value(payload, key, default)
if not isinstance(value, bool):
raise ValueError(f"{key} must be a JSON boolean")
return value
def read_float(payload: dict[str, Any], key: str, default: float) -> float:
"""Read a finite JSON number, including overflow-safe integer conversion."""
return finite_number(_value(payload, key, default), key)
def finite_number(value: Any, context: str) -> float:
"""Validate a number without accepting booleans, strings or nonfinite values."""
if isinstance(value, bool) or not isinstance(value, (int, float)):
raise ValueError(f"{context} must be a JSON number")
try:
result = float(value)
except OverflowError as exc:
raise ValueError(f"{context} must be a finite number") from exc
if not math.isfinite(result):
raise ValueError(f"{context} must be a finite number")
return result