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