Skip to content

Commit 415cb70

Browse files
Limit pandas to < 3 for DataFrame XComs (#70791)
* 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>
1 parent 3b2445a commit 415cb70

44 files changed

Lines changed: 471 additions & 228 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
pandas is limited to ``< 3``; DataFrame XComs are refused on pandas 3
2+
3+
A ``pandas.DataFrame`` does not survive an XCom round trip under pandas 3 the way it does
4+
under pandas 2, so this version of Airflow constrains pandas to ``< 3`` and refuses DataFrame
5+
XComs at runtime when a newer pandas is installed anyway.
6+
7+
Two things change under pandas 3. Its public classes are exposed from the ``pandas``
8+
namespace, so a DataFrame qualifies as ``pandas.DataFrame`` rather than
9+
``pandas.core.frame.DataFrame`` and the XCom serializer registry -- keyed on the latter --
10+
never dispatches to the pandas serializer. And the dtypes differ: an ``object`` column reads
11+
back as ``str``, and missing values as ``nan`` rather than ``None``, so the *reader's* pandas
12+
version decides what a task receives rather than the writer's.
13+
14+
Because pandas is an optional dependency, the ``< 3`` constraint alone cannot be relied on --
15+
a deployment may install pandas 3 directly, or pull it in through another package. It is
16+
therefore backed by a runtime check.
17+
18+
**Behaviour changes:**
19+
20+
- With pandas 3 or newer installed, pushing **or** pulling a ``DataFrame`` through XCom now
21+
raises ``RuntimeError`` naming the installed pandas version and the supported range.
22+
Reads are refused as well as writes, because a payload written under pandas 2 reads back
23+
with pandas 3 dtypes and would otherwise hand the task different data than was pushed,
24+
with no signal.
25+
- Previously the same situation produced an opaque
26+
``TypeError: cannot serialize object of type <class 'pandas.DataFrame'>`` from the
27+
serializer registry, with nothing identifying pandas as the cause.
28+
- Deployments that pass DataFrames through XCom must pin ``pandas < 3`` in the environment
29+
that runs their tasks. Deployments that do not use DataFrame XComs are unaffected at
30+
runtime.
31+
- Nothing changes for pandas 2 users.
32+
33+
**This defers pandas 3 support rather than dropping it.** Moving from pandas 2 to pandas 3
34+
is a deliberate migration for users to make, given the dtype changes it brings to data that
35+
has already been written. Support for pandas 3 will be enabled in a future Airflow release.

providers/amazon/docs/index.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,9 @@ Install them when installing from PyPI. For example:
171171
pip install apache-airflow-providers-amazon[aiobotocore]
172172
173173
174-
==================== ============================================================================================================================================================
174+
==================== =====================================================================================================================================================================
175175
Extra Dependencies
176-
==================== ============================================================================================================================================================
176+
==================== =====================================================================================================================================================================
177177
``aiobotocore`` ``aiobotocore>=3.0.0``
178178
``cncf.kubernetes`` ``apache-airflow-providers-cncf-kubernetes>=7.2.0``
179179
``s3fs`` ``s3fs>=2023.10.0``
@@ -186,14 +186,14 @@ Extra Dependencies
186186
``imap`` ``apache-airflow-providers-imap``
187187
``microsoft.azure`` ``apache-airflow-providers-microsoft-azure``
188188
``mongo`` ``apache-airflow-providers-mongo``
189-
``pandas`` ``pandas>=2.1.2; python_version <"3.13"``, ``pandas>=2.2.3; python_version >="3.13" and python_version <"3.14"``, ``pandas>=2.3.3; python_version >="3.14"``
189+
``pandas`` ``pandas>=2.1.2,<3; python_version <"3.13"``, ``pandas>=2.2.3,<3; python_version >="3.13" and python_version <"3.14"``, ``pandas>=2.3.3,<3; python_version >="3.14"``
190190
``openlineage`` ``apache-airflow-providers-openlineage>=2.3.0``
191191
``salesforce`` ``apache-airflow-providers-salesforce``
192192
``ssh`` ``apache-airflow-providers-ssh``
193193
``standard`` ``apache-airflow-providers-standard``
194194
``common.messaging`` ``apache-airflow-providers-common-messaging>=2.0.0``
195195
``sqlalchemy`` ``sqlalchemy>=1.4.54``
196-
==================== ============================================================================================================================================================
196+
==================== =====================================================================================================================================================================
197197

198198
Downloading official packages
199199
-----------------------------

providers/amazon/pyproject.toml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,18 @@ dependencies = [
130130
"apache-airflow-providers-mongo"
131131
]
132132
"pandas" = [
133-
'pandas>=2.1.2; python_version <"3.13"',
134-
'pandas>=2.2.3; python_version >="3.13" and python_version <"3.14"',
135-
'pandas>=2.3.3; python_version >="3.14"',
133+
# pandas 3 changes the dtypes a DataFrame reads back with, so DataFrame XComs do not
134+
# round trip; capped until pandas 3 support lands.
135+
# Tracked at https://github.com/apache/airflow/pull/70558
136+
'pandas>=2.1.2,<3; python_version <"3.13"',
137+
# pandas 3 changes the dtypes a DataFrame reads back with, so DataFrame XComs do not
138+
# round trip; capped until pandas 3 support lands.
139+
# Tracked at https://github.com/apache/airflow/pull/70558
140+
'pandas>=2.2.3,<3; python_version >="3.13" and python_version <"3.14"',
141+
# pandas 3 changes the dtypes a DataFrame reads back with, so DataFrame XComs do not
142+
# round trip; capped until pandas 3 support lands.
143+
# Tracked at https://github.com/apache/airflow/pull/70558
144+
'pandas>=2.3.3,<3; python_version >="3.14"',
136145
]
137146
"openlineage" = [
138147
"apache-airflow-providers-openlineage>=2.3.0"

providers/apache/hdfs/README.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,19 @@ The package supports the following python versions: 3.10,3.11,3.12,3.13,3.14
5151
Requirements
5252
------------
5353

54-
========================================== ==================================================================
54+
========================================== ====================================================================
5555
PIP package Version required
56-
========================================== ==================================================================
56+
========================================== ====================================================================
5757
``apache-airflow`` ``>=2.11.0``
5858
``apache-airflow-providers-common-compat`` ``>=1.12.0``
5959
``hdfs[avro,dataframe,kerberos]`` ``>=2.5.4; python_version < "3.12"``
6060
``hdfs[avro,dataframe,kerberos]`` ``>=2.7.3; python_version >= "3.12"``
6161
``fastavro`` ``>=1.10.0; python_version >= "3.13" and python_version < "3.14"``
6262
``fastavro`` ``>=1.12.1; python_version >= "3.14"``
63-
``pandas`` ``>=2.1.2; python_version < "3.13"``
64-
``pandas`` ``>=2.2.3; python_version >= "3.13" and python_version < "3.14"``
65-
``pandas`` ``>=2.3.3; python_version >= "3.14"``
66-
========================================== ==================================================================
63+
``pandas`` ``>=2.1.2,<3; python_version < "3.13"``
64+
``pandas`` ``>=2.2.3,<3; python_version >= "3.13" and python_version < "3.14"``
65+
``pandas`` ``>=2.3.3,<3; python_version >= "3.14"``
66+
========================================== ====================================================================
6767

6868
The changelog for the provider package can be found in the
6969
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-apache-hdfs/4.12.1/changelog.html>`_.

providers/apache/hdfs/docs/index.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,19 +85,19 @@ Requirements
8585

8686
The minimum Apache Airflow version supported by this provider distribution is ``2.11.0``.
8787

88-
========================================== ==================================================================
88+
========================================== ====================================================================
8989
PIP package Version required
90-
========================================== ==================================================================
90+
========================================== ====================================================================
9191
``apache-airflow`` ``>=2.11.0``
9292
``apache-airflow-providers-common-compat`` ``>=1.12.0``
9393
``hdfs[avro,dataframe,kerberos]`` ``>=2.5.4; python_version < "3.12"``
9494
``hdfs[avro,dataframe,kerberos]`` ``>=2.7.3; python_version >= "3.12"``
9595
``fastavro`` ``>=1.10.0; python_version >= "3.13" and python_version < "3.14"``
9696
``fastavro`` ``>=1.12.1; python_version >= "3.14"``
97-
``pandas`` ``>=2.1.2; python_version < "3.13"``
98-
``pandas`` ``>=2.2.3; python_version >= "3.13" and python_version < "3.14"``
99-
``pandas`` ``>=2.3.3; python_version >= "3.14"``
100-
========================================== ==================================================================
97+
``pandas`` ``>=2.1.2,<3; python_version < "3.13"``
98+
``pandas`` ``>=2.2.3,<3; python_version >= "3.13" and python_version < "3.14"``
99+
``pandas`` ``>=2.3.3,<3; python_version >= "3.14"``
100+
========================================== ====================================================================
101101

102102
Downloading official packages
103103
-----------------------------

providers/apache/hdfs/pyproject.toml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,18 @@ dependencies = [
6565
'hdfs[avro,dataframe,kerberos]>=2.7.3;python_version>="3.12"',
6666
'fastavro>=1.10.0; python_version>="3.13" and python_version<"3.14"',
6767
'fastavro>=1.12.1; python_version>="3.14"',
68-
'pandas>=2.1.2; python_version <"3.13"',
69-
'pandas>=2.2.3; python_version >="3.13" and python_version <"3.14"',
70-
'pandas>=2.3.3; python_version >="3.14"',
68+
# pandas 3 changes the dtypes a DataFrame reads back with, so DataFrame XComs do not
69+
# round trip; capped until pandas 3 support lands.
70+
# Tracked at https://github.com/apache/airflow/pull/70558
71+
'pandas>=2.1.2,<3; python_version <"3.13"',
72+
# pandas 3 changes the dtypes a DataFrame reads back with, so DataFrame XComs do not
73+
# round trip; capped until pandas 3 support lands.
74+
# Tracked at https://github.com/apache/airflow/pull/70558
75+
'pandas>=2.2.3,<3; python_version >="3.13" and python_version <"3.14"',
76+
# pandas 3 changes the dtypes a DataFrame reads back with, so DataFrame XComs do not
77+
# round trip; capped until pandas 3 support lands.
78+
# Tracked at https://github.com/apache/airflow/pull/70558
79+
'pandas>=2.3.3,<3; python_version >="3.14"',
7180
]
7281

7382
[dependency-groups]

providers/apache/hive/README.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,19 @@ The package supports the following python versions: 3.10,3.11,3.12,3.13,3.14
5050
Requirements
5151
------------
5252

53-
========================================== =================================================================
53+
========================================== ====================================================================
5454
PIP package Version required
55-
========================================== =================================================================
55+
========================================== ====================================================================
5656
``apache-airflow`` ``>=2.11.0``
5757
``apache-airflow-providers-common-compat`` ``>=1.12.0``
5858
``apache-airflow-providers-common-sql`` ``>=1.32.0``
5959
``hmsclient`` ``>=0.1.0``
60-
``pandas`` ``>=2.1.2; python_version < "3.13"``
61-
``pandas`` ``>=2.2.3; python_version >= "3.13" and python_version < "3.14"``
62-
``pandas`` ``>=2.3.3; python_version >= "3.14"``
60+
``pandas`` ``>=2.1.2,<3; python_version < "3.13"``
61+
``pandas`` ``>=2.2.3,<3; python_version >= "3.13" and python_version < "3.14"``
62+
``pandas`` ``>=2.3.3,<3; python_version >= "3.14"``
6363
``pyhive[hive_pure_sasl]`` ``>=0.7.0``
6464
``jmespath`` ``>=0.7.0``
65-
========================================== =================================================================
65+
========================================== ====================================================================
6666

6767
Optional cross provider package dependencies
6868
--------------------------------------------

providers/apache/hive/docs/index.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,19 +99,19 @@ Requirements
9999

100100
The minimum Apache Airflow version supported by this provider distribution is ``2.11.0``.
101101

102-
========================================== =================================================================
102+
========================================== ====================================================================
103103
PIP package Version required
104-
========================================== =================================================================
104+
========================================== ====================================================================
105105
``apache-airflow`` ``>=2.11.0``
106106
``apache-airflow-providers-common-compat`` ``>=1.12.0``
107107
``apache-airflow-providers-common-sql`` ``>=1.32.0``
108108
``hmsclient`` ``>=0.1.0``
109-
``pandas`` ``>=2.1.2; python_version < "3.13"``
110-
``pandas`` ``>=2.2.3; python_version >= "3.13" and python_version < "3.14"``
111-
``pandas`` ``>=2.3.3; python_version >= "3.14"``
109+
``pandas`` ``>=2.1.2,<3; python_version < "3.13"``
110+
``pandas`` ``>=2.2.3,<3; python_version >= "3.13" and python_version < "3.14"``
111+
``pandas`` ``>=2.3.3,<3; python_version >= "3.14"``
112112
``pyhive[hive_pure_sasl]`` ``>=0.7.0``
113113
``jmespath`` ``>=0.7.0``
114-
========================================== =================================================================
114+
========================================== ====================================================================
115115

116116
Optional cross provider package dependencies
117117
--------------------------------------------

providers/apache/hive/pyproject.toml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,18 @@ dependencies = [
6363
"apache-airflow-providers-common-compat>=1.12.0",
6464
"apache-airflow-providers-common-sql>=1.32.0",
6565
"hmsclient>=0.1.0",
66-
'pandas>=2.1.2; python_version <"3.13"',
67-
'pandas>=2.2.3; python_version >="3.13" and python_version <"3.14"',
68-
'pandas>=2.3.3; python_version >="3.14"',
66+
# pandas 3 changes the dtypes a DataFrame reads back with, so DataFrame XComs do not
67+
# round trip; capped until pandas 3 support lands.
68+
# Tracked at https://github.com/apache/airflow/pull/70558
69+
'pandas>=2.1.2,<3; python_version <"3.13"',
70+
# pandas 3 changes the dtypes a DataFrame reads back with, so DataFrame XComs do not
71+
# round trip; capped until pandas 3 support lands.
72+
# Tracked at https://github.com/apache/airflow/pull/70558
73+
'pandas>=2.2.3,<3; python_version >="3.13" and python_version <"3.14"',
74+
# pandas 3 changes the dtypes a DataFrame reads back with, so DataFrame XComs do not
75+
# round trip; capped until pandas 3 support lands.
76+
# Tracked at https://github.com/apache/airflow/pull/70558
77+
'pandas>=2.3.3,<3; python_version >="3.14"',
6978
"pyhive[hive_pure_sasl]>=0.7.0",
7079
"jmespath>=0.7.0",
7180
]

providers/common/sql/docs/index.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,18 +141,18 @@ Install them when installing from PyPI. For example:
141141
pip install apache-airflow-providers-common-sql[pandas]
142142
143143
144-
================== =======================================================================================================================================================================
144+
================== ================================================================================================================================================================================
145145
Extra Dependencies
146-
================== =======================================================================================================================================================================
147-
``pandas`` ``pandas[sql-other]>=2.1.2; python_version <"3.13"``, ``pandas>=2.2.3; python_version >="3.13" and python_version <"3.14"``, ``pandas>=2.3.3; python_version >="3.14"``
146+
================== ================================================================================================================================================================================
147+
``pandas`` ``pandas[sql-other]>=2.1.2,<3; python_version <"3.13"``, ``pandas>=2.2.3,<3; python_version >="3.13" and python_version <"3.14"``, ``pandas>=2.3.3,<3; python_version >="3.14"``
148148
``openlineage`` ``apache-airflow-providers-openlineage``
149149
``polars`` ``polars>=1.26.0``
150150
``sqlalchemy`` ``sqlalchemy>=1.4.54``
151151
``amazon`` ``apache-airflow-providers-amazon``
152152
``datafusion`` ``datafusion>=50.0.0,<52.0.0``
153153
``pyiceberg-core`` ``pyiceberg-core>=0.8.0``
154154
``apache.iceberg`` ``apache-airflow-providers-apache-iceberg``
155-
================== =======================================================================================================================================================================
155+
================== ================================================================================================================================================================================
156156

157157
Downloading official packages
158158
-----------------------------

0 commit comments

Comments
 (0)