diff --git a/Lib/_pyrepl/unix_console.py b/Lib/_pyrepl/unix_console.py index 937b5df6ff7d4c..cb8f51cdc4a67a 100644 --- a/Lib/_pyrepl/unix_console.py +++ b/Lib/_pyrepl/unix_console.py @@ -542,7 +542,7 @@ def getpending(self): while not self.event_queue.empty(): e2 = self.event_queue.get() e.data += e2.data - e.raw += e.raw + e.raw += e2.raw amount = struct.unpack("i", ioctl(self.input_fd, FIONREAD, b"\0\0\0\0"))[0] trace("getpending({a})", a=amount) @@ -566,7 +566,7 @@ def getpending(self): while not self.event_queue.empty(): e2 = self.event_queue.get() e.data += e2.data - e.raw += e.raw + e.raw += e2.raw amount = 10000 raw = self.__read(amount) diff --git a/Lib/test/test_pyrepl/test_unix_console.py b/Lib/test/test_pyrepl/test_unix_console.py index 680adbc2d968f0..38f14fca4ee39a 100644 --- a/Lib/test/test_pyrepl/test_unix_console.py +++ b/Lib/test/test_pyrepl/test_unix_console.py @@ -400,3 +400,30 @@ def test_repl_eio(self): ), f"Expected EIO/ENXIO error message in stderr: {err}", ) + + +@unittest.skipIf(sys.platform == "win32", "No Unix console on Windows") +class TestGetPending(TestCase): + def test_getpending_accumulates_raw_from_queued_events(self): + # gh-145886: getpending was adding e.raw to itself instead of e2.raw + console = UnixConsole.__new__(UnixConsole) + console.encoding = "utf-8" + console.input_fd = 0 + + ev1 = Event("key", "a", b"x") + ev2 = Event("key", "b", b"y") + queue = [ev1, ev2] + + mock_eq = MagicMock() + mock_eq.empty = lambda: len(queue) == 0 + mock_eq.get = lambda: queue.pop(0) + console.event_queue = mock_eq + + # Mock __read to return empty bytes (no additional pending input) + console._UnixConsole__read = lambda n: b"" + + with patch("_pyrepl.unix_console.ioctl", return_value=b"\0\0\0\0"): + result = console.getpending() + + self.assertEqual(result.data, "ab") + self.assertEqual(result.raw, b"xy")