Skip to content

BUG: .isin on datetimelike indexes do not validate input of level parameter #26677

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jun 9, 2019
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.25.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ Datetimelike
- Bug in :func:`to_datetime` which does not replace the invalid argument with ``NaT`` when error is set to coerce (:issue:`26122`)
- Bug in adding :class:`DateOffset` with nonzero month to :class:`DatetimeIndex` would raise ``ValueError`` (:issue:`26258`)
- 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`)
- Bug in :meth:`isin` for datetimelike indexes; :class:`DatetimeIndex`, :class:`TimedeltaIndex` and :class:`PeriodIndex` where the ``levels`` parameter was ignored. (:issue:`26675`)
- 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'``
- Bug when comparing a :class:`PeriodIndex` against a zero-dimensional numpy array (:issue:`26689`)

Expand Down
3 changes: 3 additions & 0 deletions pandas/core/indexes/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,9 @@ def isin(self, values, level=None):
-------
is_contained : ndarray (boolean dtype)
"""
if level is not None:
self._validate_index_level(level)

if not isinstance(values, type(self)):
try:
values = type(self)(values)
Expand Down
27 changes: 14 additions & 13 deletions pandas/tests/indexes/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1791,22 +1791,23 @@ def test_isin_level_kwarg(self, level, index):
tm.assert_numpy_array_equal(expected,
index.isin(values, level='foobar'))

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

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

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