Pandas version checks

  • [x] I have checked that this issue has not already been reported.

  • [x] I have confirmed this bug exists on the latest version of pandas.

  • [x] I have confirmed this bug exists on the main branch of pandas.

Reproducible Example

In [1]: import pandas as pd

In [2]: s = pd.Series([1,2,3], dtype='Int64[pyarrow]')

In [3]: s.iloc[pd.Index([0, 1])] = pd.Series([7, 8], dtype='Int64[pyarrow]')

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[3], line 1
----> 1 s.iloc[pd.Series([0, 1])] = pd.Series([7, 8], dtype='Int64[pyarrow]')

File ~/polars-api-compat-dev/.venv/lib/python3.12/site-packages/pandas/core/indexing.py:943, in _LocationIndexer.__setitem__(self, key, value)
    938 self._has_valid_setitem_indexer(key)
    940 iloc: _iLocIndexer = (
    941     cast("_iLocIndexer", self) if self.name == "iloc" else self.obj.iloc
    942 )
--> 943 iloc._setitem_with_indexer(indexer, value, self.name)

File ~/polars-api-compat-dev/.venv/lib/python3.12/site-packages/pandas/core/indexing.py:1969, in _iLocIndexer._setitem_with_indexer(self, indexer, value, name)
   1967     self._setitem_with_indexer_split_path(indexer, value, name)
   1968 else:
-> 1969     self._setitem_single_block(indexer, value, name)

File ~/polars-api-compat-dev/.venv/lib/python3.12/site-packages/pandas/core/indexing.py:2233, in _iLocIndexer._setitem_single_block(self, indexer, value, name)
   2230     value = self._align_frame(indexer, value)._values
   2232 # actually do the set
-> 2233 self.obj._mgr = self.obj._mgr.setitem(indexer=indexer, value=value)

File ~/polars-api-compat-dev/.venv/lib/python3.12/site-packages/pandas/core/internals/managers.py:603, in BaseBlockManager.setitem(self, indexer, value)
    599     # No need to split if we either set all columns or on a single block
    600     # manager
    601     self = self.copy()
--> 603 return self.apply("setitem", indexer=indexer, value=value)

File ~/polars-api-compat-dev/.venv/lib/python3.12/site-packages/pandas/core/internals/managers.py:441, in BaseBlockManager.apply(self, f, align_keys, **kwargs)
    439         applied = b.apply(f, **kwargs)
    440     else:
--> 441         applied = getattr(b, f)(**kwargs)
    442     result_blocks = extend_blocks(applied, result_blocks)
    444 out = type(self).from_blocks(result_blocks, self.axes)

File ~/polars-api-compat-dev/.venv/lib/python3.12/site-packages/pandas/core/internals/blocks.py:1659, in EABackedBlock.setitem(self, indexer, value)
   1656 check_setitem_lengths(indexer, value, values)
   1658 try:
-> 1659     values[indexer] = value
   1660 except (ValueError, TypeError):
   1661     if isinstance(self.dtype, IntervalDtype):
   1662         # see TestSetitemFloatIntervalWithIntIntervalValues

File ~/polars-api-compat-dev/.venv/lib/python3.12/site-packages/pandas/core/arrays/arrow/array.py:2184, in ArrowExtensionArray.__setitem__(self, key, value)
   2181     key = key[0]
   2183 key = check_array_indexer(self, key)
-> 2184 value = self._maybe_convert_setitem_value(value)
   2186 if com.is_null_slice(key):
   2187     # fast path (GH50248)
   2188     data = self._if_else(True, value, self._pa_array)

File ~/polars-api-compat-dev/.venv/lib/python3.12/site-packages/pandas/core/arrays/arrow/array.py:2408, in ArrowExtensionArray._maybe_convert_setitem_value(self, value)
   2406 """Maybe convert value to be pyarrow compatible."""
   2407 try:
-> 2408     value = self._box_pa(value, self._pa_array.type)
   2409 except pa.ArrowTypeError as err:
   2410     msg = f"Invalid value '{value!s}' for dtype '{self.dtype}'"

File ~/polars-api-compat-dev/.venv/lib/python3.12/site-packages/pandas/core/arrays/arrow/array.py:514, in ArrowExtensionArray._box_pa(cls, value, pa_type)
    512 if isinstance(value, pa.Scalar) or not is_list_like(value):
    513     return cls._box_pa_scalar(value, pa_type)
--> 514 return cls._box_pa_array(value, pa_type)

File ~/polars-api-compat-dev/.venv/lib/python3.12/site-packages/pandas/core/arrays/arrow/array.py:663, in ArrowExtensionArray._box_pa_array(cls, value, pa_type, copy)
    660     mask = is_pdna_or_none(arr_value)  # type: ignore[assignment]
    662 try:
--> 663     pa_array = pa.array(value, type=pa_type, mask=mask)
    664 except (pa.ArrowInvalid, pa.ArrowTypeError):
    665     # GH50430: let pyarrow infer type, then cast
    666     pa_array = pa.array(value, mask=mask)

File ~/polars-api-compat-dev/.venv/lib/python3.12/site-packages/pyarrow/array.pxi:312, in pyarrow.lib.array()

File ~/polars-api-compat-dev/.venv/lib/python3.12/site-packages/pyarrow/array.pxi:115, in pyarrow.lib._handle_arrow_array_protocol()

ValueError: Cannot specify a mask or a size when passing an object that is converted with the __arrow_array__ protocol.

Issue Description

The above raises on the latest nightly release, whereas it used to work until yesterday's (it also works with the latest stable release)

This was spotted in Narwhals where it broke the nightly CI

Expected Behavior

In [4]: s
Out[4]:
0   7
1   8
2   3
dtype: int64[pyarrow]

Installed Versions

INSTALLED VERSIONS ------------------ commit : e4ca40511c13cf845058066ce174d4e233840d92 python : 3.12.8 python-bits : 64 OS : Linux OS-release : 6.6.87.2-microsoft-standard-WSL2 Version : #1 SMP PREEMPT_DYNAMIC Thu Jun 5 18:30:46 UTC 2025 machine : x86_64 processor : x86_64 byteorder : little LC_ALL : None LANG : C.UTF-8 LOCALE : C.UTF-8 pandas : 3.0.0.dev0+2449.ge4ca40511c numpy : 2.4.0.dev0+git20250823.9b16cb3 dateutil : 2.9.0.post0 pip : None Cython : None sphinx : None IPython : 9.1.0 adbc-driver-postgresql: None adbc-driver-sqlite : None bs4 : None bottleneck : None fastparquet : None fsspec : 2025.9.0 html5lib : None hypothesis : 6.138.14 gcsfs : None jinja2 : 3.1.6 lxml.etree : None matplotlib : 3.10.3 numba : None numexpr : None odfpy : None openpyxl : None psycopg2 : None pymysql : None pyarrow : 21.0.0 pyiceberg : None pyreadstat : None pytest : 8.4.2 python-calamine : None pytz : 2025.2 pyxlsb : None s3fs : None scipy : 1.16.0 sqlalchemy : None tables : None tabulate : None xarray : None xlrd : None xlsxwriter : None zstandard : None qtpy : None pyqt5 : None

Comment From: rhshadrach

A git bisect points at

Author: jbrockmendel
Date:   Thu Sep 25 19:53:12 2025 -0700

    API: mode.nan_is_na to consistently distinguish NaN-vs-NA (#62077)

cc @jbrockmendel

Comment From: jbrockmendel

will take a look