Skip to content

Add support for pandas 3 based xcoms in airflow - #71103

Merged
amoghrajesh merged 7 commits into
apache:mainfrom
astronomer:serde-pandas-3
Aug 5, 2026
Merged

Add support for pandas 3 based xcoms in airflow#71103
amoghrajesh merged 7 commits into
apache:mainfrom
astronomer:serde-pandas-3

Conversation

@amoghrajesh

Copy link
Copy Markdown
Contributor

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

Supersedes #70558

Following discussion from Ash on https://lists.apache.org/thread/tbv4q04b3xx1hnmtq1b34tkzf43d5yqz

pandas 3 exposes its public classes from the pandas namespace, so a DataFrame is qualified as
pandas.DataFrame rather than pandas.core.frame.DataFrame. The serde registry is keyed on that
name and only knew the old one, so under pandas 3 no DataFrame could be pushed through XCom at
all
:

TypeError: cannot serialize object of type <class 'pandas.DataFrame'>

Both names are now registered, so a DataFrame written by either pandas version can be read by
either. Verified across all four combinations (writer x reader), with the payload written by one
interpreter and read by the other:

Readerpandas-2 payloadpandas-3 payload
pandas 2.3.3object, missing = Noneobject, missing = None
pandas 3.0.5str, missing = nanstr, missing = nan

The reader's pandas version decides the dtypes, not the writer's -- that, and the fact that a
component without this change cannot read a pandas-3-written DataFrame XCom, is what the
significant newsfragment documents.

Two provider tests also asserted on pandas 2 behaviour (object dtype, missing values stringified
to "nan" / "None") and are now version-aware. The production paths were already correct.

Reopened from #70558 -- carries the same three commits unchanged, plus one added test closing a
review gap: nothing previously forced deserialization through the registry entry for the other
pandas major's qualname, since serialize() only ever produces the qualname of whatever pandas is
actually installed. Depends on the separate revert of #70791 landing first.

related: #70558, #70791

Testing

Testing with pandas v2

DAG:

from __future__ import annotations
import pendulum
from airflow.sdk import DAG, task
@task
def push_df():
import pandas as pd
print(f"pandas version (push): {pd.__version__}")
return pd.DataFrame({"strings": ["a", "b", None], "ints": [1, 2, None]})
@task
def pull_df(df):
import pandas as pd
print(f"pandas version (pull): {pd.__version__}")
print(f"dtypes:\n{df.dtypes}")
print(f"strings column: {df['strings'].tolist()}")
print(f"ints column: {df['ints'].tolist()}")
with DAG(
dag_id="pandas3_xcom_check",
start_date=pendulum.datetime(2024, 1, 1, tz="UTC"),
schedule=None,
catchup=False,
):
pull_df(push_df())
imageimage

Testing with pandas v3

imageimage
  • 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.

potiukand others added 4 commits August 4, 2026 19:32
pandas 3 exposes its public classes from the `pandas` namespace, so a
DataFrame is now qualified as `pandas.DataFrame` rather than
`pandas.core.frame.DataFrame`. The serializer was registered only under the
old name, so pushing a DataFrame through XCom raised "cannot serialize
object of type <class 'pandas.DataFrame'>". Both names are registered so
values written by either version stay readable.
pandas 3 also infers a str column where it used to infer object, and keeps
its missing values as NA instead of stringifying them, which the amazon and
salesforce tests asserted on.
Deployments need to know that every component has to carry the pandas 3
support before pandas 3 reaches any worker, that a rollback strands the
XComs written in the meantime, and that a pulled DataFrame now takes its
dtypes from the reader's pandas version.
@vatsrahul1001vatsrahul1001 added this to the Airflow 3.3.1 milestone Aug 4, 2026
@vatsrahul1001vatsrahul1001 added type:misc/internal Changelog: Misc changes that should appear in change log skip newsfragment check Skip the newsfragment PR number check labels Aug 4, 2026
@amoghrajesh

Copy link
Copy Markdown
ContributorAuthor

Ah I have to resolve conflicts

@amoghrajesh

Copy link
Copy Markdown
ContributorAuthor

Compat failures are unrelated, likely fixed by #71145. I will review that

@amoghrajeshamoghrajesh added the backport-to-v3-3-test Backport to v3-3-test label Aug 5, 2026
@amoghrajesh

Copy link
Copy Markdown
ContributorAuthor

Failures fixed by #71145, merging this one.

@amoghrajesh
amoghrajesh merged commit 4091ccf into apache:mainAug 5, 2026
102 of 105 checks passed
@amoghrajesh
amoghrajesh deleted the serde-pandas-3 branch August 5, 2026 10:07
@github-actions

Copy link
Copy Markdown
Contributor

Backport failed to create: v3-3-test. View the failure log Run details

Note: As of Merging PRs targeted for Airflow 3.X
the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.

In matter of doubt please ask in #release-management Slack channel.

StatusBranchResult
v3-3-testCommit Link

You can attempt to backport this manually by running:

cherry_picker 4091ccf v3-3-test

This should apply the commit to the v3-3-test branch and leave the commit in conflict state marking
the files that need manual conflict resolution.

After you have resolved the conflicts, you can continue the backport process by running:

cherry_picker --continue

If you don't have cherry-picker installed, see the installation guide.

vatsrahul1001 added a commit that referenced this pull request Aug 5, 2026
Backport of #71100, which reverted "Limit pandas to < 3 for DataFrame XComs"
(#70791) on main. v3-3-test carried the cap via the #70912 backport; reverting
that commit removes the cap here too so the release branch matches main. The
pandas-3 XCom serializer support lands separately in #71169 (the #71103
backport) -- the same order main used (#71100 before #71103). uv.lock
regenerated with uv 0.12.1 to drop the pandas <3 specifier.
vatsrahul1001 pushed a commit that referenced this pull request Aug 5, 2026
* Keep DataFrame XComs working on pandas 3
pandas 3 exposes its public classes from the `pandas` namespace, so a
DataFrame is now qualified as `pandas.DataFrame` rather than
`pandas.core.frame.DataFrame`. The serializer was registered only under the
old name, so pushing a DataFrame through XCom raised "cannot serialize
object of type <class 'pandas.DataFrame'>". Both names are registered so
values written by either version stay readable.
pandas 3 also infers a str column where it used to infer object, and keeps
its missing values as NA instead of stringifying them, which the amazon and
salesforce tests asserted on.
* Document pandas 3 impact on DataFrame XComs
Deployments need to know that every component has to carry the pandas 3
support before pandas 3 reaches any worker, that a rollback strands the
XComs written in the meantime, and that a pulled DataFrame now takes its
dtypes from the reader's pandas version.
* Name the pandas 3 newsfragment after its own pull request
* Add regression test for the pandas 2/3 cross-version registry lookup
* rename newsfragment file
---------
Co-authored-by: Jarek Potiuk <jarek@potiuk.com>
(cherry picked from commit 4091ccf)
vatsrahul1001 pushed a commit that referenced this pull request Aug 5, 2026
* Keep DataFrame XComs working on pandas 3
pandas 3 exposes its public classes from the `pandas` namespace, so a
DataFrame is now qualified as `pandas.DataFrame` rather than
`pandas.core.frame.DataFrame`. The serializer was registered only under the
old name, so pushing a DataFrame through XCom raised "cannot serialize
object of type <class 'pandas.DataFrame'>". Both names are registered so
values written by either version stay readable.
pandas 3 also infers a str column where it used to infer object, and keeps
its missing values as NA instead of stringifying them, which the amazon and
salesforce tests asserted on.
* Document pandas 3 impact on DataFrame XComs
Deployments need to know that every component has to carry the pandas 3
support before pandas 3 reaches any worker, that a rollback strands the
XComs written in the meantime, and that a pulled DataFrame now takes its
dtypes from the reader's pandas version.
* Name the pandas 3 newsfragment after its own pull request
* Add regression test for the pandas 2/3 cross-version registry lookup
* rename newsfragment file
---------
(cherry picked from commit 4091ccf)
Co-authored-by: Jarek Potiuk <jarek@potiuk.com>
vatsrahul1001 added a commit that referenced this pull request Aug 5, 2026
Backport of #71100, which reverted "Limit pandas to < 3 for DataFrame XComs"
(#70791) on main. v3-3-test carried the cap via the #70912 backport; reverting
that commit removes the cap here too so the release branch matches main. The
pandas-3 XCom serializer support lands separately in #71169 (the #71103
backport) -- the same order main used (#71100 before #71103). uv.lock
regenerated with uv 0.12.1 to drop the pandas <3 specifier.
vatsrahul1001 pushed a commit that referenced this pull request Aug 5, 2026
* Keep DataFrame XComs working on pandas 3
pandas 3 exposes its public classes from the `pandas` namespace, so a
DataFrame is now qualified as `pandas.DataFrame` rather than
`pandas.core.frame.DataFrame`. The serializer was registered only under the
old name, so pushing a DataFrame through XCom raised "cannot serialize
object of type <class 'pandas.DataFrame'>". Both names are registered so
values written by either version stay readable.
pandas 3 also infers a str column where it used to infer object, and keeps
its missing values as NA instead of stringifying them, which the amazon and
salesforce tests asserted on.
* Document pandas 3 impact on DataFrame XComs
Deployments need to know that every component has to carry the pandas 3
support before pandas 3 reaches any worker, that a rollback strands the
XComs written in the meantime, and that a pulled DataFrame now takes its
dtypes from the reader's pandas version.
* Name the pandas 3 newsfragment after its own pull request
* Add regression test for the pandas 2/3 cross-version registry lookup
* rename newsfragment file
---------
(cherry picked from commit 4091ccf)
Co-authored-by: Jarek Potiuk <jarek@potiuk.com>
dabla pushed a commit to dabla/airflow that referenced this pull request Aug 14, 2026
* Keep DataFrame XComs working on pandas 3
pandas 3 exposes its public classes from the `pandas` namespace, so a
DataFrame is now qualified as `pandas.DataFrame` rather than
`pandas.core.frame.DataFrame`. The serializer was registered only under the
old name, so pushing a DataFrame through XCom raised "cannot serialize
object of type <class 'pandas.DataFrame'>". Both names are registered so
values written by either version stay readable.
pandas 3 also infers a str column where it used to infer object, and keeps
its missing values as NA instead of stringifying them, which the amazon and
salesforce tests asserted on.
* Document pandas 3 impact on DataFrame XComs
Deployments need to know that every component has to carry the pandas 3
support before pandas 3 reaches any worker, that a rollback strands the
XComs written in the meantime, and that a pulled DataFrame now takes its
dtypes from the reader's pandas version.
* Name the pandas 3 newsfragment after its own pull request
* Add regression test for the pandas 2/3 cross-version registry lookup
* rename newsfragment file
---------
Co-authored-by: Jarek Potiuk <jarek@potiuk.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:providersarea:task-sdkbackport-to-v3-3-testBackport to v3-3-testprovider:amazonAWS/Amazon - related issuesprovider:salesforceskip newsfragment checkSkip the newsfragment PR number checktype:misc/internalChangelog: Misc changes that should appear in change log

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@amoghrajesh@potiuk@vatsrahul1001