@@ -1337,6 +1337,55 @@ def test_handle_eof(self):
13371337 self .assertEqual (process .returncode , 0 )
13381338 self .assertEqual (stderr , "" )
13391339
1340+ def test_colorized_list_has_no_caret_encoded_newlines (self ):
1341+ """A colorized ``list`` must not append "^J" to each source line.
1342+
1343+ The remote server colorizes the source it sends to the client. The
1344+ colorizer renders control characters in caret notation, so a source
1345+ line's trailing newline has to be stripped *before* it is colorized;
1346+ otherwise every listed line ends with a spurious "^J". ``where`` was
1347+ unaffected because it strips the line before colorizing. See
1348+ gh-154470.
1349+ """
1350+ # colorize=True is what attaching from a color-capable terminal passes
1351+ # to the server, and it is what makes the server colorize ``list``.
1352+ script = textwrap .dedent (f"""
1353+ import pdb, sys
1354+ def helper():
1355+ x = 42
1356+ return x
1357+ def connect():
1358+ frame = sys._getframe()
1359+ pdb._connect(
1360+ host='127.0.0.1',
1361+ port={ self .port } ,
1362+ frame=frame,
1363+ commands="",
1364+ version=pdb._PdbServer.protocol_version(),
1365+ signal_raising_thread=False,
1366+ colorize=True,
1367+ )
1368+ return helper()
1369+ connect()
1370+ """ )
1371+ self ._create_script (script = script )
1372+ process , client_file = self ._connect_and_get_client_file ()
1373+
1374+ with kill_on_error (process ):
1375+ self ._read_until_prompt (client_file )
1376+ self ._send_command (client_file , "l 1, 15" )
1377+ messages = self ._read_until_prompt (client_file )
1378+ source = "" .join (m ["message" ] for m in messages if "message" in m )
1379+
1380+ # Sanity: we really did receive colorized source ...
1381+ self .assertIn ("helper" , source )
1382+ self .assertIn ("\x1b [" , source ) # ANSI color escapes are present
1383+ # ... and no trailing newline leaked through as caret notation.
1384+ self .assertNotIn ("^J" , source )
1385+ self ._send_command (client_file , "c" )
1386+ process .wait (timeout = SHORT_TIMEOUT )
1387+ self .assertEqual (process .returncode , 0 )
1388+
13401389 @unittest .skipUnless (pty , "requires pty" )
13411390 def test_prompt_with_interactive_terminal (self ):
13421391 """The server must send "(Pdb) " even when the target owns a terminal.
0 commit comments