Skip to content

[v3-3-test] Limit pandas to < 3 for DataFrame XComs (#70791) - #70912

Merged
potiuk merged 1 commit into
apache:v3-3-testfrom
potiuk:backport-70791-v3-3-test
Aug 1, 2026
Merged

[v3-3-test] Limit pandas to < 3 for DataFrame XComs (#70791)#70912
potiuk merged 1 commit into
apache:v3-3-testfrom
potiuk:backport-70791-v3-3-test

Conversation

@potiuk

@potiuk potiuk commented Aug 1, 2026

Copy link
Copy Markdown
Member

Backport of #70791 to v3-3-test.

Under pandas 3 a DataFrame does not round trip through an XCom the way it does under
pandas 2, so the pandas dependency is capped at <3 everywhere Airflow declares it,
backed by a runtime check in the Task SDK serializer.

Conflict resolution

The cherry-pick conflicted in ten files. Every conflict came from unrelated main-only
changes rather than from the pandas work itself, so in each case the v3-3-test side was
kept and only the pandas cap was taken:

  • providers/exasol/pyproject.toml, providers/weaviate/pyproject.toml — kept the
    branch pins (pyexasol>=0.26.0, weaviate-client>=4.4.0); the main side also carried
    a pyexasol<2 cap and a weaviate-client>=4.16.0 bump that belong to other PRs.
  • providers/{amazon,common/sql,postgres}/docs/index.rstmain adds an "Optional
    dependencies" section generated by tooling that does not exist on v3-3-test, so these
    three files end up unchanged here.
  • exasol/weaviate README.rst and docs/index.rst — took the pandas rows and table
    widths, restored the branch's client pins.
  • uv.lock — regenerated with the branch's pinned uv 0.11.21 rather than hand-merged.

The lock diff is larger than the pandas rows alone because capping pandas collapses a
dual-version resolution fork, which in turn simplifies markers on caio, aiohttp,
typing-extensions and adbc-driver-manager. Regenerating the lock on an otherwise
pristine v3-3-test tree with the same uv produces a zero diff, confirming none of that
churn is uv-version drift.


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Opus 5 (1M context)

Generated-by: Claude Opus 5 (1M context) following the guidelines

* Limit pandas to < 3 for DataFrame XComs

Under pandas 3 a DataFrame does not round trip through an XCom the way it does
under pandas 2. The public classes moved to the `pandas` namespace, so the same
object qualifies as `pandas.DataFrame` rather than `pandas.core.frame.DataFrame`
and the serde registry -- keyed on the latter -- does not dispatch to the pandas
serializer at all. The caller gets serde's generic "cannot serialize object of
type" with nothing pointing at pandas. Beyond that, the dtypes differ: an
`object` column reads back as `str` and missing values as `nan` rather than
`None`, so the reader's pandas version, not the writer's, decides what a task
receives.

Declare `pandas<3` where Airflow declares pandas, and back it with a runtime
check, since pandas is an optional dependency and the constraint alone cannot be
relied on -- a deployment may install pandas 3 directly or pull it in through
another package.

The check needs the pandas 3 qualname registered to be reachable at all:
without `pandas.DataFrame` in the registry the request never reaches this module.
It is registered for that reason only, to refuse the value with a message that
names pandas and says what to do, not to support it.

Reads are refused as well as writes. A payload written under pandas 2 comes back
with pandas 3 dtypes, so accepting it would hand the task different data than was
pushed, with no signal.

Moving from pandas 2 to pandas 3 is a deliberate migration for users to make.
Support for it is not dropped, only deferred.

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

* Sync uv.lock with the pandas < 3 constraint

* Add significant newsfragment for the pandas < 3 limit

* Apply the pandas < 3 limit to the remaining providers

The XCom limit only binds where Airflow declares pandas. Thirteen providers pin
pandas independently of common-sql, so a deployment installing any of them could
still resolve pandas 3 and reach the runtime refusal rather than being held on a
supported version by the constraint.

pandas-gbq is deliberately untouched -- a different package, unaffected by this.

Provider READMEs and uv.lock are regenerated to match.

* Regenerate provider docs index for the pandas < 3 pins

The update-providers-build-files hook renders the extras table in each
provider's docs/index.rst from its pyproject dependencies. Fourteen providers
show the pandas extra, so the pin change widens those tables.

* Explain the pandas upper bound at every site and drop a vacuous test

contributing-docs/13_airflow_dependencies_and_extras.rst asks for a comment
saying why whenever a dependency is upper-bound, and AGENTS.md asks for the
tracking URL in the file rather than only in a PR comment. All 45 specifiers
across 15 files landed without either. Add the rationale and a pointer to the
pandas 3 support PR above each block, so whoever decides when the cap comes off
does not have to reconstruct it.

test_pandas_2_dataframe_xcom_still_round_trips passed unchanged on main: nothing
read pd.__version__ before this PR, so monkeypatching it to a 2.x value while the
installed pandas is already 2.x changed nothing observable, and the round trip is
already covered by test_pandas_serializers. Dropped.

---------

Co-authored-by: Rahul Vats <43964496+vatsrahul1001@users.noreply.github.com>
(cherry picked from commit 415cb70)
@potiuk
potiuk merged commit ae7c36b into apache:v3-3-test Aug 1, 2026
109 checks passed
@potiuk
potiuk deleted the backport-70791-v3-3-test branch August 1, 2026 16:33
@github-actions github-actions Bot added this to the Airflow 3.3.2 milestone Aug 1, 2026
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Hi maintainer, this PR was merged without a milestone set.
We've automatically set the milestone to Airflow 3.3.2 based on: merged to version branch
If this milestone is not correct, please update it to the appropriate milestone.

This comment was generated by Milestone Tag Assistant.

@vatsrahul1001 vatsrahul1001 added the type:misc/internal Changelog: Misc changes that should appear in change log label Aug 3, 2026
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.

2 participants