diff --git a/homeassistant/components/alarm_control_panel/__init__.py b/homeassistant/components/alarm_control_panel/__init__.py index f3e02465c13..c307e96e9f0 100644 --- a/homeassistant/components/alarm_control_panel/__init__.py +++ b/homeassistant/components/alarm_control_panel/__init__.py @@ -1,7 +1,6 @@ """Component to interface with an alarm control panel.""" from __future__ import annotations -from dataclasses import dataclass from datetime import timedelta import logging from typing import Any, Final, final @@ -121,8 +120,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class AlarmControlPanelEntityDescription(EntityDescription): +class AlarmControlPanelEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes alarm control panel entities.""" diff --git a/homeassistant/components/binary_sensor/__init__.py b/homeassistant/components/binary_sensor/__init__.py index a84cbc18756..a3303c525cb 100644 --- a/homeassistant/components/binary_sensor/__init__.py +++ b/homeassistant/components/binary_sensor/__init__.py @@ -1,7 +1,6 @@ """Component to interface with binary sensors.""" from __future__ import annotations -from dataclasses import dataclass from datetime import timedelta from enum import StrEnum import logging @@ -176,8 +175,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class BinarySensorEntityDescription(EntityDescription): +class BinarySensorEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes binary sensor entities.""" device_class: BinarySensorDeviceClass | None = None diff --git a/homeassistant/components/bluetooth/passive_update_processor.py b/homeassistant/components/bluetooth/passive_update_processor.py index eeccf081b55..601f78d4c8d 100644 --- a/homeassistant/components/bluetooth/passive_update_processor.py +++ b/homeassistant/components/bluetooth/passive_update_processor.py @@ -93,7 +93,10 @@ def deserialize_entity_description( descriptions_class: type[EntityDescription], data: dict[str, Any] ) -> EntityDescription: """Deserialize an entity description.""" + # pylint: disable=protected-access result: dict[str, Any] = {} + if hasattr(descriptions_class, "_dataclass"): + descriptions_class = descriptions_class._dataclass for field in cached_fields(descriptions_class): field_name = field.name # It would be nice if field.type returned the actual diff --git a/homeassistant/components/button/__init__.py b/homeassistant/components/button/__init__.py index 901acdcdec1..4ebe1df68a2 100644 --- a/homeassistant/components/button/__init__.py +++ b/homeassistant/components/button/__init__.py @@ -1,7 +1,6 @@ """Component to pressing a button as platforms.""" from __future__ import annotations -from dataclasses import dataclass from datetime import datetime, timedelta from enum import StrEnum import logging @@ -73,8 +72,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class ButtonEntityDescription(EntityDescription): +class ButtonEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes button entities.""" device_class: ButtonDeviceClass | None = None diff --git a/homeassistant/components/camera/__init__.py b/homeassistant/components/camera/__init__.py index bb5a44a530c..528c2cef50a 100644 --- a/homeassistant/components/camera/__init__.py +++ b/homeassistant/components/camera/__init__.py @@ -5,7 +5,7 @@ import asyncio import collections from collections.abc import Awaitable, Callable, Iterable from contextlib import suppress -from dataclasses import asdict, dataclass +from dataclasses import asdict from datetime import datetime, timedelta from enum import IntFlag from functools import partial @@ -132,8 +132,7 @@ CAMERA_SERVICE_RECORD: Final = { } -@dataclass -class CameraEntityDescription(EntityDescription): +class CameraEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes camera entities.""" diff --git a/homeassistant/components/climate/__init__.py b/homeassistant/components/climate/__init__.py index a075467a313..3e93bf27ffc 100644 --- a/homeassistant/components/climate/__init__.py +++ b/homeassistant/components/climate/__init__.py @@ -1,7 +1,6 @@ """Provides functionality to interact with climate devices.""" from __future__ import annotations -from dataclasses import dataclass from datetime import timedelta import functools as ft import logging @@ -201,8 +200,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class ClimateEntityDescription(EntityDescription): +class ClimateEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes climate entities.""" diff --git a/homeassistant/components/cover/__init__.py b/homeassistant/components/cover/__init__.py index 354b972e2b7..633300af591 100644 --- a/homeassistant/components/cover/__init__.py +++ b/homeassistant/components/cover/__init__.py @@ -2,7 +2,6 @@ from __future__ import annotations from collections.abc import Callable -from dataclasses import dataclass from datetime import timedelta from enum import IntFlag, StrEnum import functools as ft @@ -212,8 +211,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class CoverEntityDescription(EntityDescription): +class CoverEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes cover entities.""" device_class: CoverDeviceClass | None = None diff --git a/homeassistant/components/date/__init__.py b/homeassistant/components/date/__init__.py index 51f3a492c47..7426293cfb4 100644 --- a/homeassistant/components/date/__init__.py +++ b/homeassistant/components/date/__init__.py @@ -1,7 +1,6 @@ """Component to allow setting date as platforms.""" from __future__ import annotations -from dataclasses import dataclass from datetime import date, timedelta import logging from typing import final @@ -62,8 +61,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class DateEntityDescription(EntityDescription): +class DateEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes date entities.""" diff --git a/homeassistant/components/datetime/__init__.py b/homeassistant/components/datetime/__init__.py index e25f4535d0c..823028ee6a7 100644 --- a/homeassistant/components/datetime/__init__.py +++ b/homeassistant/components/datetime/__init__.py @@ -1,7 +1,6 @@ """Component to allow setting date/time as platforms.""" from __future__ import annotations -from dataclasses import dataclass from datetime import UTC, datetime, timedelta import logging from typing import final @@ -71,8 +70,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class DateTimeEntityDescription(EntityDescription): +class DateTimeEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes date/time entities.""" diff --git a/homeassistant/components/event/__init__.py b/homeassistant/components/event/__init__.py index d9608670972..40e55472d12 100644 --- a/homeassistant/components/event/__init__.py +++ b/homeassistant/components/event/__init__.py @@ -71,8 +71,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class EventEntityDescription(EntityDescription): +class EventEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes event entities.""" device_class: EventDeviceClass | None = None diff --git a/homeassistant/components/fan/__init__.py b/homeassistant/components/fan/__init__.py index 21ffca35962..23261c4d944 100644 --- a/homeassistant/components/fan/__init__.py +++ b/homeassistant/components/fan/__init__.py @@ -1,7 +1,6 @@ """Provides functionality to interact with fans.""" from __future__ import annotations -from dataclasses import dataclass from datetime import timedelta from enum import IntFlag import functools as ft @@ -187,8 +186,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class FanEntityDescription(ToggleEntityDescription): +class FanEntityDescription(ToggleEntityDescription, frozen_or_thawed=True): """A class that describes fan entities.""" diff --git a/homeassistant/components/humidifier/__init__.py b/homeassistant/components/humidifier/__init__.py index 47745c53394..39150126b7a 100644 --- a/homeassistant/components/humidifier/__init__.py +++ b/homeassistant/components/humidifier/__init__.py @@ -1,7 +1,6 @@ """Provides functionality to interact with humidifier devices.""" from __future__ import annotations -from dataclasses import dataclass from datetime import timedelta from enum import StrEnum import logging @@ -124,8 +123,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class HumidifierEntityDescription(ToggleEntityDescription): +class HumidifierEntityDescription(ToggleEntityDescription, frozen_or_thawed=True): """A class that describes humidifier entities.""" device_class: HumidifierDeviceClass | None = None diff --git a/homeassistant/components/image/__init__.py b/homeassistant/components/image/__init__.py index e5c40affe0f..d90295f6279 100644 --- a/homeassistant/components/image/__init__.py +++ b/homeassistant/components/image/__init__.py @@ -44,8 +44,7 @@ _RND: Final = SystemRandom() GET_IMAGE_TIMEOUT: Final = 10 -@dataclass -class ImageEntityDescription(EntityDescription): +class ImageEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes image entities.""" diff --git a/homeassistant/components/image_processing/__init__.py b/homeassistant/components/image_processing/__init__.py index 7640925451a..916812e41c9 100644 --- a/homeassistant/components/image_processing/__init__.py +++ b/homeassistant/components/image_processing/__init__.py @@ -2,7 +2,6 @@ from __future__ import annotations import asyncio -from dataclasses import dataclass from datetime import timedelta from enum import StrEnum import logging @@ -120,8 +119,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: return True -@dataclass -class ImageProcessingEntityDescription(EntityDescription): +class ImageProcessingEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes sensor entities.""" device_class: ImageProcessingDeviceClass | None = None diff --git a/homeassistant/components/lawn_mower/__init__.py b/homeassistant/components/lawn_mower/__init__.py index 5388463316f..b25f9ab34af 100644 --- a/homeassistant/components/lawn_mower/__init__.py +++ b/homeassistant/components/lawn_mower/__init__.py @@ -1,7 +1,6 @@ """The lawn mower integration.""" from __future__ import annotations -from dataclasses import dataclass from datetime import timedelta import logging from typing import final @@ -65,8 +64,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class LawnMowerEntityEntityDescription(EntityDescription): +class LawnMowerEntityEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes lawn mower entities.""" diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index 3bb3797c284..6643884566f 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -816,8 +816,7 @@ class Profiles: params.setdefault(ATTR_TRANSITION, profile.transition) -@dataclasses.dataclass -class LightEntityDescription(ToggleEntityDescription): +class LightEntityDescription(ToggleEntityDescription, frozen_or_thawed=True): """A class that describes binary sensor entities.""" diff --git a/homeassistant/components/lock/__init__.py b/homeassistant/components/lock/__init__.py index ca91236a77c..b28aa9d0a1b 100644 --- a/homeassistant/components/lock/__init__.py +++ b/homeassistant/components/lock/__init__.py @@ -1,7 +1,6 @@ """Component to interface with locks that can be controlled remotely.""" from __future__ import annotations -from dataclasses import dataclass from datetime import timedelta from enum import IntFlag import functools as ft @@ -101,8 +100,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class LockEntityDescription(EntityDescription): +class LockEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes lock entities.""" diff --git a/homeassistant/components/media_player/__init__.py b/homeassistant/components/media_player/__init__.py index 2ca47b97275..a45127d7b86 100644 --- a/homeassistant/components/media_player/__init__.py +++ b/homeassistant/components/media_player/__init__.py @@ -5,7 +5,6 @@ import asyncio import collections from collections.abc import Callable from contextlib import suppress -from dataclasses import dataclass import datetime as dt from enum import StrEnum import functools as ft @@ -449,8 +448,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class MediaPlayerEntityDescription(EntityDescription): +class MediaPlayerEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes media player entities.""" device_class: MediaPlayerDeviceClass | None = None diff --git a/homeassistant/components/number/__init__.py b/homeassistant/components/number/__init__.py index 201fa8fedb6..631fc5fc96c 100644 --- a/homeassistant/components/number/__init__.py +++ b/homeassistant/components/number/__init__.py @@ -120,8 +120,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclasses.dataclass -class NumberEntityDescription(EntityDescription): +class NumberEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes number entities.""" device_class: NumberDeviceClass | None = None diff --git a/homeassistant/components/remote/__init__.py b/homeassistant/components/remote/__init__.py index 17915e1be19..2901c14c455 100644 --- a/homeassistant/components/remote/__init__.py +++ b/homeassistant/components/remote/__init__.py @@ -2,7 +2,6 @@ from __future__ import annotations from collections.abc import Iterable -from dataclasses import dataclass from datetime import timedelta from enum import IntFlag import functools as ft @@ -155,8 +154,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class RemoteEntityDescription(ToggleEntityDescription): +class RemoteEntityDescription(ToggleEntityDescription, frozen_or_thawed=True): """A class that describes remote entities.""" diff --git a/homeassistant/components/select/__init__.py b/homeassistant/components/select/__init__.py index 4997e088a54..9c978555dd5 100644 --- a/homeassistant/components/select/__init__.py +++ b/homeassistant/components/select/__init__.py @@ -1,7 +1,6 @@ """Component to allow selecting an option from a list as platforms.""" from __future__ import annotations -from dataclasses import dataclass from datetime import timedelta import logging from typing import Any, final @@ -118,8 +117,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class SelectEntityDescription(EntityDescription): +class SelectEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes select entities.""" options: list[str] | None = None diff --git a/homeassistant/components/sensor/__init__.py b/homeassistant/components/sensor/__init__.py index 0fa270bb03d..9cdcfade9ec 100644 --- a/homeassistant/components/sensor/__init__.py +++ b/homeassistant/components/sensor/__init__.py @@ -136,8 +136,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class SensorEntityDescription(EntityDescription): +class SensorEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes sensor entities.""" device_class: SensorDeviceClass | None = None diff --git a/homeassistant/components/siren/__init__.py b/homeassistant/components/siren/__init__.py index ac02201b928..d7e8843f54b 100644 --- a/homeassistant/components/siren/__init__.py +++ b/homeassistant/components/siren/__init__.py @@ -1,7 +1,6 @@ """Component to interface with various sirens/chimes.""" from __future__ import annotations -from dataclasses import dataclass from datetime import timedelta import logging from typing import Any, TypedDict, cast, final @@ -149,8 +148,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class SirenEntityDescription(ToggleEntityDescription): +class SirenEntityDescription(ToggleEntityDescription, frozen_or_thawed=True): """A class that describes siren entities.""" available_tones: list[int | str] | dict[int, str] | None = None diff --git a/homeassistant/components/switch/__init__.py b/homeassistant/components/switch/__init__.py index bf3c3424142..bdbb2b7701b 100644 --- a/homeassistant/components/switch/__init__.py +++ b/homeassistant/components/switch/__init__.py @@ -1,7 +1,6 @@ """Component to interface with switches that can be controlled remotely.""" from __future__ import annotations -from dataclasses import dataclass from datetime import timedelta from enum import StrEnum import logging @@ -89,8 +88,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class SwitchEntityDescription(ToggleEntityDescription): +class SwitchEntityDescription(ToggleEntityDescription, frozen_or_thawed=True): """A class that describes switch entities.""" device_class: SwitchDeviceClass | None = None diff --git a/homeassistant/components/text/__init__.py b/homeassistant/components/text/__init__.py index acc5f62a0cc..8e20fdd33af 100644 --- a/homeassistant/components/text/__init__.py +++ b/homeassistant/components/text/__init__.py @@ -98,8 +98,7 @@ class TextMode(StrEnum): TEXT = "text" -@dataclass -class TextEntityDescription(EntityDescription): +class TextEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes text entities.""" native_min: int = 0 diff --git a/homeassistant/components/time/__init__.py b/homeassistant/components/time/__init__.py index 26d40191fb9..2b5721aaf1b 100644 --- a/homeassistant/components/time/__init__.py +++ b/homeassistant/components/time/__init__.py @@ -1,7 +1,6 @@ """Component to allow setting time as platforms.""" from __future__ import annotations -from dataclasses import dataclass from datetime import time, timedelta import logging from typing import final @@ -62,8 +61,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class TimeEntityDescription(EntityDescription): +class TimeEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes time entities.""" diff --git a/homeassistant/components/update/__init__.py b/homeassistant/components/update/__init__.py index c9496ce8f7b..8597647fc18 100644 --- a/homeassistant/components/update/__init__.py +++ b/homeassistant/components/update/__init__.py @@ -1,7 +1,6 @@ """Component to allow for providing device or service updates.""" from __future__ import annotations -from dataclasses import dataclass from datetime import timedelta from enum import StrEnum from functools import lru_cache @@ -175,8 +174,7 @@ async def async_clear_skipped(entity: UpdateEntity, service_call: ServiceCall) - await entity.async_clear_skipped() -@dataclass -class UpdateEntityDescription(EntityDescription): +class UpdateEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes update entities.""" device_class: UpdateDeviceClass | None = None diff --git a/homeassistant/components/vacuum/__init__.py b/homeassistant/components/vacuum/__init__.py index c0680913df6..5ffb3de2a12 100644 --- a/homeassistant/components/vacuum/__init__.py +++ b/homeassistant/components/vacuum/__init__.py @@ -3,7 +3,6 @@ from __future__ import annotations import asyncio from collections.abc import Mapping -from dataclasses import dataclass from datetime import timedelta from enum import IntFlag from functools import partial @@ -367,8 +366,7 @@ class _BaseVacuum(Entity): ) -@dataclass -class VacuumEntityDescription(ToggleEntityDescription): +class VacuumEntityDescription(ToggleEntityDescription, frozen_or_thawed=True): """A class that describes vacuum entities.""" @@ -490,8 +488,7 @@ class VacuumEntity(_BaseVacuum, ToggleEntity): await self.hass.async_add_executor_job(partial(self.start_pause, **kwargs)) -@dataclass -class StateVacuumEntityDescription(EntityDescription): +class StateVacuumEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes vacuum entities.""" diff --git a/homeassistant/components/water_heater/__init__.py b/homeassistant/components/water_heater/__init__.py index 9e796092f6a..6506be10065 100644 --- a/homeassistant/components/water_heater/__init__.py +++ b/homeassistant/components/water_heater/__init__.py @@ -2,7 +2,6 @@ from __future__ import annotations from collections.abc import Mapping -from dataclasses import dataclass from datetime import timedelta from enum import IntFlag import functools as ft @@ -156,8 +155,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class WaterHeaterEntityEntityDescription(EntityDescription): +class WaterHeaterEntityEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes water heater entities.""" diff --git a/homeassistant/components/weather/__init__.py b/homeassistant/components/weather/__init__.py index 3d9eccd9425..899181f2b5f 100644 --- a/homeassistant/components/weather/__init__.py +++ b/homeassistant/components/weather/__init__.py @@ -5,7 +5,6 @@ import abc import asyncio from collections.abc import Callable, Iterable from contextlib import suppress -from dataclasses import dataclass from datetime import timedelta from functools import partial import logging @@ -251,8 +250,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return await component.async_unload_entry(entry) -@dataclass -class WeatherEntityDescription(EntityDescription): +class WeatherEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes weather entities.""" diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index f19edaf28b9..9f5ff3dad52 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -1313,8 +1313,7 @@ class Entity(ABC): ) -@dataclasses.dataclass(slots=True) -class ToggleEntityDescription(EntityDescription): +class ToggleEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes toggle entities."""