Skip to content

CLN: Index methods incorrectly assuming object dtype #45767

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 1 commit into from
Feb 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,6 @@ def _outer_indexer(
_comparables: list[str] = ["name"]
_attributes: list[str] = ["name"]
_is_numeric_dtype: bool = False
_can_hold_na: bool = True
_can_hold_strings: bool = True

# Whether this index is a NumericIndex, but not a Int64Index, Float64Index,
Expand Down Expand Up @@ -2206,6 +2205,20 @@ def _get_grouper_for_level(self, mapper, *, level=None):
# --------------------------------------------------------------------
# Introspection Methods

@cache_readonly
@final
def _can_hold_na(self) -> bool:
if isinstance(self.dtype, ExtensionDtype):
if isinstance(self.dtype, IntervalDtype):
# FIXME(GH#45720): this is inaccurate for integer-backed
# IntervalArray, but without it other.categories.take raises
# in IntervalArray._cmp_method
return True
return self.dtype._can_hold_na
if self.dtype.kind in ["i", "u", "b"]:
return False
return True

@final
@property
def is_monotonic(self) -> bool:
Expand Down Expand Up @@ -2662,10 +2675,21 @@ def inferred_type(self) -> str_t:
return lib.infer_dtype(self._values, skipna=False)

@cache_readonly
@final
def _is_all_dates(self) -> bool:
"""
Whether or not the index values only consist of dates.
"""

if needs_i8_conversion(self.dtype):
return True
elif self.dtype != _dtype_obj:
# TODO(ExtensionIndex): 3rd party EA might override?
# Note: this includes IntervalIndex, even when the left/right
# contain datetime-like objects.
return False
elif self._is_multi:
return False
return is_datetime_array(ensure_object(self._values))

@cache_readonly
Expand Down Expand Up @@ -6159,6 +6183,10 @@ def _is_comparable_dtype(self, dtype: DtypeObj) -> bool:
"""
Can we compare values of the given dtype to our own?
"""
if self.dtype.kind == "b":
return dtype.kind == "b"
elif is_numeric_dtype(self.dtype):
return is_numeric_dtype(dtype)
return True

@final
Expand Down
6 changes: 0 additions & 6 deletions pandas/core/indexes/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,6 @@ class DatetimeIndexOpsMixin(NDArrayBackedExtensionIndex):
),
)

@property
def _is_all_dates(self) -> bool:
return True

# ------------------------------------------------------------------------

def equals(self, other: Any) -> bool:
Expand Down Expand Up @@ -151,8 +147,6 @@ def __contains__(self, key: Any) -> bool:
return False
return True

_can_hold_na = True

def _convert_tolerance(self, tolerance, target):
tolerance = np.asarray(to_timedelta(tolerance).to_numpy())
return super()._convert_tolerance(tolerance, target)
Expand Down
8 changes: 0 additions & 8 deletions pandas/core/indexes/interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -897,14 +897,6 @@ def _intersection_non_unique(self, other: IntervalIndex) -> IntervalIndex:

# --------------------------------------------------------------------

@property
def _is_all_dates(self) -> bool:
"""
This is False even when left/right contain datetime-like objects,
as the check is done on the Interval itself
"""
return False

def _get_engine_target(self) -> np.ndarray:
# Note: we _could_ use libjoin functions by either casting to object
# dtype or constructing tuples (faster than constructing Intervals)
Expand Down
4 changes: 0 additions & 4 deletions pandas/core/indexes/multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -1841,10 +1841,6 @@ def to_flat_index(self) -> Index:
"""
return Index(self._values, tupleize_cols=False)

@property
def _is_all_dates(self) -> bool:
return False

def is_lexsorted(self) -> bool:
warnings.warn(
"MultiIndex.is_lexsorted is deprecated as a public function, "
Expand Down
20 changes: 0 additions & 20 deletions pandas/core/indexes/numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
)
from pandas._typing import (
Dtype,
DtypeObj,
npt,
)
from pandas.util._decorators import (
Expand Down Expand Up @@ -91,14 +90,6 @@ class NumericIndex(Index):
_can_hold_strings = False
_is_backward_compat_public_numeric_index: bool = True

# error: Signature of "_can_hold_na" incompatible with supertype "Index"
@cache_readonly
def _can_hold_na(self) -> bool: # type: ignore[override]
if is_float_dtype(self.dtype):
return True
else:
return False

_engine_types: dict[np.dtype, type[libindex.IndexEngine]] = {
np.dtype(np.int8): libindex.Int8Engine,
np.dtype(np.int16): libindex.Int16Engine,
Expand Down Expand Up @@ -268,10 +259,6 @@ def _convert_tolerance(self, tolerance, target):
)
return tolerance

def _is_comparable_dtype(self, dtype: DtypeObj) -> bool:
# If we ever have BoolIndex or ComplexIndex, this may need to be tightened
return is_numeric_dtype(dtype)

@classmethod
def _assert_safe_casting(cls, data: np.ndarray, subarr: np.ndarray) -> None:
"""
Expand All @@ -284,13 +271,6 @@ def _assert_safe_casting(cls, data: np.ndarray, subarr: np.ndarray) -> None:
if not np.array_equal(data, subarr):
raise TypeError("Unsafe NumPy casting, you must explicitly cast")

@property
def _is_all_dates(self) -> bool:
"""
Checks that all the labels are datetime objects.
"""
return False

def _format_native_types(
self, *, na_rep="", float_format=None, decimal=".", quoting=None, **kwargs
):
Expand Down