Skip to content

Fix @task decorator to use identity check instead of truthiness#63788

Merged
eladkal merged 2 commits intoapache:mainfrom
Dev-iL:2603/fix-task-callable-truthiness
Mar 18, 2026
Merged

Fix @task decorator to use identity check instead of truthiness#63788
eladkal merged 2 commits intoapache:mainfrom
Dev-iL:2603/fix-task-callable-truthiness

Conversation

@Dev-iL
Copy link
Collaborator

@Dev-iL Dev-iL commented Mar 17, 2026

Summary

  • Change if python_callable: to if python_callable is not None: in task_decorator_factory() to avoid triggering __bool__ on callable objects.
  • Convert the task attribute on the serialized DAG test proxy from a class-level binding to a @property, preventing proxy leakage into the decorator callable.
  • Add test for callable objects with falsey __bool__.
  • Remove xfail marker from test_infer_multiple_outputs_forward_annotation (now passes).

Details

task_decorator_factory() used if python_callable: which invokes __bool__ on the argument. This is incorrect — a callable that happens to be falsey (e.g., __bool__ returns False) would incorrectly take the "no callable provided" path. The fix uses is not None for a proper identity check and consolidates the error handling.

The test proxy in dag_maker bound task = factory.dag.task as a class attribute, which caused proxy binding behavior to leak into the decorator when accessed via @dag.task. Converting to a @property ensures the real task decorator is returned without proxy interference.

related: #63520


Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Generated-by: Claude Opus 4.6 following the guidelines


  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.

@Dev-iL Dev-iL force-pushed the 2603/fix-task-callable-truthiness branch 2 times, most recently from 148c3f8 to 149ee6c Compare March 17, 2026 10:14
@Dev-iL Dev-iL mentioned this pull request Mar 17, 2026
6 tasks
@eladkal eladkal requested a review from uranusjr March 17, 2026 22:49
Dev-iL and others added 2 commits March 18, 2026 08:27
Changed the serialized Dag test proxy so task is exposed via a property returning `factory.dag.task`, instead of binding `task = factory.dag.task` on the proxy class.

The two fixes address the same Python 3.14 issue surface in serialized-DAG decorator tests:

- The proxy used by `dag_maker` can leak proxy/binding behavior into `@dag.task`.
- Python 3.14 is less forgiving when `inspect.signature()` and callable binding hit those proxy objects.
- The truthiness check in `task_decorator_factory()` made that worse by evaluating objects that only needed an identity check.

Together, the effect is:

- `@dag.task` gets the real task decorator from the underlying Dag, not a proxy-bound callable.
- `task_decorator_factory()` no longer triggers proxy resolution via boolean evaluation.
Co-authored-by: Tzu-ping Chung <uranusjr@gmail.com>
@Dev-iL Dev-iL force-pushed the 2603/fix-task-callable-truthiness branch from 1fff339 to 4960bee Compare March 18, 2026 06:27
@eladkal eladkal added this to the Airflow 3.2.0 milestone Mar 18, 2026
@eladkal eladkal merged commit 6d8e0e1 into apache:main Mar 18, 2026
255 of 257 checks passed
@Dev-iL Dev-iL deleted the 2603/fix-task-callable-truthiness branch March 18, 2026 18:37
fat-catTW pushed a commit to fat-catTW/airflow that referenced this pull request Mar 22, 2026
…he#63788)

* Avoid invoking truthiness on the `task` callable

Changed the serialized Dag test proxy so task is exposed via a property returning `factory.dag.task`, instead of binding `task = factory.dag.task` on the proxy class.

The two fixes address the same Python 3.14 issue surface in serialized-DAG decorator tests:

- The proxy used by `dag_maker` can leak proxy/binding behavior into `@dag.task`.
- Python 3.14 is less forgiving when `inspect.signature()` and callable binding hit those proxy objects.
- The truthiness check in `task_decorator_factory()` made that worse by evaluating objects that only needed an identity check.

Together, the effect is:

- `@dag.task` gets the real task decorator from the underlying Dag, not a proxy-bound callable.
- `task_decorator_factory()` no longer triggers proxy resolution via boolean evaluation.

* Update task-sdk/src/airflow/sdk/bases/decorator.py

Co-authored-by: Tzu-ping Chung <uranusjr@gmail.com>

---------

Co-authored-by: Tzu-ping Chung <uranusjr@gmail.com>
techcodie pushed a commit to techcodie/airflow that referenced this pull request Mar 23, 2026
…he#63788)

* Avoid invoking truthiness on the `task` callable

Changed the serialized Dag test proxy so task is exposed via a property returning `factory.dag.task`, instead of binding `task = factory.dag.task` on the proxy class.

The two fixes address the same Python 3.14 issue surface in serialized-DAG decorator tests:

- The proxy used by `dag_maker` can leak proxy/binding behavior into `@dag.task`.
- Python 3.14 is less forgiving when `inspect.signature()` and callable binding hit those proxy objects.
- The truthiness check in `task_decorator_factory()` made that worse by evaluating objects that only needed an identity check.

Together, the effect is:

- `@dag.task` gets the real task decorator from the underlying Dag, not a proxy-bound callable.
- `task_decorator_factory()` no longer triggers proxy resolution via boolean evaluation.

* Update task-sdk/src/airflow/sdk/bases/decorator.py

Co-authored-by: Tzu-ping Chung <uranusjr@gmail.com>

---------

Co-authored-by: Tzu-ping Chung <uranusjr@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants