##// END OF EJS Templates
elide long containers in pretty...
MinRK -
Show More
@@ -1,851 +1,870 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 print_function
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 collections import deque
113 113
114 114 from IPython.utils.py3compat import PY3
115 115
116 116 if PY3:
117 117 from io import StringIO
118 118 else:
119 119 from StringIO import StringIO
120 120
121 121
122 122 __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter',
123 123 'for_type', 'for_type_by_name']
124 124
125 SEQ_LENGTH_LIMIT = 1000
125 126
126 127 _re_pattern_type = type(re.compile(''))
127 128
128 129 def _failed_repr(obj, e):
129 130 """Render a failed repr, including the exception.
130 131
131 132 Tries to get exception and type info
132 133 """
133 134 # get exception name
134 135 if e.__class__.__module__ in ('exceptions', 'builtins'):
135 136 ename = e.__class__.__name__
136 137 else:
137 138 ename = '{}.{}'.format(
138 139 e.__class__.__module__,
139 140 e.__class__.__name__,
140 141 )
141 142 # and exception string, which sometimes fails
142 143 # (usually due to unicode error message)
143 144 try:
144 145 estr = str(e)
145 146 except Exception:
146 147 estr = "unknown"
147 148
148 149 # and class name
149 150 try:
150 151 klass = _safe_getattr(obj, '__class__', None) or type(obj)
151 152 mod = _safe_getattr(klass, '__module__', None)
152 153 if mod in (None, '__builtin__', 'builtins', 'exceptions'):
153 154 classname = klass.__name__
154 155 else:
155 156 classname = mod + '.' + klass.__name__
156 157 except Exception:
157 158 # this may be paranoid, but we already know repr is broken
158 159 classname = "unknown type"
159 160
160 161 # the informative repr
161 162 return "<repr(<{} at 0x{:x}>) failed: {}: {}>".format(
162 163 classname, id(obj), ename, estr,
163 164 )
164 165
165 166 def _safe_repr(obj):
166 167 """Don't assume repr is not broken."""
167 168 try:
168 169 return repr(obj)
169 170 except Exception as e:
170 171 return _failed_repr(obj, e)
171 172
172 173 def _safe_getattr(obj, attr, default=None):
173 174 """Safe version of getattr.
174 175
175 176 Same as getattr, but will return ``default`` on any Exception,
176 177 rather than raising.
177 178 """
178 179 try:
179 180 return getattr(obj, attr, default)
180 181 except Exception:
181 182 return default
182 183
183 184 def pretty(obj, verbose=False, max_width=79, newline='\n'):
184 185 """
185 186 Pretty print the object's representation.
186 187 """
187 188 stream = StringIO()
188 189 printer = RepresentationPrinter(stream, verbose, max_width, newline)
189 190 printer.pretty(obj)
190 191 printer.flush()
191 192 return stream.getvalue()
192 193
193 194
194 195 def pprint(obj, verbose=False, max_width=79, newline='\n'):
195 196 """
196 197 Like `pretty` but print to stdout.
197 198 """
198 199 printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline)
199 200 printer.pretty(obj)
200 201 printer.flush()
201 202 sys.stdout.write(newline)
202 203 sys.stdout.flush()
203 204
204 205 class _PrettyPrinterBase(object):
205 206
206 207 @contextmanager
207 208 def indent(self, indent):
208 209 """with statement support for indenting/dedenting."""
209 210 self.indentation += indent
210 211 try:
211 212 yield
212 213 finally:
213 214 self.indentation -= indent
214 215
215 216 @contextmanager
216 217 def group(self, indent=0, open='', close=''):
217 218 """like begin_group / end_group but for the with statement."""
218 219 self.begin_group(indent, open)
219 220 try:
220 221 yield
221 222 finally:
222 223 self.end_group(indent, close)
223 224
224 225 class PrettyPrinter(_PrettyPrinterBase):
225 226 """
226 227 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
227 228 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
228 229 this printer knows nothing about the default pprinters or the `_repr_pretty_`
229 230 callback method.
230 231 """
231 232
232 233 def __init__(self, output, max_width=79, newline='\n'):
233 234 self.output = output
234 235 self.max_width = max_width
235 236 self.newline = newline
236 237 self.output_width = 0
237 238 self.buffer_width = 0
238 239 self.buffer = deque()
239 240
240 241 root_group = Group(0)
241 242 self.group_stack = [root_group]
242 243 self.group_queue = GroupQueue(root_group)
243 244 self.indentation = 0
244 245
245 246 def _break_outer_groups(self):
246 247 while self.max_width < self.output_width + self.buffer_width:
247 248 group = self.group_queue.deq()
248 249 if not group:
249 250 return
250 251 while group.breakables:
251 252 x = self.buffer.popleft()
252 253 self.output_width = x.output(self.output, self.output_width)
253 254 self.buffer_width -= x.width
254 255 while self.buffer and isinstance(self.buffer[0], Text):
255 256 x = self.buffer.popleft()
256 257 self.output_width = x.output(self.output, self.output_width)
257 258 self.buffer_width -= x.width
258 259
259 260 def text(self, obj):
260 261 """Add literal text to the output."""
261 262 width = len(obj)
262 263 if self.buffer:
263 264 text = self.buffer[-1]
264 265 if not isinstance(text, Text):
265 266 text = Text()
266 267 self.buffer.append(text)
267 268 text.add(obj, width)
268 269 self.buffer_width += width
269 270 self._break_outer_groups()
270 271 else:
271 272 self.output.write(obj)
272 273 self.output_width += width
273 274
274 275 def breakable(self, sep=' '):
275 276 """
276 277 Add a breakable separator to the output. This does not mean that it
277 278 will automatically break here. If no breaking on this position takes
278 279 place the `sep` is inserted which default to one space.
279 280 """
280 281 width = len(sep)
281 282 group = self.group_stack[-1]
282 283 if group.want_break:
283 284 self.flush()
284 285 self.output.write(self.newline)
285 286 self.output.write(' ' * self.indentation)
286 287 self.output_width = self.indentation
287 288 self.buffer_width = 0
288 289 else:
289 290 self.buffer.append(Breakable(sep, width, self))
290 291 self.buffer_width += width
291 292 self._break_outer_groups()
292 293
293 294 def break_(self):
294 295 """
295 296 Explicitly insert a newline into the output, maintaining correct indentation.
296 297 """
297 298 self.flush()
298 299 self.output.write(self.newline)
299 300 self.output.write(' ' * self.indentation)
300 301 self.output_width = self.indentation
301 302 self.buffer_width = 0
302 303
303 304
304 305 def begin_group(self, indent=0, open=''):
305 306 """
306 307 Begin a group. If you want support for python < 2.5 which doesn't has
307 308 the with statement this is the preferred way:
308 309
309 310 p.begin_group(1, '{')
310 311 ...
311 312 p.end_group(1, '}')
312 313
313 314 The python 2.5 expression would be this:
314 315
315 316 with p.group(1, '{', '}'):
316 317 ...
317 318
318 319 The first parameter specifies the indentation for the next line (usually
319 320 the width of the opening text), the second the opening text. All
320 321 parameters are optional.
321 322 """
322 323 if open:
323 324 self.text(open)
324 325 group = Group(self.group_stack[-1].depth + 1)
325 326 self.group_stack.append(group)
326 327 self.group_queue.enq(group)
327 328 self.indentation += indent
328 329
329 330 def end_group(self, dedent=0, close=''):
330 331 """End a group. See `begin_group` for more details."""
331 332 self.indentation -= dedent
332 333 group = self.group_stack.pop()
333 334 if not group.breakables:
334 335 self.group_queue.remove(group)
335 336 if close:
336 337 self.text(close)
337 338
338 339 def flush(self):
339 340 """Flush data that is left in the buffer."""
340 341 for data in self.buffer:
341 342 self.output_width += data.output(self.output, self.output_width)
342 343 self.buffer.clear()
343 344 self.buffer_width = 0
344 345
345 346
346 347 def _get_mro(obj_class):
347 348 """ Get a reasonable method resolution order of a class and its superclasses
348 349 for both old-style and new-style classes.
349 350 """
350 351 if not hasattr(obj_class, '__mro__'):
351 352 # Old-style class. Mix in object to make a fake new-style class.
352 353 try:
353 354 obj_class = type(obj_class.__name__, (obj_class, object), {})
354 355 except TypeError:
355 356 # Old-style extension type that does not descend from object.
356 357 # FIXME: try to construct a more thorough MRO.
357 358 mro = [obj_class]
358 359 else:
359 360 mro = obj_class.__mro__[1:-1]
360 361 else:
361 362 mro = obj_class.__mro__
362 363 return mro
363 364
364 365
365 366 class RepresentationPrinter(PrettyPrinter):
366 367 """
367 368 Special pretty printer that has a `pretty` method that calls the pretty
368 369 printer for a python object.
369 370
370 371 This class stores processing data on `self` so you must *never* use
371 372 this class in a threaded environment. Always lock it or reinstanciate
372 373 it.
373 374
374 375 Instances also have a verbose flag callbacks can access to control their
375 376 output. For example the default instance repr prints all attributes and
376 377 methods that are not prefixed by an underscore if the printer is in
377 378 verbose mode.
378 379 """
379 380
380 381 def __init__(self, output, verbose=False, max_width=79, newline='\n',
381 382 singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None):
382 383
383 384 PrettyPrinter.__init__(self, output, max_width, newline)
384 385 self.verbose = verbose
385 386 self.stack = []
386 387 if singleton_pprinters is None:
387 388 singleton_pprinters = _singleton_pprinters.copy()
388 389 self.singleton_pprinters = singleton_pprinters
389 390 if type_pprinters is None:
390 391 type_pprinters = _type_pprinters.copy()
391 392 self.type_pprinters = type_pprinters
392 393 if deferred_pprinters is None:
393 394 deferred_pprinters = _deferred_type_pprinters.copy()
394 395 self.deferred_pprinters = deferred_pprinters
395 396
396 397 def pretty(self, obj):
397 398 """Pretty print the given object."""
398 399 obj_id = id(obj)
399 400 cycle = obj_id in self.stack
400 401 self.stack.append(obj_id)
401 402 self.begin_group()
402 403 try:
403 404 obj_class = _safe_getattr(obj, '__class__', None) or type(obj)
404 405 # First try to find registered singleton printers for the type.
405 406 try:
406 407 printer = self.singleton_pprinters[obj_id]
407 408 except (TypeError, KeyError):
408 409 pass
409 410 else:
410 411 return printer(obj, self, cycle)
411 412 # Next walk the mro and check for either:
412 413 # 1) a registered printer
413 414 # 2) a _repr_pretty_ method
414 415 for cls in _get_mro(obj_class):
415 416 if cls in self.type_pprinters:
416 417 # printer registered in self.type_pprinters
417 418 return self.type_pprinters[cls](obj, self, cycle)
418 419 else:
419 420 # deferred printer
420 421 printer = self._in_deferred_types(cls)
421 422 if printer is not None:
422 423 return printer(obj, self, cycle)
423 424 else:
424 425 # Finally look for special method names.
425 426 # Some objects automatically create any requested
426 427 # attribute. Try to ignore most of them by checking for
427 428 # callability.
428 429 if '_repr_pretty_' in cls.__dict__:
429 430 meth = cls._repr_pretty_
430 431 if callable(meth):
431 432 return meth(obj, self, cycle)
432 433 return _default_pprint(obj, self, cycle)
433 434 finally:
434 435 self.end_group()
435 436 self.stack.pop()
436 437
437 438 def _in_deferred_types(self, cls):
438 439 """
439 440 Check if the given class is specified in the deferred type registry.
440 441
441 442 Returns the printer from the registry if it exists, and None if the
442 443 class is not in the registry. Successful matches will be moved to the
443 444 regular type registry for future use.
444 445 """
445 446 mod = _safe_getattr(cls, '__module__', None)
446 447 name = _safe_getattr(cls, '__name__', None)
447 448 key = (mod, name)
448 449 printer = None
449 450 if key in self.deferred_pprinters:
450 451 # Move the printer over to the regular registry.
451 452 printer = self.deferred_pprinters.pop(key)
452 453 self.type_pprinters[cls] = printer
453 454 return printer
454 455
455 456
456 457 class Printable(object):
457 458
458 459 def output(self, stream, output_width):
459 460 return output_width
460 461
461 462
462 463 class Text(Printable):
463 464
464 465 def __init__(self):
465 466 self.objs = []
466 467 self.width = 0
467 468
468 469 def output(self, stream, output_width):
469 470 for obj in self.objs:
470 471 stream.write(obj)
471 472 return output_width + self.width
472 473
473 474 def add(self, obj, width):
474 475 self.objs.append(obj)
475 476 self.width += width
476 477
477 478
478 479 class Breakable(Printable):
479 480
480 481 def __init__(self, seq, width, pretty):
481 482 self.obj = seq
482 483 self.width = width
483 484 self.pretty = pretty
484 485 self.indentation = pretty.indentation
485 486 self.group = pretty.group_stack[-1]
486 487 self.group.breakables.append(self)
487 488
488 489 def output(self, stream, output_width):
489 490 self.group.breakables.popleft()
490 491 if self.group.want_break:
491 492 stream.write(self.pretty.newline)
492 493 stream.write(' ' * self.indentation)
493 494 return self.indentation
494 495 if not self.group.breakables:
495 496 self.pretty.group_queue.remove(self.group)
496 497 stream.write(self.obj)
497 498 return output_width + self.width
498 499
499 500
500 501 class Group(Printable):
501 502
502 503 def __init__(self, depth):
503 504 self.depth = depth
504 505 self.breakables = deque()
505 506 self.want_break = False
506 507
507 508
508 509 class GroupQueue(object):
509 510
510 511 def __init__(self, *groups):
511 512 self.queue = []
512 513 for group in groups:
513 514 self.enq(group)
514 515
515 516 def enq(self, group):
516 517 depth = group.depth
517 518 while depth > len(self.queue) - 1:
518 519 self.queue.append([])
519 520 self.queue[depth].append(group)
520 521
521 522 def deq(self):
522 523 for stack in self.queue:
523 524 for idx, group in enumerate(reversed(stack)):
524 525 if group.breakables:
525 526 del stack[idx]
526 527 group.want_break = True
527 528 return group
528 529 for group in stack:
529 530 group.want_break = True
530 531 del stack[:]
531 532
532 533 def remove(self, group):
533 534 try:
534 535 self.queue[group.depth].remove(group)
535 536 except ValueError:
536 537 pass
537 538
538 539 try:
539 540 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
540 541 except AttributeError: # Python 3
541 542 _baseclass_reprs = (object.__repr__,)
542 543
543 544
544 545 def _default_pprint(obj, p, cycle):
545 546 """
546 547 The default print function. Used if an object does not provide one and
547 548 it's none of the builtin objects.
548 549 """
549 550 klass = _safe_getattr(obj, '__class__', None) or type(obj)
550 551 if _safe_getattr(klass, '__repr__', None) not in _baseclass_reprs:
551 552 # A user-provided repr. Find newlines and replace them with p.break_()
552 553 output = _safe_repr(obj)
553 554 for idx,output_line in enumerate(output.splitlines()):
554 555 if idx:
555 556 p.break_()
556 557 p.text(output_line)
557 558 return
558 559 p.begin_group(1, '<')
559 560 p.pretty(klass)
560 561 p.text(' at 0x%x' % id(obj))
561 562 if cycle:
562 563 p.text(' ...')
563 564 elif p.verbose:
564 565 first = True
565 566 for key in dir(obj):
566 567 if not key.startswith('_'):
567 568 try:
568 569 value = getattr(obj, key)
569 570 except AttributeError:
570 571 continue
571 572 if isinstance(value, types.MethodType):
572 573 continue
573 574 if not first:
574 575 p.text(',')
575 576 p.breakable()
576 577 p.text(key)
577 578 p.text('=')
578 579 step = len(key) + 1
579 580 p.indentation += step
580 581 p.pretty(value)
581 582 p.indentation -= step
582 583 first = False
583 584 p.end_group(1, '>')
584 585
585 586
586 587 def _seq_pprinter_factory(start, end, basetype):
587 588 """
588 589 Factory that returns a pprint function useful for sequences. Used by
589 590 the default pprint for tuples, dicts, and lists.
590 591 """
591 592 def inner(obj, p, cycle):
592 593 typ = type(obj)
593 594 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
594 595 # If the subclass provides its own repr, use it instead.
595 596 return p.text(typ.__repr__(obj))
596 597
597 598 if cycle:
598 599 return p.text(start + '...' + end)
599 600 step = len(start)
600 601 p.begin_group(step, start)
601 602 for idx, x in enumerate(obj):
603 if idx >= SEQ_LENGTH_LIMIT:
604 p.text(',')
605 p.breakable()
606 p.text('...')
607 p.end_group(step, end)
608 return
602 609 if idx:
603 610 p.text(',')
604 611 p.breakable()
605 612 p.pretty(x)
606 613 if len(obj) == 1 and type(obj) is tuple:
607 614 # Special case for 1-item tuples.
608 615 p.text(',')
609 616 p.end_group(step, end)
610 617 return inner
611 618
612 619
613 620 def _set_pprinter_factory(start, end, basetype):
614 621 """
615 622 Factory that returns a pprint function useful for sets and frozensets.
616 623 """
617 624 def inner(obj, p, cycle):
618 625 typ = type(obj)
619 626 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
620 627 # If the subclass provides its own repr, use it instead.
621 628 return p.text(typ.__repr__(obj))
622 629
623 630 if cycle:
624 631 return p.text(start + '...' + end)
625 632 if len(obj) == 0:
626 633 # Special case.
627 634 p.text(basetype.__name__ + '()')
628 635 else:
629 636 step = len(start)
630 637 p.begin_group(step, start)
631 638 # Like dictionary keys, we will try to sort the items.
632 639 items = list(obj)
633 640 try:
634 641 items.sort()
635 642 except Exception:
636 643 # Sometimes the items don't sort.
637 644 pass
638 645 for idx, x in enumerate(items):
646 if idx >= SEQ_LENGTH_LIMIT:
647 p.text(',')
648 p.breakable()
649 p.text('...')
650 p.end_group(step, end)
651 return
639 652 if idx:
640 653 p.text(',')
641 654 p.breakable()
642 655 p.pretty(x)
643 656 p.end_group(step, end)
644 657 return inner
645 658
646 659
647 660 def _dict_pprinter_factory(start, end, basetype=None):
648 661 """
649 662 Factory that returns a pprint function used by the default pprint of
650 663 dicts and dict proxies.
651 664 """
652 665 def inner(obj, p, cycle):
653 666 typ = type(obj)
654 667 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
655 668 # If the subclass provides its own repr, use it instead.
656 669 return p.text(typ.__repr__(obj))
657 670
658 671 if cycle:
659 672 return p.text('{...}')
660 673 p.begin_group(1, start)
661 674 keys = obj.keys()
662 675 try:
663 676 keys.sort()
664 677 except Exception as e:
665 678 # Sometimes the keys don't sort.
666 679 pass
667 680 for idx, key in enumerate(keys):
681 if idx >= SEQ_LENGTH_LIMIT:
682 p.text(',')
683 p.breakable()
684 p.text('...')
685 p.end_group(1, end)
686 return
668 687 if idx:
669 688 p.text(',')
670 689 p.breakable()
671 690 p.pretty(key)
672 691 p.text(': ')
673 692 p.pretty(obj[key])
674 693 p.end_group(1, end)
675 694 return inner
676 695
677 696
678 697 def _super_pprint(obj, p, cycle):
679 698 """The pprint for the super type."""
680 699 p.begin_group(8, '<super: ')
681 700 p.pretty(obj.__thisclass__)
682 701 p.text(',')
683 702 p.breakable()
684 703 p.pretty(obj.__self__)
685 704 p.end_group(8, '>')
686 705
687 706
688 707 def _re_pattern_pprint(obj, p, cycle):
689 708 """The pprint function for regular expression patterns."""
690 709 p.text('re.compile(')
691 710 pattern = repr(obj.pattern)
692 711 if pattern[:1] in 'uU':
693 712 pattern = pattern[1:]
694 713 prefix = 'ur'
695 714 else:
696 715 prefix = 'r'
697 716 pattern = prefix + pattern.replace('\\\\', '\\')
698 717 p.text(pattern)
699 718 if obj.flags:
700 719 p.text(',')
701 720 p.breakable()
702 721 done_one = False
703 722 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
704 723 'UNICODE', 'VERBOSE', 'DEBUG'):
705 724 if obj.flags & getattr(re, flag):
706 725 if done_one:
707 726 p.text('|')
708 727 p.text('re.' + flag)
709 728 done_one = True
710 729 p.text(')')
711 730
712 731
713 732 def _type_pprint(obj, p, cycle):
714 733 """The pprint for classes and types."""
715 734 mod = _safe_getattr(obj, '__module__', None)
716 735 if mod is None:
717 736 # Heap allocated types might not have the module attribute,
718 737 # and others may set it to None.
719 738 return p.text(obj.__name__)
720 739
721 740 if mod in ('__builtin__', 'builtins', 'exceptions'):
722 741 name = obj.__name__
723 742 else:
724 743 name = mod + '.' + obj.__name__
725 744 p.text(name)
726 745
727 746
728 747 def _repr_pprint(obj, p, cycle):
729 748 """A pprint that just redirects to the normal repr function."""
730 749 p.text(_safe_repr(obj))
731 750
732 751
733 752 def _function_pprint(obj, p, cycle):
734 753 """Base pprint for all functions and builtin functions."""
735 754 if obj.__module__ in ('__builtin__', 'builtins', 'exceptions') or not obj.__module__:
736 755 name = obj.__name__
737 756 else:
738 757 name = obj.__module__ + '.' + obj.__name__
739 758 p.text('<function %s>' % name)
740 759
741 760
742 761 def _exception_pprint(obj, p, cycle):
743 762 """Base pprint for all exceptions."""
744 763 if obj.__class__.__module__ in ('exceptions', 'builtins'):
745 764 name = obj.__class__.__name__
746 765 else:
747 766 name = '%s.%s' % (
748 767 obj.__class__.__module__,
749 768 obj.__class__.__name__
750 769 )
751 770 step = len(name) + 1
752 771 p.begin_group(step, name + '(')
753 772 for idx, arg in enumerate(getattr(obj, 'args', ())):
754 773 if idx:
755 774 p.text(',')
756 775 p.breakable()
757 776 p.pretty(arg)
758 777 p.end_group(step, ')')
759 778
760 779
761 780 #: the exception base
762 781 try:
763 782 _exception_base = BaseException
764 783 except NameError:
765 784 _exception_base = Exception
766 785
767 786
768 787 #: printers for builtin types
769 788 _type_pprinters = {
770 789 int: _repr_pprint,
771 790 float: _repr_pprint,
772 791 str: _repr_pprint,
773 792 tuple: _seq_pprinter_factory('(', ')', tuple),
774 793 list: _seq_pprinter_factory('[', ']', list),
775 794 dict: _dict_pprinter_factory('{', '}', dict),
776 795
777 796 set: _set_pprinter_factory('{', '}', set),
778 797 frozenset: _set_pprinter_factory('frozenset({', '})', frozenset),
779 798 super: _super_pprint,
780 799 _re_pattern_type: _re_pattern_pprint,
781 800 type: _type_pprint,
782 801 types.FunctionType: _function_pprint,
783 802 types.BuiltinFunctionType: _function_pprint,
784 803 types.MethodType: _repr_pprint,
785 804
786 805 datetime.datetime: _repr_pprint,
787 806 datetime.timedelta: _repr_pprint,
788 807 _exception_base: _exception_pprint
789 808 }
790 809
791 810 try:
792 811 _type_pprinters[types.DictProxyType] = _dict_pprinter_factory('<dictproxy {', '}>')
793 812 _type_pprinters[types.ClassType] = _type_pprint
794 813 _type_pprinters[types.SliceType] = _repr_pprint
795 814 except AttributeError: # Python 3
796 815 _type_pprinters[slice] = _repr_pprint
797 816
798 817 try:
799 818 _type_pprinters[xrange] = _repr_pprint
800 819 _type_pprinters[long] = _repr_pprint
801 820 _type_pprinters[unicode] = _repr_pprint
802 821 except NameError:
803 822 _type_pprinters[range] = _repr_pprint
804 823 _type_pprinters[bytes] = _repr_pprint
805 824
806 825 #: printers for types specified by name
807 826 _deferred_type_pprinters = {
808 827 }
809 828
810 829 def for_type(typ, func):
811 830 """
812 831 Add a pretty printer for a given type.
813 832 """
814 833 oldfunc = _type_pprinters.get(typ, None)
815 834 if func is not None:
816 835 # To support easy restoration of old pprinters, we need to ignore Nones.
817 836 _type_pprinters[typ] = func
818 837 return oldfunc
819 838
820 839 def for_type_by_name(type_module, type_name, func):
821 840 """
822 841 Add a pretty printer for a type specified by the module and name of a type
823 842 rather than the type object itself.
824 843 """
825 844 key = (type_module, type_name)
826 845 oldfunc = _deferred_type_pprinters.get(key, None)
827 846 if func is not None:
828 847 # To support easy restoration of old pprinters, we need to ignore Nones.
829 848 _deferred_type_pprinters[key] = func
830 849 return oldfunc
831 850
832 851
833 852 #: printers for the default singletons
834 853 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
835 854 NotImplemented]), _repr_pprint)
836 855
837 856
838 857 if __name__ == '__main__':
839 858 from random import randrange
840 859 class Foo(object):
841 860 def __init__(self):
842 861 self.foo = 1
843 862 self.bar = re.compile(r'\s+')
844 863 self.blub = dict.fromkeys(range(30), randrange(1, 40))
845 864 self.hehe = 23424.234234
846 865 self.list = ["blub", "blah", self]
847 866
848 867 def get_foo(self):
849 868 print("foo")
850 869
851 870 pprint(Foo(), verbose=True)
@@ -1,199 +1,224 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 68 class BreakingRepr(object):
69 69 def __repr__(self):
70 70 return "Breaking(\n)"
71 71
72 72 class BreakingReprParent(object):
73 73 def _repr_pretty_(self, p, cycle):
74 74 with p.group(4,"TG: ",":"):
75 75 p.pretty(BreakingRepr())
76 76
77 77 class BadRepr(object):
78 78
79 79 def __repr__(self):
80 80 return 1/0
81 81
82 82
83 83 def test_indentation():
84 84 """Test correct indentation in groups"""
85 85 count = 40
86 86 gotoutput = pretty.pretty(MyList(range(count)))
87 87 expectedoutput = "MyList(\n" + ",\n".join(" %d" % i for i in range(count)) + ")"
88 88
89 89 nt.assert_equal(gotoutput, expectedoutput)
90 90
91 91
92 92 def test_dispatch():
93 93 """
94 94 Test correct dispatching: The _repr_pretty_ method for MyDict
95 95 must be found before the registered printer for dict.
96 96 """
97 97 gotoutput = pretty.pretty(MyDict())
98 98 expectedoutput = "MyDict(...)"
99 99
100 100 nt.assert_equal(gotoutput, expectedoutput)
101 101
102 102
103 103 def test_callability_checking():
104 104 """
105 105 Test that the _repr_pretty_ method is tested for callability and skipped if
106 106 not.
107 107 """
108 108 gotoutput = pretty.pretty(Dummy2())
109 109 expectedoutput = "Dummy1(...)"
110 110
111 111 nt.assert_equal(gotoutput, expectedoutput)
112 112
113 113
114 114 def test_sets():
115 115 """
116 116 Test that set and frozenset use Python 3 formatting.
117 117 """
118 118 objects = [set(), frozenset(), set([1]), frozenset([1]), set([1, 2]),
119 119 frozenset([1, 2]), set([-1, -2, -3])]
120 120 expected = ['set()', 'frozenset()', '{1}', 'frozenset({1})', '{1, 2}',
121 121 'frozenset({1, 2})', '{-3, -2, -1}']
122 122 for obj, expected_output in zip(objects, expected):
123 123 got_output = pretty.pretty(obj)
124 124 yield nt.assert_equal, got_output, expected_output
125 125
126 126
127 127 @skip_without('xxlimited')
128 128 def test_pprint_heap_allocated_type():
129 129 """
130 130 Test that pprint works for heap allocated types.
131 131 """
132 132 import xxlimited
133 133 output = pretty.pretty(xxlimited.Null)
134 134 nt.assert_equal(output, 'xxlimited.Null')
135 135
136 136 def test_pprint_nomod():
137 137 """
138 138 Test that pprint works for classes with no __module__.
139 139 """
140 140 output = pretty.pretty(NoModule)
141 141 nt.assert_equal(output, 'NoModule')
142 142
143 143 def test_pprint_break():
144 144 """
145 145 Test that p.break_ produces expected output
146 146 """
147 147 output = pretty.pretty(Breaking())
148 148 expected = "TG: Breaking(\n ):"
149 149 nt.assert_equal(output, expected)
150 150
151 151 def test_pprint_break_repr():
152 152 """
153 153 Test that p.break_ is used in repr
154 154 """
155 155 output = pretty.pretty(BreakingReprParent())
156 156 expected = "TG: Breaking(\n ):"
157 157 nt.assert_equal(output, expected)
158 158
159 159 def test_bad_repr():
160 160 """Don't raise, even when repr fails"""
161 161 output = pretty.pretty(BadRepr())
162 162 nt.assert_in("failed", output)
163 163 nt.assert_in("at 0x", output)
164 164 nt.assert_in("test_pretty", output)
165 165
166 166 class BadException(Exception):
167 167 def __str__(self):
168 168 return -1
169 169
170 170 class ReallyBadRepr(object):
171 171 __module__ = 1
172 172 @property
173 173 def __class__(self):
174 174 raise ValueError("I am horrible")
175 175
176 176 def __repr__(self):
177 177 raise BadException()
178 178
179 179 def test_really_bad_repr():
180 180 output = pretty.pretty(ReallyBadRepr())
181 181 nt.assert_in("failed", output)
182 182 nt.assert_in("BadException: unknown", output)
183 183 nt.assert_in("unknown type", output)
184 184
185 185
186 186 class SA(object):
187 187 pass
188 188
189 189 class SB(SA):
190 190 pass
191 191
192 192 def test_super_repr():
193 193 output = pretty.pretty(super(SA))
194 194 nt.assert_in("SA", output)
195 195
196 196 sb = SB()
197 197 output = pretty.pretty(super(SA, sb))
198 198 nt.assert_in("SA", output)
199 No newline at end of file
199
200
201 def test_long_list():
202 lis = list(range(10000))
203 p = pretty.pretty(lis)
204 last2 = p.rsplit('\n', 2)[-2:]
205 nt.assert_equal(last2, [' 999,', ' ...]'])
206
207 def test_long_set():
208 s = set(range(10000))
209 p = pretty.pretty(s)
210 last2 = p.rsplit('\n', 2)[-2:]
211 nt.assert_equal(last2, [' 999,', ' ...}'])
212
213 def test_long_tuple():
214 tup = tuple(range(10000))
215 p = pretty.pretty(tup)
216 last2 = p.rsplit('\n', 2)[-2:]
217 nt.assert_equal(last2, [' 999,', ' ...)'])
218
219 def test_long_dict():
220 d = { n:n for n in range(10000) }
221 p = pretty.pretty(d)
222 last2 = p.rsplit('\n', 2)[-2:]
223 nt.assert_equal(last2, [' 999: 999,', ' ...}'])
224
General Comments 0
You need to be logged in to leave comments. Login now