From f3dece047ea63acd9b68c1f90054cba6683d9b5f Mon Sep 17 00:00:00 2001 From: phofl Date: Tue, 20 Oct 2020 23:13:23 +0200 Subject: [PATCH 1/7] Add hash function to Tick class for offsets --- pandas/_libs/tslibs/offsets.pyx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx index 101e86bb37912..5469c0afd7036 100644 --- a/pandas/_libs/tslibs/offsets.pyx +++ b/pandas/_libs/tslibs/offsets.pyx @@ -752,6 +752,9 @@ cdef class Tick(SingleConstructorOffset): "Tick offset with `normalize=True` are not allowed." ) + def __hash__(self) -> int: + return hash(self._params) + # FIXME: Without making this cpdef, we get AttributeError when calling # from __mul__ cpdef Tick _next_higher_resolution(Tick self): From fdd983ccc0464368bd329a559ed4101d02047c0c Mon Sep 17 00:00:00 2001 From: phofl Date: Tue, 20 Oct 2020 23:24:01 +0200 Subject: [PATCH 2/7] Add tests and whatsnew --- doc/source/whatsnew/v1.1.4.rst | 1 + pandas/tests/tseries/offsets/test_ticks.py | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/doc/source/whatsnew/v1.1.4.rst b/doc/source/whatsnew/v1.1.4.rst index c3868fd147974..c426400a0570c 100644 --- a/doc/source/whatsnew/v1.1.4.rst +++ b/doc/source/whatsnew/v1.1.4.rst @@ -22,6 +22,7 @@ Fixed regressions - Fixed regression in :class:`RollingGroupby` causing a segmentation fault with Index of dtype object (:issue:`36727`) - Fixed regression in :meth:`DataFrame.resample(...).apply(...)` raised ``AttributeError`` when input was a :class:`DataFrame` and only a :class:`Series` was evaluated (:issue:`36951`) - Fixed regression in :class:`PeriodDtype` comparing both equal and unequal to its string representation (:issue:`37265`) +- Fixed regression in :meth:`pd.offsets.Day() ` and associated functions caused that offsets were no longer hashable (:issue:` .. --------------------------------------------------------------------------- diff --git a/pandas/tests/tseries/offsets/test_ticks.py b/pandas/tests/tseries/offsets/test_ticks.py index c1621669bffd0..82dc4cecf50f0 100644 --- a/pandas/tests/tseries/offsets/test_ticks.py +++ b/pandas/tests/tseries/offsets/test_ticks.py @@ -369,3 +369,8 @@ def test_compare_ticks_to_timedeltalike(cls): assert not off > other assert off <= other assert off >= other + + +def test_offsets_hashable(): + # GH: 37267 + assert offsets.Day() is not None From a7611de63183fa033e73b45477125d50f3f04a0c Mon Sep 17 00:00:00 2001 From: phofl Date: Wed, 21 Oct 2020 00:09:23 +0200 Subject: [PATCH 3/7] Fix whatsnew --- doc/source/whatsnew/v1.1.4.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.1.4.rst b/doc/source/whatsnew/v1.1.4.rst index c426400a0570c..b820c9f167abf 100644 --- a/doc/source/whatsnew/v1.1.4.rst +++ b/doc/source/whatsnew/v1.1.4.rst @@ -22,7 +22,7 @@ Fixed regressions - Fixed regression in :class:`RollingGroupby` causing a segmentation fault with Index of dtype object (:issue:`36727`) - Fixed regression in :meth:`DataFrame.resample(...).apply(...)` raised ``AttributeError`` when input was a :class:`DataFrame` and only a :class:`Series` was evaluated (:issue:`36951`) - Fixed regression in :class:`PeriodDtype` comparing both equal and unequal to its string representation (:issue:`37265`) -- Fixed regression in :meth:`pd.offsets.Day() ` and associated functions caused that offsets were no longer hashable (:issue:` +- Fixed regression in :meth:`pd.offsets.Day() ` and associated functions caused that offsets were no longer hashable (:issue:`37267`) .. --------------------------------------------------------------------------- From 9bac84c53ad7190a9ad0ec944a32cb2fa89cc61d Mon Sep 17 00:00:00 2001 From: phofl Date: Wed, 21 Oct 2020 00:56:51 +0200 Subject: [PATCH 4/7] Add offsets function and hash function --- pandas/tests/tseries/offsets/test_offsets.py | 4 ++++ pandas/tests/tseries/offsets/test_ticks.py | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/pandas/tests/tseries/offsets/test_offsets.py b/pandas/tests/tseries/offsets/test_offsets.py index 6a87c05384689..067c5f2079ed1 100644 --- a/pandas/tests/tseries/offsets/test_offsets.py +++ b/pandas/tests/tseries/offsets/test_offsets.py @@ -678,6 +678,10 @@ def test_isAnchored_deprecated(self, offset_types): expected = off.is_anchored() assert result == expected + def test_offsets_hashable(self, offset_types): + # GH: 37267 + assert hash(offset_types) is not None + class TestDateOffset(Base): def setup_method(self, method): diff --git a/pandas/tests/tseries/offsets/test_ticks.py b/pandas/tests/tseries/offsets/test_ticks.py index 82dc4cecf50f0..c1621669bffd0 100644 --- a/pandas/tests/tseries/offsets/test_ticks.py +++ b/pandas/tests/tseries/offsets/test_ticks.py @@ -369,8 +369,3 @@ def test_compare_ticks_to_timedeltalike(cls): assert not off > other assert off <= other assert off >= other - - -def test_offsets_hashable(): - # GH: 37267 - assert offsets.Day() is not None From e5b66a0791c88f73f9375d4fe899543081889cca Mon Sep 17 00:00:00 2001 From: phofl Date: Wed, 21 Oct 2020 21:18:46 +0200 Subject: [PATCH 5/7] Adress review comments --- doc/source/whatsnew/v1.1.4.rst | 2 +- pandas/_libs/tslibs/offsets.pyx | 7 ++++--- pandas/tests/tseries/offsets/test_offsets.py | 3 ++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/doc/source/whatsnew/v1.1.4.rst b/doc/source/whatsnew/v1.1.4.rst index b820c9f167abf..043b817bb9026 100644 --- a/doc/source/whatsnew/v1.1.4.rst +++ b/doc/source/whatsnew/v1.1.4.rst @@ -22,7 +22,7 @@ Fixed regressions - Fixed regression in :class:`RollingGroupby` causing a segmentation fault with Index of dtype object (:issue:`36727`) - Fixed regression in :meth:`DataFrame.resample(...).apply(...)` raised ``AttributeError`` when input was a :class:`DataFrame` and only a :class:`Series` was evaluated (:issue:`36951`) - Fixed regression in :class:`PeriodDtype` comparing both equal and unequal to its string representation (:issue:`37265`) -- Fixed regression in :meth:`pd.offsets.Day() ` and associated functions caused that offsets were no longer hashable (:issue:`37267`) +- Fixed regression in certain offsets (:meth:`pd.offsets.Day() ` and below) no longer being hashable (:issue:`37267`) .. --------------------------------------------------------------------------- diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx index 5469c0afd7036..9520a27c89d7a 100644 --- a/pandas/_libs/tslibs/offsets.pyx +++ b/pandas/_libs/tslibs/offsets.pyx @@ -752,9 +752,6 @@ cdef class Tick(SingleConstructorOffset): "Tick offset with `normalize=True` are not allowed." ) - def __hash__(self) -> int: - return hash(self._params) - # FIXME: Without making this cpdef, we get AttributeError when calling # from __mul__ cpdef Tick _next_higher_resolution(Tick self): @@ -794,6 +791,10 @@ cdef class Tick(SingleConstructorOffset): def is_anchored(self) -> bool: return False + # This is identical to DateOffset.__hash__, but has to be redefined here + # for Python 3, because we've redefined __eq__. + def __hash__(self) -> int: + return hash(self._params) # -------------------------------------------------------------------- # Comparison and Arithmetic Methods diff --git a/pandas/tests/tseries/offsets/test_offsets.py b/pandas/tests/tseries/offsets/test_offsets.py index 067c5f2079ed1..922aff1792227 100644 --- a/pandas/tests/tseries/offsets/test_offsets.py +++ b/pandas/tests/tseries/offsets/test_offsets.py @@ -680,7 +680,8 @@ def test_isAnchored_deprecated(self, offset_types): def test_offsets_hashable(self, offset_types): # GH: 37267 - assert hash(offset_types) is not None + off = self._get_offset(offset_types) + assert hash(off) is not None class TestDateOffset(Base): From f2e883596f808f614a8a543600d284dcb73d522b Mon Sep 17 00:00:00 2001 From: patrick <61934744+phofl@users.noreply.github.com> Date: Wed, 21 Oct 2020 22:01:32 +0200 Subject: [PATCH 6/7] Update pandas/_libs/tslibs/offsets.pyx Co-authored-by: Joris Van den Bossche --- pandas/_libs/tslibs/offsets.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx index 9520a27c89d7a..d72e5b419f4d1 100644 --- a/pandas/_libs/tslibs/offsets.pyx +++ b/pandas/_libs/tslibs/offsets.pyx @@ -791,7 +791,7 @@ cdef class Tick(SingleConstructorOffset): def is_anchored(self) -> bool: return False - # This is identical to DateOffset.__hash__, but has to be redefined here + # This is identical to BaseOffset.__hash__, but has to be redefined here # for Python 3, because we've redefined __eq__. def __hash__(self) -> int: return hash(self._params) From 0f705901fea09c176fa682033dc660b190275c51 Mon Sep 17 00:00:00 2001 From: phofl Date: Wed, 21 Oct 2020 22:08:11 +0200 Subject: [PATCH 7/7] Add empty line --- pandas/_libs/tslibs/offsets.pyx | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx index d72e5b419f4d1..98b2ddbd21ee1 100644 --- a/pandas/_libs/tslibs/offsets.pyx +++ b/pandas/_libs/tslibs/offsets.pyx @@ -795,6 +795,7 @@ cdef class Tick(SingleConstructorOffset): # for Python 3, because we've redefined __eq__. def __hash__(self) -> int: return hash(self._params) + # -------------------------------------------------------------------- # Comparison and Arithmetic Methods