Skip to content
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,7 @@ Indexing
- Bug in :meth:`DataFrame.loc` coercing dtypes when setting values with a list indexer (:issue:`49159`)
- Bug in :meth:`Series.loc` raising error for out of bounds end of slice indexer (:issue:`50161`)
- Bug in :meth:`DataFrame.loc` raising ``ValueError`` with ``bool`` indexer and :class:`MultiIndex` (:issue:`47687`)
- Bug in :meth:`DataFrame.loc` raising ``IndexError`` when setting values for a pyarrow-backed column with a non-scalar indexer (:issue:`50085`)
- Bug in :meth:`DataFrame.__setitem__` raising ``ValueError`` when right hand side is :class:`DataFrame` with :class:`MultiIndex` columns (:issue:`49121`)
- Bug in :meth:`DataFrame.reindex` casting dtype to ``object`` when :class:`DataFrame` has single extension array column when re-indexing ``columns`` and ``index`` (:issue:`48190`)
- Bug in :meth:`DataFrame.iloc` raising ``IndexError`` when indexer is a :class:`Series` with numeric extension array dtype (:issue:`49521`)
Expand Down
7 changes: 5 additions & 2 deletions pandas/core/arrays/arrow/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,7 @@ def pyarrow_meth(data, skip_nulls, **kwargs):
return self.dtype.na_value
return result.as_py()

def __setitem__(self, key: int | slice | np.ndarray, value: Any) -> None:
def __setitem__(self, key, value) -> None:
"""Set one or more values inplace.

Parameters
Expand All @@ -972,6 +972,10 @@ def __setitem__(self, key: int | slice | np.ndarray, value: Any) -> None:
-------
None
"""
# GH50085: unwrap 1D indexers
if isinstance(key, tuple) and len(key) == 1:
key = key[0]

key = check_array_indexer(self, key)
value = self._maybe_convert_setitem_value(value)

Expand All @@ -997,7 +1001,6 @@ def __setitem__(self, key: int | slice | np.ndarray, value: Any) -> None:
return

indices = self._indexing_key_to_indices(key)

argsort = np.argsort(indices)
indices = indices[argsort]

Expand Down
2 changes: 1 addition & 1 deletion pandas/core/arrays/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ def __getitem__(
"""
raise AbstractMethodError(self)

def __setitem__(self, key: int | slice | np.ndarray, value: Any) -> None:
def __setitem__(self, key, value) -> None:
"""
Set one or more values inplace.

Expand Down
2 changes: 1 addition & 1 deletion pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ def _get_getitem_freq(self, key) -> BaseOffset | None:
# error: Argument 1 of "__setitem__" is incompatible with supertype
# "ExtensionArray"; supertype defines the argument type as "Union[int,
# ndarray]"
def __setitem__( # type: ignore[override]
def __setitem__(
self,
key: int | Sequence[int] | Sequence[bool] | slice,
value: NaTType | Any | Sequence[Any],
Expand Down
8 changes: 8 additions & 0 deletions pandas/tests/extension/base/setitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,3 +418,11 @@ def test_setitem_invalid(self, data, invalid_scalar):

with pytest.raises((ValueError, TypeError), match=msg):
data[:] = invalid_scalar

def test_setitem_2d_values(self, data):
# GH50085
original = data.copy()
df = pd.DataFrame({"a": data, "b": data})
df.loc[[0, 1], :] = df.loc[[1, 0], :].values
assert (df.loc[0, :] == original[1]).all()
assert (df.loc[1, :] == original[0]).all()