diff --git a/homeassistant/config_entries.py b/homeassistant/config_entries.py index a96716ff84b..b1a4a8ce6cc 100644 --- a/homeassistant/config_entries.py +++ b/homeassistant/config_entries.py @@ -245,7 +245,11 @@ UPDATE_ENTRY_CONFIG_ENTRY_ATTRS = { } -ConfigFlowResult = FlowResult +class ConfigFlowResult(FlowResult, total=False): + """Typed result dict for config flow.""" + + minor_version: int + version: int class ConfigEntry: diff --git a/homeassistant/data_entry_flow.py b/homeassistant/data_entry_flow.py index b573f528945..526b859d29c 100644 --- a/homeassistant/data_entry_flow.py +++ b/homeassistant/data_entry_flow.py @@ -151,7 +151,6 @@ class FlowResult(TypedDict, total=False): handler: Required[str] last_step: bool | None menu_options: list[str] | dict[str, str] - minor_version: int options: Mapping[str, Any] preview: str | None progress_action: str @@ -164,7 +163,6 @@ class FlowResult(TypedDict, total=False): translation_domain: str type: FlowResultType url: str - version: int def _map_error_to_schema_errors( diff --git a/pylint/plugins/hass_enforce_type_hints.py b/pylint/plugins/hass_enforce_type_hints.py index 602bd8a443d..c3c74c95c84 100644 --- a/pylint/plugins/hass_enforce_type_hints.py +++ b/pylint/plugins/hass_enforce_type_hints.py @@ -494,11 +494,6 @@ _CLASS_MATCH: dict[str, list[ClassTypeHintMatch]] = { ClassTypeHintMatch( base_class="ConfigFlow", matches=[ - TypeHintMatch( - function_name="async_step123_*", - arg_types={}, - return_type=["ConfigFlowResult", "FlowResult"], - ), TypeHintMatch( function_name="async_get_options_flow", arg_types={ @@ -511,56 +506,61 @@ _CLASS_MATCH: dict[str, list[ClassTypeHintMatch]] = { arg_types={ 1: "DhcpServiceInfo", }, - return_type=["ConfigFlowResult", "FlowResult"], + return_type="ConfigFlowResult", ), TypeHintMatch( function_name="async_step_hassio", arg_types={ 1: "HassioServiceInfo", }, - return_type=["ConfigFlowResult", "FlowResult"], + return_type="ConfigFlowResult", ), TypeHintMatch( function_name="async_step_homekit", arg_types={ 1: "ZeroconfServiceInfo", }, - return_type=["ConfigFlowResult", "FlowResult"], + return_type="ConfigFlowResult", ), TypeHintMatch( function_name="async_step_mqtt", arg_types={ 1: "MqttServiceInfo", }, - return_type=["ConfigFlowResult", "FlowResult"], + return_type="ConfigFlowResult", ), TypeHintMatch( function_name="async_step_reauth", arg_types={ 1: "Mapping[str, Any]", }, - return_type=["ConfigFlowResult", "FlowResult"], + return_type="ConfigFlowResult", ), TypeHintMatch( function_name="async_step_ssdp", arg_types={ 1: "SsdpServiceInfo", }, - return_type=["ConfigFlowResult", "FlowResult"], + return_type="ConfigFlowResult", ), TypeHintMatch( function_name="async_step_usb", arg_types={ 1: "UsbServiceInfo", }, - return_type=["ConfigFlowResult", "FlowResult"], + return_type="ConfigFlowResult", ), TypeHintMatch( function_name="async_step_zeroconf", arg_types={ 1: "ZeroconfServiceInfo", }, - return_type=["ConfigFlowResult", "FlowResult"], + return_type="ConfigFlowResult", + ), + TypeHintMatch( + function_name="async_step_*", + arg_types={}, + return_type="ConfigFlowResult", ), ], ), @@ -570,7 +570,7 @@ _CLASS_MATCH: dict[str, list[ClassTypeHintMatch]] = { TypeHintMatch( function_name="async_step_*", arg_types={}, - return_type=["ConfigFlowResult", "FlowResult"], + return_type="ConfigFlowResult", ), ], ), diff --git a/tests/pylint/test_enforce_type_hints.py b/tests/pylint/test_enforce_type_hints.py index 2a03343cb82..d3b7efae19b 100644 --- a/tests/pylint/test_enforce_type_hints.py +++ b/tests/pylint/test_enforce_type_hints.py @@ -346,7 +346,7 @@ def test_invalid_config_flow_step( pylint.testutils.MessageTest( msg_id="hass-return-type", node=func_node, - args=(["ConfigFlowResult", "FlowResult"], "async_step_zeroconf"), + args=("ConfigFlowResult", "async_step_zeroconf"), line=11, col_offset=4, end_line=11, @@ -356,6 +356,46 @@ def test_invalid_config_flow_step( type_hint_checker.visit_classdef(class_node) +def test_invalid_custom_config_flow_step( + linter: UnittestLinter, type_hint_checker: BaseChecker +) -> None: + """Ensure invalid hints are rejected for ConfigFlow step.""" + class_node, func_node, arg_node = astroid.extract_node( + """ + class FlowHandler(): + pass + + class ConfigFlow(FlowHandler): + pass + + class AxisFlowHandler( #@ + ConfigFlow, domain=AXIS_DOMAIN + ): + async def async_step_axis_specific( #@ + self, + device_config: dict #@ + ): + pass + """, + "homeassistant.components.pylint_test.config_flow", + ) + type_hint_checker.visit_module(class_node.parent) + + with assert_adds_messages( + linter, + pylint.testutils.MessageTest( + msg_id="hass-return-type", + node=func_node, + args=("ConfigFlowResult", "async_step_axis_specific"), + line=11, + col_offset=4, + end_line=11, + end_col_offset=38, + ), + ): + type_hint_checker.visit_classdef(class_node) + + def test_valid_config_flow_step( linter: UnittestLinter, type_hint_checker: BaseChecker ) -> None: