You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
_CustomTextWrap produces lines wider than width after the #399 fix (032dc0d) #478
The fix for #399 (032dc0d, on master, not in a release yet) stops the infinite loop, but it also makes some lines wider than the requested width. Before that commit, the same inputs wrapped correctly.
Minimal repro
>>>importtabulate, wcwidth>>>out=tabulate._CustomTextWrap(width=3).wrap("a 글글")
>>>out, [wcwidth.wcswidth(x) forxinout]
(['a 글', '글'], [4, 2]) # master @ 268615a: first line is 4 columns in a 3-column width
Before 032dc0d (and on PyPI 0.10.0): ['a ', '글', '글'], which fits.
This forces at least one character onto the line even when cur_line already has content, so a wide character that doesn't fit in the remaining space gets squeezed onto a non-empty line. Forcing progress is only needed when the line is empty. Taking the character in that case still breaks the loop, and otherwise the chunk can move to the next line as before:
ifi==1andnotcur_lineandstripped_chunk:
i=2
How I found it
I compared the pre-fix code and master on 6,910 random strings (a mix of ASCII, CJK, emoji, combining marks and ANSI codes, at widths 1/2/3/4/7). The pre-fix code hangs on 1,291 of them. Master fixes all of those hangs, but changes 201 outputs that previously terminated, and all 201 now have a line wider than width. With the guard above, every hang is fixed and none of the previously-terminating outputs change. The full test/ suite passes, including the #399 test.
Happy to open a PR with this change and a regression test if that's useful.
I'll take this one. Plan: change _handle_long_word so the i = max(i, 2) progress force only applies when cur_line is empty (as proposed in the issue), add a regression for the a 글글 / width=3 case, and keep the #399 no-infinite-loop behavior. Will open a PR shortly.
Activity
MbappeWU commentedon Oct 24, 2026
I'll take this one. Plan: change
_handle_long_wordso thei = max(i, 2)progress force only applies whencur_lineis empty (as proposed in the issue), add a regression for thea 글글/ width=3 case, and keep the #399 no-infinite-loop behavior. Will open a PR shortly.MbappeWU commentedon Oct 29, 2026
I'd like to take this — working on a fix that keeps post-#399 wrapping within
widthfor_CustomTextWrap.