diff --git a/homeassistant/components/kostal_plenticore/coordinator.py b/homeassistant/components/kostal_plenticore/coordinator.py index 33adfa103d0..fa6aa92856b 100644 --- a/homeassistant/components/kostal_plenticore/coordinator.py +++ b/homeassistant/components/kostal_plenticore/coordinator.py @@ -6,7 +6,7 @@ from collections import defaultdict from collections.abc import Mapping from datetime import datetime, timedelta import logging -from typing import TypeVar, cast +from typing import cast from aiohttp.client_exceptions import ClientError from pykoplenti import ( @@ -28,7 +28,6 @@ from .const import DOMAIN from .helper import get_hostname_id _LOGGER = logging.getLogger(__name__) -_DataT = TypeVar("_DataT") class Plenticore: @@ -160,7 +159,7 @@ class DataUpdateCoordinatorMixin: return True -class PlenticoreUpdateCoordinator(DataUpdateCoordinator[_DataT]): +class PlenticoreUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT]): """Base implementation of DataUpdateCoordinator for Plenticore data.""" def __init__( @@ -238,7 +237,7 @@ class SettingDataUpdateCoordinator( return await client.get_setting_values(self._fetch) -class PlenticoreSelectUpdateCoordinator(DataUpdateCoordinator[_DataT]): +class PlenticoreSelectUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT]): """Base implementation of DataUpdateCoordinator for Plenticore data.""" def __init__( diff --git a/homeassistant/components/lookin/coordinator.py b/homeassistant/components/lookin/coordinator.py index 925a7416731..d9834bd1d94 100644 --- a/homeassistant/components/lookin/coordinator.py +++ b/homeassistant/components/lookin/coordinator.py @@ -6,7 +6,6 @@ from collections.abc import Awaitable, Callable from datetime import timedelta import logging import time -from typing import TypeVar from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator @@ -14,7 +13,6 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import NEVER_TIME, POLLING_FALLBACK_SECONDS _LOGGER = logging.getLogger(__name__) -_DataT = TypeVar("_DataT") class LookinPushCoordinator: @@ -42,7 +40,7 @@ class LookinPushCoordinator: return is_active -class LookinDataUpdateCoordinator(DataUpdateCoordinator[_DataT]): +class LookinDataUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT]): """DataUpdateCoordinator to gather data for a specific lookin devices.""" def __init__( diff --git a/homeassistant/components/meteo_france/sensor.py b/homeassistant/components/meteo_france/sensor.py index 23ea6bb1500..d8dbdfc4265 100644 --- a/homeassistant/components/meteo_france/sensor.py +++ b/homeassistant/components/meteo_france/sensor.py @@ -3,7 +3,7 @@ from __future__ import annotations from dataclasses import dataclass -from typing import Any, TypeVar +from typing import Any from meteofrance_api.helpers import ( get_warning_text_status_from_indice_color, @@ -49,8 +49,6 @@ from .const import ( MODEL, ) -_DataT = TypeVar("_DataT", bound=Rain | Forecast | CurrentPhenomenons) - @dataclass(frozen=True, kw_only=True) class MeteoFranceSensorEntityDescription(SensorEntityDescription): @@ -226,7 +224,9 @@ async def async_setup_entry( async_add_entities(entities, False) -class MeteoFranceSensor(CoordinatorEntity[DataUpdateCoordinator[_DataT]], SensorEntity): +class MeteoFranceSensor[_DataT: Rain | Forecast | CurrentPhenomenons]( + CoordinatorEntity[DataUpdateCoordinator[_DataT]], SensorEntity +): """Representation of a Meteo-France sensor.""" entity_description: MeteoFranceSensorEntityDescription diff --git a/homeassistant/components/nibe_heatpump/coordinator.py b/homeassistant/components/nibe_heatpump/coordinator.py index fc212faee71..0f1fabe4249 100644 --- a/homeassistant/components/nibe_heatpump/coordinator.py +++ b/homeassistant/components/nibe_heatpump/coordinator.py @@ -7,7 +7,7 @@ from collections import defaultdict from collections.abc import Callable, Iterable from datetime import date, timedelta from functools import cached_property -from typing import Any, Generic, TypeVar +from typing import Any from nibe.coil import Coil, CoilData from nibe.connection import Connection @@ -26,13 +26,8 @@ from homeassistant.helpers.update_coordinator import ( from .const import DOMAIN, LOGGER -_DataTypeT = TypeVar("_DataTypeT") -_ContextTypeT = TypeVar("_ContextTypeT") - -class ContextCoordinator( - Generic[_DataTypeT, _ContextTypeT], DataUpdateCoordinator[_DataTypeT] -): +class ContextCoordinator[_DataTypeT, _ContextTypeT](DataUpdateCoordinator[_DataTypeT]): """Update coordinator with context adjustments.""" @cached_property diff --git a/homeassistant/components/nuki/__init__.py b/homeassistant/components/nuki/__init__.py index cbd7af3ecec..6577921753f 100644 --- a/homeassistant/components/nuki/__init__.py +++ b/homeassistant/components/nuki/__init__.py @@ -8,7 +8,6 @@ from dataclasses import dataclass from datetime import timedelta from http import HTTPStatus import logging -from typing import Generic, TypeVar from aiohttp import web from pynuki import NukiBridge, NukiLock, NukiOpener @@ -43,8 +42,6 @@ from homeassistant.helpers.update_coordinator import ( from .const import CONF_ENCRYPT_TOKEN, DEFAULT_TIMEOUT, DOMAIN, ERROR_STATES from .helpers import NukiWebhookException, parse_id -_NukiDeviceT = TypeVar("_NukiDeviceT", bound=NukiDevice) - _LOGGER = logging.getLogger(__name__) PLATFORMS = [Platform.BINARY_SENSOR, Platform.LOCK, Platform.SENSOR] @@ -360,7 +357,7 @@ class NukiCoordinator(DataUpdateCoordinator[None]): # pylint: disable=hass-enfo return events -class NukiEntity(CoordinatorEntity[NukiCoordinator], Generic[_NukiDeviceT]): +class NukiEntity[_NukiDeviceT: NukiDevice](CoordinatorEntity[NukiCoordinator]): """An entity using CoordinatorEntity. The CoordinatorEntity class provides: diff --git a/homeassistant/components/nuki/lock.py b/homeassistant/components/nuki/lock.py index d63bfaf6757..5a8734d5df7 100644 --- a/homeassistant/components/nuki/lock.py +++ b/homeassistant/components/nuki/lock.py @@ -3,7 +3,7 @@ from __future__ import annotations from abc import abstractmethod -from typing import Any, TypeVar +from typing import Any from pynuki import NukiLock, NukiOpener from pynuki.constants import MODE_OPENER_CONTINUOUS @@ -28,8 +28,6 @@ from .const import ( ) from .helpers import CannotConnect -_NukiDeviceT = TypeVar("_NukiDeviceT", bound=NukiDevice) - async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback @@ -64,7 +62,7 @@ async def async_setup_entry( ) -class NukiDeviceEntity(NukiEntity[_NukiDeviceT], LockEntity): +class NukiDeviceEntity[_NukiDeviceT: NukiDevice](NukiEntity[_NukiDeviceT], LockEntity): """Representation of a Nuki device.""" _attr_has_entity_name = True diff --git a/homeassistant/components/osoenergy/__init__.py b/homeassistant/components/osoenergy/__init__.py index 20ff22cea23..cbfffeefcd8 100644 --- a/homeassistant/components/osoenergy/__init__.py +++ b/homeassistant/components/osoenergy/__init__.py @@ -1,6 +1,6 @@ """Support for the OSO Energy devices and services.""" -from typing import Any, Generic, TypeVar +from typing import Any from aiohttp.web_exceptions import HTTPException from apyosoenergyapi import OSOEnergy @@ -21,13 +21,6 @@ from homeassistant.helpers.entity import Entity from .const import DOMAIN -_OSOEnergyT = TypeVar( - "_OSOEnergyT", - OSOEnergyBinarySensorData, - OSOEnergySensorData, - OSOEnergyWaterHeaterData, -) - MANUFACTURER = "OSO Energy" PLATFORMS = [ Platform.SENSOR, @@ -77,7 +70,13 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return unload_ok -class OSOEnergyEntity(Entity, Generic[_OSOEnergyT]): +class OSOEnergyEntity[ + _OSOEnergyT: ( + OSOEnergyBinarySensorData, + OSOEnergySensorData, + OSOEnergyWaterHeaterData, + ) +](Entity): """Initiate OSO Energy Base Class.""" _attr_has_entity_name = True diff --git a/homeassistant/components/recorder/table_managers/__init__.py b/homeassistant/components/recorder/table_managers/__init__.py index c064987ddcb..c6dcc1cffad 100644 --- a/homeassistant/components/recorder/table_managers/__init__.py +++ b/homeassistant/components/recorder/table_managers/__init__.py @@ -1,6 +1,6 @@ """Managers for each table.""" -from typing import TYPE_CHECKING, Any, Generic, TypeVar +from typing import TYPE_CHECKING, Any from lru import LRU @@ -9,10 +9,8 @@ from homeassistant.util.event_type import EventType if TYPE_CHECKING: from ..core import Recorder -_DataT = TypeVar("_DataT") - -class BaseTableManager(Generic[_DataT]): +class BaseTableManager[_DataT]: """Base class for table managers.""" _id_map: "LRU[EventType[Any] | str, int]" @@ -54,7 +52,7 @@ class BaseTableManager(Generic[_DataT]): self._pending.clear() -class BaseLRUTableManager(BaseTableManager[_DataT]): +class BaseLRUTableManager[_DataT](BaseTableManager[_DataT]): """Base class for LRU table managers.""" def __init__(self, recorder: "Recorder", lru_size: int) -> None: diff --git a/homeassistant/components/reolink/entity.py b/homeassistant/components/reolink/entity.py index e02fd931f66..29c1e95be81 100644 --- a/homeassistant/components/reolink/entity.py +++ b/homeassistant/components/reolink/entity.py @@ -4,7 +4,6 @@ from __future__ import annotations from collections.abc import Callable from dataclasses import dataclass -from typing import TypeVar from reolink_aio.api import DUAL_LENS_MODELS, Host @@ -18,8 +17,6 @@ from homeassistant.helpers.update_coordinator import ( from . import ReolinkData from .const import DOMAIN -_T = TypeVar("_T") - @dataclass(frozen=True, kw_only=True) class ReolinkChannelEntityDescription(EntityDescription): @@ -37,7 +34,9 @@ class ReolinkHostEntityDescription(EntityDescription): supported: Callable[[Host], bool] = lambda api: True -class ReolinkBaseCoordinatorEntity(CoordinatorEntity[DataUpdateCoordinator[_T]]): +class ReolinkBaseCoordinatorEntity[_DataT]( + CoordinatorEntity[DataUpdateCoordinator[_DataT]] +): """Parent class for Reolink entities.""" _attr_has_entity_name = True @@ -45,7 +44,7 @@ class ReolinkBaseCoordinatorEntity(CoordinatorEntity[DataUpdateCoordinator[_T]]) def __init__( self, reolink_data: ReolinkData, - coordinator: DataUpdateCoordinator[_T], + coordinator: DataUpdateCoordinator[_DataT], ) -> None: """Initialize ReolinkBaseCoordinatorEntity.""" super().__init__(coordinator) diff --git a/homeassistant/components/samsungtv/bridge.py b/homeassistant/components/samsungtv/bridge.py index 817437ef4d6..56ed2a35b49 100644 --- a/homeassistant/components/samsungtv/bridge.py +++ b/homeassistant/components/samsungtv/bridge.py @@ -8,7 +8,7 @@ from asyncio.exceptions import TimeoutError as AsyncioTimeoutError from collections.abc import Callable, Iterable, Mapping import contextlib from datetime import datetime, timedelta -from typing import Any, Generic, TypeVar, cast +from typing import Any, cast from samsungctl import Remote from samsungctl.exceptions import AccessDenied, ConnectionClosed, UnhandledResponse @@ -85,9 +85,6 @@ ENCRYPTED_MODEL_USES_POWER = {"JU6400", "JU641D"} REST_EXCEPTIONS = (HttpApiError, AsyncioTimeoutError, ResponseError) -_RemoteT = TypeVar("_RemoteT", SamsungTVWSAsyncRemote, SamsungTVEncryptedWSAsyncRemote) -_CommandT = TypeVar("_CommandT", SamsungTVCommand, SamsungTVEncryptedCommand) - def mac_from_device_info(info: dict[str, Any]) -> str | None: """Extract the mac address from the device info.""" @@ -393,7 +390,10 @@ class SamsungTVLegacyBridge(SamsungTVBridge): LOGGER.debug("Could not establish connection") -class SamsungTVWSBaseBridge(SamsungTVBridge, Generic[_RemoteT, _CommandT]): +class SamsungTVWSBaseBridge[ + _RemoteT: (SamsungTVWSAsyncRemote, SamsungTVEncryptedWSAsyncRemote), + _CommandT: (SamsungTVCommand, SamsungTVEncryptedCommand), +](SamsungTVBridge): """The Bridge for WebSocket TVs (v1/v2).""" def __init__( diff --git a/homeassistant/components/sfr_box/binary_sensor.py b/homeassistant/components/sfr_box/binary_sensor.py index 7ddcb16c9f8..b299af33513 100644 --- a/homeassistant/components/sfr_box/binary_sensor.py +++ b/homeassistant/components/sfr_box/binary_sensor.py @@ -4,7 +4,6 @@ from __future__ import annotations from collections.abc import Callable from dataclasses import dataclass -from typing import Generic, TypeVar from sfrbox_api.models import DslInfo, FtthInfo, SystemInfo, WanInfo @@ -24,11 +23,9 @@ from .const import DOMAIN from .coordinator import SFRDataUpdateCoordinator from .models import DomainData -_T = TypeVar("_T") - @dataclass(frozen=True, kw_only=True) -class SFRBoxBinarySensorEntityDescription(BinarySensorEntityDescription, Generic[_T]): +class SFRBoxBinarySensorEntityDescription[_T](BinarySensorEntityDescription): """Description for SFR Box binary sensors.""" value_fn: Callable[[_T], bool | None] @@ -87,7 +84,7 @@ async def async_setup_entry( async_add_entities(entities) -class SFRBoxBinarySensor( +class SFRBoxBinarySensor[_T]( CoordinatorEntity[SFRDataUpdateCoordinator[_T]], BinarySensorEntity ): """SFR Box sensor.""" diff --git a/homeassistant/components/sfr_box/coordinator.py b/homeassistant/components/sfr_box/coordinator.py index 08698edd74a..af3195723f4 100644 --- a/homeassistant/components/sfr_box/coordinator.py +++ b/homeassistant/components/sfr_box/coordinator.py @@ -3,7 +3,7 @@ from collections.abc import Callable, Coroutine from datetime import timedelta import logging -from typing import Any, TypeVar +from typing import Any from sfrbox_api.bridge import SFRBox from sfrbox_api.exceptions import SFRBoxError @@ -14,10 +14,8 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda _LOGGER = logging.getLogger(__name__) _SCAN_INTERVAL = timedelta(minutes=1) -_T = TypeVar("_T") - -class SFRDataUpdateCoordinator(DataUpdateCoordinator[_T]): +class SFRDataUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT]): """Coordinator to manage data updates.""" def __init__( @@ -25,14 +23,14 @@ class SFRDataUpdateCoordinator(DataUpdateCoordinator[_T]): hass: HomeAssistant, box: SFRBox, name: str, - method: Callable[[SFRBox], Coroutine[Any, Any, _T]], + method: Callable[[SFRBox], Coroutine[Any, Any, _DataT]], ) -> None: """Initialize coordinator.""" self.box = box self._method = method super().__init__(hass, _LOGGER, name=name, update_interval=_SCAN_INTERVAL) - async def _async_update_data(self) -> _T: + async def _async_update_data(self) -> _DataT: """Update data.""" try: return await self._method(self.box) diff --git a/homeassistant/components/sfr_box/sensor.py b/homeassistant/components/sfr_box/sensor.py index 403ec762768..d19ff82b393 100644 --- a/homeassistant/components/sfr_box/sensor.py +++ b/homeassistant/components/sfr_box/sensor.py @@ -2,7 +2,6 @@ from collections.abc import Callable from dataclasses import dataclass -from typing import Generic, TypeVar from sfrbox_api.models import DslInfo, SystemInfo, WanInfo @@ -30,11 +29,9 @@ from .const import DOMAIN from .coordinator import SFRDataUpdateCoordinator from .models import DomainData -_T = TypeVar("_T") - @dataclass(frozen=True, kw_only=True) -class SFRBoxSensorEntityDescription(SensorEntityDescription, Generic[_T]): +class SFRBoxSensorEntityDescription[_T](SensorEntityDescription): """Description for SFR Box sensors.""" value_fn: Callable[[_T], StateType] @@ -229,7 +226,7 @@ async def async_setup_entry( async_add_entities(entities) -class SFRBoxSensor(CoordinatorEntity[SFRDataUpdateCoordinator[_T]], SensorEntity): +class SFRBoxSensor[_T](CoordinatorEntity[SFRDataUpdateCoordinator[_T]], SensorEntity): """SFR Box sensor.""" entity_description: SFRBoxSensorEntityDescription[_T] diff --git a/homeassistant/components/shelly/button.py b/homeassistant/components/shelly/button.py index 8c1b1c4ef43..f1e2f8ef885 100644 --- a/homeassistant/components/shelly/button.py +++ b/homeassistant/components/shelly/button.py @@ -5,7 +5,7 @@ from __future__ import annotations from collections.abc import Callable, Coroutine from dataclasses import dataclass from functools import partial -from typing import TYPE_CHECKING, Any, Final, Generic, TypeVar +from typing import TYPE_CHECKING, Any, Final from aioshelly.const import RPC_GENERATIONS @@ -26,13 +26,11 @@ from .const import LOGGER, SHELLY_GAS_MODELS from .coordinator import ShellyBlockCoordinator, ShellyConfigEntry, ShellyRpcCoordinator from .utils import get_device_entry_gen -_ShellyCoordinatorT = TypeVar( - "_ShellyCoordinatorT", bound=ShellyBlockCoordinator | ShellyRpcCoordinator -) - @dataclass(frozen=True, kw_only=True) -class ShellyButtonDescription(ButtonEntityDescription, Generic[_ShellyCoordinatorT]): +class ShellyButtonDescription[ + _ShellyCoordinatorT: ShellyBlockCoordinator | ShellyRpcCoordinator +](ButtonEntityDescription): """Class to describe a Button entity.""" press_action: Callable[[_ShellyCoordinatorT], Coroutine[Any, Any, None]] diff --git a/homeassistant/components/shelly/coordinator.py b/homeassistant/components/shelly/coordinator.py index 3f5900b61db..d6aa77539f9 100644 --- a/homeassistant/components/shelly/coordinator.py +++ b/homeassistant/components/shelly/coordinator.py @@ -6,7 +6,7 @@ import asyncio from collections.abc import Callable, Coroutine from dataclasses import dataclass from datetime import timedelta -from typing import Any, Generic, TypeVar, cast +from typing import Any, cast from aioshelly.ble import async_ensure_ble_enabled, async_stop_scanner from aioshelly.block_device import BlockDevice, BlockUpdateType @@ -70,8 +70,6 @@ from .utils import ( update_device_fw_info, ) -_DeviceT = TypeVar("_DeviceT", bound="BlockDevice|RpcDevice") - @dataclass class ShellyEntryData: @@ -86,7 +84,9 @@ class ShellyEntryData: type ShellyConfigEntry = ConfigEntry[ShellyEntryData] -class ShellyCoordinatorBase(DataUpdateCoordinator[None], Generic[_DeviceT]): +class ShellyCoordinatorBase[_DeviceT: BlockDevice | RpcDevice]( + DataUpdateCoordinator[None] +): """Coordinator for a Shelly device.""" def __init__(