Bug description:
curses.termattrs() returns a negative value on a terminal that advertises
A_ITALIC (bit 31), so its result cannot be passed back to the attribute
functions:
>>> curses.termattrs()
-2130771968
>>> curses.term_attrs() # the same bits, unsigned
2164195328
>>> curses.newwin(1, 1).attrset(curses.termattrs())
OverflowError: can't convert negative value to unsigned int
This is a regression in 3.15. Up to 3.14 the macro behind it returned
PyLong_FromLong((long) X()), and on a 64-bit long the mask stayed positive.
GH-134327 rewrote it to check for ERR through an int, which sign-extends:
int rtn = X();
if (rtn == ERR) { ... }
return PyLong_FromLong(rtn);
ERR checking is right for baudrate(), the macro's only other user, but
termattrs() returns a chtype mask, not a status. term_attrs(),
slk_attr() and window.getattrs() all return theirs with
PyLong_FromUnsignedLong.
CPython versions tested on:
CPython main branch, 3.14
Operating systems tested on:
Linux
Linked PRs
Bug description:
curses.termattrs()returns a negative value on a terminal that advertisesA_ITALIC(bit 31), so its result cannot be passed back to the attributefunctions:
This is a regression in 3.15. Up to 3.14 the macro behind it returned
PyLong_FromLong((long) X()), and on a 64-bitlongthe mask stayed positive.GH-134327 rewrote it to check for
ERRthrough anint, which sign-extends:ERRchecking is right forbaudrate(), the macro's only other user, buttermattrs()returns achtypemask, not a status.term_attrs(),slk_attr()andwindow.getattrs()all return theirs withPyLong_FromUnsignedLong.CPython versions tested on:
CPython main branch, 3.14
Operating systems tested on:
Linux
Linked PRs