blob: 6c714fd39e203a029dfe683f2ab133dff823e1ed [file] [log] [blame]
Antoine Pitrou64c16c32013-03-23 20:30:39 +01001# -*- coding: utf-8 -*-
2
Raymond Hettingerbad3c882010-09-09 12:31:00 +00003import collections
Lewis Gaul11159d22021-04-14 00:59:24 +01004import dataclasses
Serhiy Storchakaf3fa3082015-03-26 08:43:21 +02005import io
Raymond Hettingerbad3c882010-09-09 12:31:00 +00006import itertools
Serhiy Storchakaf3fa3082015-03-26 08:43:21 +02007import pprint
8import random
9import test.support
10import test.test_set
Serhiy Storchaka87eb4822015-03-24 19:31:50 +020011import types
Serhiy Storchakaf3fa3082015-03-26 08:43:21 +020012import unittest
Tim Petersa814db52001-05-14 07:05:58 +000013
Walter Dörwald7a7ede52003-12-03 20:15:28 +000014# list, tuple and dict subclasses that do or don't overwrite __repr__
15class list2(list):
16 pass
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000017
Walter Dörwald7a7ede52003-12-03 20:15:28 +000018class list3(list):
19 def __repr__(self):
20 return list.__repr__(self)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000021
Irit Katriel582f1372020-08-30 18:29:53 +010022class list_custom_repr(list):
23 def __repr__(self):
24 return '*'*len(list.__repr__(self))
25
Walter Dörwald7a7ede52003-12-03 20:15:28 +000026class tuple2(tuple):
27 pass
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000028
Walter Dörwald7a7ede52003-12-03 20:15:28 +000029class tuple3(tuple):
30 def __repr__(self):
31 return tuple.__repr__(self)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000032
Irit Katriel582f1372020-08-30 18:29:53 +010033class tuple_custom_repr(tuple):
34 def __repr__(self):
35 return '*'*len(tuple.__repr__(self))
36
Serhiy Storchaka51844382013-10-02 11:40:49 +030037class set2(set):
38 pass
39
40class set3(set):
41 def __repr__(self):
42 return set.__repr__(self)
43
Irit Katriel582f1372020-08-30 18:29:53 +010044class set_custom_repr(set):
45 def __repr__(self):
46 return '*'*len(set.__repr__(self))
47
Serhiy Storchaka51844382013-10-02 11:40:49 +030048class frozenset2(frozenset):
49 pass
50
51class frozenset3(frozenset):
52 def __repr__(self):
53 return frozenset.__repr__(self)
54
Irit Katriel582f1372020-08-30 18:29:53 +010055class frozenset_custom_repr(frozenset):
56 def __repr__(self):
57 return '*'*len(frozenset.__repr__(self))
58
Walter Dörwald7a7ede52003-12-03 20:15:28 +000059class dict2(dict):
60 pass
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000061
Walter Dörwald7a7ede52003-12-03 20:15:28 +000062class dict3(dict):
63 def __repr__(self):
64 return dict.__repr__(self)
Tim Petersa814db52001-05-14 07:05:58 +000065
Irit Katriel582f1372020-08-30 18:29:53 +010066class dict_custom_repr(dict):
67 def __repr__(self):
68 return '*'*len(dict.__repr__(self))
69
Lewis Gaul11159d22021-04-14 00:59:24 +010070@dataclasses.dataclass
71class dataclass1:
72 field1: str
73 field2: int
74 field3: bool = False
75 field4: int = dataclasses.field(default=1, repr=False)
76
77@dataclasses.dataclass
78class dataclass2:
79 a: int = 1
80 def __repr__(self):
81 return "custom repr that doesn't fit within pprint width"
82
83@dataclasses.dataclass(repr=False)
84class dataclass3:
85 a: int = 1
86
87@dataclasses.dataclass
88class dataclass4:
89 a: "dataclass4"
90 b: int = 1
91
92@dataclasses.dataclass
93class dataclass5:
94 a: "dataclass6"
95 b: int = 1
96
97@dataclasses.dataclass
98class dataclass6:
99 c: "dataclass5"
100 d: int = 1
101
Raymond Hettingera7da1662009-11-19 01:07:05 +0000102class Unorderable:
103 def __repr__(self):
104 return str(id(self))
105
Serhiy Storchaka62aa7dc2015-04-06 22:52:44 +0300106# Class Orderable is orderable with any type
107class Orderable:
108 def __init__(self, hash):
109 self._hash = hash
110 def __lt__(self, other):
111 return False
112 def __gt__(self, other):
113 return self != other
114 def __le__(self, other):
115 return self == other
116 def __ge__(self, other):
117 return True
118 def __eq__(self, other):
119 return self is other
120 def __ne__(self, other):
121 return self is not other
122 def __hash__(self):
123 return self._hash
124
Fred Drake43913dd2001-05-14 17:41:20 +0000125class QueryTestCase(unittest.TestCase):
Tim Petersa814db52001-05-14 07:05:58 +0000126
Fred Drake43913dd2001-05-14 17:41:20 +0000127 def setUp(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000128 self.a = list(range(100))
129 self.b = list(range(200))
Fred Drake43913dd2001-05-14 17:41:20 +0000130 self.a[-12] = self.b
Tim Petersa814db52001-05-14 07:05:58 +0000131
Serhiy Storchakaf3fa3082015-03-26 08:43:21 +0200132 def test_init(self):
133 pp = pprint.PrettyPrinter()
134 pp = pprint.PrettyPrinter(indent=4, width=40, depth=5,
135 stream=io.StringIO(), compact=True)
136 pp = pprint.PrettyPrinter(4, 40, 5, io.StringIO())
Rémi Lapeyre96831c72019-03-22 18:22:20 +0100137 pp = pprint.PrettyPrinter(sort_dicts=False)
Serhiy Storchakaf3fa3082015-03-26 08:43:21 +0200138 with self.assertRaises(TypeError):
139 pp = pprint.PrettyPrinter(4, 40, 5, io.StringIO(), True)
140 self.assertRaises(ValueError, pprint.PrettyPrinter, indent=-1)
141 self.assertRaises(ValueError, pprint.PrettyPrinter, depth=0)
142 self.assertRaises(ValueError, pprint.PrettyPrinter, depth=-1)
143 self.assertRaises(ValueError, pprint.PrettyPrinter, width=0)
144
Fred Drake43913dd2001-05-14 17:41:20 +0000145 def test_basic(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000146 # Verify .isrecursive() and .isreadable() w/o recursion
Fred Drakeb456e4f2002-12-31 07:16:16 +0000147 pp = pprint.PrettyPrinter()
Serhiy Storchakacbfe07e2015-05-20 19:37:10 +0300148 for safe in (2, 2.0, 2j, "abc", [3], (2,2), {3: 3}, b"def",
149 bytearray(b"ghi"), True, False, None, ...,
Fred Drake43913dd2001-05-14 17:41:20 +0000150 self.a, self.b):
Fred Drakeb456e4f2002-12-31 07:16:16 +0000151 # module-level convenience functions
Ezio Melottib19f43d2010-01-24 20:59:24 +0000152 self.assertFalse(pprint.isrecursive(safe),
153 "expected not isrecursive for %r" % (safe,))
154 self.assertTrue(pprint.isreadable(safe),
155 "expected isreadable for %r" % (safe,))
Fred Drakeb456e4f2002-12-31 07:16:16 +0000156 # PrettyPrinter methods
Ezio Melottib19f43d2010-01-24 20:59:24 +0000157 self.assertFalse(pp.isrecursive(safe),
158 "expected not isrecursive for %r" % (safe,))
159 self.assertTrue(pp.isreadable(safe),
160 "expected isreadable for %r" % (safe,))
Tim Petersa814db52001-05-14 07:05:58 +0000161
Fred Drake43913dd2001-05-14 17:41:20 +0000162 def test_knotted(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000163 # Verify .isrecursive() and .isreadable() w/ recursion
Fred Drake43913dd2001-05-14 17:41:20 +0000164 # Tie a knot.
165 self.b[67] = self.a
166 # Messy dict.
167 self.d = {}
168 self.d[0] = self.d[1] = self.d[2] = self.d
Tim Petersa814db52001-05-14 07:05:58 +0000169
Fred Drakeb456e4f2002-12-31 07:16:16 +0000170 pp = pprint.PrettyPrinter()
Tim Petersa814db52001-05-14 07:05:58 +0000171
Fred Drake43913dd2001-05-14 17:41:20 +0000172 for icky in self.a, self.b, self.d, (self.d, self.d):
Ezio Melottib19f43d2010-01-24 20:59:24 +0000173 self.assertTrue(pprint.isrecursive(icky), "expected isrecursive")
174 self.assertFalse(pprint.isreadable(icky), "expected not isreadable")
175 self.assertTrue(pp.isrecursive(icky), "expected isrecursive")
176 self.assertFalse(pp.isreadable(icky), "expected not isreadable")
Fred Drake43913dd2001-05-14 17:41:20 +0000177
178 # Break the cycles.
179 self.d.clear()
180 del self.a[:]
181 del self.b[:]
182
183 for safe in self.a, self.b, self.d, (self.d, self.d):
Fred Drakeb456e4f2002-12-31 07:16:16 +0000184 # module-level convenience functions
Ezio Melottib19f43d2010-01-24 20:59:24 +0000185 self.assertFalse(pprint.isrecursive(safe),
186 "expected not isrecursive for %r" % (safe,))
187 self.assertTrue(pprint.isreadable(safe),
188 "expected isreadable for %r" % (safe,))
Fred Drakeb456e4f2002-12-31 07:16:16 +0000189 # PrettyPrinter methods
Ezio Melottib19f43d2010-01-24 20:59:24 +0000190 self.assertFalse(pp.isrecursive(safe),
191 "expected not isrecursive for %r" % (safe,))
192 self.assertTrue(pp.isreadable(safe),
193 "expected isreadable for %r" % (safe,))
Fred Drake43913dd2001-05-14 17:41:20 +0000194
195 def test_unreadable(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000196 # Not recursive but not readable anyway
Fred Drakeb456e4f2002-12-31 07:16:16 +0000197 pp = pprint.PrettyPrinter()
Fred Drake43913dd2001-05-14 17:41:20 +0000198 for unreadable in type(3), pprint, pprint.isrecursive:
Fred Drakeb456e4f2002-12-31 07:16:16 +0000199 # module-level convenience functions
Ezio Melottib19f43d2010-01-24 20:59:24 +0000200 self.assertFalse(pprint.isrecursive(unreadable),
201 "expected not isrecursive for %r" % (unreadable,))
202 self.assertFalse(pprint.isreadable(unreadable),
203 "expected not isreadable for %r" % (unreadable,))
Fred Drakeb456e4f2002-12-31 07:16:16 +0000204 # PrettyPrinter methods
Ezio Melottib19f43d2010-01-24 20:59:24 +0000205 self.assertFalse(pp.isrecursive(unreadable),
206 "expected not isrecursive for %r" % (unreadable,))
207 self.assertFalse(pp.isreadable(unreadable),
208 "expected not isreadable for %r" % (unreadable,))
Fred Drake43913dd2001-05-14 17:41:20 +0000209
Tim Peters95b3f782001-05-14 18:39:41 +0000210 def test_same_as_repr(self):
Irit Katriel582f1372020-08-30 18:29:53 +0100211 # Simple objects, small containers and classes that override __repr__
212 # to directly call super's __repr__.
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000213 # For those the result should be the same as repr().
214 # Ahem. The docs don't say anything about that -- this appears to
215 # be testing an implementation quirk. Starting in Python 2.5, it's
216 # not true for dicts: pprint always sorts dicts by key now; before,
217 # it sorted a dict display if and only if the display required
218 # multiple lines. For that reason, dicts with more than one element
219 # aren't tested here.
Serhiy Storchakacbfe07e2015-05-20 19:37:10 +0300220 for simple in (0, 0, 0+0j, 0.0, "", b"", bytearray(),
Walter Dörwald7a7ede52003-12-03 20:15:28 +0000221 (), tuple2(), tuple3(),
222 [], list2(), list3(),
Serhiy Storchaka51844382013-10-02 11:40:49 +0300223 set(), set2(), set3(),
224 frozenset(), frozenset2(), frozenset3(),
Walter Dörwald7a7ede52003-12-03 20:15:28 +0000225 {}, dict2(), dict3(),
Ezio Melottib19f43d2010-01-24 20:59:24 +0000226 self.assertTrue, pprint,
Serhiy Storchakacbfe07e2015-05-20 19:37:10 +0300227 -6, -6, -6-6j, -1.5, "x", b"x", bytearray(b"x"),
228 (3,), [3], {3: 6},
Benjamin Petersond23f8222009-04-05 19:13:16 +0000229 (1,2), [3,4], {5: 6},
Walter Dörwald7a7ede52003-12-03 20:15:28 +0000230 tuple2((1,2)), tuple3((1,2)), tuple3(range(100)),
231 [3,4], list2([3,4]), list3([3,4]), list3(range(100)),
Serhiy Storchaka51844382013-10-02 11:40:49 +0300232 set({7}), set2({7}), set3({7}),
233 frozenset({8}), frozenset2({8}), frozenset3({8}),
Benjamin Petersond23f8222009-04-05 19:13:16 +0000234 dict2({5: 6}), dict3({5: 6}),
Serhiy Storchakacbfe07e2015-05-20 19:37:10 +0300235 range(10, -11, -1),
236 True, False, None, ...,
Tim Peters95b3f782001-05-14 18:39:41 +0000237 ):
238 native = repr(simple)
Serhiy Storchaka51844382013-10-02 11:40:49 +0300239 self.assertEqual(pprint.pformat(simple), native)
240 self.assertEqual(pprint.pformat(simple, width=1, indent=0)
241 .replace('\n', ' '), native)
sblondon3ba3d512021-03-24 09:23:20 +0100242 self.assertEqual(pprint.pformat(simple, underscore_numbers=True), native)
Serhiy Storchaka51844382013-10-02 11:40:49 +0300243 self.assertEqual(pprint.saferepr(simple), native)
Fred Drake43913dd2001-05-14 17:41:20 +0000244
Irit Katriel582f1372020-08-30 18:29:53 +0100245 def test_container_repr_override_called(self):
246 N = 1000
247 # Ensure that __repr__ override is called for subclasses of containers
248
249 for cont in (list_custom_repr(),
250 list_custom_repr([1,2,3]),
251 list_custom_repr(range(N)),
252 tuple_custom_repr(),
253 tuple_custom_repr([1,2,3]),
254 tuple_custom_repr(range(N)),
255 set_custom_repr(),
256 set_custom_repr([1,2,3]),
257 set_custom_repr(range(N)),
258 frozenset_custom_repr(),
259 frozenset_custom_repr([1,2,3]),
260 frozenset_custom_repr(range(N)),
261 dict_custom_repr(),
262 dict_custom_repr({5: 6}),
263 dict_custom_repr(zip(range(N),range(N))),
264 ):
265 native = repr(cont)
266 expected = '*' * len(native)
267 self.assertEqual(pprint.pformat(cont), expected)
268 self.assertEqual(pprint.pformat(cont, width=1, indent=0), expected)
269 self.assertEqual(pprint.saferepr(cont), expected)
270
Barry Warsaw00859c02001-11-28 05:49:39 +0000271 def test_basic_line_wrap(self):
Guido van Rossum32c2ae72002-08-22 19:45:32 +0000272 # verify basic line-wrapping operation
Barry Warsaw00859c02001-11-28 05:49:39 +0000273 o = {'RPM_cal': 0,
274 'RPM_cal2': 48059,
275 'Speed_cal': 0,
276 'controldesk_runtime_us': 0,
277 'main_code_runtime_us': 0,
278 'read_io_runtime_us': 0,
279 'write_io_runtime_us': 43690}
280 exp = """\
281{'RPM_cal': 0,
282 'RPM_cal2': 48059,
283 'Speed_cal': 0,
284 'controldesk_runtime_us': 0,
285 'main_code_runtime_us': 0,
286 'read_io_runtime_us': 0,
287 'write_io_runtime_us': 43690}"""
Walter Dörwald7a7ede52003-12-03 20:15:28 +0000288 for type in [dict, dict2]:
289 self.assertEqual(pprint.pformat(type(o)), exp)
290
291 o = range(100)
292 exp = '[%s]' % ',\n '.join(map(str, o))
293 for type in [list, list2]:
294 self.assertEqual(pprint.pformat(type(o)), exp)
295
296 o = tuple(range(100))
297 exp = '(%s)' % ',\n '.join(map(str, o))
298 for type in [tuple, tuple2]:
299 self.assertEqual(pprint.pformat(type(o)), exp)
Barry Warsaw00859c02001-11-28 05:49:39 +0000300
Walter Dörwaldc8de4582003-12-03 20:26:05 +0000301 # indent parameter
302 o = range(100)
303 exp = '[ %s]' % ',\n '.join(map(str, o))
304 for type in [list, list2]:
305 self.assertEqual(pprint.pformat(type(o), indent=4), exp)
306
Georg Brandl3ccb7872008-07-16 03:00:45 +0000307 def test_nested_indentations(self):
308 o1 = list(range(10))
309 o2 = dict(first=1, second=2, third=3)
310 o = [o1, o2]
311 expected = """\
312[ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
Serhiy Storchakaa750ce32015-02-14 10:55:19 +0200313 {'first': 1, 'second': 2, 'third': 3}]"""
314 self.assertEqual(pprint.pformat(o, indent=4, width=42), expected)
315 expected = """\
316[ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
Georg Brandl3ccb7872008-07-16 03:00:45 +0000317 { 'first': 1,
318 'second': 2,
319 'third': 3}]"""
Serhiy Storchakaa750ce32015-02-14 10:55:19 +0200320 self.assertEqual(pprint.pformat(o, indent=4, width=41), expected)
321
322 def test_width(self):
323 expected = """\
324[[[[[[1, 2, 3],
325 '1 2']]]],
326 {1: [1, 2, 3],
327 2: [12, 34]},
328 'abc def ghi',
329 ('ab cd ef',),
330 set2({1, 23}),
331 [[[[[1, 2, 3],
332 '1 2']]]]]"""
333 o = eval(expected)
334 self.assertEqual(pprint.pformat(o, width=15), expected)
335 self.assertEqual(pprint.pformat(o, width=16), expected)
336 self.assertEqual(pprint.pformat(o, width=25), expected)
337 self.assertEqual(pprint.pformat(o, width=14), """\
338[[[[[[1,
339 2,
340 3],
341 '1 '
342 '2']]]],
343 {1: [1,
344 2,
345 3],
346 2: [12,
347 34]},
348 'abc def '
349 'ghi',
350 ('ab cd '
351 'ef',),
352 set2({1,
353 23}),
354 [[[[[1,
355 2,
356 3],
357 '1 '
358 '2']]]]]""")
Georg Brandl3ccb7872008-07-16 03:00:45 +0000359
sblondon3ba3d512021-03-24 09:23:20 +0100360 def test_integer(self):
361 self.assertEqual(pprint.pformat(1234567), '1234567')
362 self.assertEqual(pprint.pformat(1234567, underscore_numbers=True), '1_234_567')
363
364 class Temperature(int):
365 def __new__(cls, celsius_degrees):
366 return super().__new__(Temperature, celsius_degrees)
367 def __repr__(self):
368 kelvin_degrees = self + 273.15
369 return f"{kelvin_degrees}°K"
370 self.assertEqual(pprint.pformat(Temperature(1000)), '1273.15°K')
371
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000372 def test_sorted_dict(self):
373 # Starting in Python 2.5, pprint sorts dict displays by key regardless
374 # of how small the dictionary may be.
375 # Before the change, on 32-bit Windows pformat() gave order
376 # 'a', 'c', 'b' here, so this test failed.
377 d = {'a': 1, 'b': 1, 'c': 1}
378 self.assertEqual(pprint.pformat(d), "{'a': 1, 'b': 1, 'c': 1}")
379 self.assertEqual(pprint.pformat([d, d]),
380 "[{'a': 1, 'b': 1, 'c': 1}, {'a': 1, 'b': 1, 'c': 1}]")
381
382 # The next one is kind of goofy. The sorted order depends on the
383 # alphabetic order of type names: "int" < "str" < "tuple". Before
384 # Python 2.5, this was in the test_same_as_repr() test. It's worth
385 # keeping around for now because it's one of few tests of pprint
386 # against a crazy mix of types.
387 self.assertEqual(pprint.pformat({"xy\tab\n": (3,), 5: [[]], (): {}}),
388 r"{5: [[]], 'xy\tab\n': (3,), (): {}}")
389
Rémi Lapeyre96831c72019-03-22 18:22:20 +0100390 def test_sort_dict(self):
391 d = dict.fromkeys('cba')
392 self.assertEqual(pprint.pformat(d, sort_dicts=False), "{'c': None, 'b': None, 'a': None}")
393 self.assertEqual(pprint.pformat([d, d], sort_dicts=False),
394 "[{'c': None, 'b': None, 'a': None}, {'c': None, 'b': None, 'a': None}]")
395
Raymond Hettingerbad3c882010-09-09 12:31:00 +0000396 def test_ordered_dict(self):
Serhiy Storchakaaa4c36f2015-03-26 08:51:33 +0200397 d = collections.OrderedDict()
398 self.assertEqual(pprint.pformat(d, width=1), 'OrderedDict()')
399 d = collections.OrderedDict([])
400 self.assertEqual(pprint.pformat(d, width=1), 'OrderedDict()')
Raymond Hettingerbad3c882010-09-09 12:31:00 +0000401 words = 'the quick brown fox jumped over a lazy dog'.split()
402 d = collections.OrderedDict(zip(words, itertools.count()))
403 self.assertEqual(pprint.pformat(d),
404"""\
Serhiy Storchakaaa4c36f2015-03-26 08:51:33 +0200405OrderedDict([('the', 0),
406 ('quick', 1),
407 ('brown', 2),
408 ('fox', 3),
409 ('jumped', 4),
410 ('over', 5),
411 ('a', 6),
412 ('lazy', 7),
413 ('dog', 8)])""")
Serhiy Storchaka87eb4822015-03-24 19:31:50 +0200414
415 def test_mapping_proxy(self):
416 words = 'the quick brown fox jumped over a lazy dog'.split()
417 d = dict(zip(words, itertools.count()))
418 m = types.MappingProxyType(d)
419 self.assertEqual(pprint.pformat(m), """\
420mappingproxy({'a': 6,
421 'brown': 2,
422 'dog': 8,
423 'fox': 3,
424 'jumped': 4,
425 'lazy': 7,
426 'over': 5,
427 'quick': 1,
428 'the': 0})""")
429 d = collections.OrderedDict(zip(words, itertools.count()))
430 m = types.MappingProxyType(d)
431 self.assertEqual(pprint.pformat(m), """\
Serhiy Storchakaaa4c36f2015-03-26 08:51:33 +0200432mappingproxy(OrderedDict([('the', 0),
433 ('quick', 1),
434 ('brown', 2),
435 ('fox', 3),
436 ('jumped', 4),
437 ('over', 5),
438 ('a', 6),
439 ('lazy', 7),
440 ('dog', 8)]))""")
Serhiy Storchaka87eb4822015-03-24 19:31:50 +0200441
Carl Bordum Hansen06a89162019-06-27 01:13:18 +0200442 def test_empty_simple_namespace(self):
443 ns = types.SimpleNamespace()
444 formatted = pprint.pformat(ns)
445 self.assertEqual(formatted, "namespace()")
446
447 def test_small_simple_namespace(self):
448 ns = types.SimpleNamespace(a=1, b=2)
449 formatted = pprint.pformat(ns)
450 self.assertEqual(formatted, "namespace(a=1, b=2)")
451
452 def test_simple_namespace(self):
453 ns = types.SimpleNamespace(
454 the=0,
455 quick=1,
456 brown=2,
457 fox=3,
458 jumped=4,
459 over=5,
460 a=6,
461 lazy=7,
462 dog=8,
463 )
Lewis Gaul11159d22021-04-14 00:59:24 +0100464 formatted = pprint.pformat(ns, width=60, indent=4)
Carl Bordum Hansen06a89162019-06-27 01:13:18 +0200465 self.assertEqual(formatted, """\
466namespace(the=0,
467 quick=1,
468 brown=2,
469 fox=3,
470 jumped=4,
471 over=5,
472 a=6,
473 lazy=7,
474 dog=8)""")
475
476 def test_simple_namespace_subclass(self):
477 class AdvancedNamespace(types.SimpleNamespace): pass
478 ns = AdvancedNamespace(
479 the=0,
480 quick=1,
481 brown=2,
482 fox=3,
483 jumped=4,
484 over=5,
485 a=6,
486 lazy=7,
487 dog=8,
488 )
489 formatted = pprint.pformat(ns, width=60)
490 self.assertEqual(formatted, """\
491AdvancedNamespace(the=0,
492 quick=1,
493 brown=2,
494 fox=3,
495 jumped=4,
496 over=5,
497 a=6,
498 lazy=7,
499 dog=8)""")
500
Lewis Gaul11159d22021-04-14 00:59:24 +0100501 def test_empty_dataclass(self):
502 dc = dataclasses.make_dataclass("MyDataclass", ())()
503 formatted = pprint.pformat(dc)
504 self.assertEqual(formatted, "MyDataclass()")
505
506 def test_small_dataclass(self):
507 dc = dataclass1("text", 123)
508 formatted = pprint.pformat(dc)
509 self.assertEqual(formatted, "dataclass1(field1='text', field2=123, field3=False)")
510
511 def test_larger_dataclass(self):
512 dc = dataclass1("some fairly long text", int(1e10), True)
513 formatted = pprint.pformat([dc, dc], width=60, indent=4)
514 self.assertEqual(formatted, """\
515[ dataclass1(field1='some fairly long text',
516 field2=10000000000,
517 field3=True),
518 dataclass1(field1='some fairly long text',
519 field2=10000000000,
520 field3=True)]""")
521
522 def test_dataclass_with_repr(self):
523 dc = dataclass2()
524 formatted = pprint.pformat(dc, width=20)
525 self.assertEqual(formatted, "custom repr that doesn't fit within pprint width")
526
527 def test_dataclass_no_repr(self):
528 dc = dataclass3()
529 formatted = pprint.pformat(dc, width=10)
530 self.assertRegex(formatted, r"<test.test_pprint.dataclass3 object at \w+>")
531
532 def test_recursive_dataclass(self):
533 dc = dataclass4(None)
534 dc.a = dc
535 formatted = pprint.pformat(dc, width=10)
536 self.assertEqual(formatted, """\
537dataclass4(a=...,
538 b=1)""")
539
540 def test_cyclic_dataclass(self):
541 dc5 = dataclass5(None)
542 dc6 = dataclass6(None)
543 dc5.a = dc6
544 dc6.c = dc5
545 formatted = pprint.pformat(dc5, width=10)
546 self.assertEqual(formatted, """\
547dataclass5(a=dataclass6(c=...,
548 d=1),
549 b=1)""")
550
Fred Drakeaee113d2002-04-02 05:08:35 +0000551 def test_subclassing(self):
Irit Katrielff420f02020-11-23 13:31:31 +0000552 # length(repr(obj)) > width
Fred Drakeaee113d2002-04-02 05:08:35 +0000553 o = {'names with spaces': 'should be presented using repr()',
554 'others.should.not.be': 'like.this'}
555 exp = """\
556{'names with spaces': 'should be presented using repr()',
557 others.should.not.be: like.this}"""
Irit Katrielff420f02020-11-23 13:31:31 +0000558
559 dotted_printer = DottedPrettyPrinter()
560 self.assertEqual(dotted_printer.pformat(o), exp)
561
562 # length(repr(obj)) < width
563 o1 = ['with space']
564 exp1 = "['with space']"
565 self.assertEqual(dotted_printer.pformat(o1), exp1)
566 o2 = ['without.space']
567 exp2 = "[without.space]"
568 self.assertEqual(dotted_printer.pformat(o2), exp2)
Fred Drakeaee113d2002-04-02 05:08:35 +0000569
Serhiy Storchaka51844382013-10-02 11:40:49 +0300570 def test_set_reprs(self):
571 self.assertEqual(pprint.pformat(set()), 'set()')
572 self.assertEqual(pprint.pformat(set(range(3))), '{0, 1, 2}')
573 self.assertEqual(pprint.pformat(set(range(7)), width=20), '''\
574{0,
575 1,
576 2,
577 3,
578 4,
579 5,
580 6}''')
581 self.assertEqual(pprint.pformat(set2(range(7)), width=20), '''\
582set2({0,
583 1,
584 2,
585 3,
586 4,
587 5,
588 6})''')
589 self.assertEqual(pprint.pformat(set3(range(7)), width=20),
590 'set3({0, 1, 2, 3, 4, 5, 6})')
591
592 self.assertEqual(pprint.pformat(frozenset()), 'frozenset()')
593 self.assertEqual(pprint.pformat(frozenset(range(3))),
594 'frozenset({0, 1, 2})')
595 self.assertEqual(pprint.pformat(frozenset(range(7)), width=20), '''\
596frozenset({0,
597 1,
598 2,
599 3,
600 4,
601 5,
602 6})''')
603 self.assertEqual(pprint.pformat(frozenset2(range(7)), width=20), '''\
604frozenset2({0,
605 1,
606 2,
607 3,
608 4,
609 5,
610 6})''')
611 self.assertEqual(pprint.pformat(frozenset3(range(7)), width=20),
612 'frozenset3({0, 1, 2, 3, 4, 5, 6})')
613
Benjamin Peterson7d95e402012-04-23 11:24:50 -0400614 @unittest.expectedFailure
615 #See http://bugs.python.org/issue13907
Daniel Stutzbachc944cfc2010-09-21 21:08:09 +0000616 @test.support.cpython_only
Serhiy Storchaka51844382013-10-02 11:40:49 +0300617 def test_set_of_sets_reprs(self):
Daniel Stutzbachc944cfc2010-09-21 21:08:09 +0000618 # This test creates a complex arrangement of frozensets and
619 # compares the pretty-printed repr against a string hard-coded in
620 # the test. The hard-coded repr depends on the sort order of
621 # frozensets.
622 #
623 # However, as the docs point out: "Since sets only define
624 # partial ordering (subset relationships), the output of the
625 # list.sort() method is undefined for lists of sets."
626 #
627 # In a nutshell, the test assumes frozenset({0}) will always
628 # sort before frozenset({1}), but:
629 #
630 # >>> frozenset({0}) < frozenset({1})
631 # False
632 # >>> frozenset({1}) < frozenset({0})
633 # False
634 #
635 # Consequently, this test is fragile and
636 # implementation-dependent. Small changes to Python's sort
637 # algorithm cause the test to fail when it should pass.
Min ho Kimc4cacc82019-07-31 08:16:13 +1000638 # XXX Or changes to the dictionary implementation...
Daniel Stutzbachc944cfc2010-09-21 21:08:09 +0000639
Christian Heimes969fe572008-01-25 11:23:10 +0000640 cube_repr_tgt = """\
641{frozenset(): frozenset({frozenset({2}), frozenset({0}), frozenset({1})}),
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000642 frozenset({0}): frozenset({frozenset(),
Christian Heimes969fe572008-01-25 11:23:10 +0000643 frozenset({0, 2}),
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000644 frozenset({0, 1})}),
645 frozenset({1}): frozenset({frozenset(),
Christian Heimes969fe572008-01-25 11:23:10 +0000646 frozenset({1, 2}),
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000647 frozenset({0, 1})}),
648 frozenset({2}): frozenset({frozenset(),
Christian Heimes969fe572008-01-25 11:23:10 +0000649 frozenset({1, 2}),
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000650 frozenset({0, 2})}),
651 frozenset({1, 2}): frozenset({frozenset({2}),
Christian Heimes969fe572008-01-25 11:23:10 +0000652 frozenset({1}),
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000653 frozenset({0, 1, 2})}),
654 frozenset({0, 2}): frozenset({frozenset({2}),
Christian Heimes969fe572008-01-25 11:23:10 +0000655 frozenset({0}),
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000656 frozenset({0, 1, 2})}),
657 frozenset({0, 1}): frozenset({frozenset({0}),
Christian Heimes969fe572008-01-25 11:23:10 +0000658 frozenset({1}),
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000659 frozenset({0, 1, 2})}),
660 frozenset({0, 1, 2}): frozenset({frozenset({1, 2}),
Christian Heimes969fe572008-01-25 11:23:10 +0000661 frozenset({0, 2}),
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000662 frozenset({0, 1})})}"""
Christian Heimes969fe572008-01-25 11:23:10 +0000663 cube = test.test_set.cube(3)
664 self.assertEqual(pprint.pformat(cube), cube_repr_tgt)
665 cubo_repr_tgt = """\
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000666{frozenset({frozenset({0, 2}), frozenset({0})}): frozenset({frozenset({frozenset({0,
667 2}),
668 frozenset({0,
Christian Heimes969fe572008-01-25 11:23:10 +0000669 1,
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000670 2})}),
671 frozenset({frozenset({0}),
672 frozenset({0,
673 1})}),
674 frozenset({frozenset(),
675 frozenset({0})}),
676 frozenset({frozenset({2}),
677 frozenset({0,
678 2})})}),
679 frozenset({frozenset({0, 1}), frozenset({1})}): frozenset({frozenset({frozenset({0,
680 1}),
681 frozenset({0,
Christian Heimes969fe572008-01-25 11:23:10 +0000682 1,
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000683 2})}),
684 frozenset({frozenset({0}),
685 frozenset({0,
686 1})}),
687 frozenset({frozenset({1}),
688 frozenset({1,
689 2})}),
690 frozenset({frozenset(),
691 frozenset({1})})}),
692 frozenset({frozenset({1, 2}), frozenset({1})}): frozenset({frozenset({frozenset({1,
693 2}),
694 frozenset({0,
Christian Heimes969fe572008-01-25 11:23:10 +0000695 1,
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000696 2})}),
697 frozenset({frozenset({2}),
698 frozenset({1,
699 2})}),
700 frozenset({frozenset(),
701 frozenset({1})}),
702 frozenset({frozenset({1}),
703 frozenset({0,
704 1})})}),
705 frozenset({frozenset({1, 2}), frozenset({2})}): frozenset({frozenset({frozenset({1,
706 2}),
707 frozenset({0,
Christian Heimes969fe572008-01-25 11:23:10 +0000708 1,
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000709 2})}),
710 frozenset({frozenset({1}),
711 frozenset({1,
712 2})}),
713 frozenset({frozenset({2}),
714 frozenset({0,
715 2})}),
716 frozenset({frozenset(),
717 frozenset({2})})}),
718 frozenset({frozenset(), frozenset({0})}): frozenset({frozenset({frozenset({0}),
719 frozenset({0,
720 1})}),
721 frozenset({frozenset({0}),
722 frozenset({0,
723 2})}),
724 frozenset({frozenset(),
725 frozenset({1})}),
726 frozenset({frozenset(),
727 frozenset({2})})}),
728 frozenset({frozenset(), frozenset({1})}): frozenset({frozenset({frozenset(),
729 frozenset({0})}),
730 frozenset({frozenset({1}),
731 frozenset({1,
732 2})}),
733 frozenset({frozenset(),
734 frozenset({2})}),
735 frozenset({frozenset({1}),
736 frozenset({0,
737 1})})}),
738 frozenset({frozenset({2}), frozenset()}): frozenset({frozenset({frozenset({2}),
739 frozenset({1,
740 2})}),
741 frozenset({frozenset(),
742 frozenset({0})}),
743 frozenset({frozenset(),
744 frozenset({1})}),
745 frozenset({frozenset({2}),
746 frozenset({0,
747 2})})}),
748 frozenset({frozenset({0, 1, 2}), frozenset({0, 1})}): frozenset({frozenset({frozenset({1,
749 2}),
750 frozenset({0,
Christian Heimes969fe572008-01-25 11:23:10 +0000751 1,
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000752 2})}),
753 frozenset({frozenset({0,
754 2}),
755 frozenset({0,
Christian Heimes969fe572008-01-25 11:23:10 +0000756 1,
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000757 2})}),
758 frozenset({frozenset({0}),
759 frozenset({0,
760 1})}),
761 frozenset({frozenset({1}),
762 frozenset({0,
763 1})})}),
764 frozenset({frozenset({0}), frozenset({0, 1})}): frozenset({frozenset({frozenset(),
765 frozenset({0})}),
766 frozenset({frozenset({0,
767 1}),
768 frozenset({0,
Christian Heimes969fe572008-01-25 11:23:10 +0000769 1,
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000770 2})}),
771 frozenset({frozenset({0}),
772 frozenset({0,
773 2})}),
774 frozenset({frozenset({1}),
775 frozenset({0,
776 1})})}),
777 frozenset({frozenset({2}), frozenset({0, 2})}): frozenset({frozenset({frozenset({0,
778 2}),
779 frozenset({0,
Christian Heimes969fe572008-01-25 11:23:10 +0000780 1,
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000781 2})}),
782 frozenset({frozenset({2}),
783 frozenset({1,
784 2})}),
785 frozenset({frozenset({0}),
786 frozenset({0,
787 2})}),
788 frozenset({frozenset(),
789 frozenset({2})})}),
790 frozenset({frozenset({0, 1, 2}), frozenset({0, 2})}): frozenset({frozenset({frozenset({1,
791 2}),
792 frozenset({0,
Christian Heimes969fe572008-01-25 11:23:10 +0000793 1,
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000794 2})}),
795 frozenset({frozenset({0,
796 1}),
797 frozenset({0,
Christian Heimes969fe572008-01-25 11:23:10 +0000798 1,
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000799 2})}),
800 frozenset({frozenset({0}),
801 frozenset({0,
802 2})}),
803 frozenset({frozenset({2}),
804 frozenset({0,
805 2})})}),
806 frozenset({frozenset({1, 2}), frozenset({0, 1, 2})}): frozenset({frozenset({frozenset({0,
807 2}),
808 frozenset({0,
Christian Heimes969fe572008-01-25 11:23:10 +0000809 1,
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000810 2})}),
811 frozenset({frozenset({0,
812 1}),
813 frozenset({0,
Christian Heimes969fe572008-01-25 11:23:10 +0000814 1,
Raymond Hettinger4b8db412008-01-31 01:10:03 +0000815 2})}),
816 frozenset({frozenset({2}),
817 frozenset({1,
818 2})}),
819 frozenset({frozenset({1}),
820 frozenset({1,
821 2})})})}"""
Christian Heimes969fe572008-01-25 11:23:10 +0000822
823 cubo = test.test_set.linegraph(cube)
824 self.assertEqual(pprint.pformat(cubo), cubo_repr_tgt)
825
Alexandre Vassalottieca20b62008-05-16 02:54:33 +0000826 def test_depth(self):
827 nested_tuple = (1, (2, (3, (4, (5, 6)))))
828 nested_dict = {1: {2: {3: {4: {5: {6: 6}}}}}}
829 nested_list = [1, [2, [3, [4, [5, [6, []]]]]]]
830 self.assertEqual(pprint.pformat(nested_tuple), repr(nested_tuple))
831 self.assertEqual(pprint.pformat(nested_dict), repr(nested_dict))
832 self.assertEqual(pprint.pformat(nested_list), repr(nested_list))
833
834 lv1_tuple = '(1, (...))'
835 lv1_dict = '{1: {...}}'
836 lv1_list = '[1, [...]]'
837 self.assertEqual(pprint.pformat(nested_tuple, depth=1), lv1_tuple)
838 self.assertEqual(pprint.pformat(nested_dict, depth=1), lv1_dict)
839 self.assertEqual(pprint.pformat(nested_list, depth=1), lv1_list)
840
Raymond Hettingera7da1662009-11-19 01:07:05 +0000841 def test_sort_unorderable_values(self):
842 # Issue 3976: sorted pprints fail for unorderable values.
843 n = 20
844 keys = [Unorderable() for i in range(n)]
845 random.shuffle(keys)
846 skeys = sorted(keys, key=id)
847 clean = lambda s: s.replace(' ', '').replace('\n','')
848
849 self.assertEqual(clean(pprint.pformat(set(keys))),
850 '{' + ','.join(map(repr, skeys)) + '}')
851 self.assertEqual(clean(pprint.pformat(frozenset(keys))),
852 'frozenset({' + ','.join(map(repr, skeys)) + '})')
853 self.assertEqual(clean(pprint.pformat(dict.fromkeys(keys))),
854 '{' + ','.join('%r:None' % k for k in skeys) + '}')
Fred Drakeaee113d2002-04-02 05:08:35 +0000855
Florent Xiclunad6da90f2012-07-21 11:17:38 +0200856 # Issue 10017: TypeError on user-defined types as dict keys.
857 self.assertEqual(pprint.pformat({Unorderable: 0, 1: 0}),
858 '{1: 0, ' + repr(Unorderable) +': 0}')
859
860 # Issue 14998: TypeError on tuples with NoneTypes as dict keys.
Florent Xicluna6e571d62012-07-21 12:44:20 +0200861 keys = [(1,), (None,)]
862 self.assertEqual(pprint.pformat(dict.fromkeys(keys, 0)),
863 '{%r: 0, %r: 0}' % tuple(sorted(keys, key=id)))
Florent Xiclunad6da90f2012-07-21 11:17:38 +0200864
Serhiy Storchaka62aa7dc2015-04-06 22:52:44 +0300865 def test_sort_orderable_and_unorderable_values(self):
866 # Issue 22721: sorted pprints is not stable
867 a = Unorderable()
868 b = Orderable(hash(a)) # should have the same hash value
869 # self-test
870 self.assertLess(a, b)
871 self.assertLess(str(type(b)), str(type(a)))
872 self.assertEqual(sorted([b, a]), [a, b])
873 self.assertEqual(sorted([a, b]), [a, b])
874 # set
875 self.assertEqual(pprint.pformat(set([b, a]), width=1),
876 '{%r,\n %r}' % (a, b))
877 self.assertEqual(pprint.pformat(set([a, b]), width=1),
878 '{%r,\n %r}' % (a, b))
879 # dict
880 self.assertEqual(pprint.pformat(dict.fromkeys([b, a]), width=1),
881 '{%r: None,\n %r: None}' % (a, b))
882 self.assertEqual(pprint.pformat(dict.fromkeys([a, b]), width=1),
883 '{%r: None,\n %r: None}' % (a, b))
884
Antoine Pitrou64c16c32013-03-23 20:30:39 +0100885 def test_str_wrap(self):
886 # pprint tries to wrap strings intelligently
887 fox = 'the quick brown fox jumped over a lazy dog'
Serhiy Storchakaa750ce32015-02-14 10:55:19 +0200888 self.assertEqual(pprint.pformat(fox, width=19), """\
889('the quick brown '
890 'fox jumped over '
891 'a lazy dog')""")
Antoine Pitrou64c16c32013-03-23 20:30:39 +0100892 self.assertEqual(pprint.pformat({'a': 1, 'b': fox, 'c': 2},
Serhiy Storchakaa750ce32015-02-14 10:55:19 +0200893 width=25), """\
Antoine Pitrou64c16c32013-03-23 20:30:39 +0100894{'a': 1,
895 'b': 'the quick brown '
896 'fox jumped over '
897 'a lazy dog',
898 'c': 2}""")
899 # With some special characters
900 # - \n always triggers a new line in the pprint
901 # - \t and \n are escaped
902 # - non-ASCII is allowed
903 # - an apostrophe doesn't disrupt the pprint
904 special = "Portons dix bons \"whiskys\"\nà l'avocat goujat\t qui fumait au zoo"
Serhiy Storchakaa750ce32015-02-14 10:55:19 +0200905 self.assertEqual(pprint.pformat(special, width=68), repr(special))
906 self.assertEqual(pprint.pformat(special, width=31), """\
907('Portons dix bons "whiskys"\\n'
908 "à l'avocat goujat\\t qui "
909 'fumait au zoo')""")
910 self.assertEqual(pprint.pformat(special, width=20), """\
911('Portons dix bons '
912 '"whiskys"\\n'
Serhiy Storchakafe3dc372014-12-20 20:57:15 +0200913 "à l'avocat "
914 'goujat\\t qui '
915 'fumait au zoo')""")
Serhiy Storchakaa750ce32015-02-14 10:55:19 +0200916 self.assertEqual(pprint.pformat([[[[[special]]]]], width=35), """\
917[[[[['Portons dix bons "whiskys"\\n'
918 "à l'avocat goujat\\t qui "
919 'fumait au zoo']]]]]""")
920 self.assertEqual(pprint.pformat([[[[[special]]]]], width=25), """\
921[[[[['Portons dix bons '
922 '"whiskys"\\n'
923 "à l'avocat "
924 'goujat\\t qui '
925 'fumait au zoo']]]]]""")
926 self.assertEqual(pprint.pformat([[[[[special]]]]], width=23), """\
927[[[[['Portons dix '
928 'bons "whiskys"\\n'
929 "à l'avocat "
930 'goujat\\t qui '
931 'fumait au '
932 'zoo']]]]]""")
Antoine Pitrou64c16c32013-03-23 20:30:39 +0100933 # An unwrappable string is formatted as its repr
934 unwrappable = "x" * 100
935 self.assertEqual(pprint.pformat(unwrappable, width=80), repr(unwrappable))
936 self.assertEqual(pprint.pformat(''), "''")
937 # Check that the pprint is a usable repr
938 special *= 10
939 for width in range(3, 40):
940 formatted = pprint.pformat(special, width=width)
Serhiy Storchakafe3dc372014-12-20 20:57:15 +0200941 self.assertEqual(eval(formatted), special)
942 formatted = pprint.pformat([special] * 2, width=width)
943 self.assertEqual(eval(formatted), [special] * 2)
Antoine Pitrou64c16c32013-03-23 20:30:39 +0100944
Serhiy Storchaka7c411a42013-10-02 11:56:18 +0300945 def test_compact(self):
946 o = ([list(range(i * i)) for i in range(5)] +
947 [list(range(i)) for i in range(6)])
948 expected = """\
949[[], [0], [0, 1, 2, 3],
950 [0, 1, 2, 3, 4, 5, 6, 7, 8],
951 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
952 14, 15],
953 [], [0], [0, 1], [0, 1, 2], [0, 1, 2, 3],
954 [0, 1, 2, 3, 4]]"""
Serhiy Storchakaa750ce32015-02-14 10:55:19 +0200955 self.assertEqual(pprint.pformat(o, width=47, compact=True), expected)
956
957 def test_compact_width(self):
958 levels = 20
959 number = 10
960 o = [0] * number
961 for i in range(levels - 1):
962 o = [o]
963 for w in range(levels * 2 + 1, levels + 3 * number - 1):
964 lines = pprint.pformat(o, width=w, compact=True).splitlines()
965 maxwidth = max(map(len, lines))
966 self.assertLessEqual(maxwidth, w)
967 self.assertGreater(maxwidth, w - 3)
Serhiy Storchaka7c411a42013-10-02 11:56:18 +0300968
Serhiy Storchaka022f2032015-03-24 19:22:37 +0200969 def test_bytes_wrap(self):
970 self.assertEqual(pprint.pformat(b'', width=1), "b''")
971 self.assertEqual(pprint.pformat(b'abcd', width=1), "b'abcd'")
972 letters = b'abcdefghijklmnopqrstuvwxyz'
973 self.assertEqual(pprint.pformat(letters, width=29), repr(letters))
974 self.assertEqual(pprint.pformat(letters, width=19), """\
975(b'abcdefghijkl'
976 b'mnopqrstuvwxyz')""")
977 self.assertEqual(pprint.pformat(letters, width=18), """\
978(b'abcdefghijkl'
979 b'mnopqrstuvwx'
980 b'yz')""")
981 self.assertEqual(pprint.pformat(letters, width=16), """\
982(b'abcdefghijkl'
983 b'mnopqrstuvwx'
984 b'yz')""")
985 special = bytes(range(16))
986 self.assertEqual(pprint.pformat(special, width=61), repr(special))
987 self.assertEqual(pprint.pformat(special, width=48), """\
988(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b'
989 b'\\x0c\\r\\x0e\\x0f')""")
990 self.assertEqual(pprint.pformat(special, width=32), """\
991(b'\\x00\\x01\\x02\\x03'
992 b'\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b'
993 b'\\x0c\\r\\x0e\\x0f')""")
994 self.assertEqual(pprint.pformat(special, width=1), """\
995(b'\\x00\\x01\\x02\\x03'
996 b'\\x04\\x05\\x06\\x07'
997 b'\\x08\\t\\n\\x0b'
998 b'\\x0c\\r\\x0e\\x0f')""")
999 self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2},
1000 width=21), """\
1001{'a': 1,
1002 'b': b'abcdefghijkl'
1003 b'mnopqrstuvwx'
1004 b'yz',
1005 'c': 2}""")
1006 self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2},
1007 width=20), """\
1008{'a': 1,
1009 'b': b'abcdefgh'
1010 b'ijklmnop'
1011 b'qrstuvwxyz',
1012 'c': 2}""")
1013 self.assertEqual(pprint.pformat([[[[[[letters]]]]]], width=25), """\
1014[[[[[[b'abcdefghijklmnop'
1015 b'qrstuvwxyz']]]]]]""")
1016 self.assertEqual(pprint.pformat([[[[[[special]]]]]], width=41), """\
1017[[[[[[b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07'
1018 b'\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f']]]]]]""")
1019 # Check that the pprint is a usable repr
1020 for width in range(1, 64):
1021 formatted = pprint.pformat(special, width=width)
1022 self.assertEqual(eval(formatted), special)
1023 formatted = pprint.pformat([special] * 2, width=width)
1024 self.assertEqual(eval(formatted), [special] * 2)
1025
1026 def test_bytearray_wrap(self):
1027 self.assertEqual(pprint.pformat(bytearray(), width=1), "bytearray(b'')")
1028 letters = bytearray(b'abcdefghijklmnopqrstuvwxyz')
1029 self.assertEqual(pprint.pformat(letters, width=40), repr(letters))
1030 self.assertEqual(pprint.pformat(letters, width=28), """\
1031bytearray(b'abcdefghijkl'
1032 b'mnopqrstuvwxyz')""")
1033 self.assertEqual(pprint.pformat(letters, width=27), """\
1034bytearray(b'abcdefghijkl'
1035 b'mnopqrstuvwx'
1036 b'yz')""")
1037 self.assertEqual(pprint.pformat(letters, width=25), """\
1038bytearray(b'abcdefghijkl'
1039 b'mnopqrstuvwx'
1040 b'yz')""")
1041 special = bytearray(range(16))
1042 self.assertEqual(pprint.pformat(special, width=72), repr(special))
1043 self.assertEqual(pprint.pformat(special, width=57), """\
1044bytearray(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b'
1045 b'\\x0c\\r\\x0e\\x0f')""")
1046 self.assertEqual(pprint.pformat(special, width=41), """\
1047bytearray(b'\\x00\\x01\\x02\\x03'
1048 b'\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b'
1049 b'\\x0c\\r\\x0e\\x0f')""")
1050 self.assertEqual(pprint.pformat(special, width=1), """\
1051bytearray(b'\\x00\\x01\\x02\\x03'
1052 b'\\x04\\x05\\x06\\x07'
1053 b'\\x08\\t\\n\\x0b'
1054 b'\\x0c\\r\\x0e\\x0f')""")
1055 self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2},
1056 width=31), """\
1057{'a': 1,
1058 'b': bytearray(b'abcdefghijkl'
1059 b'mnopqrstuvwx'
1060 b'yz'),
1061 'c': 2}""")
1062 self.assertEqual(pprint.pformat([[[[[letters]]]]], width=37), """\
1063[[[[[bytearray(b'abcdefghijklmnop'
1064 b'qrstuvwxyz')]]]]]""")
1065 self.assertEqual(pprint.pformat([[[[[special]]]]], width=50), """\
1066[[[[[bytearray(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07'
1067 b'\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f')]]]]]""")
1068
Serhiy Storchakabedbf962015-05-12 13:35:48 +03001069 def test_default_dict(self):
1070 d = collections.defaultdict(int)
Benjamin Petersonab078e92016-07-13 21:13:29 -07001071 self.assertEqual(pprint.pformat(d, width=1), "defaultdict(<class 'int'>, {})")
Serhiy Storchakabedbf962015-05-12 13:35:48 +03001072 words = 'the quick brown fox jumped over a lazy dog'.split()
1073 d = collections.defaultdict(int, zip(words, itertools.count()))
Benjamin Petersonab078e92016-07-13 21:13:29 -07001074 self.assertEqual(pprint.pformat(d),
1075"""\
1076defaultdict(<class 'int'>,
Serhiy Storchakabedbf962015-05-12 13:35:48 +03001077 {'a': 6,
1078 'brown': 2,
1079 'dog': 8,
1080 'fox': 3,
1081 'jumped': 4,
1082 'lazy': 7,
1083 'over': 5,
1084 'quick': 1,
Benjamin Petersonab078e92016-07-13 21:13:29 -07001085 'the': 0})""")
Serhiy Storchakabedbf962015-05-12 13:35:48 +03001086
1087 def test_counter(self):
1088 d = collections.Counter()
1089 self.assertEqual(pprint.pformat(d, width=1), "Counter()")
1090 d = collections.Counter('senselessness')
1091 self.assertEqual(pprint.pformat(d, width=40),
1092"""\
1093Counter({'s': 6,
1094 'e': 4,
1095 'n': 2,
1096 'l': 1})""")
1097
1098 def test_chainmap(self):
1099 d = collections.ChainMap()
1100 self.assertEqual(pprint.pformat(d, width=1), "ChainMap({})")
1101 words = 'the quick brown fox jumped over a lazy dog'.split()
1102 items = list(zip(words, itertools.count()))
1103 d = collections.ChainMap(dict(items))
1104 self.assertEqual(pprint.pformat(d),
1105"""\
1106ChainMap({'a': 6,
1107 'brown': 2,
1108 'dog': 8,
1109 'fox': 3,
1110 'jumped': 4,
1111 'lazy': 7,
1112 'over': 5,
1113 'quick': 1,
1114 'the': 0})""")
1115 d = collections.ChainMap(dict(items), collections.OrderedDict(items))
1116 self.assertEqual(pprint.pformat(d),
1117"""\
1118ChainMap({'a': 6,
1119 'brown': 2,
1120 'dog': 8,
1121 'fox': 3,
1122 'jumped': 4,
1123 'lazy': 7,
1124 'over': 5,
1125 'quick': 1,
1126 'the': 0},
1127 OrderedDict([('the', 0),
1128 ('quick', 1),
1129 ('brown', 2),
1130 ('fox', 3),
1131 ('jumped', 4),
1132 ('over', 5),
1133 ('a', 6),
1134 ('lazy', 7),
1135 ('dog', 8)]))""")
1136
1137 def test_deque(self):
1138 d = collections.deque()
1139 self.assertEqual(pprint.pformat(d, width=1), "deque([])")
1140 d = collections.deque(maxlen=7)
1141 self.assertEqual(pprint.pformat(d, width=1), "deque([], maxlen=7)")
1142 words = 'the quick brown fox jumped over a lazy dog'.split()
1143 d = collections.deque(zip(words, itertools.count()))
1144 self.assertEqual(pprint.pformat(d),
1145"""\
1146deque([('the', 0),
1147 ('quick', 1),
1148 ('brown', 2),
1149 ('fox', 3),
1150 ('jumped', 4),
1151 ('over', 5),
1152 ('a', 6),
1153 ('lazy', 7),
1154 ('dog', 8)])""")
1155 d = collections.deque(zip(words, itertools.count()), maxlen=7)
1156 self.assertEqual(pprint.pformat(d),
1157"""\
1158deque([('brown', 2),
1159 ('fox', 3),
1160 ('jumped', 4),
1161 ('over', 5),
1162 ('a', 6),
1163 ('lazy', 7),
1164 ('dog', 8)],
1165 maxlen=7)""")
1166
1167 def test_user_dict(self):
1168 d = collections.UserDict()
1169 self.assertEqual(pprint.pformat(d, width=1), "{}")
1170 words = 'the quick brown fox jumped over a lazy dog'.split()
1171 d = collections.UserDict(zip(words, itertools.count()))
1172 self.assertEqual(pprint.pformat(d),
1173"""\
1174{'a': 6,
1175 'brown': 2,
1176 'dog': 8,
1177 'fox': 3,
1178 'jumped': 4,
1179 'lazy': 7,
1180 'over': 5,
1181 'quick': 1,
1182 'the': 0}""")
1183
Serhiy Storchaka265cee02015-10-29 09:52:20 +02001184 def test_user_list(self):
Serhiy Storchakabedbf962015-05-12 13:35:48 +03001185 d = collections.UserList()
1186 self.assertEqual(pprint.pformat(d, width=1), "[]")
1187 words = 'the quick brown fox jumped over a lazy dog'.split()
1188 d = collections.UserList(zip(words, itertools.count()))
1189 self.assertEqual(pprint.pformat(d),
1190"""\
1191[('the', 0),
1192 ('quick', 1),
1193 ('brown', 2),
1194 ('fox', 3),
1195 ('jumped', 4),
1196 ('over', 5),
1197 ('a', 6),
1198 ('lazy', 7),
1199 ('dog', 8)]""")
1200
1201 def test_user_string(self):
1202 d = collections.UserString('')
1203 self.assertEqual(pprint.pformat(d, width=1), "''")
1204 d = collections.UserString('the quick brown fox jumped over a lazy dog')
1205 self.assertEqual(pprint.pformat(d, width=20),
1206"""\
1207('the quick brown '
1208 'fox jumped over '
1209 'a lazy dog')""")
1210 self.assertEqual(pprint.pformat({1: d}, width=20),
1211"""\
1212{1: 'the quick '
1213 'brown fox '
1214 'jumped over a '
1215 'lazy dog'}""")
1216
Florent Xiclunad6da90f2012-07-21 11:17:38 +02001217
Fred Drakeaee113d2002-04-02 05:08:35 +00001218class DottedPrettyPrinter(pprint.PrettyPrinter):
Guido van Rossum32c2ae72002-08-22 19:45:32 +00001219
Fred Drakeaee113d2002-04-02 05:08:35 +00001220 def format(self, object, context, maxlevels, level):
1221 if isinstance(object, str):
1222 if ' ' in object:
Walter Dörwald70a6b492004-02-12 17:35:32 +00001223 return repr(object), 1, 0
Fred Drakeaee113d2002-04-02 05:08:35 +00001224 else:
1225 return object, 0, 0
1226 else:
1227 return pprint.PrettyPrinter.format(
1228 self, object, context, maxlevels, level)
1229
1230
Fred Drake2e2be372001-09-20 21:33:42 +00001231if __name__ == "__main__":
Serhiy Storchakacbfe07e2015-05-20 19:37:10 +03001232 unittest.main()