This is an automated email from the ASF dual-hosted git repository.
shahar pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v3-1-test by this push:
new f5b6be4d581 [v3-1-test] fix type error when date_time is str (#60414)
(#60578)
f5b6be4d581 is described below
commit f5b6be4d5816747ca8c21482539c44b04c816e80
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Sat Jan 17 15:20:03 2026 +0200
[v3-1-test] fix type error when date_time is str (#60414) (#60578)
cherry picked from commit c58bdfca4b740fce2ee76f34b738c9b3b7307498
---------
Co-authored-by: Henry Chen <[email protected]>
Co-authored-by: pierrejeambrun <[email protected]>
---
.../airflow/serialization/serialized_objects.py | 7 ++++-
.../unit/serialization/test_serialized_objects.py | 35 ++++++++++++++++++++++
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/airflow-core/src/airflow/serialization/serialized_objects.py
b/airflow-core/src/airflow/serialization/serialized_objects.py
index fcc923ba592..62259d131f0 100644
--- a/airflow-core/src/airflow/serialization/serialized_objects.py
+++ b/airflow-core/src/airflow/serialization/serialized_objects.py
@@ -988,7 +988,12 @@ class BaseSerialization:
else:
raise TypeError(f"Invalid type {type_!s} in deserialization.")
- _deserialize_datetime = from_timestamp
+ @classmethod
+ def _deserialize_datetime(cls, arg):
+ if isinstance(arg, str):
+ return arg
+ return from_timestamp(arg)
+
_deserialize_timezone = parse_timezone
@classmethod
diff --git a/airflow-core/tests/unit/serialization/test_serialized_objects.py
b/airflow-core/tests/unit/serialization/test_serialized_objects.py
index bf9c4f34e44..1931e8df82d 100644
--- a/airflow-core/tests/unit/serialization/test_serialized_objects.py
+++ b/airflow-core/tests/unit/serialization/test_serialized_objects.py
@@ -726,6 +726,41 @@ class TestSerializedBaseOperator:
context={},
)
+ def test_deserialize_datetime_with_template_string(self):
+ """Test that _deserialize_datetime handles template strings
correctly."""
+ from airflow.providers.standard.operators.trigger_dagrun import
TriggerDagRunOperator
+ from airflow.serialization.serialized_objects import SerializedDAG
+
+ # Create a DAG with a mapped operator that has a template string for
logical_date
+ with DAG(DAG_ID, start_date=DEFAULT_DATE) as dag:
+ TriggerDagRunOperator.partial(
+ task_id="test_trigger",
+ logical_date="{{ ts_nodash_with_tz }}", # Template string
+ pool="default_pool",
+ ).expand(trigger_dag_id=["dag1", "dag2"])
+
+ # Serialize the DAG
+ serialized_dag = SerializedDAG.serialize_dag(dag)
+
+ # Deserialize the DAG
+ deserialized_dag = SerializedDAG.deserialize_dag(serialized_dag)
+
+ # Verify the operator was deserialized correctly
+ task = deserialized_dag.task_dict["test_trigger"]
+ assert task.partial_kwargs["logical_date"] == "{{ ts_nodash_with_tz }}"
+
+ def test_deserialize_datetime_with_timestamp(self):
+ """Test that _deserialize_datetime handles timestamp values
correctly."""
+ from airflow.serialization.serialized_objects import BaseSerialization
+
+ # Test with a numeric timestamp
+ timestamp = 1234567890.0
+ result = BaseSerialization._deserialize_datetime(timestamp)
+
+ # Should return a datetime object
+ assert isinstance(result, datetime)
+ assert result.timestamp() == timestamp
+
class TestKubernetesImportAvoidance:
"""Test that serialization doesn't import kubernetes unnecessarily."""