Repository: home-assistant/core
File: homeassistant/components/todo/intent.py (Python)

Code before:
"""Intents for the todo integration."""

from __future__ import annotations

import voluptuous as vol

from homeassistant.core import HomeAssistant
from homeassistant.helpers import intent

from . import TodoItem, TodoItemStatus, TodoListEntity
from .const import DATA_COMPONENT, DOMAIN

INTENT_LIST_ADD_ITEM = "HassListAddItem"
INTENT_LIST_COMPLETE_ITEM = "HassListCompleteItem"
INTENT_LIST_REMOVE_ITEM = "HassListRemoveItem"


async def async_setup_intents(hass: HomeAssistant) -> None:
    """Set up the todo intents."""
    intent.async_register(hass, ListAddItemIntent())
    intent.async_register(hass, ListCompleteItemIntent())
    intent.async_register(hass, ListRemoveItemIntent())


class ListBaseItent(intent.IntentHandler):
    """Base class for toto intents."""

    slot_schema = {
        vol.Required("item"): intent.non_empty_string,
        vol.Required("name"): intent.non_empty_string,
    }
    platforms = {DOMAIN}

    def _get_params(self, intent_obj: intent.Intent) -> tuple[str, str]:
        """Validate and return intent params."""
        slots = self.async_validate_slots(intent_obj.slots)

        item = slots["item"]["value"].strip()
        list_name = slots["name"]["value"]

        return item, list_name

    def _get_target_list(
        self, intent_obj: intent.Intent, list_name: str
    ) -> TodoListEntity:
        """Return the requested todo list."""
        hass = intent_obj.hass

        target_list: TodoListEntity | None = None

        match_constraints = intent.MatchTargetsConstraints(

Review comment (suggestion):
Instead of having subclasses reach into here for multiple methods, try having `async_handle` defined here and call into a single method in the subclass.

Also please name things using `IntentHandler` suffix, here for example `ListBaseIntentHandler`.

Code after:
"""Intents for the todo integration."""

from __future__ import annotations

import voluptuous as vol

from homeassistant.core import HomeAssistant
from homeassistant.helpers import intent

from . import TodoItem, TodoItemStatus, TodoListEntity
from .const import DATA_COMPONENT, DOMAIN

INTENT_LIST_ADD_ITEM = "HassListAddItem"
INTENT_LIST_COMPLETE_ITEM = "HassListCompleteItem"
INTENT_LIST_REMOVE_ITEM = "HassListRemoveItem"


async def async_setup_intents(hass: HomeAssistant) -> None:
    """Set up the todo intent handlers."""
    intent.async_register(hass, ListAddItemIntentHandler())
    intent.async_register(hass, ListCompleteItemIntentHandler())
    intent.async_register(hass, ListRemoveItemIntentHandler())


class ListBaseIntentHandler(intent.IntentHandler):
    """Base class for toto intent handlers."""

    slot_schema = {
        vol.Required("item"): intent.non_empty_string,
        vol.Required("name"): intent.non_empty_string,
    }
    platforms = {DOMAIN}

    async def _async_do_handle(self, target_list: TodoListEntity, item: str) -> None:
        """Execute action specific to this intent handler."""
        raise NotImplementedError

    async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse:
        """Handle the intent."""
        hass = intent_obj.hass

        slots = self.async_validate_slots(intent_obj.slots)
        item = slots["item"]["value"].strip()
        list_name = slots["name"]["value"]

        target_list: TodoListEntity | None = None

        # Find matching list
        match_constraints = intent.MatchTargetsConstraints(
            name=list_name, domains=[DOMAIN], assistant=intent_obj.assistant
        )