##// END OF EJS Templates
BUG: Fix pprint failure on non-string __qualname__ or __name__....
Scott Sanderson -
Show More
@@ -1,847 +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 Here is an example implementation of a `_repr_pretty_` method for a list
38 38 subclass::
39 39
40 40 class MyList(list):
41 41
42 42 def _repr_pretty_(self, p, cycle):
43 43 if cycle:
44 44 p.text('MyList(...)')
45 45 else:
46 46 with p.group(8, 'MyList([', '])'):
47 47 for idx, item in enumerate(self):
48 48 if idx:
49 49 p.text(',')
50 50 p.breakable()
51 51 p.pretty(item)
52 52
53 53 The `cycle` parameter is `True` if pretty detected a cycle. You *have* to
54 54 react to that or the result is an infinite loop. `p.text()` just adds
55 55 non breaking text to the output, `p.breakable()` either adds a whitespace
56 56 or breaks here. If you pass it an argument it's used instead of the
57 57 default space. `p.pretty` prettyprints another object using the pretty print
58 58 method.
59 59
60 60 The first parameter to the `group` function specifies the extra indentation
61 61 of the next line. In this example the next item will either be on the same
62 62 line (if the items are short enough) or aligned with the right edge of the
63 63 opening bracket of `MyList`.
64 64
65 65 If you just want to indent something you can use the group function
66 66 without open / close parameters. You can also use this code::
67 67
68 68 with p.indent(2):
69 69 ...
70 70
71 71 Inheritance diagram:
72 72
73 73 .. inheritance-diagram:: IPython.lib.pretty
74 74 :parts: 3
75 75
76 76 :copyright: 2007 by Armin Ronacher.
77 77 Portions (c) 2009 by Robert Kern.
78 78 :license: BSD License.
79 79 """
80 80 from __future__ import print_function
81 81 from contextlib import contextmanager
82 82 import sys
83 83 import types
84 84 import re
85 85 import datetime
86 86 from collections import deque
87 87
88 from IPython.utils.py3compat import PY3, cast_unicode
88 from IPython.utils.py3compat import PY3, cast_unicode, string_types
89 89 from IPython.utils.encoding import get_stream_enc
90 90
91 91 from io import StringIO
92 92
93 93
94 94 __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter',
95 95 'for_type', 'for_type_by_name']
96 96
97 97
98 98 MAX_SEQ_LENGTH = 1000
99 99 _re_pattern_type = type(re.compile(''))
100 100
101 101 def _safe_getattr(obj, attr, default=None):
102 102 """Safe version of getattr.
103 103
104 104 Same as getattr, but will return ``default`` on any Exception,
105 105 rather than raising.
106 106 """
107 107 try:
108 108 return getattr(obj, attr, default)
109 109 except Exception:
110 110 return default
111 111
112 112 if PY3:
113 113 CUnicodeIO = StringIO
114 114 else:
115 115 class CUnicodeIO(StringIO):
116 116 """StringIO that casts str to unicode on Python 2"""
117 117 def write(self, text):
118 118 return super(CUnicodeIO, self).write(
119 119 cast_unicode(text, encoding=get_stream_enc(sys.stdout)))
120 120
121 121
122 122 def pretty(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
123 123 """
124 124 Pretty print the object's representation.
125 125 """
126 126 stream = CUnicodeIO()
127 127 printer = RepresentationPrinter(stream, verbose, max_width, newline, max_seq_length)
128 128 printer.pretty(obj)
129 129 printer.flush()
130 130 return stream.getvalue()
131 131
132 132
133 133 def pprint(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
134 134 """
135 135 Like `pretty` but print to stdout.
136 136 """
137 137 printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline, max_seq_length)
138 138 printer.pretty(obj)
139 139 printer.flush()
140 140 sys.stdout.write(newline)
141 141 sys.stdout.flush()
142 142
143 143 class _PrettyPrinterBase(object):
144 144
145 145 @contextmanager
146 146 def indent(self, indent):
147 147 """with statement support for indenting/dedenting."""
148 148 self.indentation += indent
149 149 try:
150 150 yield
151 151 finally:
152 152 self.indentation -= indent
153 153
154 154 @contextmanager
155 155 def group(self, indent=0, open='', close=''):
156 156 """like begin_group / end_group but for the with statement."""
157 157 self.begin_group(indent, open)
158 158 try:
159 159 yield
160 160 finally:
161 161 self.end_group(indent, close)
162 162
163 163 class PrettyPrinter(_PrettyPrinterBase):
164 164 """
165 165 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
166 166 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
167 167 this printer knows nothing about the default pprinters or the `_repr_pretty_`
168 168 callback method.
169 169 """
170 170
171 171 def __init__(self, output, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
172 172 self.output = output
173 173 self.max_width = max_width
174 174 self.newline = newline
175 175 self.max_seq_length = max_seq_length
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 _enumerate(self, seq):
270 270 """like enumerate, but with an upper limit on the number of items"""
271 271 for idx, x in enumerate(seq):
272 272 if self.max_seq_length and idx >= self.max_seq_length:
273 273 self.text(',')
274 274 self.breakable()
275 275 self.text('...')
276 276 raise StopIteration
277 277 yield idx, x
278 278
279 279 def end_group(self, dedent=0, close=''):
280 280 """End a group. See `begin_group` for more details."""
281 281 self.indentation -= dedent
282 282 group = self.group_stack.pop()
283 283 if not group.breakables:
284 284 self.group_queue.remove(group)
285 285 if close:
286 286 self.text(close)
287 287
288 288 def flush(self):
289 289 """Flush data that is left in the buffer."""
290 290 for data in self.buffer:
291 291 self.output_width += data.output(self.output, self.output_width)
292 292 self.buffer.clear()
293 293 self.buffer_width = 0
294 294
295 295
296 296 def _get_mro(obj_class):
297 297 """ Get a reasonable method resolution order of a class and its superclasses
298 298 for both old-style and new-style classes.
299 299 """
300 300 if not hasattr(obj_class, '__mro__'):
301 301 # Old-style class. Mix in object to make a fake new-style class.
302 302 try:
303 303 obj_class = type(obj_class.__name__, (obj_class, object), {})
304 304 except TypeError:
305 305 # Old-style extension type that does not descend from object.
306 306 # FIXME: try to construct a more thorough MRO.
307 307 mro = [obj_class]
308 308 else:
309 309 mro = obj_class.__mro__[1:-1]
310 310 else:
311 311 mro = obj_class.__mro__
312 312 return mro
313 313
314 314
315 315 class RepresentationPrinter(PrettyPrinter):
316 316 """
317 317 Special pretty printer that has a `pretty` method that calls the pretty
318 318 printer for a python object.
319 319
320 320 This class stores processing data on `self` so you must *never* use
321 321 this class in a threaded environment. Always lock it or reinstanciate
322 322 it.
323 323
324 324 Instances also have a verbose flag callbacks can access to control their
325 325 output. For example the default instance repr prints all attributes and
326 326 methods that are not prefixed by an underscore if the printer is in
327 327 verbose mode.
328 328 """
329 329
330 330 def __init__(self, output, verbose=False, max_width=79, newline='\n',
331 331 singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None,
332 332 max_seq_length=MAX_SEQ_LENGTH):
333 333
334 334 PrettyPrinter.__init__(self, output, max_width, newline, max_seq_length=max_seq_length)
335 335 self.verbose = verbose
336 336 self.stack = []
337 337 if singleton_pprinters is None:
338 338 singleton_pprinters = _singleton_pprinters.copy()
339 339 self.singleton_pprinters = singleton_pprinters
340 340 if type_pprinters is None:
341 341 type_pprinters = _type_pprinters.copy()
342 342 self.type_pprinters = type_pprinters
343 343 if deferred_pprinters is None:
344 344 deferred_pprinters = _deferred_type_pprinters.copy()
345 345 self.deferred_pprinters = deferred_pprinters
346 346
347 347 def pretty(self, obj):
348 348 """Pretty print the given object."""
349 349 obj_id = id(obj)
350 350 cycle = obj_id in self.stack
351 351 self.stack.append(obj_id)
352 352 self.begin_group()
353 353 try:
354 354 obj_class = _safe_getattr(obj, '__class__', None) or type(obj)
355 355 # First try to find registered singleton printers for the type.
356 356 try:
357 357 printer = self.singleton_pprinters[obj_id]
358 358 except (TypeError, KeyError):
359 359 pass
360 360 else:
361 361 return printer(obj, self, cycle)
362 362 # Next walk the mro and check for either:
363 363 # 1) a registered printer
364 364 # 2) a _repr_pretty_ method
365 365 for cls in _get_mro(obj_class):
366 366 if cls in self.type_pprinters:
367 367 # printer registered in self.type_pprinters
368 368 return self.type_pprinters[cls](obj, self, cycle)
369 369 else:
370 370 # deferred printer
371 371 printer = self._in_deferred_types(cls)
372 372 if printer is not None:
373 373 return printer(obj, self, cycle)
374 374 else:
375 375 # Finally look for special method names.
376 376 # Some objects automatically create any requested
377 377 # attribute. Try to ignore most of them by checking for
378 378 # callability.
379 379 if '_repr_pretty_' in cls.__dict__:
380 380 meth = cls._repr_pretty_
381 381 if callable(meth):
382 382 return meth(obj, self, cycle)
383 383 return _default_pprint(obj, self, cycle)
384 384 finally:
385 385 self.end_group()
386 386 self.stack.pop()
387 387
388 388 def _in_deferred_types(self, cls):
389 389 """
390 390 Check if the given class is specified in the deferred type registry.
391 391
392 392 Returns the printer from the registry if it exists, and None if the
393 393 class is not in the registry. Successful matches will be moved to the
394 394 regular type registry for future use.
395 395 """
396 396 mod = _safe_getattr(cls, '__module__', None)
397 397 name = _safe_getattr(cls, '__name__', None)
398 398 key = (mod, name)
399 399 printer = None
400 400 if key in self.deferred_pprinters:
401 401 # Move the printer over to the regular registry.
402 402 printer = self.deferred_pprinters.pop(key)
403 403 self.type_pprinters[cls] = printer
404 404 return printer
405 405
406 406
407 407 class Printable(object):
408 408
409 409 def output(self, stream, output_width):
410 410 return output_width
411 411
412 412
413 413 class Text(Printable):
414 414
415 415 def __init__(self):
416 416 self.objs = []
417 417 self.width = 0
418 418
419 419 def output(self, stream, output_width):
420 420 for obj in self.objs:
421 421 stream.write(obj)
422 422 return output_width + self.width
423 423
424 424 def add(self, obj, width):
425 425 self.objs.append(obj)
426 426 self.width += width
427 427
428 428
429 429 class Breakable(Printable):
430 430
431 431 def __init__(self, seq, width, pretty):
432 432 self.obj = seq
433 433 self.width = width
434 434 self.pretty = pretty
435 435 self.indentation = pretty.indentation
436 436 self.group = pretty.group_stack[-1]
437 437 self.group.breakables.append(self)
438 438
439 439 def output(self, stream, output_width):
440 440 self.group.breakables.popleft()
441 441 if self.group.want_break:
442 442 stream.write(self.pretty.newline)
443 443 stream.write(' ' * self.indentation)
444 444 return self.indentation
445 445 if not self.group.breakables:
446 446 self.pretty.group_queue.remove(self.group)
447 447 stream.write(self.obj)
448 448 return output_width + self.width
449 449
450 450
451 451 class Group(Printable):
452 452
453 453 def __init__(self, depth):
454 454 self.depth = depth
455 455 self.breakables = deque()
456 456 self.want_break = False
457 457
458 458
459 459 class GroupQueue(object):
460 460
461 461 def __init__(self, *groups):
462 462 self.queue = []
463 463 for group in groups:
464 464 self.enq(group)
465 465
466 466 def enq(self, group):
467 467 depth = group.depth
468 468 while depth > len(self.queue) - 1:
469 469 self.queue.append([])
470 470 self.queue[depth].append(group)
471 471
472 472 def deq(self):
473 473 for stack in self.queue:
474 474 for idx, group in enumerate(reversed(stack)):
475 475 if group.breakables:
476 476 del stack[idx]
477 477 group.want_break = True
478 478 return group
479 479 for group in stack:
480 480 group.want_break = True
481 481 del stack[:]
482 482
483 483 def remove(self, group):
484 484 try:
485 485 self.queue[group.depth].remove(group)
486 486 except ValueError:
487 487 pass
488 488
489 489 try:
490 490 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
491 491 except AttributeError: # Python 3
492 492 _baseclass_reprs = (object.__repr__,)
493 493
494 494
495 495 def _default_pprint(obj, p, cycle):
496 496 """
497 497 The default print function. Used if an object does not provide one and
498 498 it's none of the builtin objects.
499 499 """
500 500 klass = _safe_getattr(obj, '__class__', None) or type(obj)
501 501 if _safe_getattr(klass, '__repr__', None) not in _baseclass_reprs:
502 502 # A user-provided repr. Find newlines and replace them with p.break_()
503 503 _repr_pprint(obj, p, cycle)
504 504 return
505 505 p.begin_group(1, '<')
506 506 p.pretty(klass)
507 507 p.text(' at 0x%x' % id(obj))
508 508 if cycle:
509 509 p.text(' ...')
510 510 elif p.verbose:
511 511 first = True
512 512 for key in dir(obj):
513 513 if not key.startswith('_'):
514 514 try:
515 515 value = getattr(obj, key)
516 516 except AttributeError:
517 517 continue
518 518 if isinstance(value, types.MethodType):
519 519 continue
520 520 if not first:
521 521 p.text(',')
522 522 p.breakable()
523 523 p.text(key)
524 524 p.text('=')
525 525 step = len(key) + 1
526 526 p.indentation += step
527 527 p.pretty(value)
528 528 p.indentation -= step
529 529 first = False
530 530 p.end_group(1, '>')
531 531
532 532
533 533 def _seq_pprinter_factory(start, end, basetype):
534 534 """
535 535 Factory that returns a pprint function useful for sequences. Used by
536 536 the default pprint for tuples, dicts, and lists.
537 537 """
538 538 def inner(obj, p, cycle):
539 539 typ = type(obj)
540 540 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
541 541 # If the subclass provides its own repr, use it instead.
542 542 return p.text(typ.__repr__(obj))
543 543
544 544 if cycle:
545 545 return p.text(start + '...' + end)
546 546 step = len(start)
547 547 p.begin_group(step, start)
548 548 for idx, x in p._enumerate(obj):
549 549 if idx:
550 550 p.text(',')
551 551 p.breakable()
552 552 p.pretty(x)
553 553 if len(obj) == 1 and type(obj) is tuple:
554 554 # Special case for 1-item tuples.
555 555 p.text(',')
556 556 p.end_group(step, end)
557 557 return inner
558 558
559 559
560 560 def _set_pprinter_factory(start, end, basetype):
561 561 """
562 562 Factory that returns a pprint function useful for sets and frozensets.
563 563 """
564 564 def inner(obj, p, cycle):
565 565 typ = type(obj)
566 566 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
567 567 # If the subclass provides its own repr, use it instead.
568 568 return p.text(typ.__repr__(obj))
569 569
570 570 if cycle:
571 571 return p.text(start + '...' + end)
572 572 if len(obj) == 0:
573 573 # Special case.
574 574 p.text(basetype.__name__ + '()')
575 575 else:
576 576 step = len(start)
577 577 p.begin_group(step, start)
578 578 # Like dictionary keys, we will try to sort the items if there aren't too many
579 579 items = obj
580 580 if not (p.max_seq_length and len(obj) >= p.max_seq_length):
581 581 try:
582 582 items = sorted(obj)
583 583 except Exception:
584 584 # Sometimes the items don't sort.
585 585 pass
586 586 for idx, x in p._enumerate(items):
587 587 if idx:
588 588 p.text(',')
589 589 p.breakable()
590 590 p.pretty(x)
591 591 p.end_group(step, end)
592 592 return inner
593 593
594 594
595 595 def _dict_pprinter_factory(start, end, basetype=None):
596 596 """
597 597 Factory that returns a pprint function used by the default pprint of
598 598 dicts and dict proxies.
599 599 """
600 600 def inner(obj, p, cycle):
601 601 typ = type(obj)
602 602 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
603 603 # If the subclass provides its own repr, use it instead.
604 604 return p.text(typ.__repr__(obj))
605 605
606 606 if cycle:
607 607 return p.text('{...}')
608 608 p.begin_group(1, start)
609 609 keys = obj.keys()
610 610 # if dict isn't large enough to be truncated, sort keys before displaying
611 611 if not (p.max_seq_length and len(obj) >= p.max_seq_length):
612 612 try:
613 613 keys = sorted(keys)
614 614 except Exception:
615 615 # Sometimes the keys don't sort.
616 616 pass
617 617 for idx, key in p._enumerate(keys):
618 618 if idx:
619 619 p.text(',')
620 620 p.breakable()
621 621 p.pretty(key)
622 622 p.text(': ')
623 623 p.pretty(obj[key])
624 624 p.end_group(1, end)
625 625 return inner
626 626
627 627
628 628 def _super_pprint(obj, p, cycle):
629 629 """The pprint for the super type."""
630 630 p.begin_group(8, '<super: ')
631 631 p.pretty(obj.__thisclass__)
632 632 p.text(',')
633 633 p.breakable()
634 634 p.pretty(obj.__self__)
635 635 p.end_group(8, '>')
636 636
637 637
638 638 def _re_pattern_pprint(obj, p, cycle):
639 639 """The pprint function for regular expression patterns."""
640 640 p.text('re.compile(')
641 641 pattern = repr(obj.pattern)
642 642 if pattern[:1] in 'uU':
643 643 pattern = pattern[1:]
644 644 prefix = 'ur'
645 645 else:
646 646 prefix = 'r'
647 647 pattern = prefix + pattern.replace('\\\\', '\\')
648 648 p.text(pattern)
649 649 if obj.flags:
650 650 p.text(',')
651 651 p.breakable()
652 652 done_one = False
653 653 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
654 654 'UNICODE', 'VERBOSE', 'DEBUG'):
655 655 if obj.flags & getattr(re, flag):
656 656 if done_one:
657 657 p.text('|')
658 658 p.text('re.' + flag)
659 659 done_one = True
660 660 p.text(')')
661 661
662 662
663 663 def _type_pprint(obj, p, cycle):
664 664 """The pprint for classes and types."""
665 665 # Heap allocated types might not have the module attribute,
666 666 # and others may set it to None.
667 667
668 668 # Checks for a __repr__ override in the metaclass
669 669 if type(obj).__repr__ is not type.__repr__:
670 670 _repr_pprint(obj, p, cycle)
671 671 return
672 672
673 673 mod = _safe_getattr(obj, '__module__', None)
674 name = _safe_getattr(obj, '__qualname__', obj.__name__)
674 try:
675 name = obj.__qualname__
676 if not isinstance(name, string_types):
677 # This can happen if the type implements __qualname__ as a property
678 # or other descriptor in Python 2.
679 raise Exception("Try __name__")
680 except Exception:
681 name = obj.__name__
682 if not isinstance(name, string_types):
683 name = '<unknown type>'
675 684
676 685 if mod in (None, '__builtin__', 'builtins', 'exceptions'):
677 686 p.text(name)
678 687 else:
679 688 p.text(mod + '.' + name)
680 689
681 690
682 691 def _repr_pprint(obj, p, cycle):
683 692 """A pprint that just redirects to the normal repr function."""
684 693 # Find newlines and replace them with p.break_()
685 694 output = repr(obj)
686 695 for idx,output_line in enumerate(output.splitlines()):
687 696 if idx:
688 697 p.break_()
689 698 p.text(output_line)
690 699
691 700
692 701 def _function_pprint(obj, p, cycle):
693 702 """Base pprint for all functions and builtin functions."""
694 703 name = _safe_getattr(obj, '__qualname__', obj.__name__)
695 704 mod = obj.__module__
696 705 if mod and mod not in ('__builtin__', 'builtins', 'exceptions'):
697 706 name = mod + '.' + name
698 707 p.text('<function %s>' % name)
699 708
700 709
701 710 def _exception_pprint(obj, p, cycle):
702 711 """Base pprint for all exceptions."""
703 712 name = getattr(obj.__class__, '__qualname__', obj.__class__.__name__)
704 713 if obj.__class__.__module__ not in ('exceptions', 'builtins'):
705 714 name = '%s.%s' % (obj.__class__.__module__, name)
706 715 step = len(name) + 1
707 716 p.begin_group(step, name + '(')
708 717 for idx, arg in enumerate(getattr(obj, 'args', ())):
709 718 if idx:
710 719 p.text(',')
711 720 p.breakable()
712 721 p.pretty(arg)
713 722 p.end_group(step, ')')
714 723
715 724
716 725 #: the exception base
717 726 try:
718 727 _exception_base = BaseException
719 728 except NameError:
720 729 _exception_base = Exception
721 730
722 731
723 732 #: printers for builtin types
724 733 _type_pprinters = {
725 734 int: _repr_pprint,
726 735 float: _repr_pprint,
727 736 str: _repr_pprint,
728 737 tuple: _seq_pprinter_factory('(', ')', tuple),
729 738 list: _seq_pprinter_factory('[', ']', list),
730 739 dict: _dict_pprinter_factory('{', '}', dict),
731 740
732 741 set: _set_pprinter_factory('{', '}', set),
733 742 frozenset: _set_pprinter_factory('frozenset({', '})', frozenset),
734 743 super: _super_pprint,
735 744 _re_pattern_type: _re_pattern_pprint,
736 745 type: _type_pprint,
737 746 types.FunctionType: _function_pprint,
738 747 types.BuiltinFunctionType: _function_pprint,
739 748 types.MethodType: _repr_pprint,
740 749
741 750 datetime.datetime: _repr_pprint,
742 751 datetime.timedelta: _repr_pprint,
743 752 _exception_base: _exception_pprint
744 753 }
745 754
746 755 try:
747 756 _type_pprinters[types.DictProxyType] = _dict_pprinter_factory('<dictproxy {', '}>')
748 757 _type_pprinters[types.ClassType] = _type_pprint
749 758 _type_pprinters[types.SliceType] = _repr_pprint
750 759 except AttributeError: # Python 3
751 760 _type_pprinters[slice] = _repr_pprint
752 761
753 762 try:
754 763 _type_pprinters[xrange] = _repr_pprint
755 764 _type_pprinters[long] = _repr_pprint
756 765 _type_pprinters[unicode] = _repr_pprint
757 766 except NameError:
758 767 _type_pprinters[range] = _repr_pprint
759 768 _type_pprinters[bytes] = _repr_pprint
760 769
761 770 #: printers for types specified by name
762 771 _deferred_type_pprinters = {
763 772 }
764 773
765 774 def for_type(typ, func):
766 775 """
767 776 Add a pretty printer for a given type.
768 777 """
769 778 oldfunc = _type_pprinters.get(typ, None)
770 779 if func is not None:
771 780 # To support easy restoration of old pprinters, we need to ignore Nones.
772 781 _type_pprinters[typ] = func
773 782 return oldfunc
774 783
775 784 def for_type_by_name(type_module, type_name, func):
776 785 """
777 786 Add a pretty printer for a type specified by the module and name of a type
778 787 rather than the type object itself.
779 788 """
780 789 key = (type_module, type_name)
781 790 oldfunc = _deferred_type_pprinters.get(key, None)
782 791 if func is not None:
783 792 # To support easy restoration of old pprinters, we need to ignore Nones.
784 793 _deferred_type_pprinters[key] = func
785 794 return oldfunc
786 795
787 796
788 797 #: printers for the default singletons
789 798 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
790 799 NotImplemented]), _repr_pprint)
791 800
792 801
793 802 def _defaultdict_pprint(obj, p, cycle):
794 803 name = obj.__class__.__name__
795 804 with p.group(len(name) + 1, name + '(', ')'):
796 805 if cycle:
797 806 p.text('...')
798 807 else:
799 808 p.pretty(obj.default_factory)
800 809 p.text(',')
801 810 p.breakable()
802 811 p.pretty(dict(obj))
803 812
804 813 def _ordereddict_pprint(obj, p, cycle):
805 814 name = obj.__class__.__name__
806 815 with p.group(len(name) + 1, name + '(', ')'):
807 816 if cycle:
808 817 p.text('...')
809 818 elif len(obj):
810 819 p.pretty(list(obj.items()))
811 820
812 821 def _deque_pprint(obj, p, cycle):
813 822 name = obj.__class__.__name__
814 823 with p.group(len(name) + 1, name + '(', ')'):
815 824 if cycle:
816 825 p.text('...')
817 826 else:
818 827 p.pretty(list(obj))
819 828
820 829
821 830 def _counter_pprint(obj, p, cycle):
822 831 name = obj.__class__.__name__
823 832 with p.group(len(name) + 1, name + '(', ')'):
824 833 if cycle:
825 834 p.text('...')
826 835 elif len(obj):
827 836 p.pretty(dict(obj))
828 837
829 838 for_type_by_name('collections', 'defaultdict', _defaultdict_pprint)
830 839 for_type_by_name('collections', 'OrderedDict', _ordereddict_pprint)
831 840 for_type_by_name('collections', 'deque', _deque_pprint)
832 841 for_type_by_name('collections', 'Counter', _counter_pprint)
833 842
834 843 if __name__ == '__main__':
835 844 from random import randrange
836 845 class Foo(object):
837 846 def __init__(self):
838 847 self.foo = 1
839 848 self.bar = re.compile(r'\s+')
840 849 self.blub = dict.fromkeys(range(30), randrange(1, 40))
841 850 self.hehe = 23424.234234
842 851 self.list = ["blub", "blah", self]
843 852
844 853 def get_foo(self):
845 854 print("foo")
846 855
847 856 pprint(Foo(), verbose=True)
@@ -1,361 +1,438 b''
1 1 # coding: utf-8
2 2 """Tests for IPython.lib.pretty."""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7 from __future__ import print_function
8 8
9 9 from collections import Counter, defaultdict, deque, OrderedDict
10 10
11 11 import nose.tools as nt
12 12
13 13 from IPython.lib import pretty
14 from IPython.testing.decorators import skip_without
14 from IPython.testing.decorators import skip_without, py2_only
15 15 from IPython.utils.py3compat import PY3, unicode_to_str
16 16
17 17 if PY3:
18 18 from io import StringIO
19 19 else:
20 20 from StringIO import StringIO
21 21
22 22
23 23 class MyList(object):
24 24 def __init__(self, content):
25 25 self.content = content
26 26 def _repr_pretty_(self, p, cycle):
27 27 if cycle:
28 28 p.text("MyList(...)")
29 29 else:
30 30 with p.group(3, "MyList(", ")"):
31 31 for (i, child) in enumerate(self.content):
32 32 if i:
33 33 p.text(",")
34 34 p.breakable()
35 35 else:
36 36 p.breakable("")
37 37 p.pretty(child)
38 38
39 39
40 40 class MyDict(dict):
41 41 def _repr_pretty_(self, p, cycle):
42 42 p.text("MyDict(...)")
43 43
44 44 class MyObj(object):
45 45 def somemethod(self):
46 46 pass
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 catch bad repr errors"""
161 161 with nt.assert_raises(ZeroDivisionError):
162 162 output = pretty.pretty(BadRepr())
163 163
164 164 class BadException(Exception):
165 165 def __str__(self):
166 166 return -1
167 167
168 168 class ReallyBadRepr(object):
169 169 __module__ = 1
170 170 @property
171 171 def __class__(self):
172 172 raise ValueError("I am horrible")
173 173
174 174 def __repr__(self):
175 175 raise BadException()
176 176
177 177 def test_really_bad_repr():
178 178 with nt.assert_raises(BadException):
179 179 output = pretty.pretty(ReallyBadRepr())
180 180
181 181
182 182 class SA(object):
183 183 pass
184 184
185 185 class SB(SA):
186 186 pass
187 187
188 188 def test_super_repr():
189 189 output = pretty.pretty(super(SA))
190 190 nt.assert_in("SA", output)
191 191
192 192 sb = SB()
193 193 output = pretty.pretty(super(SA, sb))
194 194 nt.assert_in("SA", output)
195 195
196 196
197 197 def test_long_list():
198 198 lis = list(range(10000))
199 199 p = pretty.pretty(lis)
200 200 last2 = p.rsplit('\n', 2)[-2:]
201 201 nt.assert_equal(last2, [' 999,', ' ...]'])
202 202
203 203 def test_long_set():
204 204 s = set(range(10000))
205 205 p = pretty.pretty(s)
206 206 last2 = p.rsplit('\n', 2)[-2:]
207 207 nt.assert_equal(last2, [' 999,', ' ...}'])
208 208
209 209 def test_long_tuple():
210 210 tup = tuple(range(10000))
211 211 p = pretty.pretty(tup)
212 212 last2 = p.rsplit('\n', 2)[-2:]
213 213 nt.assert_equal(last2, [' 999,', ' ...)'])
214 214
215 215 def test_long_dict():
216 216 d = { n:n for n in range(10000) }
217 217 p = pretty.pretty(d)
218 218 last2 = p.rsplit('\n', 2)[-2:]
219 219 nt.assert_equal(last2, [' 999: 999,', ' ...}'])
220 220
221 221 def test_unbound_method():
222 222 output = pretty.pretty(MyObj.somemethod)
223 223 nt.assert_in('MyObj.somemethod', output)
224 224
225 225
226 226 class MetaClass(type):
227 227 def __new__(cls, name):
228 228 return type.__new__(cls, name, (object,), {'name': name})
229 229
230 230 def __repr__(self):
231 231 return "[CUSTOM REPR FOR CLASS %s]" % self.name
232 232
233 233
234 234 ClassWithMeta = MetaClass('ClassWithMeta')
235 235
236 236
237 237 def test_metaclass_repr():
238 238 output = pretty.pretty(ClassWithMeta)
239 239 nt.assert_equal(output, "[CUSTOM REPR FOR CLASS ClassWithMeta]")
240 240
241 241
242 242 def test_unicode_repr():
243 243 u = u"üniçodé"
244 244 ustr = unicode_to_str(u)
245 245
246 246 class C(object):
247 247 def __repr__(self):
248 248 return ustr
249 249
250 250 c = C()
251 251 p = pretty.pretty(c)
252 252 nt.assert_equal(p, u)
253 253 p = pretty.pretty([c])
254 254 nt.assert_equal(p, u'[%s]' % u)
255 255
256 256
257 257 def test_basic_class():
258 258 def type_pprint_wrapper(obj, p, cycle):
259 259 if obj is MyObj:
260 260 type_pprint_wrapper.called = True
261 261 return pretty._type_pprint(obj, p, cycle)
262 262 type_pprint_wrapper.called = False
263 263
264 264 stream = StringIO()
265 265 printer = pretty.RepresentationPrinter(stream)
266 266 printer.type_pprinters[type] = type_pprint_wrapper
267 267 printer.pretty(MyObj)
268 268 printer.flush()
269 269 output = stream.getvalue()
270 270
271 271 nt.assert_equal(output, '%s.MyObj' % __name__)
272 272 nt.assert_true(type_pprint_wrapper.called)
273 273
274 274
275 # This is only run on Python 2 because in Python 3 the language prevents you
276 # from setting a non-unicode value for __qualname__ on a metaclass, and it
277 # doesn't respect the descriptor protocol if you subclass unicode and implement
278 # __get__.
279 @py2_only
280 def test_fallback_to__name__on_type():
281 # Test that we correctly repr types that have non-string values for
282 # __qualname__ by falling back to __name__
283
284 class Type(object):
285 __qualname__ = 5
286
287 # Test repring of the type.
288 stream = StringIO()
289 printer = pretty.RepresentationPrinter(stream)
290
291 printer.pretty(Type)
292 printer.flush()
293 output = stream.getvalue()
294
295 # If __qualname__ is malformed, we should fall back to __name__.
296 expected = '.'.join([__name__, Type.__name__])
297 nt.assert_equal(output, expected)
298
299 # Clear stream buffer.
300 stream.buf = ''
301
302 # Test repring of an instance of the type.
303 instance = Type()
304 printer.pretty(instance)
305 printer.flush()
306 output = stream.getvalue()
307
308 # Should look like:
309 # <IPython.lib.tests.test_pretty.Type at 0x7f7658ae07d0>
310 prefix = '<' + '.'.join([__name__, Type.__name__]) + ' at 0x'
311 nt.assert_true(output.startswith(prefix))
312
313
314 @py2_only
315 def test_fail_gracefully_on_bogus__qualname__and__name__():
316 # Test that we correctly repr types that have non-string values for both
317 # __qualname__ and __name__
318
319 class Meta(type):
320 __name__ = 5
321
322 class Type(object):
323 __metaclass__ = Meta
324 __qualname__ = 5
325
326 stream = StringIO()
327 printer = pretty.RepresentationPrinter(stream)
328
329 printer.pretty(Type)
330 printer.flush()
331 output = stream.getvalue()
332
333 # If we can't find __name__ or __qualname__ just use a sentinel string.
334 expected = '.'.join([__name__, '<unknown type>'])
335 nt.assert_equal(output, expected)
336
337 # Clear stream buffer.
338 stream.buf = ''
339
340 # Test repring of an instance of the type.
341 instance = Type()
342 printer.pretty(instance)
343 printer.flush()
344 output = stream.getvalue()
345
346 # Should look like:
347 # <IPython.lib.tests.test_pretty.<unknown type> at 0x7f7658ae07d0>
348 prefix = '<' + '.'.join([__name__, '<unknown type>']) + ' at 0x'
349 nt.assert_true(output.startswith(prefix))
350
351
275 352 def test_collections_defaultdict():
276 353 # Create defaultdicts with cycles
277 354 a = defaultdict()
278 355 a.default_factory = a
279 356 b = defaultdict(list)
280 357 b['key'] = b
281 358
282 359 # Dictionary order cannot be relied on, test against single keys.
283 360 cases = [
284 361 (defaultdict(list), 'defaultdict(list, {})'),
285 362 (defaultdict(list, {'key': '-' * 50}),
286 363 "defaultdict(list,\n"
287 364 " {'key': '--------------------------------------------------'})"),
288 365 (a, 'defaultdict(defaultdict(...), {})'),
289 366 (b, "defaultdict(list, {'key': defaultdict(...)})"),
290 367 ]
291 368 for obj, expected in cases:
292 369 nt.assert_equal(pretty.pretty(obj), expected)
293 370
294 371
295 372 def test_collections_ordereddict():
296 373 # Create OrderedDict with cycle
297 374 a = OrderedDict()
298 375 a['key'] = a
299 376
300 377 cases = [
301 378 (OrderedDict(), 'OrderedDict()'),
302 379 (OrderedDict((i, i) for i in range(1000, 1010)),
303 380 'OrderedDict([(1000, 1000),\n'
304 381 ' (1001, 1001),\n'
305 382 ' (1002, 1002),\n'
306 383 ' (1003, 1003),\n'
307 384 ' (1004, 1004),\n'
308 385 ' (1005, 1005),\n'
309 386 ' (1006, 1006),\n'
310 387 ' (1007, 1007),\n'
311 388 ' (1008, 1008),\n'
312 389 ' (1009, 1009)])'),
313 390 (a, "OrderedDict([('key', OrderedDict(...))])"),
314 391 ]
315 392 for obj, expected in cases:
316 393 nt.assert_equal(pretty.pretty(obj), expected)
317 394
318 395
319 396 def test_collections_deque():
320 397 # Create deque with cycle
321 398 a = deque()
322 399 a.append(a)
323 400
324 401 cases = [
325 402 (deque(), 'deque([])'),
326 403 (deque(i for i in range(1000, 1020)),
327 404 'deque([1000,\n'
328 405 ' 1001,\n'
329 406 ' 1002,\n'
330 407 ' 1003,\n'
331 408 ' 1004,\n'
332 409 ' 1005,\n'
333 410 ' 1006,\n'
334 411 ' 1007,\n'
335 412 ' 1008,\n'
336 413 ' 1009,\n'
337 414 ' 1010,\n'
338 415 ' 1011,\n'
339 416 ' 1012,\n'
340 417 ' 1013,\n'
341 418 ' 1014,\n'
342 419 ' 1015,\n'
343 420 ' 1016,\n'
344 421 ' 1017,\n'
345 422 ' 1018,\n'
346 423 ' 1019])'),
347 424 (a, 'deque([deque(...)])'),
348 425 ]
349 426 for obj, expected in cases:
350 427 nt.assert_equal(pretty.pretty(obj), expected)
351 428
352 429 def test_collections_counter():
353 430 class MyCounter(Counter):
354 431 pass
355 432 cases = [
356 433 (Counter(), 'Counter()'),
357 434 (Counter(a=1), "Counter({'a': 1})"),
358 435 (MyCounter(a=1), "MyCounter({'a': 1})"),
359 436 ]
360 437 for obj, expected in cases:
361 438 nt.assert_equal(pretty.pretty(obj), expected)
@@ -1,377 +1,380 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Decorators for labeling test objects.
3 3
4 4 Decorators that merely return a modified version of the original function
5 5 object are straightforward. Decorators that return a new function object need
6 6 to use nose.tools.make_decorator(original_function)(decorator) in returning the
7 7 decorator, in order to preserve metadata such as function name, setup and
8 8 teardown functions and so on - see nose.tools for more information.
9 9
10 10 This module provides a set of useful decorators meant to be ready to use in
11 11 your own tests. See the bottom of the file for the ready-made ones, and if you
12 12 find yourself writing a new one that may be of generic use, add it here.
13 13
14 14 Included decorators:
15 15
16 16
17 17 Lightweight testing that remains unittest-compatible.
18 18
19 19 - An @as_unittest decorator can be used to tag any normal parameter-less
20 20 function as a unittest TestCase. Then, both nose and normal unittest will
21 21 recognize it as such. This will make it easier to migrate away from Nose if
22 22 we ever need/want to while maintaining very lightweight tests.
23 23
24 24 NOTE: This file contains IPython-specific decorators. Using the machinery in
25 25 IPython.external.decorators, we import either numpy.testing.decorators if numpy is
26 26 available, OR use equivalent code in IPython.external._decorators, which
27 27 we've copied verbatim from numpy.
28 28
29 29 """
30 30
31 31 # Copyright (c) IPython Development Team.
32 32 # Distributed under the terms of the Modified BSD License.
33 33
34 34 import sys
35 35 import os
36 36 import tempfile
37 37 import unittest
38 38 import warnings
39 39
40 40 from decorator import decorator
41 41
42 42 # Expose the unittest-driven decorators
43 43 from .ipunittest import ipdoctest, ipdocstring
44 44
45 45 # Grab the numpy-specific decorators which we keep in a file that we
46 46 # occasionally update from upstream: decorators.py is a copy of
47 47 # numpy.testing.decorators, we expose all of it here.
48 48 from IPython.external.decorators import *
49 49
50 50 # For onlyif_cmd_exists decorator
51 from IPython.utils.py3compat import string_types, which
51 from IPython.utils.py3compat import string_types, which, PY2, PY3
52 52
53 53 #-----------------------------------------------------------------------------
54 54 # Classes and functions
55 55 #-----------------------------------------------------------------------------
56 56
57 57 # Simple example of the basic idea
58 58 def as_unittest(func):
59 59 """Decorator to make a simple function into a normal test via unittest."""
60 60 class Tester(unittest.TestCase):
61 61 def test(self):
62 62 func()
63 63
64 64 Tester.__name__ = func.__name__
65 65
66 66 return Tester
67 67
68 68 # Utility functions
69 69
70 70 def apply_wrapper(wrapper,func):
71 71 """Apply a wrapper to a function for decoration.
72 72
73 73 This mixes Michele Simionato's decorator tool with nose's make_decorator,
74 74 to apply a wrapper in a decorator so that all nose attributes, as well as
75 75 function signature and other properties, survive the decoration cleanly.
76 76 This will ensure that wrapped functions can still be well introspected via
77 77 IPython, for example.
78 78 """
79 79 warnings.warn("The function `apply_wrapper` is deprecated and might be removed in next major version of IPython", DeprecationWarning)
80 80
81 81 import nose.tools
82 82
83 83 return decorator(wrapper,nose.tools.make_decorator(func)(wrapper))
84 84
85 85
86 86 def make_label_dec(label,ds=None):
87 87 """Factory function to create a decorator that applies one or more labels.
88 88
89 89 Parameters
90 90 ----------
91 91 label : string or sequence
92 92 One or more labels that will be applied by the decorator to the functions
93 93 it decorates. Labels are attributes of the decorated function with their
94 94 value set to True.
95 95
96 96 ds : string
97 97 An optional docstring for the resulting decorator. If not given, a
98 98 default docstring is auto-generated.
99 99
100 100 Returns
101 101 -------
102 102 A decorator.
103 103
104 104 Examples
105 105 --------
106 106
107 107 A simple labeling decorator:
108 108
109 109 >>> slow = make_label_dec('slow')
110 110 >>> slow.__doc__
111 111 "Labels a test as 'slow'."
112 112
113 113 And one that uses multiple labels and a custom docstring:
114 114
115 115 >>> rare = make_label_dec(['slow','hard'],
116 116 ... "Mix labels 'slow' and 'hard' for rare tests.")
117 117 >>> rare.__doc__
118 118 "Mix labels 'slow' and 'hard' for rare tests."
119 119
120 120 Now, let's test using this one:
121 121 >>> @rare
122 122 ... def f(): pass
123 123 ...
124 124 >>>
125 125 >>> f.slow
126 126 True
127 127 >>> f.hard
128 128 True
129 129 """
130 130
131 131 warnings.warn("The function `make_label_dec` is deprecated and might be removed in next major version of IPython", DeprecationWarning)
132 132 if isinstance(label, string_types):
133 133 labels = [label]
134 134 else:
135 135 labels = label
136 136
137 137 # Validate that the given label(s) are OK for use in setattr() by doing a
138 138 # dry run on a dummy function.
139 139 tmp = lambda : None
140 140 for label in labels:
141 141 setattr(tmp,label,True)
142 142
143 143 # This is the actual decorator we'll return
144 144 def decor(f):
145 145 for label in labels:
146 146 setattr(f,label,True)
147 147 return f
148 148
149 149 # Apply the user's docstring, or autogenerate a basic one
150 150 if ds is None:
151 151 ds = "Labels a test as %r." % label
152 152 decor.__doc__ = ds
153 153
154 154 return decor
155 155
156 156
157 157 # Inspired by numpy's skipif, but uses the full apply_wrapper utility to
158 158 # preserve function metadata better and allows the skip condition to be a
159 159 # callable.
160 160 def skipif(skip_condition, msg=None):
161 161 ''' Make function raise SkipTest exception if skip_condition is true
162 162
163 163 Parameters
164 164 ----------
165 165
166 166 skip_condition : bool or callable
167 167 Flag to determine whether to skip test. If the condition is a
168 168 callable, it is used at runtime to dynamically make the decision. This
169 169 is useful for tests that may require costly imports, to delay the cost
170 170 until the test suite is actually executed.
171 171 msg : string
172 172 Message to give on raising a SkipTest exception.
173 173
174 174 Returns
175 175 -------
176 176 decorator : function
177 177 Decorator, which, when applied to a function, causes SkipTest
178 178 to be raised when the skip_condition was True, and the function
179 179 to be called normally otherwise.
180 180
181 181 Notes
182 182 -----
183 183 You will see from the code that we had to further decorate the
184 184 decorator with the nose.tools.make_decorator function in order to
185 185 transmit function name, and various other metadata.
186 186 '''
187 187
188 188 def skip_decorator(f):
189 189 # Local import to avoid a hard nose dependency and only incur the
190 190 # import time overhead at actual test-time.
191 191 import nose
192 192
193 193 # Allow for both boolean or callable skip conditions.
194 194 if callable(skip_condition):
195 195 skip_val = skip_condition
196 196 else:
197 197 skip_val = lambda : skip_condition
198 198
199 199 def get_msg(func,msg=None):
200 200 """Skip message with information about function being skipped."""
201 201 if msg is None: out = 'Test skipped due to test condition.'
202 202 else: out = msg
203 203 return "Skipping test: %s. %s" % (func.__name__,out)
204 204
205 205 # We need to define *two* skippers because Python doesn't allow both
206 206 # return with value and yield inside the same function.
207 207 def skipper_func(*args, **kwargs):
208 208 """Skipper for normal test functions."""
209 209 if skip_val():
210 210 raise nose.SkipTest(get_msg(f,msg))
211 211 else:
212 212 return f(*args, **kwargs)
213 213
214 214 def skipper_gen(*args, **kwargs):
215 215 """Skipper for test generators."""
216 216 if skip_val():
217 217 raise nose.SkipTest(get_msg(f,msg))
218 218 else:
219 219 for x in f(*args, **kwargs):
220 220 yield x
221 221
222 222 # Choose the right skipper to use when building the actual generator.
223 223 if nose.util.isgenerator(f):
224 224 skipper = skipper_gen
225 225 else:
226 226 skipper = skipper_func
227 227
228 228 return nose.tools.make_decorator(f)(skipper)
229 229
230 230 return skip_decorator
231 231
232 232 # A version with the condition set to true, common case just to attach a message
233 233 # to a skip decorator
234 234 def skip(msg=None):
235 235 """Decorator factory - mark a test function for skipping from test suite.
236 236
237 237 Parameters
238 238 ----------
239 239 msg : string
240 240 Optional message to be added.
241 241
242 242 Returns
243 243 -------
244 244 decorator : function
245 245 Decorator, which, when applied to a function, causes SkipTest
246 246 to be raised, with the optional message added.
247 247 """
248 248
249 249 return skipif(True,msg)
250 250
251 251
252 252 def onlyif(condition, msg):
253 253 """The reverse from skipif, see skipif for details."""
254 254
255 255 if callable(condition):
256 256 skip_condition = lambda : not condition()
257 257 else:
258 258 skip_condition = lambda : not condition
259 259
260 260 return skipif(skip_condition, msg)
261 261
262 262 #-----------------------------------------------------------------------------
263 263 # Utility functions for decorators
264 264 def module_not_available(module):
265 265 """Can module be imported? Returns true if module does NOT import.
266 266
267 267 This is used to make a decorator to skip tests that require module to be
268 268 available, but delay the 'import numpy' to test execution time.
269 269 """
270 270 try:
271 271 mod = __import__(module)
272 272 mod_not_avail = False
273 273 except ImportError:
274 274 mod_not_avail = True
275 275
276 276 return mod_not_avail
277 277
278 278
279 279 def decorated_dummy(dec, name):
280 280 """Return a dummy function decorated with dec, with the given name.
281 281
282 282 Examples
283 283 --------
284 284 import IPython.testing.decorators as dec
285 285 setup = dec.decorated_dummy(dec.skip_if_no_x11, __name__)
286 286 """
287 287 warnings.warn("The function `make_label_dec` is deprecated and might be removed in next major version of IPython", DeprecationWarning)
288 288 dummy = lambda: None
289 289 dummy.__name__ = name
290 290 return dec(dummy)
291 291
292 292 #-----------------------------------------------------------------------------
293 293 # Decorators for public use
294 294
295 295 # Decorators to skip certain tests on specific platforms.
296 296 skip_win32 = skipif(sys.platform == 'win32',
297 297 "This test does not run under Windows")
298 298 skip_linux = skipif(sys.platform.startswith('linux'),
299 299 "This test does not run under Linux")
300 300 skip_osx = skipif(sys.platform == 'darwin',"This test does not run under OS X")
301 301
302 302
303 303 # Decorators to skip tests if not on specific platforms.
304 304 skip_if_not_win32 = skipif(sys.platform != 'win32',
305 305 "This test only runs under Windows")
306 306 skip_if_not_linux = skipif(not sys.platform.startswith('linux'),
307 307 "This test only runs under Linux")
308 308 skip_if_not_osx = skipif(sys.platform != 'darwin',
309 309 "This test only runs under OSX")
310 310
311 311
312 312 _x11_skip_cond = (sys.platform not in ('darwin', 'win32') and
313 313 os.environ.get('DISPLAY', '') == '')
314 314 _x11_skip_msg = "Skipped under *nix when X11/XOrg not available"
315 315
316 316 skip_if_no_x11 = skipif(_x11_skip_cond, _x11_skip_msg)
317 317
318 318 # not a decorator itself, returns a dummy function to be used as setup
319 319 def skip_file_no_x11(name):
320 320 warnings.warn("The function `skip_file_no_x11` is deprecated and might be removed in next major version of IPython", DeprecationWarning)
321 321 return decorated_dummy(skip_if_no_x11, name) if _x11_skip_cond else None
322 322
323 323 # Other skip decorators
324 324
325 325 # generic skip without module
326 326 skip_without = lambda mod: skipif(module_not_available(mod), "This test requires %s" % mod)
327 327
328 328 skipif_not_numpy = skip_without('numpy')
329 329
330 330 skipif_not_matplotlib = skip_without('matplotlib')
331 331
332 332 skipif_not_sympy = skip_without('sympy')
333 333
334 334 skip_known_failure = knownfailureif(True,'This test is known to fail')
335 335
336 336 known_failure_py3 = knownfailureif(sys.version_info[0] >= 3,
337 337 'This test is known to fail on Python 3.')
338 338
339 py2_only = skipif(PY3, "This test only runs on Python 2.")
340 py3_only = skipif(PY2, "This test only runs on Python 3.")
341
339 342 # A null 'decorator', useful to make more readable code that needs to pick
340 343 # between different decorators based on OS or other conditions
341 344 null_deco = lambda f: f
342 345
343 346 # Some tests only run where we can use unicode paths. Note that we can't just
344 347 # check os.path.supports_unicode_filenames, which is always False on Linux.
345 348 try:
346 349 f = tempfile.NamedTemporaryFile(prefix=u"tmp€")
347 350 except UnicodeEncodeError:
348 351 unicode_paths = False
349 352 else:
350 353 unicode_paths = True
351 354 f.close()
352 355
353 356 onlyif_unicode_paths = onlyif(unicode_paths, ("This test is only applicable "
354 357 "where we can use unicode in filenames."))
355 358
356 359
357 360 def onlyif_cmds_exist(*commands):
358 361 """
359 362 Decorator to skip test when at least one of `commands` is not found.
360 363 """
361 364 warnings.warn("The function `onlyif_cmds_exist` is deprecated and might be removed in next major version of IPython", DeprecationWarning)
362 365 for cmd in commands:
363 366 if not which(cmd):
364 367 return skip("This test runs only if command '{0}' "
365 368 "is installed".format(cmd))
366 369 return null_deco
367 370
368 371 def onlyif_any_cmd_exists(*commands):
369 372 """
370 373 Decorator to skip test unless at least one of `commands` is found.
371 374 """
372 375 warnings.warn("The function `onlyif_any_cmd_exists` is deprecated and might be removed in next major version of IPython", DeprecationWarning)
373 376 for cmd in commands:
374 377 if which(cmd):
375 378 return null_deco
376 379 return skip("This test runs only if one of the commands {0} "
377 380 "is installed".format(commands))
@@ -1,329 +1,332 b''
1 1 # coding: utf-8
2 2 """Compatibility tricks for Python 3. Mainly to do with unicode."""
3 3 import functools
4 4 import os
5 5 import sys
6 6 import re
7 7 import shutil
8 8 import types
9 9
10 10 from .encoding import DEFAULT_ENCODING
11 11
12 12 def no_code(x, encoding=None):
13 13 return x
14 14
15 15 def decode(s, encoding=None):
16 16 encoding = encoding or DEFAULT_ENCODING
17 17 return s.decode(encoding, "replace")
18 18
19 19 def encode(u, encoding=None):
20 20 encoding = encoding or DEFAULT_ENCODING
21 21 return u.encode(encoding, "replace")
22 22
23 23
24 24 def cast_unicode(s, encoding=None):
25 25 if isinstance(s, bytes):
26 26 return decode(s, encoding)
27 27 return s
28 28
29 29 def cast_bytes(s, encoding=None):
30 30 if not isinstance(s, bytes):
31 31 return encode(s, encoding)
32 32 return s
33 33
34 34 def buffer_to_bytes(buf):
35 35 """Cast a buffer object to bytes"""
36 36 if not isinstance(buf, bytes):
37 37 buf = bytes(buf)
38 38 return buf
39 39
40 40 def _modify_str_or_docstring(str_change_func):
41 41 @functools.wraps(str_change_func)
42 42 def wrapper(func_or_str):
43 43 if isinstance(func_or_str, string_types):
44 44 func = None
45 45 doc = func_or_str
46 46 else:
47 47 func = func_or_str
48 48 doc = func.__doc__
49 49
50 50 doc = str_change_func(doc)
51 51
52 52 if func:
53 53 func.__doc__ = doc
54 54 return func
55 55 return doc
56 56 return wrapper
57 57
58 58 def safe_unicode(e):
59 59 """unicode(e) with various fallbacks. Used for exceptions, which may not be
60 60 safe to call unicode() on.
61 61 """
62 62 try:
63 63 return unicode_type(e)
64 64 except UnicodeError:
65 65 pass
66 66
67 67 try:
68 68 return str_to_unicode(str(e))
69 69 except UnicodeError:
70 70 pass
71 71
72 72 try:
73 73 return str_to_unicode(repr(e))
74 74 except UnicodeError:
75 75 pass
76 76
77 77 return u'Unrecoverably corrupt evalue'
78 78
79 79 # shutil.which from Python 3.4
80 80 def _shutil_which(cmd, mode=os.F_OK | os.X_OK, path=None):
81 81 """Given a command, mode, and a PATH string, return the path which
82 82 conforms to the given mode on the PATH, or None if there is no such
83 83 file.
84 84
85 85 `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
86 86 of os.environ.get("PATH"), or can be overridden with a custom search
87 87 path.
88 88
89 89 This is a backport of shutil.which from Python 3.4
90 90 """
91 91 # Check that a given file can be accessed with the correct mode.
92 92 # Additionally check that `file` is not a directory, as on Windows
93 93 # directories pass the os.access check.
94 94 def _access_check(fn, mode):
95 95 return (os.path.exists(fn) and os.access(fn, mode)
96 96 and not os.path.isdir(fn))
97 97
98 98 # If we're given a path with a directory part, look it up directly rather
99 99 # than referring to PATH directories. This includes checking relative to the
100 100 # current directory, e.g. ./script
101 101 if os.path.dirname(cmd):
102 102 if _access_check(cmd, mode):
103 103 return cmd
104 104 return None
105 105
106 106 if path is None:
107 107 path = os.environ.get("PATH", os.defpath)
108 108 if not path:
109 109 return None
110 110 path = path.split(os.pathsep)
111 111
112 112 if sys.platform == "win32":
113 113 # The current directory takes precedence on Windows.
114 114 if not os.curdir in path:
115 115 path.insert(0, os.curdir)
116 116
117 117 # PATHEXT is necessary to check on Windows.
118 118 pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
119 119 # See if the given file matches any of the expected path extensions.
120 120 # This will allow us to short circuit when given "python.exe".
121 121 # If it does match, only test that one, otherwise we have to try
122 122 # others.
123 123 if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
124 124 files = [cmd]
125 125 else:
126 126 files = [cmd + ext for ext in pathext]
127 127 else:
128 128 # On other platforms you don't have things like PATHEXT to tell you
129 129 # what file suffixes are executable, so just pass on cmd as-is.
130 130 files = [cmd]
131 131
132 132 seen = set()
133 133 for dir in path:
134 134 normdir = os.path.normcase(dir)
135 135 if not normdir in seen:
136 136 seen.add(normdir)
137 137 for thefile in files:
138 138 name = os.path.join(dir, thefile)
139 139 if _access_check(name, mode):
140 140 return name
141 141 return None
142 142
143 143 if sys.version_info[0] >= 3:
144 144 PY3 = True
145 145
146 146 # keep reference to builtin_mod because the kernel overrides that value
147 147 # to forward requests to a frontend.
148 148 def input(prompt=''):
149 149 return builtin_mod.input(prompt)
150 150
151 151 builtin_mod_name = "builtins"
152 152 import builtins as builtin_mod
153 153
154 154 str_to_unicode = no_code
155 155 unicode_to_str = no_code
156 156 str_to_bytes = encode
157 157 bytes_to_str = decode
158 158 cast_bytes_py2 = no_code
159 159 cast_unicode_py2 = no_code
160 160 buffer_to_bytes_py2 = no_code
161 161
162 162 string_types = (str,)
163 163 unicode_type = str
164 164
165 165 which = shutil.which
166 166
167 167 def isidentifier(s, dotted=False):
168 168 if dotted:
169 169 return all(isidentifier(a) for a in s.split("."))
170 170 return s.isidentifier()
171 171
172 172 xrange = range
173 173 def iteritems(d): return iter(d.items())
174 174 def itervalues(d): return iter(d.values())
175 175 getcwd = os.getcwd
176 176
177 177 MethodType = types.MethodType
178 178
179 179 def execfile(fname, glob, loc=None, compiler=None):
180 180 loc = loc if (loc is not None) else glob
181 181 with open(fname, 'rb') as f:
182 182 compiler = compiler or compile
183 183 exec(compiler(f.read(), fname, 'exec'), glob, loc)
184 184
185 185 # Refactor print statements in doctests.
186 186 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
187 187 def _print_statement_sub(match):
188 188 expr = match.groups('expr')
189 189 return "print(%s)" % expr
190 190
191 191 @_modify_str_or_docstring
192 192 def doctest_refactor_print(doc):
193 193 """Refactor 'print x' statements in a doctest to print(x) style. 2to3
194 194 unfortunately doesn't pick up on our doctests.
195 195
196 196 Can accept a string or a function, so it can be used as a decorator."""
197 197 return _print_statement_re.sub(_print_statement_sub, doc)
198 198
199 199 # Abstract u'abc' syntax:
200 200 @_modify_str_or_docstring
201 201 def u_format(s):
202 202 """"{u}'abc'" --> "'abc'" (Python 3)
203 203
204 204 Accepts a string or a function, so it can be used as a decorator."""
205 205 return s.format(u='')
206 206
207 207 def get_closure(f):
208 208 """Get a function's closure attribute"""
209 209 return f.__closure__
210 210
211 211 else:
212 212 PY3 = False
213 213
214 214 # keep reference to builtin_mod because the kernel overrides that value
215 215 # to forward requests to a frontend.
216 216 def input(prompt=''):
217 217 return builtin_mod.raw_input(prompt)
218 218
219 219 builtin_mod_name = "__builtin__"
220 220 import __builtin__ as builtin_mod
221 221
222 222 str_to_unicode = decode
223 223 unicode_to_str = encode
224 224 str_to_bytes = no_code
225 225 bytes_to_str = no_code
226 226 cast_bytes_py2 = cast_bytes
227 227 cast_unicode_py2 = cast_unicode
228 228 buffer_to_bytes_py2 = buffer_to_bytes
229 229
230 230 string_types = (str, unicode)
231 231 unicode_type = unicode
232 232
233 233 import re
234 234 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
235 235 def isidentifier(s, dotted=False):
236 236 if dotted:
237 237 return all(isidentifier(a) for a in s.split("."))
238 238 return bool(_name_re.match(s))
239 239
240 240 xrange = xrange
241 241 def iteritems(d): return d.iteritems()
242 242 def itervalues(d): return d.itervalues()
243 243 getcwd = os.getcwdu
244 244
245 245 def MethodType(func, instance):
246 246 return types.MethodType(func, instance, type(instance))
247 247
248 248 def doctest_refactor_print(func_or_str):
249 249 return func_or_str
250 250
251 251 def get_closure(f):
252 252 """Get a function's closure attribute"""
253 253 return f.func_closure
254 254
255 255 which = _shutil_which
256 256
257 257 # Abstract u'abc' syntax:
258 258 @_modify_str_or_docstring
259 259 def u_format(s):
260 260 """"{u}'abc'" --> "u'abc'" (Python 2)
261 261
262 262 Accepts a string or a function, so it can be used as a decorator."""
263 263 return s.format(u='u')
264 264
265 265 if sys.platform == 'win32':
266 266 def execfile(fname, glob=None, loc=None, compiler=None):
267 267 loc = loc if (loc is not None) else glob
268 268 scripttext = builtin_mod.open(fname).read()+ '\n'
269 269 # compile converts unicode filename to str assuming
270 270 # ascii. Let's do the conversion before calling compile
271 271 if isinstance(fname, unicode):
272 272 filename = unicode_to_str(fname)
273 273 else:
274 274 filename = fname
275 275 compiler = compiler or compile
276 276 exec(compiler(scripttext, filename, 'exec'), glob, loc)
277 277
278 278 else:
279 279 def execfile(fname, glob=None, loc=None, compiler=None):
280 280 if isinstance(fname, unicode):
281 281 filename = fname.encode(sys.getfilesystemencoding())
282 282 else:
283 283 filename = fname
284 284 where = [ns for ns in [glob, loc] if ns is not None]
285 285 if compiler is None:
286 286 builtin_mod.execfile(filename, *where)
287 287 else:
288 288 scripttext = builtin_mod.open(fname).read().rstrip() + '\n'
289 289 exec(compiler(scripttext, filename, 'exec'), glob, loc)
290 290
291 291
292 PY2 = not PY3
293
294
292 295 def annotate(**kwargs):
293 296 """Python 3 compatible function annotation for Python 2."""
294 297 if not kwargs:
295 298 raise ValueError('annotations must be provided as keyword arguments')
296 299 def dec(f):
297 300 if hasattr(f, '__annotations__'):
298 301 for k, v in kwargs.items():
299 302 f.__annotations__[k] = v
300 303 else:
301 304 f.__annotations__ = kwargs
302 305 return f
303 306 return dec
304 307
305 308
306 309 # Parts below taken from six:
307 310 # Copyright (c) 2010-2013 Benjamin Peterson
308 311 #
309 312 # Permission is hereby granted, free of charge, to any person obtaining a copy
310 313 # of this software and associated documentation files (the "Software"), to deal
311 314 # in the Software without restriction, including without limitation the rights
312 315 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
313 316 # copies of the Software, and to permit persons to whom the Software is
314 317 # furnished to do so, subject to the following conditions:
315 318 #
316 319 # The above copyright notice and this permission notice shall be included in all
317 320 # copies or substantial portions of the Software.
318 321 #
319 322 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
320 323 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
321 324 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
322 325 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
323 326 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
324 327 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
325 328 # SOFTWARE.
326 329
327 330 def with_metaclass(meta, *bases):
328 331 """Create a base class with a metaclass."""
329 332 return meta("_NewBase", bases, {})
General Comments 0
You need to be logged in to leave comments. Login now