Skip to content

Commit fdf513a

Browse files
committed
disallow numeric setlike operations on CategoricalIndex (GH10039)
1 parent 8f0f417 commit fdf513a

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

pandas/core/index.py

+16
Original file line numberDiff line numberDiff line change
@@ -2469,6 +2469,21 @@ def _evaluate_compare(self, other):
24692469
cls.__le__ = _make_compare('__le__')
24702470
cls.__ge__ = _make_compare('__ge__')
24712471

2472+
@classmethod
2473+
def _add_numericlike_set_methods_disabled(cls):
2474+
""" add in the numeric set-like methods to disable """
2475+
2476+
def _make_invalid_op(name):
2477+
2478+
def invalid_op(self, other=None):
2479+
raise TypeError("cannot perform {name} with this index type: {typ}".format(name=name,
2480+
typ=type(self)))
2481+
invalid_op.__name__ = name
2482+
return invalid_op
2483+
2484+
cls.__add__ = cls.__add__ = __iadd__ = _make_invalid_op('__add__')
2485+
cls.__sub__ = cls.__sub__ = __isub__ = _make_invalid_op('__sub__')
2486+
24722487
@classmethod
24732488
def _add_numeric_methods_disabled(cls):
24742489
""" add in numeric methods to disable """
@@ -3148,6 +3163,7 @@ def _add_accessors(cls):
31483163
overwrite=True)
31493164

31503165

3166+
CategoricalIndex._add_numericlike_set_methods_disabled()
31513167
CategoricalIndex._add_numeric_methods_disabled()
31523168
CategoricalIndex._add_logical_methods_disabled()
31533169
CategoricalIndex._add_comparison_methods()

pandas/tests/test_index.py

+19
Original file line numberDiff line numberDiff line change
@@ -1488,6 +1488,19 @@ def test_construction_with_dtype(self):
14881488
result = CategoricalIndex(idx, categories=idx, ordered=True)
14891489
tm.assert_index_equal(result, expected, exact=True)
14901490

1491+
def test_disallow_set_ops(self):
1492+
1493+
# GH 10039
1494+
# set ops (+/-) raise TypeError
1495+
idx = pd.Index(pd.Categorical(['a', 'b']))
1496+
1497+
self.assertRaises(TypeError, lambda : idx - idx)
1498+
self.assertRaises(TypeError, lambda : idx + idx)
1499+
self.assertRaises(TypeError, lambda : idx - ['a','b'])
1500+
self.assertRaises(TypeError, lambda : idx + ['a','b'])
1501+
self.assertRaises(TypeError, lambda : ['a','b'] - idx)
1502+
self.assertRaises(TypeError, lambda : ['a','b'] + idx)
1503+
14911504
def test_method_delegation(self):
14921505

14931506
ci = CategoricalIndex(list('aabbca'), categories=list('cabdef'))
@@ -3882,6 +3895,12 @@ def test_difference(self):
38823895
# - API change GH 8226
38833896
with tm.assert_produces_warning():
38843897
first - self.index[-3:]
3898+
with tm.assert_produces_warning():
3899+
self.index[-3:] - first
3900+
with tm.assert_produces_warning():
3901+
self.index[-3:] - first.tolist()
3902+
with tm.assert_produces_warning():
3903+
first.tolist() - self.index[-3:]
38853904

38863905
expected = MultiIndex.from_tuples(sorted(self.index[:-3].values),
38873906
sortorder=0,

0 commit comments

Comments
 (0)