1# -*- coding: utf-8 -*- 2 3import collections 4import io 5import itertools 6import pprint 7import random 8import test.support 9import test.test_set 10import types 11import unittest 12 13# list, tuple and dict subclasses that do or don't overwrite __repr__ 14class list2(list): 15 pass 16 17class list3(list): 18 def __repr__(self): 19 return list.__repr__(self) 20 21class tuple2(tuple): 22 pass 23 24class tuple3(tuple): 25 def __repr__(self): 26 return tuple.__repr__(self) 27 28class set2(set): 29 pass 30 31class set3(set): 32 def __repr__(self): 33 return set.__repr__(self) 34 35class frozenset2(frozenset): 36 pass 37 38class frozenset3(frozenset): 39 def __repr__(self): 40 return frozenset.__repr__(self) 41 42class dict2(dict): 43 pass 44 45class dict3(dict): 46 def __repr__(self): 47 return dict.__repr__(self) 48 49class Unorderable: 50 def __repr__(self): 51 return str(id(self)) 52 53# Class Orderable is orderable with any type 54class Orderable: 55 def __init__(self, hash): 56 self._hash = hash 57 def __lt__(self, other): 58 return False 59 def __gt__(self, other): 60 return self != other 61 def __le__(self, other): 62 return self == other 63 def __ge__(self, other): 64 return True 65 def __eq__(self, other): 66 return self is other 67 def __ne__(self, other): 68 return self is not other 69 def __hash__(self): 70 return self._hash 71 72class QueryTestCase(unittest.TestCase): 73 74 def setUp(self): 75 self.a = list(range(100)) 76 self.b = list(range(200)) 77 self.a[-12] = self.b 78 79 def test_init(self): 80 pp = pprint.PrettyPrinter() 81 pp = pprint.PrettyPrinter(indent=4, width=40, depth=5, 82 stream=io.StringIO(), compact=True) 83 pp = pprint.PrettyPrinter(4, 40, 5, io.StringIO()) 84 pp = pprint.PrettyPrinter(sort_dicts=False) 85 with self.assertRaises(TypeError): 86 pp = pprint.PrettyPrinter(4, 40, 5, io.StringIO(), True) 87 self.assertRaises(ValueError, pprint.PrettyPrinter, indent=-1) 88 self.assertRaises(ValueError, pprint.PrettyPrinter, depth=0) 89 self.assertRaises(ValueError, pprint.PrettyPrinter, depth=-1) 90 self.assertRaises(ValueError, pprint.PrettyPrinter, width=0) 91 92 def test_basic(self): 93 # Verify .isrecursive() and .isreadable() w/o recursion 94 pp = pprint.PrettyPrinter() 95 for safe in (2, 2.0, 2j, "abc", [3], (2,2), {3: 3}, b"def", 96 bytearray(b"ghi"), True, False, None, ..., 97 self.a, self.b): 98 # module-level convenience functions 99 self.assertFalse(pprint.isrecursive(safe), 100 "expected not isrecursive for %r" % (safe,)) 101 self.assertTrue(pprint.isreadable(safe), 102 "expected isreadable for %r" % (safe,)) 103 # PrettyPrinter methods 104 self.assertFalse(pp.isrecursive(safe), 105 "expected not isrecursive for %r" % (safe,)) 106 self.assertTrue(pp.isreadable(safe), 107 "expected isreadable for %r" % (safe,)) 108 109 def test_knotted(self): 110 # Verify .isrecursive() and .isreadable() w/ recursion 111 # Tie a knot. 112 self.b[67] = self.a 113 # Messy dict. 114 self.d = {} 115 self.d[0] = self.d[1] = self.d[2] = self.d 116 117 pp = pprint.PrettyPrinter() 118 119 for icky in self.a, self.b, self.d, (self.d, self.d): 120 self.assertTrue(pprint.isrecursive(icky), "expected isrecursive") 121 self.assertFalse(pprint.isreadable(icky), "expected not isreadable") 122 self.assertTrue(pp.isrecursive(icky), "expected isrecursive") 123 self.assertFalse(pp.isreadable(icky), "expected not isreadable") 124 125 # Break the cycles. 126 self.d.clear() 127 del self.a[:] 128 del self.b[:] 129 130 for safe in self.a, self.b, self.d, (self.d, self.d): 131 # module-level convenience functions 132 self.assertFalse(pprint.isrecursive(safe), 133 "expected not isrecursive for %r" % (safe,)) 134 self.assertTrue(pprint.isreadable(safe), 135 "expected isreadable for %r" % (safe,)) 136 # PrettyPrinter methods 137 self.assertFalse(pp.isrecursive(safe), 138 "expected not isrecursive for %r" % (safe,)) 139 self.assertTrue(pp.isreadable(safe), 140 "expected isreadable for %r" % (safe,)) 141 142 def test_unreadable(self): 143 # Not recursive but not readable anyway 144 pp = pprint.PrettyPrinter() 145 for unreadable in type(3), pprint, pprint.isrecursive: 146 # module-level convenience functions 147 self.assertFalse(pprint.isrecursive(unreadable), 148 "expected not isrecursive for %r" % (unreadable,)) 149 self.assertFalse(pprint.isreadable(unreadable), 150 "expected not isreadable for %r" % (unreadable,)) 151 # PrettyPrinter methods 152 self.assertFalse(pp.isrecursive(unreadable), 153 "expected not isrecursive for %r" % (unreadable,)) 154 self.assertFalse(pp.isreadable(unreadable), 155 "expected not isreadable for %r" % (unreadable,)) 156 157 def test_same_as_repr(self): 158 # Simple objects, small containers and classes that overwrite __repr__ 159 # For those the result should be the same as repr(). 160 # Ahem. The docs don't say anything about that -- this appears to 161 # be testing an implementation quirk. Starting in Python 2.5, it's 162 # not true for dicts: pprint always sorts dicts by key now; before, 163 # it sorted a dict display if and only if the display required 164 # multiple lines. For that reason, dicts with more than one element 165 # aren't tested here. 166 for simple in (0, 0, 0+0j, 0.0, "", b"", bytearray(), 167 (), tuple2(), tuple3(), 168 [], list2(), list3(), 169 set(), set2(), set3(), 170 frozenset(), frozenset2(), frozenset3(), 171 {}, dict2(), dict3(), 172 self.assertTrue, pprint, 173 -6, -6, -6-6j, -1.5, "x", b"x", bytearray(b"x"), 174 (3,), [3], {3: 6}, 175 (1,2), [3,4], {5: 6}, 176 tuple2((1,2)), tuple3((1,2)), tuple3(range(100)), 177 [3,4], list2([3,4]), list3([3,4]), list3(range(100)), 178 set({7}), set2({7}), set3({7}), 179 frozenset({8}), frozenset2({8}), frozenset3({8}), 180 dict2({5: 6}), dict3({5: 6}), 181 range(10, -11, -1), 182 True, False, None, ..., 183 ): 184 native = repr(simple) 185 self.assertEqual(pprint.pformat(simple), native) 186 self.assertEqual(pprint.pformat(simple, width=1, indent=0) 187 .replace('\n', ' '), native) 188 self.assertEqual(pprint.saferepr(simple), native) 189 190 def test_basic_line_wrap(self): 191 # verify basic line-wrapping operation 192 o = {'RPM_cal': 0, 193 'RPM_cal2': 48059, 194 'Speed_cal': 0, 195 'controldesk_runtime_us': 0, 196 'main_code_runtime_us': 0, 197 'read_io_runtime_us': 0, 198 'write_io_runtime_us': 43690} 199 exp = """\ 200{'RPM_cal': 0, 201 'RPM_cal2': 48059, 202 'Speed_cal': 0, 203 'controldesk_runtime_us': 0, 204 'main_code_runtime_us': 0, 205 'read_io_runtime_us': 0, 206 'write_io_runtime_us': 43690}""" 207 for type in [dict, dict2]: 208 self.assertEqual(pprint.pformat(type(o)), exp) 209 210 o = range(100) 211 exp = '[%s]' % ',\n '.join(map(str, o)) 212 for type in [list, list2]: 213 self.assertEqual(pprint.pformat(type(o)), exp) 214 215 o = tuple(range(100)) 216 exp = '(%s)' % ',\n '.join(map(str, o)) 217 for type in [tuple, tuple2]: 218 self.assertEqual(pprint.pformat(type(o)), exp) 219 220 # indent parameter 221 o = range(100) 222 exp = '[ %s]' % ',\n '.join(map(str, o)) 223 for type in [list, list2]: 224 self.assertEqual(pprint.pformat(type(o), indent=4), exp) 225 226 def test_nested_indentations(self): 227 o1 = list(range(10)) 228 o2 = dict(first=1, second=2, third=3) 229 o = [o1, o2] 230 expected = """\ 231[ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 232 {'first': 1, 'second': 2, 'third': 3}]""" 233 self.assertEqual(pprint.pformat(o, indent=4, width=42), expected) 234 expected = """\ 235[ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 236 { 'first': 1, 237 'second': 2, 238 'third': 3}]""" 239 self.assertEqual(pprint.pformat(o, indent=4, width=41), expected) 240 241 def test_width(self): 242 expected = """\ 243[[[[[[1, 2, 3], 244 '1 2']]]], 245 {1: [1, 2, 3], 246 2: [12, 34]}, 247 'abc def ghi', 248 ('ab cd ef',), 249 set2({1, 23}), 250 [[[[[1, 2, 3], 251 '1 2']]]]]""" 252 o = eval(expected) 253 self.assertEqual(pprint.pformat(o, width=15), expected) 254 self.assertEqual(pprint.pformat(o, width=16), expected) 255 self.assertEqual(pprint.pformat(o, width=25), expected) 256 self.assertEqual(pprint.pformat(o, width=14), """\ 257[[[[[[1, 258 2, 259 3], 260 '1 ' 261 '2']]]], 262 {1: [1, 263 2, 264 3], 265 2: [12, 266 34]}, 267 'abc def ' 268 'ghi', 269 ('ab cd ' 270 'ef',), 271 set2({1, 272 23}), 273 [[[[[1, 274 2, 275 3], 276 '1 ' 277 '2']]]]]""") 278 279 def test_sorted_dict(self): 280 # Starting in Python 2.5, pprint sorts dict displays by key regardless 281 # of how small the dictionary may be. 282 # Before the change, on 32-bit Windows pformat() gave order 283 # 'a', 'c', 'b' here, so this test failed. 284 d = {'a': 1, 'b': 1, 'c': 1} 285 self.assertEqual(pprint.pformat(d), "{'a': 1, 'b': 1, 'c': 1}") 286 self.assertEqual(pprint.pformat([d, d]), 287 "[{'a': 1, 'b': 1, 'c': 1}, {'a': 1, 'b': 1, 'c': 1}]") 288 289 # The next one is kind of goofy. The sorted order depends on the 290 # alphabetic order of type names: "int" < "str" < "tuple". Before 291 # Python 2.5, this was in the test_same_as_repr() test. It's worth 292 # keeping around for now because it's one of few tests of pprint 293 # against a crazy mix of types. 294 self.assertEqual(pprint.pformat({"xy\tab\n": (3,), 5: [[]], (): {}}), 295 r"{5: [[]], 'xy\tab\n': (3,), (): {}}") 296 297 def test_sort_dict(self): 298 d = dict.fromkeys('cba') 299 self.assertEqual(pprint.pformat(d, sort_dicts=False), "{'c': None, 'b': None, 'a': None}") 300 self.assertEqual(pprint.pformat([d, d], sort_dicts=False), 301 "[{'c': None, 'b': None, 'a': None}, {'c': None, 'b': None, 'a': None}]") 302 303 def test_ordered_dict(self): 304 d = collections.OrderedDict() 305 self.assertEqual(pprint.pformat(d, width=1), 'OrderedDict()') 306 d = collections.OrderedDict([]) 307 self.assertEqual(pprint.pformat(d, width=1), 'OrderedDict()') 308 words = 'the quick brown fox jumped over a lazy dog'.split() 309 d = collections.OrderedDict(zip(words, itertools.count())) 310 self.assertEqual(pprint.pformat(d), 311"""\ 312OrderedDict([('the', 0), 313 ('quick', 1), 314 ('brown', 2), 315 ('fox', 3), 316 ('jumped', 4), 317 ('over', 5), 318 ('a', 6), 319 ('lazy', 7), 320 ('dog', 8)])""") 321 322 def test_mapping_proxy(self): 323 words = 'the quick brown fox jumped over a lazy dog'.split() 324 d = dict(zip(words, itertools.count())) 325 m = types.MappingProxyType(d) 326 self.assertEqual(pprint.pformat(m), """\ 327mappingproxy({'a': 6, 328 'brown': 2, 329 'dog': 8, 330 'fox': 3, 331 'jumped': 4, 332 'lazy': 7, 333 'over': 5, 334 'quick': 1, 335 'the': 0})""") 336 d = collections.OrderedDict(zip(words, itertools.count())) 337 m = types.MappingProxyType(d) 338 self.assertEqual(pprint.pformat(m), """\ 339mappingproxy(OrderedDict([('the', 0), 340 ('quick', 1), 341 ('brown', 2), 342 ('fox', 3), 343 ('jumped', 4), 344 ('over', 5), 345 ('a', 6), 346 ('lazy', 7), 347 ('dog', 8)]))""") 348 349 def test_subclassing(self): 350 o = {'names with spaces': 'should be presented using repr()', 351 'others.should.not.be': 'like.this'} 352 exp = """\ 353{'names with spaces': 'should be presented using repr()', 354 others.should.not.be: like.this}""" 355 self.assertEqual(DottedPrettyPrinter().pformat(o), exp) 356 357 def test_set_reprs(self): 358 self.assertEqual(pprint.pformat(set()), 'set()') 359 self.assertEqual(pprint.pformat(set(range(3))), '{0, 1, 2}') 360 self.assertEqual(pprint.pformat(set(range(7)), width=20), '''\ 361{0, 362 1, 363 2, 364 3, 365 4, 366 5, 367 6}''') 368 self.assertEqual(pprint.pformat(set2(range(7)), width=20), '''\ 369set2({0, 370 1, 371 2, 372 3, 373 4, 374 5, 375 6})''') 376 self.assertEqual(pprint.pformat(set3(range(7)), width=20), 377 'set3({0, 1, 2, 3, 4, 5, 6})') 378 379 self.assertEqual(pprint.pformat(frozenset()), 'frozenset()') 380 self.assertEqual(pprint.pformat(frozenset(range(3))), 381 'frozenset({0, 1, 2})') 382 self.assertEqual(pprint.pformat(frozenset(range(7)), width=20), '''\ 383frozenset({0, 384 1, 385 2, 386 3, 387 4, 388 5, 389 6})''') 390 self.assertEqual(pprint.pformat(frozenset2(range(7)), width=20), '''\ 391frozenset2({0, 392 1, 393 2, 394 3, 395 4, 396 5, 397 6})''') 398 self.assertEqual(pprint.pformat(frozenset3(range(7)), width=20), 399 'frozenset3({0, 1, 2, 3, 4, 5, 6})') 400 401 @unittest.expectedFailure 402 #See http://bugs.python.org/issue13907 403 @test.support.cpython_only 404 def test_set_of_sets_reprs(self): 405 # This test creates a complex arrangement of frozensets and 406 # compares the pretty-printed repr against a string hard-coded in 407 # the test. The hard-coded repr depends on the sort order of 408 # frozensets. 409 # 410 # However, as the docs point out: "Since sets only define 411 # partial ordering (subset relationships), the output of the 412 # list.sort() method is undefined for lists of sets." 413 # 414 # In a nutshell, the test assumes frozenset({0}) will always 415 # sort before frozenset({1}), but: 416 # 417 # >>> frozenset({0}) < frozenset({1}) 418 # False 419 # >>> frozenset({1}) < frozenset({0}) 420 # False 421 # 422 # Consequently, this test is fragile and 423 # implementation-dependent. Small changes to Python's sort 424 # algorithm cause the test to fail when it should pass. 425 # XXX Or changes to the dictionary implmentation... 426 427 cube_repr_tgt = """\ 428{frozenset(): frozenset({frozenset({2}), frozenset({0}), frozenset({1})}), 429 frozenset({0}): frozenset({frozenset(), 430 frozenset({0, 2}), 431 frozenset({0, 1})}), 432 frozenset({1}): frozenset({frozenset(), 433 frozenset({1, 2}), 434 frozenset({0, 1})}), 435 frozenset({2}): frozenset({frozenset(), 436 frozenset({1, 2}), 437 frozenset({0, 2})}), 438 frozenset({1, 2}): frozenset({frozenset({2}), 439 frozenset({1}), 440 frozenset({0, 1, 2})}), 441 frozenset({0, 2}): frozenset({frozenset({2}), 442 frozenset({0}), 443 frozenset({0, 1, 2})}), 444 frozenset({0, 1}): frozenset({frozenset({0}), 445 frozenset({1}), 446 frozenset({0, 1, 2})}), 447 frozenset({0, 1, 2}): frozenset({frozenset({1, 2}), 448 frozenset({0, 2}), 449 frozenset({0, 1})})}""" 450 cube = test.test_set.cube(3) 451 self.assertEqual(pprint.pformat(cube), cube_repr_tgt) 452 cubo_repr_tgt = """\ 453{frozenset({frozenset({0, 2}), frozenset({0})}): frozenset({frozenset({frozenset({0, 454 2}), 455 frozenset({0, 456 1, 457 2})}), 458 frozenset({frozenset({0}), 459 frozenset({0, 460 1})}), 461 frozenset({frozenset(), 462 frozenset({0})}), 463 frozenset({frozenset({2}), 464 frozenset({0, 465 2})})}), 466 frozenset({frozenset({0, 1}), frozenset({1})}): frozenset({frozenset({frozenset({0, 467 1}), 468 frozenset({0, 469 1, 470 2})}), 471 frozenset({frozenset({0}), 472 frozenset({0, 473 1})}), 474 frozenset({frozenset({1}), 475 frozenset({1, 476 2})}), 477 frozenset({frozenset(), 478 frozenset({1})})}), 479 frozenset({frozenset({1, 2}), frozenset({1})}): frozenset({frozenset({frozenset({1, 480 2}), 481 frozenset({0, 482 1, 483 2})}), 484 frozenset({frozenset({2}), 485 frozenset({1, 486 2})}), 487 frozenset({frozenset(), 488 frozenset({1})}), 489 frozenset({frozenset({1}), 490 frozenset({0, 491 1})})}), 492 frozenset({frozenset({1, 2}), frozenset({2})}): frozenset({frozenset({frozenset({1, 493 2}), 494 frozenset({0, 495 1, 496 2})}), 497 frozenset({frozenset({1}), 498 frozenset({1, 499 2})}), 500 frozenset({frozenset({2}), 501 frozenset({0, 502 2})}), 503 frozenset({frozenset(), 504 frozenset({2})})}), 505 frozenset({frozenset(), frozenset({0})}): frozenset({frozenset({frozenset({0}), 506 frozenset({0, 507 1})}), 508 frozenset({frozenset({0}), 509 frozenset({0, 510 2})}), 511 frozenset({frozenset(), 512 frozenset({1})}), 513 frozenset({frozenset(), 514 frozenset({2})})}), 515 frozenset({frozenset(), frozenset({1})}): frozenset({frozenset({frozenset(), 516 frozenset({0})}), 517 frozenset({frozenset({1}), 518 frozenset({1, 519 2})}), 520 frozenset({frozenset(), 521 frozenset({2})}), 522 frozenset({frozenset({1}), 523 frozenset({0, 524 1})})}), 525 frozenset({frozenset({2}), frozenset()}): frozenset({frozenset({frozenset({2}), 526 frozenset({1, 527 2})}), 528 frozenset({frozenset(), 529 frozenset({0})}), 530 frozenset({frozenset(), 531 frozenset({1})}), 532 frozenset({frozenset({2}), 533 frozenset({0, 534 2})})}), 535 frozenset({frozenset({0, 1, 2}), frozenset({0, 1})}): frozenset({frozenset({frozenset({1, 536 2}), 537 frozenset({0, 538 1, 539 2})}), 540 frozenset({frozenset({0, 541 2}), 542 frozenset({0, 543 1, 544 2})}), 545 frozenset({frozenset({0}), 546 frozenset({0, 547 1})}), 548 frozenset({frozenset({1}), 549 frozenset({0, 550 1})})}), 551 frozenset({frozenset({0}), frozenset({0, 1})}): frozenset({frozenset({frozenset(), 552 frozenset({0})}), 553 frozenset({frozenset({0, 554 1}), 555 frozenset({0, 556 1, 557 2})}), 558 frozenset({frozenset({0}), 559 frozenset({0, 560 2})}), 561 frozenset({frozenset({1}), 562 frozenset({0, 563 1})})}), 564 frozenset({frozenset({2}), frozenset({0, 2})}): frozenset({frozenset({frozenset({0, 565 2}), 566 frozenset({0, 567 1, 568 2})}), 569 frozenset({frozenset({2}), 570 frozenset({1, 571 2})}), 572 frozenset({frozenset({0}), 573 frozenset({0, 574 2})}), 575 frozenset({frozenset(), 576 frozenset({2})})}), 577 frozenset({frozenset({0, 1, 2}), frozenset({0, 2})}): frozenset({frozenset({frozenset({1, 578 2}), 579 frozenset({0, 580 1, 581 2})}), 582 frozenset({frozenset({0, 583 1}), 584 frozenset({0, 585 1, 586 2})}), 587 frozenset({frozenset({0}), 588 frozenset({0, 589 2})}), 590 frozenset({frozenset({2}), 591 frozenset({0, 592 2})})}), 593 frozenset({frozenset({1, 2}), frozenset({0, 1, 2})}): frozenset({frozenset({frozenset({0, 594 2}), 595 frozenset({0, 596 1, 597 2})}), 598 frozenset({frozenset({0, 599 1}), 600 frozenset({0, 601 1, 602 2})}), 603 frozenset({frozenset({2}), 604 frozenset({1, 605 2})}), 606 frozenset({frozenset({1}), 607 frozenset({1, 608 2})})})}""" 609 610 cubo = test.test_set.linegraph(cube) 611 self.assertEqual(pprint.pformat(cubo), cubo_repr_tgt) 612 613 def test_depth(self): 614 nested_tuple = (1, (2, (3, (4, (5, 6))))) 615 nested_dict = {1: {2: {3: {4: {5: {6: 6}}}}}} 616 nested_list = [1, [2, [3, [4, [5, [6, []]]]]]] 617 self.assertEqual(pprint.pformat(nested_tuple), repr(nested_tuple)) 618 self.assertEqual(pprint.pformat(nested_dict), repr(nested_dict)) 619 self.assertEqual(pprint.pformat(nested_list), repr(nested_list)) 620 621 lv1_tuple = '(1, (...))' 622 lv1_dict = '{1: {...}}' 623 lv1_list = '[1, [...]]' 624 self.assertEqual(pprint.pformat(nested_tuple, depth=1), lv1_tuple) 625 self.assertEqual(pprint.pformat(nested_dict, depth=1), lv1_dict) 626 self.assertEqual(pprint.pformat(nested_list, depth=1), lv1_list) 627 628 def test_sort_unorderable_values(self): 629 # Issue 3976: sorted pprints fail for unorderable values. 630 n = 20 631 keys = [Unorderable() for i in range(n)] 632 random.shuffle(keys) 633 skeys = sorted(keys, key=id) 634 clean = lambda s: s.replace(' ', '').replace('\n','') 635 636 self.assertEqual(clean(pprint.pformat(set(keys))), 637 '{' + ','.join(map(repr, skeys)) + '}') 638 self.assertEqual(clean(pprint.pformat(frozenset(keys))), 639 'frozenset({' + ','.join(map(repr, skeys)) + '})') 640 self.assertEqual(clean(pprint.pformat(dict.fromkeys(keys))), 641 '{' + ','.join('%r:None' % k for k in skeys) + '}') 642 643 # Issue 10017: TypeError on user-defined types as dict keys. 644 self.assertEqual(pprint.pformat({Unorderable: 0, 1: 0}), 645 '{1: 0, ' + repr(Unorderable) +': 0}') 646 647 # Issue 14998: TypeError on tuples with NoneTypes as dict keys. 648 keys = [(1,), (None,)] 649 self.assertEqual(pprint.pformat(dict.fromkeys(keys, 0)), 650 '{%r: 0, %r: 0}' % tuple(sorted(keys, key=id))) 651 652 def test_sort_orderable_and_unorderable_values(self): 653 # Issue 22721: sorted pprints is not stable 654 a = Unorderable() 655 b = Orderable(hash(a)) # should have the same hash value 656 # self-test 657 self.assertLess(a, b) 658 self.assertLess(str(type(b)), str(type(a))) 659 self.assertEqual(sorted([b, a]), [a, b]) 660 self.assertEqual(sorted([a, b]), [a, b]) 661 # set 662 self.assertEqual(pprint.pformat(set([b, a]), width=1), 663 '{%r,\n %r}' % (a, b)) 664 self.assertEqual(pprint.pformat(set([a, b]), width=1), 665 '{%r,\n %r}' % (a, b)) 666 # dict 667 self.assertEqual(pprint.pformat(dict.fromkeys([b, a]), width=1), 668 '{%r: None,\n %r: None}' % (a, b)) 669 self.assertEqual(pprint.pformat(dict.fromkeys([a, b]), width=1), 670 '{%r: None,\n %r: None}' % (a, b)) 671 672 def test_str_wrap(self): 673 # pprint tries to wrap strings intelligently 674 fox = 'the quick brown fox jumped over a lazy dog' 675 self.assertEqual(pprint.pformat(fox, width=19), """\ 676('the quick brown ' 677 'fox jumped over ' 678 'a lazy dog')""") 679 self.assertEqual(pprint.pformat({'a': 1, 'b': fox, 'c': 2}, 680 width=25), """\ 681{'a': 1, 682 'b': 'the quick brown ' 683 'fox jumped over ' 684 'a lazy dog', 685 'c': 2}""") 686 # With some special characters 687 # - \n always triggers a new line in the pprint 688 # - \t and \n are escaped 689 # - non-ASCII is allowed 690 # - an apostrophe doesn't disrupt the pprint 691 special = "Portons dix bons \"whiskys\"\nà l'avocat goujat\t qui fumait au zoo" 692 self.assertEqual(pprint.pformat(special, width=68), repr(special)) 693 self.assertEqual(pprint.pformat(special, width=31), """\ 694('Portons dix bons "whiskys"\\n' 695 "à l'avocat goujat\\t qui " 696 'fumait au zoo')""") 697 self.assertEqual(pprint.pformat(special, width=20), """\ 698('Portons dix bons ' 699 '"whiskys"\\n' 700 "à l'avocat " 701 'goujat\\t qui ' 702 'fumait au zoo')""") 703 self.assertEqual(pprint.pformat([[[[[special]]]]], width=35), """\ 704[[[[['Portons dix bons "whiskys"\\n' 705 "à l'avocat goujat\\t qui " 706 'fumait au zoo']]]]]""") 707 self.assertEqual(pprint.pformat([[[[[special]]]]], width=25), """\ 708[[[[['Portons dix bons ' 709 '"whiskys"\\n' 710 "à l'avocat " 711 'goujat\\t qui ' 712 'fumait au zoo']]]]]""") 713 self.assertEqual(pprint.pformat([[[[[special]]]]], width=23), """\ 714[[[[['Portons dix ' 715 'bons "whiskys"\\n' 716 "à l'avocat " 717 'goujat\\t qui ' 718 'fumait au ' 719 'zoo']]]]]""") 720 # An unwrappable string is formatted as its repr 721 unwrappable = "x" * 100 722 self.assertEqual(pprint.pformat(unwrappable, width=80), repr(unwrappable)) 723 self.assertEqual(pprint.pformat(''), "''") 724 # Check that the pprint is a usable repr 725 special *= 10 726 for width in range(3, 40): 727 formatted = pprint.pformat(special, width=width) 728 self.assertEqual(eval(formatted), special) 729 formatted = pprint.pformat([special] * 2, width=width) 730 self.assertEqual(eval(formatted), [special] * 2) 731 732 def test_compact(self): 733 o = ([list(range(i * i)) for i in range(5)] + 734 [list(range(i)) for i in range(6)]) 735 expected = """\ 736[[], [0], [0, 1, 2, 3], 737 [0, 1, 2, 3, 4, 5, 6, 7, 8], 738 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 739 14, 15], 740 [], [0], [0, 1], [0, 1, 2], [0, 1, 2, 3], 741 [0, 1, 2, 3, 4]]""" 742 self.assertEqual(pprint.pformat(o, width=47, compact=True), expected) 743 744 def test_compact_width(self): 745 levels = 20 746 number = 10 747 o = [0] * number 748 for i in range(levels - 1): 749 o = [o] 750 for w in range(levels * 2 + 1, levels + 3 * number - 1): 751 lines = pprint.pformat(o, width=w, compact=True).splitlines() 752 maxwidth = max(map(len, lines)) 753 self.assertLessEqual(maxwidth, w) 754 self.assertGreater(maxwidth, w - 3) 755 756 def test_bytes_wrap(self): 757 self.assertEqual(pprint.pformat(b'', width=1), "b''") 758 self.assertEqual(pprint.pformat(b'abcd', width=1), "b'abcd'") 759 letters = b'abcdefghijklmnopqrstuvwxyz' 760 self.assertEqual(pprint.pformat(letters, width=29), repr(letters)) 761 self.assertEqual(pprint.pformat(letters, width=19), """\ 762(b'abcdefghijkl' 763 b'mnopqrstuvwxyz')""") 764 self.assertEqual(pprint.pformat(letters, width=18), """\ 765(b'abcdefghijkl' 766 b'mnopqrstuvwx' 767 b'yz')""") 768 self.assertEqual(pprint.pformat(letters, width=16), """\ 769(b'abcdefghijkl' 770 b'mnopqrstuvwx' 771 b'yz')""") 772 special = bytes(range(16)) 773 self.assertEqual(pprint.pformat(special, width=61), repr(special)) 774 self.assertEqual(pprint.pformat(special, width=48), """\ 775(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b' 776 b'\\x0c\\r\\x0e\\x0f')""") 777 self.assertEqual(pprint.pformat(special, width=32), """\ 778(b'\\x00\\x01\\x02\\x03' 779 b'\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b' 780 b'\\x0c\\r\\x0e\\x0f')""") 781 self.assertEqual(pprint.pformat(special, width=1), """\ 782(b'\\x00\\x01\\x02\\x03' 783 b'\\x04\\x05\\x06\\x07' 784 b'\\x08\\t\\n\\x0b' 785 b'\\x0c\\r\\x0e\\x0f')""") 786 self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2}, 787 width=21), """\ 788{'a': 1, 789 'b': b'abcdefghijkl' 790 b'mnopqrstuvwx' 791 b'yz', 792 'c': 2}""") 793 self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2}, 794 width=20), """\ 795{'a': 1, 796 'b': b'abcdefgh' 797 b'ijklmnop' 798 b'qrstuvwxyz', 799 'c': 2}""") 800 self.assertEqual(pprint.pformat([[[[[[letters]]]]]], width=25), """\ 801[[[[[[b'abcdefghijklmnop' 802 b'qrstuvwxyz']]]]]]""") 803 self.assertEqual(pprint.pformat([[[[[[special]]]]]], width=41), """\ 804[[[[[[b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07' 805 b'\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f']]]]]]""") 806 # Check that the pprint is a usable repr 807 for width in range(1, 64): 808 formatted = pprint.pformat(special, width=width) 809 self.assertEqual(eval(formatted), special) 810 formatted = pprint.pformat([special] * 2, width=width) 811 self.assertEqual(eval(formatted), [special] * 2) 812 813 def test_bytearray_wrap(self): 814 self.assertEqual(pprint.pformat(bytearray(), width=1), "bytearray(b'')") 815 letters = bytearray(b'abcdefghijklmnopqrstuvwxyz') 816 self.assertEqual(pprint.pformat(letters, width=40), repr(letters)) 817 self.assertEqual(pprint.pformat(letters, width=28), """\ 818bytearray(b'abcdefghijkl' 819 b'mnopqrstuvwxyz')""") 820 self.assertEqual(pprint.pformat(letters, width=27), """\ 821bytearray(b'abcdefghijkl' 822 b'mnopqrstuvwx' 823 b'yz')""") 824 self.assertEqual(pprint.pformat(letters, width=25), """\ 825bytearray(b'abcdefghijkl' 826 b'mnopqrstuvwx' 827 b'yz')""") 828 special = bytearray(range(16)) 829 self.assertEqual(pprint.pformat(special, width=72), repr(special)) 830 self.assertEqual(pprint.pformat(special, width=57), """\ 831bytearray(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b' 832 b'\\x0c\\r\\x0e\\x0f')""") 833 self.assertEqual(pprint.pformat(special, width=41), """\ 834bytearray(b'\\x00\\x01\\x02\\x03' 835 b'\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b' 836 b'\\x0c\\r\\x0e\\x0f')""") 837 self.assertEqual(pprint.pformat(special, width=1), """\ 838bytearray(b'\\x00\\x01\\x02\\x03' 839 b'\\x04\\x05\\x06\\x07' 840 b'\\x08\\t\\n\\x0b' 841 b'\\x0c\\r\\x0e\\x0f')""") 842 self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2}, 843 width=31), """\ 844{'a': 1, 845 'b': bytearray(b'abcdefghijkl' 846 b'mnopqrstuvwx' 847 b'yz'), 848 'c': 2}""") 849 self.assertEqual(pprint.pformat([[[[[letters]]]]], width=37), """\ 850[[[[[bytearray(b'abcdefghijklmnop' 851 b'qrstuvwxyz')]]]]]""") 852 self.assertEqual(pprint.pformat([[[[[special]]]]], width=50), """\ 853[[[[[bytearray(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07' 854 b'\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f')]]]]]""") 855 856 def test_default_dict(self): 857 d = collections.defaultdict(int) 858 self.assertEqual(pprint.pformat(d, width=1), "defaultdict(<class 'int'>, {})") 859 words = 'the quick brown fox jumped over a lazy dog'.split() 860 d = collections.defaultdict(int, zip(words, itertools.count())) 861 self.assertEqual(pprint.pformat(d), 862"""\ 863defaultdict(<class 'int'>, 864 {'a': 6, 865 'brown': 2, 866 'dog': 8, 867 'fox': 3, 868 'jumped': 4, 869 'lazy': 7, 870 'over': 5, 871 'quick': 1, 872 'the': 0})""") 873 874 def test_counter(self): 875 d = collections.Counter() 876 self.assertEqual(pprint.pformat(d, width=1), "Counter()") 877 d = collections.Counter('senselessness') 878 self.assertEqual(pprint.pformat(d, width=40), 879"""\ 880Counter({'s': 6, 881 'e': 4, 882 'n': 2, 883 'l': 1})""") 884 885 def test_chainmap(self): 886 d = collections.ChainMap() 887 self.assertEqual(pprint.pformat(d, width=1), "ChainMap({})") 888 words = 'the quick brown fox jumped over a lazy dog'.split() 889 items = list(zip(words, itertools.count())) 890 d = collections.ChainMap(dict(items)) 891 self.assertEqual(pprint.pformat(d), 892"""\ 893ChainMap({'a': 6, 894 'brown': 2, 895 'dog': 8, 896 'fox': 3, 897 'jumped': 4, 898 'lazy': 7, 899 'over': 5, 900 'quick': 1, 901 'the': 0})""") 902 d = collections.ChainMap(dict(items), collections.OrderedDict(items)) 903 self.assertEqual(pprint.pformat(d), 904"""\ 905ChainMap({'a': 6, 906 'brown': 2, 907 'dog': 8, 908 'fox': 3, 909 'jumped': 4, 910 'lazy': 7, 911 'over': 5, 912 'quick': 1, 913 'the': 0}, 914 OrderedDict([('the', 0), 915 ('quick', 1), 916 ('brown', 2), 917 ('fox', 3), 918 ('jumped', 4), 919 ('over', 5), 920 ('a', 6), 921 ('lazy', 7), 922 ('dog', 8)]))""") 923 924 def test_deque(self): 925 d = collections.deque() 926 self.assertEqual(pprint.pformat(d, width=1), "deque([])") 927 d = collections.deque(maxlen=7) 928 self.assertEqual(pprint.pformat(d, width=1), "deque([], maxlen=7)") 929 words = 'the quick brown fox jumped over a lazy dog'.split() 930 d = collections.deque(zip(words, itertools.count())) 931 self.assertEqual(pprint.pformat(d), 932"""\ 933deque([('the', 0), 934 ('quick', 1), 935 ('brown', 2), 936 ('fox', 3), 937 ('jumped', 4), 938 ('over', 5), 939 ('a', 6), 940 ('lazy', 7), 941 ('dog', 8)])""") 942 d = collections.deque(zip(words, itertools.count()), maxlen=7) 943 self.assertEqual(pprint.pformat(d), 944"""\ 945deque([('brown', 2), 946 ('fox', 3), 947 ('jumped', 4), 948 ('over', 5), 949 ('a', 6), 950 ('lazy', 7), 951 ('dog', 8)], 952 maxlen=7)""") 953 954 def test_user_dict(self): 955 d = collections.UserDict() 956 self.assertEqual(pprint.pformat(d, width=1), "{}") 957 words = 'the quick brown fox jumped over a lazy dog'.split() 958 d = collections.UserDict(zip(words, itertools.count())) 959 self.assertEqual(pprint.pformat(d), 960"""\ 961{'a': 6, 962 'brown': 2, 963 'dog': 8, 964 'fox': 3, 965 'jumped': 4, 966 'lazy': 7, 967 'over': 5, 968 'quick': 1, 969 'the': 0}""") 970 971 def test_user_list(self): 972 d = collections.UserList() 973 self.assertEqual(pprint.pformat(d, width=1), "[]") 974 words = 'the quick brown fox jumped over a lazy dog'.split() 975 d = collections.UserList(zip(words, itertools.count())) 976 self.assertEqual(pprint.pformat(d), 977"""\ 978[('the', 0), 979 ('quick', 1), 980 ('brown', 2), 981 ('fox', 3), 982 ('jumped', 4), 983 ('over', 5), 984 ('a', 6), 985 ('lazy', 7), 986 ('dog', 8)]""") 987 988 def test_user_string(self): 989 d = collections.UserString('') 990 self.assertEqual(pprint.pformat(d, width=1), "''") 991 d = collections.UserString('the quick brown fox jumped over a lazy dog') 992 self.assertEqual(pprint.pformat(d, width=20), 993"""\ 994('the quick brown ' 995 'fox jumped over ' 996 'a lazy dog')""") 997 self.assertEqual(pprint.pformat({1: d}, width=20), 998"""\ 999{1: 'the quick ' 1000 'brown fox ' 1001 'jumped over a ' 1002 'lazy dog'}""") 1003 1004 1005class DottedPrettyPrinter(pprint.PrettyPrinter): 1006 1007 def format(self, object, context, maxlevels, level): 1008 if isinstance(object, str): 1009 if ' ' in object: 1010 return repr(object), 1, 0 1011 else: 1012 return object, 0, 0 1013 else: 1014 return pprint.PrettyPrinter.format( 1015 self, object, context, maxlevels, level) 1016 1017 1018if __name__ == "__main__": 1019 unittest.main() 1020