#15510: clarify textwrap's handling of whitespace, and add confirming tests.

Patch by Chris Jerdonek.
This commit is contained in:
R David Murray 2012-09-08 13:13:25 -04:00
parent b522828d2a
commit 1585b70813
2 changed files with 69 additions and 14 deletions

View File

@ -25,6 +25,9 @@ otherwise, you should use an instance of :class:`TextWrapper` for efficiency.
Optional keyword arguments correspond to the instance attributes of
:class:`TextWrapper`, documented below. *width* defaults to ``70``.
See the :meth:`TextWrapper.wrap` method for additional details on how
:func:`wrap` behaves.
.. function:: fill(text, width=70, **kwargs)
@ -131,15 +134,18 @@ indentation from strings that have unwanted whitespace to the left of the text.
.. attribute:: drop_whitespace
(default: ``True``) If true, whitespace that, after wrapping, happens to
end up at the beginning or end of a line is dropped (leading whitespace in
the first line is always preserved, though).
(default: ``True``) If true, whitespace at the beginning and ending of
every line (after wrapping but before indenting) is dropped.
Whitespace at the beginning of the paragraph, however, is not dropped
if non-whitespace follows it. If whitespace being dropped takes up an
entire line, the whole line is dropped.
.. attribute:: initial_indent
(default: ``''``) String that will be prepended to the first line of
wrapped output. Counts towards the length of the first line.
wrapped output. Counts towards the length of the first line. The empty
string is not indented.
.. attribute:: subsequent_indent
@ -200,8 +206,9 @@ indentation from strings that have unwanted whitespace to the left of the text.
Wraps the single paragraph in *text* (a string) so every line is at most
:attr:`width` characters long. All wrapping options are taken from
instance attributes of the :class:`TextWrapper` instance. Returns a list
of output lines, without final newlines.
instance attributes of the :class:`TextWrapper` instance. Returns a list
of output lines, without final newlines. If the wrapped output has no
content, the returned list is empty.
.. method:: fill(text)

View File

@ -22,7 +22,7 @@ class BaseTestCase(unittest.TestCase):
result = []
for i in range(len(textin)):
result.append(" %d: %r" % (i, textin[i]))
result = '\n'.join(result)
result = "\n".join(result) if result else " no lines"
elif isinstance(textin, str):
result = " %s\n" % repr(textin)
return result
@ -66,6 +66,15 @@ class WrapTestCase(BaseTestCase):
"I'm glad to hear it!"])
self.check_wrap(text, 80, [text])
def test_empty_string(self):
# Check that wrapping the empty string returns an empty list.
self.check_wrap("", 6, [])
self.check_wrap("", 6, [], drop_whitespace=False)
def test_empty_string_with_initial_indent(self):
# Check that the empty string is not indented.
self.check_wrap("", 6, [], initial_indent="++")
self.check_wrap("", 6, [], initial_indent="++", drop_whitespace=False)
def test_whitespace(self):
# Whitespace munging and end-of-sentence detection
@ -323,7 +332,32 @@ What a mess!
["blah", " ", "(ding", " ", "dong),",
" ", "wubba"])
def test_initial_whitespace(self):
def test_drop_whitespace_false(self):
# Check that drop_whitespace=False preserves whitespace.
# SF patch #1581073
text = " This is a sentence with much whitespace."
self.check_wrap(text, 10,
[" This is a", " ", "sentence ",
"with ", "much white", "space."],
drop_whitespace=False)
def test_drop_whitespace_false_whitespace_only(self):
# Check that drop_whitespace=False preserves a whitespace-only string.
self.check_wrap(" ", 6, [" "], drop_whitespace=False)
def test_drop_whitespace_false_whitespace_only_with_indent(self):
# Check that a whitespace-only string gets indented (when
# drop_whitespace is False).
self.check_wrap(" ", 6, [" "], drop_whitespace=False,
initial_indent=" ")
def test_drop_whitespace_whitespace_only(self):
# Check drop_whitespace on a whitespace-only string.
self.check_wrap(" ", 6, [])
def test_drop_whitespace_leading_whitespace(self):
# Check that drop_whitespace does not drop leading whitespace (if
# followed by non-whitespace).
# SF bug #622849 reported inconsistent handling of leading
# whitespace; let's test that a bit, shall we?
text = " This is a sentence with leading whitespace."
@ -332,13 +366,27 @@ What a mess!
self.check_wrap(text, 30,
[" This is a sentence with", "leading whitespace."])
def test_no_drop_whitespace(self):
# SF patch #1581073
text = " This is a sentence with much whitespace."
self.check_wrap(text, 10,
[" This is a", " ", "sentence ",
"with ", "much white", "space."],
def test_drop_whitespace_whitespace_line(self):
# Check that drop_whitespace skips the whole line if a non-leading
# line consists only of whitespace.
text = "abcd efgh"
# Include the result for drop_whitespace=False for comparison.
self.check_wrap(text, 6, ["abcd", " ", "efgh"],
drop_whitespace=False)
self.check_wrap(text, 6, ["abcd", "efgh"])
def test_drop_whitespace_whitespace_only_with_indent(self):
# Check that initial_indent is not applied to a whitespace-only
# string. This checks a special case of the fact that dropping
# whitespace occurs before indenting.
self.check_wrap(" ", 6, [], initial_indent="++")
def test_drop_whitespace_whitespace_indent(self):
# Check that drop_whitespace does not drop whitespace indents.
# This checks a special case of the fact that dropping whitespace
# occurs before indenting.
self.check_wrap("abcd efgh", 6, [" abcd", " efgh"],
initial_indent=" ", subsequent_indent=" ")
def test_split(self):
# Ensure that the standard _split() method works as advertised