https://github.com/python/cpython/commit/8e220a1b951d5fe21c518e9115464d67be89f711
commit: 8e220a1b951d5fe21c518e9115464d67be89f711
branch: 3.14
author: Eduardo Villalpando Mello <[email protected]>
committer: brettcannon <[email protected]>
date: 2026-10-31T01:56:20Z
summary:
[3.14] gh-157928: PyREPL detect OSC sequences (GH-157932) (GH-160935)
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
files:
A Misc/NEWS.d/next/Library/2026-10-29-23-24-59.gh-issue-157928.vjwtXc.rst
M Lib/_pyrepl/utils.py
M Lib/test/test_pyrepl/test_utils.py
diff --git a/Lib/_pyrepl/utils.py b/Lib/_pyrepl/utils.py
index 1a697ad61c8e896..716ac7985854ae7 100644
--- a/Lib/_pyrepl/utils.py
+++ b/Lib/_pyrepl/utils.py
@@ -16,7 +16,21 @@
from .types import CharBuffer, CharWidths
from .trace import trace
-ANSI_ESCAPE_SEQUENCE = re.compile(r"\x1b\[[ -@]*[A-~]")
+ANSI_ESCAPE_SEQUENCE = re.compile(
+ r"""
+ \x1b
+ (?:
+ # CSI: ESC [ followed by parameter/intermediate bytes and a final byte.
+ # For example, ESC [ 31 m ("\x1b[31m") selects red foreground text.
+ \[ [ -@]* [A-~]
+ |
+ # OSC: ESC ] followed by a payload terminated by BEL or ST (ESC \).
+ # For example, ESC ] 0 ; title BEL ("\x1b]0;title\x07") sets the title.
+ \] [^\x1b\x07]* (?: \x07 | \x1b\\ )
+ )
+ """,
+ re.X,
+)
ZERO_WIDTH_BRACKET = re.compile(r"\x01.*?\x02")
ZERO_WIDTH_TRANS = str.maketrans({"\x01": "", "\x02": ""})
IDENTIFIERS_AFTER = {"def", "class"}
diff --git a/Lib/test/test_pyrepl/test_utils.py
b/Lib/test/test_pyrepl/test_utils.py
index b621071f1249c30..e91b82cfc6d21b9 100644
--- a/Lib/test/test_pyrepl/test_utils.py
+++ b/Lib/test/test_pyrepl/test_utils.py
@@ -47,6 +47,14 @@ def test_wlen(self):
self.assertEqual(wlen('e\N{COMBINING ACUTE ACCENT}'), 1)
self.assertEqual(wlen('a\N{ZERO WIDTH JOINER}b'), 2)
+ def test_wlen_with_osc_sequence(self):
+ prompt = ">>> "
+ self.assertEqual(wlen("\x1b]633;A\x07" + prompt), len(prompt))
+
+ def
test_wlen_with_unterminated_osc_sequence_as_individual_characters(self):
+ # \x1b is treated as a single character (ESC)
+ self.assertEqual(wlen("\x1b]633;A"), len("\x1b]633;A"))
+
def test_prev_next_window(self):
def gen_normal():
yield 1
diff --git
a/Misc/NEWS.d/next/Library/2026-10-29-23-24-59.gh-issue-157928.vjwtXc.rst
b/Misc/NEWS.d/next/Library/2026-10-29-23-24-59.gh-issue-157928.vjwtXc.rst
new file mode 100644
index 000000000000000..dfa7a122a9e22e8
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-10-29-23-24-59.gh-issue-157928.vjwtXc.rst
@@ -0,0 +1 @@
+Correctly detect and handle OSC sequences in PyREPL.
_______________________________________________
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]