azharizz opened a new issue, #70527:
URL: https://github.com/apache/airflow/issues/70527
### Under which category would you file this issue?
Airflow Core
### Apache Airflow version
Airflow 3.x
### What happened and how to reproduce it?
Serializing a `dateutil.relativedelta` that uses absolute time fields set to
`0` (e.g. `hour=0` for midnight) drops those fields. After the Dag is
deserialized, the schedule no longer snaps to midnight and keeps the base
datetime's clock time instead.
Root cause is in `encode_relativedelta`
(`airflow-core/src/airflow/serialization/encoders.py`):
```python
encoded = {k: v for k, v in var.__dict__.items() if not k.startswith("_")
and v}
```
The `and v` filter treats every falsy value as "unset". That is correct for
**relative** fields (`hours`, `days`, …), which default to `0`, but wrong for
**absolute** fields (`hour`, `minute`, `second`, `day`, …), which default to
`None`. For absolute fields, `0` is meaningful like e.g. `hour=0` means "snap
to midnight".
**Minimal repro:**
```python
from datetime import datetime
from dateutil.relativedelta import relativedelta, FR
from airflow.serialization.serialized_objects import BaseSerialization
delta = relativedelta(weekday=FR, hour=0, minute=0, second=0)
base = datetime(2024, 1, 10, 15, 30, 45)
print(base + delta)
# expected: 2024-01-12 00:00:00
round_tripped =
BaseSerialization.deserialize(BaseSerialization.serialize(delta))
print(base + round_tripped)
# actual today: 2024-01-12 15:30:45 (hour/minute/second lost)
```
Same bug hits any path that serializes intervals via `encode_relativedelta`
/ `encode_interval` (Dag schedules, timetables, serialized deltas).
Example Dag schedule that silently changes meaning after parse → serialize →
scheduler:
```python
from datetime import datetime
from dateutil.relativedelta import relativedelta, FR
from airflow.sdk import DAG
with DAG(
dag_id="example_friday_midnight",
start_date=datetime(2024, 1, 1),
schedule=relativedelta(weekday=FR, hour=0, minute=0, second=0),
catchup=False,
):
...
```
After serialization, the absolute `hour`/`minute`/`second` fields are gone,
so runs are planned at the previous interval's wall-clock time instead of
00:00:00.
### What you think should happen instead?
This is for the example:
Absolute fields with value `0` must survive the encode → decode round-trip.
Relative fields that are `0` can still be dropped (they mean "unset").
Expected encode for `relativedelta(weekday=FR, hour=0)`:
```python
{"hour": 0, "weekday": [4]}
```
not only `{"weekday": [4]}`.
### Operating System
Debian
### Deployment
Other
### Apache Airflow Provider(s)
_No response_
### Versions of Apache Airflow Providers
_No response_
### Official Helm Chart version
main (development)
### Kubernetes Version
_No response_
### Helm Chart configuration
_No response_
### Docker Image customizations
_No response_
### Anything else?
_No response_
### Are you willing to submit PR?
- [x] Yes I am willing to submit a PR!
### Code of Conduct
- [x] I agree to follow this project's [Code of
Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]