From 72e709f1f2cf88357f52237ab1941dc8fad08e51 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 27 Nov 2019 17:01:48 -0800 Subject: [PATCH 1/2] BUG/DEPR: Timestamp/Timedelta resolution --- doc/source/whatsnew/v1.0.0.rst | 3 +- pandas/_libs/tslibs/timedeltas.pyx | 51 +------------------ pandas/_libs/tslibs/timestamps.pyx | 10 +--- .../tests/scalar/timedelta/test_timedelta.py | 10 ++-- .../tests/scalar/timestamp/test_timestamp.py | 4 ++ 5 files changed, 15 insertions(+), 63 deletions(-) diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index d01a5fb4f8b43..5dde5cb20889d 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -455,7 +455,7 @@ or ``matplotlib.Axes.plot``. See :ref:`plotting.formatters` for more. - Removed previously deprecated keyword "n" from :meth:`DatetimeIndex.shift`, :meth:`TimedeltaIndex.shift`, :meth:`PeriodIndex.shift`, use "periods" instead (:issue:`22458`) - Changed the default value for the `raw` argument in :func:`Series.rolling().apply() `, :func:`DataFrame.rolling().apply() `, - :func:`Series.expanding().apply() `, and :func:`DataFrame.expanding().apply() ` to ``False`` (:issue:`20584`) -- +- Changed :meth:`Timedelta.resolution` to match the behavior of the standard library ``datetime.timedelta.resolution``, for the old behavior, use :meth:`Timedelta.resolution_string` (:issue:`26839`) .. _whatsnew_1000.performance: @@ -512,6 +512,7 @@ Datetimelike - Bug in :func:`pandas._config.localization.get_locales` where the ``locales -a`` encodes the locales list as windows-1252 (:issue:`23638`, :issue:`24760`, :issue:`27368`) - Bug in :meth:`Series.var` failing to raise ``TypeError`` when called with ``timedelta64[ns]`` dtype (:issue:`28289`) - Bug in :meth:`DatetimeIndex.strftime` and :meth:`Series.dt.strftime` where ``NaT`` was converted to the string ``'NaT'`` instead of ``np.nan`` (:issue:`29578`) +- Bug in :attr:`Timestamp.resolution` being a property instead of a class attribute (:issue:`?????`) Timedelta ^^^^^^^^^ diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index 48a2a05011ab5..d6ab305d6cc21 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -1005,56 +1005,6 @@ cdef class _Timedelta(timedelta): else: return "D" - @property - def resolution(self): - """ - Return a string representing the lowest timedelta resolution. - - Each timedelta has a defined resolution that represents the lowest OR - most granular level of precision. Each level of resolution is - represented by a short string as defined below: - - Resolution: Return value - - * Days: 'D' - * Hours: 'H' - * Minutes: 'T' - * Seconds: 'S' - * Milliseconds: 'L' - * Microseconds: 'U' - * Nanoseconds: 'N' - - Returns - ------- - str - Timedelta resolution. - - Examples - -------- - >>> td = pd.Timedelta('1 days 2 min 3 us 42 ns') - >>> td.resolution - 'N' - - >>> td = pd.Timedelta('1 days 2 min 3 us') - >>> td.resolution - 'U' - - >>> td = pd.Timedelta('2 min 3 s') - >>> td.resolution - 'S' - - >>> td = pd.Timedelta(36, unit='us') - >>> td.resolution - 'U' - """ - # See GH#21344 - warnings.warn("Timedelta.resolution is deprecated, in a future " - "version will behave like the standard library " - "datetime.timedelta.resolution attribute. " - "Use Timedelta.resolution_string instead.", - FutureWarning) - return self.resolution_string - @property def nanoseconds(self): """ @@ -1602,3 +1552,4 @@ cdef _broadcast_floordiv_td64(int64_t value, object other, # resolution in ns Timedelta.min = Timedelta(np.iinfo(np.int64).min + 1) Timedelta.max = Timedelta(np.iinfo(np.int64).max) +Timedelta.resolution = Timedelta(nanoseconds=1) \ No newline at end of file diff --git a/pandas/_libs/tslibs/timestamps.pyx b/pandas/_libs/tslibs/timestamps.pyx index bb136e1f80386..8f16ba534308e 100644 --- a/pandas/_libs/tslibs/timestamps.pyx +++ b/pandas/_libs/tslibs/timestamps.pyx @@ -755,15 +755,6 @@ timedelta}, default 'raise' """ return bool(ccalendar.is_leapyear(self.year)) - @property - def resolution(self): - """ - Return resolution describing the smallest difference between two - times that can be represented by Timestamp object_state. - """ - # GH#21336, GH#21365 - return Timedelta(nanoseconds=1) - def tz_localize(self, tz, ambiguous='raise', nonexistent='raise', errors=None): """ @@ -1073,3 +1064,4 @@ cdef int64_t _NS_LOWER_BOUND = -9223372036854775000 # Resolution is in nanoseconds Timestamp.min = Timestamp(_NS_LOWER_BOUND) Timestamp.max = Timestamp(_NS_UPPER_BOUND) +Timestamp.resolution = Timedelta(nanoseconds=1) # GH#21336, GH#21365 diff --git a/pandas/tests/scalar/timedelta/test_timedelta.py b/pandas/tests/scalar/timedelta/test_timedelta.py index d4881ff0e1747..5a5724401029c 100644 --- a/pandas/tests/scalar/timedelta/test_timedelta.py +++ b/pandas/tests/scalar/timedelta/test_timedelta.py @@ -804,9 +804,13 @@ def test_resolution_string(self): def test_resolution_deprecated(self): # GH#21344 td = Timedelta(days=4, hours=3) - with tm.assert_produces_warning(FutureWarning) as w: - td.resolution - assert "Use Timedelta.resolution_string instead" in str(w[0].message) + result = td.resolution + assert result == Timedelta(nanoseconds=1) + + # Check that the attribute is available on the class, mirroring + # the stdlib timedelta behavior + result = Timedelta.resolution + assert result == Timedelta(nanoseconds=1) @pytest.mark.parametrize( diff --git a/pandas/tests/scalar/timestamp/test_timestamp.py b/pandas/tests/scalar/timestamp/test_timestamp.py index f9fa80644d4b9..57bbfe480d82a 100644 --- a/pandas/tests/scalar/timestamp/test_timestamp.py +++ b/pandas/tests/scalar/timestamp/test_timestamp.py @@ -194,6 +194,10 @@ def test_resolution(self): dt = Timestamp("2100-01-01 00:00:00") assert dt.resolution == Timedelta(nanoseconds=1) + # Check that the attribute is available on the class, mirroring + # the stdlib datetime behavior + assert Timestamp.resolution == Timedelta(nanoseconds=1) + class TestTimestampConstructors: def test_constructor(self): From 86c95ab34621dc4ef8d1f4234a23adc55b4f1e50 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 27 Nov 2019 17:12:52 -0800 Subject: [PATCH 2/2] GH ref --- doc/source/whatsnew/v1.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index 5dde5cb20889d..aabd52faaa68d 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -512,7 +512,7 @@ Datetimelike - Bug in :func:`pandas._config.localization.get_locales` where the ``locales -a`` encodes the locales list as windows-1252 (:issue:`23638`, :issue:`24760`, :issue:`27368`) - Bug in :meth:`Series.var` failing to raise ``TypeError`` when called with ``timedelta64[ns]`` dtype (:issue:`28289`) - Bug in :meth:`DatetimeIndex.strftime` and :meth:`Series.dt.strftime` where ``NaT`` was converted to the string ``'NaT'`` instead of ``np.nan`` (:issue:`29578`) -- Bug in :attr:`Timestamp.resolution` being a property instead of a class attribute (:issue:`?????`) +- Bug in :attr:`Timestamp.resolution` being a property instead of a class attribute (:issue:`29910`) Timedelta ^^^^^^^^^