Skip to content

Commit d20d6df

Browse files
committed
gh-158827: Convert sys.ps1 and sys.ps2 to strings before PyREPL use
Users may be able to assign non-string, but string representable values to ps1, but these should be converted to their string representations before use by PyREPL rendering.
1 parent 84b0669 commit d20d6df

2 files changed

Lines changed: 30 additions & 4 deletions

File tree

‎Lib/_pyrepl/simple_interact.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ def maybe_run_command(statement: str) -> bool:
135135
except Exception:
136136
pass
137137

138-
ps1 = getattr(sys, "ps1", ">>> ")
139-
ps2 = getattr(sys, "ps2", "... ")
138+
ps1 = str(getattr(sys, "ps1", ">>> "))
139+
ps2 = str(getattr(sys, "ps2", "... "))
140140
try:
141141
statement = multiline_input(more_lines, ps1, ps2)
142142
except EOFError:

‎Lib/test/test_pyrepl/test_interact.py‎

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,42 @@
11
import contextlib
22
import io
3+
import sys
34
import warnings
45
import unittest
5-
from unittest.mock import patch
6+
from unittest.mock import ANY, patch
67
from textwrap import dedent
78

89
from test.support import force_not_colorized
910

1011
from _pyrepl.console import InteractiveColoredConsole
11-
from _pyrepl.simple_interact import _more_lines
12+
from _pyrepl.simple_interact import (
13+
_more_lines,
14+
run_multiline_interactive_console,
15+
)
1216

1317
class TestSimpleInteract(unittest.TestCase):
18+
def test_prompts_are_converted_to_strings(self):
19+
console = InteractiveColoredConsole()
20+
21+
class Prompt:
22+
def __init__(self, value):
23+
self.value = value
24+
25+
def __str__(self):
26+
return self.value
27+
28+
with (
29+
patch.object(sys, "ps1", Prompt("primary"), create=True),
30+
patch.object(sys, "ps2", Prompt("secondary"), create=True),
31+
patch("_pyrepl.readline._setup"),
32+
patch(
33+
"_pyrepl.simple_interact.multiline_input", side_effect=EOFError
34+
) as multiline_input,
35+
):
36+
run_multiline_interactive_console(console)
37+
38+
multiline_input.assert_called_once_with(ANY, "primary", "secondary")
39+
1440
def test_multiple_statements(self):
1541
namespace = {}
1642
code = dedent("""\

0 commit comments

Comments
 (0)