From cf1caab18da94aa876bd62590eccfa296d138aa0 Mon Sep 17 00:00:00 2001 From: Christian Sattler Date: Wed, 14 Oct 2026 12:40:42 +0200 Subject: [PATCH 1/2] Clean up String.from_raw, fixing #655. --- tomlkit/items.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/tomlkit/items.py b/tomlkit/items.py index 26b01097..eeec2821 100644 --- a/tomlkit/items.py +++ b/tomlkit/items.py @@ -2305,20 +2305,19 @@ def from_raw( if any(c in checked for c in invalid): raise InvalidStringError(value, invalid, type_.value) - escaped = type_.escaped_sequences - string_value = escape_string(value, escaped) if escape and escaped else value - - if type_ is StringType.MLB and escape: - string_value = _BARE_CR.sub(r"\\r", string_value) - - if type_.is_multiline() and string_value[:1] in ("\n", "\r"): - # A newline immediately following the opening delimiter of a - # multiline string is trimmed by the parser, so a value that - # starts with a newline would otherwise lose it on round-trip. - # Emit an extra leading newline (the trimmed one) to preserve it. - string_value = "\n" + string_value - - return cls(type_, decode(value), string_value, Trivia()) + string_value = value + if escape: + string_value = escape_string(string_value, type_.escaped_sequences) + if type_ is StringType.MLB and escape: + string_value = _BARE_CR.sub(r"\\r", string_value) + if type_.is_multiline() and string_value[:1] in ("\n", "\r"): + # A newline immediately following the opening delimiter of a + # multiline string is trimmed by the parser, so a value that + # starts with a newline would otherwise lose it on round-trip. + # Emit an extra leading newline (the trimmed one) to preserve it. + string_value = "\n" + string_value + + return cls(type_, value, string_value, Trivia()) class AoT(Item, _CustomList): # type: ignore[type-arg] From 386786c7a48ca621ca5778e63f1bc626a7000698 Mon Sep 17 00:00:00 2001 From: Christian Sattler Date: Wed, 14 Oct 2026 14:26:09 +0200 Subject: [PATCH 2/2] Improve documentation of escape option for strings. --- tomlkit/api.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tomlkit/api.py b/tomlkit/api.py index a7f3abdd..b1d2e7d7 100644 --- a/tomlkit/api.py +++ b/tomlkit/api.py @@ -170,10 +170,12 @@ def string( For more information, please check the spec: ``__. - Common escaping rules will be applied for basic strings. - This can be controlled by explicitly setting ``escape=False``. - Please note that, if you disable escaping, you will have to make sure that - the given strings don't contain any forbidden character or sequence. + Dumping produces a TOML string that faithfully represents the given string. + This includes character escaping for basic strings. + This behaviour can be disabled by setting ``escape=False``. + In that case, the given string is used verbatim for the content of the TOML string. + Please note that this makes you responsible for ensuring the given string does not + contain any forbidden character or sequence. """ type_ = _StringType.select(literal, multiline) return String.from_raw(raw, type_, escape)