This is an automated email from the ASF dual-hosted git repository.
potiuk 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 5aee0fb4ad5 Fix timedelta serde to accept int payloads (#72326)
5aee0fb4ad5 is described below
commit 5aee0fb4ad56d1dd4ce1361f2a06f41138a1e6e0
Author: Anmol Mishra <[email protected]>
AuthorDate: Wed Sep 23 04:00:07 2026 +0530
Fix timedelta serde to accept int payloads (#72326)
* Fix timedelta serde to accept int payloads
The datetime deserializer only accepted str|float for timedelta,
so integer second values (e.g. 2700 for 45 minutes) raised
TypeError and crashed the scheduler during DeadlineAlert
Dag-run creation. Accept int as well.
Fixes #72319
Signed-off-by: Anmol Mishra <[email protected]>
* Add regression test for int timedelta serde payloads
Covers int/float/str DATA payloads for datetime.timedelta
deserialization (issue #72319), as requested in review.
Signed-off-by: anmolxlight <[email protected]>
* Address review nit: name DeadlineAlert interval directly in docstring
Signed-off-by: anmolxlight <[email protected]>
---------
Signed-off-by: Anmol Mishra <[email protected]>
Signed-off-by: anmolxlight <[email protected]>
Co-authored-by: Anmol Mishra <[email protected]>
---
task-sdk/src/airflow/sdk/serde/serializers/datetime.py | 2 +-
task-sdk/tests/task_sdk/serde/test_serializers.py | 12 ++++++++++++
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/task-sdk/src/airflow/sdk/serde/serializers/datetime.py
b/task-sdk/src/airflow/sdk/serde/serializers/datetime.py
index 4b471c56ef7..3c7c3ebef9c 100644
--- a/task-sdk/src/airflow/sdk/serde/serializers/datetime.py
+++ b/task-sdk/src/airflow/sdk/serde/serializers/datetime.py
@@ -104,7 +104,7 @@ def deserialize(cls: type, version: int, data: dict | str)
-> datetime.date | da
if cls is DateTime and isinstance(data, dict):
return DateTime.fromtimestamp(float(data[TIMESTAMP]), tz=tz)
- if cls is datetime.timedelta and isinstance(data, str | float):
+ if cls is datetime.timedelta and isinstance(data, str | float | int):
return datetime.timedelta(seconds=float(data))
if cls is Date and isinstance(data, str):
diff --git a/task-sdk/tests/task_sdk/serde/test_serializers.py
b/task-sdk/tests/task_sdk/serde/test_serializers.py
index 30b9ea71d8d..ea252b66354 100644
--- a/task-sdk/tests/task_sdk/serde/test_serializers.py
+++ b/task-sdk/tests/task_sdk/serde/test_serializers.py
@@ -164,6 +164,18 @@ class TestSerializers:
nested = deserialize({"moment": legacy})
assert nested["moment"].timestamp() == moment.timestamp()
+ @pytest.mark.parametrize(
+ ("payload", "expected"),
+ [
+ pytest.param(2700, datetime.timedelta(minutes=45), id="int"),
+ pytest.param(2700.0, datetime.timedelta(minutes=45), id="float"),
+ pytest.param("2700", datetime.timedelta(minutes=45), id="str"),
+ ],
+ )
+ def test_deserialize_timedelta_numeric_payloads(self, payload, expected):
+ """Timedelta payloads may arrive as int (DeadlineAlert interval); see
#72319."""
+ assert deserialize({CLASSNAME: "datetime.timedelta", VERSION: 2, DATA:
payload}) == expected
+
@pytest.mark.parametrize(
("expr", "expected"),
[("1", "1"), ("52e4", "520000"), ("2e0", "2"), ("12e-2", "0.12"),
("12.34", "12.34")],