[3.9] bpo-42681: Fix test_curses failures related to color pairs (GH-24089)
On ncurses 6.1 pair numbers are limited by SHORT_MAX-1, even
with extended color support.
Improve error reporting and tests for color functions..
(cherry picked from commit 59f9b4e450
)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
80e5732d31
commit
ad76ab2a4b
|
@ -323,11 +323,20 @@ class TestCurses(unittest.TestCase):
|
||||||
def bad_pairs(self):
|
def bad_pairs(self):
|
||||||
return (-2**31 - 1, 2**31, -2**63 - 1, 2**63, 2**64)
|
return (-2**31 - 1, 2**31, -2**63 - 1, 2**63, 2**64)
|
||||||
|
|
||||||
|
def test_start_color(self):
|
||||||
|
if not curses.has_colors():
|
||||||
|
self.skipTest('requires colors support')
|
||||||
|
curses.start_color()
|
||||||
|
if verbose:
|
||||||
|
print(f'COLORS = {curses.COLORS}', file=sys.stderr)
|
||||||
|
print(f'COLOR_PAIRS = {curses.COLOR_PAIRS}', file=sys.stderr)
|
||||||
|
|
||||||
@requires_colors
|
@requires_colors
|
||||||
def test_color_content(self):
|
def test_color_content(self):
|
||||||
self.assertEqual(curses.color_content(curses.COLOR_BLACK), (0, 0, 0))
|
self.assertEqual(curses.color_content(curses.COLOR_BLACK), (0, 0, 0))
|
||||||
curses.color_content(0)
|
curses.color_content(0)
|
||||||
curses.color_content(min(curses.COLORS - 1, SHORT_MAX))
|
maxcolor = min(curses.COLORS - 1, SHORT_MAX)
|
||||||
|
curses.color_content(maxcolor)
|
||||||
|
|
||||||
for color in self.bad_colors():
|
for color in self.bad_colors():
|
||||||
self.assertRaises(OverflowError, curses.color_content, color)
|
self.assertRaises(OverflowError, curses.color_content, color)
|
||||||
|
@ -368,13 +377,18 @@ class TestCurses(unittest.TestCase):
|
||||||
self.assertRaises(curses.error, curses.init_color, 0, 0, comp, 0)
|
self.assertRaises(curses.error, curses.init_color, 0, 0, comp, 0)
|
||||||
self.assertRaises(curses.error, curses.init_color, 0, 0, 0, comp)
|
self.assertRaises(curses.error, curses.init_color, 0, 0, 0, comp)
|
||||||
|
|
||||||
|
def get_pair_limit(self):
|
||||||
|
return min(curses.COLOR_PAIRS, SHORT_MAX)
|
||||||
|
|
||||||
@requires_colors
|
@requires_colors
|
||||||
def test_pair_content(self):
|
def test_pair_content(self):
|
||||||
if not hasattr(curses, 'use_default_colors'):
|
if not hasattr(curses, 'use_default_colors'):
|
||||||
self.assertEqual(curses.pair_content(0),
|
self.assertEqual(curses.pair_content(0),
|
||||||
(curses.COLOR_WHITE, curses.COLOR_BLACK))
|
(curses.COLOR_WHITE, curses.COLOR_BLACK))
|
||||||
curses.pair_content(0)
|
curses.pair_content(0)
|
||||||
curses.pair_content(min(curses.COLOR_PAIRS - 1, SHORT_MAX))
|
maxpair = self.get_pair_limit() - 1
|
||||||
|
if maxpair > 0:
|
||||||
|
curses.pair_content(maxpair)
|
||||||
|
|
||||||
for pair in self.bad_pairs():
|
for pair in self.bad_pairs():
|
||||||
self.assertRaises(OverflowError, curses.pair_content, pair)
|
self.assertRaises(OverflowError, curses.pair_content, pair)
|
||||||
|
@ -389,11 +403,14 @@ class TestCurses(unittest.TestCase):
|
||||||
curses.init_pair(1, 0, 0)
|
curses.init_pair(1, 0, 0)
|
||||||
self.assertEqual(curses.pair_content(1), (0, 0))
|
self.assertEqual(curses.pair_content(1), (0, 0))
|
||||||
maxcolor = min(curses.COLORS - 1, SHORT_MAX)
|
maxcolor = min(curses.COLORS - 1, SHORT_MAX)
|
||||||
curses.init_pair(1, maxcolor, maxcolor)
|
curses.init_pair(1, maxcolor, 0)
|
||||||
self.assertEqual(curses.pair_content(1), (maxcolor, maxcolor))
|
self.assertEqual(curses.pair_content(1), (maxcolor, 0))
|
||||||
maxpair = min(curses.COLOR_PAIRS - 1, SHORT_MAX)
|
curses.init_pair(1, 0, maxcolor)
|
||||||
curses.init_pair(maxpair, 2, 3)
|
self.assertEqual(curses.pair_content(1), (0, maxcolor))
|
||||||
self.assertEqual(curses.pair_content(maxpair), (2, 3))
|
maxpair = self.get_pair_limit() - 1
|
||||||
|
if maxpair > 1:
|
||||||
|
curses.init_pair(maxpair, 0, 0)
|
||||||
|
self.assertEqual(curses.pair_content(maxpair), (0, 0))
|
||||||
|
|
||||||
for pair in self.bad_pairs():
|
for pair in self.bad_pairs():
|
||||||
self.assertRaises(OverflowError, curses.init_pair, pair, 0, 0)
|
self.assertRaises(OverflowError, curses.init_pair, pair, 0, 0)
|
||||||
|
@ -591,6 +608,8 @@ class MiscTests(unittest.TestCase):
|
||||||
@requires_curses_func('ncurses_version')
|
@requires_curses_func('ncurses_version')
|
||||||
def test_ncurses_version(self):
|
def test_ncurses_version(self):
|
||||||
v = curses.ncurses_version
|
v = curses.ncurses_version
|
||||||
|
if verbose:
|
||||||
|
print(f'ncurses_version = {curses.ncurses_version}', flush=True)
|
||||||
self.assertIsInstance(v[:], tuple)
|
self.assertIsInstance(v[:], tuple)
|
||||||
self.assertEqual(len(v), 3)
|
self.assertEqual(len(v), 3)
|
||||||
self.assertIsInstance(v[0], int)
|
self.assertIsInstance(v[0], int)
|
||||||
|
|
|
@ -2592,13 +2592,18 @@ _curses_color_content_impl(PyObject *module, short color_number)
|
||||||
PyCursesInitialised;
|
PyCursesInitialised;
|
||||||
PyCursesInitialisedColor;
|
PyCursesInitialisedColor;
|
||||||
|
|
||||||
if (color_content(color_number, &r, &g, &b) != ERR)
|
if (color_content(color_number, &r, &g, &b) == ERR) {
|
||||||
return Py_BuildValue("(iii)", r, g, b);
|
if (color_number >= COLORS) {
|
||||||
else {
|
|
||||||
PyErr_SetString(PyCursesError,
|
PyErr_SetString(PyCursesError,
|
||||||
"Argument 1 was out of range. Check value of COLORS.");
|
"Argument 1 was out of range. Check value of COLORS.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyErr_SetString(PyCursesError, "color_content() returned ERR");
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Py_BuildValue("(iii)", r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
|
@ -3702,8 +3707,13 @@ _curses_pair_content_impl(PyObject *module, short pair_number)
|
||||||
PyCursesInitialisedColor;
|
PyCursesInitialisedColor;
|
||||||
|
|
||||||
if (pair_content(pair_number, &f, &b) == ERR) {
|
if (pair_content(pair_number, &f, &b) == ERR) {
|
||||||
|
if (pair_number >= COLOR_PAIRS) {
|
||||||
PyErr_SetString(PyCursesError,
|
PyErr_SetString(PyCursesError,
|
||||||
"Argument 1 was out of range. (0..COLOR_PAIRS-1)");
|
"Argument 1 was out of range. (0..COLOR_PAIRS-1)");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyErr_SetString(PyCursesError, "pair_content() returned ERR");
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue