##// END OF EJS Templates
reorder stdlib imports...
MinRK -
Show More
@@ -1,557 +1,557 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Display formatters.
3 3
4 4
5 5 Authors:
6 6
7 7 * Robert Kern
8 8 * Brian Granger
9 9 """
10 10 #-----------------------------------------------------------------------------
11 11 # Copyright (c) 2010, IPython Development Team.
12 12 #
13 13 # Distributed under the terms of the Modified BSD License.
14 14 #
15 15 # The full license is in the file COPYING.txt, distributed with this software.
16 16 #-----------------------------------------------------------------------------
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Imports
20 20 #-----------------------------------------------------------------------------
21 21
22 22 # Stdlib imports
23 import sys
24 23 import abc
24 import sys
25 25 # We must use StringIO, as cStringIO doesn't handle unicode properly.
26 26 from StringIO import StringIO
27 27
28 28 # Our own imports
29 29 from IPython.config.configurable import Configurable
30 30 from IPython.external import pretty
31 31 from IPython.utils.traitlets import Bool, Dict, Int, Str, CStr
32 32
33 33
34 34 #-----------------------------------------------------------------------------
35 35 # The main DisplayFormatter class
36 36 #-----------------------------------------------------------------------------
37 37
38 38
39 39 class DisplayFormatter(Configurable):
40 40
41 41 # When set to true only the default plain text formatter will be used.
42 42 plain_text_only = Bool(False, config=True)
43 43
44 44 # A dict of formatter whose keys are format types (MIME types) and whose
45 45 # values are subclasses of BaseFormatter.
46 46 formatters = Dict(config=True)
47 47 def _formatters_default(self):
48 48 """Activate the default formatters."""
49 49 formatter_classes = [
50 50 PlainTextFormatter,
51 51 HTMLFormatter,
52 52 SVGFormatter,
53 53 PNGFormatter,
54 54 LatexFormatter,
55 55 JSONFormatter
56 56 ]
57 57 d = {}
58 58 for cls in formatter_classes:
59 59 f = cls(config=self.config)
60 60 d[f.format_type] = f
61 61 return d
62 62
63 63 def format(self, obj, include=None, exclude=None):
64 64 """Return a format data dict for an object.
65 65
66 66 By default all format types will be computed.
67 67
68 68 The following MIME types are currently implemented:
69 69
70 70 * text/plain
71 71 * text/html
72 72 * text/latex
73 73 * application/json
74 74 * image/png
75 75 * immage/svg+xml
76 76
77 77 Parameters
78 78 ----------
79 79 obj : object
80 80 The Python object whose format data will be computed.
81 81 include : list or tuple, optional
82 82 A list of format type strings (MIME types) to include in the
83 83 format data dict. If this is set *only* the format types included
84 84 in this list will be computed.
85 85 exclude : list or tuple, optional
86 86 A list of format type string (MIME types) to exclue in the format
87 87 data dict. If this is set all format types will be computed,
88 88 except for those included in this argument.
89 89
90 90 Returns
91 91 -------
92 92 format_dict : dict
93 93 A dictionary of key/value pairs, one or each format that was
94 94 generated for the object. The keys are the format types, which
95 95 will usually be MIME type strings and the values and JSON'able
96 96 data structure containing the raw data for the representation in
97 97 that format.
98 98 """
99 99 format_dict = {}
100 100
101 101 # If plain text only is active
102 102 if self.plain_text_only:
103 103 formatter = self.formatters['text/plain']
104 104 try:
105 105 data = formatter(obj)
106 106 except:
107 107 # FIXME: log the exception
108 108 raise
109 109 if data is not None:
110 110 format_dict['text/plain'] = data
111 111 return format_dict
112 112
113 113 for format_type, formatter in self.formatters.items():
114 114 if include is not None:
115 115 if format_type not in include:
116 116 continue
117 117 if exclude is not None:
118 118 if format_type in exclude:
119 119 continue
120 120 try:
121 121 data = formatter(obj)
122 122 except:
123 123 # FIXME: log the exception
124 124 raise
125 125 if data is not None:
126 126 format_dict[format_type] = data
127 127 return format_dict
128 128
129 129 @property
130 130 def format_types(self):
131 131 """Return the format types (MIME types) of the active formatters."""
132 132 return self.formatters.keys()
133 133
134 134
135 135 #-----------------------------------------------------------------------------
136 136 # Formatters for specific format types (text, html, svg, etc.)
137 137 #-----------------------------------------------------------------------------
138 138
139 139
140 140 class FormatterABC(object):
141 141 """ Abstract base class for Formatters.
142 142
143 143 A formatter is a callable class that is responsible for computing the
144 144 raw format data for a particular format type (MIME type). For example,
145 145 an HTML formatter would have a format type of `text/html` and would return
146 146 the HTML representation of the object when called.
147 147 """
148 148 __metaclass__ = abc.ABCMeta
149 149
150 150 # The format type of the data returned, usually a MIME type.
151 151 format_type = 'text/plain'
152 152
153 153 # Is the formatter enabled...
154 154 enabled = True
155 155
156 156 @abc.abstractmethod
157 157 def __call__(self, obj):
158 158 """Return a JSON'able representation of the object.
159 159
160 160 If the object cannot be formatted by this formatter, then return None
161 161 """
162 162 try:
163 163 return repr(obj)
164 164 except TypeError:
165 165 return None
166 166
167 167
168 168 class BaseFormatter(Configurable):
169 169 """A base formatter class that is configurable.
170 170
171 171 This formatter should usually be used as the base class of all formatters.
172 172 It is a traited :class:`Configurable` class and includes an extensible
173 173 API for users to determine how their objects are formatted. The following
174 174 logic is used to find a function to format an given object.
175 175
176 176 1. The object is introspected to see if it has a method with the name
177 177 :attr:`print_method`. If is does, that object is passed to that method
178 178 for formatting.
179 179 2. If no print method is found, three internal dictionaries are consulted
180 180 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
181 181 and :attr:`deferred_printers`.
182 182
183 183 Users should use these dictionaries to register functions that will be
184 184 used to compute the format data for their objects (if those objects don't
185 185 have the special print methods). The easiest way of using these
186 186 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
187 187 methods.
188 188
189 189 If no function/callable is found to compute the format data, ``None`` is
190 190 returned and this format type is not used.
191 191 """
192 192
193 193 format_type = Str('text/plain')
194 194
195 195 enabled = Bool(True, config=True)
196 196
197 197 print_method = Str('__repr__')
198 198
199 199 # The singleton printers.
200 200 # Maps the IDs of the builtin singleton objects to the format functions.
201 201 singleton_printers = Dict(config=True)
202 202 def _singleton_printers_default(self):
203 203 return {}
204 204
205 205 # The type-specific printers.
206 206 # Map type objects to the format functions.
207 207 type_printers = Dict(config=True)
208 208 def _type_printers_default(self):
209 209 return {}
210 210
211 211 # The deferred-import type-specific printers.
212 212 # Map (modulename, classname) pairs to the format functions.
213 213 deferred_printers = Dict(config=True)
214 214 def _deferred_printers_default(self):
215 215 return {}
216 216
217 217 def __call__(self, obj):
218 218 """Compute the format for an object."""
219 219 if self.enabled:
220 220 obj_id = id(obj)
221 221 try:
222 222 obj_class = getattr(obj, '__class__', None) or type(obj)
223 223 if hasattr(obj_class, self.print_method):
224 224 printer = getattr(obj_class, self.print_method)
225 225 return printer(obj)
226 226 try:
227 227 printer = self.singleton_printers[obj_id]
228 228 except (TypeError, KeyError):
229 229 pass
230 230 else:
231 231 return printer(obj)
232 232 for cls in pretty._get_mro(obj_class):
233 233 if cls in self.type_printers:
234 234 return self.type_printers[cls](obj)
235 235 else:
236 236 printer = self._in_deferred_types(cls)
237 237 if printer is not None:
238 238 return printer(obj)
239 239 return None
240 240 except Exception:
241 241 pass
242 242 else:
243 243 return None
244 244
245 245 def for_type(self, typ, func):
246 246 """Add a format function for a given type.
247 247
248 248 Parameters
249 249 -----------
250 250 typ : class
251 251 The class of the object that will be formatted using `func`.
252 252 func : callable
253 253 The callable that will be called to compute the format data. The
254 254 call signature of this function is simple, it must take the
255 255 object to be formatted and return the raw data for the given
256 256 format. Subclasses may use a different call signature for the
257 257 `func` argument.
258 258 """
259 259 oldfunc = self.type_printers.get(typ, None)
260 260 if func is not None:
261 261 # To support easy restoration of old printers, we need to ignore
262 262 # Nones.
263 263 self.type_printers[typ] = func
264 264 return oldfunc
265 265
266 266 def for_type_by_name(self, type_module, type_name, func):
267 267 """Add a format function for a type specified by the full dotted
268 268 module and name of the type, rather than the type of the object.
269 269
270 270 Parameters
271 271 ----------
272 272 type_module : str
273 273 The full dotted name of the module the type is defined in, like
274 274 ``numpy``.
275 275 type_name : str
276 276 The name of the type (the class name), like ``dtype``
277 277 func : callable
278 278 The callable that will be called to compute the format data. The
279 279 call signature of this function is simple, it must take the
280 280 object to be formatted and return the raw data for the given
281 281 format. Subclasses may use a different call signature for the
282 282 `func` argument.
283 283 """
284 284 key = (type_module, type_name)
285 285 oldfunc = self.deferred_printers.get(key, None)
286 286 if func is not None:
287 287 # To support easy restoration of old printers, we need to ignore
288 288 # Nones.
289 289 self.deferred_printers[key] = func
290 290 return oldfunc
291 291
292 292 def _in_deferred_types(self, cls):
293 293 """
294 294 Check if the given class is specified in the deferred type registry.
295 295
296 296 Returns the printer from the registry if it exists, and None if the
297 297 class is not in the registry. Successful matches will be moved to the
298 298 regular type registry for future use.
299 299 """
300 300 mod = getattr(cls, '__module__', None)
301 301 name = getattr(cls, '__name__', None)
302 302 key = (mod, name)
303 303 printer = None
304 304 if key in self.deferred_printers:
305 305 # Move the printer over to the regular registry.
306 306 printer = self.deferred_printers.pop(key)
307 307 self.type_printers[cls] = printer
308 308 return printer
309 309
310 310
311 311 class PlainTextFormatter(BaseFormatter):
312 312 """The default pretty-printer.
313 313
314 314 This uses :mod:`IPython.external.pretty` to compute the format data of
315 315 the object. If the object cannot be pretty printed, :func:`repr` is used.
316 316 See the documentation of :mod:`IPython.external.pretty` for details on
317 317 how to write pretty printers. Here is a simple example::
318 318
319 319 def dtype_pprinter(obj, p, cycle):
320 320 if cycle:
321 321 return p.text('dtype(...)')
322 322 if hasattr(obj, 'fields'):
323 323 if obj.fields is None:
324 324 p.text(repr(obj))
325 325 else:
326 326 p.begin_group(7, 'dtype([')
327 327 for i, field in enumerate(obj.descr):
328 328 if i > 0:
329 329 p.text(',')
330 330 p.breakable()
331 331 p.pretty(field)
332 332 p.end_group(7, '])')
333 333 """
334 334
335 335 # The format type of data returned.
336 336 format_type = Str('text/plain')
337 337
338 338 # This subclass ignores this attribute as it always need to return
339 339 # something.
340 340 enabled = Bool(True, config=False)
341 341
342 342 # Look for a __pretty__ methods to use for pretty printing.
343 343 print_method = Str('__pretty__')
344 344
345 345 # Whether to pretty-print or not.
346 346 pprint = Bool(True, config=True)
347 347
348 348 # Whether to be verbose or not.
349 349 verbose = Bool(False, config=True)
350 350
351 351 # The maximum width.
352 352 max_width = Int(79, config=True)
353 353
354 354 # The newline character.
355 355 newline = Str('\n', config=True)
356 356
357 357 # format-string for pprinting floats
358 358 float_format = Str('%r')
359 359 # setter for float precision, either int or direct format-string
360 360 float_precision = CStr('', config=True)
361 361
362 362 def _float_precision_changed(self, name, old, new):
363 363 """float_precision changed, set float_format accordingly.
364 364
365 365 float_precision can be set by int or str.
366 366 This will set float_format, after interpreting input.
367 367 If numpy has been imported, numpy print precision will also be set.
368 368
369 369 integer `n` sets format to '%.nf', otherwise, format set directly.
370 370
371 371 An empty string returns to defaults (repr for float, 8 for numpy).
372 372
373 373 This parameter can be set via the '%precision' magic.
374 374 """
375 375
376 376 if '%' in new:
377 377 # got explicit format string
378 378 fmt = new
379 379 try:
380 380 fmt%3.14159
381 381 except Exception:
382 382 raise ValueError("Precision must be int or format string, not %r"%new)
383 383 elif new:
384 384 # otherwise, should be an int
385 385 try:
386 386 i = int(new)
387 387 assert i >= 0
388 388 except ValueError:
389 389 raise ValueError("Precision must be int or format string, not %r"%new)
390 390 except AssertionError:
391 391 raise ValueError("int precision must be non-negative, not %r"%i)
392 392
393 393 fmt = '%%.%if'%i
394 394 if 'numpy' in sys.modules:
395 395 # set numpy precision if it has been imported
396 396 import numpy
397 397 numpy.set_printoptions(precision=i)
398 398 else:
399 399 # default back to repr
400 400 fmt = '%r'
401 401 if 'numpy' in sys.modules:
402 402 import numpy
403 403 # numpy default is 8
404 404 numpy.set_printoptions(precision=8)
405 405 self.float_format = fmt
406 406
407 407 # Use the default pretty printers from IPython.external.pretty.
408 408 def _singleton_printers_default(self):
409 409 return pretty._singleton_pprinters.copy()
410 410
411 411 def _type_printers_default(self):
412 412 d = pretty._type_pprinters.copy()
413 413 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
414 414 return d
415 415
416 416 def _deferred_printers_default(self):
417 417 return pretty._deferred_type_pprinters.copy()
418 418
419 419 #### FormatterABC interface ####
420 420
421 421 def __call__(self, obj):
422 422 """Compute the pretty representation of the object."""
423 423 if not self.pprint:
424 424 try:
425 425 return repr(obj)
426 426 except TypeError:
427 427 return ''
428 428 else:
429 429 # This uses use StringIO, as cStringIO doesn't handle unicode.
430 430 stream = StringIO()
431 431 printer = pretty.RepresentationPrinter(stream, self.verbose,
432 432 self.max_width, self.newline,
433 433 singleton_pprinters=self.singleton_printers,
434 434 type_pprinters=self.type_printers,
435 435 deferred_pprinters=self.deferred_printers)
436 436 printer.pretty(obj)
437 437 printer.flush()
438 438 return stream.getvalue()
439 439
440 440
441 441 class HTMLFormatter(BaseFormatter):
442 442 """An HTML formatter.
443 443
444 444 To define the callables that compute the HTML representation of your
445 445 objects, define a :meth:`__html__` method or use the :meth:`for_type`
446 446 or :meth:`for_type_by_name` methods to register functions that handle
447 447 this.
448 448 """
449 449 format_type = Str('text/html')
450 450
451 451 print_method = Str('__html__')
452 452
453 453
454 454 class SVGFormatter(BaseFormatter):
455 455 """An SVG formatter.
456 456
457 457 To define the callables that compute the SVG representation of your
458 458 objects, define a :meth:`__svg__` method or use the :meth:`for_type`
459 459 or :meth:`for_type_by_name` methods to register functions that handle
460 460 this.
461 461 """
462 462 format_type = Str('image/svg+xml')
463 463
464 464 print_method = Str('__svg__')
465 465
466 466
467 467 class PNGFormatter(BaseFormatter):
468 468 """A PNG formatter.
469 469
470 470 To define the callables that compute the PNG representation of your
471 471 objects, define a :meth:`__png__` method or use the :meth:`for_type`
472 472 or :meth:`for_type_by_name` methods to register functions that handle
473 473 this. The raw data should be the base64 encoded raw png data.
474 474 """
475 475 format_type = Str('image/png')
476 476
477 477 print_method = Str('__png__')
478 478
479 479
480 480 class LatexFormatter(BaseFormatter):
481 481 """A LaTeX formatter.
482 482
483 483 To define the callables that compute the LaTeX representation of your
484 484 objects, define a :meth:`__latex__` method or use the :meth:`for_type`
485 485 or :meth:`for_type_by_name` methods to register functions that handle
486 486 this.
487 487 """
488 488 format_type = Str('text/latex')
489 489
490 490 print_method = Str('__latex__')
491 491
492 492
493 493 class JSONFormatter(BaseFormatter):
494 494 """A JSON string formatter.
495 495
496 496 To define the callables that compute the JSON string representation of
497 497 your objects, define a :meth:`__json__` method or use the :meth:`for_type`
498 498 or :meth:`for_type_by_name` methods to register functions that handle
499 499 this.
500 500 """
501 501 format_type = Str('application/json')
502 502
503 503 print_method = Str('__json__')
504 504
505 505
506 506 FormatterABC.register(BaseFormatter)
507 507 FormatterABC.register(PlainTextFormatter)
508 508 FormatterABC.register(HTMLFormatter)
509 509 FormatterABC.register(SVGFormatter)
510 510 FormatterABC.register(PNGFormatter)
511 511 FormatterABC.register(LatexFormatter)
512 512 FormatterABC.register(JSONFormatter)
513 513
514 514
515 515 def format_display_data(obj, include=None, exclude=None):
516 516 """Return a format data dict for an object.
517 517
518 518 By default all format types will be computed.
519 519
520 520 The following MIME types are currently implemented:
521 521
522 522 * text/plain
523 523 * text/html
524 524 * text/latex
525 525 * application/json
526 526 * image/png
527 527 * immage/svg+xml
528 528
529 529 Parameters
530 530 ----------
531 531 obj : object
532 532 The Python object whose format data will be computed.
533 533
534 534 Returns
535 535 -------
536 536 format_dict : dict
537 537 A dictionary of key/value pairs, one or each format that was
538 538 generated for the object. The keys are the format types, which
539 539 will usually be MIME type strings and the values and JSON'able
540 540 data structure containing the raw data for the representation in
541 541 that format.
542 542 include : list or tuple, optional
543 543 A list of format type strings (MIME types) to include in the
544 544 format data dict. If this is set *only* the format types included
545 545 in this list will be computed.
546 546 exclude : list or tuple, optional
547 547 A list of format type string (MIME types) to exclue in the format
548 548 data dict. If this is set all format types will be computed,
549 549 except for those included in this argument.
550 550 """
551 551 from IPython.core.interactiveshell import InteractiveShell
552 552
553 553 InteractiveShell.instance().display_formatter.format(
554 554 obj,
555 555 include,
556 556 exclude
557 557 )
General Comments 0
You need to be logged in to leave comments. Login now