-
- Notifications
You must be signed in to change notification settings - Fork 19.3k
BUG: Fix Index.get_level_values() mishandling of boolean, pd.NA, np.nan, and pd.NaT levels #62175
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
3df788a fe07d18 f57ddc5 eca19a2 390f3ef 629bdf9 041994c d881247 3e63865 7f541de 703085e 3793317 d32d836 c03d480 19832f3 File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
…enhance error handling for boolean levels
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| | @@ -2085,20 +2085,24 @@ def _validate_index_level(self, level) -> None: | |||||||||||
| | ||||||||||||
| """ | ||||||||||||
| # Explicitly raise for missing/null values to match pandas convention | ||||||||||||
| # Also reject all NA-like values (np.nan, pd.NA, pd.NaT, etc.) | ||||||||||||
| if isna(level): | ||||||||||||
| raise KeyError( | ||||||||||||
| "Requested level is NA/NaN/NaT, which is not a valid level name" | ||||||||||||
| ) | ||||||||||||
| | ||||||||||||
| # Standard integer check, but reject bool | ||||||||||||
| if lib.is_integer(level) and not isinstance(level, bool): | ||||||||||||
| # If the index itself is named as integer, accept | ||||||||||||
| if lib.is_integer(self.name) and level == self.name: | ||||||||||||
| return | ||||||||||||
| # Only allow 0 and -1 for a single-level Index | ||||||||||||
| if level in (0, -1): | ||||||||||||
| return | ||||||||||||
| if level < 0: | ||||||||||||
| # Reject booleans unless the index name is actually a boolean and matches | ||||||||||||
| if isinstance(level, bool): | ||||||||||||
| ||||||||||||
| if level != self.name: | ||||||||||||
| raise KeyError( | ||||||||||||
| f"Requested level ({level}) does not match index name ({self.name})" | ||||||||||||
| ) | ||||||||||||
| return | ||||||||||||
| | ||||||||||||
| # Integer-like levels | ||||||||||||
| if lib.is_integer(level): | ||||||||||||
| # Exclude bools (already handled above) | ||||||||||||
| if level < 0 and level != -1: | ||||||||||||
| raise IndexError( | ||||||||||||
| "Too many levels: Index has only 1 level, " | ||||||||||||
| f"{level} is not a valid level number" | ||||||||||||
| | @@ -2107,21 +2111,15 @@ def _validate_index_level(self, level) -> None: | |||||||||||
| raise IndexError( | ||||||||||||
| f"Too many levels: Index has only 1 level, not {level + 1}" | ||||||||||||
| ) | ||||||||||||
| return | ||||||||||||
| | ||||||||||||
| Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that this is a better verification that validates what is expected from the documentation. Suggested change
| ||||||||||||
| # String level: only match if name is exactly the same string | ||||||||||||
| elif isinstance(level, str) and not ( | ||||||||||||
| isinstance(self.name, str) and level == self.name | ||||||||||||
| ): | ||||||||||||
| # For all other types, require exact match to index name | ||||||||||||
| # Use pandas' isna for both level and self.name to catch NA-like names | ||||||||||||
| if isna(self.name) or level != self.name: | ||||||||||||
| raise KeyError( | ||||||||||||
| f"Requested level ({level}) does not match index name ({self.name})" | ||||||||||||
| ) | ||||||||||||
| | ||||||||||||
| # If level type is not int, str, or is NA, always raise KeyError | ||||||||||||
| else: | ||||||||||||
| raise KeyError( | ||||||||||||
| f"Requested level ({level}) is not a valid level name or number" | ||||||||||||
| ) | ||||||||||||
| | ||||||||||||
| def _get_level_number(self, level) -> int: | ||||||||||||
| self._validate_index_level(level) | ||||||||||||
| return 0 | ||||||||||||
| | ||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if index.name is a na-like scalar?