Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

### Fixed

- 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

### Changed
Expand Down
25 changes: 25 additions & 0 deletions tests/test_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,31 @@ def test_item_array_of_dicts_converted_to_aot() -> None:
)


@pytest.mark.parametrize(
("content", "op"),
[
("my_int = 1 # keep\n", lambda item: item + 1),
("my_float = 1.5 # keep\n", lambda item: item + 1),
('my_str = "a" # keep\n', lambda item: item + "b"),
(
"my_dt = 1979-05-27T07:32:00Z # keep\n",
lambda item: item + timedelta(days=1),
),
("my_date = 1979-05-27 # keep\n", lambda item: item + timedelta(days=1)),
("my_time = 07:32:00 # keep\n", lambda item: item.replace(second=1)),
],
)
def test_arithmetic_result_does_not_share_trivia(content: str, op: Callable) -> None:
doc = parse(content)
original = doc[next(iter(doc))]

result = op(original)
assert result.trivia is not original.trivia

result.trivia.comment = "# MUTATED"
assert doc.as_string() == content


def test_add_float_to_int() -> None:
content = "[table]\nmy_int = 2043"
doc = parse(content)
Expand Down
12 changes: 6 additions & 6 deletions tomlkit/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ def _new(self, result: int) -> Integer:
if self._sign and result >= 0:
raw = f"+{raw}"

return Integer(result, self._trivia, raw)
return Integer(result, self._trivia.copy(), raw)

def _getstate(self, protocol: int = 3) -> tuple[int, Trivia, str]:
return int(self), self._trivia, self._raw
Expand Down Expand Up @@ -896,7 +896,7 @@ def _new(self, result: float) -> Float:
if self._sign and result >= 0 and not raw.startswith("-"):
raw = f"+{raw}"

return Float(result, self._trivia, raw)
return Float(result, self._trivia.copy(), raw)

def _getstate(self, protocol: int = 3) -> tuple[float, Trivia, str]:
return float(self), self._trivia, self._raw
Expand Down Expand Up @@ -1202,7 +1202,7 @@ def _new(self, result: datetime) -> DateTime:
result.second,
result.microsecond,
result.tzinfo,
self._trivia,
self._trivia.copy(),
raw,
fold=result.fold,
)
Expand Down Expand Up @@ -1297,7 +1297,7 @@ def replace(self, *args: object, **kwargs: object) -> Date:
def _new(self, result: date) -> Date:
raw = result.isoformat()

return Date(result.year, result.month, result.day, self._trivia, raw)
return Date(result.year, result.month, result.day, self._trivia.copy(), raw)

def _getstate(self, protocol: int = 3) -> tuple[int, int, int, Trivia, str]:
return (self.year, self.month, self.day, self._trivia, self._raw)
Expand Down Expand Up @@ -1363,7 +1363,7 @@ def _new(self, result: time) -> Time:
result.second,
result.microsecond,
result.tzinfo,
self._trivia,
self._trivia.copy(),
raw,
fold=result.fold,
)
Expand Down Expand Up @@ -2291,7 +2291,7 @@ def __add__(self, other: str) -> String:
return self._new(result, original)

def _new(self, result: str, original: str) -> String:
return String(self._t, result, original, self._trivia)
return String(self._t, result, original, self._trivia.copy())

def _getstate(self, protocol: int = 3) -> tuple[StringType, str, str, Trivia]:
return self._t, str(self), self._original, self._trivia
Expand Down
Loading