Skip to content

Commit 53a4b34

Browse files
TomAugspurgerPingviinituutti
authored andcommitted
Ensure Index._data is an ndarray (pandas-dev#23628)
1 parent f81f2b1 commit 53a4b34

File tree

3 files changed

+28
-15
lines changed

3 files changed

+28
-15
lines changed

pandas/core/indexes/base.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
ABCSeries, ABCDataFrame,
2020
ABCMultiIndex,
2121
ABCPeriodIndex, ABCTimedeltaIndex, ABCDatetimeIndex,
22-
ABCDateOffset)
22+
ABCDateOffset, ABCIndexClass)
2323
from pandas.core.dtypes.missing import isna, array_equivalent
2424
from pandas.core.dtypes.cast import maybe_cast_to_integer_array
2525
from pandas.core.dtypes.common import (
@@ -522,6 +522,12 @@ def _simple_new(cls, values, name=None, dtype=None, **kwargs):
522522
values = cls(values, name=name, dtype=dtype,
523523
**kwargs)._ndarray_values
524524

525+
if isinstance(values, (ABCSeries, ABCIndexClass)):
526+
# Index._data must always be an ndarray.
527+
# This is no-copy for when _values is an ndarray,
528+
# which should be always at this point.
529+
values = np.asarray(values._values)
530+
525531
result = object.__new__(cls)
526532
result._data = values
527533
result.name = name

pandas/tests/indexes/test_base.py

+7
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,13 @@ def test_constructor_cast(self):
504504
with pytest.raises(ValueError, match=msg):
505505
Index(["a", "b", "c"], dtype=float)
506506

507+
def test_constructor_unwraps_index(self, indices):
508+
if isinstance(indices, pd.MultiIndex):
509+
raise pytest.skip("MultiIndex has no ._data")
510+
a = indices
511+
b = type(a)(a)
512+
tm.assert_equal(a._data, b._data)
513+
507514
def test_view_with_args(self):
508515

509516
restricted = ['unicodeIndex', 'strIndex', 'catIndex', 'boolIndex',

pandas/tests/series/test_operators.py

+14-14
Original file line numberDiff line numberDiff line change
@@ -189,20 +189,7 @@ def test_scalar_na_logical_ops_corners(self):
189189
operator.and_,
190190
operator.or_,
191191
operator.xor,
192-
pytest.param(ops.rand_,
193-
marks=pytest.mark.xfail(reason="GH#22092 Index "
194-
"implementation returns "
195-
"Index",
196-
raises=AssertionError,
197-
strict=True)),
198-
pytest.param(ops.ror_,
199-
marks=pytest.mark.xfail(reason="GH#22092 Index "
200-
"implementation raises",
201-
raises=ValueError, strict=True)),
202-
pytest.param(ops.rxor,
203-
marks=pytest.mark.xfail(reason="GH#22092 Index "
204-
"implementation raises",
205-
raises=TypeError, strict=True))
192+
206193
])
207194
def test_logical_ops_with_index(self, op):
208195
# GH#22092, GH#19792
@@ -221,6 +208,19 @@ def test_logical_ops_with_index(self, op):
221208
result = op(ser, idx2)
222209
assert_series_equal(result, expected)
223210

211+
@pytest.mark.parametrize("op, expected", [
212+
(ops.rand_, pd.Index([False, True])),
213+
(ops.ror_, pd.Index([False, True])),
214+
(ops.rxor, pd.Index([])),
215+
])
216+
def test_reverse_ops_with_index(self, op, expected):
217+
# https://github.com/pandas-dev/pandas/pull/23628
218+
# multi-set Index ops are buggy, so let's avoid duplicates...
219+
ser = Series([True, False])
220+
idx = Index([False, True])
221+
result = op(ser, idx)
222+
tm.assert_index_equal(result, expected)
223+
224224
def test_logical_ops_label_based(self):
225225
# GH#4947
226226
# logical ops should be label based

0 commit comments

Comments
 (0)