mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
Patch #750542: pprint now will pretty print subclasses of list, tuple
and dict too, as long as they don't overwrite __repr__().
This commit is contained in:
parent
291481b4db
commit
7a7ede54d4
3 changed files with 55 additions and 13 deletions
|
@ -90,9 +90,9 @@ class PrettyPrinter:
|
||||||
"""
|
"""
|
||||||
indent = int(indent)
|
indent = int(indent)
|
||||||
width = int(width)
|
width = int(width)
|
||||||
assert indent >= 0
|
assert indent >= 0, "indent must be >= 0"
|
||||||
assert depth is None or depth > 0, "depth must be > 0"
|
assert depth is None or depth > 0, "depth must be > 0"
|
||||||
assert width
|
assert width, "width must be != 0"
|
||||||
self._depth = depth
|
self._depth = depth
|
||||||
self._indent_per_level = indent
|
self._indent_per_level = indent
|
||||||
self._width = width
|
self._width = width
|
||||||
|
@ -130,7 +130,8 @@ class PrettyPrinter:
|
||||||
write = stream.write
|
write = stream.write
|
||||||
|
|
||||||
if sepLines:
|
if sepLines:
|
||||||
if typ is dict:
|
r = typ.__repr__
|
||||||
|
if issubclass(typ, dict) and r is dict.__repr__:
|
||||||
write('{')
|
write('{')
|
||||||
if self._indent_per_level > 1:
|
if self._indent_per_level > 1:
|
||||||
write((self._indent_per_level - 1) * ' ')
|
write((self._indent_per_level - 1) * ' ')
|
||||||
|
@ -157,8 +158,9 @@ class PrettyPrinter:
|
||||||
write('}')
|
write('}')
|
||||||
return
|
return
|
||||||
|
|
||||||
if typ is list or typ is tuple:
|
if (issubclass(typ, list) and r is list.__repr__) or \
|
||||||
if typ is list:
|
(issubclass(typ, tuple) and r is tuple.__repr__):
|
||||||
|
if issubclass(typ, list):
|
||||||
write('[')
|
write('[')
|
||||||
endchar = ']'
|
endchar = ']'
|
||||||
else:
|
else:
|
||||||
|
@ -179,7 +181,7 @@ class PrettyPrinter:
|
||||||
allowance + 1, context, level)
|
allowance + 1, context, level)
|
||||||
indent = indent - self._indent_per_level
|
indent = indent - self._indent_per_level
|
||||||
del context[objid]
|
del context[objid]
|
||||||
if typ is tuple and length == 1:
|
if issubclass(typ, tuple) and length == 1:
|
||||||
write(',')
|
write(',')
|
||||||
write(endchar)
|
write(endchar)
|
||||||
return
|
return
|
||||||
|
@ -226,7 +228,8 @@ def _safe_repr(object, context, maxlevels, level):
|
||||||
write(qget(char, `char`[1:-1]))
|
write(qget(char, `char`[1:-1]))
|
||||||
return ("%s%s%s" % (closure, sio.getvalue(), closure)), True, False
|
return ("%s%s%s" % (closure, sio.getvalue(), closure)), True, False
|
||||||
|
|
||||||
if typ is dict:
|
r = typ.__repr__
|
||||||
|
if issubclass(typ, dict) and r is dict.__repr__:
|
||||||
if not object:
|
if not object:
|
||||||
return "{}", True, False
|
return "{}", True, False
|
||||||
objid = _id(object)
|
objid = _id(object)
|
||||||
|
@ -251,8 +254,9 @@ def _safe_repr(object, context, maxlevels, level):
|
||||||
del context[objid]
|
del context[objid]
|
||||||
return "{%s}" % _commajoin(components), readable, recursive
|
return "{%s}" % _commajoin(components), readable, recursive
|
||||||
|
|
||||||
if typ is list or typ is tuple:
|
if (issubclass(typ, list) and r is list.__repr__) or \
|
||||||
if typ is list:
|
(issubclass(typ, tuple) and r is tuple.__repr__):
|
||||||
|
if issubclass(typ, list):
|
||||||
if not object:
|
if not object:
|
||||||
return "[]", True, False
|
return "[]", True, False
|
||||||
format = "[%s]"
|
format = "[%s]"
|
||||||
|
|
|
@ -8,6 +8,22 @@ except NameError:
|
||||||
def uni(x):
|
def uni(x):
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
# list, tuple and dict subclasses that do or don't overwrite __repr__
|
||||||
|
class list2(list):
|
||||||
|
pass
|
||||||
|
class list3(list):
|
||||||
|
def __repr__(self):
|
||||||
|
return list.__repr__(self)
|
||||||
|
class tuple2(tuple):
|
||||||
|
pass
|
||||||
|
class tuple3(tuple):
|
||||||
|
def __repr__(self):
|
||||||
|
return tuple.__repr__(self)
|
||||||
|
class dict2(dict):
|
||||||
|
pass
|
||||||
|
class dict3(dict):
|
||||||
|
def __repr__(self):
|
||||||
|
return dict.__repr__(self)
|
||||||
|
|
||||||
class QueryTestCase(unittest.TestCase):
|
class QueryTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -84,11 +100,20 @@ class QueryTestCase(unittest.TestCase):
|
||||||
"expected not isreadable for " + `unreadable`)
|
"expected not isreadable for " + `unreadable`)
|
||||||
|
|
||||||
def test_same_as_repr(self):
|
def test_same_as_repr(self):
|
||||||
# Simple objects and small containers that should be same as repr()
|
# Simple objects, small containers and classes that overwrite __repr__
|
||||||
|
# For those the result should be the same as repr()
|
||||||
verify = self.assert_
|
verify = self.assert_
|
||||||
for simple in (0, 0L, 0+0j, 0.0, "", uni(""), (), [], {}, verify, pprint,
|
for simple in (0, 0L, 0+0j, 0.0, "", uni(""),
|
||||||
|
(), tuple2(), tuple3(),
|
||||||
|
[], list2(), list3(),
|
||||||
|
{}, dict2(), dict3(),
|
||||||
|
verify, pprint,
|
||||||
-6, -6L, -6-6j, -1.5, "x", uni("x"), (3,), [3], {3: 6},
|
-6, -6L, -6-6j, -1.5, "x", uni("x"), (3,), [3], {3: 6},
|
||||||
(1,2), [3,4], {5: 6, 7: 8},
|
(1,2), [3,4], {5: 6, 7: 8},
|
||||||
|
tuple2((1,2)), tuple3((1,2)), tuple3(range(100)),
|
||||||
|
[3,4], list2([3,4]), list3([3,4]), list3(range(100)),
|
||||||
|
{5: 6, 7: 8}, dict2({5: 6, 7: 8}), dict3({5: 6, 7: 8}),
|
||||||
|
dict3([(x,x) for x in range(100)]),
|
||||||
{"xy\tab\n": (3,), 5: [[]], (): {}},
|
{"xy\tab\n": (3,), 5: [[]], (): {}},
|
||||||
range(10, -11, -1)
|
range(10, -11, -1)
|
||||||
):
|
):
|
||||||
|
@ -99,7 +124,6 @@ class QueryTestCase(unittest.TestCase):
|
||||||
verify(native == got, "expected %s got %s from pprint.%s" %
|
verify(native == got, "expected %s got %s from pprint.%s" %
|
||||||
(native, got, function))
|
(native, got, function))
|
||||||
|
|
||||||
|
|
||||||
def test_basic_line_wrap(self):
|
def test_basic_line_wrap(self):
|
||||||
# verify basic line-wrapping operation
|
# verify basic line-wrapping operation
|
||||||
o = {'RPM_cal': 0,
|
o = {'RPM_cal': 0,
|
||||||
|
@ -117,7 +141,18 @@ class QueryTestCase(unittest.TestCase):
|
||||||
'main_code_runtime_us': 0,
|
'main_code_runtime_us': 0,
|
||||||
'read_io_runtime_us': 0,
|
'read_io_runtime_us': 0,
|
||||||
'write_io_runtime_us': 43690}"""
|
'write_io_runtime_us': 43690}"""
|
||||||
self.assertEqual(pprint.pformat(o), exp)
|
for type in [dict, dict2]:
|
||||||
|
self.assertEqual(pprint.pformat(type(o)), exp)
|
||||||
|
|
||||||
|
o = range(100)
|
||||||
|
exp = '[%s]' % ',\n '.join(map(str, o))
|
||||||
|
for type in [list, list2]:
|
||||||
|
self.assertEqual(pprint.pformat(type(o)), exp)
|
||||||
|
|
||||||
|
o = tuple(range(100))
|
||||||
|
exp = '(%s)' % ',\n '.join(map(str, o))
|
||||||
|
for type in [tuple, tuple2]:
|
||||||
|
self.assertEqual(pprint.pformat(type(o)), exp)
|
||||||
|
|
||||||
def test_subclassing(self):
|
def test_subclassing(self):
|
||||||
o = {'names with spaces': 'should be presented using repr()',
|
o = {'names with spaces': 'should be presented using repr()',
|
||||||
|
|
|
@ -170,6 +170,9 @@ Extension modules
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Patch #750542: pprint now will pretty print subclasses of list, tuple
|
||||||
|
and dict too, as long as they don't overwrite __repr__().
|
||||||
|
|
||||||
- Bug #848614: distutils' msvccompiler fails to find the MSVC6
|
- Bug #848614: distutils' msvccompiler fails to find the MSVC6
|
||||||
compiler because of incomplete registry entries.
|
compiler because of incomplete registry entries.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue