diff --git a/airflow-core/src/airflow/serialization/serialized_objects.py b/airflow-core/src/airflow/serialization/serialized_objects.py index e3cf0f019d5d1..324e7c69ded0e 100644 --- a/airflow-core/src/airflow/serialization/serialized_objects.py +++ b/airflow-core/src/airflow/serialization/serialized_objects.py @@ -25,6 +25,7 @@ import enum import itertools import logging +import math import weakref from collections.abc import Collection, Generator, Iterable, Mapping from functools import cache, cached_property @@ -731,6 +732,9 @@ def serialize( # enum.IntEnum is an int instance, it causes json dumps error so we use its value. if isinstance(var, enum.Enum): return var.value + # These are not allowed in JSON. https://datatracker.ietf.org/doc/html/rfc8259#section-6 + if isinstance(var, float) and (math.isnan(var) or math.isinf(var)): + return str(var) return var elif isinstance(var, dict): return cls._encode( diff --git a/airflow-core/tests/unit/serialization/test_serialized_objects.py b/airflow-core/tests/unit/serialization/test_serialized_objects.py index a0167f1b7db46..7a8225a13cb40 100644 --- a/airflow-core/tests/unit/serialization/test_serialized_objects.py +++ b/airflow-core/tests/unit/serialization/test_serialized_objects.py @@ -18,6 +18,7 @@ from __future__ import annotations import json +import math from collections.abc import Iterator from datetime import datetime, timedelta @@ -205,6 +206,9 @@ def __len__(self) -> int: [ ("test_str", None, equals), (1, None, equals), + (math.nan, None, lambda a, b: b == "nan"), + (math.inf, None, lambda a, b: b == "inf"), + (-math.inf, None, lambda a, b: b == "-inf"), (timezone.utcnow(), DAT.DATETIME, equal_time), (timedelta(minutes=2), DAT.TIMEDELTA, equals), (Timezone("UTC"), DAT.TIMEZONE, lambda a, b: a.name == b.name),