Skip to content
Merged
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
15 changes: 14 additions & 1 deletion Lib/test/test_curses.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ def wrapped(self, *args, **kwargs):
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.
Expand Down Expand Up @@ -139,7 +145,7 @@ def setUp(self):
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.
Expand All @@ -157,7 +163,11 @@ def setUp(self):
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)
Expand Down Expand Up @@ -2026,6 +2036,7 @@ def test_use_window(self):

@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(
Expand Down Expand Up @@ -2913,6 +2924,7 @@ def stop_reader():


@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",
Expand Down Expand Up @@ -2994,6 +3006,7 @@ def test_disallow_instantiation(self):

@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",
Expand Down
Loading