diff --git a/CHANGELOG.md b/CHANGELOG.md index d36550d8..c5510aa2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Fixed +- Preserve date text and temporal trivia when adding a timedelta from the left to `Date` or `DateTime` values. + - Arithmetic and `replace()` results for `Integer`, `Float`, `String`, `DateTime`, `Date` and `Time` no longer share the original item's `Trivia`, so changing the result's comment or indentation no longer rewrites the item still stored in the document. ## [0.15.2] - 2026-10-16 diff --git a/tests/test_items.py b/tests/test_items.py index 36f4afd2..05a6079e 100644 --- a/tests/test_items.py +++ b/tests/test_items.py @@ -828,6 +828,27 @@ def test_datetimes_behave_like_datetimes(tz_utc: tzinfo, tz_pst: tzinfo) -> None assert doc.as_string() == "dt = 2018-07-23T12:34:56-05:00" +@pytest.mark.parametrize( + "literal", ["2024-02-28", "2024-02-28T10:00:00", "2024-02-28T10:00:00Z"] +) +@pytest.mark.parametrize("delta", [timedelta(days=1), timedelta(days=-1)]) +def test_reflected_temporal_addition_preserves_serialization( + literal: str, delta: timedelta +) -> None: + doc = parse(f"when = {literal} # birthday\n") + value = doc["when"] + expected = value + delta + + result = delta + value + + assert type(result) is type(value) + assert result.unwrap() == expected.unwrap() + assert result.as_string() == expected.as_string() + assert result.trivia == expected.trivia + doc["when"] = result + assert parse(doc.as_string())["when"] == expected + + @pytest.mark.parametrize("fold", [0, 1]) def test_datetime_subtraction_preserves_input_fold(tz_fold: tzinfo, fold: int) -> None: value = datetime(2018, 11, 4, 1, 30, tzinfo=tz_fold, fold=fold) diff --git a/tomlkit/items.py b/tomlkit/items.py index a73fab8a..c544bca3 100644 --- a/tomlkit/items.py +++ b/tomlkit/items.py @@ -1154,6 +1154,8 @@ def __add__(self, other: timedelta) -> DateTime: return self._new(result) + __radd__ = __add__ + @overload # type: ignore[override] def __sub__(self, other: timedelta) -> DateTime: ... @@ -1274,6 +1276,8 @@ def __add__(self, other: timedelta) -> Date: return self._new(result) + __radd__ = __add__ + @overload # type: ignore[override] def __sub__(self, other: timedelta) -> Date: ...