##// END OF EJS Templates
Update IPython/lib/tests/test_pretty.py...
Lumír 'Frenzy' Balhar -
Show More
@@ -1,539 +1,539 b''
1 1 # coding: utf-8
2 2 """Tests for IPython.lib.pretty."""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7
8 8 from collections import Counter, defaultdict, deque, OrderedDict, UserList
9 9 import os
10 10 import pytest
11 11 import types
12 12 import string
13 13 import sys
14 14 import unittest
15 15
16 16 import pytest
17 17
18 18 from IPython.lib import pretty
19 19
20 20 from io import StringIO
21 21
22 22
23 23 class MyList(object):
24 24 def __init__(self, content):
25 25 self.content = content
26 26 def _repr_pretty_(self, p, cycle):
27 27 if cycle:
28 28 p.text("MyList(...)")
29 29 else:
30 30 with p.group(3, "MyList(", ")"):
31 31 for (i, child) in enumerate(self.content):
32 32 if i:
33 33 p.text(",")
34 34 p.breakable()
35 35 else:
36 36 p.breakable("")
37 37 p.pretty(child)
38 38
39 39
40 40 class MyDict(dict):
41 41 def _repr_pretty_(self, p, cycle):
42 42 p.text("MyDict(...)")
43 43
44 44 class MyObj(object):
45 45 def somemethod(self):
46 46 pass
47 47
48 48
49 49 class Dummy1(object):
50 50 def _repr_pretty_(self, p, cycle):
51 51 p.text("Dummy1(...)")
52 52
53 53 class Dummy2(Dummy1):
54 54 _repr_pretty_ = None
55 55
56 56 class NoModule(object):
57 57 pass
58 58
59 59 NoModule.__module__ = None
60 60
61 61 class Breaking(object):
62 62 def _repr_pretty_(self, p, cycle):
63 63 with p.group(4,"TG: ",":"):
64 64 p.text("Breaking(")
65 65 p.break_()
66 66 p.text(")")
67 67
68 68 class BreakingRepr(object):
69 69 def __repr__(self):
70 70 return "Breaking(\n)"
71 71
72 72 class BadRepr(object):
73 73 def __repr__(self):
74 74 return 1/0
75 75
76 76
77 77 def test_indentation():
78 78 """Test correct indentation in groups"""
79 79 count = 40
80 80 gotoutput = pretty.pretty(MyList(range(count)))
81 81 expectedoutput = "MyList(\n" + ",\n".join(" %d" % i for i in range(count)) + ")"
82 82
83 83 assert gotoutput == expectedoutput
84 84
85 85
86 86 def test_dispatch():
87 87 """
88 88 Test correct dispatching: The _repr_pretty_ method for MyDict
89 89 must be found before the registered printer for dict.
90 90 """
91 91 gotoutput = pretty.pretty(MyDict())
92 92 expectedoutput = "MyDict(...)"
93 93
94 94 assert gotoutput == expectedoutput
95 95
96 96
97 97 def test_callability_checking():
98 98 """
99 99 Test that the _repr_pretty_ method is tested for callability and skipped if
100 100 not.
101 101 """
102 102 gotoutput = pretty.pretty(Dummy2())
103 103 expectedoutput = "Dummy1(...)"
104 104
105 105 assert gotoutput == expectedoutput
106 106
107 107
108 108 @pytest.mark.parametrize(
109 109 "obj,expected_output",
110 110 zip(
111 111 [
112 112 set(),
113 113 frozenset(),
114 114 set([1]),
115 115 frozenset([1]),
116 116 set([1, 2]),
117 117 frozenset([1, 2]),
118 118 set([-1, -2, -3]),
119 119 ],
120 120 [
121 121 "set()",
122 122 "frozenset()",
123 123 "{1}",
124 124 "frozenset({1})",
125 125 "{1, 2}",
126 126 "frozenset({1, 2})",
127 127 "{-3, -2, -1}",
128 128 ],
129 129 ),
130 130 )
131 131 def test_sets(obj, expected_output):
132 132 """
133 133 Test that set and frozenset use Python 3 formatting.
134 134 """
135 135 got_output = pretty.pretty(obj)
136 136 assert got_output == expected_output
137 137
138 138
139 139 def test_pprint_heap_allocated_type():
140 140 """
141 141 Test that pprint works for heap allocated types.
142 142 """
143 143 module_name = "xxlimited" if sys.version_info < (3, 10) else "xxlimited_35"
144 144 expected_output = (
145 "xxlimited.Null" if sys.version_info < (3, 11) else "xxlimited_35.Null"
145 "xxlimited.Null" if sys.version_info < (3, 10, 6) else "xxlimited_35.Null"
146 146 )
147 147 xxlimited = pytest.importorskip(module_name)
148 148 output = pretty.pretty(xxlimited.Null)
149 149 assert output == expected_output
150 150
151 151
152 152 def test_pprint_nomod():
153 153 """
154 154 Test that pprint works for classes with no __module__.
155 155 """
156 156 output = pretty.pretty(NoModule)
157 157 assert output == "NoModule"
158 158
159 159
160 160 def test_pprint_break():
161 161 """
162 162 Test that p.break_ produces expected output
163 163 """
164 164 output = pretty.pretty(Breaking())
165 165 expected = "TG: Breaking(\n ):"
166 166 assert output == expected
167 167
168 168 def test_pprint_break_repr():
169 169 """
170 170 Test that p.break_ is used in repr
171 171 """
172 172 output = pretty.pretty([[BreakingRepr()]])
173 173 expected = "[[Breaking(\n )]]"
174 174 assert output == expected
175 175
176 176 output = pretty.pretty([[BreakingRepr()]*2])
177 177 expected = "[[Breaking(\n ),\n Breaking(\n )]]"
178 178 assert output == expected
179 179
180 180 def test_bad_repr():
181 181 """Don't catch bad repr errors"""
182 182 with pytest.raises(ZeroDivisionError):
183 183 pretty.pretty(BadRepr())
184 184
185 185 class BadException(Exception):
186 186 def __str__(self):
187 187 return -1
188 188
189 189 class ReallyBadRepr(object):
190 190 __module__ = 1
191 191 @property
192 192 def __class__(self):
193 193 raise ValueError("I am horrible")
194 194
195 195 def __repr__(self):
196 196 raise BadException()
197 197
198 198 def test_really_bad_repr():
199 199 with pytest.raises(BadException):
200 200 pretty.pretty(ReallyBadRepr())
201 201
202 202
203 203 class SA(object):
204 204 pass
205 205
206 206 class SB(SA):
207 207 pass
208 208
209 209 class TestsPretty(unittest.TestCase):
210 210
211 211 def test_super_repr(self):
212 212 # "<super: module_name.SA, None>"
213 213 output = pretty.pretty(super(SA))
214 214 self.assertRegex(output, r"<super: \S+.SA, None>")
215 215
216 216 # "<super: module_name.SA, <module_name.SB at 0x...>>"
217 217 sb = SB()
218 218 output = pretty.pretty(super(SA, sb))
219 219 self.assertRegex(output, r"<super: \S+.SA,\s+<\S+.SB at 0x\S+>>")
220 220
221 221
222 222 def test_long_list(self):
223 223 lis = list(range(10000))
224 224 p = pretty.pretty(lis)
225 225 last2 = p.rsplit('\n', 2)[-2:]
226 226 self.assertEqual(last2, [' 999,', ' ...]'])
227 227
228 228 def test_long_set(self):
229 229 s = set(range(10000))
230 230 p = pretty.pretty(s)
231 231 last2 = p.rsplit('\n', 2)[-2:]
232 232 self.assertEqual(last2, [' 999,', ' ...}'])
233 233
234 234 def test_long_tuple(self):
235 235 tup = tuple(range(10000))
236 236 p = pretty.pretty(tup)
237 237 last2 = p.rsplit('\n', 2)[-2:]
238 238 self.assertEqual(last2, [' 999,', ' ...)'])
239 239
240 240 def test_long_dict(self):
241 241 d = { n:n for n in range(10000) }
242 242 p = pretty.pretty(d)
243 243 last2 = p.rsplit('\n', 2)[-2:]
244 244 self.assertEqual(last2, [' 999: 999,', ' ...}'])
245 245
246 246 def test_unbound_method(self):
247 247 output = pretty.pretty(MyObj.somemethod)
248 248 self.assertIn('MyObj.somemethod', output)
249 249
250 250
251 251 class MetaClass(type):
252 252 def __new__(cls, name):
253 253 return type.__new__(cls, name, (object,), {'name': name})
254 254
255 255 def __repr__(self):
256 256 return "[CUSTOM REPR FOR CLASS %s]" % self.name
257 257
258 258
259 259 ClassWithMeta = MetaClass('ClassWithMeta')
260 260
261 261
262 262 def test_metaclass_repr():
263 263 output = pretty.pretty(ClassWithMeta)
264 264 assert output == "[CUSTOM REPR FOR CLASS ClassWithMeta]"
265 265
266 266
267 267 def test_unicode_repr():
268 268 u = u"üniçodé"
269 269 ustr = u
270 270
271 271 class C(object):
272 272 def __repr__(self):
273 273 return ustr
274 274
275 275 c = C()
276 276 p = pretty.pretty(c)
277 277 assert p == u
278 278 p = pretty.pretty([c])
279 279 assert p == "[%s]" % u
280 280
281 281
282 282 def test_basic_class():
283 283 def type_pprint_wrapper(obj, p, cycle):
284 284 if obj is MyObj:
285 285 type_pprint_wrapper.called = True
286 286 return pretty._type_pprint(obj, p, cycle)
287 287 type_pprint_wrapper.called = False
288 288
289 289 stream = StringIO()
290 290 printer = pretty.RepresentationPrinter(stream)
291 291 printer.type_pprinters[type] = type_pprint_wrapper
292 292 printer.pretty(MyObj)
293 293 printer.flush()
294 294 output = stream.getvalue()
295 295
296 296 assert output == "%s.MyObj" % __name__
297 297 assert type_pprint_wrapper.called is True
298 298
299 299
300 300 def test_collections_userlist():
301 301 # Create userlist with cycle
302 302 a = UserList()
303 303 a.append(a)
304 304
305 305 cases = [
306 306 (UserList(), "UserList([])"),
307 307 (
308 308 UserList(i for i in range(1000, 1020)),
309 309 "UserList([1000,\n"
310 310 " 1001,\n"
311 311 " 1002,\n"
312 312 " 1003,\n"
313 313 " 1004,\n"
314 314 " 1005,\n"
315 315 " 1006,\n"
316 316 " 1007,\n"
317 317 " 1008,\n"
318 318 " 1009,\n"
319 319 " 1010,\n"
320 320 " 1011,\n"
321 321 " 1012,\n"
322 322 " 1013,\n"
323 323 " 1014,\n"
324 324 " 1015,\n"
325 325 " 1016,\n"
326 326 " 1017,\n"
327 327 " 1018,\n"
328 328 " 1019])",
329 329 ),
330 330 (a, "UserList([UserList(...)])"),
331 331 ]
332 332 for obj, expected in cases:
333 333 assert pretty.pretty(obj) == expected
334 334
335 335
336 336 # TODO : pytest.mark.parametrise once nose is gone.
337 337 def test_collections_defaultdict():
338 338 # Create defaultdicts with cycles
339 339 a = defaultdict()
340 340 a.default_factory = a
341 341 b = defaultdict(list)
342 342 b['key'] = b
343 343
344 344 # Dictionary order cannot be relied on, test against single keys.
345 345 cases = [
346 346 (defaultdict(list), 'defaultdict(list, {})'),
347 347 (defaultdict(list, {'key': '-' * 50}),
348 348 "defaultdict(list,\n"
349 349 " {'key': '--------------------------------------------------'})"),
350 350 (a, 'defaultdict(defaultdict(...), {})'),
351 351 (b, "defaultdict(list, {'key': defaultdict(...)})"),
352 352 ]
353 353 for obj, expected in cases:
354 354 assert pretty.pretty(obj) == expected
355 355
356 356
357 357 # TODO : pytest.mark.parametrise once nose is gone.
358 358 def test_collections_ordereddict():
359 359 # Create OrderedDict with cycle
360 360 a = OrderedDict()
361 361 a['key'] = a
362 362
363 363 cases = [
364 364 (OrderedDict(), 'OrderedDict()'),
365 365 (OrderedDict((i, i) for i in range(1000, 1010)),
366 366 'OrderedDict([(1000, 1000),\n'
367 367 ' (1001, 1001),\n'
368 368 ' (1002, 1002),\n'
369 369 ' (1003, 1003),\n'
370 370 ' (1004, 1004),\n'
371 371 ' (1005, 1005),\n'
372 372 ' (1006, 1006),\n'
373 373 ' (1007, 1007),\n'
374 374 ' (1008, 1008),\n'
375 375 ' (1009, 1009)])'),
376 376 (a, "OrderedDict([('key', OrderedDict(...))])"),
377 377 ]
378 378 for obj, expected in cases:
379 379 assert pretty.pretty(obj) == expected
380 380
381 381
382 382 # TODO : pytest.mark.parametrise once nose is gone.
383 383 def test_collections_deque():
384 384 # Create deque with cycle
385 385 a = deque()
386 386 a.append(a)
387 387
388 388 cases = [
389 389 (deque(), 'deque([])'),
390 390 (deque(i for i in range(1000, 1020)),
391 391 'deque([1000,\n'
392 392 ' 1001,\n'
393 393 ' 1002,\n'
394 394 ' 1003,\n'
395 395 ' 1004,\n'
396 396 ' 1005,\n'
397 397 ' 1006,\n'
398 398 ' 1007,\n'
399 399 ' 1008,\n'
400 400 ' 1009,\n'
401 401 ' 1010,\n'
402 402 ' 1011,\n'
403 403 ' 1012,\n'
404 404 ' 1013,\n'
405 405 ' 1014,\n'
406 406 ' 1015,\n'
407 407 ' 1016,\n'
408 408 ' 1017,\n'
409 409 ' 1018,\n'
410 410 ' 1019])'),
411 411 (a, 'deque([deque(...)])'),
412 412 ]
413 413 for obj, expected in cases:
414 414 assert pretty.pretty(obj) == expected
415 415
416 416
417 417 # TODO : pytest.mark.parametrise once nose is gone.
418 418 def test_collections_counter():
419 419 class MyCounter(Counter):
420 420 pass
421 421 cases = [
422 422 (Counter(), 'Counter()'),
423 423 (Counter(a=1), "Counter({'a': 1})"),
424 424 (MyCounter(a=1), "MyCounter({'a': 1})"),
425 425 ]
426 426 for obj, expected in cases:
427 427 assert pretty.pretty(obj) == expected
428 428
429 429 # TODO : pytest.mark.parametrise once nose is gone.
430 430 def test_mappingproxy():
431 431 MP = types.MappingProxyType
432 432 underlying_dict = {}
433 433 mp_recursive = MP(underlying_dict)
434 434 underlying_dict[2] = mp_recursive
435 435 underlying_dict[3] = underlying_dict
436 436
437 437 cases = [
438 438 (MP({}), "mappingproxy({})"),
439 439 (MP({None: MP({})}), "mappingproxy({None: mappingproxy({})})"),
440 440 (MP({k: k.upper() for k in string.ascii_lowercase}),
441 441 "mappingproxy({'a': 'A',\n"
442 442 " 'b': 'B',\n"
443 443 " 'c': 'C',\n"
444 444 " 'd': 'D',\n"
445 445 " 'e': 'E',\n"
446 446 " 'f': 'F',\n"
447 447 " 'g': 'G',\n"
448 448 " 'h': 'H',\n"
449 449 " 'i': 'I',\n"
450 450 " 'j': 'J',\n"
451 451 " 'k': 'K',\n"
452 452 " 'l': 'L',\n"
453 453 " 'm': 'M',\n"
454 454 " 'n': 'N',\n"
455 455 " 'o': 'O',\n"
456 456 " 'p': 'P',\n"
457 457 " 'q': 'Q',\n"
458 458 " 'r': 'R',\n"
459 459 " 's': 'S',\n"
460 460 " 't': 'T',\n"
461 461 " 'u': 'U',\n"
462 462 " 'v': 'V',\n"
463 463 " 'w': 'W',\n"
464 464 " 'x': 'X',\n"
465 465 " 'y': 'Y',\n"
466 466 " 'z': 'Z'})"),
467 467 (mp_recursive, "mappingproxy({2: {...}, 3: {2: {...}, 3: {...}}})"),
468 468 (underlying_dict,
469 469 "{2: mappingproxy({2: {...}, 3: {...}}), 3: {...}}"),
470 470 ]
471 471 for obj, expected in cases:
472 472 assert pretty.pretty(obj) == expected
473 473
474 474
475 475 # TODO : pytest.mark.parametrise once nose is gone.
476 476 def test_simplenamespace():
477 477 SN = types.SimpleNamespace
478 478
479 479 sn_recursive = SN()
480 480 sn_recursive.first = sn_recursive
481 481 sn_recursive.second = sn_recursive
482 482 cases = [
483 483 (SN(), "namespace()"),
484 484 (SN(x=SN()), "namespace(x=namespace())"),
485 485 (SN(a_long_name=[SN(s=string.ascii_lowercase)]*3, a_short_name=None),
486 486 "namespace(a_long_name=[namespace(s='abcdefghijklmnopqrstuvwxyz'),\n"
487 487 " namespace(s='abcdefghijklmnopqrstuvwxyz'),\n"
488 488 " namespace(s='abcdefghijklmnopqrstuvwxyz')],\n"
489 489 " a_short_name=None)"),
490 490 (sn_recursive, "namespace(first=namespace(...), second=namespace(...))"),
491 491 ]
492 492 for obj, expected in cases:
493 493 assert pretty.pretty(obj) == expected
494 494
495 495
496 496 def test_pretty_environ():
497 497 dict_repr = pretty.pretty(dict(os.environ))
498 498 # reindent to align with 'environ' prefix
499 499 dict_indented = dict_repr.replace('\n', '\n' + (' ' * len('environ')))
500 500 env_repr = pretty.pretty(os.environ)
501 501 assert env_repr == "environ" + dict_indented
502 502
503 503
504 504 def test_function_pretty():
505 505 "Test pretty print of function"
506 506 # posixpath is a pure python module, its interface is consistent
507 507 # across Python distributions
508 508 import posixpath
509 509
510 510 assert pretty.pretty(posixpath.join) == "<function posixpath.join(a, *p)>"
511 511
512 512 # custom function
513 513 def meaning_of_life(question=None):
514 514 if question:
515 515 return 42
516 516 return "Don't panic"
517 517
518 518 assert "meaning_of_life(question=None)" in pretty.pretty(meaning_of_life)
519 519
520 520
521 521 class OrderedCounter(Counter, OrderedDict):
522 522 'Counter that remembers the order elements are first encountered'
523 523
524 524 def __repr__(self):
525 525 return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))
526 526
527 527 def __reduce__(self):
528 528 return self.__class__, (OrderedDict(self),)
529 529
530 530 class MySet(set): # Override repr of a basic type
531 531 def __repr__(self):
532 532 return 'mine'
533 533
534 534 def test_custom_repr():
535 535 """A custom repr should override a pretty printer for a parent type"""
536 536 oc = OrderedCounter("abracadabra")
537 537 assert "OrderedCounter(OrderedDict" in pretty.pretty(oc)
538 538
539 539 assert pretty.pretty(MySet()) == "mine"
General Comments 0
You need to be logged in to leave comments. Login now