https://github.com/python/cpython/commit/7a90d94df7905b773594e0cfb756830e8c630757
commit: 7a90d94df7905b773594e0cfb756830e8c630757
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: DinoV <[email protected]>
date: 2024-07-30T12:34:22-07:00
summary:

[3.13] gh-119896: Fix CTRL-Z behavior in the new REPL on Windows (GH-122217) 
(#122451)

gh-119896: Fix CTRL-Z behavior in the new REPL on Windows (GH-122217)
(cherry picked from commit d1a1bca1f0550a4715f1bf32b1586caa7bc4487b)

Co-authored-by: Dino Viehland <[email protected]>

files:
M Lib/_pyrepl/reader.py
M Lib/_pyrepl/simple_interact.py
M Lib/_pyrepl/utils.py
M Lib/_pyrepl/windows_console.py

diff --git a/Lib/_pyrepl/reader.py b/Lib/_pyrepl/reader.py
index bb1406bae7483e..1e11a54309a771 100644
--- a/Lib/_pyrepl/reader.py
+++ b/Lib/_pyrepl/reader.py
@@ -21,6 +21,8 @@
 
 from __future__ import annotations
 
+import sys
+
 from contextlib import contextmanager
 from dataclasses import dataclass, field, fields
 import unicodedata
@@ -52,7 +54,10 @@ def disp_str(buffer: str) -> tuple[str, list[int]]:
     b: list[int] = []
     s: list[str] = []
     for c in buffer:
-        if ord(c) < 128:
+        if c == '\x1a':
+            s.append(c)
+            b.append(2)
+        elif ord(c) < 128:
             s.append(c)
             b.append(1)
         elif unicodedata.category(c).startswith("C"):
@@ -110,7 +115,7 @@ def make_default_commands() -> dict[CommandName, 
type[Command]]:
         (r"\C-w", "unix-word-rubout"),
         (r"\C-x\C-u", "upcase-region"),
         (r"\C-y", "yank"),
-        (r"\C-z", "suspend"),
+        *(() if sys.platform == "win32" else ((r"\C-z", "suspend"), )),
         (r"\M-b", "backward-word"),
         (r"\M-c", "capitalize-word"),
         (r"\M-d", "kill-word"),
diff --git a/Lib/_pyrepl/simple_interact.py b/Lib/_pyrepl/simple_interact.py
index 2c3dffe070c629..91aef5e01eb867 100644
--- a/Lib/_pyrepl/simple_interact.py
+++ b/Lib/_pyrepl/simple_interact.py
@@ -76,6 +76,7 @@ def _clear_screen():
     "copyright": _sitebuiltins._Printer('copyright', sys.copyright),
     "help": "help",
     "clear": _clear_screen,
+    "\x1a": _sitebuiltins.Quitter('\x1a', ''),
 }
 
 
diff --git a/Lib/_pyrepl/utils.py b/Lib/_pyrepl/utils.py
index 20dbb1f7e17229..0f36083b6ffa92 100644
--- a/Lib/_pyrepl/utils.py
+++ b/Lib/_pyrepl/utils.py
@@ -21,4 +21,5 @@ def wlen(s: str) -> int:
     length = sum(str_width(i) for i in s)
     # remove lengths of any escape sequences
     sequence = ANSI_ESCAPE_SEQUENCE.findall(s)
-    return length - sum(len(i) for i in sequence)
+    ctrl_z_cnt = s.count('\x1a')
+    return length - sum(len(i) for i in sequence) + ctrl_z_cnt
diff --git a/Lib/_pyrepl/windows_console.py b/Lib/_pyrepl/windows_console.py
index 9e97b1524e29a0..ba9af36b8be99c 100644
--- a/Lib/_pyrepl/windows_console.py
+++ b/Lib/_pyrepl/windows_console.py
@@ -253,7 +253,7 @@ def __write_changed_line(
         else:
             self.__posxy = wlen(newline), y
 
-            if "\x1b" in newline or y != self.__posxy[1]:
+            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.
@@ -291,6 +291,9 @@ def _disable_blinking(self):
         self.__write("\x1b[?12l")
 
     def __write(self, text: str) -> None:
+        if "\x1a" in text:
+            text = ''.join(["^Z" if x == '\x1a' else x for x in text])
+
         if self.out is not None:
             self.out.write(text.encode(self.encoding, "replace"))
             self.out.flush()

_______________________________________________
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]

Reply via email to