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