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]

Reply via email to