Make Event data generic (#111955)

This commit is contained in:
Marc Mueller 2024-03-08 13:46:16 +01:00 committed by GitHub
parent f8b05a0a81
commit d7e7dc96cc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 15 additions and 28 deletions

View File

@ -359,7 +359,7 @@ async def _async_events_consumer(
def _async_subscribe_events( def _async_subscribe_events(
hass: HomeAssistant, hass: HomeAssistant,
subscriptions: list[CALLBACK_TYPE], subscriptions: list[CALLBACK_TYPE],
target: Callable[[Event], None], target: Callable[[Event[Any]], None],
entity_ids: list[str], entity_ids: list[str],
significant_changes_only: bool, significant_changes_only: bool,
minimal_response: bool, minimal_response: bool,

View File

@ -161,7 +161,7 @@ def event_forwarder_filtered(
def async_subscribe_events( def async_subscribe_events(
hass: HomeAssistant, hass: HomeAssistant,
subscriptions: list[CALLBACK_TYPE], subscriptions: list[CALLBACK_TYPE],
target: Callable[[Event], None], target: Callable[[Event[Any]], None],
event_types: tuple[str, ...], event_types: tuple[str, ...],
entities_filter: Callable[[str], bool] | None, entities_filter: Callable[[str], bool] | None,
entity_ids: list[str] | None, entity_ids: list[str] | None,

View File

@ -30,19 +30,10 @@ import re
import threading import threading
import time import time
from time import monotonic from time import monotonic
from typing import ( from typing import TYPE_CHECKING, Any, Generic, Literal, ParamSpec, Self, cast, overload
TYPE_CHECKING,
Any,
Generic,
Literal,
ParamSpec,
Self,
TypeVar,
cast,
overload,
)
from urllib.parse import urlparse from urllib.parse import urlparse
from typing_extensions import TypeVar
import voluptuous as vol import voluptuous as vol
import yarl import yarl
@ -133,6 +124,7 @@ _P = ParamSpec("_P")
# Internal; not helpers.typing.UNDEFINED due to circular dependency # Internal; not helpers.typing.UNDEFINED due to circular dependency
_UNDEF: dict[Any, Any] = {} _UNDEF: dict[Any, Any] = {}
_CallableT = TypeVar("_CallableT", bound=Callable[..., Any]) _CallableT = TypeVar("_CallableT", bound=Callable[..., Any])
_DataT = TypeVar("_DataT", bound=Mapping[str, Any], default=dict[str, Any])
CALLBACK_TYPE = Callable[[], None] CALLBACK_TYPE = Callable[[], None]
CORE_STORAGE_KEY = "core.config" CORE_STORAGE_KEY = "core.config"
@ -1164,7 +1156,7 @@ class Context:
self.id = id or ulid_now() self.id = id or ulid_now()
self.user_id = user_id self.user_id = user_id
self.parent_id = parent_id self.parent_id = parent_id
self.origin_event: Event | None = None self.origin_event: Event[Any] | None = None
def __eq__(self, other: Any) -> bool: def __eq__(self, other: Any) -> bool:
"""Compare contexts.""" """Compare contexts."""
@ -1209,20 +1201,20 @@ class EventOrigin(enum.Enum):
return self.value return self.value
class Event: class Event(Generic[_DataT]):
"""Representation of an event within the bus.""" """Representation of an event within the bus."""
def __init__( def __init__(
self, self,
event_type: str, event_type: str,
data: Mapping[str, Any] | None = None, data: _DataT | None = None,
origin: EventOrigin = EventOrigin.local, origin: EventOrigin = EventOrigin.local,
time_fired: datetime.datetime | None = None, time_fired: datetime.datetime | None = None,
context: Context | None = None, context: Context | None = None,
) -> None: ) -> None:
"""Initialize a new event.""" """Initialize a new event."""
self.event_type = event_type self.event_type = event_type
self.data = data or {} self.data: _DataT = data or {} # type: ignore[assignment]
self.origin = origin self.origin = origin
self.time_fired = time_fired or dt_util.utcnow() self.time_fired = time_fired or dt_util.utcnow()
if not context: if not context:
@ -1294,8 +1286,8 @@ class Event:
_FilterableJobType = tuple[ _FilterableJobType = tuple[
HassJob[[Event], Coroutine[Any, Any, None] | None], # job HassJob[[Event[_DataT]], Coroutine[Any, Any, None] | None], # job
Callable[[Event], bool] | None, # event_filter Callable[[Event[_DataT]], bool] | None, # event_filter
bool, # run_immediately bool, # run_immediately
] ]
@ -1331,8 +1323,8 @@ class EventBus:
def __init__(self, hass: HomeAssistant) -> None: def __init__(self, hass: HomeAssistant) -> None:
"""Initialize a new event bus.""" """Initialize a new event bus."""
self._listeners: dict[str, list[_FilterableJobType]] = {} self._listeners: dict[str, list[_FilterableJobType[Any]]] = {}
self._match_all_listeners: list[_FilterableJobType] = [] self._match_all_listeners: list[_FilterableJobType[Any]] = []
self._listeners[MATCH_ALL] = self._match_all_listeners self._listeners[MATCH_ALL] = self._match_all_listeners
self._hass = hass self._hass = hass

View File

@ -1,7 +1,7 @@
"""Typing Helpers for Home Assistant.""" """Typing Helpers for Home Assistant."""
from collections.abc import Mapping from collections.abc import Mapping
from enum import Enum from enum import Enum
from typing import Any, Generic, TypeVar from typing import Any, TypeVar
import homeassistant.core import homeassistant.core
@ -33,11 +33,6 @@ UNDEFINED = UndefinedType._singleton # pylint: disable=protected-access
# They are kept in order not to break custom integrations # They are kept in order not to break custom integrations
# that may rely on them. # that may rely on them.
# In due time they will be removed. # In due time they will be removed.
EventType = homeassistant.core.Event
HomeAssistantType = homeassistant.core.HomeAssistant HomeAssistantType = homeassistant.core.HomeAssistant
ServiceCallType = homeassistant.core.ServiceCall ServiceCallType = homeassistant.core.ServiceCall
class EventType(homeassistant.core.Event, Generic[_DataT]):
"""Generic Event class to better type data."""
data: _DataT # type: ignore[assignment]