bujjibabukatta opened a new pull request, #71480:
URL: https://github.com/apache/airflow/pull/71480

   Closes #71187.
   
   ### Problem
   `[scheduler] create_cron_data_intervals` restores Airflow 2-style 
`logical_date`/data-interval
   semantics for `CronDataIntervalTimetable` and `DeltaDataIntervalTimetable`, 
but it doesn't extend
   to `run_id`. `generate_run_id()` is only defined once, on the shared base 
`Timetable` class, and
   always anchors to `run_after` — the AIP-76 default. So enabling the flag 
restores `logical_date`
   but silently leaves `run_id` on the new scheme, which breaks any workflow 
that parses `run_id` to
   recover the logical date (a common pattern carried over from Airflow 2).
   
   This is a documented gap, not a regression — `_create_timetable()` in
   `airflow.sdk.definitions.dag` confirms `_DataIntervalTimetable` subclasses 
are only instantiated
   when the flag is on, so the fix is naturally scoped by construction rather 
than an extra
   conditional.
   
   ### Fix
   Adds a `generate_run_id()` override on the shared `_DataIntervalTimetable` 
base in
   `airflow-core/src/airflow/timetables/interval.py`, covering both 
`CronDataIntervalTimetable` and
   `DeltaDataIntervalTimetable` symmetrically. It anchors to 
`data_interval.start` when a data
   interval is available, and falls back to the base (`run_after`-anchored) 
behavior otherwise, so it
   never raises on an unexpected `None`. 
`CronTriggerTimetable`/`DeltaTriggerTimetable` (the AIP-76
   default path) are untouched.
   
   This mirrors the `LogicalDateRunIdTimetable` workaround already posted in 
the issue by the
   reporter, who confirmed it works in their environment — promoted here into 
core so it applies
   without a custom DAG-level subclass.
   
   ### Tests
   Added three regression tests to 
`airflow-core/tests/unit/timetables/test_interval_timetable.py`:
   - `test_generate_run_id_anchors_to_data_interval_start` — `run_id` anchors 
to `data_interval.start`
     for both `CronDataIntervalTimetable` and `DeltaDataIntervalTimetable`
   - `test_generate_run_id_falls_back_without_data_interval` — falls back 
correctly when
     `data_interval=None`
   - `test_generate_run_id_default_timetable_unaffected` — confirms 
`CronTriggerTimetable` (default)
     is unaffected, i.e. zero regression to the majority code path
   
   ### Docs
   - `config.yml`: extended the `create_cron_data_intervals` description to 
note it now also covers
     `run_id`.
   - `authoring-and-scheduling/timetable.rst`: added a scoping note to the 
`run_id`/`logical_date`
     section — that section previously described this behavior as already true, 
which it wasn't until
     this PR.
   - `installation/upgrading_to_airflow3.rst`: added a note for 2→3 migrators 
who rely on `run_id`
     reflecting the logical date.
   
   ### Verification performed
   - `python -m py_compile` on changed files
   - `ruff check` / `ruff format --check` against the repo's actual 
`pyproject.toml` — clean
   - Installed the real dependency chain and imported the actual patched 
classes (not stand-ins) to
     confirm `run_id` anchoring, the `None` fallback, and that 
`CronTriggerTimetable` is unaffected —
     all as expected
   - Best-effort `mypy` (couldn't install the internal `airflow_mypy` plugin 
outside CI, so treat as a
     strong signal, not equivalent to the CI job)
   - **Not run**: the full pytest suite via Breeze (`tests/conftest.py` shells 
out to `uv` for
     provider dependency metadata, which needs the Breeze/CI environment) — 
please run
     `breeze testing tests 
airflow-core/tests/unit/timetables/test_interval_timetable.py` before
     merging
   
   ### Open question for maintainers
   The issue outlines two possible directions: (1) extend this flag to cover 
`run_id` (what this PR
   does), or (2) a more general `dag_run_policy`-style cluster policy hook, 
noted in the issue as
   possibly the preferred long-term design. This PR takes the smaller-scoped 
option since it's a pure
   addition with low regression risk, but happy to rework toward the hook 
approach if that's the
   preferred direction.
   
   One incidental finding while researching this: `[scheduler] 
create_delta_data_intervals` is
   documented in `config.yml` and listed in the CLI config commands, but I 
couldn't find anywhere in
   `_create_timetable()` (or elsewhere) that actually reads it to gate 
`DeltaDataIntervalTimetable`
   selection — `create_cron_data_intervals` appears to gate both cron and delta 
branches today.
   Flagging in case that's a known issue or I'm missing a call site; didn't 
want to fix it as a
   drive-by in this PR.
   
   Newsfragment will be added as a follow-up commit once this PR has a number, 
per the contribution
   guide.
   
   ---
   
   **AI disclosure:** All code, documentation, and test changes in this PR were 
written by me. An AI
   coding tool (Claude) was used only PR description and to run the new 
regression test cases locally and verify they
   pass against the patched code.


-- 
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]

Reply via email to