Skip to content

TST: Extend datetime64 arith tests to array classes, fix several broken cases #23771

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 15 commits into from
Nov 19, 2018
Merged
Show file tree
Hide file tree
Changes from 12 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
5 changes: 5 additions & 0 deletions pandas/_libs/tslibs/offsets.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ def apply_index_wraps(func):
result = func(self, other)
if self.normalize:
result = result.to_period('D').to_timestamp()

if hasattr(other, 'name'):
# only relevant for datetimeindex
result.name = other.name

return result

# do @functools.wraps(func) manually since it doesn't work on cdef funcs
Expand Down
3 changes: 2 additions & 1 deletion pandas/_libs/tslibs/timestamps.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,8 @@ cdef class _Timestamp(datetime):
return -other.__sub__(self)

# a Timestamp-TimedeltaIndex -> yields a negative TimedeltaIndex
elif getattr(other, '_typ', None) == 'timedeltaindex':
elif getattr(other, '_typ', None) in ('timedeltaindex',
'timedeltaarray'):
return (-other).__add__(self)

elif other is NaT:
Expand Down
8 changes: 8 additions & 0 deletions pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,10 @@ def __add__(self, other):
else: # pragma: no cover
return NotImplemented

if is_timedelta64_dtype(result) and isinstance(result, np.ndarray):
from pandas.core.arrays import TimedeltaArrayMixin
# TODO: infer freq?
return TimedeltaArrayMixin(result)
return result

cls.__add__ = __add__
Expand Down Expand Up @@ -791,6 +795,10 @@ def __sub__(self, other):
else: # pragma: no cover
return NotImplemented

if is_timedelta64_dtype(result) and isinstance(result, np.ndarray):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

worth comments here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really. It would just say # wrap result in TimedeltaArray which is pretty redundant given the one-liner here

from pandas.core.arrays import TimedeltaArrayMixin
# TODO: infer freq?
return TimedeltaArrayMixin(result)
return result

cls.__sub__ = __sub__
Expand Down
5 changes: 5 additions & 0 deletions pandas/core/arrays/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ def __new__(cls, values, freq=None, tz=None, dtype=None):
# if dtype has an embedded tz, capture it
tz = dtl.validate_tz_from_dtype(dtype, tz)

if is_object_dtype(values):
# kludge; dispatch until the DatetimeArray constructor is complete
from pandas import DatetimeIndex
values = DatetimeIndex(values, freq=freq, tz=tz)

if isinstance(values, ABCSeries):
# extract to ndarray or DatetimeIndex
values = values._values
Expand Down
5 changes: 5 additions & 0 deletions pandas/core/arrays/timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,11 @@ def _evaluate_with_timedelta_like(self, other, op):

return NotImplemented

def __neg__(self):
if self.freq is not None:
return type(self)(-self._data, freq=-self.freq)
return type(self)(-self._data)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be made unnecessary by #23642.

# ----------------------------------------------------------------
# Conversion Methods - Vectorized analogues of Timedelta methods

Expand Down
4 changes: 4 additions & 0 deletions pandas/core/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,10 @@ def should_series_dispatch(left, right, op):
# numpy integer dtypes as timedelta64 dtypes in this scenario
return True

if is_datetime64_dtype(ldtype) and is_object_dtype(rdtype):
# in particular case where right is an array of DateOffsets
return True

return False


Expand Down
8 changes: 0 additions & 8 deletions pandas/tests/arithmetic/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,6 @@ def numeric_idx(request):
return request.param


@pytest.fixture
def tdser():
"""
Return a Series with dtype='timedelta64[ns]', including a NaT.
"""
return pd.Series(['59 Days', '59 Days', 'NaT'], dtype='timedelta64[ns]')


# ------------------------------------------------------------------
# Scalar Fixtures

Expand Down
Loading