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