Bug description:
Reader.suspend() captures all 29 fields of the reader, but only restores
6 of them (msg, ps1–ps4, paste_mode). The self.prepare() call in
the finally block clears self.buffer, resets self.pos, and clears
self.kill_ring, and those are not restored.
Reproducer:
from _pyrepl.reader import Reader
class FakeConsole:
height = 24
width = 80
input_hook = None
def prepare(self): pass
def restore(self): pass
def refresh(self, screen): pass
def move_cursor(self, x, y): pass
def finish(self): pass
def wait(self, timeout): return False
def get_event(self, block=False): return None
def push_char(self, c): pass
def getheightwidth(self): return (self.height, self.width)
r = Reader(FakeConsole())
r.buffer[:] = list("hello world")
r.pos = 5
r.kill_ring.append(list("saved"))
before = (list(r.buffer), r.pos, [list(k) for k in r.kill_ring])
with r.suspend():
pass
after = (list(r.buffer), r.pos, [list(k) for k in r.kill_ring])
print(f"before: {before}")
print(f"after: {after}")
Expected:
suspend() should be transparent: after the context manager exits, the
reader should be in the same state as before, apart from the fields that
the nested reader is allowed to change.
Actual:
The buffer is empty, pos is 0, and kill_ring is cleared.
Reachability:
Reader.suspend() is called by help (F1) in Lib/_pyrepl/commands.py:
python
class help(Command):
def do(self) -> None:
import _sitebuiltins
with self.reader.suspend():
self.reader.msg = _sitebuiltins._Helper()()
self.reader.invalidate_prompt()
and wrapped by HistoricalReader.suspend() in
Lib/_pyrepl/historical_reader.py:
python
@contextmanager
def suspend(self) -> SimpleContextManager:
with super().suspend(), self.suspend_history():
yield
A user who types something and then presses F1 loses their input.
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs
Bug description:
Reader.suspend()captures all 29 fields of the reader, but only restores6 of them (
msg,ps1–ps4,paste_mode). Theself.prepare()call inthe
finallyblock clearsself.buffer, resetsself.pos, and clearsself.kill_ring, and those are not restored.Reproducer:
A user who types something and then presses F1 loses their input.
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs