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

Make AbstractSpookEntityService and AbstractSpookEntityComponentService generic #729

Merged
merged 1 commit into from
Apr 23, 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
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
from homeassistant.core import ServiceCall


class SpookService(AbstractSpookEntityComponentService, ReplaceExistingService):
class SpookService(
AbstractSpookEntityComponentService[InputNumber], ReplaceExistingService
):
"""Input number entity service, decrease value by a single step.

It override the built-in increment service to allow for a custom amount.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
from homeassistant.core import ServiceCall


class SpookService(AbstractSpookEntityComponentService, ReplaceExistingService):
class SpookService(
AbstractSpookEntityComponentService[InputNumber], ReplaceExistingService
):
"""Input number entity service, increase value by a single step.

It override the built-in increment service to allow for a custom amount.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@
from homeassistant.core import ServiceCall


class SpookService(AbstractSpookEntityComponentService):
class SpookService(AbstractSpookEntityComponentService[InputNumber]):
"""Input number entity service, set the max value."""

domain = DOMAIN
service = "max"

async def async_handle_service(self, entity: InputNumber, _: ServiceCall) -> None:
async def async_handle_service(
self,
entity: InputNumber,
call: ServiceCall, # noqa: ARG002
) -> None:
Comment on lines -21 to +25
Copy link
Contributor Author

@cdce8p cdce8p Apr 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The argument names of overwritten methods should match the ones from the super class.
Mypy does not (yet?) validate this, but pyright does.

Parameter 3 name mismatch: base parameter is named "call", override parameter is named "_"

I believe ruff ARG002 is too strict in this case.

Update Found this old mypy issue: python/mypy#6709

"""Handle the service call."""
# pylint: disable-next=protected-access
await entity.async_set_value(entity._maximum) # noqa: SLF001
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@
from homeassistant.core import ServiceCall


class SpookService(AbstractSpookEntityComponentService):
class SpookService(AbstractSpookEntityComponentService[InputNumber]):
"""Input number entity service, set the min value."""

domain = DOMAIN
service = "min"

async def async_handle_service(self, entity: InputNumber, _: ServiceCall) -> None:
async def async_handle_service(
self,
entity: InputNumber,
call: ServiceCall, # noqa: ARG002
) -> None:
"""Handle the service call."""
# pylint: disable-next=protected-access
await entity.async_set_value(entity._minimum) # noqa: SLF001
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from homeassistant.core import ServiceCall


class SpookService(AbstractSpookEntityComponentService):
class SpookService(AbstractSpookEntityComponentService[InputSelect]):
"""Input select entity service, shuffling the positions.

These changes are not permanent, and will be lost when input select entities
Expand All @@ -26,7 +26,7 @@ class SpookService(AbstractSpookEntityComponentService):
async def async_handle_service(
self,
entity: InputSelect,
_call: ServiceCall,
call: ServiceCall, # noqa: ARG002
) -> None:
"""Handle the service call."""
# pylint: disable-next=protected-access
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from homeassistant.core import ServiceCall


class SpookService(AbstractSpookEntityComponentService):
class SpookService(AbstractSpookEntityComponentService[InputSelect]):
"""Input select entity service, sorting the positions.

These changes are not permanent, and will be lost when input select entities
Expand All @@ -25,7 +25,7 @@ class SpookService(AbstractSpookEntityComponentService):
async def async_handle_service(
self,
entity: InputSelect,
_call: ServiceCall,
call: ServiceCall, # noqa: ARG002
) -> None:
"""Handle the service call."""
# pylint: disable-next=protected-access
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from homeassistant.core import ServiceCall


class SpookService(AbstractSpookEntityComponentService):
class SpookService(AbstractSpookEntityComponentService[NumberEntity]):
"""Number entity service, decrease value by a single step."""

domain = DOMAIN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from homeassistant.core import ServiceCall


class SpookService(AbstractSpookEntityComponentService):
class SpookService(AbstractSpookEntityComponentService[NumberEntity]):
"""Number entity service, increase value by a single step."""

domain = DOMAIN
Expand Down
8 changes: 6 additions & 2 deletions custom_components/spook/ectoplasms/number/services/max.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@
from homeassistant.core import ServiceCall


class SpookService(AbstractSpookEntityComponentService):
class SpookService(AbstractSpookEntityComponentService[NumberEntity]):
"""Number entity service, set the max value."""

domain = DOMAIN
service = "max"

async def async_handle_service(self, entity: NumberEntity, _: ServiceCall) -> None:
async def async_handle_service(
self,
entity: NumberEntity,
call: ServiceCall, # noqa: ARG002
) -> None:
"""Handle the service call."""
if entity.max_value is None:
msg = f"Entity {entity.entity_id} has no max value"
Expand Down
8 changes: 6 additions & 2 deletions custom_components/spook/ectoplasms/number/services/min.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@
from homeassistant.core import ServiceCall


class SpookService(AbstractSpookEntityComponentService):
class SpookService(AbstractSpookEntityComponentService[NumberEntity]):
"""Number entity service, set the min value."""

domain = DOMAIN
service = "min"

async def async_handle_service(self, entity: NumberEntity, _: ServiceCall) -> None:
async def async_handle_service(
self,
entity: NumberEntity,
call: ServiceCall, # noqa: ARG002
) -> None:
"""Handle the service call."""
if entity.min_value is None:
msg = f"Entity {entity.entity_id} has no min value"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from homeassistant.core import ServiceCall


class SpookService(AbstractSpookEntityComponentService):
class SpookService(AbstractSpookEntityComponentService[SelectEntity]):
"""Select entity service, select a random option."""

domain = DOMAIN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from homeassistant.core import ServiceCall


class SpookService(AbstractSpookEntityService):
class SpookService(AbstractSpookEntityService[Timer]):
"""Home Assistant service to set duration for a timer."""

domain = DOMAIN
Expand Down
15 changes: 9 additions & 6 deletions custom_components/spook/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
from dataclasses import dataclass, field
import importlib
from pathlib import Path
from typing import TYPE_CHECKING, Any, cast, final
from typing import TYPE_CHECKING, Any, Generic, cast, final

from typing_extensions import TypeVar
import voluptuous as vol

from homeassistant.core import (
Expand All @@ -18,6 +19,7 @@
SupportsResponse,
callback,
)
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import DATA_INSTANCES, EntityComponent
from homeassistant.helpers.entity_platform import DATA_ENTITY_PLATFORM
from homeassistant.helpers.service import (
Expand All @@ -33,7 +35,8 @@
if TYPE_CHECKING:
from types import ModuleType

from homeassistant.helpers.entity import Entity

_EntityT = TypeVar("_EntityT", bound=Entity, default=Entity)


class AbstractSpookServiceBase(ABC):
Expand Down Expand Up @@ -147,7 +150,7 @@ async def async_handle_service(self, call: ServiceCall) -> None:
raise NotImplementedError


class AbstractSpookEntityService(AbstractSpookServiceBase):
class AbstractSpookEntityService(AbstractSpookServiceBase, Generic[_EntityT]):
"""Abstract class to hold a Spook entity service."""

platform: str
Expand Down Expand Up @@ -190,14 +193,14 @@ def async_register(self) -> None:
@abstractmethod
async def async_handle_service(
self,
entity: Entity,
entity: _EntityT,
call: ServiceCall,
) -> ServiceResponse:
"""Handle the service call."""
raise NotImplementedError


class AbstractSpookEntityComponentService(AbstractSpookServiceBase):
class AbstractSpookEntityComponentService(AbstractSpookServiceBase, Generic[_EntityT]):
"""Abstract class to hold a Spook entity component service."""

required_features: list[int] | None = None
Expand Down Expand Up @@ -233,7 +236,7 @@ def async_register(self) -> None:
@abstractmethod
async def async_handle_service(
self,
entity: Entity,
entity: _EntityT,
call: ServiceCall,
) -> ServiceResponse:
"""Handle the service call."""
Expand Down