Skip to content

BUG: DTA/TDA/PA iadd/isub should actually be inplace #30505

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 2 commits into from
Dec 27, 2019
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
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v1.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ Datetimelike
- Bug in :class:`DatetimeIndex` addition when adding a non-optimized :class:`DateOffset` incorrectly dropping timezone information (:issue:`30336`)
- Bug in :meth:`DataFrame.drop` where attempting to drop non-existent values from a DatetimeIndex would yield a confusing error message (:issue:`30399`)
- Bug in :meth:`DataFrame.append` would remove the timezone-awareness of new data (:issue:`30238`)

- Bug in :class:`DatetimeArray`, :class:`TimedeltaArray`, and :class:`PeriodArray` where inplace addition and subtraction did not actually operate inplace (:issue:`24115`)

Timedelta
^^^^^^^^^
Expand Down
19 changes: 14 additions & 5 deletions pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -1311,14 +1311,23 @@ def __rsub__(self, other):

return -(self - other)

# FIXME: DTA/TDA/PA inplace methods should actually be inplace, GH#24115
def __iadd__(self, other): # type: ignore
# alias for __add__
return self.__add__(other)
result = self + other
self[:] = result[:]

if not is_period_dtype(self):
# restore freq, which is invalidated by setitem
self._freq = result._freq
return self

def __isub__(self, other): # type: ignore
# alias for __sub__
return self.__sub__(other)
result = self - other
self[:] = result[:]

if not is_period_dtype(self):
# restore freq, which is invalidated by setitem
self._freq = result._freq
return self

# --------------------------------------------------------------
# Comparison Methods
Expand Down
13 changes: 13 additions & 0 deletions pandas/tests/arrays/test_datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,19 @@ def test_setitem_raises(self):
with pytest.raises(TypeError, match="'value' should be a.* 'object'"):
arr[0] = object()

def test_inplace_arithmetic(self):
# GH#24115 check that iadd and isub are actually in-place
data = np.arange(10, dtype="i8") * 24 * 3600 * 10 ** 9
arr = self.array_cls(data, freq="D")

expected = arr + pd.Timedelta(days=1)
arr += pd.Timedelta(days=1)
tm.assert_equal(arr, expected)

expected = arr - pd.Timedelta(days=1)
arr -= pd.Timedelta(days=1)
tm.assert_equal(arr, expected)


class TestDatetimeArray(SharedTests):
index_cls = pd.DatetimeIndex
Expand Down