Skip to content

Commit 54d5320

Browse files
gh-160558: Fix textwrap hang when an indent is longer than width
When initial_indent or subsequent_indent was longer than width, _handle_long_word() could leave an empty chunk that never fit on the line, and _wrap_chunks() looped forever. Always accept zero-length chunks; they add nothing to the line.
1 parent dc28c3a commit 54d5320

3 files changed

Lines changed: 11 additions & 1 deletion

File tree

‎Lib/test/test_textwrap.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,14 @@ def test_subsequent_indent(self):
760760
initial_indent=" * ", subsequent_indent=" ")
761761
self.check(result, expect)
762762

763+
def test_indent_longer_than_width(self):
764+
# gh-160558: wrap() looped forever when an indent was longer than
765+
# width.
766+
self.check_wrap(" ", 3, [], initial_indent="----")
767+
self.check_wrap(" a", 3, ["----a"], initial_indent="----")
768+
self.check_wrap("aaaa", 3, ["aaa", "----a", "----"],
769+
subsequent_indent="----", drop_whitespace=False)
770+
763771

764772
# Despite the similar names, DedentTestCase is *not* the inverse
765773
# of IndentTestCase!

‎Lib/textwrap.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ def _wrap_chunks(self, chunks):
288288
l = len(chunks[-1])
289289

290290
# Can at least squeeze this chunk onto the current line.
291-
if cur_len + l <= width:
291+
if cur_len + l <= width or not l:
292292
cur_line.append(chunks.pop())
293293
cur_len += l
294294

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :func:`textwrap.wrap` and :func:`textwrap.fill` hanging in some cases
2+
when *initial_indent* or *subsequent_indent* is longer than *width*.

0 commit comments

Comments
 (0)