From 12be82fdbc5aac5839ebedc4a11300efe9735902 Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Fri, 6 Dec 2024 22:40:29 +0100 Subject: [PATCH] Add parallel-updates rule to quality_scale validation (#132041) --- .../components/acaia/binary_sensor.py | 3 ++ homeassistant/components/acaia/sensor.py | 3 ++ .../components/elgato/quality_scale.yaml | 5 ++- homeassistant/components/elgato/sensor.py | 3 ++ .../husqvarna_automower/binary_sensor.py | 2 ++ .../husqvarna_automower/calendar.py | 2 ++ .../husqvarna_automower/device_tracker.py | 3 ++ .../components/husqvarna_automower/sensor.py | 2 ++ homeassistant/components/imap/sensor.py | 3 ++ homeassistant/components/iron_os/sensor.py | 3 ++ .../components/ista_ecotrend/sensor.py | 2 ++ .../components/lamarzocco/binary_sensor.py | 3 ++ .../components/lamarzocco/calendar.py | 3 ++ homeassistant/components/lamarzocco/sensor.py | 3 ++ .../components/mastodon/quality_scale.yaml | 5 ++- homeassistant/components/mastodon/sensor.py | 3 ++ .../components/tedee/binary_sensor.py | 3 ++ homeassistant/components/tedee/sensor.py | 3 ++ script/hassfest/quality_scale.py | 3 +- .../parallel_updates.py | 35 +++++++++++++++++++ 20 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 script/hassfest/quality_scale_validation/parallel_updates.py diff --git a/homeassistant/components/acaia/binary_sensor.py b/homeassistant/components/acaia/binary_sensor.py index 9aa4b92e932..ecb7ac06eb5 100644 --- a/homeassistant/components/acaia/binary_sensor.py +++ b/homeassistant/components/acaia/binary_sensor.py @@ -16,6 +16,9 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .coordinator import AcaiaConfigEntry from .entity import AcaiaEntity +# Coordinator is used to centralize the data updates +PARALLEL_UPDATES = 0 + @dataclass(kw_only=True, frozen=True) class AcaiaBinarySensorEntityDescription(BinarySensorEntityDescription): diff --git a/homeassistant/components/acaia/sensor.py b/homeassistant/components/acaia/sensor.py index 6e6ce6afcb8..7ba44958eca 100644 --- a/homeassistant/components/acaia/sensor.py +++ b/homeassistant/components/acaia/sensor.py @@ -21,6 +21,9 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .coordinator import AcaiaConfigEntry from .entity import AcaiaEntity +# Coordinator is used to centralize the data updates +PARALLEL_UPDATES = 0 + @dataclass(kw_only=True, frozen=True) class AcaiaSensorEntityDescription(SensorEntityDescription): diff --git a/homeassistant/components/elgato/quality_scale.yaml b/homeassistant/components/elgato/quality_scale.yaml index 2910bdb4473..301d00931d2 100644 --- a/homeassistant/components/elgato/quality_scale.yaml +++ b/homeassistant/components/elgato/quality_scale.yaml @@ -33,7 +33,10 @@ rules: entity-unavailable: done integration-owner: done log-when-unavailable: done - parallel-updates: done + parallel-updates: + status: todo + comment: | + Does not set parallel-updates on button/switch action calls. reauthentication-flow: status: exempt comment: | diff --git a/homeassistant/components/elgato/sensor.py b/homeassistant/components/elgato/sensor.py index f794d26cf7f..a28ee01f505 100644 --- a/homeassistant/components/elgato/sensor.py +++ b/homeassistant/components/elgato/sensor.py @@ -25,6 +25,9 @@ from . import ElgatorConfigEntry from .coordinator import ElgatoData, ElgatoDataUpdateCoordinator from .entity import ElgatoEntity +# Coordinator is used to centralize the data updates +PARALLEL_UPDATES = 0 + @dataclass(frozen=True, kw_only=True) class ElgatoSensorEntityDescription(SensorEntityDescription): diff --git a/homeassistant/components/husqvarna_automower/binary_sensor.py b/homeassistant/components/husqvarna_automower/binary_sensor.py index f8b8f155458..3c23da76797 100644 --- a/homeassistant/components/husqvarna_automower/binary_sensor.py +++ b/homeassistant/components/husqvarna_automower/binary_sensor.py @@ -30,6 +30,8 @@ from .coordinator import AutomowerDataUpdateCoordinator from .entity import AutomowerBaseEntity _LOGGER = logging.getLogger(__name__) +# Coordinator is used to centralize the data updates +PARALLEL_UPDATES = 0 def entity_used_in(hass: HomeAssistant, entity_id: str) -> list[str]: diff --git a/homeassistant/components/husqvarna_automower/calendar.py b/homeassistant/components/husqvarna_automower/calendar.py index d4162af0c5c..f3e82fde5d4 100644 --- a/homeassistant/components/husqvarna_automower/calendar.py +++ b/homeassistant/components/husqvarna_automower/calendar.py @@ -15,6 +15,8 @@ from .coordinator import AutomowerDataUpdateCoordinator from .entity import AutomowerBaseEntity _LOGGER = logging.getLogger(__name__) +# Coordinator is used to centralize the data updates +PARALLEL_UPDATES = 0 async def async_setup_entry( diff --git a/homeassistant/components/husqvarna_automower/device_tracker.py b/homeassistant/components/husqvarna_automower/device_tracker.py index 5e84b7cc67d..520eaceb1d0 100644 --- a/homeassistant/components/husqvarna_automower/device_tracker.py +++ b/homeassistant/components/husqvarna_automower/device_tracker.py @@ -8,6 +8,9 @@ from . import AutomowerConfigEntry from .coordinator import AutomowerDataUpdateCoordinator from .entity import AutomowerBaseEntity +# Coordinator is used to centralize the data updates +PARALLEL_UPDATES = 0 + async def async_setup_entry( hass: HomeAssistant, diff --git a/homeassistant/components/husqvarna_automower/sensor.py b/homeassistant/components/husqvarna_automower/sensor.py index 70b5510de36..fb8603623e4 100644 --- a/homeassistant/components/husqvarna_automower/sensor.py +++ b/homeassistant/components/husqvarna_automower/sensor.py @@ -35,6 +35,8 @@ from .entity import ( ) _LOGGER = logging.getLogger(__name__) +# Coordinator is used to centralize the data updates +PARALLEL_UPDATES = 0 ATTR_WORK_AREA_ID_ASSIGNMENT = "work_area_id_assignment" diff --git a/homeassistant/components/imap/sensor.py b/homeassistant/components/imap/sensor.py index b484586e057..60892388252 100644 --- a/homeassistant/components/imap/sensor.py +++ b/homeassistant/components/imap/sensor.py @@ -17,6 +17,9 @@ from . import ImapConfigEntry from .const import DOMAIN from .coordinator import ImapDataUpdateCoordinator +# Coordinator is used to centralize the data updates +PARALLEL_UPDATES = 0 + IMAP_MAIL_COUNT_DESCRIPTION = SensorEntityDescription( key="imap_mail_count", entity_category=EntityCategory.DIAGNOSTIC, diff --git a/homeassistant/components/iron_os/sensor.py b/homeassistant/components/iron_os/sensor.py index 05d56db26d3..34f0f6af6b2 100644 --- a/homeassistant/components/iron_os/sensor.py +++ b/homeassistant/components/iron_os/sensor.py @@ -30,6 +30,9 @@ from . import IronOSConfigEntry from .const import OHM from .entity import IronOSBaseEntity +# Coordinator is used to centralize the data updates +PARALLEL_UPDATES = 0 + class PinecilSensor(StrEnum): """Pinecil Sensors.""" diff --git a/homeassistant/components/ista_ecotrend/sensor.py b/homeassistant/components/ista_ecotrend/sensor.py index 779a5d5c55f..eb06fabe373 100644 --- a/homeassistant/components/ista_ecotrend/sensor.py +++ b/homeassistant/components/ista_ecotrend/sensor.py @@ -40,6 +40,8 @@ from .coordinator import IstaCoordinator from .util import IstaConsumptionType, IstaValueType, get_native_value, get_statistics _LOGGER = logging.getLogger(__name__) +# Coordinator is used to centralize the data updates +PARALLEL_UPDATES = 0 @dataclass(kw_only=True, frozen=True) diff --git a/homeassistant/components/lamarzocco/binary_sensor.py b/homeassistant/components/lamarzocco/binary_sensor.py index 444e4d0723b..0e11c54d896 100644 --- a/homeassistant/components/lamarzocco/binary_sensor.py +++ b/homeassistant/components/lamarzocco/binary_sensor.py @@ -17,6 +17,9 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .coordinator import LaMarzoccoConfigEntry from .entity import LaMarzoccoEntity, LaMarzoccoEntityDescription +# Coordinator is used to centralize the data updates +PARALLEL_UPDATES = 0 + @dataclass(frozen=True, kw_only=True) class LaMarzoccoBinarySensorEntityDescription( diff --git a/homeassistant/components/lamarzocco/calendar.py b/homeassistant/components/lamarzocco/calendar.py index 0ec9b55a9a1..46bfe875c9f 100644 --- a/homeassistant/components/lamarzocco/calendar.py +++ b/homeassistant/components/lamarzocco/calendar.py @@ -13,6 +13,9 @@ from homeassistant.util import dt as dt_util from .coordinator import LaMarzoccoConfigEntry, LaMarzoccoUpdateCoordinator from .entity import LaMarzoccoBaseEntity +# Coordinator is used to centralize the data updates +PARALLEL_UPDATES = 0 + CALENDAR_KEY = "auto_on_off_schedule" DAY_OF_WEEK = [ diff --git a/homeassistant/components/lamarzocco/sensor.py b/homeassistant/components/lamarzocco/sensor.py index d9e858b8191..6dda6e69a02 100644 --- a/homeassistant/components/lamarzocco/sensor.py +++ b/homeassistant/components/lamarzocco/sensor.py @@ -19,6 +19,9 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .coordinator import LaMarzoccoConfigEntry from .entity import LaMarzoccoEntity, LaMarzoccoEntityDescription +# Coordinator is used to centralize the data updates +PARALLEL_UPDATES = 0 + @dataclass(frozen=True, kw_only=True) class LaMarzoccoSensorEntityDescription( diff --git a/homeassistant/components/mastodon/quality_scale.yaml b/homeassistant/components/mastodon/quality_scale.yaml index f287b9a0c1f..315ef808701 100644 --- a/homeassistant/components/mastodon/quality_scale.yaml +++ b/homeassistant/components/mastodon/quality_scale.yaml @@ -39,7 +39,10 @@ rules: entity-unavailable: done integration-owner: done log-when-unavailable: done - parallel-updates: done + parallel-updates: + status: todo + comment: | + Does not set parallel-updates on notify platform. reauthentication-flow: status: todo comment: | diff --git a/homeassistant/components/mastodon/sensor.py b/homeassistant/components/mastodon/sensor.py index a7a1d40fcc4..1bb59ad7c05 100644 --- a/homeassistant/components/mastodon/sensor.py +++ b/homeassistant/components/mastodon/sensor.py @@ -23,6 +23,9 @@ from .const import ( ) from .entity import MastodonEntity +# Coordinator is used to centralize the data updates +PARALLEL_UPDATES = 0 + @dataclass(frozen=True, kw_only=True) class MastodonSensorEntityDescription(SensorEntityDescription): diff --git a/homeassistant/components/tedee/binary_sensor.py b/homeassistant/components/tedee/binary_sensor.py index b586db7c2a7..94d3f0b6831 100644 --- a/homeassistant/components/tedee/binary_sensor.py +++ b/homeassistant/components/tedee/binary_sensor.py @@ -18,6 +18,9 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .coordinator import TedeeConfigEntry from .entity import TedeeDescriptionEntity +# Coordinator is used to centralize the data updates +PARALLEL_UPDATES = 0 + @dataclass(frozen=True, kw_only=True) class TedeeBinarySensorEntityDescription( diff --git a/homeassistant/components/tedee/sensor.py b/homeassistant/components/tedee/sensor.py index 90f76317fff..d61e7360dc4 100644 --- a/homeassistant/components/tedee/sensor.py +++ b/homeassistant/components/tedee/sensor.py @@ -18,6 +18,9 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .coordinator import TedeeConfigEntry from .entity import TedeeDescriptionEntity +# Coordinator is used to centralize the data updates +PARALLEL_UPDATES = 0 + @dataclass(frozen=True, kw_only=True) class TedeeSensorEntityDescription(SensorEntityDescription): diff --git a/script/hassfest/quality_scale.py b/script/hassfest/quality_scale.py index c55915c19c1..b33649427c1 100644 --- a/script/hassfest/quality_scale.py +++ b/script/hassfest/quality_scale.py @@ -18,6 +18,7 @@ from .quality_scale_validation import ( config_flow, diagnostics, discovery, + parallel_updates, reauthentication_flow, reconfiguration_flow, runtime_data, @@ -67,7 +68,7 @@ ALL_RULES = [ Rule("entity-unavailable", ScaledQualityScaleTiers.SILVER), Rule("integration-owner", ScaledQualityScaleTiers.SILVER), Rule("log-when-unavailable", ScaledQualityScaleTiers.SILVER), - Rule("parallel-updates", ScaledQualityScaleTiers.SILVER), + Rule("parallel-updates", ScaledQualityScaleTiers.SILVER, parallel_updates), Rule( "reauthentication-flow", ScaledQualityScaleTiers.SILVER, reauthentication_flow ), diff --git a/script/hassfest/quality_scale_validation/parallel_updates.py b/script/hassfest/quality_scale_validation/parallel_updates.py new file mode 100644 index 00000000000..918d27a3fa8 --- /dev/null +++ b/script/hassfest/quality_scale_validation/parallel_updates.py @@ -0,0 +1,35 @@ +"""Enforce that the integration sets PARALLEL_UPDATES constant. + +https://developers.home-assistant.io/docs/core/integration-quality-scale/rules/parallel-updates +""" + +import ast + +from homeassistant.const import Platform +from script.hassfest.model import Integration + + +def _has_parallel_updates_defined(module: ast.Module) -> bool: + """Test if the module defines `PARALLEL_UPDATES` constant.""" + return any( + type(item) is ast.Assign and item.targets[0].id == "PARALLEL_UPDATES" + for item in module.body + ) + + +def validate(integration: Integration) -> list[str] | None: + """Validate that the integration sets PARALLEL_UPDATES constant.""" + + errors = [] + for platform in Platform: + module_file = integration.path / f"{platform}.py" + if not module_file.exists(): + continue + module = ast.parse(module_file.read_text()) + + if not _has_parallel_updates_defined(module): + errors.append( + f"Integration does not set `PARALLEL_UPDATES` in {module_file}" + ) + + return errors