gh-155499: Fix curses border() and box() rejecting 0 mixed with str/bytes - #155521
gh-155499: Fix curses border() and box() rejecting 0 mixed with str/bytes#155521Lohitha0-0 wants to merge 2 commits into
Conversation
… str/bytes border() and box() raise TypeError when a wide-character (ncursesw) build receives a one-character str/bytes argument alongside an int 0, even though 0 is documented as the sentinel meaning "use the default character" (pythonGH-151758 introduced the stricter type-mixing check but didn't account for this documented case). border() now treats an int argument as acceptable when it is 0. box() is restructured to select each side's cchar_t pointer independently, since it previously required both verch and horch to share the same type. Adds Lib/test/test_curses.py coverage for both functions.
| else if (types[i] == 2) { | ||
| wch_p[i] = &wch[i]; | ||
| } | ||
| else if (types[i] == 1 && ch[i] == 0) { |
There was a problem hiding this comment.
You can merge that check with the check at L2708
There was a problem hiding this comment.
Done, merged both branches into a single objs[i] == NULL || (types[i] == 1 && ch[i] == 0) condition.
| return NULL; | ||
| const cchar_t *wch1_p, *wch2_p; | ||
|
|
||
| if (t1 == 2) { |
There was a problem hiding this comment.
I feel that we could have a claener if-else if-else and keep an if (cond) { raise } and later wch1p = c2 ? NULL : &wch1; and same for wch2p (namely we can simplify the checks and diff). Unfortunately it's too late now for me to think in terms of boolean arithmetic so I'll let you figure it out.
There was a problem hiding this comment.
reworked it to a single upfront check (t1_ok/t2_ok) plus a ternary for the pointer assignment, no more goto/label.
- border(): merge the NULL-default and int-0-default branches into a single condition, as suggested by @picnixz. - box(): replace the goto-based per-side validation with a single upfront check plus ternary pointer assignment, avoiding the extra label.
|
Thank you for the patch. Only the integer The sentinel is also not the only regression from GH-151758: a string character could be mixed with byte and integer characters, including the #155871 solves both: One note for future patches: |
Fixes #155499
border()andbox()were raisingTypeErrorwhen you mix a one-characterstr/bytesarg with a plain0, even though0is documented as meaning "use the default character" for that spot. This broke in GH-151758, which added a check to stop mixing wide-char types with int/bytes types, but didn't account for0being a valid sentinel value regardless of type.For
border(), the fix is small — just treat an int argument as fine when its value is0, in addition to the existing wide-char case.box()needed a bit more work. It was checkingverchandhorchtogether (t1 != 2 || t2 != 2), so it would already reject the call before it even got to check whether the individual value was0. I restructured it to resolve each side'scchar_tpointer on its own, so0is accepted per-side instead of requiring both sides to match types.Added a test (
test_border_box_zero_sentinel) covering both functions with0mixed in, and also checking that a real type mismatch (like1mixed with astr) still correctly raisesTypeError.border()andbox()no longer accept0with astr#155499