Skip to content

curses.window.insch() does not decode a non-ASCII byte on a wide build #153864

Description

@serhiy-storchaka

Bug report

On a wide (ncursesw) build, window.insch() and window.mvinsch() insert a non-ASCII int/bytes byte as its Latin-1 code point instead of decoding it through the window's encoding, unlike addch(). It is invisible for ASCII/Latin-1 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.insch(0, 0, 0xA4)
    print(str(stdscr.in_wch(0, 0)))    # '¤'  — wrong (byte stored as U+00A4)
    stdscr.addch(1, 0, 0xA4)
    print(str(stdscr.in_wch(1, 0)))    # '€'  — addch() decodes correctly
curses.wrapper(main)

Cause: ncurses' winsch() has a fast path for a printable 8-bit byte that stores it directly as a code point, bypassing the locale decode waddch() performs. Reported upstream (bug-ncurses). It should be worked around on the CPython side by decoding the byte (with btowc(), the inverse of inch()'s wctob()) and inserting it with wins_wch().

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