Skip to content

Commit 064bc12

Browse files
tehunterrhshadrach
authored andcommitted
Backport PR pandas-dev#58043: BUG: DataFrame slice selection treated as hashable in Python 3.12 pandas-dev#57500
1 parent 5fc3df3 commit 064bc12

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

doc/source/whatsnew/v2.3.4.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
.. _whatsnew_234:
2+
3+
What's new in 2.3.4 (November XX, 2025)
4+
----------------------------------------
5+
6+
These are the changes in pandas 2.3.3. See :ref:`release` for a full changelog
7+
including other versions of pandas.
8+
9+
{{ header }}
10+
11+
.. ---------------------------------------------------------------------------
12+
13+
Bug fixes
14+
^^^^^^^^^
15+
- Bug in :meth:`DataFrame.__getitem__` returning modified columns when called with ``slice`` in Python 3.12 (:issue:`57500`)
16+
17+
.. ---------------------------------------------------------------------------
18+
.. _whatsnew_234.contributors:
19+
20+
Contributors
21+
~~~~~~~~~~~~

pandas/core/frame.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4075,8 +4075,10 @@ def __getitem__(self, key):
40754075
key = lib.item_from_zerodim(key)
40764076
key = com.apply_if_callable(key, self)
40774077

4078-
if is_hashable(key) and not is_iterator(key):
4078+
if is_hashable(key) and not is_iterator(key) and not isinstance(key, slice):
40794079
# is_iterator to exclude generator e.g. test_getitem_listlike
4080+
# As of Python 3.12, slice is hashable which breaks MultiIndex (GH#57500)
4081+
40804082
# shortcut if the key is in columns
40814083
is_mi = isinstance(self.columns, MultiIndex)
40824084
# GH#45316 Return view if key is not duplicated

pandas/tests/frame/indexing/test_indexing.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,16 @@ def test_loc_setitem_boolean_mask_allfalse(self):
538538
result.loc[result.b.isna(), "a"] = result.a.copy()
539539
tm.assert_frame_equal(result, df)
540540

541+
def test_getitem_slice_empty(self):
542+
df = DataFrame([[1]], columns=MultiIndex.from_product([["A"], ["a"]]))
543+
result = df[:]
544+
545+
expected = DataFrame([[1]], columns=MultiIndex.from_product([["A"], ["a"]]))
546+
547+
tm.assert_frame_equal(result, expected)
548+
# Ensure df[:] returns a view of df, not the same object
549+
assert result is not df
550+
541551
def test_getitem_fancy_slice_integers_step(self):
542552
df = DataFrame(np.random.default_rng(2).standard_normal((10, 5)))
543553

0 commit comments

Comments
 (0)