Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc typing improvements #731

Merged
merged 1 commit into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions custom_components/spook/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
import asyncio
from typing import TYPE_CHECKING

from homeassistant.const import RESTART_EXIT_CODE
from homeassistant.core import (
from homeassistant.const import (
EVENT_HOMEASSISTANT_START,
EVENT_HOMEASSISTANT_STARTED,
RESTART_EXIT_CODE,
)
from homeassistant.core import (
CoreState,
callback,
)
Expand Down
15 changes: 6 additions & 9 deletions custom_components/spook/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,14 @@

from __future__ import annotations

from typing import TYPE_CHECKING, Any
from typing import Any

import voluptuous as vol

from homeassistant.config_entries import ConfigFlow
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult

from .const import DOMAIN

if TYPE_CHECKING:
from homeassistant.data_entry_flow import FlowResult


class UptimeConfigFlow(ConfigFlow, domain=DOMAIN):
"""Config flow for Spook."""
Expand All @@ -22,7 +19,7 @@ class UptimeConfigFlow(ConfigFlow, domain=DOMAIN):
async def async_step_user(
self,
user_input: dict[str, Any] | None = None,
) -> FlowResult:
) -> ConfigFlowResult:
"""Handle a flow initialized someone that didn't read the warnings."""
if self._async_current_entries():
return self.async_abort(reason="already_spooked")
Expand All @@ -35,7 +32,7 @@ async def async_step_user(
async def async_step_choice_restart(
self,
_: dict[str, Any] | None = None,
) -> FlowResult:
) -> ConfigFlowResult:
"""Handle the user's choice.

Allows the user to choose to restart now or later.
Expand All @@ -48,14 +45,14 @@ async def async_step_choice_restart(
async def async_step_restart_later(
self,
_: dict[str, Any] | None = None,
) -> FlowResult:
) -> ConfigFlowResult:
"""Handle restart later case."""
return self.async_create_entry(title="Your homie", data={})

async def async_step_restart_now(
self,
_: dict[str, Any] | None = None,
) -> FlowResult:
) -> ConfigFlowResult:
"""Handle restart now case.

Sets a flag, so the integraton setup knows it can go ahead and restart.
Expand Down
2 changes: 1 addition & 1 deletion custom_components/spook/ectoplasms/homeassistant/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from homeassistant.components import homeassistant
from homeassistant.const import __version__
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.device_registry import DeviceInfo

from ...const import DOMAIN
from ...entity import SpookEntity, SpookEntityDescription
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ def _function(
self,
value: Iterable[Any],
levels: int | None = None,
) -> bool:
) -> list[Any]:
"""Flattens a list of lists."""
flattend = []
flattend: list[Any] = []
for item in value:
if isinstance(item, Iterable) and not isinstance(item, str):
if levels is None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
from typing import TYPE_CHECKING, Any

from homeassistant.components.lovelace import DOMAIN
from homeassistant.components.lovelace.const import (
EVENT_LOVELACE_UPDATED,
ConfigNotFound,
)
from homeassistant.components.lovelace.const import ConfigNotFound
from homeassistant.const import (
EVENT_COMPONENT_LOADED,
EVENT_LOVELACE_UPDATED,
)
from homeassistant.core import callback
from homeassistant.helpers import entity_registry as er
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from __future__ import annotations

from typing import TYPE_CHECKING

import voluptuous as vol

from homeassistant.components.recorder import DOMAIN
Expand All @@ -14,6 +16,9 @@

from ....services import AbstractSpookAdminService

if TYPE_CHECKING:
from homeassistant.components.recorder.models import StatisticMetaData


class SpookService(AbstractSpookAdminService):
"""Recorder integration service to import statistics."""
Expand Down Expand Up @@ -42,7 +47,7 @@ class SpookService(AbstractSpookAdminService):

async def async_handle_service(self, call: ServiceCall) -> None:
"""Handle the service call."""
metadata = {
metadata: StatisticMetaData = {
"has_mean": call.data["has_mean"],
"has_sum": call.data["has_sum"],
"name": call.data["name"],
Expand Down
2 changes: 1 addition & 1 deletion custom_components/spook/ectoplasms/repairs/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ async def async_setup_entry(


class RepairsSpookButtonEntity(RepairsSpookEntity, ButtonEntity):
"""Spook button providig Repairs actions."""
"""Spook button providing Repairs actions."""

entity_description: RepairsSpookButtonEntityDescription

Expand Down
2 changes: 1 addition & 1 deletion custom_components/spook/ectoplasms/repairs/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from homeassistant.components import repairs
from homeassistant.const import __version__
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.device_registry import DeviceInfo

from ...const import DOMAIN
from ...entity import SpookEntity, SpookEntityDescription
Expand Down
2 changes: 1 addition & 1 deletion custom_components/spook/ectoplasms/repairs/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ async def async_added_to_hass(self) -> None:
@callback
def _fire(event: Event) -> None:
"""Update state."""
data = event.data.copy()
data = {**event.data}
event_type = data.pop("action")
self._trigger_event(event_type, data)
self.async_schedule_update_ha_state()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,13 @@ async def async_handle_service(
}
)

collection: TimerStorageCollection
if DOMAIN in entity.hass.data:
collection: TimerStorageCollection = entity.hass.data[DOMAIN]
collection = entity.hass.data[DOMAIN]
else:
# Major hack borrowed from ../../zone/services/create.py:27 👻
collection: TimerStorageCollection = entity.hass.data["websocket_api"][
"timer/list"
][0].__self__.storage_collection
collection = entity.hass.data["websocket_api"]["timer/list"][
0
].__self__.storage_collection

await collection.async_update_item(item_id, updates)
4 changes: 1 addition & 3 deletions custom_components/spook/ectoplasms/zone/services/delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ class SpookService(AbstractSpookAdminService):

async def async_handle_service(self, call: ServiceCall) -> None:
"""Handle the service call."""
entity_component: [EntityComponent[Zone]] = self.hass.data[DATA_INSTANCES][
DOMAIN
]
entity_component: EntityComponent[Zone] = self.hass.data[DATA_INSTANCES][DOMAIN]

collection: ZoneStorageCollection
if DOMAIN in self.hass.data:
Expand Down
4 changes: 1 addition & 3 deletions custom_components/spook/ectoplasms/zone/services/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ class SpookService(AbstractSpookAdminService):

async def async_handle_service(self, call: ServiceCall) -> None:
"""Handle the service call."""
entity_component: [EntityComponent[Zone]] = self.hass.data[DATA_INSTANCES][
DOMAIN
]
entity_component: EntityComponent[Zone] = self.hass.data[DATA_INSTANCES][DOMAIN]

collection: ZoneStorageCollection
if DOMAIN in self.hass.data:
Expand Down
18 changes: 10 additions & 8 deletions custom_components/spook/integrations/spook_inverse/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
CONF_ENTITY_ID,
STATE_UNAVAILABLE,
)
from homeassistant.core import HomeAssistant, State, callback
from homeassistant.core import Event, HomeAssistant, State, callback
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.entity import DeviceInfo, Entity
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.event import (
EventStateChangedData,
async_track_state_change_event,
Expand All @@ -24,7 +25,6 @@

if TYPE_CHECKING:
from homeassistant.config_entries import ConfigEntry
from homeassistant.helpers.typing import EventType


class InverseEntity(Entity): # pylint: disable=too-many-instance-attributes
Expand Down Expand Up @@ -90,7 +90,7 @@ async def async_update_at_start(_: HomeAssistant) -> None:
@callback
def async_update_and_write_state(
self,
event: EventType[EventStateChangedData] | None = None,
event: Event[EventStateChangedData] | None = None,
) -> None:
"""Update the state and write it to the entity."""
if not self.hass.is_running:
Expand All @@ -112,12 +112,14 @@ def async_update_and_write_state(

self.async_update_state(state)

self._attr_extra_state_attributes |= {
state_attributes = {
**self._attr_extra_state_attributes,
ATTR_ENTITY_ID: self._entity_id,
}
self._attr_extra_state_attributes.pop(ATTR_ICON, None)
self._attr_extra_state_attributes.pop(ATTR_DEVICE_CLASS, None)
self._attr_extra_state_attributes.pop(ATTR_SUPPORTED_FEATURES, None)
state_attributes.pop(ATTR_ICON, None)
state_attributes.pop(ATTR_DEVICE_CLASS, None)
state_attributes.pop(ATTR_SUPPORTED_FEATURES, None)
self._attr_extra_state_attributes = state_attributes

self.async_write_ha_state()

Expand Down
19 changes: 11 additions & 8 deletions custom_components/spook/repairs.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@

from homeassistant.components.homeassistant import SERVICE_HOMEASSISTANT_RESTART
from homeassistant.components.repairs import ConfirmRepairFlow, RepairsFlow
from homeassistant.config_entries import SIGNAL_CONFIG_ENTRY_CHANGED, ConfigEntry
from homeassistant.config_entries import (
SIGNAL_CONFIG_ENTRY_CHANGED,
ConfigEntry,
ConfigEntryChange,
)
from homeassistant.core import Event, HomeAssistant, callback
from homeassistant.helpers import (
area_registry as ar,
Expand All @@ -26,7 +30,7 @@
from .const import DOMAIN, LOGGER

if TYPE_CHECKING:
from collections.abc import Callable, Mapping
from collections.abc import Callable, Coroutine, Mapping
from types import ModuleType

from homeassistant.data_entry_flow import FlowResult
Expand Down Expand Up @@ -122,7 +126,7 @@ class AbstractSpookRepair(AbstractSpookRepairBase):
"""Abstract base class to hold a Spook repairs."""

inspect_events: set[str] | None = None
inspect_debouncer: Debouncer
inspect_debouncer: Debouncer[Coroutine[Any, Any, None]]
inspect_config_entry_changed: bool | str = False
inspect_on_reload: bool | str = False

Expand Down Expand Up @@ -188,10 +192,9 @@ async def _async_call_inspect_debouncer(_: Event) -> None:
if self.inspect_on_reload:

@callback
def _filter_event(event_data: Mapping[str, Any] | Event) -> bool:
def _filter_event(data: Mapping[str, Any] | Event) -> bool:
"""Filter for reload events."""
if type(event_data) is Event: # pylint: disable=unidiomatic-typecheck
event_data = event_data.data
event_data = data.data if isinstance(data, Event) else data
frenck marked this conversation as resolved.
Show resolved Hide resolved
service = event_data.get("service")
if service is None:
return False
Expand All @@ -213,8 +216,8 @@ def _filter_event(event_data: Mapping[str, Any] | Event) -> bool:

if self.inspect_config_entry_changed:

async def _async_config_entry_changed(
_hass: HomeAssistant,
async def _async_config_entry_changed( # pylint: disable=unused-argument
change: ConfigEntryChange, # noqa: ARG001
entry: ConfigEntry,
) -> None:
"""Handle options update."""
Expand Down
13 changes: 8 additions & 5 deletions custom_components/spook/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from dataclasses import dataclass, field
import importlib
from pathlib import Path
from typing import TYPE_CHECKING, Any, final
from typing import TYPE_CHECKING, Any, cast, final

import voluptuous as vol

Expand Down Expand Up @@ -259,10 +259,13 @@ async def async_setup(self) -> None:

# Load service schemas
integration = await async_get_integration(self.hass, DOMAIN)
self._service_schemas = await self.hass.async_add_executor_job(
_load_services_file,
self.hass,
integration,
self._service_schemas = cast(
dict[str, Any],
await self.hass.async_add_executor_job(
_load_services_file,
self.hass,
integration,
),
)

modules: list[ModuleType] = []
Expand Down
2 changes: 1 addition & 1 deletion custom_components/spook/templating.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def function(self) -> Callable[..., Any]:
@final
@callback
def async_register(
self, environment: TemplateEnvironment, *, is_limited: bool = False
self, environment: TemplateEnvironment, *, is_limited: bool | None = False
) -> None:
"""Register the template method."""
if environment.hass is None and self.requires_hass_object:
Expand Down
8 changes: 5 additions & 3 deletions custom_components/spook/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from .const import DOMAIN, LOGGER

if TYPE_CHECKING:
from collections.abc import Sequence
from collections.abc import Iterable, Sequence
from types import ModuleType

from homeassistant.config_entries import ConfigEntry
Expand Down Expand Up @@ -125,7 +125,7 @@ def link_sub_integrations(hass: HomeAssistant) -> bool:
return changes


def unlink_sub_integrations(hass: HomeAssistant) -> bool:
def unlink_sub_integrations(hass: HomeAssistant) -> None:
"""Unlink Spook sub integrations."""
LOGGER.debug("Unlinking Spook sub integrations")
for manifest in Path(__file__).parent.rglob("integrations/*/manifest.json"):
Expand Down Expand Up @@ -225,7 +225,9 @@ def async_get_all_entity_ids(

@callback
def async_filter_known_entity_ids(
hass: HomeAssistant, entity_ids: set[str], known_entity_ids: set[str] | None = None
hass: HomeAssistant,
entity_ids: Iterable[str],
known_entity_ids: set[str] | None = None,
) -> set[str]:
"""Filter out known entity IDs."""
if known_entity_ids is None:
Expand Down