From 54d53203f018291c28a32a60acd478e44a3e6343 Mon Sep 17 00:00:00 2001 From: devdavidejesus Date: Fri, 23 Oct 2026 21:53:48 -0300 Subject: [PATCH] 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. --- Lib/test/test_textwrap.py | 8 ++++++++ Lib/textwrap.py | 2 +- .../2026-10-24-00-53-48.gh-issue-160558.XyEOEz.rst | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-10-24-00-53-48.gh-issue-160558.XyEOEz.rst diff --git a/Lib/test/test_textwrap.py b/Lib/test/test_textwrap.py index aca1f427656bb5..99fce6f241e007 100644 --- a/Lib/test/test_textwrap.py +++ b/Lib/test/test_textwrap.py @@ -760,6 +760,14 @@ def test_subsequent_indent(self): initial_indent=" * ", subsequent_indent=" ") self.check(result, expect) + def test_indent_longer_than_width(self): + # gh-160558: wrap() looped forever when an indent was longer than + # width. + self.check_wrap(" ", 3, [], initial_indent="----") + self.check_wrap(" a", 3, ["----a"], initial_indent="----") + self.check_wrap("aaaa", 3, ["aaa", "----a", "----"], + subsequent_indent="----", drop_whitespace=False) + # Despite the similar names, DedentTestCase is *not* the inverse # of IndentTestCase! diff --git a/Lib/textwrap.py b/Lib/textwrap.py index 2f213e34c2c329..ca87df5f46cb56 100644 --- a/Lib/textwrap.py +++ b/Lib/textwrap.py @@ -288,7 +288,7 @@ def _wrap_chunks(self, chunks): l = len(chunks[-1]) # Can at least squeeze this chunk onto the current line. - if cur_len + l <= width: + if cur_len + l <= width or not l: cur_line.append(chunks.pop()) cur_len += l diff --git a/Misc/NEWS.d/next/Library/2026-10-24-00-53-48.gh-issue-160558.XyEOEz.rst b/Misc/NEWS.d/next/Library/2026-10-24-00-53-48.gh-issue-160558.XyEOEz.rst new file mode 100644 index 00000000000000..0c0e2c6632df7a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-10-24-00-53-48.gh-issue-160558.XyEOEz.rst @@ -0,0 +1,2 @@ +Fix :func:`textwrap.wrap` and :func:`textwrap.fill` hanging in some cases +when *initial_indent* or *subsequent_indent* is longer than *width*.