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_empty_simple_namespace(self): 350 ns = types.SimpleNamespace() 351 formatted = pprint.pformat(ns) 352 self.assertEqual(formatted, "namespace()") 353 354 def test_small_simple_namespace(self): 355 ns = types.SimpleNamespace(a=1, b=2) 356 formatted = pprint.pformat(ns) 357 self.assertEqual(formatted, "namespace(a=1, b=2)") 358 359 def test_simple_namespace(self): 360 ns = types.SimpleNamespace( 361 the=0, 362 quick=1, 363 brown=2, 364 fox=3, 365 jumped=4, 366 over=5, 367 a=6, 368 lazy=7, 369 dog=8, 370 ) 371 formatted = pprint.pformat(ns, width=60) 372 self.assertEqual(formatted, """\ 373namespace(the=0, 374 quick=1, 375 brown=2, 376 fox=3, 377 jumped=4, 378 over=5, 379 a=6, 380 lazy=7, 381 dog=8)""") 382 383 def test_simple_namespace_subclass(self): 384 class AdvancedNamespace(types.SimpleNamespace): pass 385 ns = AdvancedNamespace( 386 the=0, 387 quick=1, 388 brown=2, 389 fox=3, 390 jumped=4, 391 over=5, 392 a=6, 393 lazy=7, 394 dog=8, 395 ) 396 formatted = pprint.pformat(ns, width=60) 397 self.assertEqual(formatted, """\ 398AdvancedNamespace(the=0, 399 quick=1, 400 brown=2, 401 fox=3, 402 jumped=4, 403 over=5, 404 a=6, 405 lazy=7, 406 dog=8)""") 407 408 def test_subclassing(self): 409 o = {'names with spaces': 'should be presented using repr()', 410 'others.should.not.be': 'like.this'} 411 exp = """\ 412{'names with spaces': 'should be presented using repr()', 413 others.should.not.be: like.this}""" 414 self.assertEqual(DottedPrettyPrinter().pformat(o), exp) 415 416 def test_set_reprs(self): 417 self.assertEqual(pprint.pformat(set()), 'set()') 418 self.assertEqual(pprint.pformat(set(range(3))), '{0, 1, 2}') 419 self.assertEqual(pprint.pformat(set(range(7)), width=20), '''\ 420{0, 421 1, 422 2, 423 3, 424 4, 425 5, 426 6}''') 427 self.assertEqual(pprint.pformat(set2(range(7)), width=20), '''\ 428set2({0, 429 1, 430 2, 431 3, 432 4, 433 5, 434 6})''') 435 self.assertEqual(pprint.pformat(set3(range(7)), width=20), 436 'set3({0, 1, 2, 3, 4, 5, 6})') 437 438 self.assertEqual(pprint.pformat(frozenset()), 'frozenset()') 439 self.assertEqual(pprint.pformat(frozenset(range(3))), 440 'frozenset({0, 1, 2})') 441 self.assertEqual(pprint.pformat(frozenset(range(7)), width=20), '''\ 442frozenset({0, 443 1, 444 2, 445 3, 446 4, 447 5, 448 6})''') 449 self.assertEqual(pprint.pformat(frozenset2(range(7)), width=20), '''\ 450frozenset2({0, 451 1, 452 2, 453 3, 454 4, 455 5, 456 6})''') 457 self.assertEqual(pprint.pformat(frozenset3(range(7)), width=20), 458 'frozenset3({0, 1, 2, 3, 4, 5, 6})') 459 460 @unittest.expectedFailure 461 #See http://bugs.python.org/issue13907 462 @test.support.cpython_only 463 def test_set_of_sets_reprs(self): 464 # This test creates a complex arrangement of frozensets and 465 # compares the pretty-printed repr against a string hard-coded in 466 # the test. The hard-coded repr depends on the sort order of 467 # frozensets. 468 # 469 # However, as the docs point out: "Since sets only define 470 # partial ordering (subset relationships), the output of the 471 # list.sort() method is undefined for lists of sets." 472 # 473 # In a nutshell, the test assumes frozenset({0}) will always 474 # sort before frozenset({1}), but: 475 # 476 # >>> frozenset({0}) < frozenset({1}) 477 # False 478 # >>> frozenset({1}) < frozenset({0}) 479 # False 480 # 481 # Consequently, this test is fragile and 482 # implementation-dependent. Small changes to Python's sort 483 # algorithm cause the test to fail when it should pass. 484 # XXX Or changes to the dictionary implementation... 485 486 cube_repr_tgt = """\ 487{frozenset(): frozenset({frozenset({2}), frozenset({0}), frozenset({1})}), 488 frozenset({0}): frozenset({frozenset(), 489 frozenset({0, 2}), 490 frozenset({0, 1})}), 491 frozenset({1}): frozenset({frozenset(), 492 frozenset({1, 2}), 493 frozenset({0, 1})}), 494 frozenset({2}): frozenset({frozenset(), 495 frozenset({1, 2}), 496 frozenset({0, 2})}), 497 frozenset({1, 2}): frozenset({frozenset({2}), 498 frozenset({1}), 499 frozenset({0, 1, 2})}), 500 frozenset({0, 2}): frozenset({frozenset({2}), 501 frozenset({0}), 502 frozenset({0, 1, 2})}), 503 frozenset({0, 1}): frozenset({frozenset({0}), 504 frozenset({1}), 505 frozenset({0, 1, 2})}), 506 frozenset({0, 1, 2}): frozenset({frozenset({1, 2}), 507 frozenset({0, 2}), 508 frozenset({0, 1})})}""" 509 cube = test.test_set.cube(3) 510 self.assertEqual(pprint.pformat(cube), cube_repr_tgt) 511 cubo_repr_tgt = """\ 512{frozenset({frozenset({0, 2}), frozenset({0})}): frozenset({frozenset({frozenset({0, 513 2}), 514 frozenset({0, 515 1, 516 2})}), 517 frozenset({frozenset({0}), 518 frozenset({0, 519 1})}), 520 frozenset({frozenset(), 521 frozenset({0})}), 522 frozenset({frozenset({2}), 523 frozenset({0, 524 2})})}), 525 frozenset({frozenset({0, 1}), frozenset({1})}): frozenset({frozenset({frozenset({0, 526 1}), 527 frozenset({0, 528 1, 529 2})}), 530 frozenset({frozenset({0}), 531 frozenset({0, 532 1})}), 533 frozenset({frozenset({1}), 534 frozenset({1, 535 2})}), 536 frozenset({frozenset(), 537 frozenset({1})})}), 538 frozenset({frozenset({1, 2}), frozenset({1})}): frozenset({frozenset({frozenset({1, 539 2}), 540 frozenset({0, 541 1, 542 2})}), 543 frozenset({frozenset({2}), 544 frozenset({1, 545 2})}), 546 frozenset({frozenset(), 547 frozenset({1})}), 548 frozenset({frozenset({1}), 549 frozenset({0, 550 1})})}), 551 frozenset({frozenset({1, 2}), frozenset({2})}): frozenset({frozenset({frozenset({1, 552 2}), 553 frozenset({0, 554 1, 555 2})}), 556 frozenset({frozenset({1}), 557 frozenset({1, 558 2})}), 559 frozenset({frozenset({2}), 560 frozenset({0, 561 2})}), 562 frozenset({frozenset(), 563 frozenset({2})})}), 564 frozenset({frozenset(), frozenset({0})}): frozenset({frozenset({frozenset({0}), 565 frozenset({0, 566 1})}), 567 frozenset({frozenset({0}), 568 frozenset({0, 569 2})}), 570 frozenset({frozenset(), 571 frozenset({1})}), 572 frozenset({frozenset(), 573 frozenset({2})})}), 574 frozenset({frozenset(), frozenset({1})}): frozenset({frozenset({frozenset(), 575 frozenset({0})}), 576 frozenset({frozenset({1}), 577 frozenset({1, 578 2})}), 579 frozenset({frozenset(), 580 frozenset({2})}), 581 frozenset({frozenset({1}), 582 frozenset({0, 583 1})})}), 584 frozenset({frozenset({2}), frozenset()}): frozenset({frozenset({frozenset({2}), 585 frozenset({1, 586 2})}), 587 frozenset({frozenset(), 588 frozenset({0})}), 589 frozenset({frozenset(), 590 frozenset({1})}), 591 frozenset({frozenset({2}), 592 frozenset({0, 593 2})})}), 594 frozenset({frozenset({0, 1, 2}), frozenset({0, 1})}): frozenset({frozenset({frozenset({1, 595 2}), 596 frozenset({0, 597 1, 598 2})}), 599 frozenset({frozenset({0, 600 2}), 601 frozenset({0, 602 1, 603 2})}), 604 frozenset({frozenset({0}), 605 frozenset({0, 606 1})}), 607 frozenset({frozenset({1}), 608 frozenset({0, 609 1})})}), 610 frozenset({frozenset({0}), frozenset({0, 1})}): frozenset({frozenset({frozenset(), 611 frozenset({0})}), 612 frozenset({frozenset({0, 613 1}), 614 frozenset({0, 615 1, 616 2})}), 617 frozenset({frozenset({0}), 618 frozenset({0, 619 2})}), 620 frozenset({frozenset({1}), 621 frozenset({0, 622 1})})}), 623 frozenset({frozenset({2}), frozenset({0, 2})}): frozenset({frozenset({frozenset({0, 624 2}), 625 frozenset({0, 626 1, 627 2})}), 628 frozenset({frozenset({2}), 629 frozenset({1, 630 2})}), 631 frozenset({frozenset({0}), 632 frozenset({0, 633 2})}), 634 frozenset({frozenset(), 635 frozenset({2})})}), 636 frozenset({frozenset({0, 1, 2}), frozenset({0, 2})}): frozenset({frozenset({frozenset({1, 637 2}), 638 frozenset({0, 639 1, 640 2})}), 641 frozenset({frozenset({0, 642 1}), 643 frozenset({0, 644 1, 645 2})}), 646 frozenset({frozenset({0}), 647 frozenset({0, 648 2})}), 649 frozenset({frozenset({2}), 650 frozenset({0, 651 2})})}), 652 frozenset({frozenset({1, 2}), frozenset({0, 1, 2})}): frozenset({frozenset({frozenset({0, 653 2}), 654 frozenset({0, 655 1, 656 2})}), 657 frozenset({frozenset({0, 658 1}), 659 frozenset({0, 660 1, 661 2})}), 662 frozenset({frozenset({2}), 663 frozenset({1, 664 2})}), 665 frozenset({frozenset({1}), 666 frozenset({1, 667 2})})})}""" 668 669 cubo = test.test_set.linegraph(cube) 670 self.assertEqual(pprint.pformat(cubo), cubo_repr_tgt) 671 672 def test_depth(self): 673 nested_tuple = (1, (2, (3, (4, (5, 6))))) 674 nested_dict = {1: {2: {3: {4: {5: {6: 6}}}}}} 675 nested_list = [1, [2, [3, [4, [5, [6, []]]]]]] 676 self.assertEqual(pprint.pformat(nested_tuple), repr(nested_tuple)) 677 self.assertEqual(pprint.pformat(nested_dict), repr(nested_dict)) 678 self.assertEqual(pprint.pformat(nested_list), repr(nested_list)) 679 680 lv1_tuple = '(1, (...))' 681 lv1_dict = '{1: {...}}' 682 lv1_list = '[1, [...]]' 683 self.assertEqual(pprint.pformat(nested_tuple, depth=1), lv1_tuple) 684 self.assertEqual(pprint.pformat(nested_dict, depth=1), lv1_dict) 685 self.assertEqual(pprint.pformat(nested_list, depth=1), lv1_list) 686 687 def test_sort_unorderable_values(self): 688 # Issue 3976: sorted pprints fail for unorderable values. 689 n = 20 690 keys = [Unorderable() for i in range(n)] 691 random.shuffle(keys) 692 skeys = sorted(keys, key=id) 693 clean = lambda s: s.replace(' ', '').replace('\n','') 694 695 self.assertEqual(clean(pprint.pformat(set(keys))), 696 '{' + ','.join(map(repr, skeys)) + '}') 697 self.assertEqual(clean(pprint.pformat(frozenset(keys))), 698 'frozenset({' + ','.join(map(repr, skeys)) + '})') 699 self.assertEqual(clean(pprint.pformat(dict.fromkeys(keys))), 700 '{' + ','.join('%r:None' % k for k in skeys) + '}') 701 702 # Issue 10017: TypeError on user-defined types as dict keys. 703 self.assertEqual(pprint.pformat({Unorderable: 0, 1: 0}), 704 '{1: 0, ' + repr(Unorderable) +': 0}') 705 706 # Issue 14998: TypeError on tuples with NoneTypes as dict keys. 707 keys = [(1,), (None,)] 708 self.assertEqual(pprint.pformat(dict.fromkeys(keys, 0)), 709 '{%r: 0, %r: 0}' % tuple(sorted(keys, key=id))) 710 711 def test_sort_orderable_and_unorderable_values(self): 712 # Issue 22721: sorted pprints is not stable 713 a = Unorderable() 714 b = Orderable(hash(a)) # should have the same hash value 715 # self-test 716 self.assertLess(a, b) 717 self.assertLess(str(type(b)), str(type(a))) 718 self.assertEqual(sorted([b, a]), [a, b]) 719 self.assertEqual(sorted([a, b]), [a, b]) 720 # set 721 self.assertEqual(pprint.pformat(set([b, a]), width=1), 722 '{%r,\n %r}' % (a, b)) 723 self.assertEqual(pprint.pformat(set([a, b]), width=1), 724 '{%r,\n %r}' % (a, b)) 725 # dict 726 self.assertEqual(pprint.pformat(dict.fromkeys([b, a]), width=1), 727 '{%r: None,\n %r: None}' % (a, b)) 728 self.assertEqual(pprint.pformat(dict.fromkeys([a, b]), width=1), 729 '{%r: None,\n %r: None}' % (a, b)) 730 731 def test_str_wrap(self): 732 # pprint tries to wrap strings intelligently 733 fox = 'the quick brown fox jumped over a lazy dog' 734 self.assertEqual(pprint.pformat(fox, width=19), """\ 735('the quick brown ' 736 'fox jumped over ' 737 'a lazy dog')""") 738 self.assertEqual(pprint.pformat({'a': 1, 'b': fox, 'c': 2}, 739 width=25), """\ 740{'a': 1, 741 'b': 'the quick brown ' 742 'fox jumped over ' 743 'a lazy dog', 744 'c': 2}""") 745 # With some special characters 746 # - \n always triggers a new line in the pprint 747 # - \t and \n are escaped 748 # - non-ASCII is allowed 749 # - an apostrophe doesn't disrupt the pprint 750 special = "Portons dix bons \"whiskys\"\nà l'avocat goujat\t qui fumait au zoo" 751 self.assertEqual(pprint.pformat(special, width=68), repr(special)) 752 self.assertEqual(pprint.pformat(special, width=31), """\ 753('Portons dix bons "whiskys"\\n' 754 "à l'avocat goujat\\t qui " 755 'fumait au zoo')""") 756 self.assertEqual(pprint.pformat(special, width=20), """\ 757('Portons dix bons ' 758 '"whiskys"\\n' 759 "à l'avocat " 760 'goujat\\t qui ' 761 'fumait au zoo')""") 762 self.assertEqual(pprint.pformat([[[[[special]]]]], width=35), """\ 763[[[[['Portons dix bons "whiskys"\\n' 764 "à l'avocat goujat\\t qui " 765 'fumait au zoo']]]]]""") 766 self.assertEqual(pprint.pformat([[[[[special]]]]], width=25), """\ 767[[[[['Portons dix bons ' 768 '"whiskys"\\n' 769 "à l'avocat " 770 'goujat\\t qui ' 771 'fumait au zoo']]]]]""") 772 self.assertEqual(pprint.pformat([[[[[special]]]]], width=23), """\ 773[[[[['Portons dix ' 774 'bons "whiskys"\\n' 775 "à l'avocat " 776 'goujat\\t qui ' 777 'fumait au ' 778 'zoo']]]]]""") 779 # An unwrappable string is formatted as its repr 780 unwrappable = "x" * 100 781 self.assertEqual(pprint.pformat(unwrappable, width=80), repr(unwrappable)) 782 self.assertEqual(pprint.pformat(''), "''") 783 # Check that the pprint is a usable repr 784 special *= 10 785 for width in range(3, 40): 786 formatted = pprint.pformat(special, width=width) 787 self.assertEqual(eval(formatted), special) 788 formatted = pprint.pformat([special] * 2, width=width) 789 self.assertEqual(eval(formatted), [special] * 2) 790 791 def test_compact(self): 792 o = ([list(range(i * i)) for i in range(5)] + 793 [list(range(i)) for i in range(6)]) 794 expected = """\ 795[[], [0], [0, 1, 2, 3], 796 [0, 1, 2, 3, 4, 5, 6, 7, 8], 797 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 798 14, 15], 799 [], [0], [0, 1], [0, 1, 2], [0, 1, 2, 3], 800 [0, 1, 2, 3, 4]]""" 801 self.assertEqual(pprint.pformat(o, width=47, compact=True), expected) 802 803 def test_compact_width(self): 804 levels = 20 805 number = 10 806 o = [0] * number 807 for i in range(levels - 1): 808 o = [o] 809 for w in range(levels * 2 + 1, levels + 3 * number - 1): 810 lines = pprint.pformat(o, width=w, compact=True).splitlines() 811 maxwidth = max(map(len, lines)) 812 self.assertLessEqual(maxwidth, w) 813 self.assertGreater(maxwidth, w - 3) 814 815 def test_bytes_wrap(self): 816 self.assertEqual(pprint.pformat(b'', width=1), "b''") 817 self.assertEqual(pprint.pformat(b'abcd', width=1), "b'abcd'") 818 letters = b'abcdefghijklmnopqrstuvwxyz' 819 self.assertEqual(pprint.pformat(letters, width=29), repr(letters)) 820 self.assertEqual(pprint.pformat(letters, width=19), """\ 821(b'abcdefghijkl' 822 b'mnopqrstuvwxyz')""") 823 self.assertEqual(pprint.pformat(letters, width=18), """\ 824(b'abcdefghijkl' 825 b'mnopqrstuvwx' 826 b'yz')""") 827 self.assertEqual(pprint.pformat(letters, width=16), """\ 828(b'abcdefghijkl' 829 b'mnopqrstuvwx' 830 b'yz')""") 831 special = bytes(range(16)) 832 self.assertEqual(pprint.pformat(special, width=61), repr(special)) 833 self.assertEqual(pprint.pformat(special, width=48), """\ 834(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b' 835 b'\\x0c\\r\\x0e\\x0f')""") 836 self.assertEqual(pprint.pformat(special, width=32), """\ 837(b'\\x00\\x01\\x02\\x03' 838 b'\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b' 839 b'\\x0c\\r\\x0e\\x0f')""") 840 self.assertEqual(pprint.pformat(special, width=1), """\ 841(b'\\x00\\x01\\x02\\x03' 842 b'\\x04\\x05\\x06\\x07' 843 b'\\x08\\t\\n\\x0b' 844 b'\\x0c\\r\\x0e\\x0f')""") 845 self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2}, 846 width=21), """\ 847{'a': 1, 848 'b': b'abcdefghijkl' 849 b'mnopqrstuvwx' 850 b'yz', 851 'c': 2}""") 852 self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2}, 853 width=20), """\ 854{'a': 1, 855 'b': b'abcdefgh' 856 b'ijklmnop' 857 b'qrstuvwxyz', 858 'c': 2}""") 859 self.assertEqual(pprint.pformat([[[[[[letters]]]]]], width=25), """\ 860[[[[[[b'abcdefghijklmnop' 861 b'qrstuvwxyz']]]]]]""") 862 self.assertEqual(pprint.pformat([[[[[[special]]]]]], width=41), """\ 863[[[[[[b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07' 864 b'\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f']]]]]]""") 865 # Check that the pprint is a usable repr 866 for width in range(1, 64): 867 formatted = pprint.pformat(special, width=width) 868 self.assertEqual(eval(formatted), special) 869 formatted = pprint.pformat([special] * 2, width=width) 870 self.assertEqual(eval(formatted), [special] * 2) 871 872 def test_bytearray_wrap(self): 873 self.assertEqual(pprint.pformat(bytearray(), width=1), "bytearray(b'')") 874 letters = bytearray(b'abcdefghijklmnopqrstuvwxyz') 875 self.assertEqual(pprint.pformat(letters, width=40), repr(letters)) 876 self.assertEqual(pprint.pformat(letters, width=28), """\ 877bytearray(b'abcdefghijkl' 878 b'mnopqrstuvwxyz')""") 879 self.assertEqual(pprint.pformat(letters, width=27), """\ 880bytearray(b'abcdefghijkl' 881 b'mnopqrstuvwx' 882 b'yz')""") 883 self.assertEqual(pprint.pformat(letters, width=25), """\ 884bytearray(b'abcdefghijkl' 885 b'mnopqrstuvwx' 886 b'yz')""") 887 special = bytearray(range(16)) 888 self.assertEqual(pprint.pformat(special, width=72), repr(special)) 889 self.assertEqual(pprint.pformat(special, width=57), """\ 890bytearray(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b' 891 b'\\x0c\\r\\x0e\\x0f')""") 892 self.assertEqual(pprint.pformat(special, width=41), """\ 893bytearray(b'\\x00\\x01\\x02\\x03' 894 b'\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b' 895 b'\\x0c\\r\\x0e\\x0f')""") 896 self.assertEqual(pprint.pformat(special, width=1), """\ 897bytearray(b'\\x00\\x01\\x02\\x03' 898 b'\\x04\\x05\\x06\\x07' 899 b'\\x08\\t\\n\\x0b' 900 b'\\x0c\\r\\x0e\\x0f')""") 901 self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2}, 902 width=31), """\ 903{'a': 1, 904 'b': bytearray(b'abcdefghijkl' 905 b'mnopqrstuvwx' 906 b'yz'), 907 'c': 2}""") 908 self.assertEqual(pprint.pformat([[[[[letters]]]]], width=37), """\ 909[[[[[bytearray(b'abcdefghijklmnop' 910 b'qrstuvwxyz')]]]]]""") 911 self.assertEqual(pprint.pformat([[[[[special]]]]], width=50), """\ 912[[[[[bytearray(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07' 913 b'\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f')]]]]]""") 914 915 def test_default_dict(self): 916 d = collections.defaultdict(int) 917 self.assertEqual(pprint.pformat(d, width=1), "defaultdict(<class 'int'>, {})") 918 words = 'the quick brown fox jumped over a lazy dog'.split() 919 d = collections.defaultdict(int, zip(words, itertools.count())) 920 self.assertEqual(pprint.pformat(d), 921"""\ 922defaultdict(<class 'int'>, 923 {'a': 6, 924 'brown': 2, 925 'dog': 8, 926 'fox': 3, 927 'jumped': 4, 928 'lazy': 7, 929 'over': 5, 930 'quick': 1, 931 'the': 0})""") 932 933 def test_counter(self): 934 d = collections.Counter() 935 self.assertEqual(pprint.pformat(d, width=1), "Counter()") 936 d = collections.Counter('senselessness') 937 self.assertEqual(pprint.pformat(d, width=40), 938"""\ 939Counter({'s': 6, 940 'e': 4, 941 'n': 2, 942 'l': 1})""") 943 944 def test_chainmap(self): 945 d = collections.ChainMap() 946 self.assertEqual(pprint.pformat(d, width=1), "ChainMap({})") 947 words = 'the quick brown fox jumped over a lazy dog'.split() 948 items = list(zip(words, itertools.count())) 949 d = collections.ChainMap(dict(items)) 950 self.assertEqual(pprint.pformat(d), 951"""\ 952ChainMap({'a': 6, 953 'brown': 2, 954 'dog': 8, 955 'fox': 3, 956 'jumped': 4, 957 'lazy': 7, 958 'over': 5, 959 'quick': 1, 960 'the': 0})""") 961 d = collections.ChainMap(dict(items), collections.OrderedDict(items)) 962 self.assertEqual(pprint.pformat(d), 963"""\ 964ChainMap({'a': 6, 965 'brown': 2, 966 'dog': 8, 967 'fox': 3, 968 'jumped': 4, 969 'lazy': 7, 970 'over': 5, 971 'quick': 1, 972 'the': 0}, 973 OrderedDict([('the', 0), 974 ('quick', 1), 975 ('brown', 2), 976 ('fox', 3), 977 ('jumped', 4), 978 ('over', 5), 979 ('a', 6), 980 ('lazy', 7), 981 ('dog', 8)]))""") 982 983 def test_deque(self): 984 d = collections.deque() 985 self.assertEqual(pprint.pformat(d, width=1), "deque([])") 986 d = collections.deque(maxlen=7) 987 self.assertEqual(pprint.pformat(d, width=1), "deque([], maxlen=7)") 988 words = 'the quick brown fox jumped over a lazy dog'.split() 989 d = collections.deque(zip(words, itertools.count())) 990 self.assertEqual(pprint.pformat(d), 991"""\ 992deque([('the', 0), 993 ('quick', 1), 994 ('brown', 2), 995 ('fox', 3), 996 ('jumped', 4), 997 ('over', 5), 998 ('a', 6), 999 ('lazy', 7), 1000 ('dog', 8)])""") 1001 d = collections.deque(zip(words, itertools.count()), maxlen=7) 1002 self.assertEqual(pprint.pformat(d), 1003"""\ 1004deque([('brown', 2), 1005 ('fox', 3), 1006 ('jumped', 4), 1007 ('over', 5), 1008 ('a', 6), 1009 ('lazy', 7), 1010 ('dog', 8)], 1011 maxlen=7)""") 1012 1013 def test_user_dict(self): 1014 d = collections.UserDict() 1015 self.assertEqual(pprint.pformat(d, width=1), "{}") 1016 words = 'the quick brown fox jumped over a lazy dog'.split() 1017 d = collections.UserDict(zip(words, itertools.count())) 1018 self.assertEqual(pprint.pformat(d), 1019"""\ 1020{'a': 6, 1021 'brown': 2, 1022 'dog': 8, 1023 'fox': 3, 1024 'jumped': 4, 1025 'lazy': 7, 1026 'over': 5, 1027 'quick': 1, 1028 'the': 0}""") 1029 1030 def test_user_list(self): 1031 d = collections.UserList() 1032 self.assertEqual(pprint.pformat(d, width=1), "[]") 1033 words = 'the quick brown fox jumped over a lazy dog'.split() 1034 d = collections.UserList(zip(words, itertools.count())) 1035 self.assertEqual(pprint.pformat(d), 1036"""\ 1037[('the', 0), 1038 ('quick', 1), 1039 ('brown', 2), 1040 ('fox', 3), 1041 ('jumped', 4), 1042 ('over', 5), 1043 ('a', 6), 1044 ('lazy', 7), 1045 ('dog', 8)]""") 1046 1047 def test_user_string(self): 1048 d = collections.UserString('') 1049 self.assertEqual(pprint.pformat(d, width=1), "''") 1050 d = collections.UserString('the quick brown fox jumped over a lazy dog') 1051 self.assertEqual(pprint.pformat(d, width=20), 1052"""\ 1053('the quick brown ' 1054 'fox jumped over ' 1055 'a lazy dog')""") 1056 self.assertEqual(pprint.pformat({1: d}, width=20), 1057"""\ 1058{1: 'the quick ' 1059 'brown fox ' 1060 'jumped over a ' 1061 'lazy dog'}""") 1062 1063 1064class DottedPrettyPrinter(pprint.PrettyPrinter): 1065 1066 def format(self, object, context, maxlevels, level): 1067 if isinstance(object, str): 1068 if ' ' in object: 1069 return repr(object), 1, 0 1070 else: 1071 return object, 0, 0 1072 else: 1073 return pprint.PrettyPrinter.format( 1074 self, object, context, maxlevels, level) 1075 1076 1077if __name__ == "__main__": 1078 unittest.main() 1079