Repository: pandas-dev/pandas
Pull request: BUG: df.iloc[:, :1] with EA column
- [x] closes #32957
- [x] tests added / passed
- [x] passes `black pandas`
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [x] whatsnew entry


Problem statement:
BUG: iloc on DataFrame[ea]
```
from pandas.tests.extension.decimal.test_decimal import *
arr = data.__wrapped__()
ser = pd.Series(arr)
df = pd.DataFrame({"a": ser})

>>> df.iloc[:, :1]
                                                   a
0  Decimal: 0.32737812402736643502265678762341849...
1                                                   
2                                                   
3                                                   

>>> df.iloc[:, :1].values
array([[Decimal('0.32737812402736643502265678762341849505901336669921875')]],
      dtype=object)
```

Maybe slicing on the wrong axis?

Hints from issue discussion:

Commit message: BUG: df.iloc[:, :1] with EA column

Patch to review:
diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py
index 935ff09585b17..1978a1185a550 100644
--- a/pandas/core/internals/blocks.py
+++ b/pandas/core/internals/blocks.py
@@ -1809,6 +1809,11 @@ def _slice(self, slicer):
             if not com.is_null_slice(slicer[0]):
                 raise AssertionError("invalid slicing for a 1-ndim categorical")
             slicer = slicer[1]
+        elif not isinstance(slicer, tuple) and self.ndim == 2:
+            # reached via getitem_block via _slice_take_blocks_ax0
+            # TODO(EA2D): wont be necessary with 2D EAs
+            # treat this like (slicer, slice(None)
+            slicer = slice(None)
 
         return self.values[slicer]
 
diff --git a/pandas/tests/extension/base/getitem.py b/pandas/tests/extension/base/getitem.py
index b08a64cc076b6..57929b9e77e37 100644
--- a/pandas/tests/extension/base/getitem.py
+++ b/pandas/tests/extension/base/getitem.py
@@ -40,6 +40,10 @@ def test_iloc_frame(self, data):
         result = df.iloc[:4, 0]
         self.assert_series_equal(result, expected)
 
+        # GH#32957 null slice along index, slice along rows
+        result = df.iloc[:, :1]
+        self.assert_frame_equal(result, df[["A"]])
+
     def test_loc_series(self, data):
         ser = pd.Series(data)
         result = ser.loc[:3]


Code review comments:
diff_hunk: @@ -1809,6 +1809,11 @@ def _slice(self, slicer):
             if not com.is_null_slice(slicer[0]):
                 raise AssertionError("invalid slicing for a 1-ndim categorical")
             slicer = slicer[1]
+        elif not isinstance(slicer, tuple) and self.ndim == 2:
+            # reached via getitem_block via _slice_take_blocks_ax0
+            # TODO(EA2D): wont be necessary with 2D EAs
+            # treat this like (slicer, slice(None)
+            slicer = slice(None)
path: pandas/core/internals/blocks.py
text: @user1:
What about slices that wouldn't include this column? Eg slice(1, 2, None) shouldn't just be converted to slice(None) ?

@author:
_slice_take_blocks_ax0 shouldnt call this in that case

@user1:
But it seems it does though. If I put a breakpoint here, it halts with `df.iloc[:, 1:2]`

@author:
comments addressed, i think

@user1:
Can you add this as a test case?

diff_hunk: @@ -40,6 +40,10 @@ def test_iloc_frame(self, data):
         result = df.iloc[:4, 0]
         self.assert_series_equal(result, expected)
 
+        # GH#32957 null slice along index, slice along rows
path: pandas/tests/extension/base/getitem.py
text: @user1:
```suggestion
        # GH#32957 null slice along index, slice along columns
```

? 
(or do I understand the "along" wrongly?)


@author:
good catch, thanks