mirror of https://github.com/python/cpython
Merge #15510: clarify textwrap's handling of whitespace, and add confirming tests.
Patch by Chris Jerdonek.
This commit is contained in:
commit
0fbbce99c3
|
@ -25,6 +25,9 @@ otherwise, you should use an instance of :class:`TextWrapper` for efficiency.
|
||||||
Optional keyword arguments correspond to the instance attributes of
|
Optional keyword arguments correspond to the instance attributes of
|
||||||
:class:`TextWrapper`, documented below. *width* defaults to ``70``.
|
: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)
|
.. function:: fill(text, width=70, **kwargs)
|
||||||
|
|
||||||
|
@ -167,15 +170,18 @@ in a block of text.
|
||||||
|
|
||||||
.. attribute:: drop_whitespace
|
.. attribute:: drop_whitespace
|
||||||
|
|
||||||
(default: ``True``) If true, whitespace that, after wrapping, happens to
|
(default: ``True``) If true, whitespace at the beginning and ending of
|
||||||
end up at the beginning or end of a line is dropped (leading whitespace in
|
every line (after wrapping but before indenting) is dropped.
|
||||||
the first line is always preserved, though).
|
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
|
.. attribute:: initial_indent
|
||||||
|
|
||||||
(default: ``''``) String that will be prepended to the first line of
|
(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
|
.. attribute:: subsequent_indent
|
||||||
|
@ -236,8 +242,9 @@ in a block of text.
|
||||||
|
|
||||||
Wraps the single paragraph in *text* (a string) so every line is at most
|
Wraps the single paragraph in *text* (a string) so every line is at most
|
||||||
:attr:`width` characters long. All wrapping options are taken from
|
:attr:`width` characters long. All wrapping options are taken from
|
||||||
instance attributes of the :class:`TextWrapper` instance. Returns a list
|
instance attributes of the :class:`TextWrapper` instance. Returns a list
|
||||||
of output lines, without final newlines.
|
of output lines, without final newlines. If the wrapped output has no
|
||||||
|
content, the returned list is empty.
|
||||||
|
|
||||||
|
|
||||||
.. method:: fill(text)
|
.. method:: fill(text)
|
||||||
|
|
|
@ -22,7 +22,7 @@ class BaseTestCase(unittest.TestCase):
|
||||||
result = []
|
result = []
|
||||||
for i in range(len(textin)):
|
for i in range(len(textin)):
|
||||||
result.append(" %d: %r" % (i, textin[i]))
|
result.append(" %d: %r" % (i, textin[i]))
|
||||||
result = '\n'.join(result)
|
result = "\n".join(result) if result else " no lines"
|
||||||
elif isinstance(textin, str):
|
elif isinstance(textin, str):
|
||||||
result = " %s\n" % repr(textin)
|
result = " %s\n" % repr(textin)
|
||||||
return result
|
return result
|
||||||
|
@ -66,6 +66,15 @@ class WrapTestCase(BaseTestCase):
|
||||||
"I'm glad to hear it!"])
|
"I'm glad to hear it!"])
|
||||||
self.check_wrap(text, 80, [text])
|
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):
|
def test_whitespace(self):
|
||||||
# Whitespace munging and end-of-sentence detection
|
# Whitespace munging and end-of-sentence detection
|
||||||
|
@ -331,7 +340,32 @@ What a mess!
|
||||||
["blah", " ", "(ding", " ", "dong),",
|
["blah", " ", "(ding", " ", "dong),",
|
||||||
" ", "wubba"])
|
" ", "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
|
# SF bug #622849 reported inconsistent handling of leading
|
||||||
# whitespace; let's test that a bit, shall we?
|
# whitespace; let's test that a bit, shall we?
|
||||||
text = " This is a sentence with leading whitespace."
|
text = " This is a sentence with leading whitespace."
|
||||||
|
@ -340,13 +374,27 @@ What a mess!
|
||||||
self.check_wrap(text, 30,
|
self.check_wrap(text, 30,
|
||||||
[" This is a sentence with", "leading whitespace."])
|
[" This is a sentence with", "leading whitespace."])
|
||||||
|
|
||||||
def test_no_drop_whitespace(self):
|
def test_drop_whitespace_whitespace_line(self):
|
||||||
# SF patch #1581073
|
# Check that drop_whitespace skips the whole line if a non-leading
|
||||||
text = " This is a sentence with much whitespace."
|
# line consists only of whitespace.
|
||||||
self.check_wrap(text, 10,
|
text = "abcd efgh"
|
||||||
[" This is a", " ", "sentence ",
|
# Include the result for drop_whitespace=False for comparison.
|
||||||
"with ", "much white", "space."],
|
self.check_wrap(text, 6, ["abcd", " ", "efgh"],
|
||||||
drop_whitespace=False)
|
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):
|
def test_split(self):
|
||||||
# Ensure that the standard _split() method works as advertised
|
# Ensure that the standard _split() method works as advertised
|
||||||
|
|
Loading…
Reference in New Issue