Skip to content

curses window.encoding does not encode str arguments on a wide build #156347

Description

@fedonman

Documentation

The curses HOWTO says that strings passed to window.addstr() are "encoded to bytes using the value of the window's encoding attribute", and the window.encoding entry in the library reference describes it as the "Encoding used to encode method arguments (Unicode strings and characters)". On a build linked against a wide-character version of the curses library, which is what CPython configures by default, neither is true: PyCurses_ConvertToString in Modules/_cursesmodule.c converts str with PyUnicode_AsWideCharString and never reads win->encoding, so the bytes that reach the terminal come from the current locale instead.

import curses, os, pty, sys
_, slave = pty.openpty()
os.dup2(slave, 0); os.dup2(slave, 1)
win = curses.initscr()
win.encoding = 'latin-1'
win.addstr(0, 0, 'caf\xe9')
got = win.instr(0, 0, 6)
curses.endwin()
print('stored:', got, '  latin-1 would be:', 'caf\xe9'.encode('latin-1'), file=sys.stderr)
stored: b'caf\xc3\xa9 '   latin-1 would be: b'caf\xe9'

Expected: b'caf\xe9', the bytes latin-1 produces, if window.encoding were used to encode the argument.

The attribute is used on a narrow build, where it also decodes results, so the correction has to name the build rather than call the attribute unused.

Linked PRs

Metadata

Metadata

Labels

Projects

Status
No status
Status
Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions