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
96831c7f
Commit
96831c7f
authored
Mar 22, 2019
by
Rémi Lapeyre
Committed by
Raymond Hettinger
Mar 22, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-30670: Add pp function to the pprint module (GH-11769)
parent
c5c6cdad
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
84 additions
and
35 deletions
+84
-35
Doc/library/pprint.rst
Doc/library/pprint.rst
+32
-8
Doc/tools/susp-ignored.csv
Doc/tools/susp-ignored.csv
+9
-9
Lib/pprint.py
Lib/pprint.py
+32
-18
Lib/test/test_pprint.py
Lib/test/test_pprint.py
+7
-0
Misc/NEWS.d/next/Library/2019-02-06-12-07-46.bpo-30670.yffB3F.rst
...S.d/next/Library/2019-02-06-12-07-46.bpo-30670.yffB3F.rst
+4
-0
No files found.
Doc/library/pprint.rst
View file @
96831c7f
...
@@ -33,7 +33,7 @@ The :mod:`pprint` module defines one class:
...
@@ -33,7 +33,7 @@ The :mod:`pprint` module defines one class:
.. index:: single: ...; placeholder
.. index:: single: ...; placeholder
.. class:: PrettyPrinter(indent=1, width=80, depth=None, stream=None, *, \
.. class:: PrettyPrinter(indent=1, width=80, depth=None, stream=None, *, \
compact=False)
compact=False
, sort_dicts=True
)
Construct a :class:`PrettyPrinter` instance. This constructor understands
Construct a :class:`PrettyPrinter` instance. This constructor understands
several keyword parameters. An output stream may be set using the *stream*
several keyword parameters. An output stream may be set using the *stream*
...
@@ -50,11 +50,17 @@ The :mod:`pprint` module defines one class:
...
@@ -50,11 +50,17 @@ The :mod:`pprint` module defines one class:
structure cannot be formatted within the constrained width, a best effort will
structure cannot be formatted within the constrained width, a best effort will
be made. If *compact* is false (the default) each item of a long sequence
be made. If *compact* is false (the default) each item of a long sequence
will be formatted on a separate line. If *compact* is true, as many items
will be formatted on a separate line. If *compact* is true, as many items
as will fit within the *width* will be formatted on each output line.
as will fit within the *width* will be formatted on each output line. If
*sort_dicts* is true (the default), dictionaries will be formatted with their
keys sorted, otherwise they will display in insertion order.
.. versionchanged:: 3.4
.. versionchanged:: 3.4
Added the *compact* parameter.
Added the *compact* parameter.
.. versionchanged:: 3.8
Added the *sort_dicts* parameter.
>>> import pprint
>>> import pprint
>>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
>>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
>>> stuff.insert(0, stuff[:])
>>> stuff.insert(0, stuff[:])
...
@@ -81,29 +87,47 @@ The :mod:`pprint` module defines one class:
...
@@ -81,29 +87,47 @@ The :mod:`pprint` module defines one class:
The :mod:`pprint` module also provides several shortcut functions:
The :mod:`pprint` module also provides several shortcut functions:
.. function:: pformat(object, indent=1, width=80, depth=None, *, compact=False)
.. function:: pformat(object, indent=1, width=80, depth=None, *, \
compact=False, sort_dicts=True)
Return the formatted representation of *object* as a string. *indent*,
Return the formatted representation of *object* as a string. *indent*,
*width*, *depth*
and *compact* will be passed to the :class:`PrettyPrinter`
*width*, *depth*
, *compact* and *sort_dicts* will be passed to the
constructor as formatting parameters.
:class:`PrettyPrinter`
constructor as formatting parameters.
.. versionchanged:: 3.4
.. versionchanged:: 3.4
Added the *compact* parameter.
Added the *compact* parameter.
.. versionchanged:: 3.8
Added the *sort_dicts* parameter.
.. function:: pp(object, *args, sort_dicts=False, **kwargs)
Prints the formatted representation of *object* followed by a newline.
If *sort_dicts* is false (the default), dictionaries will be displayed with
their keys in insertion order, otherwise the dict keys will be sorted.
*args* an *kwargs* will be passed to :func:`pprint` as formatting
parameters.
.. versionadded:: 3.8
.. function:: pprint(object, stream=None, indent=1, width=80, depth=None, *, \
.. function:: pprint(object, stream=None, indent=1, width=80, depth=None, *, \
compact=False)
compact=False
, sort_dicts=True
)
Prints the formatted representation of *object* on *stream*, followed by a
Prints the formatted representation of *object* on *stream*, followed by a
newline. If *stream* is ``None``, ``sys.stdout`` is used. This may be used
newline. If *stream* is ``None``, ``sys.stdout`` is used. This may be used
in the interactive interpreter instead of the :func:`print` function for
in the interactive interpreter instead of the :func:`print` function for
inspecting values (you can even reassign ``print = pprint.pprint`` for use
inspecting values (you can even reassign ``print = pprint.pprint`` for use
within a scope). *indent*, *width*, *depth*
and *compact* will be passed
within a scope). *indent*, *width*, *depth*
, *compact* and *sort_dicts* will
to the :class:`PrettyPrinter` constructor as formatting parameters.
be passed
to the :class:`PrettyPrinter` constructor as formatting parameters.
.. versionchanged:: 3.4
.. versionchanged:: 3.4
Added the *compact* parameter.
Added the *compact* parameter.
.. versionchanged:: 3.8
Added the *sort_dicts* parameter.
>>> import pprint
>>> import pprint
>>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
>>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
>>> stuff.insert(0, stuff)
>>> stuff.insert(0, stuff)
...
...
Doc/tools/susp-ignored.csv
View file @
96831c7f
...
@@ -180,15 +180,15 @@ library/pickle,,:memory,"conn = sqlite3.connect("":memory:"")"
...
@@ -180,15 +180,15 @@ library/pickle,,:memory,"conn = sqlite3.connect("":memory:"")"
library/posix,,`,"CFLAGS=""`getconf LFS_CFLAGS`"" OPT=""-g -O2 $CFLAGS"""
library/posix,,`,"CFLAGS=""`getconf LFS_CFLAGS`"" OPT=""-g -O2 $CFLAGS"""
library/pprint,,::,"'Programming Language :: Python :: 2.6',"
library/pprint,,::,"'Programming Language :: Python :: 2.6',"
library/pprint,,::,"'Programming Language :: Python :: 2.7',"
library/pprint,,::,"'Programming Language :: Python :: 2.7',"
library/pprint,
225
,::,"'classifiers': ['Development Status :: 3 - Alpha',"
library/pprint,,::,"'classifiers': ['Development Status :: 3 - Alpha',"
library/pprint,
225
,::,"'Intended Audience :: Developers',"
library/pprint,,::,"'Intended Audience :: Developers',"
library/pprint,
225
,::,"'License :: OSI Approved :: MIT License',"
library/pprint,,::,"'License :: OSI Approved :: MIT License',"
library/pprint,
225
,::,"'Programming Language :: Python :: 2',"
library/pprint,,::,"'Programming Language :: Python :: 2',"
library/pprint,
225
,::,"'Programming Language :: Python :: 3',"
library/pprint,,::,"'Programming Language :: Python :: 3',"
library/pprint,
225
,::,"'Programming Language :: Python :: 3.2',"
library/pprint,,::,"'Programming Language :: Python :: 3.2',"
library/pprint,
225
,::,"'Programming Language :: Python :: 3.3',"
library/pprint,,::,"'Programming Language :: Python :: 3.3',"
library/pprint,
225
,::,"'Programming Language :: Python :: 3.4',"
library/pprint,,::,"'Programming Language :: Python :: 3.4',"
library/pprint,
225
,::,"'Topic :: Software Development :: Build Tools'],"
library/pprint,,::,"'Topic :: Software Development :: Build Tools'],"
library/profile,,:lineno,filename:lineno(function)
library/profile,,:lineno,filename:lineno(function)
library/pyexpat,,:elem1,<py:elem1 />
library/pyexpat,,:elem1,<py:elem1 />
library/pyexpat,,:py,"xmlns:py = ""http://www.python.org/ns/"">"
library/pyexpat,,:py,"xmlns:py = ""http://www.python.org/ns/"">"
...
...
Lib/pprint.py
View file @
96831c7f
...
@@ -41,33 +41,38 @@ import types as _types
...
@@ -41,33 +41,38 @@ import types as _types
from
io
import
StringIO
as
_StringIO
from
io
import
StringIO
as
_StringIO
__all__
=
[
"pprint"
,
"pformat"
,
"isreadable"
,
"isrecursive"
,
"saferepr"
,
__all__
=
[
"pprint"
,
"pformat"
,
"isreadable"
,
"isrecursive"
,
"saferepr"
,
"PrettyPrinter"
]
"PrettyPrinter"
,
"pp"
]
def
pprint
(
object
,
stream
=
None
,
indent
=
1
,
width
=
80
,
depth
=
None
,
*
,
def
pprint
(
object
,
stream
=
None
,
indent
=
1
,
width
=
80
,
depth
=
None
,
*
,
compact
=
False
):
compact
=
False
,
sort_dicts
=
True
):
"""Pretty-print a Python object to a stream [default is sys.stdout]."""
"""Pretty-print a Python object to a stream [default is sys.stdout]."""
printer
=
PrettyPrinter
(
printer
=
PrettyPrinter
(
stream
=
stream
,
indent
=
indent
,
width
=
width
,
depth
=
depth
,
stream
=
stream
,
indent
=
indent
,
width
=
width
,
depth
=
depth
,
compact
=
compact
)
compact
=
compact
,
sort_dicts
=
sort_dicts
)
printer
.
pprint
(
object
)
printer
.
pprint
(
object
)
def
pformat
(
object
,
indent
=
1
,
width
=
80
,
depth
=
None
,
*
,
compact
=
False
):
def
pformat
(
object
,
indent
=
1
,
width
=
80
,
depth
=
None
,
*
,
compact
=
False
,
sort_dicts
=
True
):
"""Format a Python object into a pretty-printed representation."""
"""Format a Python object into a pretty-printed representation."""
return
PrettyPrinter
(
indent
=
indent
,
width
=
width
,
depth
=
depth
,
return
PrettyPrinter
(
indent
=
indent
,
width
=
width
,
depth
=
depth
,
compact
=
compact
).
pformat
(
object
)
compact
=
compact
,
sort_dicts
=
sort_dicts
).
pformat
(
object
)
def
pp
(
object
,
*
args
,
sort_dicts
=
False
,
**
kwargs
):
"""Pretty-print a Python object"""
pprint
(
object
,
*
args
,
sort_dicts
=
sort_dicts
,
**
kwargs
)
def
saferepr
(
object
):
def
saferepr
(
object
):
"""Version of repr() which can handle recursive data structures."""
"""Version of repr() which can handle recursive data structures."""
return
_safe_repr
(
object
,
{},
None
,
0
)[
0
]
return
_safe_repr
(
object
,
{},
None
,
0
,
True
)[
0
]
def
isreadable
(
object
):
def
isreadable
(
object
):
"""Determine if saferepr(object) is readable by eval()."""
"""Determine if saferepr(object) is readable by eval()."""
return
_safe_repr
(
object
,
{},
None
,
0
)[
1
]
return
_safe_repr
(
object
,
{},
None
,
0
,
True
)[
1
]
def
isrecursive
(
object
):
def
isrecursive
(
object
):
"""Determine if object requires a recursive representation."""
"""Determine if object requires a recursive representation."""
return
_safe_repr
(
object
,
{},
None
,
0
)[
2
]
return
_safe_repr
(
object
,
{},
None
,
0
,
True
)[
2
]
class
_safe_key
:
class
_safe_key
:
"""Helper function for key functions when sorting unorderable objects.
"""Helper function for key functions when sorting unorderable objects.
...
@@ -97,7 +102,7 @@ def _safe_tuple(t):
...
@@ -97,7 +102,7 @@ def _safe_tuple(t):
class
PrettyPrinter
:
class
PrettyPrinter
:
def
__init__
(
self
,
indent
=
1
,
width
=
80
,
depth
=
None
,
stream
=
None
,
*
,
def
__init__
(
self
,
indent
=
1
,
width
=
80
,
depth
=
None
,
stream
=
None
,
*
,
compact
=
False
):
compact
=
False
,
sort_dicts
=
True
):
"""Handle pretty printing operations onto a stream using a set of
"""Handle pretty printing operations onto a stream using a set of
configured parameters.
configured parameters.
...
@@ -117,6 +122,9 @@ class PrettyPrinter:
...
@@ -117,6 +122,9 @@ class PrettyPrinter:
compact
compact
If true, several items will be combined in one line.
If true, several items will be combined in one line.
sort_dicts
If true, dict keys are sorted.
"""
"""
indent
=
int
(
indent
)
indent
=
int
(
indent
)
width
=
int
(
width
)
width
=
int
(
width
)
...
@@ -134,6 +142,7 @@ class PrettyPrinter:
...
@@ -134,6 +142,7 @@ class PrettyPrinter:
else
:
else
:
self
.
_stream
=
_sys
.
stdout
self
.
_stream
=
_sys
.
stdout
self
.
_compact
=
bool
(
compact
)
self
.
_compact
=
bool
(
compact
)
self
.
_sort_dicts
=
sort_dicts
def
pprint
(
self
,
object
):
def
pprint
(
self
,
object
):
self
.
_format
(
object
,
self
.
_stream
,
0
,
0
,
{},
0
)
self
.
_format
(
object
,
self
.
_stream
,
0
,
0
,
{},
0
)
...
@@ -184,7 +193,10 @@ class PrettyPrinter:
...
@@ -184,7 +193,10 @@ class PrettyPrinter:
write
((
self
.
_indent_per_level
-
1
)
*
' '
)
write
((
self
.
_indent_per_level
-
1
)
*
' '
)
length
=
len
(
object
)
length
=
len
(
object
)
if
length
:
if
length
:
if
self
.
_sort_dicts
:
items
=
sorted
(
object
.
items
(),
key
=
_safe_tuple
)
items
=
sorted
(
object
.
items
(),
key
=
_safe_tuple
)
else
:
items
=
object
.
items
()
self
.
_format_dict_items
(
items
,
stream
,
indent
,
allowance
+
1
,
self
.
_format_dict_items
(
items
,
stream
,
indent
,
allowance
+
1
,
context
,
level
)
context
,
level
)
write
(
'}'
)
write
(
'}'
)
...
@@ -402,7 +414,7 @@ class PrettyPrinter:
...
@@ -402,7 +414,7 @@ class PrettyPrinter:
and flags indicating whether the representation is 'readable'
and flags indicating whether the representation is 'readable'
and whether the object represents a recursive construct.
and whether the object represents a recursive construct.
"""
"""
return
_safe_repr
(
object
,
context
,
maxlevels
,
level
)
return
_safe_repr
(
object
,
context
,
maxlevels
,
level
,
self
.
_sort_dicts
)
def
_pprint_default_dict
(
self
,
object
,
stream
,
indent
,
allowance
,
context
,
level
):
def
_pprint_default_dict
(
self
,
object
,
stream
,
indent
,
allowance
,
context
,
level
):
if
not
len
(
object
):
if
not
len
(
object
):
...
@@ -487,7 +499,7 @@ class PrettyPrinter:
...
@@ -487,7 +499,7 @@ class PrettyPrinter:
# Return triple (repr_string, isreadable, isrecursive).
# Return triple (repr_string, isreadable, isrecursive).
def
_safe_repr
(
object
,
context
,
maxlevels
,
level
):
def
_safe_repr
(
object
,
context
,
maxlevels
,
level
,
sort_dicts
):
typ
=
type
(
object
)
typ
=
type
(
object
)
if
typ
in
_builtin_scalars
:
if
typ
in
_builtin_scalars
:
return
repr
(
object
),
True
,
False
return
repr
(
object
),
True
,
False
...
@@ -507,11 +519,13 @@ def _safe_repr(object, context, maxlevels, level):
...
@@ -507,11 +519,13 @@ def _safe_repr(object, context, maxlevels, level):
components
=
[]
components
=
[]
append
=
components
.
append
append
=
components
.
append
level
+=
1
level
+=
1
saferepr
=
_safe_repr
if
sort_dicts
:
items
=
sorted
(
object
.
items
(),
key
=
_safe_tuple
)
items
=
sorted
(
object
.
items
(),
key
=
_safe_tuple
)
else
:
items
=
object
.
items
()
for
k
,
v
in
items
:
for
k
,
v
in
items
:
krepr
,
kreadable
,
krecur
=
saferepr
(
k
,
context
,
maxlevels
,
level
)
krepr
,
kreadable
,
krecur
=
_safe_repr
(
k
,
context
,
maxlevels
,
level
,
sort_dicts
)
vrepr
,
vreadable
,
vrecur
=
saferepr
(
v
,
context
,
maxlevels
,
level
)
vrepr
,
vreadable
,
vrecur
=
_safe_repr
(
v
,
context
,
maxlevels
,
level
,
sort_dicts
)
append
(
"%s: %s"
%
(
krepr
,
vrepr
))
append
(
"%s: %s"
%
(
krepr
,
vrepr
))
readable
=
readable
and
kreadable
and
vreadable
readable
=
readable
and
kreadable
and
vreadable
if
krecur
or
vrecur
:
if
krecur
or
vrecur
:
...
@@ -543,7 +557,7 @@ def _safe_repr(object, context, maxlevels, level):
...
@@ -543,7 +557,7 @@ def _safe_repr(object, context, maxlevels, level):
append
=
components
.
append
append
=
components
.
append
level
+=
1
level
+=
1
for
o
in
object
:
for
o
in
object
:
orepr
,
oreadable
,
orecur
=
_safe_repr
(
o
,
context
,
maxlevels
,
level
)
orepr
,
oreadable
,
orecur
=
_safe_repr
(
o
,
context
,
maxlevels
,
level
,
sort_dicts
)
append
(
orepr
)
append
(
orepr
)
if
not
oreadable
:
if
not
oreadable
:
readable
=
False
readable
=
False
...
@@ -569,7 +583,7 @@ def _perfcheck(object=None):
...
@@ -569,7 +583,7 @@ def _perfcheck(object=None):
object
=
[(
"string"
,
(
1
,
2
),
[
3
,
4
],
{
5
:
6
,
7
:
8
})]
*
100000
object
=
[(
"string"
,
(
1
,
2
),
[
3
,
4
],
{
5
:
6
,
7
:
8
})]
*
100000
p
=
PrettyPrinter
()
p
=
PrettyPrinter
()
t1
=
time
.
perf_counter
()
t1
=
time
.
perf_counter
()
_safe_repr
(
object
,
{},
None
,
0
)
_safe_repr
(
object
,
{},
None
,
0
,
True
)
t2
=
time
.
perf_counter
()
t2
=
time
.
perf_counter
()
p
.
pformat
(
object
)
p
.
pformat
(
object
)
t3
=
time
.
perf_counter
()
t3
=
time
.
perf_counter
()
...
...
Lib/test/test_pprint.py
View file @
96831c7f
...
@@ -81,6 +81,7 @@ class QueryTestCase(unittest.TestCase):
...
@@ -81,6 +81,7 @@ class QueryTestCase(unittest.TestCase):
pp
=
pprint
.
PrettyPrinter
(
indent
=
4
,
width
=
40
,
depth
=
5
,
pp
=
pprint
.
PrettyPrinter
(
indent
=
4
,
width
=
40
,
depth
=
5
,
stream
=
io
.
StringIO
(),
compact
=
True
)
stream
=
io
.
StringIO
(),
compact
=
True
)
pp
=
pprint
.
PrettyPrinter
(
4
,
40
,
5
,
io
.
StringIO
())
pp
=
pprint
.
PrettyPrinter
(
4
,
40
,
5
,
io
.
StringIO
())
pp
=
pprint
.
PrettyPrinter
(
sort_dicts
=
False
)
with
self
.
assertRaises
(
TypeError
):
with
self
.
assertRaises
(
TypeError
):
pp
=
pprint
.
PrettyPrinter
(
4
,
40
,
5
,
io
.
StringIO
(),
True
)
pp
=
pprint
.
PrettyPrinter
(
4
,
40
,
5
,
io
.
StringIO
(),
True
)
self
.
assertRaises
(
ValueError
,
pprint
.
PrettyPrinter
,
indent
=-
1
)
self
.
assertRaises
(
ValueError
,
pprint
.
PrettyPrinter
,
indent
=-
1
)
...
@@ -293,6 +294,12 @@ class QueryTestCase(unittest.TestCase):
...
@@ -293,6 +294,12 @@ class QueryTestCase(unittest.TestCase):
self
.
assertEqual
(
pprint
.
pformat
({
"xy
\
t
ab
\
n
"
:
(
3
,),
5
:
[[]],
():
{}}),
self
.
assertEqual
(
pprint
.
pformat
({
"xy
\
t
ab
\
n
"
:
(
3
,),
5
:
[[]],
():
{}}),
r"{5: [[]], 'xy\tab\n': (3,), (): {}}"
)
r"{5: [[]], 'xy\tab\n': (3,), (): {}}"
)
def
test_sort_dict
(
self
):
d
=
dict
.
fromkeys
(
'cba'
)
self
.
assertEqual
(
pprint
.
pformat
(
d
,
sort_dicts
=
False
),
"{'c': None, 'b': None, 'a': None}"
)
self
.
assertEqual
(
pprint
.
pformat
([
d
,
d
],
sort_dicts
=
False
),
"[{'c': None, 'b': None, 'a': None}, {'c': None, 'b': None, 'a': None}]"
)
def
test_ordered_dict
(
self
):
def
test_ordered_dict
(
self
):
d
=
collections
.
OrderedDict
()
d
=
collections
.
OrderedDict
()
self
.
assertEqual
(
pprint
.
pformat
(
d
,
width
=
1
),
'OrderedDict()'
)
self
.
assertEqual
(
pprint
.
pformat
(
d
,
width
=
1
),
'OrderedDict()'
)
...
...
Misc/NEWS.d/next/Library/2019-02-06-12-07-46.bpo-30670.yffB3F.rst
0 → 100644
View file @
96831c7f
`pprint.pp` has been added to pretty-print objects with dictionary
keys being sorted with their insertion order by default. Parameter
*sort_dicts* has been added to `pprint.pprint`, `pprint.pformat` and
`pprint.PrettyPrinter`. Contributed by Rémi Lapeyre.
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