diff --git a/homeassistant/util/hass_dict.py b/homeassistant/util/hass_dict.py index 1d0e6844798..692a21dfc58 100644 --- a/homeassistant/util/hass_dict.py +++ b/homeassistant/util/hass_dict.py @@ -5,12 +5,8 @@ Custom for type checking. See stub file. from __future__ import annotations -from typing import Generic, TypeVar -_T = TypeVar("_T") - - -class HassKey(str, Generic[_T]): +class HassKey[_T](str): """Generic Hass key type. At runtime this is a generic subclass of str. @@ -19,7 +15,7 @@ class HassKey(str, Generic[_T]): __slots__ = () -class HassEntryKey(str, Generic[_T]): +class HassEntryKey[_T](str): """Key type for integrations with config entries. At runtime this is a generic subclass of str. diff --git a/homeassistant/util/hass_dict.pyi b/homeassistant/util/hass_dict.pyi index 0e8096eeeb6..5e48c1c0144 100644 --- a/homeassistant/util/hass_dict.pyi +++ b/homeassistant/util/hass_dict.pyi @@ -9,8 +9,7 @@ __all__ = [ "HassKey", ] -_T = TypeVar("_T") -_U = TypeVar("_U") +_T = TypeVar("_T") # needs to be invariant class _Key(Generic[_T]): """Base class for Hass key types. At runtime delegated to str.""" @@ -31,27 +30,29 @@ class HassDict(dict[_Key[Any] | str, Any]): """Custom dict type to provide better value type hints for Hass key types.""" @overload # type: ignore[override] - def __getitem__(self, key: HassEntryKey[_T], /) -> dict[str, _T]: ... + def __getitem__[_S](self, key: HassEntryKey[_S], /) -> dict[str, _S]: ... @overload - def __getitem__(self, key: HassKey[_T], /) -> _T: ... + def __getitem__[_S](self, key: HassKey[_S], /) -> _S: ... @overload def __getitem__(self, key: str, /) -> Any: ... # ------ @overload # type: ignore[override] - def __setitem__(self, key: HassEntryKey[_T], value: dict[str, _T], /) -> None: ... + def __setitem__[_S]( + self, key: HassEntryKey[_S], value: dict[str, _S], / + ) -> None: ... @overload - def __setitem__(self, key: HassKey[_T], value: _T, /) -> None: ... + def __setitem__[_S](self, key: HassKey[_S], value: _S, /) -> None: ... @overload def __setitem__(self, key: str, value: Any, /) -> None: ... # ------ @overload # type: ignore[override] - def setdefault( - self, key: HassEntryKey[_T], default: dict[str, _T], / - ) -> dict[str, _T]: ... + def setdefault[_S]( + self, key: HassEntryKey[_S], default: dict[str, _S], / + ) -> dict[str, _S]: ... @overload - def setdefault(self, key: HassKey[_T], default: _T, /) -> _T: ... + def setdefault[_S](self, key: HassKey[_S], default: _S, /) -> _S: ... @overload def setdefault(self, key: str, default: None = None, /) -> Any | None: ... @overload @@ -59,13 +60,15 @@ class HassDict(dict[_Key[Any] | str, Any]): # ------ @overload # type: ignore[override] - def get(self, key: HassEntryKey[_T], /) -> dict[str, _T] | None: ... + def get[_S](self, key: HassEntryKey[_S], /) -> dict[str, _S] | None: ... @overload - def get(self, key: HassEntryKey[_T], default: _U, /) -> dict[str, _T] | _U: ... + def get[_S, _U]( + self, key: HassEntryKey[_S], default: _U, / + ) -> dict[str, _S] | _U: ... @overload - def get(self, key: HassKey[_T], /) -> _T | None: ... + def get[_S](self, key: HassKey[_S], /) -> _S | None: ... @overload - def get(self, key: HassKey[_T], default: _U, /) -> _T | _U: ... + def get[_S, _U](self, key: HassKey[_S], default: _U, /) -> _S | _U: ... @overload def get(self, key: str, /) -> Any | None: ... @overload @@ -73,23 +76,25 @@ class HassDict(dict[_Key[Any] | str, Any]): # ------ @overload # type: ignore[override] - def pop(self, key: HassEntryKey[_T], /) -> dict[str, _T]: ... + def pop[_S](self, key: HassEntryKey[_S], /) -> dict[str, _S]: ... @overload - def pop( - self, key: HassEntryKey[_T], default: dict[str, _T], / - ) -> dict[str, _T]: ... + def pop[_S]( + self, key: HassEntryKey[_S], default: dict[str, _S], / + ) -> dict[str, _S]: ... @overload - def pop(self, key: HassEntryKey[_T], default: _U, /) -> dict[str, _T] | _U: ... + def pop[_S, _U]( + self, key: HassEntryKey[_S], default: _U, / + ) -> dict[str, _S] | _U: ... @overload - def pop(self, key: HassKey[_T], /) -> _T: ... + def pop[_S](self, key: HassKey[_S], /) -> _S: ... @overload - def pop(self, key: HassKey[_T], default: _T, /) -> _T: ... + def pop[_S](self, key: HassKey[_S], default: _S, /) -> _S: ... @overload - def pop(self, key: HassKey[_T], default: _U, /) -> _T | _U: ... + def pop[_S, _U](self, key: HassKey[_S], default: _U, /) -> _S | _U: ... @overload def pop(self, key: str, /) -> Any: ... @overload - def pop(self, key: str, default: _U, /) -> Any | _U: ... + def pop[_U](self, key: str, default: _U, /) -> Any | _U: ... def _test_hass_dict_typing() -> None: # noqa: PYI048 """Test HassDict overloads work as intended.