term = os.environ.get('TERM')
SHORT_MAX = 0x7fff
+# ncurses before 6.5 can crash on repeated newterm(). Fall back to initscr()
+# and skip the tests that need several screens.
+_ncurses_version = getattr(curses, 'ncurses_version', None)
+BROKEN_NEWTERM = _ncurses_version is not None and _ncurses_version < (6, 5)
+USE_NEWTERM = hasattr(curses, 'newterm') and not BROKEN_NEWTERM
+
# newterm() is used when available (it reports errors instead of exiting), but
# initscr() is still the fallback, and an unusable $TERM has no terminal to
# drive either way.
sys.stderr.flush()
sys.stdout.flush()
print(file=self.output, flush=True)
- if hasattr(curses, 'newterm'):
+ if USE_NEWTERM:
# Use newterm() rather than initscr(): it reports errors instead of
# exiting, and gives each test a fresh screen, which also lets
# ScreenTests run newterm()/set_term() in the same process.
self.addCleanup(setattr, self, 'screen', None)
self.addCleanup(setattr, self, 'stdscr', None)
else:
+ # Tests share one initscr() screen; clear the rendition and
+ # background so a previous test's does not bleed in.
self.stdscr = curses.initscr()
+ self.stdscr.attrset(curses.A_NORMAL)
+ self.stdscr.bkgdset(' ')
if self.isatty:
curses.savetty()
self.addCleanup(curses.endwin)
@unittest.skipUnless(hasattr(curses.screen, 'use'),
'requires screen.use()')
+ @unittest.skipUnless(USE_NEWTERM, 'no screen object without newterm()')
def test_use_screen(self):
screen = self.screen
self.assertEqual(
@unittest.skipUnless(hasattr(curses, 'newterm'), 'requires curses.newterm()')
+@unittest.skipIf(BROKEN_NEWTERM, 'ncurses < 6.5 mishandles repeated newterm()')
@unittest.skipIf(not term or term == 'unknown',
f"$TERM={term!r}, newterm() may not work")
@unittest.skipIf(sys.platform == "cygwin",
@unittest.skipUnless(hasattr(curses, 'slk_init'), 'requires curses.slk_init()')
@unittest.skipUnless(hasattr(curses, 'newterm'), 'requires curses.newterm()')
+@unittest.skipIf(BROKEN_NEWTERM, 'ncurses < 6.5 mishandles repeated newterm()')
@unittest.skipIf(not term or term == 'unknown',
f"$TERM={term!r}, newterm() may not work")
@unittest.skipIf(sys.platform == "cygwin",