From d596b4169dc909b709fa1047f0a7c866a1e6011c Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Thu, 28 Nov 2024 22:05:34 +0100 Subject: [PATCH] Add strict_typing rule to quality_scale hassfest validation (#131877) * Add strict_typing rule to quality_scale hassfest validation * Add acaia to .strict-typing --- .strict-typing | 1 + mypy.ini | 10 ++++++ script/hassfest/quality_scale.py | 3 +- .../quality_scale_validation/strict_typing.py | 35 +++++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 script/hassfest/quality_scale_validation/strict_typing.py diff --git a/.strict-typing b/.strict-typing index f1383fa3528..ed698c26ea0 100644 --- a/.strict-typing +++ b/.strict-typing @@ -41,6 +41,7 @@ homeassistant.util.unit_system # --- Add components below this line --- homeassistant.components homeassistant.components.abode.* +homeassistant.components.acaia.* homeassistant.components.accuweather.* homeassistant.components.acer_projector.* homeassistant.components.acmeda.* diff --git a/mypy.ini b/mypy.ini index aa9a2b81095..22e85244843 100644 --- a/mypy.ini +++ b/mypy.ini @@ -165,6 +165,16 @@ disallow_untyped_defs = true warn_return_any = true warn_unreachable = true +[mypy-homeassistant.components.acaia.*] +check_untyped_defs = true +disallow_incomplete_defs = true +disallow_subclassing_any = true +disallow_untyped_calls = true +disallow_untyped_decorators = true +disallow_untyped_defs = true +warn_return_any = true +warn_unreachable = true + [mypy-homeassistant.components.accuweather.*] check_untyped_defs = true disallow_incomplete_defs = true diff --git a/script/hassfest/quality_scale.py b/script/hassfest/quality_scale.py index 9d4c236b7b6..1a665df19f5 100644 --- a/script/hassfest/quality_scale.py +++ b/script/hassfest/quality_scale.py @@ -19,6 +19,7 @@ from .quality_scale_validation import ( diagnostics, reauthentication_flow, reconfiguration_flow, + strict_typing, ) QUALITY_SCALE_TIERS = {value.name.lower(): value for value in ScaledQualityScaleTiers} @@ -93,7 +94,7 @@ ALL_RULES = [ # PLATINUM Rule("async-dependency", ScaledQualityScaleTiers.PLATINUM), Rule("inject-websession", ScaledQualityScaleTiers.PLATINUM), - Rule("strict-typing", ScaledQualityScaleTiers.PLATINUM), + Rule("strict-typing", ScaledQualityScaleTiers.PLATINUM, strict_typing), ] SCALE_RULES = { diff --git a/script/hassfest/quality_scale_validation/strict_typing.py b/script/hassfest/quality_scale_validation/strict_typing.py new file mode 100644 index 00000000000..285746a9eb6 --- /dev/null +++ b/script/hassfest/quality_scale_validation/strict_typing.py @@ -0,0 +1,35 @@ +"""Enforce that the integration has strict typing enabled. + +https://developers.home-assistant.io/docs/core/integration-quality-scale/rules/strict-typing/ +""" + +from functools import lru_cache +from pathlib import Path +import re + +from script.hassfest.model import Integration + +_STRICT_TYPING_FILE = Path(".strict-typing") +_COMPONENT_REGEX = r"homeassistant.components.([^.]+).*" + + +@lru_cache +def _strict_typing_components() -> set[str]: + return set( + { + match.group(1) + for line in _STRICT_TYPING_FILE.read_text(encoding="utf-8").splitlines() + if (match := re.match(_COMPONENT_REGEX, line)) is not None + } + ) + + +def validate(integration: Integration) -> list[str] | None: + """Validate that the integration has strict typing enabled.""" + + if integration.domain not in _strict_typing_components(): + return [ + "Integration does not have strict typing enabled " + "(is missing from .strict-typing)" + ] + return None