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

   Running a Dag file as a script (`python my_dag.py dags test --show-dagrun`) 
goes through `DAG.cli()`. Its Dag-scoped parser drops the `dag_id` positional 
and passes the Dag object to the handler instead, so the parsed `Namespace` has 
no `dag_id` attribute at all. `dag_test` never needed it until it rendered the 
run: the task instance query read `args.dag_id`, so `--show-dagrun`, 
`--save-dagrun` and `--imgcat-dagrun` all raised `AttributeError: 'Namespace' 
object has no attribute 'dag_id'` after the Dag had already run, while the same 
command without a rendering flag succeeded. The regular `airflow dags test 
<dag_id> --show-dagrun` path was never affected.
   
   ### Fix
   
   The query now filters on the resolved Dag's id. On the regular path that is 
the same string as `args.dag_id` (the Dag was looked up by it), and on the 
`DAG.cli()` path it is the only id available. That lookup was the single reader 
of `args.dag_id` after the Dag is resolved, because `dag or 
get_bagged_dag(...)` short-circuits when a Dag is passed in.
   
   ### Testing
   
   - New `test_dag_test_show_dag_from_dag_cli` drives `dag_test` the way 
`DAG.cli()` does (Dag-scoped parser, Dag passed positionally), seeds a Dag run 
with one task instance via `dag_maker`, and asserts that instance reaches 
`render_dag`. Without the fix it fails on the same `AttributeError`; with it 
the whole file passes (107 tests).
   - `test_dag_test_show_dag` now gives its mocked Dag a real `dag_id`, since a 
`MagicMock` cannot be bound as a SQL parameter.
   - Reproduced end to end on a sqlite metadata DB with a one-task Dag in the 
dags folder: before the fix the `DAG.cli()` invocation exited 1 with the 
traceback above; after it prints the same DOT graph as `airflow dags test 
<dag_id> --show-dagrun`.
   
   Note for reproduction: the Dag file has to live inside a configured bundle 
and be serialized first (`airflow dags reserialize`), otherwise `dag.test()` 
fails earlier on both paths with "Cannot create DagRun ... because the dag is 
not serialized".
   
   Related: #72109 fixed the same `DAG.cli()` dispatch shape for `dags pause` 
and `dags unpause`.
   
   A pre-existing, separate limitation surfaced during review and is out of 
scope here: `@action_cli` snapshots `dag_id` from the `Namespace` before the 
handler runs, so audit `Log` rows for any `DAG.cli()` subcommand carry 
`dag_id=NULL`. The natural place to fix that is `DAG.cli()` itself.
   
   ---
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [X] Yes — Claude Code (Fable 5.1)
   
   Generated-by: Claude Code (Fable 5.1) following [the 
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
   


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