1import pprint
2import test.support
3import unittest
4import test.test_set
5import random
6import collections
7import itertools
8
9from typing import List, Any, Dict, Tuple, cast, Callable
10
11# list, tuple and dict subclasses that do or don't overwrite __repr__
12class list2(list):
13    pass
14
15class list3(list):
16    def __repr__(self) -> str:
17        return list.__repr__(self)
18
19class tuple2(tuple):
20    pass
21
22class tuple3(tuple):
23    def __repr__(self) -> str:
24        return tuple.__repr__(self)
25
26class dict2(dict):
27    pass
28
29class dict3(dict):
30    def __repr__(self) -> str:
31        return dict.__repr__(self)
32
33class Unorderable:
34    def __repr__(self) -> str:
35        return str(id(self))
36
37class QueryTestCase(unittest.TestCase):
38
39    def setUp(self) -> None:
40        self.a = list(range(100))  # type: List[Any]
41        self.b = list(range(200))  # type: List[Any]
42        self.a[-12] = self.b
43
44    def test_basic(self) -> None:
45        # Verify .isrecursive() and .isreadable() w/o recursion
46        pp = pprint.PrettyPrinter()
47        for safe in (2, 2.0, complex(0.0, 2.0), "abc", [3], (2,2), {3: 3}, "yaddayadda",
48                     self.a, self.b):
49            # module-level convenience functions
50            self.assertFalse(pprint.isrecursive(safe),
51                             "expected not isrecursive for %r" % (safe,))
52            self.assertTrue(pprint.isreadable(safe),
53                            "expected isreadable for %r" % (safe,))
54            # PrettyPrinter methods
55            self.assertFalse(pp.isrecursive(safe),
56                             "expected not isrecursive for %r" % (safe,))
57            self.assertTrue(pp.isreadable(safe),
58                            "expected isreadable for %r" % (safe,))
59
60    def test_knotted(self) -> None:
61        # Verify .isrecursive() and .isreadable() w/ recursion
62        # Tie a knot.
63        self.b[67] = self.a
64        # Messy dict.
65        self.d = {}  # type: Dict[int, dict]
66        self.d[0] = self.d[1] = self.d[2] = self.d
67
68        pp = pprint.PrettyPrinter()
69
70        for icky in self.a, self.b, self.d, (self.d, self.d):
71            self.assertTrue(pprint.isrecursive(icky), "expected isrecursive")
72            self.assertFalse(pprint.isreadable(icky), "expected not isreadable")
73            self.assertTrue(pp.isrecursive(icky), "expected isrecursive")
74            self.assertFalse(pp.isreadable(icky), "expected not isreadable")
75
76        # Break the cycles.
77        self.d.clear()
78        del self.a[:]
79        del self.b[:]
80
81        for safe in self.a, self.b, self.d, (self.d, self.d):
82            # module-level convenience functions
83            self.assertFalse(pprint.isrecursive(safe),
84                             "expected not isrecursive for %r" % (safe,))
85            self.assertTrue(pprint.isreadable(safe),
86                            "expected isreadable for %r" % (safe,))
87            # PrettyPrinter methods
88            self.assertFalse(pp.isrecursive(safe),
89                             "expected not isrecursive for %r" % (safe,))
90            self.assertTrue(pp.isreadable(safe),
91                            "expected isreadable for %r" % (safe,))
92
93    def test_unreadable(self) -> None:
94        # Not recursive but not readable anyway
95        pp = pprint.PrettyPrinter()
96        for unreadable in type(3), pprint, pprint.isrecursive:
97            # module-level convenience functions
98            self.assertFalse(pprint.isrecursive(unreadable),
99                             "expected not isrecursive for %r" % (unreadable,))
100            self.assertFalse(pprint.isreadable(unreadable),
101                             "expected not isreadable for %r" % (unreadable,))
102            # PrettyPrinter methods
103            self.assertFalse(pp.isrecursive(unreadable),
104                             "expected not isrecursive for %r" % (unreadable,))
105            self.assertFalse(pp.isreadable(unreadable),
106                             "expected not isreadable for %r" % (unreadable,))
107
108    def test_same_as_repr(self) -> None:
109        # Simple objects, small containers and classes that overwrite __repr__
110        # For those the result should be the same as repr().
111        # Ahem.  The docs don't say anything about that -- this appears to
112        # be testing an implementation quirk.  Starting in Python 2.5, it's
113        # not true for dicts:  pprint always sorts dicts by key now; before,
114        # it sorted a dict display if and only if the display required
115        # multiple lines.  For that reason, dicts with more than one element
116        # aren't tested here.
117        for simple in (0, 0, complex(0.0), 0.0, "", b"",
118                       (), tuple2(), tuple3(),
119                       [], list2(), list3(),
120                       {}, dict2(), dict3(),
121                       self.assertTrue, pprint,
122                       -6, -6, complex(-6.,-6.), -1.5, "x", b"x", (3,), [3], {3: 6},
123                       (1,2), [3,4], {5: 6},
124                       tuple2((1,2)), tuple3((1,2)), tuple3(range(100)),  # type: ignore
125                       [3,4], list2(cast(Any, [3,4])), list3(cast(Any, [3,4])),
126                       list3(cast(Any, range(100))), dict2(cast(Any, {5: 6})),
127                       dict3(cast(Any, {5: 6})), # JLe: work around mypy issue #233
128                       range(10, -11, -1)
129                      ):
130            native = repr(simple)
131            for function in "pformat", "saferepr":
132                f = getattr(pprint, function)
133                got = f(simple)
134                self.assertEqual(native, got,
135                                 "expected %s got %s from pprint.%s" %
136                                 (native, got, function))
137
138    def test_basic_line_wrap(self) -> None:
139        # verify basic line-wrapping operation
140        o = {'RPM_cal': 0,
141             'RPM_cal2': 48059,
142             'Speed_cal': 0,
143             'controldesk_runtime_us': 0,
144             'main_code_runtime_us': 0,
145             'read_io_runtime_us': 0,
146             'write_io_runtime_us': 43690}
147        exp = """\
148{'RPM_cal': 0,
149 'RPM_cal2': 48059,
150 'Speed_cal': 0,
151 'controldesk_runtime_us': 0,
152 'main_code_runtime_us': 0,
153 'read_io_runtime_us': 0,
154 'write_io_runtime_us': 43690}"""
155        # JLe: work around mypy issue #232
156        for type in cast(List[Any], [dict, dict2]):
157            self.assertEqual(pprint.pformat(type(o)), exp)
158
159        o2 = range(100)
160        exp = '[%s]' % ',\n '.join(map(str, o2))
161        for type in cast(List[Any], [list, list2]):
162            self.assertEqual(pprint.pformat(type(o2)), exp)
163
164        o3 = tuple(range(100))
165        exp = '(%s)' % ',\n '.join(map(str, o3))
166        for type in cast(List[Any], [tuple, tuple2]):
167            self.assertEqual(pprint.pformat(type(o3)), exp)
168
169        # indent parameter
170        o4 = range(100)
171        exp = '[   %s]' % ',\n    '.join(map(str, o4))
172        for type in cast(List[Any], [list, list2]):
173            self.assertEqual(pprint.pformat(type(o4), indent=4), exp)
174
175    def test_nested_indentations(self) -> None:
176        o1 = list(range(10))
177        o2 = {'first':1, 'second':2, 'third':3}
178        o = [o1, o2]
179        expected = """\
180[   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
181    {   'first': 1,
182        'second': 2,
183        'third': 3}]"""
184        self.assertEqual(pprint.pformat(o, indent=4, width=42), expected)
185
186    def test_sorted_dict(self) -> None:
187        # Starting in Python 2.5, pprint sorts dict displays by key regardless
188        # of how small the dictionary may be.
189        # Before the change, on 32-bit Windows pformat() gave order
190        # 'a', 'c', 'b' here, so this test failed.
191        d = {'a': 1, 'b': 1, 'c': 1}
192        self.assertEqual(pprint.pformat(d), "{'a': 1, 'b': 1, 'c': 1}")
193        self.assertEqual(pprint.pformat([d, d]),
194            "[{'a': 1, 'b': 1, 'c': 1}, {'a': 1, 'b': 1, 'c': 1}]")
195
196        # The next one is kind of goofy.  The sorted order depends on the
197        # alphabetic order of type names:  "int" < "str" < "tuple".  Before
198        # Python 2.5, this was in the test_same_as_repr() test.  It's worth
199        # keeping around for now because it's one of few tests of pprint
200        # against a crazy mix of types.
201        self.assertEqual(pprint.pformat({"xy\tab\n": (3,), 5: [[]], (): {}}),
202            r"{5: [[]], 'xy\tab\n': (3,), (): {}}")
203
204    def test_ordered_dict(self) -> None:
205        words = 'the quick brown fox jumped over a lazy dog'.split()
206        d = collections.OrderedDict(zip(words, itertools.count()))
207        self.assertEqual(pprint.pformat(d),
208"""\
209{'the': 0,
210 'quick': 1,
211 'brown': 2,
212 'fox': 3,
213 'jumped': 4,
214 'over': 5,
215 'a': 6,
216 'lazy': 7,
217 'dog': 8}""")
218    def test_subclassing(self) -> None:
219        o = {'names with spaces': 'should be presented using repr()',
220             'others.should.not.be': 'like.this'}
221        exp = """\
222{'names with spaces': 'should be presented using repr()',
223 others.should.not.be: like.this}"""
224        self.assertEqual(DottedPrettyPrinter().pformat(o), exp)
225
226    @test.support.cpython_only
227    def test_set_reprs(self) -> None:
228        # This test creates a complex arrangement of frozensets and
229        # compares the pretty-printed repr against a string hard-coded in
230        # the test.  The hard-coded repr depends on the sort order of
231        # frozensets.
232        #
233        # However, as the docs point out: "Since sets only define
234        # partial ordering (subset relationships), the output of the
235        # list.sort() method is undefined for lists of sets."
236        #
237        # In a nutshell, the test assumes frozenset({0}) will always
238        # sort before frozenset({1}), but:
239        #
240        # >>> frozenset({0}) < frozenset({1})
241        # False
242        # >>> frozenset({1}) < frozenset({0})
243        # False
244        #
245        # Consequently, this test is fragile and
246        # implementation-dependent.  Small changes to Python's sort
247        # algorithm cause the test to fail when it should pass.
248
249        self.assertEqual(pprint.pformat(set()), 'set()')
250        self.assertEqual(pprint.pformat(set(range(3))), '{0, 1, 2}')
251        self.assertEqual(pprint.pformat(frozenset()), 'frozenset()')
252        self.assertEqual(pprint.pformat(frozenset(range(3))), 'frozenset({0, 1, 2})')
253        cube_repr_tgt = """\
254{frozenset(): frozenset({frozenset({2}), frozenset({0}), frozenset({1})}),
255 frozenset({0}): frozenset({frozenset(),
256                            frozenset({0, 2}),
257                            frozenset({0, 1})}),
258 frozenset({1}): frozenset({frozenset(),
259                            frozenset({1, 2}),
260                            frozenset({0, 1})}),
261 frozenset({2}): frozenset({frozenset(),
262                            frozenset({1, 2}),
263                            frozenset({0, 2})}),
264 frozenset({1, 2}): frozenset({frozenset({2}),
265                               frozenset({1}),
266                               frozenset({0, 1, 2})}),
267 frozenset({0, 2}): frozenset({frozenset({2}),
268                               frozenset({0}),
269                               frozenset({0, 1, 2})}),
270 frozenset({0, 1}): frozenset({frozenset({0}),
271                               frozenset({1}),
272                               frozenset({0, 1, 2})}),
273 frozenset({0, 1, 2}): frozenset({frozenset({1, 2}),
274                                  frozenset({0, 2}),
275                                  frozenset({0, 1})})}"""
276        cube = test.test_set.cube(3)
277        self.assertEqual(pprint.pformat(cube), cube_repr_tgt)
278        cubo_repr_tgt = """\
279{frozenset({frozenset({0, 2}), frozenset({0})}): frozenset({frozenset({frozenset({0,
280                                                                                  2}),
281                                                                       frozenset({0,
282                                                                                  1,
283                                                                                  2})}),
284                                                            frozenset({frozenset({0}),
285                                                                       frozenset({0,
286                                                                                  1})}),
287                                                            frozenset({frozenset(),
288                                                                       frozenset({0})}),
289                                                            frozenset({frozenset({2}),
290                                                                       frozenset({0,
291                                                                                  2})})}),
292 frozenset({frozenset({0, 1}), frozenset({1})}): frozenset({frozenset({frozenset({0,
293                                                                                  1}),
294                                                                       frozenset({0,
295                                                                                  1,
296                                                                                  2})}),
297                                                            frozenset({frozenset({0}),
298                                                                       frozenset({0,
299                                                                                  1})}),
300                                                            frozenset({frozenset({1}),
301                                                                       frozenset({1,
302                                                                                  2})}),
303                                                            frozenset({frozenset(),
304                                                                       frozenset({1})})}),
305 frozenset({frozenset({1, 2}), frozenset({1})}): frozenset({frozenset({frozenset({1,
306                                                                                  2}),
307                                                                       frozenset({0,
308                                                                                  1,
309                                                                                  2})}),
310                                                            frozenset({frozenset({2}),
311                                                                       frozenset({1,
312                                                                                  2})}),
313                                                            frozenset({frozenset(),
314                                                                       frozenset({1})}),
315                                                            frozenset({frozenset({1}),
316                                                                       frozenset({0,
317                                                                                  1})})}),
318 frozenset({frozenset({1, 2}), frozenset({2})}): frozenset({frozenset({frozenset({1,
319                                                                                  2}),
320                                                                       frozenset({0,
321                                                                                  1,
322                                                                                  2})}),
323                                                            frozenset({frozenset({1}),
324                                                                       frozenset({1,
325                                                                                  2})}),
326                                                            frozenset({frozenset({2}),
327                                                                       frozenset({0,
328                                                                                  2})}),
329                                                            frozenset({frozenset(),
330                                                                       frozenset({2})})}),
331 frozenset({frozenset(), frozenset({0})}): frozenset({frozenset({frozenset({0}),
332                                                                 frozenset({0,
333                                                                            1})}),
334                                                      frozenset({frozenset({0}),
335                                                                 frozenset({0,
336                                                                            2})}),
337                                                      frozenset({frozenset(),
338                                                                 frozenset({1})}),
339                                                      frozenset({frozenset(),
340                                                                 frozenset({2})})}),
341 frozenset({frozenset(), frozenset({1})}): frozenset({frozenset({frozenset(),
342                                                                 frozenset({0})}),
343                                                      frozenset({frozenset({1}),
344                                                                 frozenset({1,
345                                                                            2})}),
346                                                      frozenset({frozenset(),
347                                                                 frozenset({2})}),
348                                                      frozenset({frozenset({1}),
349                                                                 frozenset({0,
350                                                                            1})})}),
351 frozenset({frozenset({2}), frozenset()}): frozenset({frozenset({frozenset({2}),
352                                                                 frozenset({1,
353                                                                            2})}),
354                                                      frozenset({frozenset(),
355                                                                 frozenset({0})}),
356                                                      frozenset({frozenset(),
357                                                                 frozenset({1})}),
358                                                      frozenset({frozenset({2}),
359                                                                 frozenset({0,
360                                                                            2})})}),
361 frozenset({frozenset({0, 1, 2}), frozenset({0, 1})}): frozenset({frozenset({frozenset({1,
362                                                                                        2}),
363                                                                             frozenset({0,
364                                                                                        1,
365                                                                                        2})}),
366                                                                  frozenset({frozenset({0,
367                                                                                        2}),
368                                                                             frozenset({0,
369                                                                                        1,
370                                                                                        2})}),
371                                                                  frozenset({frozenset({0}),
372                                                                             frozenset({0,
373                                                                                        1})}),
374                                                                  frozenset({frozenset({1}),
375                                                                             frozenset({0,
376                                                                                        1})})}),
377 frozenset({frozenset({0}), frozenset({0, 1})}): frozenset({frozenset({frozenset(),
378                                                                       frozenset({0})}),
379                                                            frozenset({frozenset({0,
380                                                                                  1}),
381                                                                       frozenset({0,
382                                                                                  1,
383                                                                                  2})}),
384                                                            frozenset({frozenset({0}),
385                                                                       frozenset({0,
386                                                                                  2})}),
387                                                            frozenset({frozenset({1}),
388                                                                       frozenset({0,
389                                                                                  1})})}),
390 frozenset({frozenset({2}), frozenset({0, 2})}): frozenset({frozenset({frozenset({0,
391                                                                                  2}),
392                                                                       frozenset({0,
393                                                                                  1,
394                                                                                  2})}),
395                                                            frozenset({frozenset({2}),
396                                                                       frozenset({1,
397                                                                                  2})}),
398                                                            frozenset({frozenset({0}),
399                                                                       frozenset({0,
400                                                                                  2})}),
401                                                            frozenset({frozenset(),
402                                                                       frozenset({2})})}),
403 frozenset({frozenset({0, 1, 2}), frozenset({0, 2})}): frozenset({frozenset({frozenset({1,
404                                                                                        2}),
405                                                                             frozenset({0,
406                                                                                        1,
407                                                                                        2})}),
408                                                                  frozenset({frozenset({0,
409                                                                                        1}),
410                                                                             frozenset({0,
411                                                                                        1,
412                                                                                        2})}),
413                                                                  frozenset({frozenset({0}),
414                                                                             frozenset({0,
415                                                                                        2})}),
416                                                                  frozenset({frozenset({2}),
417                                                                             frozenset({0,
418                                                                                        2})})}),
419 frozenset({frozenset({1, 2}), frozenset({0, 1, 2})}): frozenset({frozenset({frozenset({0,
420                                                                                        2}),
421                                                                             frozenset({0,
422                                                                                        1,
423                                                                                        2})}),
424                                                                  frozenset({frozenset({0,
425                                                                                        1}),
426                                                                             frozenset({0,
427                                                                                        1,
428                                                                                        2})}),
429                                                                  frozenset({frozenset({2}),
430                                                                             frozenset({1,
431                                                                                        2})}),
432                                                                  frozenset({frozenset({1}),
433                                                                             frozenset({1,
434                                                                                        2})})})}"""
435
436        cubo = test.test_set.linegraph(cube)
437        self.assertEqual(pprint.pformat(cubo), cubo_repr_tgt)
438
439    def test_depth(self) -> None:
440        nested_tuple = (1, (2, (3, (4, (5, 6)))))
441        nested_dict = {1: {2: {3: {4: {5: {6: 6}}}}}}
442        nested_list = [1, [2, [3, [4, [5, [6, []]]]]]]
443        self.assertEqual(pprint.pformat(nested_tuple), repr(nested_tuple))
444        self.assertEqual(pprint.pformat(nested_dict), repr(nested_dict))
445        self.assertEqual(pprint.pformat(nested_list), repr(nested_list))
446
447        lv1_tuple = '(1, (...))'
448        lv1_dict = '{1: {...}}'
449        lv1_list = '[1, [...]]'
450        self.assertEqual(pprint.pformat(nested_tuple, depth=1), lv1_tuple)
451        self.assertEqual(pprint.pformat(nested_dict, depth=1), lv1_dict)
452        self.assertEqual(pprint.pformat(nested_list, depth=1), lv1_list)
453
454    def test_sort_unorderable_values(self) -> None:
455        # Issue 3976:  sorted pprints fail for unorderable values.
456        n = 20
457        keys = [Unorderable() for i in range(n)]
458        random.shuffle(keys)
459        skeys = sorted(keys, key=id)
460        clean = lambda s: s.replace(' ', '').replace('\n','')  # type: Callable[[str], str]
461
462        self.assertEqual(clean(pprint.pformat(set(keys))),
463            '{' + ','.join(map(repr, skeys)) + '}')
464        self.assertEqual(clean(pprint.pformat(frozenset(keys))),
465            'frozenset({' + ','.join(map(repr, skeys)) + '})')
466        self.assertEqual(clean(pprint.pformat(dict.fromkeys(keys))),
467            '{' + ','.join('%r:None' % k for k in skeys) + '}')
468
469class DottedPrettyPrinter(pprint.PrettyPrinter):
470
471    def format(self, object: object, context: Dict[int, Any], maxlevels: int,
472               level: int) -> Tuple[str, int, int]:
473        if isinstance(object, str):
474            if ' ' in object:
475                return repr(object), 1, 0
476            else:
477                return object, 0, 0
478        else:
479            return pprint.PrettyPrinter.format(
480                self, object, context, maxlevels, level)
481
482
483def test_main() -> None:
484    test.support.run_unittest(QueryTestCase)
485
486
487if __name__ == "__main__":
488    test_main()
489