https://github.com/python/cpython/commit/e13f6dccd7a2f8df543a18c4a3ad92610dc087cb
commit: e13f6dccd7a2f8df543a18c4a3ad92610dc087cb
branch: main
author: Tan Long <[email protected]>
committer: ambv <[email protected]>
date: 2026-03-12T16:59:43+01:00
summary:
gh-140131: Fix REPL cursor position on Windows when module completion
suggestion line hits console width (GH-140333)
files:
A Misc/NEWS.d/next/Library/2026-02-11-21-01-30.gh-issue-144259.OAhOR8.rst
A Misc/NEWS.d/next/Windows/2025-10-19-23-44-46.gh-issue-140131.AABF2k.rst
M Lib/_pyrepl/windows_console.py
M Lib/test/test_pyrepl/test_pyrepl.py
diff --git a/Lib/_pyrepl/windows_console.py b/Lib/_pyrepl/windows_console.py
index 6c949c046875f3..cb1834168e881c 100644
--- a/Lib/_pyrepl/windows_console.py
+++ b/Lib/_pyrepl/windows_console.py
@@ -270,18 +270,13 @@ def __write_changed_line(
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
diff --git a/Lib/test/test_pyrepl/test_pyrepl.py
b/Lib/test/test_pyrepl/test_pyrepl.py
index 35a1733787e7a2..082215da0a3fba 100644
--- a/Lib/test/test_pyrepl/test_pyrepl.py
+++ b/Lib/test/test_pyrepl/test_pyrepl.py
@@ -12,7 +12,7 @@
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 @@ def test_ctrl_d_single_line_end_no_newline(self):
)
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
index 00000000000000..280f3b742b013c
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-02-11-21-01-30.gh-issue-144259.OAhOR8.rst
@@ -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
index 00000000000000..3c2d30d8d9813d
--- /dev/null
+++ b/Misc/NEWS.d/next/Windows/2025-10-19-23-44-46.gh-issue-140131.AABF2k.rst
@@ -0,0 +1,2 @@
+Fix REPL cursor position on Windows when module completion suggestion line
+hits console width.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]