diff --git a/CHANGELOG.md b/CHANGELOG.md index 47bf49b0..a8e5980e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ ### Fixed +- Preserve date text and temporal trivia when adding a timedelta from the left to `Date` or `DateTime` values. + - Fix `item()` and `dumps()` writing a `datetime` whose UTC offset is not a whole number of minutes (e.g. the historical LMT offsets `zoneinfo` gives, such as `-00:44:30`) as invalid TOML like `1900-01-01T12:00:00Z:30`, which no parser accepts. Such a value is now written as the same instant in UTC; this also covers `DateTime.replace()` and `astimezone()`. - Allow `DateTime.astimezone()` to use the local timezone when no timezone argument is supplied, matching `datetime.datetime`. - 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. diff --git a/tests/test_items.py b/tests/test_items.py index e7c00e7e..9c67174f 100644 --- a/tests/test_items.py +++ b/tests/test_items.py @@ -874,6 +874,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 + + def test_datetime_astimezone_defaults_to_local_timezone() -> None: value = parse("time = 1979-05-27T07:32:00Z # birthday\n")["time"] expected = datetime(1979, 5, 27, 7, 32, tzinfo=timezone.utc).astimezone() diff --git a/tomlkit/items.py b/tomlkit/items.py index 4ca1b1ec..26bb3cc1 100644 --- a/tomlkit/items.py +++ b/tomlkit/items.py @@ -1207,6 +1207,8 @@ def __add__(self, other: timedelta) -> DateTime: return self._new(result) + __radd__ = __add__ + @overload # type: ignore[override] def __sub__(self, other: timedelta) -> DateTime: ... @@ -1327,6 +1329,8 @@ def __add__(self, other: timedelta) -> Date: return self._new(result) + __radd__ = __add__ + @overload # type: ignore[override] def __sub__(self, other: timedelta) -> Date: ...