Issue #19104: pprint now produces evaluable output for wrapped strings.
This commit is contained in:
commit
3c6fe4da88
|
@ -235,35 +235,41 @@ class PrettyPrinter:
|
||||||
return
|
return
|
||||||
|
|
||||||
if issubclass(typ, str) and len(object) > 0 and r is str.__repr__:
|
if issubclass(typ, str) and len(object) > 0 and r is str.__repr__:
|
||||||
def _str_parts(s):
|
chunks = []
|
||||||
"""
|
lines = object.splitlines(True)
|
||||||
Return a list of string literals comprising the repr()
|
if level == 1:
|
||||||
of the given string using literal concatenation.
|
indent += 1
|
||||||
"""
|
max_width -= 2
|
||||||
lines = s.splitlines(True)
|
for i, line in enumerate(lines):
|
||||||
for i, line in enumerate(lines):
|
rep = repr(line)
|
||||||
rep = repr(line)
|
if len(rep) <= max_width:
|
||||||
if len(rep) <= max_width:
|
chunks.append(rep)
|
||||||
yield rep
|
else:
|
||||||
else:
|
# A list of alternating (non-space, space) strings
|
||||||
# A list of alternating (non-space, space) strings
|
parts = re.split(r'(\s+)', line) + ['']
|
||||||
parts = re.split(r'(\s+)', line) + ['']
|
current = ''
|
||||||
current = ''
|
for i in range(0, len(parts), 2):
|
||||||
for i in range(0, len(parts), 2):
|
part = parts[i] + parts[i+1]
|
||||||
part = parts[i] + parts[i+1]
|
candidate = current + part
|
||||||
candidate = current + part
|
if len(repr(candidate)) > max_width:
|
||||||
if len(repr(candidate)) > max_width:
|
if current:
|
||||||
if current:
|
chunks.append(repr(current))
|
||||||
yield repr(current)
|
current = part
|
||||||
current = part
|
else:
|
||||||
else:
|
current = candidate
|
||||||
current = candidate
|
if current:
|
||||||
if current:
|
chunks.append(repr(current))
|
||||||
yield repr(current)
|
if len(chunks) == 1:
|
||||||
for i, rep in enumerate(_str_parts(object)):
|
write(rep)
|
||||||
|
return
|
||||||
|
if level == 1:
|
||||||
|
write('(')
|
||||||
|
for i, rep in enumerate(chunks):
|
||||||
if i > 0:
|
if i > 0:
|
||||||
write('\n' + ' '*indent)
|
write('\n' + ' '*indent)
|
||||||
write(rep)
|
write(rep)
|
||||||
|
if level == 1:
|
||||||
|
write(')')
|
||||||
return
|
return
|
||||||
write(rep)
|
write(rep)
|
||||||
|
|
||||||
|
|
|
@ -536,9 +536,10 @@ frozenset2({0,
|
||||||
# pprint tries to wrap strings intelligently
|
# pprint tries to wrap strings intelligently
|
||||||
fox = 'the quick brown fox jumped over a lazy dog'
|
fox = 'the quick brown fox jumped over a lazy dog'
|
||||||
self.assertEqual(pprint.pformat(fox, width=20), """\
|
self.assertEqual(pprint.pformat(fox, width=20), """\
|
||||||
'the quick brown '
|
('the quick '
|
||||||
'fox jumped over '
|
'brown fox '
|
||||||
'a lazy dog'""")
|
'jumped over a '
|
||||||
|
'lazy dog')""")
|
||||||
self.assertEqual(pprint.pformat({'a': 1, 'b': fox, 'c': 2},
|
self.assertEqual(pprint.pformat({'a': 1, 'b': fox, 'c': 2},
|
||||||
width=26), """\
|
width=26), """\
|
||||||
{'a': 1,
|
{'a': 1,
|
||||||
|
@ -552,12 +553,12 @@ frozenset2({0,
|
||||||
# - non-ASCII is allowed
|
# - non-ASCII is allowed
|
||||||
# - an apostrophe doesn't disrupt the pprint
|
# - an apostrophe doesn't disrupt the pprint
|
||||||
special = "Portons dix bons \"whiskys\"\nà l'avocat goujat\t qui fumait au zoo"
|
special = "Portons dix bons \"whiskys\"\nà l'avocat goujat\t qui fumait au zoo"
|
||||||
self.assertEqual(pprint.pformat(special, width=20), """\
|
self.assertEqual(pprint.pformat(special, width=21), """\
|
||||||
'Portons dix bons '
|
('Portons dix '
|
||||||
'"whiskys"\\n'
|
'bons "whiskys"\\n'
|
||||||
"à l'avocat "
|
"à l'avocat "
|
||||||
'goujat\\t qui '
|
'goujat\\t qui '
|
||||||
'fumait au zoo'""")
|
'fumait au zoo')""")
|
||||||
# An unwrappable string is formatted as its repr
|
# An unwrappable string is formatted as its repr
|
||||||
unwrappable = "x" * 100
|
unwrappable = "x" * 100
|
||||||
self.assertEqual(pprint.pformat(unwrappable, width=80), repr(unwrappable))
|
self.assertEqual(pprint.pformat(unwrappable, width=80), repr(unwrappable))
|
||||||
|
@ -566,7 +567,9 @@ frozenset2({0,
|
||||||
special *= 10
|
special *= 10
|
||||||
for width in range(3, 40):
|
for width in range(3, 40):
|
||||||
formatted = pprint.pformat(special, width=width)
|
formatted = pprint.pformat(special, width=width)
|
||||||
self.assertEqual(eval("(" + formatted + ")"), special)
|
self.assertEqual(eval(formatted), special)
|
||||||
|
formatted = pprint.pformat([special] * 2, width=width)
|
||||||
|
self.assertEqual(eval(formatted), [special] * 2)
|
||||||
|
|
||||||
def test_compact(self):
|
def test_compact(self):
|
||||||
o = ([list(range(i * i)) for i in range(5)] +
|
o = ([list(range(i * i)) for i in range(5)] +
|
||||||
|
|
|
@ -196,6 +196,8 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #19104: pprint now produces evaluable output for wrapped strings.
|
||||||
|
|
||||||
- Issue #23071: Added missing names to codecs.__all__. Patch by Martin Panter.
|
- Issue #23071: Added missing names to codecs.__all__. Patch by Martin Panter.
|
||||||
|
|
||||||
- Issue #22783: Pickling now uses the NEWOBJ opcode instead of the NEWOBJ_EX
|
- Issue #22783: Pickling now uses the NEWOBJ opcode instead of the NEWOBJ_EX
|
||||||
|
|
Loading…
Reference in New Issue