From 479df87d69ae6e7e2ebf59285aec65d1fde88039 Mon Sep 17 00:00:00 2001 From: OSC Bot Date: Mon, 23 Mar 2026 03:01:15 +0800 Subject: [PATCH] fix: precise_diff inconsistent with pendulum.DateTime subclasses The Rust helper used for dt1 but for dt2. Since is a subclass of , returns False for it, causing dt2's time components to be left at zero. This led to incorrect interval calculations when using native objects (which get converted to in ). Fixes #906 --- rust/src/python/helpers.rs | 2 +- tests/interval/test_construct.py | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/rust/src/python/helpers.rs b/rust/src/python/helpers.rs index 979258a0..f0d881d8 100644 --- a/rust/src/python/helpers.rs +++ b/rust/src/python/helpers.rs @@ -184,7 +184,7 @@ pub fn precise_diff<'py>( total_seconds: 0, tz: dt2_tz.as_str(), offset: get_offset(dt2)?, - is_datetime: PyDateTime::is_exact_type_of(dt2), + is_datetime: PyDateTime::is_type_of(dt2), }; let in_same_tz: bool = dtinfo1.tz == dtinfo2.tz && !dtinfo1.tz.is_empty(); let mut total_days = helpers::day_number(dtinfo2.year, dtinfo2.month as u8, dtinfo2.day as u8) diff --git a/tests/interval/test_construct.py b/tests/interval/test_construct.py index 550b8088..8c9e0d97 100644 --- a/tests/interval/test_construct.py +++ b/tests/interval/test_construct.py @@ -18,6 +18,29 @@ def test_with_datetimes(): assert_datetime(p.end, 2000, 1, 31) +def test_native_datetime_interval_consistency(): + """Native datetime inputs should produce the same results as pendulum datetimes. + + Regression test for https://github.com/python-pendulum/pendulum/issues/906 + """ + # With pendulum datetimes + start_p = pendulum.datetime(2025, 7, 25, 19, 26, 34) + end_p = pendulum.datetime(2025, 7, 29, 19, 26, 34) + interval_p = pendulum.interval(start_p, end_p) + + # With native datetimes + start_n = datetime(2025, 7, 25, 19, 26, 34) + end_n = datetime(2025, 7, 29, 19, 26, 34) + interval_n = pendulum.interval(start_n, end_n) + + # Both should produce identical results + assert interval_p.in_words() == interval_n.in_words() + assert interval_p.in_words() == "4 days" + assert interval_p.days == interval_n.days == 4 + assert interval_p.hours == interval_n.hours == 0 + assert interval_p.minutes == interval_n.minutes == 0 + + def test_with_pendulum(): dt1 = pendulum.DateTime(2000, 1, 1) dt2 = pendulum.DateTime(2000, 1, 31)