Bug description:
curses.slk_color() casts its color pair to a short before passing it to ncurses, while the module's pair converter accepts pairs up to INT_MAX on a build with extended color support. Pairs of 32768 and above are therefore narrowed: some are rejected although the rest of the module accepts them on the same screen, and one whose low 16 bits name a valid pair is silently applied in place of the pair that was asked for.
import curses
def main(stdscr):
curses.start_color()
print(f'COLOR_PAIRS = {curses.COLOR_PAIRS}\r')
for pair in (32768, 131077):
for name, fn in (('slk_color', curses.slk_color),
('slk_attr_set', lambda p: curses.slk_attr_set(0, p))):
try:
fn(pair)
print(f'{name}({pair}) -> OK\r')
except curses.error as e:
print(f'{name}({pair}) -> curses.error: {e}\r')
curses.slk_init(0)
curses.wrapper(main)
In an xterm-256color terminal:
�COLOR_PAIRS = 65536
slk_color(32768) -> curses.error: slk_color() returned ERR
slk_attr_set(32768) -> OK
slk_color(131077) -> OK
slk_attr_set(131077) -> curses.error: slk_attr_set() returned ERR
Pair 131077 is not merely accepted and ignored, it is applied as pair 5 (131077 & 0xffff): the bytes ncurses writes for the label line after slk_color(131077) are byte-identical to those after slk_color(5), and differ from slk_color(0).
Doc/library/curses.rst documents slk_color(pair) as setting the soft labels to color pair number pair, with no bound of its own, and gh-152275 records the rule that a color pair that does not fit must raise rather than be truncated into a different pair. slk_color() is the one color-pair entry point in the module that still truncates.
Expected: slk_color() accepts the pairs its siblings accept, and raises curses.error for a pair that is out of range rather than selecting a different one.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs
Bug description:
curses.slk_color()casts its color pair to ashortbefore passing it to ncurses, while the module'spairconverter accepts pairs up toINT_MAXon a build with extended color support. Pairs of 32768 and above are therefore narrowed: some are rejected although the rest of the module accepts them on the same screen, and one whose low 16 bits name a valid pair is silently applied in place of the pair that was asked for.In an
xterm-256colorterminal:Pair 131077 is not merely accepted and ignored, it is applied as pair 5 (
131077 & 0xffff): the bytes ncurses writes for the label line afterslk_color(131077)are byte-identical to those afterslk_color(5), and differ fromslk_color(0).Doc/library/curses.rstdocumentsslk_color(pair)as setting the soft labels to color pair number pair, with no bound of its own, and gh-152275 records the rule that a color pair that does not fit must raise rather than be truncated into a different pair.slk_color()is the one color-pair entry point in the module that still truncates.Expected:
slk_color()accepts the pairs its siblings accept, and raisescurses.errorfor a pair that is out of range rather than selecting a different one.CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs