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")],

Reply via email to