Skip to content

Commit 72ebc5d

Browse files
committed
CLN: remove broken Index.__inv__, add Index.__invert__
closes #22335
1 parent 49c6abb commit 72ebc5d

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

doc/source/whatsnew/v0.24.0.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,8 @@ Indexing
614614
- Fixed ``DataFrame[np.nan]`` when columns are non-unique (:issue:`21428`)
615615
- Bug when indexing :class:`DatetimeIndex` with nanosecond resolution dates and timezones (:issue:`11679`)
616616
- Bug where indexing with a Numpy array containing negative values would mutate the indexer (:issue:`21867`)
617+
- Method :meth:`Index.__inv__` was suppressed, as it provided the same functionality as :meth:`Index.__neg__` rather than what its name suggested; :meth:`Index.__invert__` was added instead, and the ``~`` operator now works (analogously as for :class:`Series`) (:issue:`21688`)
618+
-
617619

618620
Missing
619621
^^^^^^^
@@ -688,4 +690,3 @@ Other
688690
- :meth: `~pandas.io.formats.style.Styler.background_gradient` now also supports tablewise application (in addition to rowwise and columnwise) with ``axis=None`` (:issue:`15204`)
689691
-
690692
-
691-
-

pandas/core/indexes/base.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4689,7 +4689,7 @@ def _add_numeric_methods_disabled(cls):
46894689
cls.__neg__ = make_invalid_op('__neg__')
46904690
cls.__pos__ = make_invalid_op('__pos__')
46914691
cls.__abs__ = make_invalid_op('__abs__')
4692-
cls.__inv__ = make_invalid_op('__inv__')
4692+
cls.__invert__ = make_invalid_op('__invert__')
46934693

46944694
def _maybe_update_attributes(self, attrs):
46954695
""" Update Index attributes (e.g. freq) depending on op """
@@ -4786,7 +4786,7 @@ def _evaluate_numeric_unary(self):
47864786
cls.__neg__ = _make_evaluate_unary(operator.neg, '__neg__')
47874787
cls.__pos__ = _make_evaluate_unary(operator.pos, '__pos__')
47884788
cls.__abs__ = _make_evaluate_unary(np.abs, '__abs__')
4789-
cls.__inv__ = _make_evaluate_unary(lambda x: -x, '__inv__')
4789+
cls.__invert__ = _make_evaluate_unary(np.invert, '__invert__')
47904790

47914791
@classmethod
47924792
def _add_numeric_methods(cls):

pandas/tests/test_arithmetic.py

+36-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from pandas._libs.tslibs import IncompatibleFrequency
1616
from pandas import (
1717
timedelta_range,
18-
Timedelta, Timestamp, NaT, Series, TimedeltaIndex, DatetimeIndex,
18+
Timedelta, Timestamp, NaT, Series, Index, TimedeltaIndex, DatetimeIndex,
1919
DataFrame)
2020

2121

@@ -73,6 +73,41 @@ def box_df_fail(request):
7373
return request.param
7474

7575

76+
# ------------------------------------------------------------------
77+
# Numeric types Arithmetic Operations
78+
79+
class TestNumericOps(object):
80+
81+
@pytest.mark.parametrize('opname', ['neg', 'pos', 'abs', 'inv', 'invert'])
82+
@pytest.mark.parametrize('dtype', [int, float, object])
83+
def test_numeric_unary_ops(self, box, dtype, opname):
84+
# GH 22335
85+
data = [-2, 0, 4, 5]
86+
obj = box(data, dtype=dtype)
87+
88+
def call_method():
89+
return getattr(obj, '__{}__'.format(opname))()
90+
91+
if opname == 'inv':
92+
# GH 22335 - 'inv' was wrong and was removed
93+
pytest.raises(AttributeError, call_method)
94+
return
95+
if opname == 'invert' and dtype is float:
96+
# inversion of floats is undefined
97+
pytest.raises(TypeError, call_method)
98+
return
99+
if dtype in (object, bool) and isinstance(obj, Index):
100+
# GH 16873 - numeric operations on 'object' dtype might be removed
101+
# from NDFrames as well
102+
pytest.raises(TypeError, call_method)
103+
return
104+
105+
result = call_method()
106+
library_op = getattr(operator, opname)
107+
expected = box([library_op(i) for i in data], dtype=dtype)
108+
tm.assert_equal(result, expected)
109+
110+
76111
# ------------------------------------------------------------------
77112
# Timedelta64[ns] dtype Comparisons
78113

0 commit comments

Comments
 (0)