##// END OF EJS Templates
Merge pull request #3851 from alexrudy/pretty-newlines...
Min RK -
r12570:fb2885fd merge
parent child Browse files
Show More
@@ -1,776 +1,790 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Python advanced pretty printer. This pretty printer is intended to
3 Python advanced pretty printer. This pretty printer is intended to
4 replace the old `pprint` python module which does not allow developers
4 replace the old `pprint` python module which does not allow developers
5 to provide their own pretty print callbacks.
5 to provide their own pretty print callbacks.
6
6
7 This module is based on ruby's `prettyprint.rb` library by `Tanaka Akira`.
7 This module is based on ruby's `prettyprint.rb` library by `Tanaka Akira`.
8
8
9
9
10 Example Usage
10 Example Usage
11 -------------
11 -------------
12
12
13 To directly print the representation of an object use `pprint`::
13 To directly print the representation of an object use `pprint`::
14
14
15 from pretty import pprint
15 from pretty import pprint
16 pprint(complex_object)
16 pprint(complex_object)
17
17
18 To get a string of the output use `pretty`::
18 To get a string of the output use `pretty`::
19
19
20 from pretty import pretty
20 from pretty import pretty
21 string = pretty(complex_object)
21 string = pretty(complex_object)
22
22
23
23
24 Extending
24 Extending
25 ---------
25 ---------
26
26
27 The pretty library allows developers to add pretty printing rules for their
27 The pretty library allows developers to add pretty printing rules for their
28 own objects. This process is straightforward. All you have to do is to
28 own objects. This process is straightforward. All you have to do is to
29 add a `_repr_pretty_` method to your object and call the methods on the
29 add a `_repr_pretty_` method to your object and call the methods on the
30 pretty printer passed::
30 pretty printer passed::
31
31
32 class MyObject(object):
32 class MyObject(object):
33
33
34 def _repr_pretty_(self, p, cycle):
34 def _repr_pretty_(self, p, cycle):
35 ...
35 ...
36
36
37 Depending on the python version you want to support you have two
37 Depending on the python version you want to support you have two
38 possibilities. The following list shows the python 2.5 version and the
38 possibilities. The following list shows the python 2.5 version and the
39 compatibility one.
39 compatibility one.
40
40
41
41
42 Here the example implementation of a `_repr_pretty_` method for a list
42 Here the example implementation of a `_repr_pretty_` method for a list
43 subclass for python 2.5 and higher (python 2.5 requires the with statement
43 subclass for python 2.5 and higher (python 2.5 requires the with statement
44 __future__ import)::
44 __future__ import)::
45
45
46 class MyList(list):
46 class MyList(list):
47
47
48 def _repr_pretty_(self, p, cycle):
48 def _repr_pretty_(self, p, cycle):
49 if cycle:
49 if cycle:
50 p.text('MyList(...)')
50 p.text('MyList(...)')
51 else:
51 else:
52 with p.group(8, 'MyList([', '])'):
52 with p.group(8, 'MyList([', '])'):
53 for idx, item in enumerate(self):
53 for idx, item in enumerate(self):
54 if idx:
54 if idx:
55 p.text(',')
55 p.text(',')
56 p.breakable()
56 p.breakable()
57 p.pretty(item)
57 p.pretty(item)
58
58
59 The `cycle` parameter is `True` if pretty detected a cycle. You *have* to
59 The `cycle` parameter is `True` if pretty detected a cycle. You *have* to
60 react to that or the result is an infinite loop. `p.text()` just adds
60 react to that or the result is an infinite loop. `p.text()` just adds
61 non breaking text to the output, `p.breakable()` either adds a whitespace
61 non breaking text to the output, `p.breakable()` either adds a whitespace
62 or breaks here. If you pass it an argument it's used instead of the
62 or breaks here. If you pass it an argument it's used instead of the
63 default space. `p.pretty` prettyprints another object using the pretty print
63 default space. `p.pretty` prettyprints another object using the pretty print
64 method.
64 method.
65
65
66 The first parameter to the `group` function specifies the extra indentation
66 The first parameter to the `group` function specifies the extra indentation
67 of the next line. In this example the next item will either be not
67 of the next line. In this example the next item will either be not
68 breaked (if the items are short enough) or aligned with the right edge of
68 breaked (if the items are short enough) or aligned with the right edge of
69 the opening bracked of `MyList`.
69 the opening bracked of `MyList`.
70
70
71 If you want to support python 2.4 and lower you can use this code::
71 If you want to support python 2.4 and lower you can use this code::
72
72
73 class MyList(list):
73 class MyList(list):
74
74
75 def _repr_pretty_(self, p, cycle):
75 def _repr_pretty_(self, p, cycle):
76 if cycle:
76 if cycle:
77 p.text('MyList(...)')
77 p.text('MyList(...)')
78 else:
78 else:
79 p.begin_group(8, 'MyList([')
79 p.begin_group(8, 'MyList([')
80 for idx, item in enumerate(self):
80 for idx, item in enumerate(self):
81 if idx:
81 if idx:
82 p.text(',')
82 p.text(',')
83 p.breakable()
83 p.breakable()
84 p.pretty(item)
84 p.pretty(item)
85 p.end_group(8, '])')
85 p.end_group(8, '])')
86
86
87 If you just want to indent something you can use the group function
87 If you just want to indent something you can use the group function
88 without open / close parameters. Under python 2.5 you can also use this
88 without open / close parameters. Under python 2.5 you can also use this
89 code::
89 code::
90
90
91 with p.indent(2):
91 with p.indent(2):
92 ...
92 ...
93
93
94 Or under python2.4 you might want to modify ``p.indentation`` by hand but
94 Or under python2.4 you might want to modify ``p.indentation`` by hand but
95 this is rather ugly.
95 this is rather ugly.
96
96
97 Inheritance diagram:
97 Inheritance diagram:
98
98
99 .. inheritance-diagram:: IPython.lib.pretty
99 .. inheritance-diagram:: IPython.lib.pretty
100 :parts: 3
100 :parts: 3
101
101
102 :copyright: 2007 by Armin Ronacher.
102 :copyright: 2007 by Armin Ronacher.
103 Portions (c) 2009 by Robert Kern.
103 Portions (c) 2009 by Robert Kern.
104 :license: BSD License.
104 :license: BSD License.
105 """
105 """
106 from __future__ import with_statement
106 from __future__ import with_statement
107 from contextlib import contextmanager
107 from contextlib import contextmanager
108 import sys
108 import sys
109 import types
109 import types
110 import re
110 import re
111 import datetime
111 import datetime
112 from StringIO import StringIO
112 from StringIO import StringIO
113 from collections import deque
113 from collections import deque
114
114
115
115
116 __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter',
116 __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter',
117 'for_type', 'for_type_by_name']
117 'for_type', 'for_type_by_name']
118
118
119
119
120 _re_pattern_type = type(re.compile(''))
120 _re_pattern_type = type(re.compile(''))
121
121
122
122
123 def pretty(obj, verbose=False, max_width=79, newline='\n'):
123 def pretty(obj, verbose=False, max_width=79, newline='\n'):
124 """
124 """
125 Pretty print the object's representation.
125 Pretty print the object's representation.
126 """
126 """
127 stream = StringIO()
127 stream = StringIO()
128 printer = RepresentationPrinter(stream, verbose, max_width, newline)
128 printer = RepresentationPrinter(stream, verbose, max_width, newline)
129 printer.pretty(obj)
129 printer.pretty(obj)
130 printer.flush()
130 printer.flush()
131 return stream.getvalue()
131 return stream.getvalue()
132
132
133
133
134 def pprint(obj, verbose=False, max_width=79, newline='\n'):
134 def pprint(obj, verbose=False, max_width=79, newline='\n'):
135 """
135 """
136 Like `pretty` but print to stdout.
136 Like `pretty` but print to stdout.
137 """
137 """
138 printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline)
138 printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline)
139 printer.pretty(obj)
139 printer.pretty(obj)
140 printer.flush()
140 printer.flush()
141 sys.stdout.write(newline)
141 sys.stdout.write(newline)
142 sys.stdout.flush()
142 sys.stdout.flush()
143
143
144 class _PrettyPrinterBase(object):
144 class _PrettyPrinterBase(object):
145
145
146 @contextmanager
146 @contextmanager
147 def indent(self, indent):
147 def indent(self, indent):
148 """with statement support for indenting/dedenting."""
148 """with statement support for indenting/dedenting."""
149 self.indentation += indent
149 self.indentation += indent
150 try:
150 try:
151 yield
151 yield
152 finally:
152 finally:
153 self.indentation -= indent
153 self.indentation -= indent
154
154
155 @contextmanager
155 @contextmanager
156 def group(self, indent=0, open='', close=''):
156 def group(self, indent=0, open='', close=''):
157 """like begin_group / end_group but for the with statement."""
157 """like begin_group / end_group but for the with statement."""
158 self.begin_group(indent, open)
158 self.begin_group(indent, open)
159 try:
159 try:
160 yield
160 yield
161 finally:
161 finally:
162 self.end_group(indent, close)
162 self.end_group(indent, close)
163
163
164 class PrettyPrinter(_PrettyPrinterBase):
164 class PrettyPrinter(_PrettyPrinterBase):
165 """
165 """
166 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
166 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
167 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
167 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
168 this printer knows nothing about the default pprinters or the `_repr_pretty_`
168 this printer knows nothing about the default pprinters or the `_repr_pretty_`
169 callback method.
169 callback method.
170 """
170 """
171
171
172 def __init__(self, output, max_width=79, newline='\n'):
172 def __init__(self, output, max_width=79, newline='\n'):
173 self.output = output
173 self.output = output
174 self.max_width = max_width
174 self.max_width = max_width
175 self.newline = newline
175 self.newline = newline
176 self.output_width = 0
176 self.output_width = 0
177 self.buffer_width = 0
177 self.buffer_width = 0
178 self.buffer = deque()
178 self.buffer = deque()
179
179
180 root_group = Group(0)
180 root_group = Group(0)
181 self.group_stack = [root_group]
181 self.group_stack = [root_group]
182 self.group_queue = GroupQueue(root_group)
182 self.group_queue = GroupQueue(root_group)
183 self.indentation = 0
183 self.indentation = 0
184
184
185 def _break_outer_groups(self):
185 def _break_outer_groups(self):
186 while self.max_width < self.output_width + self.buffer_width:
186 while self.max_width < self.output_width + self.buffer_width:
187 group = self.group_queue.deq()
187 group = self.group_queue.deq()
188 if not group:
188 if not group:
189 return
189 return
190 while group.breakables:
190 while group.breakables:
191 x = self.buffer.popleft()
191 x = self.buffer.popleft()
192 self.output_width = x.output(self.output, self.output_width)
192 self.output_width = x.output(self.output, self.output_width)
193 self.buffer_width -= x.width
193 self.buffer_width -= x.width
194 while self.buffer and isinstance(self.buffer[0], Text):
194 while self.buffer and isinstance(self.buffer[0], Text):
195 x = self.buffer.popleft()
195 x = self.buffer.popleft()
196 self.output_width = x.output(self.output, self.output_width)
196 self.output_width = x.output(self.output, self.output_width)
197 self.buffer_width -= x.width
197 self.buffer_width -= x.width
198
198
199 def text(self, obj):
199 def text(self, obj):
200 """Add literal text to the output."""
200 """Add literal text to the output."""
201 width = len(obj)
201 width = len(obj)
202 if self.buffer:
202 if self.buffer:
203 text = self.buffer[-1]
203 text = self.buffer[-1]
204 if not isinstance(text, Text):
204 if not isinstance(text, Text):
205 text = Text()
205 text = Text()
206 self.buffer.append(text)
206 self.buffer.append(text)
207 text.add(obj, width)
207 text.add(obj, width)
208 self.buffer_width += width
208 self.buffer_width += width
209 self._break_outer_groups()
209 self._break_outer_groups()
210 else:
210 else:
211 self.output.write(obj)
211 self.output.write(obj)
212 self.output_width += width
212 self.output_width += width
213
213
214 def breakable(self, sep=' '):
214 def breakable(self, sep=' '):
215 """
215 """
216 Add a breakable separator to the output. This does not mean that it
216 Add a breakable separator to the output. This does not mean that it
217 will automatically break here. If no breaking on this position takes
217 will automatically break here. If no breaking on this position takes
218 place the `sep` is inserted which default to one space.
218 place the `sep` is inserted which default to one space.
219 """
219 """
220 width = len(sep)
220 width = len(sep)
221 group = self.group_stack[-1]
221 group = self.group_stack[-1]
222 if group.want_break:
222 if group.want_break:
223 self.flush()
223 self.flush()
224 self.output.write(self.newline)
224 self.output.write(self.newline)
225 self.output.write(' ' * self.indentation)
225 self.output.write(' ' * self.indentation)
226 self.output_width = self.indentation
226 self.output_width = self.indentation
227 self.buffer_width = 0
227 self.buffer_width = 0
228 else:
228 else:
229 self.buffer.append(Breakable(sep, width, self))
229 self.buffer.append(Breakable(sep, width, self))
230 self.buffer_width += width
230 self.buffer_width += width
231 self._break_outer_groups()
231 self._break_outer_groups()
232
232
233 def break_(self):
234 """
235 Explicitly insert a newline into the output, maintaining correct indentation.
236 """
237 self.flush()
238 self.output.write(self.newline)
239 self.output.write(' ' * self.indentation)
240 self.output_width = self.indentation
241 self.buffer_width = 0
242
233
243
234 def begin_group(self, indent=0, open=''):
244 def begin_group(self, indent=0, open=''):
235 """
245 """
236 Begin a group. If you want support for python < 2.5 which doesn't has
246 Begin a group. If you want support for python < 2.5 which doesn't has
237 the with statement this is the preferred way:
247 the with statement this is the preferred way:
238
248
239 p.begin_group(1, '{')
249 p.begin_group(1, '{')
240 ...
250 ...
241 p.end_group(1, '}')
251 p.end_group(1, '}')
242
252
243 The python 2.5 expression would be this:
253 The python 2.5 expression would be this:
244
254
245 with p.group(1, '{', '}'):
255 with p.group(1, '{', '}'):
246 ...
256 ...
247
257
248 The first parameter specifies the indentation for the next line (usually
258 The first parameter specifies the indentation for the next line (usually
249 the width of the opening text), the second the opening text. All
259 the width of the opening text), the second the opening text. All
250 parameters are optional.
260 parameters are optional.
251 """
261 """
252 if open:
262 if open:
253 self.text(open)
263 self.text(open)
254 group = Group(self.group_stack[-1].depth + 1)
264 group = Group(self.group_stack[-1].depth + 1)
255 self.group_stack.append(group)
265 self.group_stack.append(group)
256 self.group_queue.enq(group)
266 self.group_queue.enq(group)
257 self.indentation += indent
267 self.indentation += indent
258
268
259 def end_group(self, dedent=0, close=''):
269 def end_group(self, dedent=0, close=''):
260 """End a group. See `begin_group` for more details."""
270 """End a group. See `begin_group` for more details."""
261 self.indentation -= dedent
271 self.indentation -= dedent
262 group = self.group_stack.pop()
272 group = self.group_stack.pop()
263 if not group.breakables:
273 if not group.breakables:
264 self.group_queue.remove(group)
274 self.group_queue.remove(group)
265 if close:
275 if close:
266 self.text(close)
276 self.text(close)
267
277
268 def flush(self):
278 def flush(self):
269 """Flush data that is left in the buffer."""
279 """Flush data that is left in the buffer."""
270 for data in self.buffer:
280 for data in self.buffer:
271 self.output_width += data.output(self.output, self.output_width)
281 self.output_width += data.output(self.output, self.output_width)
272 self.buffer.clear()
282 self.buffer.clear()
273 self.buffer_width = 0
283 self.buffer_width = 0
274
284
275
285
276 def _get_mro(obj_class):
286 def _get_mro(obj_class):
277 """ Get a reasonable method resolution order of a class and its superclasses
287 """ Get a reasonable method resolution order of a class and its superclasses
278 for both old-style and new-style classes.
288 for both old-style and new-style classes.
279 """
289 """
280 if not hasattr(obj_class, '__mro__'):
290 if not hasattr(obj_class, '__mro__'):
281 # Old-style class. Mix in object to make a fake new-style class.
291 # Old-style class. Mix in object to make a fake new-style class.
282 try:
292 try:
283 obj_class = type(obj_class.__name__, (obj_class, object), {})
293 obj_class = type(obj_class.__name__, (obj_class, object), {})
284 except TypeError:
294 except TypeError:
285 # Old-style extension type that does not descend from object.
295 # Old-style extension type that does not descend from object.
286 # FIXME: try to construct a more thorough MRO.
296 # FIXME: try to construct a more thorough MRO.
287 mro = [obj_class]
297 mro = [obj_class]
288 else:
298 else:
289 mro = obj_class.__mro__[1:-1]
299 mro = obj_class.__mro__[1:-1]
290 else:
300 else:
291 mro = obj_class.__mro__
301 mro = obj_class.__mro__
292 return mro
302 return mro
293
303
294
304
295 class RepresentationPrinter(PrettyPrinter):
305 class RepresentationPrinter(PrettyPrinter):
296 """
306 """
297 Special pretty printer that has a `pretty` method that calls the pretty
307 Special pretty printer that has a `pretty` method that calls the pretty
298 printer for a python object.
308 printer for a python object.
299
309
300 This class stores processing data on `self` so you must *never* use
310 This class stores processing data on `self` so you must *never* use
301 this class in a threaded environment. Always lock it or reinstanciate
311 this class in a threaded environment. Always lock it or reinstanciate
302 it.
312 it.
303
313
304 Instances also have a verbose flag callbacks can access to control their
314 Instances also have a verbose flag callbacks can access to control their
305 output. For example the default instance repr prints all attributes and
315 output. For example the default instance repr prints all attributes and
306 methods that are not prefixed by an underscore if the printer is in
316 methods that are not prefixed by an underscore if the printer is in
307 verbose mode.
317 verbose mode.
308 """
318 """
309
319
310 def __init__(self, output, verbose=False, max_width=79, newline='\n',
320 def __init__(self, output, verbose=False, max_width=79, newline='\n',
311 singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None):
321 singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None):
312
322
313 PrettyPrinter.__init__(self, output, max_width, newline)
323 PrettyPrinter.__init__(self, output, max_width, newline)
314 self.verbose = verbose
324 self.verbose = verbose
315 self.stack = []
325 self.stack = []
316 if singleton_pprinters is None:
326 if singleton_pprinters is None:
317 singleton_pprinters = _singleton_pprinters.copy()
327 singleton_pprinters = _singleton_pprinters.copy()
318 self.singleton_pprinters = singleton_pprinters
328 self.singleton_pprinters = singleton_pprinters
319 if type_pprinters is None:
329 if type_pprinters is None:
320 type_pprinters = _type_pprinters.copy()
330 type_pprinters = _type_pprinters.copy()
321 self.type_pprinters = type_pprinters
331 self.type_pprinters = type_pprinters
322 if deferred_pprinters is None:
332 if deferred_pprinters is None:
323 deferred_pprinters = _deferred_type_pprinters.copy()
333 deferred_pprinters = _deferred_type_pprinters.copy()
324 self.deferred_pprinters = deferred_pprinters
334 self.deferred_pprinters = deferred_pprinters
325
335
326 def pretty(self, obj):
336 def pretty(self, obj):
327 """Pretty print the given object."""
337 """Pretty print the given object."""
328 obj_id = id(obj)
338 obj_id = id(obj)
329 cycle = obj_id in self.stack
339 cycle = obj_id in self.stack
330 self.stack.append(obj_id)
340 self.stack.append(obj_id)
331 self.begin_group()
341 self.begin_group()
332 try:
342 try:
333 obj_class = getattr(obj, '__class__', None) or type(obj)
343 obj_class = getattr(obj, '__class__', None) or type(obj)
334 # First try to find registered singleton printers for the type.
344 # First try to find registered singleton printers for the type.
335 try:
345 try:
336 printer = self.singleton_pprinters[obj_id]
346 printer = self.singleton_pprinters[obj_id]
337 except (TypeError, KeyError):
347 except (TypeError, KeyError):
338 pass
348 pass
339 else:
349 else:
340 return printer(obj, self, cycle)
350 return printer(obj, self, cycle)
341 # Next walk the mro and check for either:
351 # Next walk the mro and check for either:
342 # 1) a registered printer
352 # 1) a registered printer
343 # 2) a _repr_pretty_ method
353 # 2) a _repr_pretty_ method
344 for cls in _get_mro(obj_class):
354 for cls in _get_mro(obj_class):
345 if cls in self.type_pprinters:
355 if cls in self.type_pprinters:
346 # printer registered in self.type_pprinters
356 # printer registered in self.type_pprinters
347 return self.type_pprinters[cls](obj, self, cycle)
357 return self.type_pprinters[cls](obj, self, cycle)
348 else:
358 else:
349 # deferred printer
359 # deferred printer
350 printer = self._in_deferred_types(cls)
360 printer = self._in_deferred_types(cls)
351 if printer is not None:
361 if printer is not None:
352 return printer(obj, self, cycle)
362 return printer(obj, self, cycle)
353 else:
363 else:
354 # Finally look for special method names.
364 # Finally look for special method names.
355 # Some objects automatically create any requested
365 # Some objects automatically create any requested
356 # attribute. Try to ignore most of them by checking for
366 # attribute. Try to ignore most of them by checking for
357 # callability.
367 # callability.
358 if '_repr_pretty_' in cls.__dict__:
368 if '_repr_pretty_' in cls.__dict__:
359 meth = cls._repr_pretty_
369 meth = cls._repr_pretty_
360 if callable(meth):
370 if callable(meth):
361 return meth(obj, self, cycle)
371 return meth(obj, self, cycle)
362 return _default_pprint(obj, self, cycle)
372 return _default_pprint(obj, self, cycle)
363 finally:
373 finally:
364 self.end_group()
374 self.end_group()
365 self.stack.pop()
375 self.stack.pop()
366
376
367 def _in_deferred_types(self, cls):
377 def _in_deferred_types(self, cls):
368 """
378 """
369 Check if the given class is specified in the deferred type registry.
379 Check if the given class is specified in the deferred type registry.
370
380
371 Returns the printer from the registry if it exists, and None if the
381 Returns the printer from the registry if it exists, and None if the
372 class is not in the registry. Successful matches will be moved to the
382 class is not in the registry. Successful matches will be moved to the
373 regular type registry for future use.
383 regular type registry for future use.
374 """
384 """
375 mod = getattr(cls, '__module__', None)
385 mod = getattr(cls, '__module__', None)
376 name = getattr(cls, '__name__', None)
386 name = getattr(cls, '__name__', None)
377 key = (mod, name)
387 key = (mod, name)
378 printer = None
388 printer = None
379 if key in self.deferred_pprinters:
389 if key in self.deferred_pprinters:
380 # Move the printer over to the regular registry.
390 # Move the printer over to the regular registry.
381 printer = self.deferred_pprinters.pop(key)
391 printer = self.deferred_pprinters.pop(key)
382 self.type_pprinters[cls] = printer
392 self.type_pprinters[cls] = printer
383 return printer
393 return printer
384
394
385
395
386 class Printable(object):
396 class Printable(object):
387
397
388 def output(self, stream, output_width):
398 def output(self, stream, output_width):
389 return output_width
399 return output_width
390
400
391
401
392 class Text(Printable):
402 class Text(Printable):
393
403
394 def __init__(self):
404 def __init__(self):
395 self.objs = []
405 self.objs = []
396 self.width = 0
406 self.width = 0
397
407
398 def output(self, stream, output_width):
408 def output(self, stream, output_width):
399 for obj in self.objs:
409 for obj in self.objs:
400 stream.write(obj)
410 stream.write(obj)
401 return output_width + self.width
411 return output_width + self.width
402
412
403 def add(self, obj, width):
413 def add(self, obj, width):
404 self.objs.append(obj)
414 self.objs.append(obj)
405 self.width += width
415 self.width += width
406
416
407
417
408 class Breakable(Printable):
418 class Breakable(Printable):
409
419
410 def __init__(self, seq, width, pretty):
420 def __init__(self, seq, width, pretty):
411 self.obj = seq
421 self.obj = seq
412 self.width = width
422 self.width = width
413 self.pretty = pretty
423 self.pretty = pretty
414 self.indentation = pretty.indentation
424 self.indentation = pretty.indentation
415 self.group = pretty.group_stack[-1]
425 self.group = pretty.group_stack[-1]
416 self.group.breakables.append(self)
426 self.group.breakables.append(self)
417
427
418 def output(self, stream, output_width):
428 def output(self, stream, output_width):
419 self.group.breakables.popleft()
429 self.group.breakables.popleft()
420 if self.group.want_break:
430 if self.group.want_break:
421 stream.write(self.pretty.newline)
431 stream.write(self.pretty.newline)
422 stream.write(' ' * self.indentation)
432 stream.write(' ' * self.indentation)
423 return self.indentation
433 return self.indentation
424 if not self.group.breakables:
434 if not self.group.breakables:
425 self.pretty.group_queue.remove(self.group)
435 self.pretty.group_queue.remove(self.group)
426 stream.write(self.obj)
436 stream.write(self.obj)
427 return output_width + self.width
437 return output_width + self.width
428
438
429
439
430 class Group(Printable):
440 class Group(Printable):
431
441
432 def __init__(self, depth):
442 def __init__(self, depth):
433 self.depth = depth
443 self.depth = depth
434 self.breakables = deque()
444 self.breakables = deque()
435 self.want_break = False
445 self.want_break = False
436
446
437
447
438 class GroupQueue(object):
448 class GroupQueue(object):
439
449
440 def __init__(self, *groups):
450 def __init__(self, *groups):
441 self.queue = []
451 self.queue = []
442 for group in groups:
452 for group in groups:
443 self.enq(group)
453 self.enq(group)
444
454
445 def enq(self, group):
455 def enq(self, group):
446 depth = group.depth
456 depth = group.depth
447 while depth > len(self.queue) - 1:
457 while depth > len(self.queue) - 1:
448 self.queue.append([])
458 self.queue.append([])
449 self.queue[depth].append(group)
459 self.queue[depth].append(group)
450
460
451 def deq(self):
461 def deq(self):
452 for stack in self.queue:
462 for stack in self.queue:
453 for idx, group in enumerate(reversed(stack)):
463 for idx, group in enumerate(reversed(stack)):
454 if group.breakables:
464 if group.breakables:
455 del stack[idx]
465 del stack[idx]
456 group.want_break = True
466 group.want_break = True
457 return group
467 return group
458 for group in stack:
468 for group in stack:
459 group.want_break = True
469 group.want_break = True
460 del stack[:]
470 del stack[:]
461
471
462 def remove(self, group):
472 def remove(self, group):
463 try:
473 try:
464 self.queue[group.depth].remove(group)
474 self.queue[group.depth].remove(group)
465 except ValueError:
475 except ValueError:
466 pass
476 pass
467
477
468 try:
478 try:
469 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
479 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
470 except AttributeError: # Python 3
480 except AttributeError: # Python 3
471 _baseclass_reprs = (object.__repr__,)
481 _baseclass_reprs = (object.__repr__,)
472
482
473
483
474 def _default_pprint(obj, p, cycle):
484 def _default_pprint(obj, p, cycle):
475 """
485 """
476 The default print function. Used if an object does not provide one and
486 The default print function. Used if an object does not provide one and
477 it's none of the builtin objects.
487 it's none of the builtin objects.
478 """
488 """
479 klass = getattr(obj, '__class__', None) or type(obj)
489 klass = getattr(obj, '__class__', None) or type(obj)
480 if getattr(klass, '__repr__', None) not in _baseclass_reprs:
490 if getattr(klass, '__repr__', None) not in _baseclass_reprs:
481 # A user-provided repr.
491 # A user-provided repr. Find newlines and replace them with p.break_()
482 p.text(repr(obj))
492 output = repr(obj)
493 for idx,output_line in enumerate(output.splitlines()):
494 if idx:
495 p.break_()
496 p.text(output_line)
483 return
497 return
484 p.begin_group(1, '<')
498 p.begin_group(1, '<')
485 p.pretty(klass)
499 p.pretty(klass)
486 p.text(' at 0x%x' % id(obj))
500 p.text(' at 0x%x' % id(obj))
487 if cycle:
501 if cycle:
488 p.text(' ...')
502 p.text(' ...')
489 elif p.verbose:
503 elif p.verbose:
490 first = True
504 first = True
491 for key in dir(obj):
505 for key in dir(obj):
492 if not key.startswith('_'):
506 if not key.startswith('_'):
493 try:
507 try:
494 value = getattr(obj, key)
508 value = getattr(obj, key)
495 except AttributeError:
509 except AttributeError:
496 continue
510 continue
497 if isinstance(value, types.MethodType):
511 if isinstance(value, types.MethodType):
498 continue
512 continue
499 if not first:
513 if not first:
500 p.text(',')
514 p.text(',')
501 p.breakable()
515 p.breakable()
502 p.text(key)
516 p.text(key)
503 p.text('=')
517 p.text('=')
504 step = len(key) + 1
518 step = len(key) + 1
505 p.indentation += step
519 p.indentation += step
506 p.pretty(value)
520 p.pretty(value)
507 p.indentation -= step
521 p.indentation -= step
508 first = False
522 first = False
509 p.end_group(1, '>')
523 p.end_group(1, '>')
510
524
511
525
512 def _seq_pprinter_factory(start, end, basetype):
526 def _seq_pprinter_factory(start, end, basetype):
513 """
527 """
514 Factory that returns a pprint function useful for sequences. Used by
528 Factory that returns a pprint function useful for sequences. Used by
515 the default pprint for tuples, dicts, and lists.
529 the default pprint for tuples, dicts, and lists.
516 """
530 """
517 def inner(obj, p, cycle):
531 def inner(obj, p, cycle):
518 typ = type(obj)
532 typ = type(obj)
519 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
533 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
520 # If the subclass provides its own repr, use it instead.
534 # If the subclass provides its own repr, use it instead.
521 return p.text(typ.__repr__(obj))
535 return p.text(typ.__repr__(obj))
522
536
523 if cycle:
537 if cycle:
524 return p.text(start + '...' + end)
538 return p.text(start + '...' + end)
525 step = len(start)
539 step = len(start)
526 p.begin_group(step, start)
540 p.begin_group(step, start)
527 for idx, x in enumerate(obj):
541 for idx, x in enumerate(obj):
528 if idx:
542 if idx:
529 p.text(',')
543 p.text(',')
530 p.breakable()
544 p.breakable()
531 p.pretty(x)
545 p.pretty(x)
532 if len(obj) == 1 and type(obj) is tuple:
546 if len(obj) == 1 and type(obj) is tuple:
533 # Special case for 1-item tuples.
547 # Special case for 1-item tuples.
534 p.text(',')
548 p.text(',')
535 p.end_group(step, end)
549 p.end_group(step, end)
536 return inner
550 return inner
537
551
538
552
539 def _set_pprinter_factory(start, end, basetype):
553 def _set_pprinter_factory(start, end, basetype):
540 """
554 """
541 Factory that returns a pprint function useful for sets and frozensets.
555 Factory that returns a pprint function useful for sets and frozensets.
542 """
556 """
543 def inner(obj, p, cycle):
557 def inner(obj, p, cycle):
544 typ = type(obj)
558 typ = type(obj)
545 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
559 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
546 # If the subclass provides its own repr, use it instead.
560 # If the subclass provides its own repr, use it instead.
547 return p.text(typ.__repr__(obj))
561 return p.text(typ.__repr__(obj))
548
562
549 if cycle:
563 if cycle:
550 return p.text(start + '...' + end)
564 return p.text(start + '...' + end)
551 if len(obj) == 0:
565 if len(obj) == 0:
552 # Special case.
566 # Special case.
553 p.text(basetype.__name__ + '()')
567 p.text(basetype.__name__ + '()')
554 else:
568 else:
555 step = len(start)
569 step = len(start)
556 p.begin_group(step, start)
570 p.begin_group(step, start)
557 # Like dictionary keys, we will try to sort the items.
571 # Like dictionary keys, we will try to sort the items.
558 items = list(obj)
572 items = list(obj)
559 try:
573 try:
560 items.sort()
574 items.sort()
561 except Exception:
575 except Exception:
562 # Sometimes the items don't sort.
576 # Sometimes the items don't sort.
563 pass
577 pass
564 for idx, x in enumerate(items):
578 for idx, x in enumerate(items):
565 if idx:
579 if idx:
566 p.text(',')
580 p.text(',')
567 p.breakable()
581 p.breakable()
568 p.pretty(x)
582 p.pretty(x)
569 p.end_group(step, end)
583 p.end_group(step, end)
570 return inner
584 return inner
571
585
572
586
573 def _dict_pprinter_factory(start, end, basetype=None):
587 def _dict_pprinter_factory(start, end, basetype=None):
574 """
588 """
575 Factory that returns a pprint function used by the default pprint of
589 Factory that returns a pprint function used by the default pprint of
576 dicts and dict proxies.
590 dicts and dict proxies.
577 """
591 """
578 def inner(obj, p, cycle):
592 def inner(obj, p, cycle):
579 typ = type(obj)
593 typ = type(obj)
580 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
594 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
581 # If the subclass provides its own repr, use it instead.
595 # If the subclass provides its own repr, use it instead.
582 return p.text(typ.__repr__(obj))
596 return p.text(typ.__repr__(obj))
583
597
584 if cycle:
598 if cycle:
585 return p.text('{...}')
599 return p.text('{...}')
586 p.begin_group(1, start)
600 p.begin_group(1, start)
587 keys = obj.keys()
601 keys = obj.keys()
588 try:
602 try:
589 keys.sort()
603 keys.sort()
590 except Exception as e:
604 except Exception as e:
591 # Sometimes the keys don't sort.
605 # Sometimes the keys don't sort.
592 pass
606 pass
593 for idx, key in enumerate(keys):
607 for idx, key in enumerate(keys):
594 if idx:
608 if idx:
595 p.text(',')
609 p.text(',')
596 p.breakable()
610 p.breakable()
597 p.pretty(key)
611 p.pretty(key)
598 p.text(': ')
612 p.text(': ')
599 p.pretty(obj[key])
613 p.pretty(obj[key])
600 p.end_group(1, end)
614 p.end_group(1, end)
601 return inner
615 return inner
602
616
603
617
604 def _super_pprint(obj, p, cycle):
618 def _super_pprint(obj, p, cycle):
605 """The pprint for the super type."""
619 """The pprint for the super type."""
606 p.begin_group(8, '<super: ')
620 p.begin_group(8, '<super: ')
607 p.pretty(obj.__self_class__)
621 p.pretty(obj.__self_class__)
608 p.text(',')
622 p.text(',')
609 p.breakable()
623 p.breakable()
610 p.pretty(obj.__self__)
624 p.pretty(obj.__self__)
611 p.end_group(8, '>')
625 p.end_group(8, '>')
612
626
613
627
614 def _re_pattern_pprint(obj, p, cycle):
628 def _re_pattern_pprint(obj, p, cycle):
615 """The pprint function for regular expression patterns."""
629 """The pprint function for regular expression patterns."""
616 p.text('re.compile(')
630 p.text('re.compile(')
617 pattern = repr(obj.pattern)
631 pattern = repr(obj.pattern)
618 if pattern[:1] in 'uU':
632 if pattern[:1] in 'uU':
619 pattern = pattern[1:]
633 pattern = pattern[1:]
620 prefix = 'ur'
634 prefix = 'ur'
621 else:
635 else:
622 prefix = 'r'
636 prefix = 'r'
623 pattern = prefix + pattern.replace('\\\\', '\\')
637 pattern = prefix + pattern.replace('\\\\', '\\')
624 p.text(pattern)
638 p.text(pattern)
625 if obj.flags:
639 if obj.flags:
626 p.text(',')
640 p.text(',')
627 p.breakable()
641 p.breakable()
628 done_one = False
642 done_one = False
629 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
643 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
630 'UNICODE', 'VERBOSE', 'DEBUG'):
644 'UNICODE', 'VERBOSE', 'DEBUG'):
631 if obj.flags & getattr(re, flag):
645 if obj.flags & getattr(re, flag):
632 if done_one:
646 if done_one:
633 p.text('|')
647 p.text('|')
634 p.text('re.' + flag)
648 p.text('re.' + flag)
635 done_one = True
649 done_one = True
636 p.text(')')
650 p.text(')')
637
651
638
652
639 def _type_pprint(obj, p, cycle):
653 def _type_pprint(obj, p, cycle):
640 """The pprint for classes and types."""
654 """The pprint for classes and types."""
641 mod = getattr(obj, '__module__', None)
655 mod = getattr(obj, '__module__', None)
642 if mod is None:
656 if mod is None:
643 # Heap allocated types might not have the module attribute,
657 # Heap allocated types might not have the module attribute,
644 # and others may set it to None.
658 # and others may set it to None.
645 return p.text(obj.__name__)
659 return p.text(obj.__name__)
646
660
647 if mod in ('__builtin__', 'exceptions'):
661 if mod in ('__builtin__', 'exceptions'):
648 name = obj.__name__
662 name = obj.__name__
649 else:
663 else:
650 name = mod + '.' + obj.__name__
664 name = mod + '.' + obj.__name__
651 p.text(name)
665 p.text(name)
652
666
653
667
654 def _repr_pprint(obj, p, cycle):
668 def _repr_pprint(obj, p, cycle):
655 """A pprint that just redirects to the normal repr function."""
669 """A pprint that just redirects to the normal repr function."""
656 p.text(repr(obj))
670 p.text(repr(obj))
657
671
658
672
659 def _function_pprint(obj, p, cycle):
673 def _function_pprint(obj, p, cycle):
660 """Base pprint for all functions and builtin functions."""
674 """Base pprint for all functions and builtin functions."""
661 if obj.__module__ in ('__builtin__', 'exceptions') or not obj.__module__:
675 if obj.__module__ in ('__builtin__', 'exceptions') or not obj.__module__:
662 name = obj.__name__
676 name = obj.__name__
663 else:
677 else:
664 name = obj.__module__ + '.' + obj.__name__
678 name = obj.__module__ + '.' + obj.__name__
665 p.text('<function %s>' % name)
679 p.text('<function %s>' % name)
666
680
667
681
668 def _exception_pprint(obj, p, cycle):
682 def _exception_pprint(obj, p, cycle):
669 """Base pprint for all exceptions."""
683 """Base pprint for all exceptions."""
670 if obj.__class__.__module__ in ('exceptions', 'builtins'):
684 if obj.__class__.__module__ in ('exceptions', 'builtins'):
671 name = obj.__class__.__name__
685 name = obj.__class__.__name__
672 else:
686 else:
673 name = '%s.%s' % (
687 name = '%s.%s' % (
674 obj.__class__.__module__,
688 obj.__class__.__module__,
675 obj.__class__.__name__
689 obj.__class__.__name__
676 )
690 )
677 step = len(name) + 1
691 step = len(name) + 1
678 p.begin_group(step, name + '(')
692 p.begin_group(step, name + '(')
679 for idx, arg in enumerate(getattr(obj, 'args', ())):
693 for idx, arg in enumerate(getattr(obj, 'args', ())):
680 if idx:
694 if idx:
681 p.text(',')
695 p.text(',')
682 p.breakable()
696 p.breakable()
683 p.pretty(arg)
697 p.pretty(arg)
684 p.end_group(step, ')')
698 p.end_group(step, ')')
685
699
686
700
687 #: the exception base
701 #: the exception base
688 try:
702 try:
689 _exception_base = BaseException
703 _exception_base = BaseException
690 except NameError:
704 except NameError:
691 _exception_base = Exception
705 _exception_base = Exception
692
706
693
707
694 #: printers for builtin types
708 #: printers for builtin types
695 _type_pprinters = {
709 _type_pprinters = {
696 int: _repr_pprint,
710 int: _repr_pprint,
697 long: _repr_pprint,
711 long: _repr_pprint,
698 float: _repr_pprint,
712 float: _repr_pprint,
699 str: _repr_pprint,
713 str: _repr_pprint,
700 unicode: _repr_pprint,
714 unicode: _repr_pprint,
701 tuple: _seq_pprinter_factory('(', ')', tuple),
715 tuple: _seq_pprinter_factory('(', ')', tuple),
702 list: _seq_pprinter_factory('[', ']', list),
716 list: _seq_pprinter_factory('[', ']', list),
703 dict: _dict_pprinter_factory('{', '}', dict),
717 dict: _dict_pprinter_factory('{', '}', dict),
704
718
705 set: _set_pprinter_factory('{', '}', set),
719 set: _set_pprinter_factory('{', '}', set),
706 frozenset: _set_pprinter_factory('frozenset({', '})', frozenset),
720 frozenset: _set_pprinter_factory('frozenset({', '})', frozenset),
707 super: _super_pprint,
721 super: _super_pprint,
708 _re_pattern_type: _re_pattern_pprint,
722 _re_pattern_type: _re_pattern_pprint,
709 type: _type_pprint,
723 type: _type_pprint,
710 types.FunctionType: _function_pprint,
724 types.FunctionType: _function_pprint,
711 types.BuiltinFunctionType: _function_pprint,
725 types.BuiltinFunctionType: _function_pprint,
712 types.SliceType: _repr_pprint,
726 types.SliceType: _repr_pprint,
713 types.MethodType: _repr_pprint,
727 types.MethodType: _repr_pprint,
714
728
715 datetime.datetime: _repr_pprint,
729 datetime.datetime: _repr_pprint,
716 datetime.timedelta: _repr_pprint,
730 datetime.timedelta: _repr_pprint,
717 _exception_base: _exception_pprint
731 _exception_base: _exception_pprint
718 }
732 }
719
733
720 try:
734 try:
721 _type_pprinters[types.DictProxyType] = _dict_pprinter_factory('<dictproxy {', '}>')
735 _type_pprinters[types.DictProxyType] = _dict_pprinter_factory('<dictproxy {', '}>')
722 _type_pprinters[types.ClassType] = _type_pprint
736 _type_pprinters[types.ClassType] = _type_pprint
723 except AttributeError: # Python 3
737 except AttributeError: # Python 3
724 pass
738 pass
725
739
726 try:
740 try:
727 _type_pprinters[xrange] = _repr_pprint
741 _type_pprinters[xrange] = _repr_pprint
728 except NameError:
742 except NameError:
729 _type_pprinters[range] = _repr_pprint
743 _type_pprinters[range] = _repr_pprint
730
744
731 #: printers for types specified by name
745 #: printers for types specified by name
732 _deferred_type_pprinters = {
746 _deferred_type_pprinters = {
733 }
747 }
734
748
735 def for_type(typ, func):
749 def for_type(typ, func):
736 """
750 """
737 Add a pretty printer for a given type.
751 Add a pretty printer for a given type.
738 """
752 """
739 oldfunc = _type_pprinters.get(typ, None)
753 oldfunc = _type_pprinters.get(typ, None)
740 if func is not None:
754 if func is not None:
741 # To support easy restoration of old pprinters, we need to ignore Nones.
755 # To support easy restoration of old pprinters, we need to ignore Nones.
742 _type_pprinters[typ] = func
756 _type_pprinters[typ] = func
743 return oldfunc
757 return oldfunc
744
758
745 def for_type_by_name(type_module, type_name, func):
759 def for_type_by_name(type_module, type_name, func):
746 """
760 """
747 Add a pretty printer for a type specified by the module and name of a type
761 Add a pretty printer for a type specified by the module and name of a type
748 rather than the type object itself.
762 rather than the type object itself.
749 """
763 """
750 key = (type_module, type_name)
764 key = (type_module, type_name)
751 oldfunc = _deferred_type_pprinters.get(key, None)
765 oldfunc = _deferred_type_pprinters.get(key, None)
752 if func is not None:
766 if func is not None:
753 # To support easy restoration of old pprinters, we need to ignore Nones.
767 # To support easy restoration of old pprinters, we need to ignore Nones.
754 _deferred_type_pprinters[key] = func
768 _deferred_type_pprinters[key] = func
755 return oldfunc
769 return oldfunc
756
770
757
771
758 #: printers for the default singletons
772 #: printers for the default singletons
759 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
773 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
760 NotImplemented]), _repr_pprint)
774 NotImplemented]), _repr_pprint)
761
775
762
776
763 if __name__ == '__main__':
777 if __name__ == '__main__':
764 from random import randrange
778 from random import randrange
765 class Foo(object):
779 class Foo(object):
766 def __init__(self):
780 def __init__(self):
767 self.foo = 1
781 self.foo = 1
768 self.bar = re.compile(r'\s+')
782 self.bar = re.compile(r'\s+')
769 self.blub = dict.fromkeys(range(30), randrange(1, 40))
783 self.blub = dict.fromkeys(range(30), randrange(1, 40))
770 self.hehe = 23424.234234
784 self.hehe = 23424.234234
771 self.list = ["blub", "blah", self]
785 self.list = ["blub", "blah", self]
772
786
773 def get_foo(self):
787 def get_foo(self):
774 print "foo"
788 print "foo"
775
789
776 pprint(Foo(), verbose=True)
790 pprint(Foo(), verbose=True)
@@ -1,120 +1,153 b''
1 """Tests for IPython.lib.pretty.
1 """Tests for IPython.lib.pretty.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2011, the IPython Development Team.
4 # Copyright (c) 2011, the IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
14 from __future__ import print_function
15
15
16 # Third-party imports
16 # Third-party imports
17 import nose.tools as nt
17 import nose.tools as nt
18
18
19 # Our own imports
19 # Our own imports
20 from IPython.lib import pretty
20 from IPython.lib import pretty
21 from IPython.testing.decorators import skip_without
21 from IPython.testing.decorators import skip_without
22
22
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Classes and functions
24 # Classes and functions
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26
26
27 class MyList(object):
27 class MyList(object):
28 def __init__(self, content):
28 def __init__(self, content):
29 self.content = content
29 self.content = content
30 def _repr_pretty_(self, p, cycle):
30 def _repr_pretty_(self, p, cycle):
31 if cycle:
31 if cycle:
32 p.text("MyList(...)")
32 p.text("MyList(...)")
33 else:
33 else:
34 with p.group(3, "MyList(", ")"):
34 with p.group(3, "MyList(", ")"):
35 for (i, child) in enumerate(self.content):
35 for (i, child) in enumerate(self.content):
36 if i:
36 if i:
37 p.text(",")
37 p.text(",")
38 p.breakable()
38 p.breakable()
39 else:
39 else:
40 p.breakable("")
40 p.breakable("")
41 p.pretty(child)
41 p.pretty(child)
42
42
43
43
44 class MyDict(dict):
44 class MyDict(dict):
45 def _repr_pretty_(self, p, cycle):
45 def _repr_pretty_(self, p, cycle):
46 p.text("MyDict(...)")
46 p.text("MyDict(...)")
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):
62 def _repr_pretty_(self, p, cycle):
63 with p.group(4,"TG: ",":"):
64 p.text("Breaking(")
65 p.break_()
66 p.text(")")
67
68 class BreakingRepr(object):
69 def __repr__(self):
70 return "Breaking(\n)"
71
72 class BreakingReprParent(object):
73 def _repr_pretty_(self, p, cycle):
74 with p.group(4,"TG: ",":"):
75 p.pretty(BreakingRepr())
76
77
61
78
62 def test_indentation():
79 def test_indentation():
63 """Test correct indentation in groups"""
80 """Test correct indentation in groups"""
64 count = 40
81 count = 40
65 gotoutput = pretty.pretty(MyList(range(count)))
82 gotoutput = pretty.pretty(MyList(range(count)))
66 expectedoutput = "MyList(\n" + ",\n".join(" %d" % i for i in range(count)) + ")"
83 expectedoutput = "MyList(\n" + ",\n".join(" %d" % i for i in range(count)) + ")"
67
84
68 nt.assert_equal(gotoutput, expectedoutput)
85 nt.assert_equal(gotoutput, expectedoutput)
69
86
70
87
71 def test_dispatch():
88 def test_dispatch():
72 """
89 """
73 Test correct dispatching: The _repr_pretty_ method for MyDict
90 Test correct dispatching: The _repr_pretty_ method for MyDict
74 must be found before the registered printer for dict.
91 must be found before the registered printer for dict.
75 """
92 """
76 gotoutput = pretty.pretty(MyDict())
93 gotoutput = pretty.pretty(MyDict())
77 expectedoutput = "MyDict(...)"
94 expectedoutput = "MyDict(...)"
78
95
79 nt.assert_equal(gotoutput, expectedoutput)
96 nt.assert_equal(gotoutput, expectedoutput)
80
97
81
98
82 def test_callability_checking():
99 def test_callability_checking():
83 """
100 """
84 Test that the _repr_pretty_ method is tested for callability and skipped if
101 Test that the _repr_pretty_ method is tested for callability and skipped if
85 not.
102 not.
86 """
103 """
87 gotoutput = pretty.pretty(Dummy2())
104 gotoutput = pretty.pretty(Dummy2())
88 expectedoutput = "Dummy1(...)"
105 expectedoutput = "Dummy1(...)"
89
106
90 nt.assert_equal(gotoutput, expectedoutput)
107 nt.assert_equal(gotoutput, expectedoutput)
91
108
92
109
93 def test_sets():
110 def test_sets():
94 """
111 """
95 Test that set and frozenset use Python 3 formatting.
112 Test that set and frozenset use Python 3 formatting.
96 """
113 """
97 objects = [set(), frozenset(), set([1]), frozenset([1]), set([1, 2]),
114 objects = [set(), frozenset(), set([1]), frozenset([1]), set([1, 2]),
98 frozenset([1, 2]), set([-1, -2, -3])]
115 frozenset([1, 2]), set([-1, -2, -3])]
99 expected = ['set()', 'frozenset()', '{1}', 'frozenset({1})', '{1, 2}',
116 expected = ['set()', 'frozenset()', '{1}', 'frozenset({1})', '{1, 2}',
100 'frozenset({1, 2})', '{-3, -2, -1}']
117 'frozenset({1, 2})', '{-3, -2, -1}']
101 for obj, expected_output in zip(objects, expected):
118 for obj, expected_output in zip(objects, expected):
102 got_output = pretty.pretty(obj)
119 got_output = pretty.pretty(obj)
103 yield nt.assert_equal, got_output, expected_output
120 yield nt.assert_equal, got_output, expected_output
104
121
105
122
106 @skip_without('xxlimited')
123 @skip_without('xxlimited')
107 def test_pprint_heap_allocated_type():
124 def test_pprint_heap_allocated_type():
108 """
125 """
109 Test that pprint works for heap allocated types.
126 Test that pprint works for heap allocated types.
110 """
127 """
111 import xxlimited
128 import xxlimited
112 output = pretty.pretty(xxlimited.Null)
129 output = pretty.pretty(xxlimited.Null)
113 nt.assert_equal(output, 'xxlimited.Null')
130 nt.assert_equal(output, 'xxlimited.Null')
114
131
115 def test_pprint_nomod():
132 def test_pprint_nomod():
116 """
133 """
117 Test that pprint works for classes with no __module__.
134 Test that pprint works for classes with no __module__.
118 """
135 """
119 output = pretty.pretty(NoModule)
136 output = pretty.pretty(NoModule)
120 nt.assert_equal(output, 'NoModule')
137 nt.assert_equal(output, 'NoModule')
138
139 def test_pprint_break():
140 """
141 Test that p.break_ produces expected output
142 """
143 output = pretty.pretty(Breaking())
144 expected = "TG: Breaking(\n ):"
145 nt.assert_equal(output, expected)
146
147 def test_pprint_break_repr():
148 """
149 Test that p.break_ is used in repr
150 """
151 output = pretty.pretty(BreakingReprParent())
152 expected = "TG: Breaking(\n ):"
153 nt.assert_equal(output, expected) No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now