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

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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions