diff --git a/homeassistant/helpers/condition.py b/homeassistant/helpers/condition.py index d1a7c95d16c..a59ad459874 100644 --- a/homeassistant/helpers/condition.py +++ b/homeassistant/helpers/condition.py @@ -112,15 +112,22 @@ def condition_trace_update_result(**kwargs: Any) -> None: @contextmanager def trace_condition(variables: TemplateVarsType) -> Generator: """Trace condition evaluation.""" - trace_element = condition_trace_append(variables, trace_path_get()) - trace_stack_push(trace_stack_cv, trace_element) + should_pop = True + trace_element = trace_stack_top(trace_stack_cv) + if trace_element and trace_element.reuse_by_child: + should_pop = False + trace_element.reuse_by_child = False + else: + trace_element = condition_trace_append(variables, trace_path_get()) + trace_stack_push(trace_stack_cv, trace_element) try: yield trace_element except Exception as ex: trace_element.set_error(ex) raise ex finally: - trace_stack_pop(trace_stack_cv) + if should_pop: + trace_stack_pop(trace_stack_cv) def trace_condition_function(condition: ConditionCheckerType) -> ConditionCheckerType: diff --git a/homeassistant/helpers/script.py b/homeassistant/helpers/script.py index 1deb5a5073f..ea3635888bb 100644 --- a/homeassistant/helpers/script.py +++ b/homeassistant/helpers/script.py @@ -87,6 +87,8 @@ from .trace import ( trace_stack_cv, trace_stack_pop, trace_stack_push, + trace_stack_top, + trace_update_result, ) # mypy: allow-untyped-calls, allow-untyped-defs, no-check-untyped-defs @@ -619,14 +621,16 @@ class _ScriptRun: ) cond = await self._async_get_condition(self._action) try: - with trace_path("condition"): - check = cond(self._hass, self._variables) + trace_element = trace_stack_top(trace_stack_cv) + if trace_element: + trace_element.reuse_by_child = True + check = cond(self._hass, self._variables) except exceptions.ConditionError as ex: _LOGGER.warning("Error in 'condition' evaluation:\n%s", ex) check = False self._log("Test condition %s: %s", self._script.last_action, check) - trace_set_result(result=check) + trace_update_result(result=check) if not check: raise _StopScript diff --git a/homeassistant/helpers/trace.py b/homeassistant/helpers/trace.py index e2d5144f374..bfa713a3b2a 100644 --- a/homeassistant/helpers/trace.py +++ b/homeassistant/helpers/trace.py @@ -22,6 +22,7 @@ class TraceElement: self._error: Exception | None = None self.path: str = path self._result: dict | None = None + self.reuse_by_child = False self._timestamp = dt_util.utcnow() if variables is None: @@ -198,6 +199,12 @@ def trace_set_result(**kwargs: Any) -> None: node.set_result(**kwargs) +def trace_update_result(**kwargs: Any) -> None: + """Update the result of TraceElement at the top of the stack.""" + node = cast(TraceElement, trace_stack_top(trace_stack_cv)) + node.update_result(**kwargs) + + class StopReason: """Mutable container class for script_execution.""" diff --git a/tests/helpers/test_script.py b/tests/helpers/test_script.py index 2045f8cdbbc..546f494735e 100644 --- a/tests/helpers/test_script.py +++ b/tests/helpers/test_script.py @@ -1412,8 +1412,7 @@ async def test_condition_warning(hass, caplog): { "0": [{"result": {"event": "test_event", "event_data": {}}}], "1": [{"error_type": script._StopScript, "result": {"result": False}}], - "1/condition": [{"error_type": ConditionError}], - "1/condition/entity_id/0": [{"error_type": ConditionError}], + "1/entity_id/0": [{"error_type": ConditionError}], }, expected_script_execution="aborted", ) @@ -1448,8 +1447,7 @@ async def test_condition_basic(hass, caplog): assert_action_trace( { "0": [{"result": {"event": "test_event", "event_data": {}}}], - "1": [{"result": {"result": True}}], - "1/condition": [{"result": {"entities": ["test.entity"], "result": True}}], + "1": [{"result": {"entities": ["test.entity"], "result": True}}], "2": [{"result": {"event": "test_event", "event_data": {}}}], } ) @@ -1465,8 +1463,12 @@ async def test_condition_basic(hass, caplog): assert_action_trace( { "0": [{"result": {"event": "test_event", "event_data": {}}}], - "1": [{"error_type": script._StopScript, "result": {"result": False}}], - "1/condition": [{"result": {"entities": ["test.entity"], "result": False}}], + "1": [ + { + "error_type": script._StopScript, + "result": {"entities": ["test.entity"], "result": False}, + } + ], }, expected_script_execution="aborted", )