diff --git a/.github/workflows/builder.yml b/.github/workflows/builder.yml index 168910ae3ac3cb..e8fda93d73c1e5 100644 --- a/.github/workflows/builder.yml +++ b/.github/workflows/builder.yml @@ -326,7 +326,7 @@ jobs: uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Install Cosign - uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 + uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0 with: cosign-release: "v2.2.3" diff --git a/homeassistant/components/eq3btsmart/__init__.py b/homeassistant/components/eq3btsmart/__init__.py index b4be3cf5ee9851..957d17a55d4a9f 100644 --- a/homeassistant/components/eq3btsmart/__init__.py +++ b/homeassistant/components/eq3btsmart/__init__.py @@ -52,7 +52,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: Eq3ConfigEntry) -> bool: f"[{eq3_config.mac_address}] Device could not be found" ) - thermostat = Thermostat(mac_address=device) # type: ignore[arg-type] + thermostat = Thermostat(device) entry.runtime_data = Eq3ConfigEntryData( eq3_config=eq3_config, thermostat=thermostat diff --git a/homeassistant/components/eq3btsmart/manifest.json b/homeassistant/components/eq3btsmart/manifest.json index 7253cd79910f32..1f7d37dd8a614f 100644 --- a/homeassistant/components/eq3btsmart/manifest.json +++ b/homeassistant/components/eq3btsmart/manifest.json @@ -22,5 +22,5 @@ "integration_type": "device", "iot_class": "local_polling", "loggers": ["eq3btsmart"], - "requirements": ["eq3btsmart==2.1.0", "bleak-esphome==3.3.0"] + "requirements": ["eq3btsmart==2.2.0"] } diff --git a/homeassistant/components/imeon_inverter/manifest.json b/homeassistant/components/imeon_inverter/manifest.json index 837b7351241750..ed24d169d63333 100644 --- a/homeassistant/components/imeon_inverter/manifest.json +++ b/homeassistant/components/imeon_inverter/manifest.json @@ -7,7 +7,7 @@ "integration_type": "device", "iot_class": "local_polling", "quality_scale": "bronze", - "requirements": ["imeon_inverter_api==0.3.16"], + "requirements": ["imeon_inverter_api==0.4.0"], "ssdp": [ { "manufacturer": "IMEON", diff --git a/homeassistant/components/openweathermap/config_flow.py b/homeassistant/components/openweathermap/config_flow.py index 76a32af13b09b4..5805b602821505 100644 --- a/homeassistant/components/openweathermap/config_flow.py +++ b/homeassistant/components/openweathermap/config_flow.py @@ -32,6 +32,24 @@ ) from .utils import build_data_and_options, validate_api_key +USER_SCHEMA = vol.Schema( + { + vol.Optional(CONF_NAME, default=DEFAULT_NAME): str, + vol.Optional(CONF_LATITUDE): cv.latitude, + vol.Optional(CONF_LONGITUDE): cv.longitude, + vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): vol.In(LANGUAGES), + vol.Required(CONF_API_KEY): str, + vol.Optional(CONF_MODE, default=DEFAULT_OWM_MODE): vol.In(OWM_MODES), + } +) + +OPTIONS_SCHEMA = vol.Schema( + { + vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): vol.In(LANGUAGES), + vol.Optional(CONF_MODE, default=DEFAULT_OWM_MODE): vol.In(OWM_MODES), + } +) + class OpenWeatherMapConfigFlow(ConfigFlow, domain=DOMAIN): """Config flow for OpenWeatherMap.""" @@ -68,31 +86,21 @@ async def async_step_user(self, user_input=None) -> ConfigFlowResult: return self.async_create_entry( title=user_input[CONF_NAME], data=data, options=options ) + schema_data = user_input + else: + schema_data = { + CONF_LATITUDE: self.hass.config.latitude, + CONF_LONGITUDE: self.hass.config.longitude, + CONF_LANGUAGE: self.hass.config.language, + } description_placeholders["doc_url"] = ( "https://www.home-assistant.io/integrations/openweathermap/" ) - schema = vol.Schema( - { - vol.Required(CONF_API_KEY): str, - vol.Optional(CONF_NAME, default=DEFAULT_NAME): str, - vol.Optional( - CONF_LATITUDE, default=self.hass.config.latitude - ): cv.latitude, - vol.Optional( - CONF_LONGITUDE, default=self.hass.config.longitude - ): cv.longitude, - vol.Optional(CONF_MODE, default=DEFAULT_OWM_MODE): vol.In(OWM_MODES), - vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): vol.In( - LANGUAGES - ), - } - ) - return self.async_show_form( step_id="user", - data_schema=schema, + data_schema=self.add_suggested_values_to_schema(USER_SCHEMA, schema_data), errors=errors, description_placeholders=description_placeholders, ) @@ -108,25 +116,7 @@ async def async_step_init(self, user_input: dict | None = None) -> ConfigFlowRes return self.async_show_form( step_id="init", - data_schema=self._get_options_schema(), - ) - - def _get_options_schema(self): - return vol.Schema( - { - vol.Optional( - CONF_MODE, - default=self.config_entry.options.get( - CONF_MODE, - self.config_entry.data.get(CONF_MODE, DEFAULT_OWM_MODE), - ), - ): vol.In(OWM_MODES), - vol.Optional( - CONF_LANGUAGE, - default=self.config_entry.options.get( - CONF_LANGUAGE, - self.config_entry.data.get(CONF_LANGUAGE, DEFAULT_LANGUAGE), - ), - ): vol.In(LANGUAGES), - } + data_schema=self.add_suggested_values_to_schema( + OPTIONS_SCHEMA, self.config_entry.options + ), ) diff --git a/homeassistant/components/openweathermap/strings.json b/homeassistant/components/openweathermap/strings.json index 51de5cf2244c26..718ce3e6fdd542 100644 --- a/homeassistant/components/openweathermap/strings.json +++ b/homeassistant/components/openweathermap/strings.json @@ -17,6 +17,14 @@ "mode": "[%key:common::config_flow::data::mode%]", "name": "[%key:common::config_flow::data::name%]" }, + "data_description": { + "api_key": "API key for the OpenWeatherMap integration", + "language": "Language for the OpenWeatherMap content", + "latitude": "Latitude of the location", + "longitude": "Longitude of the location", + "mode": "Mode for the OpenWeatherMap API", + "name": "Name for this OpenWeatherMap location" + }, "description": "To generate an API key, please refer to the [integration documentation]({doc_url})" } } @@ -27,6 +35,10 @@ "data": { "language": "[%key:common::config_flow::data::language%]", "mode": "[%key:common::config_flow::data::mode%]" + }, + "data_description": { + "language": "[%key:component::openweathermap::config::step::user::data_description::language%]", + "mode": "[%key:component::openweathermap::config::step::user::data_description::mode%]" } } } diff --git a/pylint/plugins/hass_enforce_type_hints.py b/pylint/plugins/hass_enforce_type_hints.py index 82118209e65496..4b22d1284d7def 100644 --- a/pylint/plugins/hass_enforce_type_hints.py +++ b/pylint/plugins/hass_enforce_type_hints.py @@ -3425,6 +3425,14 @@ def _check_function( # Check that all positional arguments are correctly annotated. if match.arg_types: for key, expected_type in match.arg_types.items(): + if key > len(node.args.args) - 1: + # The number of arguments is less than expected + self.add_message( + "hass-argument-type", + node=node, + args=(key + 1, expected_type, node.name), + ) + continue if node.args.args[key].name in _COMMON_ARGUMENTS: # It has already been checked, avoid double-message continue diff --git a/requirements_all.txt b/requirements_all.txt index 1414463a6919f4..e483dfaf4272b4 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -626,7 +626,6 @@ bimmer-connected[china]==0.17.3 # homeassistant.components.bizkaibus bizkaibus==0.1.1 -# homeassistant.components.eq3btsmart # homeassistant.components.esphome bleak-esphome==3.3.0 @@ -905,7 +904,7 @@ epion==0.0.3 epson-projector==0.5.1 # homeassistant.components.eq3btsmart -eq3btsmart==2.1.0 +eq3btsmart==2.2.0 # homeassistant.components.esphome esphome-dashboard-api==1.3.0 @@ -1244,7 +1243,7 @@ igloohome-api==0.1.1 ihcsdk==2.8.5 # homeassistant.components.imeon_inverter -imeon_inverter_api==0.3.16 +imeon_inverter_api==0.4.0 # homeassistant.components.imgw_pib imgw_pib==1.5.4 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 0f3f2997c6965d..b02e37d9d7374a 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -560,7 +560,6 @@ beautifulsoup4==4.13.3 # homeassistant.components.bmw_connected_drive bimmer-connected[china]==0.17.3 -# homeassistant.components.eq3btsmart # homeassistant.components.esphome bleak-esphome==3.3.0 @@ -787,7 +786,7 @@ epion==0.0.3 epson-projector==0.5.1 # homeassistant.components.eq3btsmart -eq3btsmart==2.1.0 +eq3btsmart==2.2.0 # homeassistant.components.esphome esphome-dashboard-api==1.3.0 @@ -1078,7 +1077,7 @@ ifaddr==0.2.0 igloohome-api==0.1.1 # homeassistant.components.imeon_inverter -imeon_inverter_api==0.3.16 +imeon_inverter_api==0.4.0 # homeassistant.components.imgw_pib imgw_pib==1.5.4 diff --git a/tests/components/zha/conftest.py b/tests/components/zha/conftest.py index df61fb499d23b0..189d7da74374ad 100644 --- a/tests/components/zha/conftest.py +++ b/tests/components/zha/conftest.py @@ -1,6 +1,6 @@ """Test configuration for the ZHA component.""" -from collections.abc import Generator +from collections.abc import Callable, Coroutine, Generator import itertools import time from typing import Any @@ -241,11 +241,11 @@ def setup_zha( hass: HomeAssistant, config_entry: MockConfigEntry, mock_zigpy_connect: ControllerApplication, -): +) -> Callable[..., Coroutine[None]]: """Set up ZHA component.""" zha_config = {zha_const.CONF_ENABLE_QUIRKS: False} - async def _setup(config=None): + async def _setup(config=None) -> None: config_entry.add_to_hass(hass) config = config or {} @@ -353,7 +353,7 @@ def network_backup() -> zigpy.backups.NetworkBackup: @pytest.fixture -def zigpy_device_mock(zigpy_app_controller): +def zigpy_device_mock(zigpy_app_controller) -> Callable[..., zigpy.device.Device]: """Make a fake device using the specified cluster classes.""" def _mock_dev( diff --git a/tests/components/zha/test_alarm_control_panel.py b/tests/components/zha/test_alarm_control_panel.py index 609438cd7250fd..9f4373557c2546 100644 --- a/tests/components/zha/test_alarm_control_panel.py +++ b/tests/components/zha/test_alarm_control_panel.py @@ -1,8 +1,10 @@ """Test ZHA alarm control panel.""" +from collections.abc import Callable, Coroutine from unittest.mock import AsyncMock, call, patch, sentinel import pytest +from zigpy.device import Device from zigpy.profiles import zha from zigpy.zcl import Cluster from zigpy.zcl.clusters import security @@ -45,7 +47,9 @@ def alarm_control_panel_platform_only(): new=AsyncMock(return_value=[sentinel.data, zcl_f.Status.SUCCESS]), ) async def test_alarm_control_panel( - hass: HomeAssistant, setup_zha, zigpy_device_mock + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], ) -> None: """Test ZHA alarm control panel platform.""" diff --git a/tests/components/zha/test_api.py b/tests/components/zha/test_api.py index 7aff6d81f5d790..f2eca7207c434e 100644 --- a/tests/components/zha/test_api.py +++ b/tests/components/zha/test_api.py @@ -2,6 +2,7 @@ from __future__ import annotations +from collections.abc import Callable, Coroutine from typing import TYPE_CHECKING from unittest.mock import AsyncMock, MagicMock, call, patch @@ -26,7 +27,7 @@ def required_platform_only(): async def test_async_get_network_settings_active( - hass: HomeAssistant, setup_zha + hass: HomeAssistant, setup_zha: Callable[..., Coroutine[None]] ) -> None: """Test reading settings with an active ZHA installation.""" await setup_zha() @@ -36,7 +37,9 @@ async def test_async_get_network_settings_active( async def test_async_get_network_settings_inactive( - hass: HomeAssistant, setup_zha, zigpy_app_controller: ControllerApplication + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_app_controller: ControllerApplication, ) -> None: """Test reading settings with an inactive ZHA installation.""" await setup_zha() @@ -63,7 +66,9 @@ async def test_async_get_network_settings_inactive( async def test_async_get_network_settings_missing( - hass: HomeAssistant, setup_zha, zigpy_app_controller: ControllerApplication + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_app_controller: ControllerApplication, ) -> None: """Test reading settings with an inactive ZHA installation, no valid channel.""" await setup_zha() @@ -86,7 +91,9 @@ async def test_async_get_network_settings_failure(hass: HomeAssistant) -> None: await api.async_get_network_settings(hass) -async def test_async_get_radio_type_active(hass: HomeAssistant, setup_zha) -> None: +async def test_async_get_radio_type_active( + hass: HomeAssistant, setup_zha: Callable[..., Coroutine[None]] +) -> None: """Test reading the radio type with an active ZHA installation.""" await setup_zha() @@ -94,7 +101,9 @@ async def test_async_get_radio_type_active(hass: HomeAssistant, setup_zha) -> No assert radio_type == RadioType.ezsp -async def test_async_get_radio_path_active(hass: HomeAssistant, setup_zha) -> None: +async def test_async_get_radio_path_active( + hass: HomeAssistant, setup_zha: Callable[..., Coroutine[None]] +) -> None: """Test reading the radio path with an active ZHA installation.""" await setup_zha() @@ -103,7 +112,9 @@ async def test_async_get_radio_path_active(hass: HomeAssistant, setup_zha) -> No async def test_change_channel( - hass: HomeAssistant, setup_zha, zigpy_app_controller: ControllerApplication + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_app_controller: ControllerApplication, ) -> None: """Test changing the channel.""" await setup_zha() @@ -113,7 +124,9 @@ async def test_change_channel( async def test_change_channel_auto( - hass: HomeAssistant, setup_zha, zigpy_app_controller: ControllerApplication + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_app_controller: ControllerApplication, ) -> None: """Test changing the channel automatically using an energy scan.""" await setup_zha() diff --git a/tests/components/zha/test_backup.py b/tests/components/zha/test_backup.py index dc6c5dc29cb157..f477364616a474 100644 --- a/tests/components/zha/test_backup.py +++ b/tests/components/zha/test_backup.py @@ -1,5 +1,6 @@ """Unit tests for ZHA backup platform.""" +from collections.abc import Callable, Coroutine from unittest.mock import AsyncMock, patch from zigpy.application import ControllerApplication @@ -9,7 +10,9 @@ async def test_pre_backup( - hass: HomeAssistant, zigpy_app_controller: ControllerApplication, setup_zha + hass: HomeAssistant, + zigpy_app_controller: ControllerApplication, + setup_zha: Callable[..., Coroutine[None]], ) -> None: """Test backup creation when `async_pre_backup` is called.""" await setup_zha() @@ -23,13 +26,17 @@ async def test_pre_backup( @patch("homeassistant.components.zha.backup.get_zha_gateway", side_effect=ValueError()) -async def test_pre_backup_no_gateway(hass: HomeAssistant, setup_zha) -> None: +async def test_pre_backup_no_gateway( + hass: HomeAssistant, setup_zha: Callable[..., Coroutine[None]] +) -> None: """Test graceful backup failure when no gateway exists.""" await setup_zha() await async_pre_backup(hass) -async def test_post_backup(hass: HomeAssistant, setup_zha) -> None: +async def test_post_backup( + hass: HomeAssistant, setup_zha: Callable[..., Coroutine[None]] +) -> None: """Test no-op `async_post_backup`.""" await setup_zha() await async_post_backup(hass) diff --git a/tests/components/zha/test_binary_sensor.py b/tests/components/zha/test_binary_sensor.py index a9765a1b547792..a912b9179e0f77 100644 --- a/tests/components/zha/test_binary_sensor.py +++ b/tests/components/zha/test_binary_sensor.py @@ -1,8 +1,10 @@ """Test ZHA binary sensor.""" +from collections.abc import Callable, Coroutine from unittest.mock import patch import pytest +from zigpy.device import Device from zigpy.profiles import zha from zigpy.zcl.clusters import general @@ -39,8 +41,8 @@ def binary_sensor_platform_only(): async def test_binary_sensor( hass: HomeAssistant, entity_registry: er.EntityRegistry, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], ) -> None: """Test ZHA binary_sensor platform.""" await setup_zha() diff --git a/tests/components/zha/test_button.py b/tests/components/zha/test_button.py index 33ed004312b9af..8c41a914f5a62c 100644 --- a/tests/components/zha/test_button.py +++ b/tests/components/zha/test_button.py @@ -1,10 +1,12 @@ """Test ZHA button.""" +from collections.abc import Callable, Coroutine from unittest.mock import patch from freezegun import freeze_time import pytest from zigpy.const import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE +from zigpy.device import Device from zigpy.profiles import zha from zigpy.zcl.clusters import general import zigpy.zcl.foundation as zcl_f @@ -44,7 +46,9 @@ def button_platform_only(): @pytest.fixture -async def setup_zha_integration(hass: HomeAssistant, setup_zha): +async def setup_zha_integration( + hass: HomeAssistant, setup_zha: Callable[..., Coroutine[None]] +): """Set up ZHA component.""" # if we call this in the test itself the test hangs forever @@ -56,7 +60,7 @@ async def test_button( hass: HomeAssistant, entity_registry: er.EntityRegistry, setup_zha_integration, # pylint: disable=unused-argument - zigpy_device_mock, + zigpy_device_mock: Callable[..., Device], ) -> None: """Test ZHA button platform.""" diff --git a/tests/components/zha/test_climate.py b/tests/components/zha/test_climate.py index 3425c1eb2b65be..27d99ddc320b55 100644 --- a/tests/components/zha/test_climate.py +++ b/tests/components/zha/test_climate.py @@ -1,5 +1,6 @@ """Test ZHA climate.""" +from collections.abc import Callable, Coroutine from typing import Literal from unittest.mock import patch @@ -7,6 +8,7 @@ from zha.application.platforms.climate.const import HVAC_MODE_2_SYSTEM, SEQ_OF_OPERATION import zhaquirks.sinope.thermostat import zhaquirks.tuya.ts0601_trv +from zigpy.device import Device import zigpy.profiles from zigpy.profiles import zha import zigpy.types @@ -147,7 +149,11 @@ def climate_platform_only(): @pytest.fixture -def device_climate_mock(hass: HomeAssistant, setup_zha, zigpy_device_mock): +def device_climate_mock( + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], +): """Test regular thermostat device.""" async def _dev(clusters, plug=None, manuf=None, quirk=None): diff --git a/tests/components/zha/test_cover.py b/tests/components/zha/test_cover.py index 70fdac2c313c58..133a7fe612b30b 100644 --- a/tests/components/zha/test_cover.py +++ b/tests/components/zha/test_cover.py @@ -1,8 +1,10 @@ """Test ZHA cover.""" +from collections.abc import Callable, Coroutine from unittest.mock import patch import pytest +from zigpy.device import Device from zigpy.profiles import zha from zigpy.zcl.clusters import closures import zigpy.zcl.foundation as zcl_f @@ -60,7 +62,11 @@ def cover_platform_only(): WCCS = closures.WindowCovering.ConfigStatus -async def test_cover(hass: HomeAssistant, setup_zha, zigpy_device_mock) -> None: +async def test_cover( + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], +) -> None: """Test ZHA cover platform.""" await setup_zha() @@ -327,7 +333,9 @@ async def test_cover(hass: HomeAssistant, setup_zha, zigpy_device_mock) -> None: async def test_cover_failures( - hass: HomeAssistant, setup_zha, zigpy_device_mock + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], ) -> None: """Test ZHA cover platform failure cases.""" await setup_zha() diff --git a/tests/components/zha/test_device_action.py b/tests/components/zha/test_device_action.py index becf9d8155732e..0ebee66fb9ae2b 100644 --- a/tests/components/zha/test_device_action.py +++ b/tests/components/zha/test_device_action.py @@ -1,9 +1,11 @@ """The test for ZHA device automation actions.""" +from collections.abc import Callable, Coroutine from unittest.mock import patch import pytest from pytest_unordered import unordered +from zigpy.device import Device from zigpy.profiles import zha from zigpy.zcl.clusters import general, security import zigpy.zcl.foundation as zcl_f @@ -56,8 +58,8 @@ async def test_get_actions( hass: HomeAssistant, device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], ) -> None: """Test we get the expected actions from a ZHA device.""" @@ -142,8 +144,8 @@ async def test_get_actions( async def test_action( hass: HomeAssistant, device_registry: dr.DeviceRegistry, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], ) -> None: """Test for executing a ZHA device action.""" await setup_zha() @@ -221,7 +223,9 @@ async def test_action( async def test_invalid_zha_event_type( - hass: HomeAssistant, setup_zha, zigpy_device_mock + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], ) -> None: """Test that unexpected types are not passed to `zha_send_event`.""" await setup_zha() @@ -261,7 +265,9 @@ async def test_invalid_zha_event_type( async def test_client_unique_id_suffix_stripped( - hass: HomeAssistant, setup_zha, zigpy_device_mock + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], ) -> None: """Test that the `_CLIENT_` unique ID suffix is stripped.""" assert await async_setup_component( diff --git a/tests/components/zha/test_device_tracker.py b/tests/components/zha/test_device_tracker.py index 8a587966f811ca..bb94bebc35b107 100644 --- a/tests/components/zha/test_device_tracker.py +++ b/tests/components/zha/test_device_tracker.py @@ -1,11 +1,13 @@ """Test ZHA Device Tracker.""" +from collections.abc import Callable, Coroutine from datetime import timedelta import time from unittest.mock import patch import pytest from zha.application.registries import SMARTTHINGS_ARRIVAL_SENSOR_DEVICE_TYPE +from zigpy.device import Device from zigpy.profiles import zha from zigpy.zcl.clusters import general @@ -44,7 +46,9 @@ def device_tracker_platforms_only(): async def test_device_tracker( - hass: HomeAssistant, setup_zha, zigpy_device_mock + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], ) -> None: """Test ZHA device tracker platform.""" diff --git a/tests/components/zha/test_device_trigger.py b/tests/components/zha/test_device_trigger.py index ace3029dac9662..d0b6eec62bf38c 100644 --- a/tests/components/zha/test_device_trigger.py +++ b/tests/components/zha/test_device_trigger.py @@ -1,5 +1,6 @@ """ZHA device automation trigger tests.""" +from collections.abc import Callable, Coroutine from unittest.mock import patch import pytest @@ -59,7 +60,7 @@ def _same_lists(list_a, list_b): async def test_triggers( hass: HomeAssistant, device_registry: dr.DeviceRegistry, - setup_zha, + setup_zha: Callable[..., Coroutine[None]], ) -> None: """Test ZHA device triggers.""" @@ -145,7 +146,9 @@ async def test_triggers( async def test_no_triggers( - hass: HomeAssistant, device_registry: dr.DeviceRegistry, setup_zha + hass: HomeAssistant, + device_registry: dr.DeviceRegistry, + setup_zha: Callable[..., Coroutine[None]], ) -> None: """Test ZHA device with no triggers.""" await setup_zha() @@ -185,7 +188,7 @@ async def test_if_fires_on_event( hass: HomeAssistant, device_registry: dr.DeviceRegistry, service_calls: list[ServiceCall], - setup_zha, + setup_zha: Callable[..., Coroutine[None]], ) -> None: """Test for remote triggers firing.""" @@ -261,7 +264,7 @@ async def test_device_offline_fires( hass: HomeAssistant, device_registry: dr.DeviceRegistry, service_calls: list[ServiceCall], - setup_zha, + setup_zha: Callable[..., Coroutine[None]], ) -> None: """Test for device offline triggers firing.""" @@ -317,7 +320,7 @@ async def test_exception_no_triggers( hass: HomeAssistant, device_registry: dr.DeviceRegistry, caplog: pytest.LogCaptureFixture, - setup_zha, + setup_zha: Callable[..., Coroutine[None]], ) -> None: """Test for exception when validating device triggers.""" @@ -370,7 +373,7 @@ async def test_exception_bad_trigger( hass: HomeAssistant, device_registry: dr.DeviceRegistry, caplog: pytest.LogCaptureFixture, - setup_zha, + setup_zha: Callable[..., Coroutine[None]], ) -> None: """Test for exception when validating device triggers.""" @@ -431,7 +434,7 @@ async def test_validate_trigger_config_missing_info( device_registry: dr.DeviceRegistry, config_entry: MockConfigEntry, caplog: pytest.LogCaptureFixture, - setup_zha, + setup_zha: Callable[..., Coroutine[None]], ) -> None: """Test device triggers referring to a missing device.""" @@ -499,7 +502,7 @@ async def test_validate_trigger_config_unloaded_bad_info( config_entry: MockConfigEntry, caplog: pytest.LogCaptureFixture, zigpy_app_controller: ControllerApplication, - setup_zha, + setup_zha: Callable[..., Coroutine[None]], ) -> None: """Test device triggers referring to a missing device.""" diff --git a/tests/components/zha/test_diagnostics.py b/tests/components/zha/test_diagnostics.py index d32dd19152711d..bc438dff285f97 100644 --- a/tests/components/zha/test_diagnostics.py +++ b/tests/components/zha/test_diagnostics.py @@ -1,10 +1,12 @@ """Tests for the diagnostics data provided by the ESPHome integration.""" +from collections.abc import Callable, Coroutine from unittest.mock import patch import pytest from syrupy.assertion import SnapshotAssertion from syrupy.filters import props +from zigpy.device import Device from zigpy.profiles import zha from zigpy.types import EUI64, NWK from zigpy.zcl.clusters import security @@ -42,8 +44,8 @@ async def test_diagnostics_for_config_entry( hass: HomeAssistant, hass_client: ClientSessionGenerator, config_entry: MockConfigEntry, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], snapshot: SnapshotAssertion, ) -> None: """Test diagnostics for config entry.""" @@ -90,8 +92,8 @@ async def test_diagnostics_for_device( hass_client: ClientSessionGenerator, device_registry: dr.DeviceRegistry, config_entry: MockConfigEntry, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], snapshot: SnapshotAssertion, ) -> None: """Test diagnostics for device.""" diff --git a/tests/components/zha/test_entity.py b/tests/components/zha/test_entity.py index add98bb96bfd93..eac987a070e5e2 100644 --- a/tests/components/zha/test_entity.py +++ b/tests/components/zha/test_entity.py @@ -1,5 +1,8 @@ """Test ZHA entities.""" +from collections.abc import Callable, Coroutine + +from zigpy.device import Device from zigpy.profiles import zha from zigpy.zcl.clusters import general @@ -12,8 +15,8 @@ async def test_device_registry_via_device( hass: HomeAssistant, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], device_registry: dr.DeviceRegistry, ) -> None: """Test ZHA `via_device` is set correctly.""" diff --git a/tests/components/zha/test_fan.py b/tests/components/zha/test_fan.py index 0105c569653d03..1bd5325dc9228e 100644 --- a/tests/components/zha/test_fan.py +++ b/tests/components/zha/test_fan.py @@ -1,9 +1,11 @@ """Test ZHA fan.""" +from collections.abc import Callable, Coroutine from unittest.mock import call, patch import pytest from zha.application.platforms.fan.const import PRESET_MODE_ON +from zigpy.device import Device from zigpy.profiles import zha from zigpy.zcl.clusters import general, hvac @@ -58,7 +60,11 @@ def fan_platform_only(): yield -async def test_fan(hass: HomeAssistant, setup_zha, zigpy_device_mock) -> None: +async def test_fan( + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], +) -> None: """Test ZHA fan platform.""" await setup_zha() diff --git a/tests/components/zha/test_init.py b/tests/components/zha/test_init.py index 66a01e0acace47..8020e2d365fd5c 100644 --- a/tests/components/zha/test_init.py +++ b/tests/components/zha/test_init.py @@ -1,6 +1,7 @@ """Tests for ZHA integration init.""" import asyncio +from collections.abc import Callable import typing from unittest.mock import AsyncMock, Mock, patch import zoneinfo @@ -8,6 +9,7 @@ import pytest from zigpy.application import ControllerApplication from zigpy.config import CONF_DEVICE, CONF_DEVICE_PATH +from zigpy.device import Device from zigpy.exceptions import TransientConnectionError from homeassistant.components.zha.const import ( @@ -231,7 +233,7 @@ async def test_migration_baudrate_and_flow_control( async def test_zha_retry_unique_ids( hass: HomeAssistant, config_entry: MockConfigEntry, - zigpy_device_mock, + zigpy_device_mock: Callable[..., Device], mock_zigpy_connect: ControllerApplication, caplog: pytest.LogCaptureFixture, ) -> None: diff --git a/tests/components/zha/test_light.py b/tests/components/zha/test_light.py index ef2714b3b58599..59bd5d4cdd51af 100644 --- a/tests/components/zha/test_light.py +++ b/tests/components/zha/test_light.py @@ -1,9 +1,11 @@ """Test ZHA light.""" +from collections.abc import Callable, Coroutine from unittest.mock import AsyncMock, call, patch, sentinel import pytest from zha.application.platforms.light.const import FLASH_EFFECTS +from zigpy.device import Device from zigpy.profiles import zha from zigpy.zcl import Cluster from zigpy.zcl.clusters import general, lighting @@ -114,8 +116,8 @@ def light_platform_only(): ) async def test_light( hass: HomeAssistant, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], device, reporting, ) -> None: @@ -193,7 +195,9 @@ async def test_light( new=AsyncMock(return_value=[sentinel.data, zcl_f.Status.SUCCESS]), ) async def test_on_with_off_color( - hass: HomeAssistant, setup_zha, zigpy_device_mock + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], ) -> None: """Test turning on the light and sending color commands before on/level commands for supporting lights.""" @@ -576,8 +580,8 @@ async def async_test_flash_from_hass( ) async def test_light_exception_on_creation( hass: HomeAssistant, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], caplog: pytest.LogCaptureFixture, ) -> None: """Test ZHA light entity creation exception.""" diff --git a/tests/components/zha/test_lock.py b/tests/components/zha/test_lock.py index dd4afb0ae14752..1fa893d34d4c2a 100644 --- a/tests/components/zha/test_lock.py +++ b/tests/components/zha/test_lock.py @@ -1,8 +1,10 @@ """Test ZHA lock.""" +from collections.abc import Callable, Coroutine from unittest.mock import patch import pytest +from zigpy.device import Device from zigpy.profiles import zha from zigpy.zcl import Cluster from zigpy.zcl.clusters import closures, general @@ -36,7 +38,11 @@ def lock_platform_only(): yield -async def test_lock(hass: HomeAssistant, setup_zha, zigpy_device_mock) -> None: +async def test_lock( + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], +) -> None: """Test ZHA lock platform.""" await setup_zha() diff --git a/tests/components/zha/test_logbook.py b/tests/components/zha/test_logbook.py index 6119bbec7699d0..1eb7ce0e01d70b 100644 --- a/tests/components/zha/test_logbook.py +++ b/tests/components/zha/test_logbook.py @@ -1,9 +1,11 @@ """ZHA logbook describe events tests.""" +from collections.abc import Callable, Coroutine from unittest.mock import patch import pytest from zha.application.const import ZHA_EVENT +from zigpy.device import Device import zigpy.profiles.zha from zigpy.zcl.clusters import general @@ -46,7 +48,11 @@ def sensor_platform_only(): @pytest.fixture -async def mock_devices(hass: HomeAssistant, setup_zha, zigpy_device_mock): +async def mock_devices( + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], +): """IAS device fixture.""" await setup_zha() diff --git a/tests/components/zha/test_number.py b/tests/components/zha/test_number.py index 91f5e32942f509..511394161e35d9 100644 --- a/tests/components/zha/test_number.py +++ b/tests/components/zha/test_number.py @@ -1,8 +1,10 @@ """Test ZHA analog output.""" +from collections.abc import Callable, Coroutine from unittest.mock import call, patch import pytest +from zigpy.device import Device from zigpy.profiles import zha from zigpy.zcl.clusters import general import zigpy.zcl.foundation as zcl_f @@ -39,7 +41,11 @@ def number_platform_only(): yield -async def test_number(hass: HomeAssistant, setup_zha, zigpy_device_mock) -> None: +async def test_number( + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], +) -> None: """Test ZHA number platform.""" await setup_zha() diff --git a/tests/components/zha/test_select.py b/tests/components/zha/test_select.py index f0f742503e31fb..fec02a68afead5 100644 --- a/tests/components/zha/test_select.py +++ b/tests/components/zha/test_select.py @@ -1,9 +1,11 @@ """Test ZHA select entities.""" +from collections.abc import Callable, Coroutine from unittest.mock import patch import pytest from zigpy.const import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE +from zigpy.device import Device from zigpy.profiles import zha from zigpy.zcl.clusters import general, security @@ -49,8 +51,8 @@ def select_select_only(): async def test_select( hass: HomeAssistant, entity_registry: er.EntityRegistry, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], ) -> None: """Test ZHA select platform.""" @@ -127,8 +129,8 @@ async def test_select( async def test_select_restore_state( hass: HomeAssistant, entity_registry: er.EntityRegistry, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], restored_state: str, expected_state: str, ) -> None: diff --git a/tests/components/zha/test_sensor.py b/tests/components/zha/test_sensor.py index 2e6b9e8bd6a31e..e7c0410e958bd0 100644 --- a/tests/components/zha/test_sensor.py +++ b/tests/components/zha/test_sensor.py @@ -1,8 +1,10 @@ """Test ZHA sensor.""" +from collections.abc import Callable, Coroutine from unittest.mock import patch import pytest +from zigpy.device import Device from zigpy.profiles import zha from zigpy.zcl import Cluster from zigpy.zcl.clusters import general, homeautomation, hvac, measurement, smartenergy @@ -519,8 +521,8 @@ async def async_test_pi_heating_demand( ) async def test_sensor( hass: HomeAssistant, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], cluster_id, entity_suffix, test_func, diff --git a/tests/components/zha/test_silabs_multiprotocol.py b/tests/components/zha/test_silabs_multiprotocol.py index a5f2db22ce5acd..83abb0f8b92f4b 100644 --- a/tests/components/zha/test_silabs_multiprotocol.py +++ b/tests/components/zha/test_silabs_multiprotocol.py @@ -2,6 +2,7 @@ from __future__ import annotations +from collections.abc import Callable, Coroutine from typing import TYPE_CHECKING from unittest.mock import call, patch @@ -25,7 +26,9 @@ def required_platform_only(): yield -async def test_async_get_channel_active(hass: HomeAssistant, setup_zha) -> None: +async def test_async_get_channel_active( + hass: HomeAssistant, setup_zha: Callable[..., Coroutine[None]] +) -> None: """Test reading channel with an active ZHA installation.""" await setup_zha() @@ -33,7 +36,9 @@ async def test_async_get_channel_active(hass: HomeAssistant, setup_zha) -> None: async def test_async_get_channel_missing( - hass: HomeAssistant, setup_zha, zigpy_app_controller: ControllerApplication + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_app_controller: ControllerApplication, ) -> None: """Test reading channel with an inactive ZHA installation, no valid channel.""" await setup_zha() @@ -52,7 +57,9 @@ async def test_async_get_channel_no_zha(hass: HomeAssistant) -> None: assert await silabs_multiprotocol.async_get_channel(hass) is None -async def test_async_using_multipan_active(hass: HomeAssistant, setup_zha) -> None: +async def test_async_using_multipan_active( + hass: HomeAssistant, setup_zha: Callable[..., Coroutine[None]] +) -> None: """Test async_using_multipan with an active ZHA installation.""" await setup_zha() @@ -65,7 +72,9 @@ async def test_async_using_multipan_no_zha(hass: HomeAssistant) -> None: async def test_change_channel( - hass: HomeAssistant, setup_zha, zigpy_app_controller: ControllerApplication + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_app_controller: ControllerApplication, ) -> None: """Test changing the channel.""" await setup_zha() @@ -89,7 +98,7 @@ async def test_change_channel_no_zha( @pytest.mark.parametrize(("delay", "sleep"), [(0, 0), (5, 0), (15, 15 - 10.27)]) async def test_change_channel_delay( hass: HomeAssistant, - setup_zha, + setup_zha: Callable[..., Coroutine[None]], zigpy_app_controller: ControllerApplication, delay: float, sleep: float, diff --git a/tests/components/zha/test_siren.py b/tests/components/zha/test_siren.py index 5849cc6f233c82..564fd4db0fb29f 100644 --- a/tests/components/zha/test_siren.py +++ b/tests/components/zha/test_siren.py @@ -1,5 +1,6 @@ """Test zha siren.""" +from collections.abc import Callable, Coroutine from datetime import timedelta from unittest.mock import ANY, call, patch @@ -9,6 +10,7 @@ WARNING_DEVICE_SOUND_MEDIUM, ) from zigpy.const import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE +from zigpy.device import Device from zigpy.profiles import zha import zigpy.zcl from zigpy.zcl.clusters import general, security @@ -51,7 +53,11 @@ def siren_platform_only(): yield -async def test_siren(hass: HomeAssistant, setup_zha, zigpy_device_mock) -> None: +async def test_siren( + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], +) -> None: """Test zha siren platform.""" await setup_zha() diff --git a/tests/components/zha/test_switch.py b/tests/components/zha/test_switch.py index cc4e41485f9d88..ca9e1345d3d1a2 100644 --- a/tests/components/zha/test_switch.py +++ b/tests/components/zha/test_switch.py @@ -1,8 +1,10 @@ """Test ZHA switch.""" +from collections.abc import Callable, Coroutine from unittest.mock import call, patch import pytest +from zigpy.device import Device from zigpy.profiles import zha from zigpy.zcl.clusters import general import zigpy.zcl.foundation as zcl_f @@ -40,7 +42,11 @@ def switch_platform_only(): yield -async def test_switch(hass: HomeAssistant, setup_zha, zigpy_device_mock) -> None: +async def test_switch( + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], +) -> None: """Test ZHA switch platform.""" await setup_zha() diff --git a/tests/components/zha/test_update.py b/tests/components/zha/test_update.py index 6371902a639e9d..3d4ea96373c8b5 100644 --- a/tests/components/zha/test_update.py +++ b/tests/components/zha/test_update.py @@ -1,11 +1,13 @@ """Test ZHA firmware updates.""" +from collections.abc import Callable, Coroutine from unittest.mock import AsyncMock, PropertyMock, call, patch import pytest from zha.application.platforms.update import ( FirmwareUpdateEntity as ZhaFirmwareUpdateEntity, ) +from zigpy.device import Device from zigpy.exceptions import DeliveryError from zigpy.ota import OtaImagesResult, OtaImageWithMetadata import zigpy.ota.image as firmware @@ -73,7 +75,7 @@ def update_platform_only(): async def setup_test_data( hass: HomeAssistant, - zigpy_device_mock, + zigpy_device_mock: Callable[..., Device], skip_attribute_plugs=False, file_not_found=False, ): @@ -163,8 +165,8 @@ async def setup_test_data( async def test_firmware_update_notification_from_zigpy( hass: HomeAssistant, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], ) -> None: """Test ZHA update platform - firmware update notification.""" await setup_zha() @@ -206,8 +208,8 @@ async def test_firmware_update_notification_from_zigpy( async def test_firmware_update_notification_from_service_call( hass: HomeAssistant, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], ) -> None: """Test ZHA update platform - firmware update manual check.""" await setup_zha() @@ -294,8 +296,8 @@ def make_packet(zigpy_device, cluster, cmd_name: str, **kwargs): @patch("zigpy.device.AFTER_OTA_ATTR_READ_DELAY", 0.01) async def test_firmware_update_success( hass: HomeAssistant, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], ) -> None: """Test ZHA update platform - firmware update success.""" await setup_zha() @@ -491,8 +493,8 @@ def read_new_fw_version(*args, **kwargs): async def test_firmware_update_raises( hass: HomeAssistant, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], ) -> None: """Test ZHA update platform - firmware update raises.""" await setup_zha() @@ -587,8 +589,8 @@ async def endpoint_reply(cluster, sequence, data, **kwargs): async def test_update_release_notes( hass: HomeAssistant, hass_ws_client: WebSocketGenerator, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], ) -> None: """Test ZHA update platform release notes.""" await setup_zha() @@ -647,8 +649,8 @@ async def test_update_release_notes( async def test_update_version_sync_device_registry( hass: HomeAssistant, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], device_registry: dr.DeviceRegistry, ) -> None: """Test firmware version syncing between the ZHA device and Home Assistant.""" diff --git a/tests/components/zha/test_websocket_api.py b/tests/components/zha/test_websocket_api.py index ae1ea90d1f9fcf..df945b8afc2bb7 100644 --- a/tests/components/zha/test_websocket_api.py +++ b/tests/components/zha/test_websocket_api.py @@ -3,6 +3,7 @@ from __future__ import annotations from binascii import unhexlify +from collections.abc import Callable, Coroutine from copy import deepcopy from typing import TYPE_CHECKING from unittest.mock import ANY, AsyncMock, MagicMock, call, patch @@ -23,7 +24,7 @@ CLUSTER_TYPE_IN, ) from zha.zigbee.cluster_handlers import ClusterBindEvent, ClusterConfigureReportingEvent -from zha.zigbee.device import ClusterHandlerConfigurationComplete +from zha.zigbee.device import ClusterHandlerConfigurationComplete, Device import zigpy.backups from zigpy.const import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE import zigpy.profiles.zha @@ -97,8 +98,8 @@ def required_platform_only(): async def zha_client( hass: HomeAssistant, hass_ws_client: WebSocketGenerator, - setup_zha, - zigpy_device_mock, + setup_zha: Callable[..., Coroutine[None]], + zigpy_device_mock: Callable[..., Device], ) -> MockHAClientWebSocket: """Get ZHA WebSocket client.""" @@ -261,7 +262,9 @@ async def test_get_zha_config(zha_client) -> None: async def test_get_zha_config_with_alarm( - hass: HomeAssistant, zha_client, zigpy_device_mock + hass: HomeAssistant, + zha_client, + zigpy_device_mock: Callable[..., Device], ) -> None: """Test getting ZHA custom configuration.""" @@ -596,7 +599,9 @@ async def test_remove_group_member(hass: HomeAssistant, zha_client) -> None: @pytest.fixture async def app_controller( - hass: HomeAssistant, setup_zha, zigpy_app_controller: ControllerApplication + hass: HomeAssistant, + setup_zha: Callable[..., Coroutine[None]], + zigpy_app_controller: ControllerApplication, ) -> ControllerApplication: """Fixture for zigpy Application Controller.""" await setup_zha() @@ -1138,7 +1143,9 @@ async def test_websocket_bind_unbind_group( async def test_websocket_reconfigure( - hass: HomeAssistant, zha_client: MockHAClientWebSocket, zigpy_device_mock + hass: HomeAssistant, + zha_client: MockHAClientWebSocket, + zigpy_device_mock: Callable[..., Device], ) -> None: """Test websocket API to reconfigure a device.""" gateway = get_zha_gateway(hass) diff --git a/tests/pylint/test_enforce_type_hints.py b/tests/pylint/test_enforce_type_hints.py index 41605bf2f2ba72..fac9cf0785c502 100644 --- a/tests/pylint/test_enforce_type_hints.py +++ b/tests/pylint/test_enforce_type_hints.py @@ -1497,3 +1497,39 @@ async def async_setup_entry( #@ ), ): type_hint_checker.visit_asyncfunctiondef(func_node) + + +def test_missing_argument( + linter: UnittestLinter, + type_hint_checker: BaseChecker, +) -> None: + """Ensure missing arg raises an error.""" + func_node = astroid.extract_node( + """ + async def async_setup_entry( #@ + hass: HomeAssistant, + entry: ConfigEntry, + ) -> None: + pass + """, + "homeassistant.components.pylint_test.sensor", + ) + type_hint_checker.visit_module(func_node.parent) + + with assert_adds_messages( + linter, + pylint.testutils.MessageTest( + msg_id="hass-argument-type", + node=func_node, + args=( + 3, + "AddConfigEntryEntitiesCallback", + "async_setup_entry", + ), + line=2, + col_offset=0, + end_line=2, + end_col_offset=27, + ), + ): + type_hint_checker.visit_asyncfunctiondef(func_node)