Skip to content

Commit

Permalink
BUG: Do not use string Index like Datetimelike Index
Browse files Browse the repository at this point in the history
  • Loading branch information
nrebena committed Jun 14, 2020
1 parent 624a1be commit 9fc201d
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 7 deletions.
46 changes: 39 additions & 7 deletions pandas/core/indexes/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,16 @@ def equals(self, other) -> bool:
if not isinstance(other, ABCIndexClass):
return False
elif not isinstance(other, type(self)):
try:
other = type(self)(other)
except (ValueError, TypeError, OverflowError):
# e.g.
# ValueError -> cannot parse str entry, or OutOfBoundsDatetime
# TypeError -> trying to convert IntervalIndex to DatetimeIndex
# OverflowError -> Index([very_large_timedeltas])
if self._is_convertible_to_index_for_join(other):
try:
other = type(self)(other)
except (ValueError, TypeError, OverflowError):
# e.g.
# ValueError -> cannot parse str entry, or OutOfBoundsDatetime
# TypeError -> trying to convert IntervalIndex to DatetimeIndex
# OverflowError -> Index([very_large_timedeltas])
return False
else:
return False

if not is_dtype_equal(self.dtype, other.dtype):
Expand Down Expand Up @@ -596,6 +599,26 @@ def _convert_arr_indexer(self, keyarr):
converted_arr = com.asarray_tuplesafe(keyarr)
return converted_arr

@classmethod
def _is_convertible_to_index_for_join(cls, other: Index) -> bool:
"""
return a boolean whether I can attempt conversion to a
DatetimeIndex/TimedeltaIndex
"""
if isinstance(other, cls):
return False
elif len(other) > 0 and other.inferred_type not in (
"floating",
"mixed-integer",
"integer",
"integer-na",
"mixed-integer-float",
"mixed",
"string",
):
return True
return False


class DatetimeTimedeltaMixin(DatetimeIndexOpsMixin, Int64Index):
"""
Expand Down Expand Up @@ -903,6 +926,15 @@ def _is_convertible_to_index_for_join(cls, other: Index) -> bool:
return True
return False

def _wrap_joined_index(self, joined: np.ndarray, other):
assert other.dtype == self.dtype, (other.dtype, self.dtype)
name = get_op_result_name(self, other)

freq = self.freq if self._can_fast_union(other) else None
new_data = type(self._data)._simple_new(joined, dtype=self.dtype, freq=freq)

return type(self)._simple_new(new_data, name=name)

# --------------------------------------------------------------------
# List-Like Methods

Expand Down
17 changes: 17 additions & 0 deletions pandas/tests/indexes/datetimes/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,3 +408,20 @@ def test_isocalendar_returns_correct_values_close_to_new_year_with_tz():
dtype="UInt32",
)
tm.assert_frame_equal(result, expected_data_frame)


def test_datetimelike_string():
# Related to PR 32739
# Ensure we do not compare strings and datetimelike type.
date_string = "2020-04-13"
i1 = pd.Index([date_string])
i2 = pd.Index([pd.to_datetime(date_string)])

assert i1.equals(i2) is False
assert i2.equals(i1) is False

assert len(i1.intersection(i2)) == 0
assert len(i2.intersection(i1)) == 0

assert len(i1.union(i2)) == 2
assert len(i2.union(i1)) == 2

0 comments on commit 9fc201d

Please sign in to comment.