From 23bc39b7f4415782b5612631cd9b22641b8967d5 Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Wed, 23 Nov 2022 20:26:55 +0100 Subject: [PATCH] Add type hints on `Template().__init__()` (#82574) --- homeassistant/components/esphome/__init__.py | 3 +-- homeassistant/components/mqtt/models.py | 2 +- .../components/shell_command/__init__.py | 2 +- .../components/websocket_api/commands.py | 2 +- homeassistant/helpers/config_validation.py | 4 ++-- homeassistant/helpers/template.py | 21 +++++++++++-------- 6 files changed, 18 insertions(+), 16 deletions(-) diff --git a/homeassistant/components/esphome/__init__.py b/homeassistant/components/esphome/__init__.py index 894928e597a..3315711f4ad 100644 --- a/homeassistant/components/esphome/__init__.py +++ b/homeassistant/components/esphome/__init__.py @@ -146,8 +146,7 @@ async def async_setup_entry( # noqa: C901 if service.data_template: try: data_template = { - key: Template(value) # type: ignore[no-untyped-call] - for key, value in service.data_template.items() + key: Template(value) for key, value in service.data_template.items() } template.attach(hass, data_template) service_data.update( diff --git a/homeassistant/components/mqtt/models.py b/homeassistant/components/mqtt/models.py index a00097a6839..c0b299c7582 100644 --- a/homeassistant/components/mqtt/models.py +++ b/homeassistant/components/mqtt/models.py @@ -152,7 +152,7 @@ class MqttCommandTemplate: values[ATTR_NAME] = self._entity.name if not self._template_state: self._template_state = template.TemplateStateFromEntityId( - self._command_template.hass, self._entity.entity_id + self._entity.hass, self._entity.entity_id ) values[ATTR_THIS] = self._template_state diff --git a/homeassistant/components/shell_command/__init__.py b/homeassistant/components/shell_command/__init__.py index a0dfd3388b4..ac47830f840 100644 --- a/homeassistant/components/shell_command/__init__.py +++ b/homeassistant/components/shell_command/__init__.py @@ -43,7 +43,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: cache[cmd] = prog, args, args_compiled else: prog, args = cmd.split(" ", 1) - args_compiled = template.Template(args, hass) + args_compiled = template.Template(str(args), hass) cache[cmd] = prog, args, args_compiled if args_compiled: diff --git a/homeassistant/components/websocket_api/commands.py b/homeassistant/components/websocket_api/commands.py index 19ec505e449..b4a18ab9ff0 100644 --- a/homeassistant/components/websocket_api/commands.py +++ b/homeassistant/components/websocket_api/commands.py @@ -446,7 +446,7 @@ async def handle_render_template( ) -> None: """Handle render_template command.""" template_str = msg["template"] - template_obj = template.Template(template_str, hass) # type: ignore[no-untyped-call] + template_obj = template.Template(template_str, hass) variables = msg.get("variables") timeout = msg.get("timeout") info = None diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index 6963b2cfb05..667aec9fccf 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -594,7 +594,7 @@ def template(value: Any | None) -> template_helper.Template: if isinstance(value, (list, dict, template_helper.Template)): raise vol.Invalid("template value should be a string") - template_value = template_helper.Template(str(value)) # type: ignore[no-untyped-call] + template_value = template_helper.Template(str(value)) try: template_value.ensure_valid() @@ -612,7 +612,7 @@ def dynamic_template(value: Any | None) -> template_helper.Template: if not template_helper.is_template_string(str(value)): raise vol.Invalid("template value does not contain a dynamic template") - template_value = template_helper.Template(str(value)) # type: ignore[no-untyped-call] + template_value = template_helper.Template(str(value)) try: template_value.ensure_valid() return template_value diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index 69986570a69..87240d35c8f 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -19,6 +19,7 @@ import re import statistics from struct import error as StructError, pack, unpack_from import sys +from types import CodeType from typing import Any, NoReturn, TypeVar, cast, overload from urllib.parse import urlencode as urllib_urlencode import weakref @@ -330,19 +331,19 @@ class Template: "_hash_cache", ) - def __init__(self, template, hass=None): + def __init__(self, template: str, hass: HomeAssistant | None = None) -> None: """Instantiate a template.""" if not isinstance(template, str): raise TypeError("Expected template to be a string") self.template: str = template.strip() - self._compiled_code = None + self._compiled_code: CodeType | None = None self._compiled: jinja2.Template | None = None self.hass = hass self.is_static = not is_template_string(template) - self._exc_info = None - self._limited = None - self._strict = None + self._exc_info: sys._OptExcInfo | None = None + self._limited: bool | None = None + self._strict: bool | None = None self._hash_cache: int = hash(self.template) @property @@ -383,10 +384,10 @@ class Template: If limited is True, the template is not allowed to access any function or filter depending on hass or the state machine. """ if self.is_static: - if not parse_result or self.hass.config.legacy_templates: + if not parse_result or self.hass and self.hass.config.legacy_templates: return self.template return self._parse_result(self.template) - + assert self.hass is not None, "hass variable not set on template" return run_callback_threadsafe( self.hass.loop, partial(self.async_render, variables, parse_result, limited, **kwargs), @@ -408,7 +409,7 @@ class Template: If limited is True, the template is not allowed to access any function or filter depending on hass or the state machine. """ if self.is_static: - if not parse_result or self.hass.config.legacy_templates: + if not parse_result or self.hass and self.hass.config.legacy_templates: return self.template return self._parse_result(self.template) @@ -424,7 +425,7 @@ class Template: render_result = render_result.strip() - if self.hass.config.legacy_templates or not parse_result: + if not parse_result or self.hass and self.hass.config.legacy_templates: return render_result return self._parse_result(render_result) @@ -494,6 +495,7 @@ class Template: finish_event = asyncio.Event() def _render_template() -> None: + assert self.hass is not None, "hass variable not set on template" try: _render_with_context(self.template, compiled, **kwargs) except TimeoutError: @@ -608,6 +610,7 @@ class Template: self._strict is None or self._strict == strict ), "can't change between strict and non strict template" assert not (strict and limited), "can't combine strict and limited template" + assert self._compiled_code is not None, "template code was not compiled" self._limited = limited self._strict = strict