FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-83395: Add curses.window.in_wch by asottile · Pull Request #17825 · python/cpython · GitHub

Repository navigation

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .c  (1) .h  (1) .py  (1) .rst  (2) All 4 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
12 changes: 12 additions & 0 deletions Doc/library/curses.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,18 @@ the following methods and attributes:
Return the character at the given position in the window. The bottom 8 bits are
the character proper, and upper bits are the attributes.

.. note::

``inch`` only works for ASCII characters. Use :meth:`in_wch` instead
for unicode support.
Comment on lines +1020 to +1023

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Suggested change
.. note::
``inch`` only works for ASCII characters. Use :meth:`in_wch` instead
for unicode support.
.. note::
This method only works for ASCII characters. Use :meth:`in_wch`
instead to retrieve the Unicode character at a given position.


.. method:: window.in_wch([x, y])
Comment on lines +1024 to +1025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Suggested change
.. method:: window.in_wch([x, y])
.. method:: window.in_wch([x, y])

We separate methods by 2 blank lines (just check that my suggestion is correct before committing it).

Comment on lines +1024 to +1025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Suggested change
.. method:: window.in_wch([x, y])
.. method:: window.in_wch([y, x])


Return the wide character at the given position in the window. The return
value is a 3-tuple ``(character, attributes, color_pair)``.
Comment on lines +1027 to +1028

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Suggested change
Return the wide character at the given position in the window. The return
value is a 3-tuple ``(character, attributes, color_pair)``.
Return the wide character at the given position in the window as
a triplet ``(character, attributes, color_pair)``.


.. versionadded:: 3.14


.. method:: window.insch(ch[, attr])
window.insch(y, x, ch[, attr])
Expand Down
33 changes: 33 additions & 0 deletions Lib/test/test_curses.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -1107,6 +1107,39 @@ def test_issue6243(self):
curses.ungetch(1025)
self.stdscr.getkey()

def test_in_wch(self):
stdscr = self.stdscr

if not hasattr(stdscr, 'in_wch'):
raise unittest.SkipTest('requires curses.window.in_wch')
Comment on lines +1113 to +1114

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Do you need this kind of check or can you use @requires_curses_window_meth('in_wch')?


if curses.has_colors():
curses.init_pair(1, curses.COLOR_RED, 0)
expected_pair = 1
color_attr = curses.color_pair(expected_pair)
else:
expected_pair = 0
color_attr = 0

def _norm(ch, attr, color):
# for some reason, curses returns some color bits here?
return ch, attr & ~curses.A_COLOR, color

for ch in ('a', '\xe9', '\u20ac', '\U0001f643'):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I would use a subTest to locate failures if needed.

expected = (ch, curses.A_BOLD, expected_pair)

stdscr.insstr(0, 0, ch, color_attr | curses.A_BOLD)
self.assertEqual(_norm(*stdscr.in_wch()), expected)

stdscr.addstr(0, 0, ch, color_attr | curses.A_BOLD)
self.assertEqual(_norm(*stdscr.in_wch(0, 0)), expected)
Comment on lines +1131 to +1135

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Can we use something that is not at (0, 0) as well to check the ordering (y, x)?


# in_wch can return multiple characters in the case of zero width
# curses at max returns 5 characters in a cchar_t
stdscr.addstr(0, 0, 'a' + '\u200b' * 10)
expected = ('a\u200b\u200b\u200b\u200b', 0, 0)
self.assertEqual(stdscr.in_wch(0, 0), expected)

@requires_curses_func('unget_wch')
@unittest.skipIf(getattr(curses, 'ncurses_version', (99,)) < (5, 8),
"unget_wch is broken in ncurses 5.7 and earlier")
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add :func:`curses.window.in_wch` function - by Anthony Sottile.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Suggested change
Add :func:`curses.window.in_wch` function - by Anthony Sottile.
Add :func:`curses.window.in_wch` function to get the Unicode character
at a given position. Patch by Anthony Sottile.

49 changes: 49 additions & 0 deletions Modules/_cursesmodule.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -1736,6 +1736,54 @@ _curses_window_inch_impl(PyCursesWindowObject *self, int group_right_1,
return rtn;
}

#ifdef HAVE_NCURSESW
/*[clinic input]
_curses.window.in_wch

[
y: int
Starting Y-coordinate.
x: int
Starting X-coordinate.
]
Comment on lines +1744 to +1748

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Suggested change
y: int
Starting Y-coordinate.
x: int
Starting X-coordinate.
]
y: int
Y-coordinate.
x: int
X-coordinate.
]

Let's use the same wording as for inch.

/

Retrieve the wide character at the gven position in the window.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Suggested change
Retrieve the wide character at the gven position in the window.
Retrieve the Unicode character at the given position in the window.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Ah, wait, should we say wide character or Unicode character here (it's a wchar_t but we use it to indicate "Unicode" range so...)


The return value is a 3-tuple of (character, attributes, color_pair).
[clinic start generated code]*/

static PyObject *
_curses_window_in_wch_impl(PyCursesWindowObject *self, int group_right_1,
int y, int x)
/*[clinic end generated code: output=846ca8a82f2ecab4 input=5c20d96b592b0e0b]*/
{
int ret;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Ah maybe I should have said it in the other review, but I think we use rtn in general and not ret.


cchar_t wcval;

wchar_t wstr[CCHARW_MAX + 1];
attr_t attr;
short color_pair;

if (group_right_1) {
ret = mvwin_wch(self->win, y, x, &wcval);
} else {
ret = win_wch(self->win, &wcval);
}
if (PyCursesCheckERR(ret, "in_wch") == NULL) {
return NULL;
}
Comment on lines +1769 to +1776

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Suggested change
if (group_right_1) {
ret = mvwin_wch(self->win, y, x, &wcval);
} else {
ret = win_wch(self->win, &wcval);
}
if (PyCursesCheckERR(ret, "in_wch") == NULL) {
return NULL;
}
if (group_right_1) {
ret = mvwin_wch(self->win, y, x, &wcval);
if (ret == ERR) {
PyErr_SetString(PyCursesError, "mvwin_wch() returned ERR");
return NULL;
}
}
else {
ret = win_wch(self->win, &wcval);
if (ret == ERR) {
PyErr_SetString(PyCursesError, "win_wch() returned ERR");
return NULL;
}
}


ret = getcchar(&wcval, wstr, &attr, &color_pair, NULL);
if (PyCursesCheckERR(ret, "getcchar") == NULL) {
return NULL;
}
Comment on lines +1779 to +1781

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Suggested change
if (PyCursesCheckERR(ret, "getcchar") == NULL) {
return NULL;
}
if (ret == ERR) {
PyErr_SetString(PyCursesError, "getcchar() returned ERR");
return NULL;
}


return Py_BuildValue("ukh", wstr, attr, color_pair);
}
#endif

/*[-clinic input]
_curses.window.instr

Expand Down Expand Up @@ -2530,6 +2578,7 @@ static PyMethodDef PyCursesWindow_Methods[] = {
{"immedok", (PyCFunction)PyCursesWindow_immedok, METH_VARARGS},
#endif
_CURSES_WINDOW_INCH_METHODDEF
_CURSES_WINDOW_IN_WCH_METHODDEF
_CURSES_WINDOW_INSCH_METHODDEF
{"insdelln", (PyCFunction)PyCursesWindow_winsdelln, METH_VARARGS},
{"insertln", (PyCFunction)PyCursesWindow_winsertln, METH_NOARGS},
Expand Down
55 changes: 54 additions & 1 deletion Modules/clinic/_cursesmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.


Back | FazBrowse Home | New Git URL