Several functions in Modules/_cursesmodule.c are called unconditionally or gated only by the ncurses-specific NCURSES_EXT_FUNCS macro. Both break building or using the module against curses implementations other than ncursesw — narrow (non-wide) ncurses, and third-party curses such as NetBSD curses — even when the library provides the function.
Unconditionally-called functions that aren't universally present (no HAVE_CURSES_* guard, so a library lacking them fails to link):
scr_dump/scr_restore/scr_init/scr_set — the whole family is absent from NetBSD curses.
key_defined — absent from NetBSD curses (which has define_key/keyok).
term_attrs — the X/Open wide attribute query, present only in libncursesw, so missing from a narrow -lncurses build.
Functions gated by NCURSES_EXT_FUNCS that NetBSD implements without defining that macro, so the module silently drops them:
define_key, keyok, set_escdelay, set_tabsize, get_escdelay, get_tabsize.
Proposed change: detect each with a configure capability probe and gate on HAVE_CURSES_*.
PY_CHECK_CURSES_FUNC probes for scr_dump (one probe gates the inseparable family), key_defined, term_attrs, define_key, keyok, set_escdelay, set_tabsize.
get_escdelay/get_tabsize read the ESCDELAY/TABSIZE variables, which some libraries declare as extern int rather than macros, so a function probe doesn't fit. Add a small PY_CHECK_CURSES_VAR macro (tests that int x = ESCDELAY; compiles) and gate the getters on HAVE_CURSES_ESCDELAY/HAVE_CURSES_TABSIZE.
None of these are in X/Open Curses; they are ncurses extensions (NetBSD provides compatible ones), so capability-gating is the correct treatment, and a probe is more portable than conditioning on NCURSES_VERSION.
No behaviour change on standard ncursesw (all macros defined). test_curses passes and is refleak-clean on ncursesw, narrow ncurses, and NetBSD curses, under UTF-8 and 8-bit locales. test_env_queries calls curses.term_attrs() unconditionally and needs a hasattr guard for the narrow case.
Linked PRs
Several functions in
Modules/_cursesmodule.care called unconditionally or gated only by the ncurses-specificNCURSES_EXT_FUNCSmacro. Both break building or using the module against curses implementations other than ncursesw — narrow (non-wide) ncurses, and third-party curses such as NetBSD curses — even when the library provides the function.Unconditionally-called functions that aren't universally present (no
HAVE_CURSES_*guard, so a library lacking them fails to link):scr_dump/scr_restore/scr_init/scr_set— the whole family is absent from NetBSD curses.key_defined— absent from NetBSD curses (which hasdefine_key/keyok).term_attrs— the X/Open wide attribute query, present only inlibncursesw, so missing from a narrow-lncursesbuild.Functions gated by
NCURSES_EXT_FUNCSthat NetBSD implements without defining that macro, so the module silently drops them:define_key,keyok,set_escdelay,set_tabsize,get_escdelay,get_tabsize.Proposed change: detect each with a configure capability probe and gate on
HAVE_CURSES_*.PY_CHECK_CURSES_FUNCprobes forscr_dump(one probe gates the inseparable family),key_defined,term_attrs,define_key,keyok,set_escdelay,set_tabsize.get_escdelay/get_tabsizeread theESCDELAY/TABSIZEvariables, which some libraries declare asextern intrather than macros, so a function probe doesn't fit. Add a smallPY_CHECK_CURSES_VARmacro (tests thatint x = ESCDELAY;compiles) and gate the getters onHAVE_CURSES_ESCDELAY/HAVE_CURSES_TABSIZE.None of these are in X/Open Curses; they are ncurses extensions (NetBSD provides compatible ones), so capability-gating is the correct treatment, and a probe is more portable than conditioning on
NCURSES_VERSION.No behaviour change on standard ncursesw (all macros defined).
test_cursespasses and is refleak-clean on ncursesw, narrow ncurses, and NetBSD curses, under UTF-8 and 8-bit locales.test_env_queriescallscurses.term_attrs()unconditionally and needs ahasattrguard for the narrow case.Linked PRs