]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-140131: Fix REPL cursor position on Windows when module completion suggestion...
authorTan Long <tanloong@foxmail.com>
Thu, 12 Mar 2026 15:59:43 +0000 (23:59 +0800)
committerGitHub <noreply@github.com>
Thu, 12 Mar 2026 15:59:43 +0000 (16:59 +0100)
Lib/_pyrepl/windows_console.py
Lib/test/test_pyrepl/test_pyrepl.py
Misc/NEWS.d/next/Library/2026-02-11-21-01-30.gh-issue-144259.OAhOR8.rst [new file with mode: 0644]
Misc/NEWS.d/next/Windows/2025-10-19-23-44-46.gh-issue-140131.AABF2k.rst [new file with mode: 0644]

index 6c949c046875f32ccda96f6629c5d9b09fadb18c..cb1834168e881c0506ab7f55dd44e3e51768c656 100644 (file)
@@ -270,18 +270,13 @@ class WindowsConsole(Console):
             self._erase_to_end()
 
         self.__write(newline[x_pos:])
-        if wlen(newline) == self.width:
-            # If we wrapped we want to start at the next line
-            self._move_relative(0, y + 1)
-            self.posxy = 0, y + 1
-        else:
-            self.posxy = wlen(newline), y
+        self.posxy = min(wlen(newline), self.width - 1), y
 
-            if "\x1b" in newline or y != self.posxy[1] or '\x1a' in newline:
-                # ANSI escape characters are present, so we can't assume
-                # anything about the position of the cursor.  Moving the cursor
-                # to the left margin should work to get to a known position.
-                self.move_cursor(0, y)
+        if "\x1b" in newline or y != self.posxy[1] or '\x1a' in newline:
+            # ANSI escape characters are present, so we can't assume
+            # anything about the position of the cursor.  Moving the cursor
+            # to the left margin should work to get to a known position.
+            self.move_cursor(0, y)
 
     def _scroll(
         self, top: int, bottom: int, left: int | None = None, right: int | None = None
index 35a1733787e7a2f96cee999180e126b54541cc81..082215da0a3fbaee7a272efbffcfcdeefbc9facf 100644 (file)
@@ -12,7 +12,7 @@ import sys
 import tempfile
 from pkgutil import ModuleInfo
 from unittest import TestCase, skipUnless, skipIf, SkipTest
-from unittest.mock import patch
+from unittest.mock import Mock, patch
 from test.support import force_not_colorized, make_clean_env, Py_DEBUG
 from test.support import has_subprocess_support, SHORT_TIMEOUT, STDLIB_DIR
 from test.support.import_helper import import_module
@@ -2105,3 +2105,47 @@ class TestPyReplCtrlD(TestCase):
         )
         reader, _ = handle_all_events(events)
         self.assertEqual("hello", "".join(reader.buffer))
+
+
+@skipUnless(sys.platform == "win32", "windows console only")
+class TestWindowsConsoleEolWrap(TestCase):
+    def _make_mock_console(self, width=80):
+        from _pyrepl import windows_console as wc
+
+        console = object.__new__(wc.WindowsConsole)
+
+        console.width = width
+        console.posxy = (0, 0)
+        console.screen = [""]
+
+        console._hide_cursor = Mock()
+        console._show_cursor = Mock()
+        console._erase_to_end = Mock()
+        console._move_relative = Mock()
+        console.move_cursor = Mock()
+        console._WindowsConsole__write = Mock()
+
+        return console, wc
+
+    def test_short_line_sets_posxy_normally(self):
+        width = 10
+        y = 3
+        console, wc = self._make_mock_console(width=width)
+        old_line = ""
+        new_line = "a" * 3
+        wc.WindowsConsole._WindowsConsole__write_changed_line(
+            console, y, old_line, new_line, 0
+        )
+        self.assertEqual(console.posxy, (3, y))
+
+    def test_exact_width_line_does_not_wrap(self):
+        width = 10
+        y = 3
+        console, wc = self._make_mock_console(width=width)
+        old_line = ""
+        new_line = "a" * width
+
+        wc.WindowsConsole._WindowsConsole__write_changed_line(
+            console, y, old_line, new_line, 0
+        )
+        self.assertEqual(console.posxy, (width - 1, y))
diff --git a/Misc/NEWS.d/next/Library/2026-02-11-21-01-30.gh-issue-144259.OAhOR8.rst b/Misc/NEWS.d/next/Library/2026-02-11-21-01-30.gh-issue-144259.OAhOR8.rst
new file mode 100644 (file)
index 0000000..280f3b7
--- /dev/null
@@ -0,0 +1 @@
+Fix inconsistent display of long multiline pasted content in the REPL.
diff --git a/Misc/NEWS.d/next/Windows/2025-10-19-23-44-46.gh-issue-140131.AABF2k.rst b/Misc/NEWS.d/next/Windows/2025-10-19-23-44-46.gh-issue-140131.AABF2k.rst
new file mode 100644 (file)
index 0000000..3c2d30d
--- /dev/null
@@ -0,0 +1,2 @@
+Fix REPL cursor position on Windows when module completion suggestion line\r
+hits console width.\r