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