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:

Reader pandas-2 payload pandas-3 payload
pandas 2.3.3 object, missing = None object, missing = None
pandas 3.0.5 str, missing = nan str, 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())

image image

Testing with pandas v3

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

potiuk and 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.
@vatsrahul1001 vatsrahul1001 added this to the Airflow 3.3.1 milestone Aug 4, 2026
@vatsrahul1001 vatsrahul1001 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
@vatsrahul1001 vatsrahul1001 reopened this Aug 4, 2026
@amoghrajesh

Copy link
Copy Markdown
Contributor Author

Ah I have to resolve conflicts

@amoghrajesh amoghrajesh self-assigned this Aug 5, 2026
@amoghrajesh

Copy link
Copy Markdown
Contributor Author

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

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

Copy link
Copy Markdown
Contributor Author

Failures fixed by #71145, merging this one.

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

github-actions Bot commented Aug 5, 2026

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.

Status Branch Result
v3-3-test Commit 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:providers area:task-sdk backport-to-v3-3-test Backport to v3-3-test provider:amazon AWS/Amazon - related issues provider:salesforce skip newsfragment check Skip the newsfragment PR number check type:misc/internal Changelog: Misc changes that should appear in change log

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants