Skip to content

Commit 8e220a1

Browse files
[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>
1 parent be5386f commit 8e220a1

3 files changed

Lines changed: 24 additions & 1 deletion

File tree

‎Lib/_pyrepl/utils.py‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,21 @@
1616
from .types import CharBuffer, CharWidths
1717
from .trace import trace
1818

19-
ANSI_ESCAPE_SEQUENCE = re.compile(r"\x1b\[[ -@]*[A-~]")
19+
ANSI_ESCAPE_SEQUENCE = re.compile(
20+
r"""
21+
\x1b
22+
(?:
23+
# CSI: ESC [ followed by parameter/intermediate bytes and a final byte.
24+
# For example, ESC [ 31 m ("\x1b[31m") selects red foreground text.
25+
\[ [ -@]* [A-~]
26+
|
27+
# OSC: ESC ] followed by a payload terminated by BEL or ST (ESC \).
28+
# For example, ESC ] 0 ; title BEL ("\x1b]0;title\x07") sets the title.
29+
\] [^\x1b\x07]* (?: \x07 | \x1b\\ )
30+
)
31+
""",
32+
re.X,
33+
)
2034
ZERO_WIDTH_BRACKET = re.compile(r"\x01.*?\x02")
2135
ZERO_WIDTH_TRANS = str.maketrans({"\x01": "", "\x02": ""})
2236
IDENTIFIERS_AFTER = {"def", "class"}

‎Lib/test/test_pyrepl/test_utils.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ def test_wlen(self):
4747
self.assertEqual(wlen('e\N{COMBINING ACUTE ACCENT}'), 1)
4848
self.assertEqual(wlen('a\N{ZERO WIDTH JOINER}b'), 2)
4949

50+
def test_wlen_with_osc_sequence(self):
51+
prompt = ">>> "
52+
self.assertEqual(wlen("\x1b]633;A\x07" + prompt), len(prompt))
53+
54+
def test_wlen_with_unterminated_osc_sequence_as_individual_characters(self):
55+
# \x1b is treated as a single character (ESC)
56+
self.assertEqual(wlen("\x1b]633;A"), len("\x1b]633;A"))
57+
5058
def test_prev_next_window(self):
5159
def gen_normal():
5260
yield 1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Correctly detect and handle OSC sequences in PyREPL.

0 commit comments

Comments
 (0)