Skip to content

Commit 0f3e8e8

Browse files
simonjayhawkinsjreback
authored andcommitted
BUG: .isin on datetimelike indexes do not validate input of level parameter (#26677)
1 parent e935c70 commit 0f3e8e8

File tree

3 files changed

+18
-13
lines changed

3 files changed

+18
-13
lines changed

doc/source/whatsnew/v0.25.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,7 @@ Datetimelike
540540
- Bug in :func:`to_datetime` which does not replace the invalid argument with ``NaT`` when error is set to coerce (:issue:`26122`)
541541
- Bug in adding :class:`DateOffset` with nonzero month to :class:`DatetimeIndex` would raise ``ValueError`` (:issue:`26258`)
542542
- Bug in :func:`to_datetime` which raises unhandled ``OverflowError`` when called with mix of invalid dates and ``NaN`` values with ``format='%Y%m%d'`` and ``error='coerce'`` (:issue:`25512`)
543+
- Bug in :meth:`isin` for datetimelike indexes; :class:`DatetimeIndex`, :class:`TimedeltaIndex` and :class:`PeriodIndex` where the ``levels`` parameter was ignored. (:issue:`26675`)
543544
- Bug in :func:`to_datetime` which raises ``TypeError`` for ``format='%Y%m%d'`` when called for invalid integer dates with length >= 6 digits with ``errors='ignore'``
544545
- Bug when comparing a :class:`PeriodIndex` against a zero-dimensional numpy array (:issue:`26689`)
545546

pandas/core/indexes/datetimelike.py

+3
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,9 @@ def isin(self, values, level=None):
522522
-------
523523
is_contained : ndarray (boolean dtype)
524524
"""
525+
if level is not None:
526+
self._validate_index_level(level)
527+
525528
if not isinstance(values, type(self)):
526529
try:
527530
values = type(self)(values)

pandas/tests/indexes/test_base.py

+14-13
Original file line numberDiff line numberDiff line change
@@ -1791,22 +1791,23 @@ def test_isin_level_kwarg(self, level, index):
17911791
tm.assert_numpy_array_equal(expected,
17921792
index.isin(values, level='foobar'))
17931793

1794-
@pytest.mark.parametrize("level", [1, 10, -2])
1795-
@pytest.mark.parametrize("index", [
1796-
Index(['qux', 'baz', 'foo', 'bar']),
1797-
# Float64Index overrides isin, so must be checked separately
1798-
Float64Index([1.0, 2.0, 3.0, 4.0])])
1799-
def test_isin_level_kwarg_raises_bad_index(self, level, index):
1794+
@pytest.mark.parametrize("level", [2, 10, -3])
1795+
def test_isin_level_kwarg_bad_level_raises(self, level, indices):
1796+
index = indices
18001797
with pytest.raises(IndexError, match='Too many levels'):
18011798
index.isin([], level=level)
18021799

1803-
@pytest.mark.parametrize("level", [1.0, 'foobar', 'xyzzy', np.nan])
1804-
@pytest.mark.parametrize("index", [
1805-
Index(['qux', 'baz', 'foo', 'bar']),
1806-
Float64Index([1.0, 2.0, 3.0, 4.0])])
1807-
def test_isin_level_kwarg_raises_key(self, level, index):
1808-
with pytest.raises(KeyError, match='must be same as name'):
1809-
index.isin([], level=level)
1800+
@pytest.mark.parametrize("label", [1.0, 'foobar', 'xyzzy', np.nan])
1801+
def test_isin_level_kwarg_bad_label_raises(self, label, indices):
1802+
index = indices
1803+
if isinstance(index, MultiIndex):
1804+
index = index.rename(['foo', 'bar'])
1805+
msg = "'Level {} not found'"
1806+
else:
1807+
index = index.rename('foo')
1808+
msg = r"'Level {} must be same as name \(foo\)'"
1809+
with pytest.raises(KeyError, match=msg.format(label)):
1810+
index.isin([], level=label)
18101811

18111812
@pytest.mark.parametrize("empty", [[], Series(), np.array([])])
18121813
def test_isin_empty(self, empty):

0 commit comments

Comments
 (0)