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