Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
5f77a1be
Commit
5f77a1be
authored
Feb 14, 2015
by
Serhiy Storchaka
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #19105: pprint now more efficiently uses free space at the right.
parent
57897505
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
147 additions
and
39 deletions
+147
-39
Lib/pprint.py
Lib/pprint.py
+59
-28
Lib/test/test_pprint.py
Lib/test/test_pprint.py
+86
-11
Misc/NEWS
Misc/NEWS
+2
-0
No files found.
Lib/pprint.py
View file @
5f77a1be
...
...
@@ -161,7 +161,7 @@ class PrettyPrinter:
return
rep
=
self
.
_repr
(
object
,
context
,
level
-
1
)
typ
=
type
(
object
)
max_width
=
self
.
_width
-
1
-
indent
-
allowance
max_width
=
self
.
_width
-
indent
-
allowance
sepLines
=
len
(
rep
)
>
max_width
write
=
stream
.
write
...
...
@@ -174,24 +174,14 @@ class PrettyPrinter:
length
=
len
(
object
)
if
length
:
context
[
objid
]
=
1
indent
=
indent
+
self
.
_indent_per_level
if
issubclass
(
typ
,
_OrderedDict
):
items
=
list
(
object
.
items
())
else
:
items
=
sorted
(
object
.
items
(),
key
=
_safe_tuple
)
key
,
ent
=
items
[
0
]
rep
=
self
.
_repr
(
key
,
context
,
level
)
write
(
rep
)
write
(
': '
)
self
.
_format
(
ent
,
stream
,
indent
+
len
(
rep
)
+
2
,
allowance
+
1
,
context
,
level
)
if
length
>
1
:
for
key
,
ent
in
items
[
1
:]:
rep
=
self
.
_repr
(
key
,
context
,
level
)
write
(
',
\
n
%s%s: '
%
(
' '
*
indent
,
rep
))
self
.
_format
(
ent
,
stream
,
indent
+
len
(
rep
)
+
2
,
allowance
+
1
,
context
,
level
)
indent
=
indent
-
self
.
_indent_per_level
self
.
_format_dict_items
(
items
,
stream
,
indent
+
self
.
_indent_per_level
,
allowance
+
1
,
context
,
level
)
del
context
[
objid
]
write
(
'}'
)
return
...
...
@@ -207,7 +197,10 @@ class PrettyPrinter:
endchar
=
']'
elif
issubclass
(
typ
,
tuple
):
write
(
'('
)
endchar
=
')'
if
length
==
1
:
endchar
=
',)'
else
:
endchar
=
')'
else
:
if
not
length
:
write
(
rep
)
...
...
@@ -227,10 +220,9 @@ class PrettyPrinter:
context
[
objid
]
=
1
self
.
_format_items
(
object
,
stream
,
indent
+
self
.
_indent_per_level
,
allowance
+
1
,
context
,
level
)
allowance
+
len
(
endchar
),
context
,
level
)
del
context
[
objid
]
if
issubclass
(
typ
,
tuple
)
and
length
==
1
:
write
(
','
)
write
(
endchar
)
return
...
...
@@ -239,19 +231,27 @@ class PrettyPrinter:
lines
=
object
.
splitlines
(
True
)
if
level
==
1
:
indent
+=
1
max_width
-=
2
allowance
+=
1
max_width1
=
max_width
=
self
.
_width
-
indent
for
i
,
line
in
enumerate
(
lines
):
rep
=
repr
(
line
)
if
len
(
rep
)
<=
max_width
:
if
i
==
len
(
lines
)
-
1
:
max_width1
-=
allowance
if
len
(
rep
)
<=
max_width1
:
chunks
.
append
(
rep
)
else
:
# A list of alternating (non-space, space) strings
parts
=
re
.
split
(
r'(\
s+)
', line) + ['']
parts
=
re
.
findall
(
r'\
S*
\s*'
,
line
)
assert
parts
assert
not
parts
[
-
1
]
parts
.
pop
()
# drop empty last part
max_width2
=
max_width
current
=
''
for i in range(0, len(parts), 2):
part = parts[i] + parts[i+1]
for
j
,
part
in
enumerate
(
parts
):
candidate
=
current
+
part
if len(repr(candidate)) > max_width:
if
j
==
len
(
parts
)
-
1
and
i
==
len
(
lines
)
-
1
:
max_width2
-=
allowance
if
len
(
repr
(
candidate
))
>
max_width2
:
if
current
:
chunks
.
append
(
repr
(
current
))
current
=
part
...
...
@@ -273,12 +273,41 @@ class PrettyPrinter:
return
write
(
rep
)
def
_format_dict_items
(
self
,
items
,
stream
,
indent
,
allowance
,
context
,
level
):
write
=
stream
.
write
delimnl
=
',
\
n
'
+
' '
*
indent
last_index
=
len
(
items
)
-
1
for
i
,
(
key
,
ent
)
in
enumerate
(
items
):
last
=
i
==
last_index
rep
=
self
.
_repr
(
key
,
context
,
level
)
write
(
rep
)
write
(
': '
)
self
.
_format
(
ent
,
stream
,
indent
+
len
(
rep
)
+
2
,
allowance
if
last
else
1
,
context
,
level
)
if
not
last
:
write
(
delimnl
)
def
_format_items
(
self
,
items
,
stream
,
indent
,
allowance
,
context
,
level
):
write
=
stream
.
write
delimnl
=
',
\
n
'
+
' '
*
indent
delim
=
''
width = max_width = self._width - indent - allowance + 2
for ent in items:
width
=
max_width
=
self
.
_width
-
indent
+
1
it
=
iter
(
items
)
try
:
next_ent
=
next
(
it
)
except
StopIteration
:
return
last
=
False
while
not
last
:
ent
=
next_ent
try
:
next_ent
=
next
(
it
)
except
StopIteration
:
last
=
True
max_width
-=
allowance
width
-=
allowance
if
self
.
_compact
:
rep
=
self
.
_repr
(
ent
,
context
,
level
)
w
=
len
(
rep
)
+
2
...
...
@@ -294,7 +323,9 @@ class PrettyPrinter:
continue
write
(
delim
)
delim
=
delimnl
self._format(ent, stream, indent, allowance, context, level)
self
.
_format
(
ent
,
stream
,
indent
,
allowance
if
last
else
1
,
context
,
level
)
def
_repr
(
self
,
object
,
context
,
level
):
repr
,
readable
,
recursive
=
self
.
format
(
object
,
context
.
copy
(),
...
...
Lib/test/test_pprint.py
View file @
5f77a1be
...
...
@@ -191,11 +191,53 @@ class QueryTestCase(unittest.TestCase):
o2
=
dict
(
first
=
1
,
second
=
2
,
third
=
3
)
o
=
[
o1
,
o2
]
expected
=
"""
\
[ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
{'first': 1, 'second': 2, 'third': 3}]"""
self
.
assertEqual
(
pprint
.
pformat
(
o
,
indent
=
4
,
width
=
42
),
expected
)
expected
=
"""
\
[ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
{ 'first': 1,
'second': 2,
'third': 3}]"""
self
.
assertEqual
(
pprint
.
pformat
(
o
,
indent
=
4
,
width
=
42
),
expected
)
self
.
assertEqual
(
pprint
.
pformat
(
o
,
indent
=
4
,
width
=
41
),
expected
)
def
test_width
(
self
):
expected
=
"""
\
[[[[[[1, 2, 3],
'1 2']]]],
{1: [1, 2, 3],
2: [12, 34]},
'abc def ghi',
('ab cd ef',),
set2({1, 23}),
[[[[[1, 2, 3],
'1 2']]]]]"""
o
=
eval
(
expected
)
self
.
assertEqual
(
pprint
.
pformat
(
o
,
width
=
15
),
expected
)
self
.
assertEqual
(
pprint
.
pformat
(
o
,
width
=
16
),
expected
)
self
.
assertEqual
(
pprint
.
pformat
(
o
,
width
=
25
),
expected
)
self
.
assertEqual
(
pprint
.
pformat
(
o
,
width
=
14
),
"""
\
[[[[[[1,
2,
3],
'1 '
'2']]]],
{1: [1,
2,
3],
2: [12,
34]},
'abc def '
'ghi',
('ab cd '
'ef',),
set2({1,
23}),
[[[[[1,
2,
3],
'1 '
'2']]]]]"""
)
def
test_sorted_dict
(
self
):
# Starting in Python 2.5, pprint sorts dict displays by key regardless
...
...
@@ -535,13 +577,12 @@ frozenset2({0,
def
test_str_wrap
(
self
):
# pprint tries to wrap strings intelligently
fox
=
'the quick brown fox jumped over a lazy dog'
self
.
assertEqual
(
pprint
.
pformat
(
fox
,
width
=
20
),
"""
\
('the quick '
'brown fox '
'jumped over a '
'lazy dog')"""
)
self
.
assertEqual
(
pprint
.
pformat
(
fox
,
width
=
19
),
"""
\
('the quick brown '
'fox jumped over '
'a lazy dog')"""
)
self
.
assertEqual
(
pprint
.
pformat
({
'a'
:
1
,
'b'
:
fox
,
'c'
:
2
},
width
=
2
6
),
"""
\
width
=
2
5
),
"""
\
{'a': 1,
'b': 'the quick brown '
'fox jumped over '
...
...
@@ -553,12 +594,34 @@ frozenset2({0,
# - non-ASCII is allowed
# - an apostrophe doesn't disrupt the pprint
special
=
"Portons dix bons
\
"
whiskys
\
"
\
n
à l'avocat goujat
\
t
qui fumait au zoo"
self
.
assertEqual
(
pprint
.
pformat
(
special
,
width
=
21
),
"""
\
('Portons dix '
'bons "whiskys"
\
\
n'
self
.
assertEqual
(
pprint
.
pformat
(
special
,
width
=
68
),
repr
(
special
))
self
.
assertEqual
(
pprint
.
pformat
(
special
,
width
=
31
),
"""
\
('Portons dix bons "whiskys"
\
\
n'
"à l'avocat goujat
\
\
t qui "
'fumait au zoo')"""
)
self
.
assertEqual
(
pprint
.
pformat
(
special
,
width
=
20
),
"""
\
('Portons dix bons '
'"whiskys"
\
\
n'
"à l'avocat "
'goujat
\
\
t qui '
'fumait au zoo')"""
)
self
.
assertEqual
(
pprint
.
pformat
([[[[[
special
]]]]],
width
=
35
),
"""
\
[[[[['Portons dix bons "whiskys"
\
\
n'
"à l'avocat goujat
\
\
t qui "
'fumait au zoo']]]]]"""
)
self
.
assertEqual
(
pprint
.
pformat
([[[[[
special
]]]]],
width
=
25
),
"""
\
[[[[['Portons dix bons '
'"whiskys"
\
\
n'
"à l'avocat "
'goujat
\
\
t qui '
'fumait au zoo']]]]]"""
)
self
.
assertEqual
(
pprint
.
pformat
([[[[[
special
]]]]],
width
=
23
),
"""
\
[[[[['Portons dix '
'bons "whiskys"
\
\
n'
"à l'avocat "
'goujat
\
\
t qui '
'fumait au '
'zoo']]]]]"""
)
# An unwrappable string is formatted as its repr
unwrappable
=
"x"
*
100
self
.
assertEqual
(
pprint
.
pformat
(
unwrappable
,
width
=
80
),
repr
(
unwrappable
))
...
...
@@ -581,7 +644,19 @@ frozenset2({0,
14, 15],
[], [0], [0, 1], [0, 1, 2], [0, 1, 2, 3],
[0, 1, 2, 3, 4]]"""
self
.
assertEqual
(
pprint
.
pformat
(
o
,
width
=
48
,
compact
=
True
),
expected
)
self
.
assertEqual
(
pprint
.
pformat
(
o
,
width
=
47
,
compact
=
True
),
expected
)
def
test_compact_width
(
self
):
levels
=
20
number
=
10
o
=
[
0
]
*
number
for
i
in
range
(
levels
-
1
):
o
=
[
o
]
for
w
in
range
(
levels
*
2
+
1
,
levels
+
3
*
number
-
1
):
lines
=
pprint
.
pformat
(
o
,
width
=
w
,
compact
=
True
).
splitlines
()
maxwidth
=
max
(
map
(
len
,
lines
))
self
.
assertLessEqual
(
maxwidth
,
w
)
self
.
assertGreater
(
maxwidth
,
w
-
3
)
class
DottedPrettyPrinter
(
pprint
.
PrettyPrinter
):
...
...
Misc/NEWS
View file @
5f77a1be
...
...
@@ -13,6 +13,8 @@ Core and Builtins
Library
-------
- Issue #19105: pprint now more efficiently uses free space at the right.
- Issue #14910: Add allow_abbrev parameter to argparse.ArgumentParser. Patch by
Jonathan Paugh, Steven Bethard, paul j3 and Daniel Eriksson.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment