Skip to content

Commit c19389a

Browse files
gh-153862: Fix spurious color pair in curses window.inch() on a wide build
winch() returns the whole code point, so inch() replacing only its low 8 bits left the high bits in the color field. Rebuild from getcchar()'s attributes and color pair. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 5062427 commit c19389a

2 files changed

Lines changed: 6 additions & 6 deletions

File tree

Lib/test/test_curses.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,7 @@ def test_read_from_window(self):
974974
with self.subTest(ch=ch):
975975
stdscr.addstr(2, 0, ch)
976976
self.assertEqual(stdscr.instr(2, 0, 1), b)
977-
self.assertEqual(stdscr.inch(2, 0) & curses.A_CHARTEXT, b[0])
977+
self.assertEqual(stdscr.inch(2, 0), b[0])
978978

979979
def test_coordinate_errors(self):
980980
# Addressing a cell outside the window raises curses.error.

Modules/_cursesmodule.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -776,10 +776,10 @@ curses_getcchar(const cchar_t *wcval, wchar_t *wstr, attr_t *attrs, int *pair)
776776
return rtn;
777777
}
778778

779-
/* winch() returns the low 8 bits of the character's code point with no locale
780-
conversion, unlike instr(), so recover the locale byte from the wide cell
781-
when the character maps to exactly one byte, keeping the attribute and color
782-
bits in RTN. A character with no single-byte form is left to winch(). */
779+
/* winch() does not convert the character to its locale byte, and its bits above
780+
the character may be code-point bits rather than attributes, so rebuild the
781+
value from the locale byte plus getcchar()'s attributes and color pair. A
782+
character with no single-byte form is left to winch(). */
783783
static chtype
784784
curses_cell_locale_byte(chtype rtn, const cchar_t *cell)
785785
{
@@ -795,7 +795,7 @@ curses_cell_locale_byte(chtype rtn, const cchar_t *cell)
795795
when the character has none in this locale. */
796796
int byte = wctob(wstr[0]);
797797
if (byte != EOF) {
798-
rtn = (rtn & ~(chtype)A_CHARTEXT) | (unsigned char)byte;
798+
rtn = (unsigned char)byte | (attrs & ~(attr_t)A_COLOR) | COLOR_PAIR(pair);
799799
}
800800
return rtn;
801801
}

0 commit comments

Comments
 (0)