From 43fa51b6965819a7b35a3f20273f4f8d61f098bc Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Tue, 2 Jan 2024 20:48:51 +0100 Subject: [PATCH] Enable strict typing for blueprint (#106887) --- .strict-typing | 1 + homeassistant/components/blueprint/models.py | 24 +++++++++---------- homeassistant/components/blueprint/schemas.py | 4 ++-- .../components/blueprint/websocket_api.py | 4 ++-- homeassistant/util/yaml/loader.py | 8 +++++-- mypy.ini | 10 ++++++++ 6 files changed, 33 insertions(+), 18 deletions(-) diff --git a/.strict-typing b/.strict-typing index f04d8d85e98..7d7fffbd714 100644 --- a/.strict-typing +++ b/.strict-typing @@ -101,6 +101,7 @@ homeassistant.components.binary_sensor.* homeassistant.components.bitcoin.* homeassistant.components.blockchain.* homeassistant.components.blue_current.* +homeassistant.components.blueprint.* homeassistant.components.bluetooth.* homeassistant.components.bluetooth_tracker.* homeassistant.components.bmw_connected_drive.* diff --git a/homeassistant/components/blueprint/models.py b/homeassistant/components/blueprint/models.py index 63a1c1b45f0..33fb87cc578 100644 --- a/homeassistant/components/blueprint/models.py +++ b/homeassistant/components/blueprint/models.py @@ -90,17 +90,17 @@ class Blueprint: @property def name(self) -> str: """Return blueprint name.""" - return self.data[CONF_BLUEPRINT][CONF_NAME] + return self.data[CONF_BLUEPRINT][CONF_NAME] # type: ignore[no-any-return] @property - def inputs(self) -> dict: + def inputs(self) -> dict[str, Any]: """Return blueprint inputs.""" - return self.data[CONF_BLUEPRINT][CONF_INPUT] + return self.data[CONF_BLUEPRINT][CONF_INPUT] # type: ignore[no-any-return] @property - def metadata(self) -> dict: + def metadata(self) -> dict[str, Any]: """Return blueprint metadata.""" - return self.data[CONF_BLUEPRINT] + return self.data[CONF_BLUEPRINT] # type: ignore[no-any-return] def update_metadata(self, *, source_url: str | None = None) -> None: """Update metadata.""" @@ -140,12 +140,12 @@ class BlueprintInputs: self.config_with_inputs = config_with_inputs @property - def inputs(self): + def inputs(self) -> dict[str, Any]: """Return the inputs.""" - return self.config_with_inputs[CONF_USE_BLUEPRINT][CONF_INPUT] + return self.config_with_inputs[CONF_USE_BLUEPRINT][CONF_INPUT] # type: ignore[no-any-return] @property - def inputs_with_default(self): + def inputs_with_default(self) -> dict[str, Any]: """Return the inputs and fallback to defaults.""" no_input = set(self.blueprint.inputs) - set(self.inputs) @@ -212,7 +212,7 @@ class DomainBlueprints: async with self._load_lock: self._blueprints = {} - def _load_blueprint(self, blueprint_path) -> Blueprint: + def _load_blueprint(self, blueprint_path: str) -> Blueprint: """Load a blueprint.""" try: blueprint_data = yaml.load_yaml_dict(self.blueprint_folder / blueprint_path) @@ -262,7 +262,7 @@ class DomainBlueprints: async def async_get_blueprint(self, blueprint_path: str) -> Blueprint: """Get a blueprint.""" - def load_from_cache(): + def load_from_cache() -> Blueprint: """Load blueprint from cache.""" if (blueprint := self._blueprints[blueprint_path]) is None: raise FailedToLoad( @@ -337,7 +337,7 @@ class DomainBlueprints: return exists async def async_add_blueprint( - self, blueprint: Blueprint, blueprint_path: str, allow_override=False + self, blueprint: Blueprint, blueprint_path: str, allow_override: bool = False ) -> bool: """Add a blueprint.""" overrides_existing = await self.hass.async_add_executor_job( @@ -359,7 +359,7 @@ class DomainBlueprints: integration = await loader.async_get_integration(self.hass, self.domain) - def populate(): + def populate() -> None: if self.blueprint_folder.exists(): return diff --git a/homeassistant/components/blueprint/schemas.py b/homeassistant/components/blueprint/schemas.py index c8271cc700d..fd3aa967336 100644 --- a/homeassistant/components/blueprint/schemas.py +++ b/homeassistant/components/blueprint/schemas.py @@ -25,7 +25,7 @@ from .const import ( ) -def version_validator(value): +def version_validator(value: Any) -> str: """Validate a Home Assistant version.""" if not isinstance(value, str): raise vol.Invalid("Version needs to be a string") @@ -36,7 +36,7 @@ def version_validator(value): raise vol.Invalid("Version needs to be formatted as {major}.{minor}.{patch}") try: - parts = [int(p) for p in parts] + [int(p) for p in parts] except ValueError: raise vol.Invalid( "Major, minor and patch version needs to be an integer" diff --git a/homeassistant/components/blueprint/websocket_api.py b/homeassistant/components/blueprint/websocket_api.py index 3c7cc3769c8..1989f0f563c 100644 --- a/homeassistant/components/blueprint/websocket_api.py +++ b/homeassistant/components/blueprint/websocket_api.py @@ -18,7 +18,7 @@ from .errors import FailedToLoad, FileAlreadyExists @callback -def async_setup(hass: HomeAssistant): +def async_setup(hass: HomeAssistant) -> None: """Set up the websocket API.""" websocket_api.async_register_command(hass, ws_list_blueprints) websocket_api.async_register_command(hass, ws_import_blueprint) @@ -76,7 +76,7 @@ async def ws_import_blueprint( imported_blueprint = await importer.fetch_blueprint_from_url(hass, msg["url"]) if imported_blueprint is None: - connection.send_error( + connection.send_error( # type: ignore[unreachable] msg["id"], websocket_api.ERR_NOT_SUPPORTED, "This url is not supported" ) return diff --git a/homeassistant/util/yaml/loader.py b/homeassistant/util/yaml/loader.py index 60e917a6a99..97dbb7d8789 100644 --- a/homeassistant/util/yaml/loader.py +++ b/homeassistant/util/yaml/loader.py @@ -215,7 +215,9 @@ class SafeLineLoader(PythonSafeLoader): LoaderType = FastSafeLoader | PythonSafeLoader -def load_yaml(fname: str, secrets: Secrets | None = None) -> JSON_TYPE | None: +def load_yaml( + fname: str | os.PathLike[str], secrets: Secrets | None = None +) -> JSON_TYPE | None: """Load a YAML file.""" try: with open(fname, encoding="utf-8") as conf_file: @@ -225,7 +227,9 @@ def load_yaml(fname: str, secrets: Secrets | None = None) -> JSON_TYPE | None: raise HomeAssistantError(exc) from exc -def load_yaml_dict(fname: str, secrets: Secrets | None = None) -> dict: +def load_yaml_dict( + fname: str | os.PathLike[str], secrets: Secrets | None = None +) -> dict: """Load a YAML file and ensure the top level is a dict. Raise if the top level is not a dict. diff --git a/mypy.ini b/mypy.ini index a65df261427..e7323b1cd07 100644 --- a/mypy.ini +++ b/mypy.ini @@ -770,6 +770,16 @@ disallow_untyped_defs = true warn_return_any = true warn_unreachable = true +[mypy-homeassistant.components.blueprint.*] +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.bluetooth.*] check_untyped_defs = true disallow_incomplete_defs = true