diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index f7584a39b182d99..602a4dd1f3d8316 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -467,6 +467,10 @@ def test_wide_characters(self): if self._encodable(vline + hline): stdscr.border(vline, vline, hline, hline) stdscr.box(vline, hline) + # Zero still requests the default character in the wide path. + stdscr.border('|', '|', '-', '-', 0, 0, 0, 0) + stdscr.box('|', 0) + stdscr.box(0, '-') # border() and box() cannot mix integer and wide-string characters. self.assertRaises(TypeError, stdscr.box, vline, ord('-')) diff --git a/Misc/NEWS.d/next/Library/2026-08-10-17-01-37.gh-issue-155499.Q7mR2x.rst b/Misc/NEWS.d/next/Library/2026-08-10-17-01-37.gh-issue-155499.Q7mR2x.rst new file mode 100644 index 000000000000000..ef2569ad89cb1eb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-08-10-17-01-37.gh-issue-155499.Q7mR2x.rst @@ -0,0 +1,2 @@ +Fix :meth:`~curses.window.border` and :meth:`~curses.window.box` to accept the +documented ``0`` default character alongside strings. diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 07e924b0fc564bc..1f61f6f186007c0 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -2705,7 +2705,7 @@ _curses_window_border_impl(PyCursesWindowObject *self, PyObject *ls, } if (use_wide) { for (i = 0; i < 8; i++) { - if (objs[i] == NULL) { + if (objs[i] == NULL || (types[i] == 1 && ch[i] == 0)) { wch_p[i] = NULL; /* use the default character */ } else if (types[i] == 2) { @@ -2775,13 +2775,15 @@ _curses_window_box_impl(PyCursesWindowObject *self, int group_right_1, } } if (t1 == 2 || t2 == 2) { - if (t1 != 2 || t2 != 2) { + if ((t1 != 2 && ch1 != 0) || (t2 != 2 && ch2 != 0)) { PyErr_SetString(PyExc_TypeError, "box() cannot mix integer or bytes characters " "with wide string characters"); return NULL; } - int rtn = wborder_set(self->win, &wch1, &wch1, &wch2, &wch2, + const cchar_t *wch1_p = t1 == 2 ? &wch1 : NULL; + const cchar_t *wch2_p = t2 == 2 ? &wch2 : NULL; + int rtn = wborder_set(self->win, wch1_p, wch1_p, wch2_p, wch2_p, NULL, NULL, NULL, NULL); return curses_window_check_err(self, rtn, "wborder_set", "box"); }