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