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