Repository: pandas-dev/pandas

Issue:
BUG: .isin on datetimelike indexes do not validate input of level parameter 
#### Code Sample, a copy-pastable example if possible

```python
index = pd.DatetimeIndex([], name='foo')
index.isin([], level='foobar')

```
#### Problem description

on master:
```
array([], dtype=bool)
```

on 0.23.4

```
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-82f8aeda6721> in <module>
      1 index = pd.DatetimeIndex([], name='foo')
----> 2 index.isin([], level='foobar')

TypeError: isin() got an unexpected keyword argument 'level'
```
#### Expected Output
to validate input and raise same message as other non-datetimelike indexes
```
KeyError: 'Level foobar must be same as name (foo)'
```

the api for `isin` is defined in #7892
#### Output of ``pd.show_versions()``

<details>

[paste the output of ``pd.show_versions()`` here below this line]

</details>



Discussion:

Resolving patch:
diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py
--- a/pandas/core/indexes/datetimelike.py
+++ b/pandas/core/indexes/datetimelike.py
@@ -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)


Test patch:
diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py
--- a/pandas/tests/indexes/test_base.py
+++ b/pandas/tests/indexes/test_base.py
@@ -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):