Skip to content

Make the wide-character curses functions available on a narrow build #152470

Description

@serhiy-storchaka

Feature or enhancement

A CPython curses module built against the non-wide curses library (ncurses, not ncursesw) is a "narrow" build. Historically several wide-character functions were available only on a wide (ncursesw) build, raising AttributeError otherwise.

On an 8-bit locale a "wide" character is just a single byte, so these functions can work on a narrow build too: read or write one byte and decode or encode it with the window's (or the standard screen's) encoding. This lets the same Python code run on both builds, which is the point of the build-transparent cell API added in gh-151757 and gh-152233 (complexchar, complexstr, window.in_wch, window.in_wstr, window.in_wchstr, window.getbkgrnd, all of which already work on a narrow build).

This issue completes that effort by giving the same treatment to the remaining wide-only functions:

  • curses.window.get_wch — on a narrow build a key is read with getch() and a character is decoded with the window's encoding; a value above 255 is still returned as an integer key code.
  • curses.window.get_wstr — reads the input bytes (as getstr()) and decodes them with the window's encoding.
  • curses.unget_wch — pushes the character as a single encoded byte; raises OverflowError if it does not encode to one byte.
  • curses.erasewchar, curses.killwchar — decode the single byte returned by erasechar() / killchar() with the standard screen's encoding.
  • curses.wunctrl — falls back to unctrl() and decodes its result with the standard screen's encoding (a complexchar argument is not accepted on a narrow build).

It also extends curses.ungetch to accept a one-character string, like unget_wch: on a wide build it can be any character (previously a multibyte character raised OverflowError) and is read back with get_wch(); otherwise it must encode to a single byte. The two functions are kept separate because for an integer argument ungetch takes a raw key code while unget_wch takes a character code point, and those ranges overlap.

On a narrow build each character must be representable as a single byte in the relevant encoding (an 8-bit locale); a character that does not fit raises OverflowError, and combining sequences and multibyte characters remain unsupported, exactly as for the cell API.

The existing gh-151757 changelog and What's New entry currently state that get_wstr, erasewchar, killwchar and wunctrl "require the wide-character ncursesw library"; that wording will be corrected, since they no longer do.

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-featureA feature request or enhancement
    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