diff --git a/script/scaffold/templates/config_flow/integration/__init__.py b/script/scaffold/templates/config_flow/integration/__init__.py index 334ac8dbbc9..24a0c1d7350 100644 --- a/script/scaffold/templates/config_flow/integration/__init__.py +++ b/script/scaffold/templates/config_flow/integration/__init__.py @@ -1,5 +1,8 @@ """The NEW_NAME integration.""" +from __future__ import annotations + import asyncio +from typing import Any from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant @@ -11,12 +14,12 @@ from .const import DOMAIN PLATFORMS = ["light"] -async def async_setup(hass: HomeAssistant, config: dict): +async def async_setup(hass: HomeAssistant, config: dict[str, Any]) -> bool: """Set up the NEW_NAME component.""" return True -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): +async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up NEW_NAME from a config entry.""" # TODO Store an API object for your platforms to access # hass.data[DOMAIN][entry.entry_id] = MyApi(...) @@ -29,7 +32,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): +async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" unload_ok = all( await asyncio.gather( diff --git a/script/scaffold/templates/config_flow/integration/config_flow.py b/script/scaffold/templates/config_flow/integration/config_flow.py index c9700463c86..aa05f633df4 100644 --- a/script/scaffold/templates/config_flow/integration/config_flow.py +++ b/script/scaffold/templates/config_flow/integration/config_flow.py @@ -1,9 +1,14 @@ """Config flow for NEW_NAME integration.""" +from __future__ import annotations + import logging +from typing import Any import voluptuous as vol -from homeassistant import config_entries, core, exceptions +from homeassistant import config_entries +from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError from .const import DOMAIN # pylint:disable=unused-import @@ -19,16 +24,16 @@ class PlaceholderHub: TODO Remove this placeholder class and replace with things from your PyPI package. """ - def __init__(self, host): + def __init__(self, host: str) -> None: """Initialize.""" self.host = host - async def authenticate(self, username, password) -> bool: + async def authenticate(self, username: str, password: str) -> bool: """Test if we can authenticate with the host.""" return True -async def validate_input(hass: core.HomeAssistant, data): +async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str, Any]: """Validate the user input allows us to connect. Data has the keys from STEP_USER_DATA_SCHEMA with values provided by the user. @@ -62,7 +67,9 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): # TODO pick one of the available connection classes in homeassistant/config_entries.py CONNECTION_CLASS = config_entries.CONN_CLASS_UNKNOWN - async def async_step_user(self, user_input=None): + async def async_step_user( + self, user_input: dict[str, Any] | None = None + ) -> dict[str, Any]: """Handle the initial step.""" if user_input is None: return self.async_show_form( @@ -88,9 +95,9 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): ) -class CannotConnect(exceptions.HomeAssistantError): +class CannotConnect(HomeAssistantError): """Error to indicate we cannot connect.""" -class InvalidAuth(exceptions.HomeAssistantError): +class InvalidAuth(HomeAssistantError): """Error to indicate there is invalid auth.""" diff --git a/script/scaffold/templates/config_flow/tests/test_config_flow.py b/script/scaffold/templates/config_flow/tests/test_config_flow.py index 04eab6e683c..8205fdbeda4 100644 --- a/script/scaffold/templates/config_flow/tests/test_config_flow.py +++ b/script/scaffold/templates/config_flow/tests/test_config_flow.py @@ -4,9 +4,10 @@ from unittest.mock import patch from homeassistant import config_entries, setup from homeassistant.components.NEW_DOMAIN.config_flow import CannotConnect, InvalidAuth from homeassistant.components.NEW_DOMAIN.const import DOMAIN +from homeassistant.core import HomeAssistant -async def test_form(hass): +async def test_form(hass: HomeAssistant) -> None: """Test we get the form.""" await setup.async_setup_component(hass, "persistent_notification", {}) result = await hass.config_entries.flow.async_init( @@ -45,7 +46,7 @@ async def test_form(hass): assert len(mock_setup_entry.mock_calls) == 1 -async def test_form_invalid_auth(hass): +async def test_form_invalid_auth(hass: HomeAssistant) -> None: """Test we handle invalid auth.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} @@ -68,7 +69,7 @@ async def test_form_invalid_auth(hass): assert result2["errors"] == {"base": "invalid_auth"} -async def test_form_cannot_connect(hass): +async def test_form_cannot_connect(hass: HomeAssistant) -> None: """Test we handle cannot connect error.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} diff --git a/script/scaffold/templates/config_flow_discovery/integration/__init__.py b/script/scaffold/templates/config_flow_discovery/integration/__init__.py index 334ac8dbbc9..24a0c1d7350 100644 --- a/script/scaffold/templates/config_flow_discovery/integration/__init__.py +++ b/script/scaffold/templates/config_flow_discovery/integration/__init__.py @@ -1,5 +1,8 @@ """The NEW_NAME integration.""" +from __future__ import annotations + import asyncio +from typing import Any from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant @@ -11,12 +14,12 @@ from .const import DOMAIN PLATFORMS = ["light"] -async def async_setup(hass: HomeAssistant, config: dict): +async def async_setup(hass: HomeAssistant, config: dict[str, Any]) -> bool: """Set up the NEW_NAME component.""" return True -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): +async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up NEW_NAME from a config entry.""" # TODO Store an API object for your platforms to access # hass.data[DOMAIN][entry.entry_id] = MyApi(...) @@ -29,7 +32,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): +async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" unload_ok = all( await asyncio.gather( diff --git a/script/scaffold/templates/config_flow_discovery/integration/config_flow.py b/script/scaffold/templates/config_flow_discovery/integration/config_flow.py index db5f719ce3d..4d2ee2c9f6b 100644 --- a/script/scaffold/templates/config_flow_discovery/integration/config_flow.py +++ b/script/scaffold/templates/config_flow_discovery/integration/config_flow.py @@ -2,12 +2,13 @@ import my_pypi_dependency from homeassistant import config_entries +from homeassistant.core import HomeAssistant from homeassistant.helpers import config_entry_flow from .const import DOMAIN -async def _async_has_devices(hass) -> bool: +async def _async_has_devices(hass: HomeAssistant) -> bool: """Return if there are devices that can be discovered.""" # TODO Check if there are any devices that can be discovered in the network. devices = await hass.async_add_executor_job(my_pypi_dependency.discover) diff --git a/script/scaffold/templates/config_flow_oauth2/integration/__init__.py b/script/scaffold/templates/config_flow_oauth2/integration/__init__.py index 4e290921047..304df8f9c79 100644 --- a/script/scaffold/templates/config_flow_oauth2/integration/__init__.py +++ b/script/scaffold/templates/config_flow_oauth2/integration/__init__.py @@ -1,5 +1,8 @@ """The NEW_NAME integration.""" +from __future__ import annotations + import asyncio +from typing import Any import voluptuous as vol @@ -32,7 +35,7 @@ CONFIG_SCHEMA = vol.Schema( PLATFORMS = ["light"] -async def async_setup(hass: HomeAssistant, config: dict): +async def async_setup(hass: HomeAssistant, config: dict[str, Any]) -> bool: """Set up the NEW_NAME component.""" hass.data[DOMAIN] = {} @@ -54,7 +57,7 @@ async def async_setup(hass: HomeAssistant, config: dict): return True -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): +async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up NEW_NAME from a config entry.""" implementation = ( await config_entry_oauth2_flow.async_get_config_entry_implementation( @@ -80,7 +83,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): +async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" unload_ok = all( await asyncio.gather( diff --git a/script/scaffold/templates/config_flow_oauth2/integration/api.py b/script/scaffold/templates/config_flow_oauth2/integration/api.py index 50b54399579..4f15099c8e1 100644 --- a/script/scaffold/templates/config_flow_oauth2/integration/api.py +++ b/script/scaffold/templates/config_flow_oauth2/integration/api.py @@ -4,7 +4,7 @@ from asyncio import run_coroutine_threadsafe from aiohttp import ClientSession import my_pypi_package -from homeassistant import core +from homeassistant.core import HomeAssistant from homeassistant.helpers import config_entry_oauth2_flow # TODO the following two API examples are based on our suggested best practices @@ -17,9 +17,9 @@ class ConfigEntryAuth(my_pypi_package.AbstractAuth): def __init__( self, - hass: core.HomeAssistant, + hass: HomeAssistant, oauth_session: config_entry_oauth2_flow.OAuth2Session, - ): + ) -> None: """Initialize NEW_NAME Auth.""" self.hass = hass self.session = oauth_session @@ -41,7 +41,7 @@ class AsyncConfigEntryAuth(my_pypi_package.AbstractAuth): self, websession: ClientSession, oauth_session: config_entry_oauth2_flow.OAuth2Session, - ): + ) -> None: """Initialize NEW_NAME auth.""" super().__init__(websession) self._oauth_session = oauth_session diff --git a/script/scaffold/templates/config_flow_oauth2/tests/test_config_flow.py b/script/scaffold/templates/config_flow_oauth2/tests/test_config_flow.py index dd0fc3446b3..ff9c5bfb848 100644 --- a/script/scaffold/templates/config_flow_oauth2/tests/test_config_flow.py +++ b/script/scaffold/templates/config_flow_oauth2/tests/test_config_flow.py @@ -7,6 +7,7 @@ from homeassistant.components.NEW_DOMAIN.const import ( OAUTH2_AUTHORIZE, OAUTH2_TOKEN, ) +from homeassistant.core import HomeAssistant from homeassistant.helpers import config_entry_oauth2_flow CLIENT_ID = "1234" @@ -14,8 +15,11 @@ CLIENT_SECRET = "5678" async def test_full_flow( - hass, aiohttp_client, aioclient_mock, current_request_with_host -): + hass: HomeAssistant, + aiohttp_client, + aioclient_mock, + current_request_with_host, +) -> None: """Check full flow.""" assert await setup.async_setup_component( hass, diff --git a/script/scaffold/templates/device_action/tests/test_device_action.py b/script/scaffold/templates/device_action/tests/test_device_action.py index 91a4693ebeb..424fa0a9afd 100644 --- a/script/scaffold/templates/device_action/tests/test_device_action.py +++ b/script/scaffold/templates/device_action/tests/test_device_action.py @@ -3,7 +3,8 @@ import pytest from homeassistant.components import automation from homeassistant.components.NEW_DOMAIN import DOMAIN -from homeassistant.helpers import device_registry +from homeassistant.core import HomeAssistant +from homeassistant.helpers import device_registry, entity_registry from homeassistant.setup import async_setup_component from tests.common import ( @@ -17,18 +18,22 @@ from tests.common import ( @pytest.fixture -def device_reg(hass): +def device_reg(hass: HomeAssistant) -> device_registry.DeviceRegistry: """Return an empty, loaded, registry.""" return mock_device_registry(hass) @pytest.fixture -def entity_reg(hass): +def entity_reg(hass: HomeAssistant) -> entity_registry.EntityRegistry: """Return an empty, loaded, registry.""" return mock_registry(hass) -async def test_get_actions(hass, device_reg, entity_reg): +async def test_get_actions( + hass: HomeAssistant, + device_reg: device_registry.DeviceRegistry, + entity_reg: entity_registry.EntityRegistry, +) -> None: """Test we get the expected actions from a NEW_DOMAIN.""" config_entry = MockConfigEntry(domain="test", data={}) config_entry.add_to_hass(hass) @@ -55,7 +60,7 @@ async def test_get_actions(hass, device_reg, entity_reg): assert_lists_same(actions, expected_actions) -async def test_action(hass): +async def test_action(hass: HomeAssistant) -> None: """Test for turn_on and turn_off actions.""" assert await async_setup_component( hass, diff --git a/script/scaffold/templates/device_condition/tests/test_device_condition.py b/script/scaffold/templates/device_condition/tests/test_device_condition.py index 07e0afd05eb..9a283fa1f5b 100644 --- a/script/scaffold/templates/device_condition/tests/test_device_condition.py +++ b/script/scaffold/templates/device_condition/tests/test_device_condition.py @@ -1,10 +1,13 @@ """The tests for NEW_NAME device conditions.""" +from __future__ import annotations + import pytest from homeassistant.components import automation from homeassistant.components.NEW_DOMAIN import DOMAIN from homeassistant.const import STATE_OFF, STATE_ON -from homeassistant.helpers import device_registry +from homeassistant.core import HomeAssistant, ServiceCall +from homeassistant.helpers import device_registry, entity_registry from homeassistant.setup import async_setup_component from tests.common import ( @@ -18,24 +21,28 @@ from tests.common import ( @pytest.fixture -def device_reg(hass): +def device_reg(hass: HomeAssistant) -> device_registry.DeviceRegistry: """Return an empty, loaded, registry.""" return mock_device_registry(hass) @pytest.fixture -def entity_reg(hass): +def entity_reg(hass: HomeAssistant) -> entity_registry.EntityRegistry: """Return an empty, loaded, registry.""" return mock_registry(hass) @pytest.fixture -def calls(hass): +def calls(hass: HomeAssistant) -> list[ServiceCall]: """Track calls to a mock service.""" return async_mock_service(hass, "test", "automation") -async def test_get_conditions(hass, device_reg, entity_reg): +async def test_get_conditions( + hass: HomeAssistant, + device_reg: device_registry.DeviceRegistry, + entity_reg: entity_registry.EntityRegistry, +) -> None: """Test we get the expected conditions from a NEW_DOMAIN.""" config_entry = MockConfigEntry(domain="test", data={}) config_entry.add_to_hass(hass) @@ -64,7 +71,7 @@ async def test_get_conditions(hass, device_reg, entity_reg): assert_lists_same(conditions, expected_conditions) -async def test_if_state(hass, calls): +async def test_if_state(hass: HomeAssistant, calls: list[ServiceCall]) -> None: """Test for turn_on and turn_off conditions.""" hass.states.async_set("NEW_DOMAIN.entity", STATE_ON) diff --git a/script/scaffold/templates/integration/integration/__init__.py b/script/scaffold/templates/integration/integration/__init__.py index 0ab65cb7da8..c1f34d5f5b1 100644 --- a/script/scaffold/templates/integration/integration/__init__.py +++ b/script/scaffold/templates/integration/integration/__init__.py @@ -1,4 +1,8 @@ """The NEW_NAME integration.""" +from __future__ import annotations + +from typing import Any + import voluptuous as vol from homeassistant.core import HomeAssistant @@ -8,6 +12,6 @@ from .const import DOMAIN CONFIG_SCHEMA = vol.Schema({vol.Optional(DOMAIN): {}}, extra=vol.ALLOW_EXTRA) -async def async_setup(hass: HomeAssistant, config: dict): +async def async_setup(hass: HomeAssistant, config: dict[str, Any]) -> bool: """Set up the NEW_NAME integration.""" return True diff --git a/script/scaffold/templates/reproduce_state/integration/reproduce_state.py b/script/scaffold/templates/reproduce_state/integration/reproduce_state.py index 2031109a6bd..19e046f4c92 100644 --- a/script/scaffold/templates/reproduce_state/integration/reproduce_state.py +++ b/script/scaffold/templates/reproduce_state/integration/reproduce_state.py @@ -12,8 +12,7 @@ from homeassistant.const import ( STATE_OFF, STATE_ON, ) -from homeassistant.core import Context, State -from homeassistant.helpers.typing import HomeAssistantType +from homeassistant.core import Context, HomeAssistant, State from . import DOMAIN @@ -24,7 +23,7 @@ VALID_STATES = {STATE_ON, STATE_OFF} async def _async_reproduce_state( - hass: HomeAssistantType, + hass: HomeAssistant, state: State, *, context: Context | None = None, @@ -69,7 +68,7 @@ async def _async_reproduce_state( async def async_reproduce_states( - hass: HomeAssistantType, + hass: HomeAssistant, states: Iterable[State], *, context: Context | None = None, diff --git a/script/scaffold/templates/reproduce_state/tests/test_reproduce_state.py b/script/scaffold/templates/reproduce_state/tests/test_reproduce_state.py index ff15625ad7c..83d95570b45 100644 --- a/script/scaffold/templates/reproduce_state/tests/test_reproduce_state.py +++ b/script/scaffold/templates/reproduce_state/tests/test_reproduce_state.py @@ -1,10 +1,14 @@ """Test reproduce state for NEW_NAME.""" -from homeassistant.core import State +import pytest + +from homeassistant.core import HomeAssistant, State from tests.common import async_mock_service -async def test_reproducing_states(hass, caplog): +async def test_reproducing_states( + hass: HomeAssistant, caplog: pytest.LogCaptureFixture +) -> None: """Test reproducing NEW_NAME states.""" hass.states.async_set("NEW_DOMAIN.entity_off", "off", {}) hass.states.async_set("NEW_DOMAIN.entity_on", "on", {"color": "red"})