Compare commits

...

4 Commits

Author SHA1 Message Date
Franck Nijhof aaedff9502 Remove dead URL no-op in Pushbullet notify 2026-06-29 16:14:24 +00:00
Franck Nijhof cb1f8ce440 Guard the probatio shim import for pre-install scripts 2026-06-29 18:05:15 +02:00
Franck Nijhof e0f5c99fdf Activate the probatio shim for script entrypoints 2026-06-29 18:05:15 +02:00
Franck Nijhof 2952bf3e1a Use probatio as the data validation engine 2026-06-29 18:05:15 +02:00
73 changed files with 230 additions and 223 deletions
+8
View File
@@ -1 +1,9 @@
"""Init file for Home Assistant."""
from probatio.compat import install_as_voluptuous
# Probatio replaces voluptuous as the validation engine. Custom integrations and a
# few dependencies still import voluptuous directly, so alias it to probatio in
# sys.modules before anything imports it. This must run before the first
# `import voluptuous`, hence the package __init__.
install_as_voluptuous()
@@ -6,8 +6,8 @@ import logging
from typing import TYPE_CHECKING, Any, cast, override
import anthropic
from probatio import to_openapi as convert
import voluptuous as vol
from voluptuous_openapi import convert
from homeassistant.components.zone import ENTITY_ID_HOME
from homeassistant.config_entries import (
+1 -1
View File
@@ -103,8 +103,8 @@ from anthropic.types.web_fetch_tool_result_block import (
from anthropic.types.web_fetch_tool_result_block_param import (
Content as WebFetchToolResultBlockParamContentParam,
)
from probatio import to_openapi as convert
import voluptuous as vol
from voluptuous_openapi import convert
from homeassistant.components import conversation
from homeassistant.config_entries import ConfigSubentry
+2 -2
View File
@@ -74,8 +74,8 @@ from ipaddress import ip_address
from typing import TYPE_CHECKING, Any, cast
from aiohttp import web
from probatio import serialize
import voluptuous as vol
import voluptuous_serialize
from homeassistant import data_entry_flow
from homeassistant.auth import AuthManagerFlowManager, InvalidAuthError
@@ -263,7 +263,7 @@ def _prepare_result_json(result: AuthFlowResult) -> dict[str, Any]:
if (schema := result["data_schema"]) is None:
data["data_schema"] = []
else:
data["data_schema"] = voluptuous_serialize.convert(schema)
data["data_schema"] = serialize(schema)
return data
@@ -3,8 +3,8 @@
import logging
from typing import Any, override
from probatio import serialize
import voluptuous as vol
import voluptuous_serialize
from homeassistant import data_entry_flow
from homeassistant.components import websocket_api
@@ -153,6 +153,6 @@ def _prepare_result_json(result: data_entry_flow.FlowResult) -> dict[str, Any]:
if (schema := result["data_schema"]) is None:
data["data_schema"] = []
else:
data["data_schema"] = voluptuous_serialize.convert(schema)
data["data_schema"] = serialize(schema)
return data
+1 -1
View File
@@ -42,8 +42,8 @@ from openai.types.responses.response_input_param import (
ImageGenerationCall as ImageGenerationCallParam,
)
from openai.types.responses.response_output_item import ImageGenerationCall
from probatio import to_openapi as convert
import voluptuous as vol
from voluptuous_openapi import convert
from homeassistant.components import conversation
from homeassistant.config_entries import ConfigEntry
@@ -9,8 +9,8 @@ import logging
from types import ModuleType
from typing import TYPE_CHECKING, Any, Literal, overload
from probatio import serialize
import voluptuous as vol
import voluptuous_serialize
from homeassistant.components import websocket_api
from homeassistant.components.websocket_api import ActiveConnection
@@ -318,7 +318,7 @@ async def _async_get_device_automation_capabilities(
if (extra_fields := capabilities.get("extra_fields")) is None:
capabilities["extra_fields"] = []
else:
capabilities["extra_fields"] = voluptuous_serialize.convert(
capabilities["extra_fields"] = serialize(
extra_fields, custom_serializer=cv.custom_serializer
)
@@ -31,8 +31,8 @@ from google.genai.types import (
Tool,
ToolListUnion,
)
from probatio import to_openapi as convert
import voluptuous as vol
from voluptuous_openapi import convert
from homeassistant.components import conversation
from homeassistant.config_entries import ConfigSubentry
@@ -2,13 +2,13 @@
from typing import Any, TypedDict
from probatio import serialize
from pyinsteon import async_close, async_connect, devices
from pyinsteon.address import Address
from pyinsteon.aldb.aldb_record import ALDBRecord
from pyinsteon.constants import LinkStatus
from pyinsteon.managers.link_manager import get_broken_links
import voluptuous as vol
import voluptuous_serialize
from homeassistant.components import websocket_api
from homeassistant.config_entries import ConfigEntry
@@ -212,12 +212,10 @@ async def websocket_get_modem_schema(
config_data = config_entry.data
if device := config_data.get(CONF_DEVICE):
ports = await async_get_usb_ports(hass=hass)
plm_schema = voluptuous_serialize.convert(
build_plm_schema(ports=ports, device=device)
)
plm_schema = serialize(build_plm_schema(ports=ports, device=device))
connection.send_result(msg[ID], plm_schema)
else:
hub_schema = voluptuous_serialize.convert(build_hub_schema(**config_data))
hub_schema = serialize(build_hub_schema(**config_data))
connection.send_result(msg[ID], hub_schema)
@@ -2,6 +2,7 @@
from typing import Any
from probatio import serialize
from pyinsteon import devices
from pyinsteon.config import (
LOAD_BUTTON,
@@ -18,7 +19,6 @@ from pyinsteon.constants import (
)
from pyinsteon.device_types.device_base import Device
import voluptuous as vol
import voluptuous_serialize
from homeassistant.components import websocket_api
from homeassistant.core import HomeAssistant
@@ -43,26 +43,26 @@ RELAY_MODES = [str(RelayMode(v)).lower() for v in list(RelayMode)]
def _bool_schema(name):
return voluptuous_serialize.convert(vol.Schema({vol.Required(name): bool}))[0]
return serialize(vol.Schema({vol.Required(name): bool}))[0]
def _byte_schema(name):
return voluptuous_serialize.convert(vol.Schema({vol.Required(name): cv.byte}))[0]
return serialize(vol.Schema({vol.Required(name): cv.byte}))[0]
def _float_schema(name):
return voluptuous_serialize.convert(vol.Schema({vol.Required(name): float}))[0]
return serialize(vol.Schema({vol.Required(name): float}))[0]
def _list_schema(name, values):
return voluptuous_serialize.convert(
return serialize(
vol.Schema({vol.Required(name): vol.In(values)}),
custom_serializer=cv.custom_serializer,
)[0]
def _multi_select_schema(name, values):
return voluptuous_serialize.convert(
return serialize(
vol.Schema({vol.Optional(name): cv.multi_select(values)}),
custom_serializer=cv.custom_serializer,
)[0]
@@ -70,7 +70,7 @@ def _multi_select_schema(name, values):
def _read_only_schema(name, value):
"""Return a constant value schema."""
return voluptuous_serialize.convert(vol.Schema({vol.Required(name): value}))[0]
return serialize(vol.Schema({vol.Required(name): value}))[0]
def get_schema(prop, name, groups):
@@ -1,6 +1,6 @@
"""Selectors for KNX."""
from collections.abc import Hashable, Iterable
from collections.abc import Iterable
from enum import Enum
from typing import Any, override
@@ -23,7 +23,7 @@ class AllSerializeFirst(vol.All):
class KNXSelectorBase:
"""Base class for KNX selectors supporting optional nested schemas."""
schema: vol.Schema | vol.Any | vol.All
schema: vol.Schema | vol.Any | vol.All | GroupSelectSchema
selector_type: str
# mark if self.schema should be serialized to `schema` key
serialize_subschema: bool = False
@@ -108,30 +108,35 @@ class GroupSelectOption(KNXSelectorBase):
}
class GroupSelectSchema(vol.Any):
"""Use the first validated value.
class GroupSelectSchema:
"""Use the first validated value, like ``vol.Any``.
This is a version of vol.Any with custom error handling to
show proper invalid markers for sub-schema items in the UI.
A standalone validator rather than a ``vol.Any`` subclass, so it does not
reach into validation-engine internals. On total failure it raises the most
useful branch error (the first that is not an unknown-key error, else the
first) so the UI marks a real problem instead of an extra key.
"""
@override
def _exec(self, funcs: Iterable, v: Any, path: list[Hashable] | None = None) -> Any:
"""Execute the validation functions."""
def __init__(self, *options: vol.Schemable, msg: str | None = None) -> None:
"""Store the options to try in order."""
self.validators = options
self.msg = msg
self._compiled = [vol.Schema(option) for option in options]
def __call__(self, data: Any) -> Any:
"""Return the first option that validates, else raise the best error."""
errors: list[vol.Invalid] = []
for func in funcs:
for option in self._compiled:
try:
if path is None:
return func(v)
return func(path, v)
except vol.Invalid as e:
errors.append(e)
return option(data)
except vol.Invalid as err:
errors.append(err)
if errors:
raise next(
(err for err in errors if "extra keys not allowed" not in err.msg),
(err for err in errors if err.code != "extra_keys_not_allowed"),
errors[0],
)
raise vol.AnyInvalid(self.msg or "no valid value found", path=path)
raise vol.AnyInvalid(self.msg or "no valid value found")
class GroupSelect(KNXSelectorBase):
@@ -2,8 +2,7 @@
from typing import Any, cast
import voluptuous as vol
from voluptuous_serialize import UNSUPPORTED, UnsupportedType, convert
from probatio import UNSUPPORTED, serialize as convert
from homeassistant.const import Platform
from homeassistant.helpers import selector
@@ -12,9 +11,7 @@ from .entity_store_schema import KNX_SCHEMA_FOR_PLATFORM
from .knx_selector import AllSerializeFirst, GroupSelectSchema, KNXSelectorBase
def knx_serializer(
schema: vol.Schema,
) -> dict[str, Any] | list[dict[str, Any]] | UnsupportedType:
def knx_serializer(schema: Any) -> Any:
"""Serialize KNX schema."""
if isinstance(schema, GroupSelectSchema):
return [
@@ -43,5 +40,8 @@ def get_serialized_schema(
) -> dict[str, Any] | list[dict[str, Any]] | None:
"""Get the schema for a specific platform."""
if knx_schema := KNX_SCHEMA_FOR_PLATFORM.get(platform):
return convert(knx_schema, custom_serializer=knx_serializer)
return cast(
"dict[str, Any] | list[dict[str, Any]]",
convert(knx_schema, custom_serializer=knx_serializer),
)
return None
+1 -1
View File
@@ -12,8 +12,8 @@ from mcp import McpError
from mcp.client.session import ClientSession
from mcp.client.sse import sse_client
from mcp.client.streamable_http import streamable_http_client
from probatio import from_openapi as convert_to_voluptuous
import voluptuous as vol
from voluptuous_openapi import convert_to_voluptuous
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_URL
@@ -15,9 +15,9 @@ from typing import Any, cast
from mcp import types
from mcp.server import Server
from mcp.server.lowlevel.helper_types import ReadResourceContents
from probatio import to_openapi as convert
from pydantic import AnyUrl
import voluptuous as vol
from voluptuous_openapi import convert
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
@@ -14,6 +14,7 @@ from aiohttp.web import HTTPBadRequest, Request, Response, json_response
from nacl.exceptions import CryptoError
from nacl.secret import SecretBox
import voluptuous as vol
from voluptuous.humanize import humanize_error
from homeassistant.components import (
camera,
@@ -159,7 +160,7 @@ def validate_schema(schema):
try:
data = schema(data)
except vol.Invalid as ex:
err = vol.humanize.humanize_error(data, ex)
err = humanize_error(data, ex)
_LOGGER.error("Received invalid webhook payload: %s", err)
return empty_okay_response()
@@ -200,7 +201,7 @@ async def handle_webhook(
try:
req_data = WEBHOOK_PAYLOAD_SCHEMA(req_data)
except vol.Invalid as ex:
err = vol.humanize.humanize_error(req_data, ex)
err = humanize_error(req_data, ex)
_LOGGER.error(
"Received invalid webhook from %s with payload: %s", device_name, err
)
@@ -648,7 +649,7 @@ async def webhook_update_sensor_states(
try:
sensor = SENSOR_SCHEMA_FULL(sensor)
except vol.Invalid as err:
err_msg = vol.humanize.humanize_error(sensor, err)
err_msg = humanize_error(sensor, err)
_LOGGER.error(
"Received invalid sensor payload from %s for %s: %s",
device_name,
+1 -1
View File
@@ -6,8 +6,8 @@ import logging
from typing import Any
import ollama
from probatio import to_openapi as convert
import voluptuous as vol
from voluptuous_openapi import convert
from homeassistant.components import conversation
from homeassistant.config_entries import ConfigSubentry
@@ -22,8 +22,8 @@ from openai.types.chat import (
from openai.types.chat.chat_completion_message_function_tool_call_param import Function
from openai.types.shared_params import FunctionDefinition, ResponseFormatJSONSchema
from openai.types.shared_params.response_format_json_schema import JSONSchema
from probatio import to_openapi as convert
import voluptuous as vol
from voluptuous_openapi import convert
from homeassistant.components import conversation
from homeassistant.config_entries import ConfigSubentry
@@ -6,8 +6,8 @@ import logging
from typing import Any, override
import openai
from probatio import to_openapi as convert
import voluptuous as vol
from voluptuous_openapi import convert
from homeassistant.components.zone import ENTITY_ID_HOME
from homeassistant.config_entries import (
@@ -56,8 +56,8 @@ from openai.types.responses.tool_param import (
ImageGeneration,
)
from openai.types.responses.web_search_tool_param import UserLocation
from probatio import to_openapi as convert
import voluptuous as vol
from voluptuous_openapi import convert
from homeassistant.components import conversation
from homeassistant.config_entries import ConfigSubentry
@@ -18,7 +18,7 @@ from openai.types.chat import (
)
from openai.types.chat.chat_completion_message_function_tool_call_param import Function
from openai.types.shared_params import FunctionDefinition
from voluptuous_openapi import convert
from probatio import to_openapi as convert
from homeassistant.components import conversation
from homeassistant.config_entries import ConfigSubentry
@@ -7,7 +7,6 @@ from typing import TYPE_CHECKING, Any, override
from pushbullet import PushBullet, PushError
from pushbullet.channel import Channel
from pushbullet.device import Device
import voluptuous as vol
from homeassistant.components.notify import (
ATTR_DATA,
@@ -144,7 +143,7 @@ class PushBulletNotificationService(BaseNotificationService):
raise ValueError("Cannot send an empty file")
kwargs.update(filedata)
pusher.push_file(**kwargs)
elif (file_url := data.get(ATTR_FILE_URL)) and vol.Url(file_url):
elif file_url := data.get(ATTR_FILE_URL):
pusher.push_file(
file_name=file_url,
file_url=file_url,
@@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, Any, Literal, override
from aiohttp import web
import voluptuous as vol
from voluptuous.humanize import humanize_error
from homeassistant.auth.models import RefreshToken, User
from homeassistant.core import Context, HomeAssistant, callback
@@ -295,7 +296,7 @@ class ActiveConnection:
err_message = "Unauthorized"
elif isinstance(err, vol.Invalid):
code = const.ERR_INVALID_FORMAT
err_message = vol.humanize.humanize_error(msg, err)
err_message = humanize_error(msg, err)
elif isinstance(err, TimeoutError):
code = const.ERR_TIMEOUT
err_message = "Timeout"
@@ -779,7 +779,7 @@ async def websocket_device_cluster_commands(
hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any]
) -> None:
"""Return a list of cluster commands."""
import voluptuous_serialize # noqa: PLC0415
from probatio import serialize # noqa: PLC0415
zha_gateway = get_zha_gateway(hass)
ieee: EUI64 = msg[ATTR_IEEE]
@@ -801,7 +801,7 @@ async def websocket_device_cluster_commands(
TYPE: CLIENT,
ID: cmd_id,
ATTR_NAME: cmd.name,
"schema": voluptuous_serialize.convert(
"schema": serialize(
cluster_command_schema_to_vol_schema(cmd.schema),
custom_serializer=cv.custom_serializer,
),
@@ -813,7 +813,7 @@ async def websocket_device_cluster_commands(
TYPE: CLUSTER_COMMAND_SERVER,
ID: cmd_id,
ATTR_NAME: cmd.name,
"schema": voluptuous_serialize.convert(
"schema": serialize(
cluster_command_schema_to_vol_schema(cmd.schema),
custom_serializer=cv.custom_serializer,
),
@@ -1087,16 +1087,14 @@ async def websocket_get_configuration(
) -> None:
"""Get ZHA configuration."""
config_entry: ConfigEntry = get_config_entry(hass)
import voluptuous_serialize # noqa: PLC0415
from probatio import serialize # noqa: PLC0415
def custom_serializer(schema: Any) -> Any:
"""Serialize additional types for voluptuous_serialize."""
"""Serialize additional types for the field-list serializer."""
if schema is cv_boolean:
return {"type": "bool"}
if schema is vol.Schema:
return voluptuous_serialize.convert(
schema, custom_serializer=custom_serializer
)
return serialize(schema, custom_serializer=custom_serializer)
return cv.custom_serializer(schema)
@@ -1106,7 +1104,7 @@ async def websocket_get_configuration(
hass, IasAce.cluster_id
):
continue
data["schemas"][section] = voluptuous_serialize.convert(
data["schemas"][section] = serialize(
schema, custom_serializer=custom_serializer
)
data["data"][section] = config_entry.options.get(CUSTOM_CONFIGURATION, {}).get(
+1 -1
View File
@@ -478,7 +478,7 @@ def stringify_invalid(
if annotation := find_annotation(config, exc.path):
message_prefix += f" at {_relpath(hass, annotation[0])}, line {annotation[1]}"
path = "->".join(str(m) for m in exc.path)
if exc.error_message == "extra keys not allowed":
if exc.code == "extra_keys_not_allowed":
return (
f"{message_prefix}: '{exc.path[-1]}' is an invalid option for '{domain}', "
f"check: {path}{message_suffix}"
+3 -3
View File
@@ -23,8 +23,8 @@ from typing import TYPE_CHECKING, Any, cast, overload
from urllib.parse import urlparse
from uuid import UUID
from probatio import UNSUPPORTED, serialize
import voluptuous as vol
import voluptuous_serialize
from homeassistant.const import (
ATTR_AREA_ID,
@@ -1188,7 +1188,7 @@ def _custom_serializer(schema: Any, *, allow_section: bool) -> Any:
raise ValueError("Nesting expandable sections is not supported")
return {
"type": "expandable",
"schema": voluptuous_serialize.convert(
"schema": serialize(
schema.schema,
custom_serializer=functools.partial(
_custom_serializer, allow_section=False
@@ -1203,7 +1203,7 @@ def _custom_serializer(schema: Any, *, allow_section: bool) -> Any:
if isinstance(schema, selector.Selector):
return schema.serialize()
return voluptuous_serialize.UNSUPPORTED
return UNSUPPORTED
# Schemas
+2 -2
View File
@@ -4,8 +4,8 @@ from http import HTTPStatus
from typing import Any, Generic, TypeVar
from aiohttp import web
from probatio import serialize
import voluptuous as vol
import voluptuous_serialize
from homeassistant import data_entry_flow
from homeassistant.components.http import HomeAssistantView
@@ -47,7 +47,7 @@ class _BaseFlowManagerView(HomeAssistantView, Generic[_FlowManagerT]):
if (schema := result["data_schema"]) is None:
data["data_schema"] = []
else:
data["data_schema"] = voluptuous_serialize.convert(
data["data_schema"] = serialize(
schema, custom_serializer=cv.custom_serializer
)
return data
+1 -1
View File
@@ -10,9 +10,9 @@ from functools import cache, partial
from operator import attrgetter
from typing import Any, cast, override
from probatio import UNSUPPORTED, to_openapi as convert
import slugify as unicode_slug
import voluptuous as vol
from voluptuous_openapi import UNSUPPORTED, convert
from homeassistant.components.calendar import (
DOMAIN as CALENDAR_DOMAIN,
+1 -3
View File
@@ -51,6 +51,7 @@ orjson==3.11.9
packaging>=23.1
paho-mqtt==2.1.0
Pillow==12.2.0
probatio==0.5.4
propcache==0.5.2
psutil-home-assistant==0.0.1
PyJWT==2.12.1
@@ -71,9 +72,6 @@ typing-extensions>=4.15.0,<5.0
ulid-transform==2.2.9
urllib3>=2.0
uv==0.11.21
voluptuous-openapi==0.4.1
voluptuous-serialize==2.7.0
voluptuous==0.15.2
webrtc-models==0.3.0
yarl==1.24.2
zeroconf==0.150.0
Generated
+1
View File
@@ -5,6 +5,7 @@
[mypy]
python_version = 3.14
platform = linux
mypy_path = stubs
plugins = pydantic.mypy
show_error_codes = true
follow_imports = normal
+1 -4
View File
@@ -75,9 +75,7 @@ dependencies = [
"ulid-transform==2.2.9",
"urllib3>=2.0",
"uv==0.11.21",
"voluptuous==0.15.2",
"voluptuous-serialize==2.7.0",
"voluptuous-openapi==0.4.1",
"probatio==0.5.4",
"yarl==1.24.2",
"webrtc-models==0.3.0",
"zeroconf==0.150.0",
@@ -785,7 +783,6 @@ ignore = [
]
[tool.ruff.lint.flake8-import-conventions.extend-aliases]
voluptuous = "vol"
"homeassistant.components.air_quality.PLATFORM_SCHEMA" = "AIR_QUALITY_PLATFORM_SCHEMA"
"homeassistant.components.alarm_control_panel.PLATFORM_SCHEMA" = "ALARM_CONTROL_PANEL_PLATFORM_SCHEMA"
"homeassistant.components.binary_sensor.PLATFORM_SCHEMA" = "BINARY_SENSOR_PLATFORM_SCHEMA"
+1 -3
View File
@@ -37,6 +37,7 @@ mutagen==1.47.0
orjson==3.11.9
packaging>=23.1
Pillow==12.2.0
probatio==0.5.4
propcache==0.5.2
psutil-home-assistant==0.0.1
PyJWT==2.12.1
@@ -56,9 +57,6 @@ typing-extensions>=4.15.0,<5.0
ulid-transform==2.2.9
urllib3>=2.0
uv==0.11.21
voluptuous-openapi==0.4.1
voluptuous-serialize==2.7.0
voluptuous==0.15.2
webrtc-models==0.3.0
yarl==1.24.2
zeroconf==0.150.0
+12
View File
@@ -1 +1,13 @@
"""Home Assistant scripts."""
import contextlib
# Scripts such as hassfest (and the libraries they import) use voluptuous. Alias it
# to probatio before anything imports it, the same as homeassistant/__init__.py does
# for the application itself. This must run before the first `import voluptuous`.
# Some scripts (for example check_requirements) run before dependencies are
# installed, so probatio may be absent; those scripts do not need the alias.
with contextlib.suppress(ImportError):
from probatio.compat import install_as_voluptuous
install_as_voluptuous()
+3
View File
@@ -31,6 +31,9 @@ HEADER: Final = """
GENERAL_SETTINGS: Final[dict[str, str]] = {
"python_version": ".".join(str(x) for x in REQUIRED_PYTHON_VER[:2]),
"platform": "linux",
# voluptuous is aliased to probatio at runtime; this stub path re-exports
# probatio's types under the voluptuous name for not-yet-migrated integrations.
"mypy_path": "stubs",
"plugins": ", ".join( # noqa: FLY002
[
"pydantic.mypy",
+1
View File
@@ -0,0 +1 @@
from probatio import * # noqa: F403
+2
View File
@@ -0,0 +1,2 @@
# See voluptuous/__init__.pyi. Re-exports probatio.error under the voluptuous name.
from probatio.error import * # noqa: F403
+5
View File
@@ -0,0 +1,5 @@
# See voluptuous/__init__.pyi. Re-exports probatio.humanize under the voluptuous name.
from probatio.humanize import (
MAX_VALIDATION_ERROR_ITEM_LENGTH as MAX_VALIDATION_ERROR_ITEM_LENGTH,
humanize_error as humanize_error,
)
+2 -2
View File
@@ -3,7 +3,7 @@
import asyncio
from unittest.mock import patch
import voluptuous_serialize
from probatio import serialize
from homeassistant import data_entry_flow
from homeassistant.auth import auth_manager_from_config, models as auth_models
@@ -251,7 +251,7 @@ async def test_setup_user_notify_service(hass: HomeAssistant) -> None:
schema = step["data_schema"]
schema({"notify_service": "test2"})
# ensure the schema can be serialized
assert voluptuous_serialize.convert(schema) == [
assert serialize(schema) == [
{
"name": "notify_service",
"options": [
+2 -2
View File
@@ -221,7 +221,7 @@ async def test_generate_data_service_structure_fields(
},
},
vol.Invalid,
r"extra keys not allowed.*",
r"not a valid option.*",
),
(
{
@@ -248,7 +248,7 @@ async def test_generate_data_service_structure_fields(
},
},
vol.Invalid,
r"extra keys not allowed .*",
r"not a valid option .*",
),
(
{
+4 -10
View File
@@ -1,8 +1,8 @@
"""The tests for Climate device actions."""
from probatio import serialize
import pytest
from pytest_unordered import unordered
import voluptuous_serialize
from homeassistant.components import automation
from homeassistant.components.climate import DOMAIN, HVACMode, const, device_action
@@ -398,9 +398,7 @@ async def test_capabilities(
assert capabilities and "extra_fields" in capabilities
assert (
voluptuous_serialize.convert(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
)
serialize(capabilities["extra_fields"], custom_serializer=cv.custom_serializer)
== expected_capabilities
)
@@ -516,9 +514,7 @@ async def test_capabilities_legacy(
assert capabilities and "extra_fields" in capabilities
assert (
voluptuous_serialize.convert(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
)
serialize(capabilities["extra_fields"], custom_serializer=cv.custom_serializer)
== expected_capabilities
)
@@ -556,8 +552,6 @@ async def test_capabilities_missing_entity(
assert capabilities and "extra_fields" in capabilities
assert (
voluptuous_serialize.convert(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
)
serialize(capabilities["extra_fields"], custom_serializer=cv.custom_serializer)
== expected_capabilities
)
@@ -1,8 +1,8 @@
"""The tests for Climate device conditions."""
from probatio import serialize
import pytest
from pytest_unordered import unordered
import voluptuous_serialize
from homeassistant.components import automation
from homeassistant.components.climate import DOMAIN, HVACMode, const, device_condition
@@ -424,9 +424,7 @@ async def test_capabilities(
assert capabilities and "extra_fields" in capabilities
assert (
voluptuous_serialize.convert(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
)
serialize(capabilities["extra_fields"], custom_serializer=cv.custom_serializer)
== expected_capabilities
)
@@ -543,9 +541,7 @@ async def test_capabilities_legacy(
assert capabilities and "extra_fields" in capabilities
assert (
voluptuous_serialize.convert(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
)
serialize(capabilities["extra_fields"], custom_serializer=cv.custom_serializer)
== expected_capabilities
)
@@ -584,8 +580,6 @@ async def test_capabilities_missing_entity(
assert capabilities and "extra_fields" in capabilities
assert (
voluptuous_serialize.convert(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
)
serialize(capabilities["extra_fields"], custom_serializer=cv.custom_serializer)
== expected_capabilities
)
@@ -1,8 +1,8 @@
"""The tests for Climate device triggers."""
from probatio import serialize
import pytest
from pytest_unordered import unordered
import voluptuous_serialize
from homeassistant.components import automation
from homeassistant.components.climate import (
@@ -332,7 +332,7 @@ async def test_get_trigger_capabilities_hvac_mode(hass: HomeAssistant) -> None:
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -382,7 +382,7 @@ async def test_get_trigger_capabilities_temp_humid(
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -3335,8 +3335,8 @@ async def test_flow_with_multiple_schema_errors_base(
assert data == {
"errors": {
"base": [
"extra keys not allowed @ data['invalid']",
"extra keys not allowed @ data['invalid_2']",
"not a valid option @ data['invalid']",
"not a valid option @ data['invalid_2']",
],
"latitude": "required key not provided",
}
@@ -1,8 +1,8 @@
"""The tests for Device Tracker device triggers."""
from probatio import serialize
import pytest
from pytest_unordered import unordered
import voluptuous_serialize
from homeassistant.components import automation, zone
from homeassistant.components.device_automation import DeviceAutomationType
@@ -327,7 +327,7 @@ async def test_get_trigger_capabilities(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -366,7 +366,7 @@ async def test_get_trigger_capabilities_legacy(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
+5 -5
View File
@@ -279,7 +279,7 @@ async def test_service_schema_validation(
) -> None:
"""Test easyEnergy service schema validation."""
with pytest.raises(vol.er.Error, match=error_message):
with pytest.raises(vol.error.Error, match=error_message):
await hass.services.async_call(
DOMAIN,
service,
@@ -307,7 +307,7 @@ async def test_service_schema_validation_vat(
) -> None:
"""Test easyEnergy service schema validation for VAT."""
with pytest.raises(vol.er.Error, match=error_message):
with pytest.raises(vol.error.Error, match=error_message):
await hass.services.async_call(
DOMAIN,
service,
@@ -341,7 +341,7 @@ async def test_service_schema_validation_usage_price_type(
) -> None:
"""Test usage service schema validation for price type."""
with pytest.raises(vol.er.Error, match=error_message):
with pytest.raises(vol.error.Error, match=error_message):
await hass.services.async_call(
DOMAIN,
service,
@@ -384,7 +384,7 @@ async def test_service_schema_validation_granularity(
if service == ENERGY_USAGE_SERVICE_NAME:
data["incl_vat"] = True
with pytest.raises(vol.er.Error, match=error_message):
with pytest.raises(vol.error.Error, match=error_message):
await hass.services.async_call(
DOMAIN,
service,
@@ -401,7 +401,7 @@ async def test_service_schema_validation_return_vat(
) -> None:
"""Test return prices do not accept VAT selection."""
with pytest.raises(vol.er.Error, match="extra keys not allowed .+"):
with pytest.raises(vol.error.Error, match="not a valid option .+"):
await hass.services.async_call(
DOMAIN,
ENERGY_RETURN_SERVICE_NAME,
+4 -4
View File
@@ -71,23 +71,23 @@ def config_entry_data(
@pytest.mark.parametrize(
("config_entry_data", "service_data", "error", "error_message"),
[
({}, {}, vol.er.Error, "required key not provided .+"),
({}, {}, vol.error.Error, "required key not provided .+"),
(
{"config_entry": True},
{},
vol.er.Error,
vol.error.Error,
"required key not provided .+",
),
(
{},
{"incl_vat": True},
vol.er.Error,
vol.error.Error,
"required key not provided .+",
),
(
{"config_entry": True},
{"incl_vat": "incorrect vat"},
vol.er.Error,
vol.error.Error,
"expected bool for dictionary value .+",
),
(
+1 -1
View File
@@ -547,7 +547,7 @@ async def test_themes_reload_themes(
"modes": {"light": {}, "dank": {}},
}
},
"extra keys not allowed.*dank",
"not a valid option.*dank",
None,
),
],
@@ -1,8 +1,8 @@
"""The tests for Humidifier device actions."""
from probatio import serialize
import pytest
from pytest_unordered import unordered
import voluptuous_serialize
from homeassistant.components import automation
from homeassistant.components.device_automation import DeviceAutomationType
@@ -489,9 +489,7 @@ async def test_capabilities(
assert capabilities and "extra_fields" in capabilities
assert (
voluptuous_serialize.convert(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
)
serialize(capabilities["extra_fields"], custom_serializer=cv.custom_serializer)
== expected_capabilities
)
@@ -633,9 +631,7 @@ async def test_capabilities_legacy(
assert capabilities and "extra_fields" in capabilities
assert (
voluptuous_serialize.convert(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
)
serialize(capabilities["extra_fields"], custom_serializer=cv.custom_serializer)
== expected_capabilities
)
@@ -674,8 +670,6 @@ async def test_capabilities_missing_entity(
assert capabilities and "extra_fields" in capabilities
assert (
voluptuous_serialize.convert(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
)
serialize(capabilities["extra_fields"], custom_serializer=cv.custom_serializer)
== expected_capabilities
)
@@ -1,8 +1,8 @@
"""The tests for Humidifier device conditions."""
from probatio import serialize
import pytest
from pytest_unordered import unordered
import voluptuous_serialize
from homeassistant.components import automation
from homeassistant.components.device_automation import DeviceAutomationType
@@ -485,9 +485,7 @@ async def test_capabilities(
assert capabilities and "extra_fields" in capabilities
assert (
voluptuous_serialize.convert(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
)
serialize(capabilities["extra_fields"], custom_serializer=cv.custom_serializer)
== expected_capabilities
)
@@ -659,9 +657,7 @@ async def test_capabilities_legacy(
assert capabilities and "extra_fields" in capabilities
assert (
voluptuous_serialize.convert(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
)
serialize(capabilities["extra_fields"], custom_serializer=cv.custom_serializer)
== expected_capabilities
)
@@ -700,8 +696,6 @@ async def test_capabilities_missing_entity(
assert capabilities and "extra_fields" in capabilities
assert (
voluptuous_serialize.convert(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
)
serialize(capabilities["extra_fields"], custom_serializer=cv.custom_serializer)
== expected_capabilities
)
@@ -2,9 +2,9 @@
import datetime
from probatio import serialize
import pytest
from pytest_unordered import unordered
import voluptuous_serialize
from homeassistant.components import automation
from homeassistant.components.device_automation import DeviceAutomationType
@@ -536,7 +536,7 @@ async def test_get_trigger_capabilities_on(hass: HomeAssistant) -> None:
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -563,7 +563,7 @@ async def test_get_trigger_capabilities_off(hass: HomeAssistant) -> None:
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -590,7 +590,7 @@ async def test_get_trigger_capabilities_humidity(hass: HomeAssistant) -> None:
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
+1 -1
View File
@@ -4,8 +4,8 @@ from collections.abc import Callable
from typing import Any
from unittest.mock import AsyncMock, patch
from probatio import serialize as convert
import pytest
from voluptuous_serialize import convert
from homeassistant import config_entries
from homeassistant.components.insteon.config_flow import (
@@ -30,7 +30,7 @@
'current_address': '0.0.0',
'version': '0.0.0',
}),
'yaml_configuration_error': "extra keys not allowed @ data['knx']['wrong_key']",
'yaml_configuration_error': "not a valid option @ data['knx']['wrong_key']",
})
# ---
# name: test_diagnostic_redact[hass_config0]
+1 -1
View File
@@ -442,7 +442,7 @@ async def test_validate_entity(
assert res["success"], res
assert res["result"]["success"] is False
# This shall test that a required key of the second GroupSelect schema is missing
# and not yield the "extra keys not allowed" error of the first GroupSelect Schema
# and not yield the "not a valid option" error of the first GroupSelect Schema
assert res["result"]["errors"][0]["path"] == [
"data",
"knx",
+3 -3
View File
@@ -2,8 +2,8 @@
import logging
from probatio import serialize
import pytest
import voluptuous_serialize
from homeassistant.components import automation
from homeassistant.components.device_automation import (
@@ -298,7 +298,7 @@ async def test_get_trigger_capabilities(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -402,7 +402,7 @@ async def test_invalid_device_trigger(
)
assert (
"Unnamed automation failed to setup triggers and has been disabled: "
"extra keys not allowed @ data['invalid']. Got None"
"not a valid option @ data['invalid']. Got None"
in caplog.records[0].message
)
+1 -1
View File
@@ -2,9 +2,9 @@
from typing import Any
from probatio import serialize as convert
import pytest
import voluptuous as vol
from voluptuous_serialize import convert
from homeassistant.components.knx.const import ColorTempModes
from homeassistant.components.knx.storage.knx_selector import (
+1 -1
View File
@@ -338,6 +338,6 @@ async def test_invalid_trigger(
)
assert (
"Unnamed automation failed to setup triggers and has been disabled: "
"extra keys not allowed @ data['invalid']. Got None"
"not a valid option @ data['invalid']. Got None"
in caplog.records[0].message
)
+5 -5
View File
@@ -1,10 +1,10 @@
"""Tests for LCN device triggers."""
from probatio import serialize
from pypck.inputs import ModSendKeysHost, ModStatusAccessControl
from pypck.lcn_addr import LcnAddr
from pypck.lcn_defs import AccessControlPeriphery, KeyAction, SendKeyCommand
from pytest_unordered import unordered
import voluptuous_serialize
from homeassistant.components import automation
from homeassistant.components.device_automation import DeviceAutomationType
@@ -347,7 +347,7 @@ async def test_get_transponder_trigger_capabilities(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -379,7 +379,7 @@ async def test_get_fingerprint_trigger_capabilities(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -411,7 +411,7 @@ async def test_get_transmitter_trigger_capabilities(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -464,7 +464,7 @@ async def test_get_send_keys_trigger_capabilities(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -1379,7 +1379,8 @@ async def test_reload_after_invalid_config(
assert await mqtt_mock_entry()
assert hass.states.get("alarm_control_panel.test") is None
assert (
"extra keys not allowed @ data['invalid_topic'] for "
"not a valid option, did you mean 'availability_topic' or "
"'command_topic'? @ data['invalid_topic'] for "
"manually configured MQTT alarm_control_panel item, "
"in ?, line ? Got {'name': 'test', 'invalid_topic': 'test-topic'}"
in caplog.text
+1 -1
View File
@@ -906,7 +906,7 @@ async def test_setup_manual_mqtt_with_platform_key(
"""Test set up a manual MQTT item with a platform key."""
assert await mqtt_mock_entry()
assert (
"extra keys not allowed @ data['platform']"
"not a valid option @ data['platform']"
" for manually configured MQTT light item" in caplog.text
)
+1 -1
View File
@@ -879,7 +879,7 @@ async def test_update_with_bad_config_not_breaks_discovery(
# Update with bad identifier
async_fire_mqtt_message(hass, "homeassistant/tag/bla1/config", data2)
await hass.async_block_till_done()
assert "extra keys not allowed @ data['device']['bad_key']" in caplog.text
assert "not a valid option @ data['device']['bad_key']" in caplog.text
# Topic update
async_fire_mqtt_message(hass, "homeassistant/tag/bla1/config", data3)
@@ -1,8 +1,8 @@
"""The tests for Number device actions."""
from probatio import serialize
import pytest
from pytest_unordered import unordered
import voluptuous_serialize
from homeassistant.components import automation
from homeassistant.components.device_automation import DeviceAutomationType
@@ -264,7 +264,7 @@ async def test_capabilities(
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [{"name": "value", "required": True, "type": "float"}]
@@ -296,6 +296,6 @@ async def test_capabilities_legacy(
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [{"name": "value", "required": True, "type": "float"}]
@@ -1,8 +1,8 @@
"""The tests for Select device actions."""
from probatio import serialize
import pytest
from pytest_unordered import unordered
import voluptuous_serialize
from homeassistant.components import automation
from homeassistant.components.device_automation import DeviceAutomationType
@@ -329,7 +329,7 @@ async def test_get_action_capabilities(
capabilities = await async_get_action_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -349,7 +349,7 @@ async def test_get_action_capabilities(
capabilities = await async_get_action_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -370,7 +370,7 @@ async def test_get_action_capabilities(
capabilities = await async_get_action_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -386,7 +386,7 @@ async def test_get_action_capabilities(
capabilities = await async_get_action_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -431,7 +431,7 @@ async def test_get_action_capabilities_legacy(
capabilities = await async_get_action_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -451,7 +451,7 @@ async def test_get_action_capabilities_legacy(
capabilities = await async_get_action_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -472,7 +472,7 @@ async def test_get_action_capabilities_legacy(
capabilities = await async_get_action_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -488,7 +488,7 @@ async def test_get_action_capabilities_legacy(
capabilities = await async_get_action_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -1,8 +1,8 @@
"""The tests for Select device conditions."""
from probatio import serialize
import pytest
from pytest_unordered import unordered
import voluptuous_serialize
from homeassistant.components import automation
from homeassistant.components.device_automation import DeviceAutomationType
@@ -271,7 +271,7 @@ async def test_get_condition_capabilities(
capabilities = await async_get_condition_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -297,7 +297,7 @@ async def test_get_condition_capabilities(
capabilities = await async_get_condition_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -333,7 +333,7 @@ async def test_get_condition_capabilities_legacy(
capabilities = await async_get_condition_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -359,7 +359,7 @@ async def test_get_condition_capabilities_legacy(
capabilities = await async_get_condition_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -1,8 +1,8 @@
"""The tests for Select device triggers."""
from probatio import serialize
import pytest
from pytest_unordered import unordered
import voluptuous_serialize
from homeassistant.components import automation
from homeassistant.components.device_automation import DeviceAutomationType
@@ -306,7 +306,7 @@ async def test_get_trigger_capabilities(
capabilities = await async_get_trigger_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -340,7 +340,7 @@ async def test_get_trigger_capabilities(
capabilities = await async_get_trigger_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -382,7 +382,7 @@ async def test_get_trigger_capabilities_unknown(
capabilities = await async_get_trigger_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -426,7 +426,7 @@ async def test_get_trigger_capabilities_legacy(
capabilities = await async_get_trigger_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -460,7 +460,7 @@ async def test_get_trigger_capabilities_legacy(
capabilities = await async_get_trigger_capabilities(hass, config)
assert capabilities
assert "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -140,7 +140,7 @@ def test_send_message_with_bad_data_throws_vol_error(
signal_notification_service.send_message(MESSAGE, data={"test": "test"})
assert "Sending signal message" in caplog.text
assert "extra keys not allowed" in str(exc.value)
assert "not a valid option" in str(exc.value)
def test_send_message_styled_with_bad_data_throws_vol_error(
+3 -3
View File
@@ -1,8 +1,8 @@
"""The tests for Text device actions."""
from probatio import serialize
import pytest
from pytest_unordered import unordered
import voluptuous_serialize
from homeassistant.components import automation
from homeassistant.components.device_automation import DeviceAutomationType
@@ -248,7 +248,7 @@ async def test_capabilities(
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [{"name": "value", "required": True, "type": "string"}]
@@ -270,6 +270,6 @@ async def test_capabilities_legacy(
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [{"name": "value", "required": True, "type": "string"}]
+2 -2
View File
@@ -3,8 +3,8 @@
import logging
from typing import Any
from probatio import serialize
import pytest
import voluptuous_serialize
from zigpy.application import ControllerApplication
from zigpy.types.basic import uint16_t
from zigpy.zcl.clusters import lighting
@@ -81,7 +81,7 @@ async def test_zcl_schema_conversions(hass: HomeAssistant) -> None:
"required": False,
},
]
vol_schema = voluptuous_serialize.convert(
vol_schema = serialize(
cluster_command_schema_to_vol_schema(command_schema),
custom_serializer=cv.custom_serializer,
)
@@ -2,8 +2,8 @@
from unittest.mock import patch
from probatio import serialize
import pytest
import voluptuous_serialize
from zwave_js_server.client import Client
from zwave_js_server.const import CommandClass
from zwave_js_server.model.node import Node
@@ -547,7 +547,7 @@ async def test_get_action_capabilities(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -605,7 +605,7 @@ async def test_get_action_capabilities(
("94", "Z-Wave Plus Info"),
]
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -642,7 +642,7 @@ async def test_get_action_capabilities(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -675,7 +675,7 @@ async def test_get_action_capabilities(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -730,7 +730,7 @@ async def test_get_action_capabilities_lock_triggers(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [{"type": "string", "name": "code_slot", "required": True}]
@@ -747,7 +747,7 @@ async def test_get_action_capabilities_lock_triggers(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{"type": "string", "name": "code_slot", "required": True},
@@ -781,7 +781,7 @@ async def test_get_action_capabilities_meter_triggers(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [{"type": "string", "name": "value", "optional": True, "required": False}]
@@ -2,9 +2,9 @@
from unittest.mock import patch
from probatio import serialize
import pytest
import voluptuous as vol
import voluptuous_serialize
from zwave_js_server.const import CommandClass
from zwave_js_server.event import Event
@@ -446,7 +446,7 @@ async def test_get_condition_capabilities_node_status(
},
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -499,7 +499,7 @@ async def test_get_condition_capabilities_value(
("134", "Version"),
]
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -543,7 +543,7 @@ async def test_get_condition_capabilities_config_parameter(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -574,7 +574,7 @@ async def test_get_condition_capabilities_config_parameter(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -2,9 +2,9 @@
from unittest.mock import patch
from probatio import serialize
import pytest
from pytest_unordered import unordered
import voluptuous_serialize
from zwave_js_server.const import CommandClass
from zwave_js_server.event import Event
from zwave_js_server.model.node import Node
@@ -197,7 +197,7 @@ async def test_get_trigger_capabilities_notification_notification(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == unordered(
[
@@ -337,7 +337,7 @@ async def test_get_trigger_capabilities_entry_control_notification(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == unordered(
[
@@ -589,7 +589,7 @@ async def test_get_trigger_capabilities_node_status(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -797,7 +797,7 @@ async def test_get_trigger_capabilities_basic_value_notification(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -993,7 +993,7 @@ async def test_get_trigger_capabilities_central_scene_value_notification(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -1186,7 +1186,7 @@ async def test_get_trigger_capabilities_scene_activation_value_notification(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -1423,7 +1423,7 @@ async def test_get_trigger_capabilities_value_updated_value(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -1583,7 +1583,7 @@ async def test_get_trigger_capabilities_value_updated_config_parameter_range(
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
@@ -1633,7 +1633,7 @@ async def test_get_trigger_capabilities_value_updated_config_parameter_enumerate
)
assert capabilities and "extra_fields" in capabilities
assert voluptuous_serialize.convert(
assert serialize(
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
) == [
{
+2 -1
View File
@@ -84,7 +84,8 @@ async def test_bad_core_config(hass: HomeAssistant) -> None:
error = CheckConfigError(
(
f"Invalid config for 'homeassistant' at {YAML_CONFIG_FILE}, line 2:"
" not a valid value for dictionary value 'unit_system', got 'bad'"
" expected 'metric' or 'us_customary' or 'imperial' for dictionary"
" value 'unit_system', got 'bad'"
),
"homeassistant",
{"unit_system": "bad"},
+1 -1
View File
@@ -27,7 +27,7 @@ known-first-party = [
known-third-party = [
"syrupy",
"pytest",
"voluptuous",
"probatio",
"pylint",
]
forced-separate = [
+2 -2
View File
@@ -10,6 +10,7 @@ from typing import Any
import attr
import attrs
from probatio import serialize
import pytest
from syrupy.constants import EXIT_STATUS_FAIL_UNUSED
from syrupy.data import Snapshot, SnapshotCollection, SnapshotCollections
@@ -20,7 +21,6 @@ from syrupy.session import ItemStatus, SnapshotSession
from syrupy.types import PropertyFilter, PropertyMatcher, PropertyPath, SerializableData
from syrupy.utils import is_xdist_controller, is_xdist_worker
import voluptuous as vol
import voluptuous_serialize
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import State
@@ -114,7 +114,7 @@ class HomeAssistantSnapshotSerializer(AmberDataSerializer):
}:
serializable_data = cls._serializable_conversation_result(data)
elif isinstance(data, vol.Schema):
serializable_data = voluptuous_serialize.convert(data)
serializable_data = serialize(data)
elif isinstance(data, ConfigEntry):
serializable_data = cls._serializable_config_entry(data)
elif dataclasses.is_dataclass(type(data)):
+3 -1
View File
@@ -212,7 +212,9 @@ def testvalidate_stun_or_turn_url() -> None:
def test_customize_glob_is_ordered() -> None:
"""Test that customize_glob preserves order."""
conf = CORE_CONFIG_SCHEMA({"customize_glob": OrderedDict()})
assert isinstance(conf["customize_glob"], OrderedDict)
# The schema returns a plain dict (insertion-ordered); core_config wraps it in
# an OrderedDict where it is consumed.
assert isinstance(conf["customize_glob"], dict)
async def _compute_state(hass: HomeAssistant, config: dict[str, Any]) -> State | None: