@@ -2084,11 +2084,21 @@ def _validate_index_level(self, level) -> None:
2084
2084
verification must be done like in MultiIndex.
2085
2085
2086
2086
"""
2087
- if lib .is_integer (level ):
2088
- if isinstance (self .name , int ) and level == self .name :
2089
- return
2087
+ # Explicitly raise for missing/null values to match pandas convention
2088
+ if isna (level ):
2089
+ raise KeyError (
2090
+ "Requested level is NA/NaN/NaT, which is not a valid level name"
2091
+ )
2090
2092
2091
- if level < 0 and level != - 1 :
2093
+ # Standard integer check, but reject bool
2094
+ if lib .is_integer (level ) and not isinstance (level , bool ):
2095
+ # If the index itself is named as integer, accept
2096
+ if lib .is_integer (self .name ) and level == self .name :
2097
+ return
2098
+ # Only allow 0 and -1 for a single-level Index
2099
+ if level in (0 , - 1 ):
2100
+ return
2101
+ if level < 0 :
2092
2102
raise IndexError (
2093
2103
"Too many levels: Index has only 1 level, "
2094
2104
f"{ level } is not a valid level number"
@@ -2098,13 +2108,20 @@ def _validate_index_level(self, level) -> None:
2098
2108
f"Too many levels: Index has only 1 level, not { level + 1 } "
2099
2109
)
2100
2110
2101
- elif (
2102
- isinstance (level , str ) and isinstance (self .name , str ) and level != self .name
2111
+ # String level: only match if name is exactly the same string
2112
+ elif isinstance (level , str ) and not (
2113
+ isinstance (self .name , str ) and level == self .name
2103
2114
):
2104
2115
raise KeyError (
2105
2116
f"Requested level ({ level } ) does not match index name ({ self .name } )"
2106
2117
)
2107
2118
2119
+ # If level type is not int, str, or is NA, always raise KeyError
2120
+ else :
2121
+ raise KeyError (
2122
+ f"Requested level ({ level } ) is not a valid level name or number"
2123
+ )
2124
+
2108
2125
def _get_level_number (self , level ) -> int :
2109
2126
self ._validate_index_level (level )
2110
2127
return 0
0 commit comments