From 4950201da04a30ada526718a929c3258f1393bcd Mon Sep 17 00:00:00 2001 From: Aaron Critchley Date: Tue, 31 Jul 2018 10:53:40 +0100 Subject: [PATCH 1/5] Update base.py --- pandas/core/indexes/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 2a191ef76473b..2c8803d4f8741 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -147,6 +147,7 @@ def index_arithmetic_method(self, other): name = '__{name}__'.format(name=op.__name__) # TODO: docstring? + foo = 'bar' # Never commit, just testing CI return set_function_name(index_arithmetic_method, name, cls) From 6b022fd528d2c0a945e25038d1b618b768b0b878 Mon Sep 17 00:00:00 2001 From: Aaron Critchley Date: Mon, 27 Aug 2018 03:10:01 +0100 Subject: [PATCH 2/5] Fixing 22397 --- pandas/core/generic.py | 2 +- pandas/core/indexes/base.py | 1 - pandas/tests/generic/test_series.py | 6 ++++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 85bd6065314f4..dde3f51997256 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -8165,7 +8165,7 @@ def mask(self, cond, other=np.nan, inplace=False, axis=None, level=None, @Appender(_shared_docs['shift'] % _shared_doc_kwargs) def shift(self, periods=1, freq=None, axis=0): if periods == 0: - return self + return self.copy() block_axis = self._get_block_manager_axis(axis) if freq is None: diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index f1a542635c6d9..2a0f164887543 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -155,7 +155,6 @@ def index_arithmetic_method(self, other): name = '__{name}__'.format(name=op.__name__) # TODO: docstring? - foo = 'bar' # Never commit, just testing CI return set_function_name(index_arithmetic_method, name, cls) diff --git a/pandas/tests/generic/test_series.py b/pandas/tests/generic/test_series.py index 3393d7704e411..648014427cf18 100644 --- a/pandas/tests/generic/test_series.py +++ b/pandas/tests/generic/test_series.py @@ -227,3 +227,9 @@ def test_valid_deprecated(self): # GH18800 with tm.assert_produces_warning(FutureWarning): pd.Series([]).valid() + + def test_shift_always_copy(self): + # GH22397 + s = Series([1, 2, 3]) + assert s.shift(0) is not s + assert s.shift(1) is not s From 98e797ab57c315a0fef402d325dd977a1254a8d6 Mon Sep 17 00:00:00 2001 From: Aaron Critchley Date: Mon, 27 Aug 2018 03:16:25 +0100 Subject: [PATCH 3/5] Adding whatsnew --- doc/source/whatsnew/v0.24.0.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index 3e22084d98234..0cbbff9c1c843 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -501,6 +501,7 @@ Other API Changes - :class:`Index` subtraction will attempt to operate element-wise instead of raising ``TypeError`` (:issue:`19369`) - :class:`pandas.io.formats.style.Styler` supports a ``number-format`` property when using :meth:`~pandas.io.formats.style.Styler.to_excel` (:issue:`22015`) - :meth:`DataFrame.corr` and :meth:`Series.corr` now raise a ``ValueError`` along with a helpful error message instead of a ``KeyError`` when supplied with an invalid method (:issue:`22298`) +- :meth:`shift` will now always return a copy, instead of the previous behaviour of returning self when shifting by 0 (:issue:`22397`) .. _whatsnew_0240.deprecations: From c724461374e0faea34b4e96a2f2cdbb3c5cdf3e8 Mon Sep 17 00:00:00 2001 From: Aaron Critchley Date: Mon, 27 Aug 2018 17:01:29 +0100 Subject: [PATCH 4/5] PR sugestions, Datetime fix --- pandas/core/arrays/datetimelike.py | 2 +- pandas/tests/generic/test_series.py | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index eb8821382037d..12e1dd1052e0b 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -548,7 +548,7 @@ def shift(self, n, freq=None): if n == 0: # immutable so OK - return self + return self.copy() if self.freq is None: raise NullFrequencyError("Cannot shift with no freq") diff --git a/pandas/tests/generic/test_series.py b/pandas/tests/generic/test_series.py index 648014427cf18..14ebd9ad758ef 100644 --- a/pandas/tests/generic/test_series.py +++ b/pandas/tests/generic/test_series.py @@ -228,8 +228,11 @@ def test_valid_deprecated(self): with tm.assert_produces_warning(FutureWarning): pd.Series([]).valid() - def test_shift_always_copy(self): + @pytest.mark.parametrize("s", [ + Series([np.arange(5)]), + pd.date_range('1/1/2011', periods=24, freq='H') + ]) + @pytest.mark.parametrize("shift_size", [0, 1, 2]) + def test_shift_always_copy(self, s, shift_size): # GH22397 - s = Series([1, 2, 3]) - assert s.shift(0) is not s - assert s.shift(1) is not s + assert s.shift(shift_size) is not s From 8d2fc41a5e4dca8883769c6477652efbbd2a8d4c Mon Sep 17 00:00:00 2001 From: Aaron Critchley Date: Sun, 9 Sep 2018 23:01:11 +0100 Subject: [PATCH 5/5] Adding timedelta test --- pandas/tests/generic/test_series.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pandas/tests/generic/test_series.py b/pandas/tests/generic/test_series.py index 14ebd9ad758ef..f0c6c969f765a 100644 --- a/pandas/tests/generic/test_series.py +++ b/pandas/tests/generic/test_series.py @@ -230,9 +230,19 @@ def test_valid_deprecated(self): @pytest.mark.parametrize("s", [ Series([np.arange(5)]), - pd.date_range('1/1/2011', periods=24, freq='H') + pd.date_range('1/1/2011', periods=24, freq='H'), + pd.Series(range(5), index=pd.date_range("2017", periods=5)) ]) @pytest.mark.parametrize("shift_size", [0, 1, 2]) def test_shift_always_copy(self, s, shift_size): # GH22397 assert s.shift(shift_size) is not s + + @pytest.mark.parametrize("move_by_freq", [ + pd.Timedelta('1D'), + pd.Timedelta('1M'), + ]) + def test_datetime_shift_always_copy(self, move_by_freq): + # GH22397 + s = pd.Series(range(5), index=pd.date_range("2017", periods=5)) + assert s.shift(freq=move_by_freq) is not s