https://github.com/python/cpython/commit/f941512ce41c4c79cce4291ab7a41c7c3ba2a60d
commit: f941512ce41c4c79cce4291ab7a41c7c3ba2a60d
branch: 3.13
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-09-23T11:32:09Z
summary:

[3.13] gh-151471: Colorize the soft keyword `type` in IDLE (GH-151700) 
(GH-157993)

`type` is now colored as a keyword when it starts a statement and is
followed by a name, as in `type Point = tuple[float, float]`.  It stays
a builtin elsewhere, for example in `type = type(1)`, `type(x)` or
`type in (int, str)`.

(cherry picked from commit 68ed7a50226f8981788f2673677e30f1431e18a9)

Co-authored-by: Locked-chess-official <[email protected]>

files:
A Misc/NEWS.d/next/IDLE/2026-09-17-08-53-12.gh-issue-151471.-yvE03.rst
M Lib/idlelib/colorizer.py
M Lib/idlelib/idle_test/test_colorizer.py

diff --git a/Lib/idlelib/colorizer.py b/Lib/idlelib/colorizer.py
index b4df353012b788..c0d46367b74766 100644
--- a/Lib/idlelib/colorizer.py
+++ b/Lib/idlelib/colorizer.py
@@ -42,6 +42,11 @@ def make_pat():
         ]) +
         r"))"
     )
+    type_softkw = (
+        r"^[ \t]*" +  # at beginning of line + possible indentation
+        r"(?P<TYPE_SOFTKW>type)" +
+        r"(?=[ \t]+(?!(?:" + "|".join(keyword.kwlist) + r")\b)[^\W\d])"
+    )
     builtinlist = [str(name) for name in dir(builtins)
                    if not name.startswith('_') and
                    name not in keyword.kwlist]
@@ -54,7 +59,7 @@ def make_pat():
     dq3string = stringprefix + r'"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?'
     string = any("STRING", [sq3string, dq3string, sqstring, dqstring])
     prog = re.compile("|".join([
-                                builtin, comment, string, kw,
+                                type_softkw, builtin, comment, string, kw,
                                 match_softkw, case_default,
                                 case_softkw_and_pattern,
                                 any("SYNC", [r"\n"]),
@@ -70,6 +75,7 @@ def make_pat():
     "CASE_SOFTKW": "KEYWORD",
     "CASE_DEFAULT_UNDERSCORE": "KEYWORD",
     "CASE_SOFTKW2": "KEYWORD",
+    "TYPE_SOFTKW": "KEYWORD",
 }
 
 
diff --git a/Lib/idlelib/idle_test/test_colorizer.py 
b/Lib/idlelib/idle_test/test_colorizer.py
index 6b36f16d94c213..9fbbf4a078f38f 100644
--- a/Lib/idlelib/idle_test/test_colorizer.py
+++ b/Lib/idlelib/idle_test/test_colorizer.py
@@ -480,6 +480,21 @@ def test_def_statement(self):
         # def followed by non-keyword
         self._assert_highlighting('def ++', {'KEYWORD': [('1.0', '1.3')]})
 
+    def test_type_soft_keyword(self):
+        # type as a soft keyword
+        self._assert_highlighting('type X = int',
+                                  {'KEYWORD': [('1.0', '1.4')],
+                                   'BUILTIN': [('1.9', '1.12')]})
+        # type as a name
+        self._assert_highlighting('type = type(1)',
+                                  {'BUILTIN': [('1.0', '1.4'), ('1.7', 
'1.11')]})
+        self._assert_highlighting('type(x)',
+                                  {'BUILTIN': [('1.0', '1.4')]})
+        self._assert_highlighting('type in (int, str)',
+                                  {'KEYWORD': [('1.5', '1.7')],
+                                   'BUILTIN': [('1.0', '1.4'), ('1.9', '1.12'),
+                                               ('1.14', '1.17')]})
+
     def test_match_soft_keyword(self):
         # empty match
         self._assert_highlighting('match', {'KEYWORD': [('1.0', '1.5')]})
diff --git 
a/Misc/NEWS.d/next/IDLE/2026-09-17-08-53-12.gh-issue-151471.-yvE03.rst 
b/Misc/NEWS.d/next/IDLE/2026-09-17-08-53-12.gh-issue-151471.-yvE03.rst
new file mode 100644
index 00000000000000..cc04822f6d3321
--- /dev/null
+++ b/Misc/NEWS.d/next/IDLE/2026-09-17-08-53-12.gh-issue-151471.-yvE03.rst
@@ -0,0 +1 @@
+Colorize the soft keyword ``type`` in IDLE.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to