Commit 51844384 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #19137: The pprint module now correctly formats instances of set and

frozenset subclasses.
parent 224c87d6
...@@ -205,24 +205,22 @@ class PrettyPrinter: ...@@ -205,24 +205,22 @@ class PrettyPrinter:
if issubclass(typ, list): if issubclass(typ, list):
write('[') write('[')
endchar = ']' endchar = ']'
elif issubclass(typ, set): elif issubclass(typ, tuple):
write('(')
endchar = ')'
else:
if not length: if not length:
write('set()') write(rep)
return return
if typ is set:
write('{') write('{')
endchar = '}' endchar = '}'
object = sorted(object, key=_safe_key) else:
elif issubclass(typ, frozenset): write(typ.__name__)
if not length: write('({')
write('frozenset()')
return
write('frozenset({')
endchar = '})' endchar = '})'
indent += len(typ.__name__) + 1
object = sorted(object, key=_safe_key) object = sorted(object, key=_safe_key)
indent += 10
else:
write('(')
endchar = ')'
if self._indent_per_level > 1: if self._indent_per_level > 1:
write((self._indent_per_level - 1) * ' ') write((self._indent_per_level - 1) * ' ')
if length: if length:
......
...@@ -21,6 +21,20 @@ class tuple3(tuple): ...@@ -21,6 +21,20 @@ class tuple3(tuple):
def __repr__(self): def __repr__(self):
return tuple.__repr__(self) return tuple.__repr__(self)
class set2(set):
pass
class set3(set):
def __repr__(self):
return set.__repr__(self)
class frozenset2(frozenset):
pass
class frozenset3(frozenset):
def __repr__(self):
return frozenset.__repr__(self)
class dict2(dict): class dict2(dict):
pass pass
...@@ -115,22 +129,24 @@ class QueryTestCase(unittest.TestCase): ...@@ -115,22 +129,24 @@ class QueryTestCase(unittest.TestCase):
for simple in (0, 0, 0+0j, 0.0, "", b"", for simple in (0, 0, 0+0j, 0.0, "", b"",
(), tuple2(), tuple3(), (), tuple2(), tuple3(),
[], list2(), list3(), [], list2(), list3(),
set(), set2(), set3(),
frozenset(), frozenset2(), frozenset3(),
{}, dict2(), dict3(), {}, dict2(), dict3(),
self.assertTrue, pprint, self.assertTrue, pprint,
-6, -6, -6-6j, -1.5, "x", b"x", (3,), [3], {3: 6}, -6, -6, -6-6j, -1.5, "x", b"x", (3,), [3], {3: 6},
(1,2), [3,4], {5: 6}, (1,2), [3,4], {5: 6},
tuple2((1,2)), tuple3((1,2)), tuple3(range(100)), tuple2((1,2)), tuple3((1,2)), tuple3(range(100)),
[3,4], list2([3,4]), list3([3,4]), list3(range(100)), [3,4], list2([3,4]), list3([3,4]), list3(range(100)),
set({7}), set2({7}), set3({7}),
frozenset({8}), frozenset2({8}), frozenset3({8}),
dict2({5: 6}), dict3({5: 6}), dict2({5: 6}), dict3({5: 6}),
range(10, -11, -1) range(10, -11, -1)
): ):
native = repr(simple) native = repr(simple)
for function in "pformat", "saferepr": self.assertEqual(pprint.pformat(simple), native)
f = getattr(pprint, function) self.assertEqual(pprint.pformat(simple, width=1, indent=0)
got = f(simple) .replace('\n', ' '), native)
self.assertEqual(native, got, self.assertEqual(pprint.saferepr(simple), native)
"expected %s got %s from pprint.%s" %
(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
...@@ -219,10 +235,54 @@ class QueryTestCase(unittest.TestCase): ...@@ -219,10 +235,54 @@ class QueryTestCase(unittest.TestCase):
others.should.not.be: like.this}""" others.should.not.be: like.this}"""
self.assertEqual(DottedPrettyPrinter().pformat(o), exp) self.assertEqual(DottedPrettyPrinter().pformat(o), exp)
def test_set_reprs(self):
self.assertEqual(pprint.pformat(set()), 'set()')
self.assertEqual(pprint.pformat(set(range(3))), '{0, 1, 2}')
self.assertEqual(pprint.pformat(set(range(7)), width=20), '''\
{0,
1,
2,
3,
4,
5,
6}''')
self.assertEqual(pprint.pformat(set2(range(7)), width=20), '''\
set2({0,
1,
2,
3,
4,
5,
6})''')
self.assertEqual(pprint.pformat(set3(range(7)), width=20),
'set3({0, 1, 2, 3, 4, 5, 6})')
self.assertEqual(pprint.pformat(frozenset()), 'frozenset()')
self.assertEqual(pprint.pformat(frozenset(range(3))),
'frozenset({0, 1, 2})')
self.assertEqual(pprint.pformat(frozenset(range(7)), width=20), '''\
frozenset({0,
1,
2,
3,
4,
5,
6})''')
self.assertEqual(pprint.pformat(frozenset2(range(7)), width=20), '''\
frozenset2({0,
1,
2,
3,
4,
5,
6})''')
self.assertEqual(pprint.pformat(frozenset3(range(7)), width=20),
'frozenset3({0, 1, 2, 3, 4, 5, 6})')
@unittest.expectedFailure @unittest.expectedFailure
#See http://bugs.python.org/issue13907 #See http://bugs.python.org/issue13907
@test.support.cpython_only @test.support.cpython_only
def test_set_reprs(self): def test_set_of_sets_reprs(self):
# This test creates a complex arrangement of frozensets and # This test creates a complex arrangement of frozensets and
# compares the pretty-printed repr against a string hard-coded in # compares the pretty-printed repr against a string hard-coded in
# the test. The hard-coded repr depends on the sort order of # the test. The hard-coded repr depends on the sort order of
...@@ -245,11 +305,6 @@ class QueryTestCase(unittest.TestCase): ...@@ -245,11 +305,6 @@ class QueryTestCase(unittest.TestCase):
# algorithm cause the test to fail when it should pass. # algorithm cause the test to fail when it should pass.
# XXX Or changes to the dictionary implmentation... # XXX Or changes to the dictionary implmentation...
self.assertEqual(pprint.pformat(set()), 'set()')
self.assertEqual(pprint.pformat(set(range(3))), '{0, 1, 2}')
self.assertEqual(pprint.pformat(frozenset()), 'frozenset()')
self.assertEqual(pprint.pformat(frozenset(range(3))), 'frozenset({0, 1, 2})')
cube_repr_tgt = """\ cube_repr_tgt = """\
{frozenset(): frozenset({frozenset({2}), frozenset({0}), frozenset({1})}), {frozenset(): frozenset({frozenset({2}), frozenset({0}), frozenset({1})}),
frozenset({0}): frozenset({frozenset(), frozenset({0}): frozenset({frozenset(),
......
...@@ -71,6 +71,9 @@ Core and Builtins ...@@ -71,6 +71,9 @@ Core and Builtins
Library Library
------- -------
- Issue #19137: The pprint module now correctly formats instances of set and
frozenset subclasses.
- Issue #19092: contextlib.ExitStack now correctly reraises exceptions - Issue #19092: contextlib.ExitStack now correctly reraises exceptions
from the __exit__ callbacks of inner context managers (Patch by Hrvoje from the __exit__ callbacks of inner context managers (Patch by Hrvoje
Nikšić) Nikšić)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment