From bc22e34fc36298009fb9daf856f3fbb9dc8783be Mon Sep 17 00:00:00 2001 From: G Johansson <goran.johansson@shiftit.se> Date: Mon, 6 Jan 2025 04:22:54 +0100 Subject: [PATCH] Add python_script to strict typing (#134822) --- .strict-typing | 1 + .../components/python_script/__init__.py | 29 +++++++++++++------ mypy.ini | 10 +++++++ 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/.strict-typing b/.strict-typing index f0f4e34c505..98fbb16ff45 100644 --- a/.strict-typing +++ b/.strict-typing @@ -383,6 +383,7 @@ homeassistant.components.pure_energie.* homeassistant.components.purpleair.* homeassistant.components.pushbullet.* homeassistant.components.pvoutput.* +homeassistant.components.python_script.* homeassistant.components.qnap_qsw.* homeassistant.components.rabbitair.* homeassistant.components.radarr.* diff --git a/homeassistant/components/python_script/__init__.py b/homeassistant/components/python_script/__init__.py index af773278029..1e41c81b010 100644 --- a/homeassistant/components/python_script/__init__.py +++ b/homeassistant/components/python_script/__init__.py @@ -1,6 +1,6 @@ """Component to allow running Python scripts.""" -from collections.abc import Mapping, Sequence +from collections.abc import Callable, Mapping, Sequence import datetime import glob import logging @@ -197,7 +197,12 @@ def guarded_inplacevar(op: str, target: Any, operand: Any) -> Any: @bind_hass -def execute_script(hass, name, data=None, return_response=False): +def execute_script( + hass: HomeAssistant, + name: str, + data: dict[str, Any] | None = None, + return_response: bool = False, +) -> dict | None: """Execute a script.""" filename = f"{name}.py" raise_if_invalid_filename(filename) @@ -207,7 +212,13 @@ def execute_script(hass, name, data=None, return_response=False): @bind_hass -def execute(hass, filename, source, data=None, return_response=False): +def execute( + hass: HomeAssistant, + filename: str, + source: Any, + data: dict[str, Any] | None = None, + return_response: bool = False, +) -> dict | None: """Execute Python source.""" compiled = compile_restricted_exec(source, filename=filename) @@ -223,7 +234,7 @@ def execute(hass, filename, source, data=None, return_response=False): "Warning loading script %s: %s", filename, ", ".join(compiled.warnings) ) - def protected_getattr(obj, name, default=None): + def protected_getattr(obj: object, name: str, default: Any = None) -> Any: """Restricted method to get attributes.""" if name.startswith("async_"): raise ScriptError("Not allowed to access async methods") @@ -316,10 +327,10 @@ def execute(hass, filename, source, data=None, return_response=False): class StubPrinter: """Class to handle printing inside scripts.""" - def __init__(self, _getattr_): + def __init__(self, _getattr_: Callable) -> None: """Initialize our printer.""" - def _call_print(self, *objects, **kwargs): + def _call_print(self, *objects: object, **kwargs: Any) -> None: """Print text.""" _LOGGER.warning("Don't use print() inside scripts. Use logger.info() instead") @@ -330,7 +341,7 @@ class TimeWrapper: # Class variable, only going to warn once per Home Assistant run warned = False - def sleep(self, *args, **kwargs): + def sleep(self, *args: Any, **kwargs: Any) -> None: """Sleep method that warns once.""" if not TimeWrapper.warned: TimeWrapper.warned = True @@ -340,12 +351,12 @@ class TimeWrapper: time.sleep(*args, **kwargs) - def __getattr__(self, attr): + def __getattr__(self, attr: str) -> Any: """Fetch an attribute from Time module.""" attribute = getattr(time, attr) if callable(attribute): - def wrapper(*args, **kw): + def wrapper(*args: Any, **kw: Any) -> Any: """Wrap to return callable method if callable.""" return attribute(*args, **kw) diff --git a/mypy.ini b/mypy.ini index e393b32f9fd..55fd0b3cd65 100644 --- a/mypy.ini +++ b/mypy.ini @@ -3586,6 +3586,16 @@ disallow_untyped_defs = true warn_return_any = true warn_unreachable = true +[mypy-homeassistant.components.python_script.*] +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.qnap_qsw.*] check_untyped_defs = true disallow_incomplete_defs = true -- GitLab