FrankYang0529 opened a new pull request, #72593:
URL: https://github.com/apache/airflow/pull/72593
## Why
- #59922 turned `airflow.utils.context` into a deprecation shim, but every
`add_deprecated_classes` target names only the module, for example `"Context":
"airflow.sdk.definitions.context"`.
- `deprecation_tools` splits the target on the last dot, so the lookup
becomes `getattr(airflow.sdk.definitions, "context")` and returns the submodule
itself. `from airflow.utils.context import Context` succeeds, but it shows
`TypeError: 'module' object is not callable` when users call it.
## How
- Fill in the full target for the three names that exist in the SDK:
`airflow.sdk.definitions.context.KNOWN_CONTEXT_KEYS`, `airflow.sdk.Context` and
`airflow.sdk.definitions.context.context_merge`.
- Drop `context_copy_partial`, because it doesn't exist.
## Verification
- Unit test: `uv run --frozen --project airflow-core pytest
airflow-core/tests/unit/utils/test_context.py`
- Integration test:
1. Create dags using old paths
```sh
mkdir -p files/dags
cat > files/dags/legacy_known_context_keys.py <<'EOF'
from __future__ import annotations
import pendulum
from airflow.sdk import DAG, BaseOperator
from airflow.utils.context import KNOWN_CONTEXT_KEYS
class KnownContextKeysOperator(BaseOperator):
"""Filter the runtime context with the KNOWN_CONTEXT_KEYS set."""
def execute(self, context):
self.log.info("KNOWN_CONTEXT_KEYS resolved to a %s",
type(KNOWN_CONTEXT_KEYS).__name__)
unknown = sorted(key for key in context if key not in
KNOWN_CONTEXT_KEYS)
self.log.info("context keys missing from KNOWN_CONTEXT_KEYS: %s",
unknown)
return unknown
with DAG(
dag_id="legacy_known_context_keys",
start_date=pendulum.datetime(2026, 1, 1, tz="UTC"),
schedule=None,
catchup=False,
):
KnownContextKeysOperator(task_id="check_known_context_keys")
EOF
cat > files/dags/legacy_context.py <<'EOF'
from __future__ import annotations
import pendulum
from airflow.sdk import DAG, BaseOperator
from airflow.utils.context import Context
class ContextOperator(BaseOperator):
"""Build a Context from a subset of the runtime context."""
def execute(self, context: Context):
self.log.info("Context resolved to %r", Context)
subset = Context(ds=context["ds"], run_id=context["run_id"])
self.log.info("Context(...) built: %s", subset)
return subset
with DAG(
dag_id="legacy_context",
start_date=pendulum.datetime(2026, 1, 1, tz="UTC"),
schedule=None,
catchup=False,
):
ContextOperator(task_id="build_context_subset")
EOF
cat > files/dags/legacy_context_merge.py <<'EOF'
from __future__ import annotations
import pendulum
from airflow.sdk import DAG, BaseOperator
from airflow.utils.context import context_merge
class ContextMergeOperator(BaseOperator):
"""Merge extra keys into the runtime context with context_merge."""
def execute(self, context):
self.log.info("context_merge resolved to %r", context_merge)
context_merge(context, region="tw", attempt=context["ti"].try_number)
self.log.info("after context_merge: region=%s attempt=%s",
context["region"], context["attempt"])
return {"region": context["region"], "attempt": context["attempt"]}
with DAG(
dag_id="legacy_context_merge",
start_date=pendulum.datetime(2026, 1, 1, tz="UTC"),
schedule=None,
catchup=False,
):
ContextMergeOperator(task_id="merge_into_context")
EOF
```
2. Run dags
```sh
breeze run --backend sqlite bash -c '
export AIRFLOW__CORE__DAGS_FOLDER=/files/dags
AIRFLOW__CORE__LOAD_EXAMPLES=False
airflow db migrate >/dev/null 2>&1
for d in legacy_known_context_keys legacy_context legacy_context_merge; do
airflow dags test "$d"; echo "##### $d exit=$?"
done'
```
On main branch, all dags fail and show `TypeError: 'module' object is not
callable`.
On this branch, all dags succeed and show
```
KNOWN_CONTEXT_KEYS resolved to a set
[airflow.task.operators.unusual_prefix_6c88b32f386c586108a845608f09d06a13ea6e33_legacy_known_context_keys.KnownContextKeysOperator]
context keys missing from KNOWN_CONTEXT_KEYS: []
Context resolved to <class 'airflow.sdk.definitions.context.Context'>
Context(...) built: {'ds': '...', 'run_id': 'manual__...'}
context_merge resolved to <function context_merge at 0x...>
after context_merge: region=tw attempt=1
```
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
<!--
Thank you for contributing!
Please provide above a brief description of the changes made in this pull
request.
Write a good git commit message following this guide:
https://chris.beams.io/posts/git-commit/
Please make sure that your code changes are covered with tests.
And in case of new features or big changes remember to adjust the
documentation.
For user-facing UI changes, please attach before/after screenshots (or a
short
screen recording) so reviewers can assess the visual impact.
Feel free to ping (in general) for the review if you do not see reaction for
a few days
(72 Hours is the minimum reaction time you can expect from volunteers) - we
sometimes miss notifications.
In case of an existing issue, reference it using one of the following:
* closes: #ISSUE
* related: #ISSUE
-->
---
##### Was generative AI tooling used to co-author this PR?
<!--
If generative AI tooling has been used in the process of authoring this PR,
please
change below checkbox to `[X]` followed by the name of the tool, uncomment
the "Generated-by".
-->
- [X] Yes - Claude Code
<!--
Generated-by: [Tool Name] following [the
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
-->
---
* Read the **[Pull Request
Guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#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](https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Improvement+Proposals))
is needed.
* When adding dependency, check compliance with the [ASF 3rd Party License
Policy](https://www.apache.org/legal/resolved.html#category-x).
* For significant user-facing changes create newsfragment:
`{pr_number}.significant.rst`, in
[airflow-core/newsfragments](https://github.com/apache/airflow/tree/main/airflow-core/newsfragments).
You can add this file in a follow-up commit after the PR is created so you
know the PR number.
--
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]