summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAidan Melen <aidan-melen@protonmail.com>2023-04-26 20:54:07 (GMT)
committerGitHub <noreply@github.com>2023-04-26 20:54:07 (GMT)
commita3a5b4bb232ba29875147baa3b56a5524eece353 (patch)
treef631eb34d279d3288e8dd2aaffc22eab94e25324
parent44010d0f1203134cd8f885ca574caaef373e80f6 (diff)
downloadcpython-a3a5b4bb232ba29875147baa3b56a5524eece353.zip
cpython-a3a5b4bb232ba29875147baa3b56a5524eece353.tar.gz
cpython-a3a5b4bb232ba29875147baa3b56a5524eece353.tar.bz2
gh-60436: fix curses textbox backspace/del (#103783)
Co-authored-by: Ɓukasz Langa <lukasz@langa.pl> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: Michael Blahay <mblahay@gmail.com>
-rw-r--r--Lib/curses/textpad.py7
-rw-r--r--Lib/test/test_curses.py71
-rw-r--r--Misc/NEWS.d/next/macOS/2023-04-24-18-37-48.gh-issue-60436.in-IyF.rst1
3 files changed, 77 insertions, 2 deletions
diff --git a/Lib/curses/textpad.py b/Lib/curses/textpad.py
index 2079953..aa87061 100644
--- a/Lib/curses/textpad.py
+++ b/Lib/curses/textpad.py
@@ -102,7 +102,10 @@ class Textbox:
self._insert_printable_char(ch)
elif ch == curses.ascii.SOH: # ^a
self.win.move(y, 0)
- elif ch in (curses.ascii.STX,curses.KEY_LEFT, curses.ascii.BS,curses.KEY_BACKSPACE):
+ elif ch in (curses.ascii.STX,curses.KEY_LEFT,
+ curses.ascii.BS,
+ curses.KEY_BACKSPACE,
+ curses.ascii.DEL):
if x > 0:
self.win.move(y, x-1)
elif y == 0:
@@ -111,7 +114,7 @@ class Textbox:
self.win.move(y-1, self._end_of_line(y-1))
else:
self.win.move(y-1, self.maxx)
- if ch in (curses.ascii.BS, curses.KEY_BACKSPACE):
+ if ch in (curses.ascii.BS, curses.KEY_BACKSPACE, curses.ascii.DEL):
self.win.delch()
elif ch == curses.ascii.EOT: # ^d
self.win.delch()
diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py
index b550f4a..3ab837e 100644
--- a/Lib/test/test_curses.py
+++ b/Lib/test/test_curses.py
@@ -5,6 +5,7 @@ import string
import sys
import tempfile
import unittest
+from unittest.mock import MagicMock
from test.support import (requires, verbose, SaveSignals, cpython_only,
check_disallow_instantiation)
@@ -1319,5 +1320,75 @@ def lorem_ipsum(win):
for y, line in enumerate(text[:maxy]):
win.addstr(y, 0, line[:maxx - (y == maxy - 1)])
+
+class TextboxTest(unittest.TestCase):
+ def setUp(self):
+ self.mock_win = MagicMock(spec=curses.window)
+ self.mock_win.getyx.return_value = (1, 1)
+ self.mock_win.getmaxyx.return_value = (10, 20)
+ self.textbox = curses.textpad.Textbox(self.mock_win)
+
+ def test_init(self):
+ """Test textbox initialization."""
+ self.mock_win.reset_mock()
+ tb = curses.textpad.Textbox(self.mock_win)
+ self.mock_win.getmaxyx.assert_called_once_with()
+ self.mock_win.keypad.assert_called_once_with(1)
+ self.assertEqual(tb.insert_mode, False)
+ self.assertEqual(tb.stripspaces, 1)
+ self.assertIsNone(tb.lastcmd)
+ self.mock_win.reset_mock()
+
+ def test_insert(self):
+ """Test inserting a printable character."""
+ self.mock_win.reset_mock()
+ self.textbox.do_command(ord('a'))
+ self.mock_win.addch.assert_called_with(ord('a'))
+ self.textbox.do_command(ord('b'))
+ self.mock_win.addch.assert_called_with(ord('b'))
+ self.textbox.do_command(ord('c'))
+ self.mock_win.addch.assert_called_with(ord('c'))
+ self.mock_win.reset_mock()
+
+ def test_delete(self):
+ """Test deleting a character."""
+ self.mock_win.reset_mock()
+ self.textbox.do_command(curses.ascii.BS)
+ self.textbox.do_command(curses.KEY_BACKSPACE)
+ self.textbox.do_command(curses.ascii.DEL)
+ assert self.mock_win.delch.call_count == 3
+ self.mock_win.reset_mock()
+
+ def test_move_left(self):
+ """Test moving the cursor left."""
+ self.mock_win.reset_mock()
+ self.textbox.do_command(curses.KEY_LEFT)
+ self.mock_win.move.assert_called_with(1, 0)
+ self.textbox.do_command(curses.KEY_RIGHT)
+ self.mock_win.move.assert_called_with(1, 2)
+ self.mock_win.reset_mock()
+
+ def test_move_left(self):
+ """Test moving the cursor left."""
+ self.mock_win.reset_mock()
+ self.textbox.do_command(curses.KEY_RIGHT)
+ self.mock_win.move.assert_called_with(1, 2)
+ self.mock_win.reset_mock()
+
+ def test_move_up(self):
+ """Test moving the cursor left."""
+ self.mock_win.reset_mock()
+ self.textbox.do_command(curses.KEY_UP)
+ self.mock_win.move.assert_called_with(0, 1)
+ self.mock_win.reset_mock()
+
+ def test_move_down(self):
+ """Test moving the cursor left."""
+ self.mock_win.reset_mock()
+ self.textbox.do_command(curses.KEY_DOWN)
+ self.mock_win.move.assert_called_with(2, 1)
+ self.mock_win.reset_mock()
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/Misc/NEWS.d/next/macOS/2023-04-24-18-37-48.gh-issue-60436.in-IyF.rst b/Misc/NEWS.d/next/macOS/2023-04-24-18-37-48.gh-issue-60436.in-IyF.rst
new file mode 100644
index 0000000..f274d3b
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2023-04-24-18-37-48.gh-issue-60436.in-IyF.rst
@@ -0,0 +1 @@
+update curses textbox to additionally handle backspace using the ``curses.ascii.DEL`` key press.