test_pprint.py 51 KB

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