Skip to content

gh-85796: Build the curses module on Windows against PDCurses - #154956

Open
serhiy-storchaka wants to merge 1 commit into
python:mainfrom
serhiy-storchaka:curses-windows-pdcurses
Open

gh-85796: Build the curses module on Windows against PDCurses#154956
serhiy-storchaka wants to merge 1 commit into
python:mainfrom
serhiy-storchaka:curses-windows-pdcurses

Conversation

@serhiy-storchaka

@serhiy-storchaka serhiy-storchaka commented Jul 30, 2026

Copy link
Copy Markdown
Member

Point PDCURSES_DIR at a PDCursesMod checkout and build.bat compiles pdcurses.dll, _curses.pyd and _curses_panel.pyd; without it nothing changes, and the installer does not ship them yet. The library is built wide, with a 64-bit chtype, and both modules link the one DLL, so they share a screen and a panel stack.

PDCurses has no terminfo database, so PC/pdcurses supplies <term.h> and the entry points the module references unconditionally: setupterm() reports success, the capability queries report "not found". What PDCurses does provide is declared in one block, in the same HAVE_CURSES_* terms that configure defines on Unix, since configure does not run here.

curses.pdcurses_version reports the library version, as ncurses_version does, and window.encoding follows the program locale, or is UTF-8 where PDCurses forces it. curses.termattrs() now returns its mask through an unsigned long long, as term_attrs() does, since a 64-bit chtype reaches past the 32 bits of an unsigned long on Windows.

test_curses covers the differences rather than skipping them: PDCurses has its own color model, keeps one screen per process, and reports some errors differently. $TERM no longer gates it there, since PDCurses does not consult it.

Tested on Windows 11, and against PDCursesMod 4.5.4 on Linux and FreeBSD in five configurations — wide and narrow, 32- and 64-bit chtype, forced UTF-8 — in three locales each. test_curses passes in all of them but the wide builds on FreeBSD in an 8-bit locale, where wchar_t holds the raw locale value rather than a code point and the round-trip through wcstombs() fails; the system ncurses fails the same tests there.

The curses and _curses_panel modules are built when PDCURSES_DIR points
to a PDCursesMod source tree, linking it as a shared library so both
modules share one screen and panel stack.  PDCurses has no terminfo
database, so PC/pdcurses supplies the entry points the module needs.

curses.pdcurses_version reports the library version, as ncurses_version
already does.  What PDCurses provides is declared in one block, in the
same HAVE_CURSES_* terms that configure defines on Unix.

window.encoding follows the program locale, or is UTF-8 where PDCurses
is built to force it.  A cell holds a character on a wide build and a
locale byte on a narrow one, whichever library provides it.

test_curses covers the differences: PDCurses has its own color model,
supports one screen per process, and reports some errors differently.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@read-the-docs-community

Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #33841086 | 📁 Comparing 3daf824 against main (0b083c4)

  🔍 Preview build  

2 files changed
± library/curses.html
± whatsnew/changelog.html

@serhiy-storchaka
serhiy-storchaka requested a review from zooba July 31, 2026 07:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant