This is an automated email from the ASF dual-hosted git repository.
jasonliu 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 e6448226ed5 Fix Enum-str interpolation in callback metrics in Python
3.11+ (#58168)
e6448226ed5 is described below
commit e6448226ed5a68ec4cedba377750c242e10f5729
Author: Ramit Kataria <[email protected]>
AuthorDate: Tue Nov 11 00:33:49 2025 -0800
Fix Enum-str interpolation in callback metrics in Python 3.11+ (#58168)
Followup to
https://github.com/apache/airflow/pull/57215#pullrequestreview-3426156849
Even though CallbackState is a string Enum and works fine with string
comparisons, the default __str__ method was changed in Python 3.11
causing test failures due to unexpected metric name:
airflow-core/tests/unit/models/test_callback.py:105: in test_get_metric_info
assert metric_info["stat"] == "deadline_alerts.callback_success"
E AssertionError: assert equals failed
E 'deadline_alerts.callback_CallbackState.SUCCESS'
'deadline_alerts.callback_success'
This overrides __str__ in CallbackState so it behaves consistently
across python versions.
---
airflow-core/src/airflow/models/callback.py | 5 ++++-
airflow-core/tests/unit/models/test_callback.py | 6 +++---
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/airflow-core/src/airflow/models/callback.py
b/airflow-core/src/airflow/models/callback.py
index bfaa43db6b2..15925e16dd4 100644
--- a/airflow-core/src/airflow/models/callback.py
+++ b/airflow-core/src/airflow/models/callback.py
@@ -50,6 +50,9 @@ class CallbackState(str, Enum):
SUCCESS = "success"
FAILED = "failed"
+ def __str__(self) -> str:
+ return self.value
+
ACTIVE_STATES = frozenset((CallbackState.QUEUED, CallbackState.RUNNING))
TERMINAL_STATES = frozenset((CallbackState.SUCCESS, CallbackState.FAILED))
@@ -153,7 +156,7 @@ class Callback(Base):
def queue(self):
self.state = CallbackState.QUEUED
- def get_metric_info(self, status: str, result: Any) -> dict:
+ def get_metric_info(self, status: CallbackState, result: Any) -> dict:
tags = {"result": result, **self.data}
tags.pop("prefix", None)
diff --git a/airflow-core/tests/unit/models/test_callback.py
b/airflow-core/tests/unit/models/test_callback.py
index 36e09713a3d..ed640ab9a97 100644
--- a/airflow-core/tests/unit/models/test_callback.py
+++ b/airflow-core/tests/unit/models/test_callback.py
@@ -100,7 +100,7 @@ class TestCallback:
def test_get_metric_info(self):
callback = TriggererCallback(TEST_ASYNC_CALLBACK,
prefix="deadline_alerts", dag_id=TEST_DAG_ID)
callback.data["kwargs"] = {"context": {"dag_id": TEST_DAG_ID},
"email": "[email protected]"}
- metric_info = callback.get_metric_info(CallbackState.SUCCESS.value,
"0")
+ metric_info = callback.get_metric_info(CallbackState.SUCCESS, "0")
assert metric_info["stat"] == "deadline_alerts.callback_success"
assert metric_info["tags"] == {
@@ -122,7 +122,7 @@ class TestTriggererCallback:
assert isinstance(retrieved, TriggererCallback)
assert retrieved.fetch_method == CallbackFetchMethod.IMPORT_PATH
assert retrieved.data == TEST_ASYNC_CALLBACK.serialize()
- assert retrieved.state == CallbackState.PENDING
+ assert retrieved.state == CallbackState.PENDING.value
assert retrieved.output is None
assert retrieved.priority_weight == 1
assert retrieved.created_at is not None
@@ -192,7 +192,7 @@ class TestExecutorCallback:
assert isinstance(retrieved, ExecutorCallback)
assert retrieved.fetch_method == CallbackFetchMethod.IMPORT_PATH
assert retrieved.data == TEST_SYNC_CALLBACK.serialize()
- assert retrieved.state == CallbackState.PENDING
+ assert retrieved.state == CallbackState.PENDING.value
assert retrieved.output is None
assert retrieved.priority_weight == 1
assert retrieved.created_at is not None