This is an automated email from the ASF dual-hosted git repository.
eladkal pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 16bb3f15960 fix: Handle `None` Task ID state when matching states in
`ExternalTaskSensor` (#66881)
16bb3f15960 is described below
commit 16bb3f15960f9d732e446b814097ebbebb288265
Author: Jake McGrath <[email protected]>
AuthorDate: Mon May 18 14:09:27 2026 -0400
fix: Handle `None` Task ID state when matching states in
`ExternalTaskSensor` (#66881)
* fix/issue-66877: Handle None task ID state
* Update sensor_helper.py
Co-authored-by: Nathan Hadfield <[email protected]>
---------
Co-authored-by: Nathan Hadfield <[email protected]>
---
.../providers/standard/utils/sensor_helper.py | 7 ++++-
.../unit/standard/utils/test_sensor_helper.py | 33 ++++++++++++++++++++++
2 files changed, 39 insertions(+), 1 deletion(-)
diff --git
a/providers/standard/src/airflow/providers/standard/utils/sensor_helper.py
b/providers/standard/src/airflow/providers/standard/utils/sensor_helper.py
index e1fc2a43403..20284b14ef2 100644
--- a/providers/standard/src/airflow/providers/standard/utils/sensor_helper.py
+++ b/providers/standard/src/airflow/providers/standard/utils/sensor_helper.py
@@ -144,6 +144,11 @@ def _get_count_by_matched_states(
):
count = 0
for _, task_states in run_id_task_state_map.items():
- if all(state in states for state in task_states.values() if state):
+ # Create this list such that len() can be checked in the conditional
(to handle empty inner)
+ matched_states: list = [state in states for state in
task_states.values()]
+
+ # An empty inner, such as {"r": {}}, results in count NOT being
incremented
+ if len(matched_states) > 0 and all(matched_states):
count += 1
+
return count
diff --git a/providers/standard/tests/unit/standard/utils/test_sensor_helper.py
b/providers/standard/tests/unit/standard/utils/test_sensor_helper.py
index 9f9bf634f38..8ba35d9b943 100644
--- a/providers/standard/tests/unit/standard/utils/test_sensor_helper.py
+++ b/providers/standard/tests/unit/standard/utils/test_sensor_helper.py
@@ -453,6 +453,39 @@ class TestSensorHelper:
0,
id="single_runid_with_no_success",
),
+ pytest.param(
+ {
+ "run_id_1": {"task_id_1": "success", "task_id_2": None},
+ },
+ ["success"],
+ 0,
+ id="single_runid_with_single_none",
+ ),
+ pytest.param(
+ {
+ "run_id_1": {},
+ },
+ ["success"],
+ 0,
+ id="single_runid_with_empty",
+ ),
+ pytest.param(
+ {
+ "run_id_1": {"task_id_1": None, "task_id_2": None},
+ },
+ ["success"],
+ 0,
+ id="single_runid_with_all_none",
+ ),
+ pytest.param(
+ {
+ "run_id_1": {"task_id_1": "success", "task_id_2": "success"},
+ "run_id_2": {"task_id_1": None, "task_id_2": None},
+ },
+ ["success"],
+ 1,
+ id="single_runid_with_all_none_success",
+ ),
],
)
@pytest.mark.skipif(not AIRFLOW_V_3_0_PLUS, reason="Test only for AF3")