@@ -796,6 +796,9 @@ def test_complexstr(self):
796796 self .assertEqual (str (s [1 :]), 'bc' )
797797 self .assertEqual (str (s [::- 1 ]), 'cbA' )
798798 self .assertEqual (str (s + curses .complexstr (['Z' ])), 'AbcZ' )
799+ # Concatenating anything else raises instead of returning NotImplemented.
800+ self .assertRaises (TypeError , lambda : s + 'Z' )
801+ self .assertRaises (TypeError , lambda : s + cc ('Z' ))
799802 # The empty complexstr.
800803 self .assertEqual (len (curses .complexstr ([])), 0 )
801804 self .assertEqual (str (curses .complexstr ('' )), '' )
@@ -3383,6 +3386,23 @@ def test_close(self):
33833386 # close() is idempotent.
33843387 screen .close ()
33853388
3389+ def test_close_then_write_with_attr_keeps_no_reference (self ):
3390+ # A write with an *attr* argument on a detached window fails while
3391+ # setting the rendition, and has to release the bytes it converted.
3392+ s = self .make_pty ()
3393+ screen = curses .newterm ('xterm' , s , s )
3394+ win = screen .stdscr
3395+ screen .close ()
3396+ writes = [lambda b : win .addstr (b , curses .A_BOLD ),
3397+ lambda b : win .addnstr (b , 4 , curses .A_BOLD ),
3398+ lambda b : win .insstr (b , curses .A_BOLD ),
3399+ lambda b : win .insnstr (b , 4 , curses .A_BOLD )]
3400+ data = b'x' * 8
3401+ nrefs = sys .getrefcount (data )
3402+ for write in writes :
3403+ self .assertRaises (curses .error , write , data )
3404+ self .assertEqual (sys .getrefcount (data ), nrefs )
3405+
33863406 @requires_curses_func ('panel' )
33873407 def test_close_then_panel_replace (self ):
33883408 # A detached window has no underlying curses window, so replace()
@@ -3479,10 +3499,10 @@ class SLKTests(NewtermTestBase):
34793499 # slk_init() must run before newterm()/initscr(), so each test sets up its
34803500 # own screen rather than reusing the one TestCurses builds in setUp().
34813501
3482- def make_slk_screen (self , fmt = 0 ):
3502+ def make_slk_screen (self , fmt = 0 , term = 'xterm' ):
34833503 s = self .make_pty ()
34843504 curses .slk_init (fmt )
3485- return curses .newterm ('xterm' , s , s )
3505+ return curses .newterm (term , s , s )
34863506
34873507 def test_init_reserves_a_line (self ):
34883508 # Every layout takes the bottom line for the labels; the index-line
@@ -3565,6 +3585,26 @@ def test_color(self):
35653585 curses .slk_attr_set (curses .A_BOLD , 0 )
35663586 curses .slk_color (0 )
35673587
3588+ def test_color_wide_pair (self ):
3589+ # Drive a terminal with enough color pairs to reach past a short,
3590+ # rather than relying on whatever $TERM happens to be.
3591+ try :
3592+ self .make_slk_screen (term = 'xterm-256color' )
3593+ except curses .error :
3594+ self .skipTest ('no xterm-256color terminfo entry' )
3595+ if not curses .has_colors ():
3596+ self .skipTest ('requires colors support' )
3597+ curses .start_color ()
3598+ if not (curses .has_extended_color_support ()
3599+ and curses .COLOR_PAIRS > SHORT_MAX + 1 ):
3600+ self .skipTest ('requires extended color support' )
3601+ # A pair that does not fit in a short is still a valid pair here.
3602+ curses .slk_color (SHORT_MAX + 1 )
3603+ # The low 16 bits of this are pair 5, but the pair itself is out of
3604+ # range, so it must raise instead of selecting pair 5.
3605+ self .assertRaises (curses .error , curses .slk_color ,
3606+ curses .COLOR_PAIRS * 2 + 5 )
3607+
35683608
35693609@unittest .skipUnless (hasattr (curses , 'newterm' ), 'requires curses.newterm()' )
35703610@unittest .skipIf (BROKEN_NEWTERM , 'ncurses < 6.5 mishandles repeated newterm()' )
0 commit comments