gh-131507: Add support for syntax highlighting in PyREPL (GH-133247)

Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com>
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
This commit is contained in:
Łukasz Langa 2025-05-02 20:22:31 +02:00 committed by GitHub
parent bfcbb28223
commit fac41f56d4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 654 additions and 99 deletions

View file

@ -45,6 +45,7 @@ def run_repl(
cmdline_args: list[str] | None = None,
cwd: str | None = None,
skip: bool = False,
timeout: float = SHORT_TIMEOUT,
) -> tuple[str, int]:
temp_dir = None
if cwd is None:
@ -52,7 +53,12 @@ def run_repl(
cwd = temp_dir.name
try:
return self._run_repl(
repl_input, env=env, cmdline_args=cmdline_args, cwd=cwd, skip=skip,
repl_input,
env=env,
cmdline_args=cmdline_args,
cwd=cwd,
skip=skip,
timeout=timeout,
)
finally:
if temp_dir is not None:
@ -66,6 +72,7 @@ def _run_repl(
cmdline_args: list[str] | None,
cwd: str,
skip: bool,
timeout: float,
) -> tuple[str, int]:
assert pty
master_fd, slave_fd = pty.openpty()
@ -103,7 +110,7 @@ def _run_repl(
os.write(master_fd, repl_input.encode("utf-8"))
output = []
while select.select([master_fd], [], [], SHORT_TIMEOUT)[0]:
while select.select([master_fd], [], [], timeout)[0]:
try:
data = os.read(master_fd, 1024).decode("utf-8")
if not data:
@ -114,12 +121,12 @@ def _run_repl(
else:
os.close(master_fd)
process.kill()
process.wait(timeout=SHORT_TIMEOUT)
process.wait(timeout=timeout)
self.fail(f"Timeout while waiting for output, got: {''.join(output)}")
os.close(master_fd)
try:
exit_code = process.wait(timeout=SHORT_TIMEOUT)
exit_code = process.wait(timeout=timeout)
except subprocess.TimeoutExpired:
process.kill()
exit_code = process.wait()
@ -1561,25 +1568,29 @@ def test_readline_history_file(self):
def test_history_survive_crash(self):
env = os.environ.copy()
commands = "1\nexit()\n"
output, exit_code = self.run_repl(commands, env=env, skip=True)
with tempfile.NamedTemporaryFile() as hfile:
env["PYTHON_HISTORY"] = hfile.name
commands = "spam\nimport time\ntime.sleep(1000)\npreved\n"
commands = "1\n2\n3\nexit()\n"
output, exit_code = self.run_repl(commands, env=env, skip=True)
commands = "spam\nimport time\ntime.sleep(1000)\nquit\n"
try:
self.run_repl(commands, env=env)
self.run_repl(commands, env=env, timeout=3)
except AssertionError:
pass
history = pathlib.Path(hfile.name).read_text()
self.assertIn("2", history)
self.assertIn("exit()", history)
self.assertIn("spam", history)
self.assertIn("time", history)
self.assertIn("import time", history)
self.assertNotIn("sleep", history)
self.assertNotIn("preved", history)
self.assertNotIn("quit", history)
def test_keyboard_interrupt_after_isearch(self):
output, exit_code = self.run_repl(["\x12", "\x03", "exit"])
output, exit_code = self.run_repl("\x12\x03exit\n")
self.assertEqual(exit_code, 0)
def test_prompt_after_help(self):