You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by "azharizz (via GitHub)" <gi...@apache.org> on 2026/07/27 15:24:35 UTC

[I] Issue relativedelta midnight serialization [airflow]

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: commits-unsubscribe@airflow.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org