]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-138318, PyREPL: builtins should not be highlighted when used as attribute names...
authoryihong <zouzou0208@gmail.com>
Mon, 8 Sep 2025 13:04:22 +0000 (21:04 +0800)
committerGitHub <noreply@github.com>
Mon, 8 Sep 2025 13:04:22 +0000 (14:04 +0100)
Lib/_pyrepl/utils.py
Lib/test/test_pyrepl/test_utils.py
Misc/NEWS.d/next/Core_and_Builtins/2025-09-01-16-09-02.gh-issue-138318.t-WEN5.rst [new file with mode: 0644]

index fd788c8429e15b2e6294b1c6bfe005770a7ce53b..c5d006afa7731fa87118825a2f389b114a742777 100644 (file)
@@ -208,7 +208,10 @@ def gen_colors_from_token_stream(
                 ):
                     span = Span.from_token(token, line_lengths)
                     yield ColorSpan(span, "soft_keyword")
-                elif token.string in BUILTINS:
+                elif (
+                    token.string in BUILTINS
+                    and not (prev_token and prev_token.exact_type == T.DOT)
+                ):
                     span = Span.from_token(token, line_lengths)
                     yield ColorSpan(span, "builtin")
 
index 8ce1e5371386f075d62c0231c03fbf08ab694115..05a4f3290598350a78771a4871f138795031868c 100644 (file)
@@ -1,6 +1,6 @@
 from unittest import TestCase
 
-from _pyrepl.utils import str_width, wlen, prev_next_window
+from _pyrepl.utils import str_width, wlen, prev_next_window, gen_colors
 
 
 class TestUtils(TestCase):
@@ -60,3 +60,25 @@ class TestUtils(TestCase):
         self.assertEqual(next(pnw), (3, 4, None))
         with self.assertRaises(ZeroDivisionError):
             next(pnw)
+
+    def test_gen_colors_keyword_highlighting(self):
+        cases = [
+            # no highlights
+            ("a.set", [(".", "op")]),
+            ("obj.list", [(".", "op")]),
+            ("obj.match", [(".", "op")]),
+            ("b. \\\n format", [(".", "op")]),
+            # highlights
+            ("set", [("set", "builtin")]),
+            ("list", [("list", "builtin")]),
+            ("    \n dict", [("dict", "builtin")]),
+        ]
+        for code, expected_highlights in cases:
+            with self.subTest(code=code):
+                colors = list(gen_colors(code))
+                # Extract (text, tag) pairs for comparison
+                actual_highlights = []
+                for color in colors:
+                    span_text = code[color.span.start:color.span.end + 1]
+                    actual_highlights.append((span_text, color.tag))
+                self.assertEqual(actual_highlights, expected_highlights)
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-09-01-16-09-02.gh-issue-138318.t-WEN5.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-09-01-16-09-02.gh-issue-138318.t-WEN5.rst
new file mode 100644 (file)
index 0000000..ce9456d
--- /dev/null
@@ -0,0 +1,3 @@
+The default REPL now avoids highlighting built-in names (for instance :class:`set`
+or :func:`format`) when they are used as attribute names (for instance in ``value.set``
+or ``text.format``).