screen.use() makes its screen current for the callback, by calling use_screen(). A screen returned by new_prescr() has no terminal, so operations that need one crash inside curses.
This is the crash of gh-154749 through a different door: use() does not go through set_term(), so GH-154750 does not affect it.
Rejecting the screen here is not an option: use() is the only thing left to do with a new_prescr() screen -- its other members are close() and stdscr, which is None -- so pre.use(lambda s: curses.use_env(False)) has to keep working.
Eleven window methods crash in such a callback -- refresh(), noutrefresh(), getch(), getkey(), get_wch(), getstr(), get_wstr(), echochar(), keypad(), idlok(), idcok() -- and newwin() and newpad() return a window whose delwin() fails.
While a screen with no terminal is current, the C global stdscr is NULL, whichever way it became current. Checking that where a terminal is required covers use() and set_term() alike.
new_prescr() and screen.use() are new in 3.16 (gh-90092), and NetBSD curses has neither, so this is reachable only on ncurses in 3.16.
Activity
gh-154786: Fix crashes on a screen without a terminal (GH-154787)
pythongh-154786: Fix crashes on a screen without a terminal (pythonGH…