From 89a5b68b56940913f37efc78973b03ec20230e59 Mon Sep 17 00:00:00 2001 From: Thomas Li <47963215+lithomas1@users.noreply.github.com> Date: Fri, 23 Dec 2022 10:34:26 -0800 Subject: [PATCH 1/3] TST: Add test for Period construction from str with zero nanos --- pandas/_libs/tslibs/parsing.pyx | 2 +- pandas/tests/scalar/period/test_period.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/_libs/tslibs/parsing.pyx b/pandas/_libs/tslibs/parsing.pyx index 992e1d90f4f3b..5d845638d9e20 100644 --- a/pandas/_libs/tslibs/parsing.pyx +++ b/pandas/_libs/tslibs/parsing.pyx @@ -386,7 +386,7 @@ cdef parse_datetime_string_with_reso( &out_tzoffset, False ) if not string_to_dts_failed: - if dts.ps != 0 or out_local: + if out_bestunit == NPY_DATETIMEUNIT.NPY_FR_ns or out_local: # TODO: the not-out_local case we could do without Timestamp; # avoid circular import from pandas import Timestamp diff --git a/pandas/tests/scalar/period/test_period.py b/pandas/tests/scalar/period/test_period.py index 112f23b3b0f16..dfef2fda886de 100644 --- a/pandas/tests/scalar/period/test_period.py +++ b/pandas/tests/scalar/period/test_period.py @@ -545,6 +545,7 @@ def test_period_cons_combined(self): (".000000999", 999), (".123456789", 789), (".999999999", 999), + (".999999000", 0), ], ) def test_period_constructor_nanosecond(self, day, hour, sec_float, expected): From 20b6b139df7b499644c80a9be1407ec872bd19ac Mon Sep 17 00:00:00 2001 From: Thomas Li <47963215+lithomas1@users.noreply.github.com> Date: Fri, 23 Dec 2022 14:23:25 -0800 Subject: [PATCH 2/3] BUG: Period would raise a KeyError when given a string with extra precision --- doc/source/whatsnew/v2.0.0.rst | 2 +- pandas/_libs/tslibs/parsing.pyx | 6 ++++++ pandas/tests/scalar/period/test_period.py | 4 ++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 75ba169600962..ab5dcd1b8cd9a 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -902,7 +902,7 @@ Period ^^^^^^ - Bug in :meth:`Period.strftime` and :meth:`PeriodIndex.strftime`, raising ``UnicodeDecodeError`` when a locale-specific directive was passed (:issue:`46319`) - Bug in adding a :class:`Period` object to an array of :class:`DateOffset` objects incorrectly raising ``TypeError`` (:issue:`50162`) -- +- Bug in :class:`Period` where passing a string with finer resolution than nanosecond would result in a ``KeyError`` instead of dropping the extra precision (:issue:`50417`) Plotting ^^^^^^^^ diff --git a/pandas/_libs/tslibs/parsing.pyx b/pandas/_libs/tslibs/parsing.pyx index 5d845638d9e20..409cf78628c62 100644 --- a/pandas/_libs/tslibs/parsing.pyx +++ b/pandas/_libs/tslibs/parsing.pyx @@ -395,6 +395,12 @@ cdef parse_datetime_string_with_reso( parsed = datetime( dts.year, dts.month, dts.day, dts.hour, dts.min, dts.sec, dts.us ) + # Match Timestamp and drop picoseconds, femtoseconds, attoseconds + # The new resolution will just be nano + if out_bestunit in {NPY_DATETIMEUNIT.NPY_FR_ps, + NPY_DATETIMEUNIT.NPY_FR_fs, + NPY_DATETIMEUNIT.NPY_FR_as}: + out_bestunit = NPY_DATETIMEUNIT.NPY_FR_ns reso = { NPY_DATETIMEUNIT.NPY_FR_Y: "year", NPY_DATETIMEUNIT.NPY_FR_M: "month", diff --git a/pandas/tests/scalar/period/test_period.py b/pandas/tests/scalar/period/test_period.py index dfef2fda886de..f28ff138847be 100644 --- a/pandas/tests/scalar/period/test_period.py +++ b/pandas/tests/scalar/period/test_period.py @@ -546,6 +546,10 @@ def test_period_cons_combined(self): (".123456789", 789), (".999999999", 999), (".999999000", 0), + # Test femtoseconds, attoseconds, picoseconds are dropped like Timestamp + (".999999001123", 1), + (".999999001123456", 1), + (".999999001123456789", 1), ], ) def test_period_constructor_nanosecond(self, day, hour, sec_float, expected): From 1e6712269a843fe8f30cc77d46543a4de0f7a430 Mon Sep 17 00:00:00 2001 From: Thomas Li <47963215+lithomas1@users.noreply.github.com> Date: Tue, 3 Jan 2023 07:09:03 -0800 Subject: [PATCH 3/3] Update parsing.pyx --- pandas/_libs/tslibs/parsing.pyx | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/_libs/tslibs/parsing.pyx b/pandas/_libs/tslibs/parsing.pyx index 9cbdc1bad812e..98f9f4a3dbd34 100644 --- a/pandas/_libs/tslibs/parsing.pyx +++ b/pandas/_libs/tslibs/parsing.pyx @@ -397,6 +397,7 @@ cdef parse_datetime_string_with_reso( ) # Match Timestamp and drop picoseconds, femtoseconds, attoseconds # The new resolution will just be nano + # GH 50417 if out_bestunit in {NPY_DATETIMEUNIT.NPY_FR_ps, NPY_DATETIMEUNIT.NPY_FR_fs, NPY_DATETIMEUNIT.NPY_FR_as}: