##// END OF EJS Templates
Uses p.break_() when repr() is used for printing...
Alex Rudy -
Show More
@@ -1,786 +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 233 def break_(self):
234 234 """
235 235 Explicitly insert a newline into the output, maintaining correct indentation.
236 236 """
237 237 self.flush()
238 238 self.output.write(self.newline)
239 239 self.output.write(' ' * self.indentation)
240 240 self.output_width = self.indentation
241 241 self.buffer_width = 0
242 242
243 243
244 244 def begin_group(self, indent=0, open=''):
245 245 """
246 246 Begin a group. If you want support for python < 2.5 which doesn't has
247 247 the with statement this is the preferred way:
248 248
249 249 p.begin_group(1, '{')
250 250 ...
251 251 p.end_group(1, '}')
252 252
253 253 The python 2.5 expression would be this:
254 254
255 255 with p.group(1, '{', '}'):
256 256 ...
257 257
258 258 The first parameter specifies the indentation for the next line (usually
259 259 the width of the opening text), the second the opening text. All
260 260 parameters are optional.
261 261 """
262 262 if open:
263 263 self.text(open)
264 264 group = Group(self.group_stack[-1].depth + 1)
265 265 self.group_stack.append(group)
266 266 self.group_queue.enq(group)
267 267 self.indentation += indent
268 268
269 269 def end_group(self, dedent=0, close=''):
270 270 """End a group. See `begin_group` for more details."""
271 271 self.indentation -= dedent
272 272 group = self.group_stack.pop()
273 273 if not group.breakables:
274 274 self.group_queue.remove(group)
275 275 if close:
276 276 self.text(close)
277 277
278 278 def flush(self):
279 279 """Flush data that is left in the buffer."""
280 280 for data in self.buffer:
281 281 self.output_width += data.output(self.output, self.output_width)
282 282 self.buffer.clear()
283 283 self.buffer_width = 0
284 284
285 285
286 286 def _get_mro(obj_class):
287 287 """ Get a reasonable method resolution order of a class and its superclasses
288 288 for both old-style and new-style classes.
289 289 """
290 290 if not hasattr(obj_class, '__mro__'):
291 291 # Old-style class. Mix in object to make a fake new-style class.
292 292 try:
293 293 obj_class = type(obj_class.__name__, (obj_class, object), {})
294 294 except TypeError:
295 295 # Old-style extension type that does not descend from object.
296 296 # FIXME: try to construct a more thorough MRO.
297 297 mro = [obj_class]
298 298 else:
299 299 mro = obj_class.__mro__[1:-1]
300 300 else:
301 301 mro = obj_class.__mro__
302 302 return mro
303 303
304 304
305 305 class RepresentationPrinter(PrettyPrinter):
306 306 """
307 307 Special pretty printer that has a `pretty` method that calls the pretty
308 308 printer for a python object.
309 309
310 310 This class stores processing data on `self` so you must *never* use
311 311 this class in a threaded environment. Always lock it or reinstanciate
312 312 it.
313 313
314 314 Instances also have a verbose flag callbacks can access to control their
315 315 output. For example the default instance repr prints all attributes and
316 316 methods that are not prefixed by an underscore if the printer is in
317 317 verbose mode.
318 318 """
319 319
320 320 def __init__(self, output, verbose=False, max_width=79, newline='\n',
321 321 singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None):
322 322
323 323 PrettyPrinter.__init__(self, output, max_width, newline)
324 324 self.verbose = verbose
325 325 self.stack = []
326 326 if singleton_pprinters is None:
327 327 singleton_pprinters = _singleton_pprinters.copy()
328 328 self.singleton_pprinters = singleton_pprinters
329 329 if type_pprinters is None:
330 330 type_pprinters = _type_pprinters.copy()
331 331 self.type_pprinters = type_pprinters
332 332 if deferred_pprinters is None:
333 333 deferred_pprinters = _deferred_type_pprinters.copy()
334 334 self.deferred_pprinters = deferred_pprinters
335 335
336 336 def pretty(self, obj):
337 337 """Pretty print the given object."""
338 338 obj_id = id(obj)
339 339 cycle = obj_id in self.stack
340 340 self.stack.append(obj_id)
341 341 self.begin_group()
342 342 try:
343 343 obj_class = getattr(obj, '__class__', None) or type(obj)
344 344 # First try to find registered singleton printers for the type.
345 345 try:
346 346 printer = self.singleton_pprinters[obj_id]
347 347 except (TypeError, KeyError):
348 348 pass
349 349 else:
350 350 return printer(obj, self, cycle)
351 351 # Next walk the mro and check for either:
352 352 # 1) a registered printer
353 353 # 2) a _repr_pretty_ method
354 354 for cls in _get_mro(obj_class):
355 355 if cls in self.type_pprinters:
356 356 # printer registered in self.type_pprinters
357 357 return self.type_pprinters[cls](obj, self, cycle)
358 358 else:
359 359 # deferred printer
360 360 printer = self._in_deferred_types(cls)
361 361 if printer is not None:
362 362 return printer(obj, self, cycle)
363 363 else:
364 364 # Finally look for special method names.
365 365 # Some objects automatically create any requested
366 366 # attribute. Try to ignore most of them by checking for
367 367 # callability.
368 368 if '_repr_pretty_' in cls.__dict__:
369 369 meth = cls._repr_pretty_
370 370 if callable(meth):
371 371 return meth(obj, self, cycle)
372 372 return _default_pprint(obj, self, cycle)
373 373 finally:
374 374 self.end_group()
375 375 self.stack.pop()
376 376
377 377 def _in_deferred_types(self, cls):
378 378 """
379 379 Check if the given class is specified in the deferred type registry.
380 380
381 381 Returns the printer from the registry if it exists, and None if the
382 382 class is not in the registry. Successful matches will be moved to the
383 383 regular type registry for future use.
384 384 """
385 385 mod = getattr(cls, '__module__', None)
386 386 name = getattr(cls, '__name__', None)
387 387 key = (mod, name)
388 388 printer = None
389 389 if key in self.deferred_pprinters:
390 390 # Move the printer over to the regular registry.
391 391 printer = self.deferred_pprinters.pop(key)
392 392 self.type_pprinters[cls] = printer
393 393 return printer
394 394
395 395
396 396 class Printable(object):
397 397
398 398 def output(self, stream, output_width):
399 399 return output_width
400 400
401 401
402 402 class Text(Printable):
403 403
404 404 def __init__(self):
405 405 self.objs = []
406 406 self.width = 0
407 407
408 408 def output(self, stream, output_width):
409 409 for obj in self.objs:
410 410 stream.write(obj)
411 411 return output_width + self.width
412 412
413 413 def add(self, obj, width):
414 414 self.objs.append(obj)
415 415 self.width += width
416 416
417 417
418 418 class Breakable(Printable):
419 419
420 420 def __init__(self, seq, width, pretty):
421 421 self.obj = seq
422 422 self.width = width
423 423 self.pretty = pretty
424 424 self.indentation = pretty.indentation
425 425 self.group = pretty.group_stack[-1]
426 426 self.group.breakables.append(self)
427 427
428 428 def output(self, stream, output_width):
429 429 self.group.breakables.popleft()
430 430 if self.group.want_break:
431 431 stream.write(self.pretty.newline)
432 432 stream.write(' ' * self.indentation)
433 433 return self.indentation
434 434 if not self.group.breakables:
435 435 self.pretty.group_queue.remove(self.group)
436 436 stream.write(self.obj)
437 437 return output_width + self.width
438 438
439 439
440 440 class Group(Printable):
441 441
442 442 def __init__(self, depth):
443 443 self.depth = depth
444 444 self.breakables = deque()
445 445 self.want_break = False
446 446
447 447
448 448 class GroupQueue(object):
449 449
450 450 def __init__(self, *groups):
451 451 self.queue = []
452 452 for group in groups:
453 453 self.enq(group)
454 454
455 455 def enq(self, group):
456 456 depth = group.depth
457 457 while depth > len(self.queue) - 1:
458 458 self.queue.append([])
459 459 self.queue[depth].append(group)
460 460
461 461 def deq(self):
462 462 for stack in self.queue:
463 463 for idx, group in enumerate(reversed(stack)):
464 464 if group.breakables:
465 465 del stack[idx]
466 466 group.want_break = True
467 467 return group
468 468 for group in stack:
469 469 group.want_break = True
470 470 del stack[:]
471 471
472 472 def remove(self, group):
473 473 try:
474 474 self.queue[group.depth].remove(group)
475 475 except ValueError:
476 476 pass
477 477
478 478 try:
479 479 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
480 480 except AttributeError: # Python 3
481 481 _baseclass_reprs = (object.__repr__,)
482 482
483 483
484 484 def _default_pprint(obj, p, cycle):
485 485 """
486 486 The default print function. Used if an object does not provide one and
487 487 it's none of the builtin objects.
488 488 """
489 489 klass = getattr(obj, '__class__', None) or type(obj)
490 490 if getattr(klass, '__repr__', None) not in _baseclass_reprs:
491 # A user-provided repr.
492 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)
493 497 return
494 498 p.begin_group(1, '<')
495 499 p.pretty(klass)
496 500 p.text(' at 0x%x' % id(obj))
497 501 if cycle:
498 502 p.text(' ...')
499 503 elif p.verbose:
500 504 first = True
501 505 for key in dir(obj):
502 506 if not key.startswith('_'):
503 507 try:
504 508 value = getattr(obj, key)
505 509 except AttributeError:
506 510 continue
507 511 if isinstance(value, types.MethodType):
508 512 continue
509 513 if not first:
510 514 p.text(',')
511 515 p.breakable()
512 516 p.text(key)
513 517 p.text('=')
514 518 step = len(key) + 1
515 519 p.indentation += step
516 520 p.pretty(value)
517 521 p.indentation -= step
518 522 first = False
519 523 p.end_group(1, '>')
520 524
521 525
522 526 def _seq_pprinter_factory(start, end, basetype):
523 527 """
524 528 Factory that returns a pprint function useful for sequences. Used by
525 529 the default pprint for tuples, dicts, and lists.
526 530 """
527 531 def inner(obj, p, cycle):
528 532 typ = type(obj)
529 533 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
530 534 # If the subclass provides its own repr, use it instead.
531 535 return p.text(typ.__repr__(obj))
532 536
533 537 if cycle:
534 538 return p.text(start + '...' + end)
535 539 step = len(start)
536 540 p.begin_group(step, start)
537 541 for idx, x in enumerate(obj):
538 542 if idx:
539 543 p.text(',')
540 544 p.breakable()
541 545 p.pretty(x)
542 546 if len(obj) == 1 and type(obj) is tuple:
543 547 # Special case for 1-item tuples.
544 548 p.text(',')
545 549 p.end_group(step, end)
546 550 return inner
547 551
548 552
549 553 def _set_pprinter_factory(start, end, basetype):
550 554 """
551 555 Factory that returns a pprint function useful for sets and frozensets.
552 556 """
553 557 def inner(obj, p, cycle):
554 558 typ = type(obj)
555 559 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
556 560 # If the subclass provides its own repr, use it instead.
557 561 return p.text(typ.__repr__(obj))
558 562
559 563 if cycle:
560 564 return p.text(start + '...' + end)
561 565 if len(obj) == 0:
562 566 # Special case.
563 567 p.text(basetype.__name__ + '()')
564 568 else:
565 569 step = len(start)
566 570 p.begin_group(step, start)
567 571 # Like dictionary keys, we will try to sort the items.
568 572 items = list(obj)
569 573 try:
570 574 items.sort()
571 575 except Exception:
572 576 # Sometimes the items don't sort.
573 577 pass
574 578 for idx, x in enumerate(items):
575 579 if idx:
576 580 p.text(',')
577 581 p.breakable()
578 582 p.pretty(x)
579 583 p.end_group(step, end)
580 584 return inner
581 585
582 586
583 587 def _dict_pprinter_factory(start, end, basetype=None):
584 588 """
585 589 Factory that returns a pprint function used by the default pprint of
586 590 dicts and dict proxies.
587 591 """
588 592 def inner(obj, p, cycle):
589 593 typ = type(obj)
590 594 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
591 595 # If the subclass provides its own repr, use it instead.
592 596 return p.text(typ.__repr__(obj))
593 597
594 598 if cycle:
595 599 return p.text('{...}')
596 600 p.begin_group(1, start)
597 601 keys = obj.keys()
598 602 try:
599 603 keys.sort()
600 604 except Exception as e:
601 605 # Sometimes the keys don't sort.
602 606 pass
603 607 for idx, key in enumerate(keys):
604 608 if idx:
605 609 p.text(',')
606 610 p.breakable()
607 611 p.pretty(key)
608 612 p.text(': ')
609 613 p.pretty(obj[key])
610 614 p.end_group(1, end)
611 615 return inner
612 616
613 617
614 618 def _super_pprint(obj, p, cycle):
615 619 """The pprint for the super type."""
616 620 p.begin_group(8, '<super: ')
617 621 p.pretty(obj.__self_class__)
618 622 p.text(',')
619 623 p.breakable()
620 624 p.pretty(obj.__self__)
621 625 p.end_group(8, '>')
622 626
623 627
624 628 def _re_pattern_pprint(obj, p, cycle):
625 629 """The pprint function for regular expression patterns."""
626 630 p.text('re.compile(')
627 631 pattern = repr(obj.pattern)
628 632 if pattern[:1] in 'uU':
629 633 pattern = pattern[1:]
630 634 prefix = 'ur'
631 635 else:
632 636 prefix = 'r'
633 637 pattern = prefix + pattern.replace('\\\\', '\\')
634 638 p.text(pattern)
635 639 if obj.flags:
636 640 p.text(',')
637 641 p.breakable()
638 642 done_one = False
639 643 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
640 644 'UNICODE', 'VERBOSE', 'DEBUG'):
641 645 if obj.flags & getattr(re, flag):
642 646 if done_one:
643 647 p.text('|')
644 648 p.text('re.' + flag)
645 649 done_one = True
646 650 p.text(')')
647 651
648 652
649 653 def _type_pprint(obj, p, cycle):
650 654 """The pprint for classes and types."""
651 655 mod = getattr(obj, '__module__', None)
652 656 if mod is None:
653 657 # Heap allocated types might not have the module attribute,
654 658 # and others may set it to None.
655 659 return p.text(obj.__name__)
656 660
657 661 if mod in ('__builtin__', 'exceptions'):
658 662 name = obj.__name__
659 663 else:
660 664 name = mod + '.' + obj.__name__
661 665 p.text(name)
662 666
663 667
664 668 def _repr_pprint(obj, p, cycle):
665 669 """A pprint that just redirects to the normal repr function."""
666 670 p.text(repr(obj))
667 671
668 672
669 673 def _function_pprint(obj, p, cycle):
670 674 """Base pprint for all functions and builtin functions."""
671 675 if obj.__module__ in ('__builtin__', 'exceptions') or not obj.__module__:
672 676 name = obj.__name__
673 677 else:
674 678 name = obj.__module__ + '.' + obj.__name__
675 679 p.text('<function %s>' % name)
676 680
677 681
678 682 def _exception_pprint(obj, p, cycle):
679 683 """Base pprint for all exceptions."""
680 684 if obj.__class__.__module__ in ('exceptions', 'builtins'):
681 685 name = obj.__class__.__name__
682 686 else:
683 687 name = '%s.%s' % (
684 688 obj.__class__.__module__,
685 689 obj.__class__.__name__
686 690 )
687 691 step = len(name) + 1
688 692 p.begin_group(step, name + '(')
689 693 for idx, arg in enumerate(getattr(obj, 'args', ())):
690 694 if idx:
691 695 p.text(',')
692 696 p.breakable()
693 697 p.pretty(arg)
694 698 p.end_group(step, ')')
695 699
696 700
697 701 #: the exception base
698 702 try:
699 703 _exception_base = BaseException
700 704 except NameError:
701 705 _exception_base = Exception
702 706
703 707
704 708 #: printers for builtin types
705 709 _type_pprinters = {
706 710 int: _repr_pprint,
707 711 long: _repr_pprint,
708 712 float: _repr_pprint,
709 713 str: _repr_pprint,
710 714 unicode: _repr_pprint,
711 715 tuple: _seq_pprinter_factory('(', ')', tuple),
712 716 list: _seq_pprinter_factory('[', ']', list),
713 717 dict: _dict_pprinter_factory('{', '}', dict),
714 718
715 719 set: _set_pprinter_factory('{', '}', set),
716 720 frozenset: _set_pprinter_factory('frozenset({', '})', frozenset),
717 721 super: _super_pprint,
718 722 _re_pattern_type: _re_pattern_pprint,
719 723 type: _type_pprint,
720 724 types.FunctionType: _function_pprint,
721 725 types.BuiltinFunctionType: _function_pprint,
722 726 types.SliceType: _repr_pprint,
723 727 types.MethodType: _repr_pprint,
724 728
725 729 datetime.datetime: _repr_pprint,
726 730 datetime.timedelta: _repr_pprint,
727 731 _exception_base: _exception_pprint
728 732 }
729 733
730 734 try:
731 735 _type_pprinters[types.DictProxyType] = _dict_pprinter_factory('<dictproxy {', '}>')
732 736 _type_pprinters[types.ClassType] = _type_pprint
733 737 except AttributeError: # Python 3
734 738 pass
735 739
736 740 try:
737 741 _type_pprinters[xrange] = _repr_pprint
738 742 except NameError:
739 743 _type_pprinters[range] = _repr_pprint
740 744
741 745 #: printers for types specified by name
742 746 _deferred_type_pprinters = {
743 747 }
744 748
745 749 def for_type(typ, func):
746 750 """
747 751 Add a pretty printer for a given type.
748 752 """
749 753 oldfunc = _type_pprinters.get(typ, None)
750 754 if func is not None:
751 755 # To support easy restoration of old pprinters, we need to ignore Nones.
752 756 _type_pprinters[typ] = func
753 757 return oldfunc
754 758
755 759 def for_type_by_name(type_module, type_name, func):
756 760 """
757 761 Add a pretty printer for a type specified by the module and name of a type
758 762 rather than the type object itself.
759 763 """
760 764 key = (type_module, type_name)
761 765 oldfunc = _deferred_type_pprinters.get(key, None)
762 766 if func is not None:
763 767 # To support easy restoration of old pprinters, we need to ignore Nones.
764 768 _deferred_type_pprinters[key] = func
765 769 return oldfunc
766 770
767 771
768 772 #: printers for the default singletons
769 773 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
770 774 NotImplemented]), _repr_pprint)
771 775
772 776
773 777 if __name__ == '__main__':
774 778 from random import randrange
775 779 class Foo(object):
776 780 def __init__(self):
777 781 self.foo = 1
778 782 self.bar = re.compile(r'\s+')
779 783 self.blub = dict.fromkeys(range(30), randrange(1, 40))
780 784 self.hehe = 23424.234234
781 785 self.list = ["blub", "blah", self]
782 786
783 787 def get_foo(self):
784 788 print "foo"
785 789
786 790 pprint(Foo(), verbose=True)
@@ -1,135 +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 61 class Breaking(object):
62 62 def _repr_pretty_(self, p, cycle):
63 63 with p.group(4,"TG: ",":"):
64 64 p.text("Breaking(")
65 65 p.break_()
66 66 p.text(")")
67 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
68 78
69 79 def test_indentation():
70 80 """Test correct indentation in groups"""
71 81 count = 40
72 82 gotoutput = pretty.pretty(MyList(range(count)))
73 83 expectedoutput = "MyList(\n" + ",\n".join(" %d" % i for i in range(count)) + ")"
74 84
75 85 nt.assert_equal(gotoutput, expectedoutput)
76 86
77 87
78 88 def test_dispatch():
79 89 """
80 90 Test correct dispatching: The _repr_pretty_ method for MyDict
81 91 must be found before the registered printer for dict.
82 92 """
83 93 gotoutput = pretty.pretty(MyDict())
84 94 expectedoutput = "MyDict(...)"
85 95
86 96 nt.assert_equal(gotoutput, expectedoutput)
87 97
88 98
89 99 def test_callability_checking():
90 100 """
91 101 Test that the _repr_pretty_ method is tested for callability and skipped if
92 102 not.
93 103 """
94 104 gotoutput = pretty.pretty(Dummy2())
95 105 expectedoutput = "Dummy1(...)"
96 106
97 107 nt.assert_equal(gotoutput, expectedoutput)
98 108
99 109
100 110 def test_sets():
101 111 """
102 112 Test that set and frozenset use Python 3 formatting.
103 113 """
104 114 objects = [set(), frozenset(), set([1]), frozenset([1]), set([1, 2]),
105 115 frozenset([1, 2]), set([-1, -2, -3])]
106 116 expected = ['set()', 'frozenset()', '{1}', 'frozenset({1})', '{1, 2}',
107 117 'frozenset({1, 2})', '{-3, -2, -1}']
108 118 for obj, expected_output in zip(objects, expected):
109 119 got_output = pretty.pretty(obj)
110 120 yield nt.assert_equal, got_output, expected_output
111 121
112 122
113 123 @skip_without('xxlimited')
114 124 def test_pprint_heap_allocated_type():
115 125 """
116 126 Test that pprint works for heap allocated types.
117 127 """
118 128 import xxlimited
119 129 output = pretty.pretty(xxlimited.Null)
120 130 nt.assert_equal(output, 'xxlimited.Null')
121 131
122 132 def test_pprint_nomod():
123 133 """
124 134 Test that pprint works for classes with no __module__.
125 135 """
126 136 output = pretty.pretty(NoModule)
127 137 nt.assert_equal(output, 'NoModule')
128 138
129 139 def test_pprint_break():
130 140 """
131 141 Test that p.break_ produces expected output
132 142 """
133 143 output = pretty.pretty(Breaking())
134 144 expected = "TG: Breaking(\n ):"
135 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