https://github.com/python/cpython/commit/71ea6a6798c5853ed33188865a73b044ede8aba8
commit: 71ea6a6798c5853ed33188865a73b044ede8aba8
branch: main
author: Loïc Simon <loic.p...@gmail.com>
committer: ambv <luk...@langa.pl>
date: 2025-05-19T16:12:23+02:00
summary:

gh-134158: Fix PyREPL coloring of double braces in f/t-strings (gh-134159)

Co-authored-by: Loïc Simon <loic.si...@napta.io>
Co-authored-by: Peter Bierma <zintensity...@gmail.com>
Co-authored-by: Łukasz Langa <luk...@langa.pl>

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2025-05-17-20-44-51.gh-issue-134158.ewLNLp.rst
M Lib/_pyrepl/utils.py
M Lib/test/test_pyrepl/test_reader.py

diff --git a/Lib/_pyrepl/utils.py b/Lib/_pyrepl/utils.py
index 752049ac05acdf..e04fbdc6c8a5c4 100644
--- a/Lib/_pyrepl/utils.py
+++ b/Lib/_pyrepl/utils.py
@@ -41,9 +41,15 @@ def from_re(cls, m: Match[str], group: int | str) -> Self:
 
     @classmethod
     def from_token(cls, token: TI, line_len: list[int]) -> Self:
+        end_offset = -1
+        if (token.type in {T.FSTRING_MIDDLE, T.TSTRING_MIDDLE}
+            and token.string.endswith(("{", "}"))):
+            # gh-134158: a visible trailing brace comes from a double brace in 
input
+            end_offset += 1
+
         return cls(
             line_len[token.start[0] - 1] + token.start[1],
-            line_len[token.end[0] - 1] + token.end[1] - 1,
+            line_len[token.end[0] - 1] + token.end[1] + end_offset,
         )
 
 
diff --git a/Lib/test/test_pyrepl/test_reader.py 
b/Lib/test/test_pyrepl/test_reader.py
index 57526f88f9384b..1f655264f1c00a 100644
--- a/Lib/test/test_pyrepl/test_reader.py
+++ b/Lib/test/test_pyrepl/test_reader.py
@@ -517,6 +517,37 @@ def unfinished_function():
         self.assert_screen_equal(reader, code, clean=True)
         self.assert_screen_equal(reader, expected)
 
+    def test_syntax_highlighting_literal_brace_in_fstring_or_tstring(self):
+        code = dedent(
+            """\
+            f"{{"
+            f"}}"
+            f"a{{b"
+            f"a}}b"
+            f"a{{b}}c"
+            t"a{{b}}c"
+            f"{{{0}}}"
+            f"{ {0} }"
+            """
+        )
+        expected = dedent(
+            """\
+            {s}f"{z}{s}<<{z}{s}"{z}
+            {s}f"{z}{s}>>{z}{s}"{z}
+            {s}f"{z}{s}a<<{z}{s}b{z}{s}"{z}
+            {s}f"{z}{s}a>>{z}{s}b{z}{s}"{z}
+            {s}f"{z}{s}a<<{z}{s}b>>{z}{s}c{z}{s}"{z}
+            {s}t"{z}{s}a<<{z}{s}b>>{z}{s}c{z}{s}"{z}
+            {s}f"{z}{s}<<{z}{o}<{z}{n}0{z}{o}>{z}{s}>>{z}{s}"{z}
+            {s}f"{z}{o}<{z} {o}<{z}{n}0{z}{o}>{z} {o}>{z}{s}"{z}
+            """
+        ).format(**colors).replace("<", "{").replace(">", "}")
+        events = code_to_events(code)
+        reader, _ = handle_all_events(events)
+        self.assert_screen_equal(reader, code, clean=True)
+        self.maxDiff=None
+        self.assert_screen_equal(reader, expected)
+
     def test_control_characters(self):
         code = 'flag = "🏳️‍🌈"'
         events = code_to_events(code)
diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2025-05-17-20-44-51.gh-issue-134158.ewLNLp.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-05-17-20-44-51.gh-issue-134158.ewLNLp.rst
new file mode 100644
index 00000000000000..7b8bab739c37c8
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-05-17-20-44-51.gh-issue-134158.ewLNLp.rst
@@ -0,0 +1 @@
+Fix coloring of double braces in f-strings and t-strings in the :term:`REPL`.

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to