Add generic classes BaseFlowHandler and BaseFlowManager (#111814)

* Add generic classes BaseFlowHandler and BaseFlowManager

* Migrate zwave_js

* Update tests

* Update tests

* Address review comments
This commit is contained in:
Erik Montnemery 2024-02-29 16:52:39 +01:00 committed by GitHub
parent 3a8b6412ed
commit a0e558c457
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 341 additions and 273 deletions

View file

@ -55,11 +55,12 @@ class TypeHintMatch:
)
@dataclass
@dataclass(kw_only=True)
class ClassTypeHintMatch:
"""Class for pattern matching."""
base_class: str
exclude_base_classes: set[str] | None = None
matches: list[TypeHintMatch]
@ -481,6 +482,7 @@ _CLASS_MATCH: dict[str, list[ClassTypeHintMatch]] = {
"config_flow": [
ClassTypeHintMatch(
base_class="FlowHandler",
exclude_base_classes={"ConfigEntryBaseFlow"},
matches=[
TypeHintMatch(
function_name="async_step_*",
@ -492,6 +494,11 @@ _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={
@ -504,56 +511,66 @@ _CLASS_MATCH: dict[str, list[ClassTypeHintMatch]] = {
arg_types={
1: "DhcpServiceInfo",
},
return_type="FlowResult",
return_type=["ConfigFlowResult", "FlowResult"],
),
TypeHintMatch(
function_name="async_step_hassio",
arg_types={
1: "HassioServiceInfo",
},
return_type="FlowResult",
return_type=["ConfigFlowResult", "FlowResult"],
),
TypeHintMatch(
function_name="async_step_homekit",
arg_types={
1: "ZeroconfServiceInfo",
},
return_type="FlowResult",
return_type=["ConfigFlowResult", "FlowResult"],
),
TypeHintMatch(
function_name="async_step_mqtt",
arg_types={
1: "MqttServiceInfo",
},
return_type="FlowResult",
return_type=["ConfigFlowResult", "FlowResult"],
),
TypeHintMatch(
function_name="async_step_reauth",
arg_types={
1: "Mapping[str, Any]",
},
return_type="FlowResult",
return_type=["ConfigFlowResult", "FlowResult"],
),
TypeHintMatch(
function_name="async_step_ssdp",
arg_types={
1: "SsdpServiceInfo",
},
return_type="FlowResult",
return_type=["ConfigFlowResult", "FlowResult"],
),
TypeHintMatch(
function_name="async_step_usb",
arg_types={
1: "UsbServiceInfo",
},
return_type="FlowResult",
return_type=["ConfigFlowResult", "FlowResult"],
),
TypeHintMatch(
function_name="async_step_zeroconf",
arg_types={
1: "ZeroconfServiceInfo",
},
return_type="FlowResult",
return_type=["ConfigFlowResult", "FlowResult"],
),
],
),
ClassTypeHintMatch(
base_class="OptionsFlow",
matches=[
TypeHintMatch(
function_name="async_step_*",
arg_types={},
return_type=["ConfigFlowResult", "FlowResult"],
),
],
),
@ -3126,11 +3143,19 @@ class HassTypeHintChecker(BaseChecker):
ancestor: nodes.ClassDef
checked_class_methods: set[str] = set()
ancestors = list(node.ancestors()) # cache result for inside loop
for class_matches in self._class_matchers:
for class_matcher in self._class_matchers:
skip_matcher = False
if exclude_base_classes := class_matcher.exclude_base_classes:
for ancestor in ancestors:
if ancestor.name in exclude_base_classes:
skip_matcher = True
break
if skip_matcher:
continue
for ancestor in ancestors:
if ancestor.name == class_matches.base_class:
if ancestor.name == class_matcher.base_class:
self._visit_class_functions(
node, class_matches.matches, checked_class_methods
node, class_matcher.matches, checked_class_methods
)
def _visit_class_functions(