From 5ebf5996f1a9ed78293cfd5642c910075c3c1298 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 9 Oct 2020 01:41:12 -0500 Subject: [PATCH] Predetermine listener type for script change listeners (#41510) --- homeassistant/helpers/script.py | 33 +++++++++++++++++++++++++++++---- tests/helpers/test_script.py | 1 + 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/homeassistant/helpers/script.py b/homeassistant/helpers/script.py index 4d958fe431f..645131b60b5 100644 --- a/homeassistant/helpers/script.py +++ b/homeassistant/helpers/script.py @@ -53,7 +53,13 @@ from homeassistant.const import ( EVENT_HOMEASSISTANT_STOP, SERVICE_TURN_ON, ) -from homeassistant.core import SERVICE_CALL_LIMIT, Context, HomeAssistant, callback +from homeassistant.core import ( + SERVICE_CALL_LIMIT, + Context, + HassJob, + HomeAssistant, + callback, +) from homeassistant.helpers import condition, config_validation as cv, template from homeassistant.helpers.event import async_call_later, async_track_template from homeassistant.helpers.script_variables import ScriptVariables @@ -789,7 +795,11 @@ class Script: self.name = name self.domain = domain self.running_description = running_description or f"{domain} script" - self.change_listener = change_listener + self._change_listener = change_listener + self._change_listener_job = ( + None if change_listener is None else HassJob(change_listener) + ) + self.script_mode = script_mode self._set_logger(logger) self._log_exceptions = log_exceptions @@ -812,6 +822,21 @@ class Script: if self._variables_dynamic: template.attach(hass, variables) + @property + def change_listener(self) -> Optional[Callable[..., Any]]: + """Return the change_listener.""" + return self._change_listener + + @change_listener.setter + def change_listener(self, change_listener: Callable[..., Any]) -> None: + """Update the change_listener.""" + self._change_listener = change_listener + if ( + self._change_listener_job is None + or change_listener != self._change_listener_job.target + ): + self._change_listener_job = HassJob(change_listener) + def _set_logger(self, logger: Optional[logging.Logger] = None) -> None: if logger: self._logger = logger @@ -830,8 +855,8 @@ class Script: choose_data["default"].update_logger(self._logger) def _changed(self): - if self.change_listener: - self._hass.async_run_job(self.change_listener) + if self._change_listener_job: + self._hass.async_run_hass_job(self._change_listener_job) def _chain_change_listener(self, sub_script): if sub_script.is_running: diff --git a/tests/helpers/test_script.py b/tests/helpers/test_script.py index a7cf6b17e7a..8f9e3cec36c 100644 --- a/tests/helpers/test_script.py +++ b/tests/helpers/test_script.py @@ -39,6 +39,7 @@ def async_watch_for_action(script_obj, message): flag.set() script_obj.change_listener = check_action + assert script_obj.change_listener is check_action return flag