Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Lib/test/test_curses.py
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,20 @@ def test_env_queries(self):
self.assertIsInstance(c, bytes)
self.assertEqual(len(c), 1)

def test_termattrs_is_not_negative(self):
# A_ITALIC is the topmost bit of a 32-bit attribute mask, so termattrs()
# only tells a signed result from an unsigned one on a terminal that
# advertises it. 3.15 lacks the newterm()/pty harness used on main, so
# exercise the current screen: skip when the top bit is not advertised.
attrs = curses.termattrs()
italic = getattr(curses, 'A_ITALIC', 0)
if not italic or not attrs & italic:
self.skipTest('the terminal advertises no attribute in the top bit')
self.assertGreaterEqual(attrs, 0)
# termattrs() exists to be passed back to the attribute functions,
# which reject a negative mask.
self.stdscr.attrset(attrs)

def test_output_options(self):
stdscr = self.stdscr

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fix :func:`curses.termattrs` returning a negative value on a terminal that
supports :const:`curses.A_ITALIC`, which left its result unusable as an
attribute mask.
6 changes: 5 additions & 1 deletion Modules/_cursesmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -4959,7 +4959,11 @@ Return a logical OR of all video attributes supported by the terminal.
static PyObject *
_curses_termattrs_impl(PyObject *module)
/*[clinic end generated code: output=b06f437fce1b6fc4 input=0559882a04f84d1d]*/
NoArgReturnIntFunctionBody(termattrs)
{
PyCursesStatefulInitialised(module);

return PyLong_FromUnsignedLong((unsigned long)(chtype)termattrs());
}

/*[clinic input]
@permit_long_summary
Expand Down
Loading