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

   A `pandas.DataFrame` does not survive an XCom round trip under pandas 3 the 
way it
   does under pandas 2, so this version of Airflow constrains pandas to `< 3` 
and
   refuses DataFrame XComs at runtime when a newer pandas is installed anyway.
   
   ### What breaks under pandas 3
   
   **The serializer is never reached.** pandas 3 exposes its public classes 
from the
   `pandas` namespace, so a DataFrame qualifies as `pandas.DataFrame` rather 
than
   `pandas.core.frame.DataFrame`. The serde registry is keyed on the latter, so 
it does
   not dispatch to the pandas serializer at all and the caller gets serde's 
generic
   
   ```
   TypeError: cannot serialize object of type <class 'pandas.DataFrame'>
   ```
   
   with nothing in it pointing at pandas or at what to do about it.
   
   **The dtypes differ.** Even once dispatch is fixed, the same payload reads 
back
   differently depending on the reader's pandas version — an `object` column 
becomes
   `str`, and missing values become `nan` rather than `None`. The *reader's* 
pandas
   version decides what a task receives, not the writer's, so a mixed-version
   deployment silently hands tasks data that differs from what was pushed.
   
   ### Approach
   
   `pandas<3` is declared where Airflow declares pandas — the `pandas` extra on
   `common-sql` (what `apache-airflow[pandas]` resolves to) and the task-sdk
   development group.
   
   **That constraint cannot be relied on by itself.** pandas is an optional
   dependency: a deployment can install pandas 3 directly, or pull it in through
   another package, and nothing in Airflow's metadata prevents it. So the 
constraint
   is backed by a runtime check that fails with a message naming pandas, the 
version
   found, and what to do.
   
   **The check needs the pandas 3 qualname registered to be reachable at all.**
   `pandas.DataFrame` is added to the registry *only* so that the request 
reaches this
   module and can be refused deliberately — not to support it. Without that 
entry the
   guard is dead code, because serde never dispatches.
   
   **Reads are refused as well as writes.** A payload written under pandas 2 
comes
   back with pandas 3 dtypes, so accepting it would give the task different 
data than
   was pushed, with no signal at all. An error on both sides is the safer 
outcome, and
   the write-side failure is the more recoverable of the two.
   
   ### Behaviour change
   
   With pandas >= 3 installed, pushing or pulling a `DataFrame` through XCom 
raises:
   
   ```
   RuntimeError: DataFrame XComs are not supported with pandas 3.0.5: this 
version of
   Airflow supports pandas < 3 for XCom serialization. Pin pandas < 3 in the
   environment that runs your tasks, or avoid passing DataFrames through XCom. 
...
   ```
   
   Previously the same situation produced an opaque serde `TypeError` on write, 
and —
   once dispatch was corrected — silently different dtypes on read. Nothing 
changes for
   pandas 2 users.
   
   **This defers pandas 3 support, it does not drop it.** Moving from pandas 2 
to
   pandas 3 is a deliberate migration for users to make, given the dtype 
changes.
   Airflow will enable it in a future release; see the follow-up PR linked in 
the
   comments.
   
   ### Test plan
   
   - [x] `task-sdk/tests/task_sdk/serde/test_serializers.py` — 11 pandas cases 
pass
   - [x] `test_pandas_3_dataframe_xcom_is_refused` — `3.0.0`, `3.0.5` and 
`4.1.2` all
         refused on **both** `serialize` and `deserialize`
   - [x] `test_pandas_3_dataframe_name_is_registered` — guards the reachability
         precondition, so the guard cannot silently become dead code if the 
registry
         entry is dropped
   - [x] `test_pandas_2_dataframe_xcom_still_round_trips` — `2.1.2` and `2.3.3`
         unaffected
   - [x] Existing pandas serde tests unchanged and passing
   - [x] `uv.lock` regenerated for the constraint
   - [x] `ruff check` / `ruff format` clean
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [X] Yes — Claude Opus 5 (1M context)
   
   Generated-by: Claude Opus 5 (1M context) following the guidelines at
   
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