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