@@ -80,6 +80,12 @@ def wrapped(self, *args, **kwargs):
8080term = os .environ .get ('TERM' )
8181SHORT_MAX = 0x7fff
8282
83+ # ncurses before 6.5 can crash on repeated newterm(). Fall back to initscr()
84+ # and skip the tests that need several screens.
85+ _ncurses_version = getattr (curses , 'ncurses_version' , None )
86+ BROKEN_NEWTERM = _ncurses_version is not None and _ncurses_version < (6 , 5 )
87+ USE_NEWTERM = hasattr (curses , 'newterm' ) and not BROKEN_NEWTERM
88+
8389# newterm() is used when available (it reports errors instead of exiting), but
8490# initscr() is still the fallback, and an unusable $TERM has no terminal to
8591# drive either way.
@@ -139,7 +145,7 @@ def setUp(self):
139145 sys .stderr .flush ()
140146 sys .stdout .flush ()
141147 print (file = self .output , flush = True )
142- if hasattr ( curses , 'newterm' ) :
148+ if USE_NEWTERM :
143149 # Use newterm() rather than initscr(): it reports errors instead of
144150 # exiting, and gives each test a fresh screen, which also lets
145151 # ScreenTests run newterm()/set_term() in the same process.
@@ -157,7 +163,11 @@ def setUp(self):
157163 self .addCleanup (setattr , self , 'screen' , None )
158164 self .addCleanup (setattr , self , 'stdscr' , None )
159165 else :
166+ # Tests share one initscr() screen; clear the rendition and
167+ # background so a previous test's does not bleed in.
160168 self .stdscr = curses .initscr ()
169+ self .stdscr .attrset (curses .A_NORMAL )
170+ self .stdscr .bkgdset (' ' )
161171 if self .isatty :
162172 curses .savetty ()
163173 self .addCleanup (curses .endwin )
@@ -2026,6 +2036,7 @@ def test_use_window(self):
20262036
20272037 @unittest .skipUnless (hasattr (curses .screen , 'use' ),
20282038 'requires screen.use()' )
2039+ @unittest .skipUnless (USE_NEWTERM , 'no screen object without newterm()' )
20292040 def test_use_screen (self ):
20302041 screen = self .screen
20312042 self .assertEqual (
@@ -2913,6 +2924,7 @@ def stop_reader():
29132924
29142925
29152926@unittest .skipUnless (hasattr (curses , 'newterm' ), 'requires curses.newterm()' )
2927+ @unittest .skipIf (BROKEN_NEWTERM , 'ncurses < 6.5 mishandles repeated newterm()' )
29162928@unittest .skipIf (not term or term == 'unknown' ,
29172929 f"$TERM={ term !r} , newterm() may not work" )
29182930@unittest .skipIf (sys .platform == "cygwin" ,
@@ -2994,6 +3006,7 @@ def test_disallow_instantiation(self):
29943006
29953007@unittest .skipUnless (hasattr (curses , 'slk_init' ), 'requires curses.slk_init()' )
29963008@unittest .skipUnless (hasattr (curses , 'newterm' ), 'requires curses.newterm()' )
3009+ @unittest .skipIf (BROKEN_NEWTERM , 'ncurses < 6.5 mishandles repeated newterm()' )
29973010@unittest .skipIf (not term or term == 'unknown' ,
29983011 f"$TERM={ term !r} , newterm() may not work" )
29993012@unittest .skipIf (sys .platform == "cygwin" ,
0 commit comments