Skip to content

curses.window.inch() returns the wrong byte for a non-ASCII character on a wide build #153862

Description

@serhiy-storchaka

Bug report

On a wide (ncursesw) build, window.inch() and window.mvinch() return the low 8 bits of a character's code point instead of its locale-encoded byte, so they disagree with instr() for the same cell. It is invisible for ASCII/Latin-1 (where the byte equals the low byte of the code point) and only shows for other single-byte characters.

Under an ISO-8859-15 locale ( U+20AC encodes to 0xA4):

import curses, locale
locale.setlocale(locale.LC_ALL, '')   # run under e.g. LANG=en_US.ISO-8859-15
def main(stdscr):
    stdscr.addstr(0, 0, '€')
    print(hex(stdscr.instr(0, 0, 1)[0]))                 # 0xa4  — correct
    print(hex(stdscr.inch(0, 0) & curses.A_CHARTEXT))    # 0xac  — wrong
curses.wrapper(main)

Cause: ncurses' winch() returns the raw cell character with no locale conversion, unlike instr() and getbkgd(). getbkgd() is not affected. Reported upstream (bug-ncurses), where the 8-bit behavior is considered documented, so this should be worked around on the CPython side by re-encoding the cell to its locale byte when the character has a single-byte form.

Linked PRs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.13bugs and security fixes3.14bugs and security fixes3.15pre-release feature fixes, bugs and security fixes3.16new features, bugs and security fixestype-bugAn unexpected behavior, bug, or error

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions