##// END OF EJS Templates
Miscellaneous Python 3 fixes
Thomas Kluyver -
Show More
@@ -1,821 +1,821
1 1 """A simple configuration system.
2 2
3 3 Inheritance diagram:
4 4
5 5 .. inheritance-diagram:: IPython.config.loader
6 6 :parts: 3
7 7
8 8 Authors
9 9 -------
10 10 * Brian Granger
11 11 * Fernando Perez
12 12 * Min RK
13 13 """
14 14
15 15 #-----------------------------------------------------------------------------
16 16 # Copyright (C) 2008-2011 The IPython Development Team
17 17 #
18 18 # Distributed under the terms of the BSD License. The full license is in
19 19 # the file COPYING, distributed as part of this software.
20 20 #-----------------------------------------------------------------------------
21 21
22 22 #-----------------------------------------------------------------------------
23 23 # Imports
24 24 #-----------------------------------------------------------------------------
25 25
26 26 import argparse
27 27 import copy
28 28 import os
29 29 import re
30 30 import sys
31 31
32 32 from IPython.utils.path import filefind, get_ipython_dir
33 33 from IPython.utils import py3compat, warn
34 34 from IPython.utils.encoding import DEFAULT_ENCODING
35 35 from IPython.utils.py3compat import builtin_mod, unicode_type, iteritems
36 36 from IPython.utils.traitlets import HasTraits, List, Any, TraitError
37 37
38 38 #-----------------------------------------------------------------------------
39 39 # Exceptions
40 40 #-----------------------------------------------------------------------------
41 41
42 42
43 43 class ConfigError(Exception):
44 44 pass
45 45
46 46 class ConfigLoaderError(ConfigError):
47 47 pass
48 48
49 49 class ConfigFileNotFound(ConfigError):
50 50 pass
51 51
52 52 class ArgumentError(ConfigLoaderError):
53 53 pass
54 54
55 55 #-----------------------------------------------------------------------------
56 56 # Argparse fix
57 57 #-----------------------------------------------------------------------------
58 58
59 59 # Unfortunately argparse by default prints help messages to stderr instead of
60 60 # stdout. This makes it annoying to capture long help screens at the command
61 61 # line, since one must know how to pipe stderr, which many users don't know how
62 62 # to do. So we override the print_help method with one that defaults to
63 63 # stdout and use our class instead.
64 64
65 65 class ArgumentParser(argparse.ArgumentParser):
66 66 """Simple argparse subclass that prints help to stdout by default."""
67 67
68 68 def print_help(self, file=None):
69 69 if file is None:
70 70 file = sys.stdout
71 71 return super(ArgumentParser, self).print_help(file)
72 72
73 73 print_help.__doc__ = argparse.ArgumentParser.print_help.__doc__
74 74
75 75 #-----------------------------------------------------------------------------
76 76 # Config class for holding config information
77 77 #-----------------------------------------------------------------------------
78 78
79 79 class LazyConfigValue(HasTraits):
80 80 """Proxy object for exposing methods on configurable containers
81 81
82 82 Exposes:
83 83
84 84 - append, extend, insert on lists
85 85 - update on dicts
86 86 - update, add on sets
87 87 """
88 88
89 89 _value = None
90 90
91 91 # list methods
92 92 _extend = List()
93 93 _prepend = List()
94 94
95 95 def append(self, obj):
96 96 self._extend.append(obj)
97 97
98 98 def extend(self, other):
99 99 self._extend.extend(other)
100 100
101 101 def prepend(self, other):
102 102 """like list.extend, but for the front"""
103 103 self._prepend[:0] = other
104 104
105 105 _inserts = List()
106 106 def insert(self, index, other):
107 107 if not isinstance(index, int):
108 108 raise TypeError("An integer is required")
109 109 self._inserts.append((index, other))
110 110
111 111 # dict methods
112 112 # update is used for both dict and set
113 113 _update = Any()
114 114 def update(self, other):
115 115 if self._update is None:
116 116 if isinstance(other, dict):
117 117 self._update = {}
118 118 else:
119 119 self._update = set()
120 120 self._update.update(other)
121 121
122 122 # set methods
123 123 def add(self, obj):
124 124 self.update({obj})
125 125
126 126 def get_value(self, initial):
127 127 """construct the value from the initial one
128 128
129 129 after applying any insert / extend / update changes
130 130 """
131 131 if self._value is not None:
132 132 return self._value
133 133 value = copy.deepcopy(initial)
134 134 if isinstance(value, list):
135 135 for idx, obj in self._inserts:
136 136 value.insert(idx, obj)
137 137 value[:0] = self._prepend
138 138 value.extend(self._extend)
139 139
140 140 elif isinstance(value, dict):
141 141 if self._update:
142 142 value.update(self._update)
143 143 elif isinstance(value, set):
144 144 if self._update:
145 145 value.update(self._update)
146 146 self._value = value
147 147 return value
148 148
149 149 def to_dict(self):
150 150 """return JSONable dict form of my data
151 151
152 152 Currently update as dict or set, extend, prepend as lists, and inserts as list of tuples.
153 153 """
154 154 d = {}
155 155 if self._update:
156 156 d['update'] = self._update
157 157 if self._extend:
158 158 d['extend'] = self._extend
159 159 if self._prepend:
160 160 d['prepend'] = self._prepend
161 161 elif self._inserts:
162 162 d['inserts'] = self._inserts
163 163 return d
164 164
165 165
166 166 class Config(dict):
167 167 """An attribute based dict that can do smart merges."""
168 168
169 169 def __init__(self, *args, **kwds):
170 170 dict.__init__(self, *args, **kwds)
171 171 # This sets self.__dict__ = self, but it has to be done this way
172 172 # because we are also overriding __setattr__.
173 173 dict.__setattr__(self, '__dict__', self)
174 174 self._ensure_subconfig()
175 175
176 176 def _ensure_subconfig(self):
177 177 """ensure that sub-dicts that should be Config objects are
178 178
179 179 casts dicts that are under section keys to Config objects,
180 180 which is necessary for constructing Config objects from dict literals.
181 181 """
182 182 for key in self:
183 183 obj = self[key]
184 184 if self._is_section_key(key) \
185 185 and isinstance(obj, dict) \
186 186 and not isinstance(obj, Config):
187 187 dict.__setattr__(self, key, Config(obj))
188 188
189 189 def _merge(self, other):
190 190 """deprecated alias, use Config.merge()"""
191 191 self.merge(other)
192 192
193 193 def merge(self, other):
194 194 """merge another config object into this one"""
195 195 to_update = {}
196 196 for k, v in iteritems(other):
197 197 if k not in self:
198 198 to_update[k] = v
199 199 else: # I have this key
200 200 if isinstance(v, Config) and isinstance(self[k], Config):
201 201 # Recursively merge common sub Configs
202 202 self[k].merge(v)
203 203 else:
204 204 # Plain updates for non-Configs
205 205 to_update[k] = v
206 206
207 207 self.update(to_update)
208 208
209 209 def _is_section_key(self, key):
210 210 if key[0].upper()==key[0] and not key.startswith('_'):
211 211 return True
212 212 else:
213 213 return False
214 214
215 215 def __contains__(self, key):
216 216 # allow nested contains of the form `"Section.key" in config`
217 217 if '.' in key:
218 218 first, remainder = key.split('.', 1)
219 219 if first not in self:
220 220 return False
221 221 return remainder in self[first]
222 222
223 223 # we always have Sections
224 224 if self._is_section_key(key):
225 225 return True
226 226 else:
227 227 return super(Config, self).__contains__(key)
228 228 # .has_key is deprecated for dictionaries.
229 229 has_key = __contains__
230 230
231 231 def _has_section(self, key):
232 232 if self._is_section_key(key):
233 233 if super(Config, self).__contains__(key):
234 234 return True
235 235 return False
236 236
237 237 def copy(self):
238 238 return type(self)(dict.copy(self))
239 239
240 240 def __copy__(self):
241 241 return self.copy()
242 242
243 243 def __deepcopy__(self, memo):
244 244 import copy
245 return type(self)(copy.deepcopy(self.items()))
245 return type(self)(copy.deepcopy(list(self.items())))
246 246
247 247 def __getitem__(self, key):
248 248 # We cannot use directly self._is_section_key, because it triggers
249 249 # infinite recursion on top of PyPy. Instead, we manually fish the
250 250 # bound method.
251 251 is_section_key = self.__class__._is_section_key.__get__(self)
252 252
253 253 # Because we use this for an exec namespace, we need to delegate
254 254 # the lookup of names in __builtin__ to itself. This means
255 255 # that you can't have section or attribute names that are
256 256 # builtins.
257 257 try:
258 258 return getattr(builtin_mod, key)
259 259 except AttributeError:
260 260 pass
261 261 if is_section_key(key):
262 262 try:
263 263 return dict.__getitem__(self, key)
264 264 except KeyError:
265 265 c = Config()
266 266 dict.__setitem__(self, key, c)
267 267 return c
268 268 else:
269 269 try:
270 270 return dict.__getitem__(self, key)
271 271 except KeyError:
272 272 # undefined
273 273 v = LazyConfigValue()
274 274 dict.__setitem__(self, key, v)
275 275 return v
276 276
277 277
278 278 def __setitem__(self, key, value):
279 279 if self._is_section_key(key):
280 280 if not isinstance(value, Config):
281 281 raise ValueError('values whose keys begin with an uppercase '
282 282 'char must be Config instances: %r, %r' % (key, value))
283 283 else:
284 284 dict.__setitem__(self, key, value)
285 285
286 286 def __getattr__(self, key):
287 287 try:
288 288 return self.__getitem__(key)
289 289 except KeyError as e:
290 290 raise AttributeError(e)
291 291
292 292 def __setattr__(self, key, value):
293 293 try:
294 294 self.__setitem__(key, value)
295 295 except KeyError as e:
296 296 raise AttributeError(e)
297 297
298 298 def __delattr__(self, key):
299 299 try:
300 300 dict.__delitem__(self, key)
301 301 except KeyError as e:
302 302 raise AttributeError(e)
303 303
304 304
305 305 #-----------------------------------------------------------------------------
306 306 # Config loading classes
307 307 #-----------------------------------------------------------------------------
308 308
309 309
310 310 class ConfigLoader(object):
311 311 """A object for loading configurations from just about anywhere.
312 312
313 313 The resulting configuration is packaged as a :class:`Struct`.
314 314
315 315 Notes
316 316 -----
317 317 A :class:`ConfigLoader` does one thing: load a config from a source
318 318 (file, command line arguments) and returns the data as a :class:`Struct`.
319 319 There are lots of things that :class:`ConfigLoader` does not do. It does
320 320 not implement complex logic for finding config files. It does not handle
321 321 default values or merge multiple configs. These things need to be
322 322 handled elsewhere.
323 323 """
324 324
325 325 def __init__(self):
326 326 """A base class for config loaders.
327 327
328 328 Examples
329 329 --------
330 330
331 331 >>> cl = ConfigLoader()
332 332 >>> config = cl.load_config()
333 333 >>> config
334 334 {}
335 335 """
336 336 self.clear()
337 337
338 338 def clear(self):
339 339 self.config = Config()
340 340
341 341 def load_config(self):
342 342 """Load a config from somewhere, return a :class:`Config` instance.
343 343
344 344 Usually, this will cause self.config to be set and then returned.
345 345 However, in most cases, :meth:`ConfigLoader.clear` should be called
346 346 to erase any previous state.
347 347 """
348 348 self.clear()
349 349 return self.config
350 350
351 351
352 352 class FileConfigLoader(ConfigLoader):
353 353 """A base class for file based configurations.
354 354
355 355 As we add more file based config loaders, the common logic should go
356 356 here.
357 357 """
358 358 pass
359 359
360 360
361 361 class PyFileConfigLoader(FileConfigLoader):
362 362 """A config loader for pure python files.
363 363
364 364 This calls execfile on a plain python file and looks for attributes
365 365 that are all caps. These attribute are added to the config Struct.
366 366 """
367 367
368 368 def __init__(self, filename, path=None):
369 369 """Build a config loader for a filename and path.
370 370
371 371 Parameters
372 372 ----------
373 373 filename : str
374 374 The file name of the config file.
375 375 path : str, list, tuple
376 376 The path to search for the config file on, or a sequence of
377 377 paths to try in order.
378 378 """
379 379 super(PyFileConfigLoader, self).__init__()
380 380 self.filename = filename
381 381 self.path = path
382 382 self.full_filename = ''
383 383 self.data = None
384 384
385 385 def load_config(self):
386 386 """Load the config from a file and return it as a Struct."""
387 387 self.clear()
388 388 try:
389 389 self._find_file()
390 390 except IOError as e:
391 391 raise ConfigFileNotFound(str(e))
392 392 self._read_file_as_dict()
393 393 self._convert_to_config()
394 394 return self.config
395 395
396 396 def _find_file(self):
397 397 """Try to find the file by searching the paths."""
398 398 self.full_filename = filefind(self.filename, self.path)
399 399
400 400 def _read_file_as_dict(self):
401 401 """Load the config file into self.config, with recursive loading."""
402 402 # This closure is made available in the namespace that is used
403 403 # to exec the config file. It allows users to call
404 404 # load_subconfig('myconfig.py') to load config files recursively.
405 405 # It needs to be a closure because it has references to self.path
406 406 # and self.config. The sub-config is loaded with the same path
407 407 # as the parent, but it uses an empty config which is then merged
408 408 # with the parents.
409 409
410 410 # If a profile is specified, the config file will be loaded
411 411 # from that profile
412 412
413 413 def load_subconfig(fname, profile=None):
414 414 # import here to prevent circular imports
415 415 from IPython.core.profiledir import ProfileDir, ProfileDirError
416 416 if profile is not None:
417 417 try:
418 418 profile_dir = ProfileDir.find_profile_dir_by_name(
419 419 get_ipython_dir(),
420 420 profile,
421 421 )
422 422 except ProfileDirError:
423 423 return
424 424 path = profile_dir.location
425 425 else:
426 426 path = self.path
427 427 loader = PyFileConfigLoader(fname, path)
428 428 try:
429 429 sub_config = loader.load_config()
430 430 except ConfigFileNotFound:
431 431 # Pass silently if the sub config is not there. This happens
432 432 # when a user s using a profile, but not the default config.
433 433 pass
434 434 else:
435 435 self.config.merge(sub_config)
436 436
437 437 # Again, this needs to be a closure and should be used in config
438 438 # files to get the config being loaded.
439 439 def get_config():
440 440 return self.config
441 441
442 442 namespace = dict(
443 443 load_subconfig=load_subconfig,
444 444 get_config=get_config,
445 445 __file__=self.full_filename,
446 446 )
447 447 fs_encoding = sys.getfilesystemencoding() or 'ascii'
448 448 conf_filename = self.full_filename.encode(fs_encoding)
449 449 py3compat.execfile(conf_filename, namespace)
450 450
451 451 def _convert_to_config(self):
452 452 if self.data is None:
453 453 ConfigLoaderError('self.data does not exist')
454 454
455 455
456 456 class CommandLineConfigLoader(ConfigLoader):
457 457 """A config loader for command line arguments.
458 458
459 459 As we add more command line based loaders, the common logic should go
460 460 here.
461 461 """
462 462
463 463 def _exec_config_str(self, lhs, rhs):
464 464 """execute self.config.<lhs> = <rhs>
465 465
466 466 * expands ~ with expanduser
467 467 * tries to assign with raw eval, otherwise assigns with just the string,
468 468 allowing `--C.a=foobar` and `--C.a="foobar"` to be equivalent. *Not*
469 469 equivalent are `--C.a=4` and `--C.a='4'`.
470 470 """
471 471 rhs = os.path.expanduser(rhs)
472 472 try:
473 473 # Try to see if regular Python syntax will work. This
474 474 # won't handle strings as the quote marks are removed
475 475 # by the system shell.
476 476 value = eval(rhs)
477 477 except (NameError, SyntaxError):
478 478 # This case happens if the rhs is a string.
479 479 value = rhs
480 480
481 481 exec(u'self.config.%s = value' % lhs)
482 482
483 483 def _load_flag(self, cfg):
484 484 """update self.config from a flag, which can be a dict or Config"""
485 485 if isinstance(cfg, (dict, Config)):
486 486 # don't clobber whole config sections, update
487 487 # each section from config:
488 488 for sec,c in iteritems(cfg):
489 489 self.config[sec].update(c)
490 490 else:
491 491 raise TypeError("Invalid flag: %r" % cfg)
492 492
493 493 # raw --identifier=value pattern
494 494 # but *also* accept '-' as wordsep, for aliases
495 495 # accepts: --foo=a
496 496 # --Class.trait=value
497 497 # --alias-name=value
498 498 # rejects: -foo=value
499 499 # --foo
500 500 # --Class.trait
501 501 kv_pattern = re.compile(r'\-\-[A-Za-z][\w\-]*(\.[\w\-]+)*\=.*')
502 502
503 503 # just flags, no assignments, with two *or one* leading '-'
504 504 # accepts: --foo
505 505 # -foo-bar-again
506 506 # rejects: --anything=anything
507 507 # --two.word
508 508
509 509 flag_pattern = re.compile(r'\-\-?\w+[\-\w]*$')
510 510
511 511 class KeyValueConfigLoader(CommandLineConfigLoader):
512 512 """A config loader that loads key value pairs from the command line.
513 513
514 514 This allows command line options to be gives in the following form::
515 515
516 516 ipython --profile="foo" --InteractiveShell.autocall=False
517 517 """
518 518
519 519 def __init__(self, argv=None, aliases=None, flags=None):
520 520 """Create a key value pair config loader.
521 521
522 522 Parameters
523 523 ----------
524 524 argv : list
525 525 A list that has the form of sys.argv[1:] which has unicode
526 526 elements of the form u"key=value". If this is None (default),
527 527 then sys.argv[1:] will be used.
528 528 aliases : dict
529 529 A dict of aliases for configurable traits.
530 530 Keys are the short aliases, Values are the resolved trait.
531 531 Of the form: `{'alias' : 'Configurable.trait'}`
532 532 flags : dict
533 533 A dict of flags, keyed by str name. Vaues can be Config objects,
534 534 dicts, or "key=value" strings. If Config or dict, when the flag
535 535 is triggered, The flag is loaded as `self.config.update(m)`.
536 536
537 537 Returns
538 538 -------
539 539 config : Config
540 540 The resulting Config object.
541 541
542 542 Examples
543 543 --------
544 544
545 545 >>> from IPython.config.loader import KeyValueConfigLoader
546 546 >>> cl = KeyValueConfigLoader()
547 547 >>> d = cl.load_config(["--A.name='brian'","--B.number=0"])
548 548 >>> sorted(d.items())
549 549 [('A', {'name': 'brian'}), ('B', {'number': 0})]
550 550 """
551 551 self.clear()
552 552 if argv is None:
553 553 argv = sys.argv[1:]
554 554 self.argv = argv
555 555 self.aliases = aliases or {}
556 556 self.flags = flags or {}
557 557
558 558
559 559 def clear(self):
560 560 super(KeyValueConfigLoader, self).clear()
561 561 self.extra_args = []
562 562
563 563
564 564 def _decode_argv(self, argv, enc=None):
565 565 """decode argv if bytes, using stin.encoding, falling back on default enc"""
566 566 uargv = []
567 567 if enc is None:
568 568 enc = DEFAULT_ENCODING
569 569 for arg in argv:
570 570 if not isinstance(arg, unicode_type):
571 571 # only decode if not already decoded
572 572 arg = arg.decode(enc)
573 573 uargv.append(arg)
574 574 return uargv
575 575
576 576
577 577 def load_config(self, argv=None, aliases=None, flags=None):
578 578 """Parse the configuration and generate the Config object.
579 579
580 580 After loading, any arguments that are not key-value or
581 581 flags will be stored in self.extra_args - a list of
582 582 unparsed command-line arguments. This is used for
583 583 arguments such as input files or subcommands.
584 584
585 585 Parameters
586 586 ----------
587 587 argv : list, optional
588 588 A list that has the form of sys.argv[1:] which has unicode
589 589 elements of the form u"key=value". If this is None (default),
590 590 then self.argv will be used.
591 591 aliases : dict
592 592 A dict of aliases for configurable traits.
593 593 Keys are the short aliases, Values are the resolved trait.
594 594 Of the form: `{'alias' : 'Configurable.trait'}`
595 595 flags : dict
596 596 A dict of flags, keyed by str name. Values can be Config objects
597 597 or dicts. When the flag is triggered, The config is loaded as
598 598 `self.config.update(cfg)`.
599 599 """
600 600 self.clear()
601 601 if argv is None:
602 602 argv = self.argv
603 603 if aliases is None:
604 604 aliases = self.aliases
605 605 if flags is None:
606 606 flags = self.flags
607 607
608 608 # ensure argv is a list of unicode strings:
609 609 uargv = self._decode_argv(argv)
610 610 for idx,raw in enumerate(uargv):
611 611 # strip leading '-'
612 612 item = raw.lstrip('-')
613 613
614 614 if raw == '--':
615 615 # don't parse arguments after '--'
616 616 # this is useful for relaying arguments to scripts, e.g.
617 617 # ipython -i foo.py --matplotlib=qt -- args after '--' go-to-foo.py
618 618 self.extra_args.extend(uargv[idx+1:])
619 619 break
620 620
621 621 if kv_pattern.match(raw):
622 622 lhs,rhs = item.split('=',1)
623 623 # Substitute longnames for aliases.
624 624 if lhs in aliases:
625 625 lhs = aliases[lhs]
626 626 if '.' not in lhs:
627 627 # probably a mistyped alias, but not technically illegal
628 628 warn.warn("Unrecognized alias: '%s', it will probably have no effect."%lhs)
629 629 try:
630 630 self._exec_config_str(lhs, rhs)
631 631 except Exception:
632 632 raise ArgumentError("Invalid argument: '%s'" % raw)
633 633
634 634 elif flag_pattern.match(raw):
635 635 if item in flags:
636 636 cfg,help = flags[item]
637 637 self._load_flag(cfg)
638 638 else:
639 639 raise ArgumentError("Unrecognized flag: '%s'"%raw)
640 640 elif raw.startswith('-'):
641 641 kv = '--'+item
642 642 if kv_pattern.match(kv):
643 643 raise ArgumentError("Invalid argument: '%s', did you mean '%s'?"%(raw, kv))
644 644 else:
645 645 raise ArgumentError("Invalid argument: '%s'"%raw)
646 646 else:
647 647 # keep all args that aren't valid in a list,
648 648 # in case our parent knows what to do with them.
649 649 self.extra_args.append(item)
650 650 return self.config
651 651
652 652 class ArgParseConfigLoader(CommandLineConfigLoader):
653 653 """A loader that uses the argparse module to load from the command line."""
654 654
655 655 def __init__(self, argv=None, aliases=None, flags=None, *parser_args, **parser_kw):
656 656 """Create a config loader for use with argparse.
657 657
658 658 Parameters
659 659 ----------
660 660
661 661 argv : optional, list
662 662 If given, used to read command-line arguments from, otherwise
663 663 sys.argv[1:] is used.
664 664
665 665 parser_args : tuple
666 666 A tuple of positional arguments that will be passed to the
667 667 constructor of :class:`argparse.ArgumentParser`.
668 668
669 669 parser_kw : dict
670 670 A tuple of keyword arguments that will be passed to the
671 671 constructor of :class:`argparse.ArgumentParser`.
672 672
673 673 Returns
674 674 -------
675 675 config : Config
676 676 The resulting Config object.
677 677 """
678 678 super(CommandLineConfigLoader, self).__init__()
679 679 self.clear()
680 680 if argv is None:
681 681 argv = sys.argv[1:]
682 682 self.argv = argv
683 683 self.aliases = aliases or {}
684 684 self.flags = flags or {}
685 685
686 686 self.parser_args = parser_args
687 687 self.version = parser_kw.pop("version", None)
688 688 kwargs = dict(argument_default=argparse.SUPPRESS)
689 689 kwargs.update(parser_kw)
690 690 self.parser_kw = kwargs
691 691
692 692 def load_config(self, argv=None, aliases=None, flags=None):
693 693 """Parse command line arguments and return as a Config object.
694 694
695 695 Parameters
696 696 ----------
697 697
698 698 args : optional, list
699 699 If given, a list with the structure of sys.argv[1:] to parse
700 700 arguments from. If not given, the instance's self.argv attribute
701 701 (given at construction time) is used."""
702 702 self.clear()
703 703 if argv is None:
704 704 argv = self.argv
705 705 if aliases is None:
706 706 aliases = self.aliases
707 707 if flags is None:
708 708 flags = self.flags
709 709 self._create_parser(aliases, flags)
710 710 self._parse_args(argv)
711 711 self._convert_to_config()
712 712 return self.config
713 713
714 714 def get_extra_args(self):
715 715 if hasattr(self, 'extra_args'):
716 716 return self.extra_args
717 717 else:
718 718 return []
719 719
720 720 def _create_parser(self, aliases=None, flags=None):
721 721 self.parser = ArgumentParser(*self.parser_args, **self.parser_kw)
722 722 self._add_arguments(aliases, flags)
723 723
724 724 def _add_arguments(self, aliases=None, flags=None):
725 725 raise NotImplementedError("subclasses must implement _add_arguments")
726 726
727 727 def _parse_args(self, args):
728 728 """self.parser->self.parsed_data"""
729 729 # decode sys.argv to support unicode command-line options
730 730 enc = DEFAULT_ENCODING
731 731 uargs = [py3compat.cast_unicode(a, enc) for a in args]
732 732 self.parsed_data, self.extra_args = self.parser.parse_known_args(uargs)
733 733
734 734 def _convert_to_config(self):
735 735 """self.parsed_data->self.config"""
736 736 for k, v in iteritems(vars(self.parsed_data)):
737 737 exec("self.config.%s = v"%k, locals(), globals())
738 738
739 739 class KVArgParseConfigLoader(ArgParseConfigLoader):
740 740 """A config loader that loads aliases and flags with argparse,
741 741 but will use KVLoader for the rest. This allows better parsing
742 742 of common args, such as `ipython -c 'print 5'`, but still gets
743 743 arbitrary config with `ipython --InteractiveShell.use_readline=False`"""
744 744
745 745 def _add_arguments(self, aliases=None, flags=None):
746 746 self.alias_flags = {}
747 747 # print aliases, flags
748 748 if aliases is None:
749 749 aliases = self.aliases
750 750 if flags is None:
751 751 flags = self.flags
752 752 paa = self.parser.add_argument
753 753 for key,value in iteritems(aliases):
754 754 if key in flags:
755 755 # flags
756 756 nargs = '?'
757 757 else:
758 758 nargs = None
759 759 if len(key) is 1:
760 760 paa('-'+key, '--'+key, type=unicode_type, dest=value, nargs=nargs)
761 761 else:
762 762 paa('--'+key, type=unicode_type, dest=value, nargs=nargs)
763 763 for key, (value, help) in iteritems(flags):
764 764 if key in self.aliases:
765 765 #
766 766 self.alias_flags[self.aliases[key]] = value
767 767 continue
768 768 if len(key) is 1:
769 769 paa('-'+key, '--'+key, action='append_const', dest='_flags', const=value)
770 770 else:
771 771 paa('--'+key, action='append_const', dest='_flags', const=value)
772 772
773 773 def _convert_to_config(self):
774 774 """self.parsed_data->self.config, parse unrecognized extra args via KVLoader."""
775 775 # remove subconfigs list from namespace before transforming the Namespace
776 776 if '_flags' in self.parsed_data:
777 777 subcs = self.parsed_data._flags
778 778 del self.parsed_data._flags
779 779 else:
780 780 subcs = []
781 781
782 782 for k, v in iteritems(vars(self.parsed_data)):
783 783 if v is None:
784 784 # it was a flag that shares the name of an alias
785 785 subcs.append(self.alias_flags[k])
786 786 else:
787 787 # eval the KV assignment
788 788 self._exec_config_str(k, v)
789 789
790 790 for subc in subcs:
791 791 self._load_flag(subc)
792 792
793 793 if self.extra_args:
794 794 sub_parser = KeyValueConfigLoader()
795 795 sub_parser.load_config(self.extra_args)
796 796 self.config.merge(sub_parser.config)
797 797 self.extra_args = sub_parser.extra_args
798 798
799 799
800 800 def load_pyconfig_files(config_files, path):
801 801 """Load multiple Python config files, merging each of them in turn.
802 802
803 803 Parameters
804 804 ==========
805 805 config_files : list of str
806 806 List of config files names to load and merge into the config.
807 807 path : unicode
808 808 The full path to the location of the config files.
809 809 """
810 810 config = Config()
811 811 for cf in config_files:
812 812 loader = PyFileConfigLoader(cf, path=path)
813 813 try:
814 814 next_config = loader.load_config()
815 815 except ConfigFileNotFound:
816 816 pass
817 817 except:
818 818 raise
819 819 else:
820 820 config.merge(next_config)
821 821 return config
@@ -1,654 +1,654
1 1 # -*- coding: utf-8 -*-
2 2 """Display formatters.
3 3
4 4 Inheritance diagram:
5 5
6 6 .. inheritance-diagram:: IPython.core.formatters
7 7 :parts: 3
8 8
9 9 Authors:
10 10
11 11 * Robert Kern
12 12 * Brian Granger
13 13 """
14 14 #-----------------------------------------------------------------------------
15 15 # Copyright (C) 2010-2011, IPython Development Team.
16 16 #
17 17 # Distributed under the terms of the Modified BSD License.
18 18 #
19 19 # The full license is in the file COPYING.txt, distributed with this software.
20 20 #-----------------------------------------------------------------------------
21 21
22 22 #-----------------------------------------------------------------------------
23 23 # Imports
24 24 #-----------------------------------------------------------------------------
25 25
26 26 # Stdlib imports
27 27 import abc
28 28 import sys
29 29 import warnings
30 30 # We must use StringIO, as cStringIO doesn't handle unicode properly.
31 31 from io import StringIO
32 32
33 33 # Our own imports
34 34 from IPython.config.configurable import Configurable
35 35 from IPython.lib import pretty
36 36 from IPython.utils.traitlets import (
37 37 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
38 38 )
39 39 from IPython.utils.py3compat import unicode_to_str, with_metaclass
40 40
41 41
42 42 #-----------------------------------------------------------------------------
43 43 # The main DisplayFormatter class
44 44 #-----------------------------------------------------------------------------
45 45
46 46
47 47 class DisplayFormatter(Configurable):
48 48
49 49 # When set to true only the default plain text formatter will be used.
50 50 plain_text_only = Bool(False, config=True)
51 51 def _plain_text_only_changed(self, name, old, new):
52 52 warnings.warn("""DisplayFormatter.plain_text_only is deprecated.
53 53
54 54 Use DisplayFormatter.active_types = ['text/plain']
55 55 for the same effect.
56 56 """, DeprecationWarning)
57 57 if new:
58 58 self.active_types = ['text/plain']
59 59 else:
60 60 self.active_types = self.format_types
61 61
62 62 active_types = List(Unicode, config=True,
63 63 help="""List of currently active mime-types to display.
64 64 You can use this to set a white-list for formats to display.
65 65
66 66 Most users will not need to change this value.
67 67 """)
68 68 def _active_types_default(self):
69 69 return self.format_types
70 70
71 71 def _active_types_changed(self, name, old, new):
72 72 for key, formatter in self.formatters.items():
73 73 if key in new:
74 74 formatter.enabled = True
75 75 else:
76 76 formatter.enabled = False
77 77
78 78 # A dict of formatter whose keys are format types (MIME types) and whose
79 79 # values are subclasses of BaseFormatter.
80 80 formatters = Dict()
81 81 def _formatters_default(self):
82 82 """Activate the default formatters."""
83 83 formatter_classes = [
84 84 PlainTextFormatter,
85 85 HTMLFormatter,
86 86 SVGFormatter,
87 87 PNGFormatter,
88 88 JPEGFormatter,
89 89 LatexFormatter,
90 90 JSONFormatter,
91 91 JavascriptFormatter
92 92 ]
93 93 d = {}
94 94 for cls in formatter_classes:
95 95 f = cls(parent=self)
96 96 d[f.format_type] = f
97 97 return d
98 98
99 99 def format(self, obj, include=None, exclude=None):
100 100 """Return a format data dict for an object.
101 101
102 102 By default all format types will be computed.
103 103
104 104 The following MIME types are currently implemented:
105 105
106 106 * text/plain
107 107 * text/html
108 108 * text/latex
109 109 * application/json
110 110 * application/javascript
111 111 * image/png
112 112 * image/jpeg
113 113 * image/svg+xml
114 114
115 115 Parameters
116 116 ----------
117 117 obj : object
118 118 The Python object whose format data will be computed.
119 119 include : list or tuple, optional
120 120 A list of format type strings (MIME types) to include in the
121 121 format data dict. If this is set *only* the format types included
122 122 in this list will be computed.
123 123 exclude : list or tuple, optional
124 124 A list of format type string (MIME types) to exclude in the format
125 125 data dict. If this is set all format types will be computed,
126 126 except for those included in this argument.
127 127
128 128 Returns
129 129 -------
130 130 (format_dict, metadata_dict) : tuple of two dicts
131 131
132 132 format_dict is a dictionary of key/value pairs, one of each format that was
133 133 generated for the object. The keys are the format types, which
134 134 will usually be MIME type strings and the values and JSON'able
135 135 data structure containing the raw data for the representation in
136 136 that format.
137 137
138 138 metadata_dict is a dictionary of metadata about each mime-type output.
139 139 Its keys will be a strict subset of the keys in format_dict.
140 140 """
141 141 format_dict = {}
142 142 md_dict = {}
143 143
144 144 for format_type, formatter in self.formatters.items():
145 145 if include and format_type not in include:
146 146 continue
147 147 if exclude and format_type in exclude:
148 148 continue
149 149
150 150 md = None
151 151 try:
152 152 data = formatter(obj)
153 153 except:
154 154 # FIXME: log the exception
155 155 raise
156 156
157 157 # formatters can return raw data or (data, metadata)
158 158 if isinstance(data, tuple) and len(data) == 2:
159 159 data, md = data
160 160
161 161 if data is not None:
162 162 format_dict[format_type] = data
163 163 if md is not None:
164 164 md_dict[format_type] = md
165 165
166 166 return format_dict, md_dict
167 167
168 168 @property
169 169 def format_types(self):
170 170 """Return the format types (MIME types) of the active formatters."""
171 return self.formatters.keys()
171 return list(self.formatters.keys())
172 172
173 173
174 174 #-----------------------------------------------------------------------------
175 175 # Formatters for specific format types (text, html, svg, etc.)
176 176 #-----------------------------------------------------------------------------
177 177
178 178
179 179 class FormatterABC(with_metaclass(abc.ABCMeta, object)):
180 180 """ Abstract base class for Formatters.
181 181
182 182 A formatter is a callable class that is responsible for computing the
183 183 raw format data for a particular format type (MIME type). For example,
184 184 an HTML formatter would have a format type of `text/html` and would return
185 185 the HTML representation of the object when called.
186 186 """
187 187
188 188 # The format type of the data returned, usually a MIME type.
189 189 format_type = 'text/plain'
190 190
191 191 # Is the formatter enabled...
192 192 enabled = True
193 193
194 194 @abc.abstractmethod
195 195 def __call__(self, obj):
196 196 """Return a JSON'able representation of the object.
197 197
198 198 If the object cannot be formatted by this formatter, then return None
199 199 """
200 200 try:
201 201 return repr(obj)
202 202 except TypeError:
203 203 return None
204 204
205 205
206 206 class BaseFormatter(Configurable):
207 207 """A base formatter class that is configurable.
208 208
209 209 This formatter should usually be used as the base class of all formatters.
210 210 It is a traited :class:`Configurable` class and includes an extensible
211 211 API for users to determine how their objects are formatted. The following
212 212 logic is used to find a function to format an given object.
213 213
214 214 1. The object is introspected to see if it has a method with the name
215 215 :attr:`print_method`. If is does, that object is passed to that method
216 216 for formatting.
217 217 2. If no print method is found, three internal dictionaries are consulted
218 218 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
219 219 and :attr:`deferred_printers`.
220 220
221 221 Users should use these dictionaries to register functions that will be
222 222 used to compute the format data for their objects (if those objects don't
223 223 have the special print methods). The easiest way of using these
224 224 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
225 225 methods.
226 226
227 227 If no function/callable is found to compute the format data, ``None`` is
228 228 returned and this format type is not used.
229 229 """
230 230
231 231 format_type = Unicode('text/plain')
232 232
233 233 enabled = Bool(True, config=True)
234 234
235 235 print_method = ObjectName('__repr__')
236 236
237 237 # The singleton printers.
238 238 # Maps the IDs of the builtin singleton objects to the format functions.
239 239 singleton_printers = Dict(config=True)
240 240 def _singleton_printers_default(self):
241 241 return {}
242 242
243 243 # The type-specific printers.
244 244 # Map type objects to the format functions.
245 245 type_printers = Dict(config=True)
246 246 def _type_printers_default(self):
247 247 return {}
248 248
249 249 # The deferred-import type-specific printers.
250 250 # Map (modulename, classname) pairs to the format functions.
251 251 deferred_printers = Dict(config=True)
252 252 def _deferred_printers_default(self):
253 253 return {}
254 254
255 255 def __call__(self, obj):
256 256 """Compute the format for an object."""
257 257 if self.enabled:
258 258 obj_id = id(obj)
259 259 try:
260 260 obj_class = getattr(obj, '__class__', None) or type(obj)
261 261 # First try to find registered singleton printers for the type.
262 262 try:
263 263 printer = self.singleton_printers[obj_id]
264 264 except (TypeError, KeyError):
265 265 pass
266 266 else:
267 267 return printer(obj)
268 268 # Next look for type_printers.
269 269 for cls in pretty._get_mro(obj_class):
270 270 if cls in self.type_printers:
271 271 return self.type_printers[cls](obj)
272 272 else:
273 273 printer = self._in_deferred_types(cls)
274 274 if printer is not None:
275 275 return printer(obj)
276 276 # Finally look for special method names.
277 277 if hasattr(obj_class, self.print_method):
278 278 printer = getattr(obj_class, self.print_method)
279 279 return printer(obj)
280 280 return None
281 281 except Exception:
282 282 pass
283 283 else:
284 284 return None
285 285
286 286 def for_type(self, typ, func):
287 287 """Add a format function for a given type.
288 288
289 289 Parameters
290 290 -----------
291 291 typ : class
292 292 The class of the object that will be formatted using `func`.
293 293 func : callable
294 294 The callable that will be called to compute the format data. The
295 295 call signature of this function is simple, it must take the
296 296 object to be formatted and return the raw data for the given
297 297 format. Subclasses may use a different call signature for the
298 298 `func` argument.
299 299 """
300 300 oldfunc = self.type_printers.get(typ, None)
301 301 if func is not None:
302 302 # To support easy restoration of old printers, we need to ignore
303 303 # Nones.
304 304 self.type_printers[typ] = func
305 305 return oldfunc
306 306
307 307 def for_type_by_name(self, type_module, type_name, func):
308 308 """Add a format function for a type specified by the full dotted
309 309 module and name of the type, rather than the type of the object.
310 310
311 311 Parameters
312 312 ----------
313 313 type_module : str
314 314 The full dotted name of the module the type is defined in, like
315 315 ``numpy``.
316 316 type_name : str
317 317 The name of the type (the class name), like ``dtype``
318 318 func : callable
319 319 The callable that will be called to compute the format data. The
320 320 call signature of this function is simple, it must take the
321 321 object to be formatted and return the raw data for the given
322 322 format. Subclasses may use a different call signature for the
323 323 `func` argument.
324 324 """
325 325 key = (type_module, type_name)
326 326 oldfunc = self.deferred_printers.get(key, None)
327 327 if func is not None:
328 328 # To support easy restoration of old printers, we need to ignore
329 329 # Nones.
330 330 self.deferred_printers[key] = func
331 331 return oldfunc
332 332
333 333 def _in_deferred_types(self, cls):
334 334 """
335 335 Check if the given class is specified in the deferred type registry.
336 336
337 337 Returns the printer from the registry if it exists, and None if the
338 338 class is not in the registry. Successful matches will be moved to the
339 339 regular type registry for future use.
340 340 """
341 341 mod = getattr(cls, '__module__', None)
342 342 name = getattr(cls, '__name__', None)
343 343 key = (mod, name)
344 344 printer = None
345 345 if key in self.deferred_printers:
346 346 # Move the printer over to the regular registry.
347 347 printer = self.deferred_printers.pop(key)
348 348 self.type_printers[cls] = printer
349 349 return printer
350 350
351 351
352 352 class PlainTextFormatter(BaseFormatter):
353 353 """The default pretty-printer.
354 354
355 355 This uses :mod:`IPython.lib.pretty` to compute the format data of
356 356 the object. If the object cannot be pretty printed, :func:`repr` is used.
357 357 See the documentation of :mod:`IPython.lib.pretty` for details on
358 358 how to write pretty printers. Here is a simple example::
359 359
360 360 def dtype_pprinter(obj, p, cycle):
361 361 if cycle:
362 362 return p.text('dtype(...)')
363 363 if hasattr(obj, 'fields'):
364 364 if obj.fields is None:
365 365 p.text(repr(obj))
366 366 else:
367 367 p.begin_group(7, 'dtype([')
368 368 for i, field in enumerate(obj.descr):
369 369 if i > 0:
370 370 p.text(',')
371 371 p.breakable()
372 372 p.pretty(field)
373 373 p.end_group(7, '])')
374 374 """
375 375
376 376 # The format type of data returned.
377 377 format_type = Unicode('text/plain')
378 378
379 379 # This subclass ignores this attribute as it always need to return
380 380 # something.
381 381 enabled = Bool(True, config=False)
382 382
383 383 # Look for a _repr_pretty_ methods to use for pretty printing.
384 384 print_method = ObjectName('_repr_pretty_')
385 385
386 386 # Whether to pretty-print or not.
387 387 pprint = Bool(True, config=True)
388 388
389 389 # Whether to be verbose or not.
390 390 verbose = Bool(False, config=True)
391 391
392 392 # The maximum width.
393 393 max_width = Integer(79, config=True)
394 394
395 395 # The newline character.
396 396 newline = Unicode('\n', config=True)
397 397
398 398 # format-string for pprinting floats
399 399 float_format = Unicode('%r')
400 400 # setter for float precision, either int or direct format-string
401 401 float_precision = CUnicode('', config=True)
402 402
403 403 def _float_precision_changed(self, name, old, new):
404 404 """float_precision changed, set float_format accordingly.
405 405
406 406 float_precision can be set by int or str.
407 407 This will set float_format, after interpreting input.
408 408 If numpy has been imported, numpy print precision will also be set.
409 409
410 410 integer `n` sets format to '%.nf', otherwise, format set directly.
411 411
412 412 An empty string returns to defaults (repr for float, 8 for numpy).
413 413
414 414 This parameter can be set via the '%precision' magic.
415 415 """
416 416
417 417 if '%' in new:
418 418 # got explicit format string
419 419 fmt = new
420 420 try:
421 421 fmt%3.14159
422 422 except Exception:
423 423 raise ValueError("Precision must be int or format string, not %r"%new)
424 424 elif new:
425 425 # otherwise, should be an int
426 426 try:
427 427 i = int(new)
428 428 assert i >= 0
429 429 except ValueError:
430 430 raise ValueError("Precision must be int or format string, not %r"%new)
431 431 except AssertionError:
432 432 raise ValueError("int precision must be non-negative, not %r"%i)
433 433
434 434 fmt = '%%.%if'%i
435 435 if 'numpy' in sys.modules:
436 436 # set numpy precision if it has been imported
437 437 import numpy
438 438 numpy.set_printoptions(precision=i)
439 439 else:
440 440 # default back to repr
441 441 fmt = '%r'
442 442 if 'numpy' in sys.modules:
443 443 import numpy
444 444 # numpy default is 8
445 445 numpy.set_printoptions(precision=8)
446 446 self.float_format = fmt
447 447
448 448 # Use the default pretty printers from IPython.lib.pretty.
449 449 def _singleton_printers_default(self):
450 450 return pretty._singleton_pprinters.copy()
451 451
452 452 def _type_printers_default(self):
453 453 d = pretty._type_pprinters.copy()
454 454 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
455 455 return d
456 456
457 457 def _deferred_printers_default(self):
458 458 return pretty._deferred_type_pprinters.copy()
459 459
460 460 #### FormatterABC interface ####
461 461
462 462 def __call__(self, obj):
463 463 """Compute the pretty representation of the object."""
464 464 if not self.pprint:
465 465 try:
466 466 return repr(obj)
467 467 except TypeError:
468 468 return ''
469 469 else:
470 470 # This uses use StringIO, as cStringIO doesn't handle unicode.
471 471 stream = StringIO()
472 472 # self.newline.encode() is a quick fix for issue gh-597. We need to
473 473 # ensure that stream does not get a mix of unicode and bytestrings,
474 474 # or it will cause trouble.
475 475 printer = pretty.RepresentationPrinter(stream, self.verbose,
476 476 self.max_width, unicode_to_str(self.newline),
477 477 singleton_pprinters=self.singleton_printers,
478 478 type_pprinters=self.type_printers,
479 479 deferred_pprinters=self.deferred_printers)
480 480 printer.pretty(obj)
481 481 printer.flush()
482 482 return stream.getvalue()
483 483
484 484
485 485 class HTMLFormatter(BaseFormatter):
486 486 """An HTML formatter.
487 487
488 488 To define the callables that compute the HTML representation of your
489 489 objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
490 490 or :meth:`for_type_by_name` methods to register functions that handle
491 491 this.
492 492
493 493 The return value of this formatter should be a valid HTML snippet that
494 494 could be injected into an existing DOM. It should *not* include the
495 495 ```<html>`` or ```<body>`` tags.
496 496 """
497 497 format_type = Unicode('text/html')
498 498
499 499 print_method = ObjectName('_repr_html_')
500 500
501 501
502 502 class SVGFormatter(BaseFormatter):
503 503 """An SVG formatter.
504 504
505 505 To define the callables that compute the SVG representation of your
506 506 objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
507 507 or :meth:`for_type_by_name` methods to register functions that handle
508 508 this.
509 509
510 510 The return value of this formatter should be valid SVG enclosed in
511 511 ```<svg>``` tags, that could be injected into an existing DOM. It should
512 512 *not* include the ```<html>`` or ```<body>`` tags.
513 513 """
514 514 format_type = Unicode('image/svg+xml')
515 515
516 516 print_method = ObjectName('_repr_svg_')
517 517
518 518
519 519 class PNGFormatter(BaseFormatter):
520 520 """A PNG formatter.
521 521
522 522 To define the callables that compute the PNG representation of your
523 523 objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
524 524 or :meth:`for_type_by_name` methods to register functions that handle
525 525 this.
526 526
527 527 The return value of this formatter should be raw PNG data, *not*
528 528 base64 encoded.
529 529 """
530 530 format_type = Unicode('image/png')
531 531
532 532 print_method = ObjectName('_repr_png_')
533 533
534 534
535 535 class JPEGFormatter(BaseFormatter):
536 536 """A JPEG formatter.
537 537
538 538 To define the callables that compute the JPEG representation of your
539 539 objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
540 540 or :meth:`for_type_by_name` methods to register functions that handle
541 541 this.
542 542
543 543 The return value of this formatter should be raw JPEG data, *not*
544 544 base64 encoded.
545 545 """
546 546 format_type = Unicode('image/jpeg')
547 547
548 548 print_method = ObjectName('_repr_jpeg_')
549 549
550 550
551 551 class LatexFormatter(BaseFormatter):
552 552 """A LaTeX formatter.
553 553
554 554 To define the callables that compute the LaTeX representation of your
555 555 objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
556 556 or :meth:`for_type_by_name` methods to register functions that handle
557 557 this.
558 558
559 559 The return value of this formatter should be a valid LaTeX equation,
560 560 enclosed in either ```$```, ```$$``` or another LaTeX equation
561 561 environment.
562 562 """
563 563 format_type = Unicode('text/latex')
564 564
565 565 print_method = ObjectName('_repr_latex_')
566 566
567 567
568 568 class JSONFormatter(BaseFormatter):
569 569 """A JSON string formatter.
570 570
571 571 To define the callables that compute the JSON string representation of
572 572 your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
573 573 or :meth:`for_type_by_name` methods to register functions that handle
574 574 this.
575 575
576 576 The return value of this formatter should be a valid JSON string.
577 577 """
578 578 format_type = Unicode('application/json')
579 579
580 580 print_method = ObjectName('_repr_json_')
581 581
582 582
583 583 class JavascriptFormatter(BaseFormatter):
584 584 """A Javascript formatter.
585 585
586 586 To define the callables that compute the Javascript representation of
587 587 your objects, define a :meth:`_repr_javascript_` method or use the
588 588 :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
589 589 that handle this.
590 590
591 591 The return value of this formatter should be valid Javascript code and
592 592 should *not* be enclosed in ```<script>``` tags.
593 593 """
594 594 format_type = Unicode('application/javascript')
595 595
596 596 print_method = ObjectName('_repr_javascript_')
597 597
598 598 FormatterABC.register(BaseFormatter)
599 599 FormatterABC.register(PlainTextFormatter)
600 600 FormatterABC.register(HTMLFormatter)
601 601 FormatterABC.register(SVGFormatter)
602 602 FormatterABC.register(PNGFormatter)
603 603 FormatterABC.register(JPEGFormatter)
604 604 FormatterABC.register(LatexFormatter)
605 605 FormatterABC.register(JSONFormatter)
606 606 FormatterABC.register(JavascriptFormatter)
607 607
608 608
609 609 def format_display_data(obj, include=None, exclude=None):
610 610 """Return a format data dict for an object.
611 611
612 612 By default all format types will be computed.
613 613
614 614 The following MIME types are currently implemented:
615 615
616 616 * text/plain
617 617 * text/html
618 618 * text/latex
619 619 * application/json
620 620 * application/javascript
621 621 * image/png
622 622 * image/jpeg
623 623 * image/svg+xml
624 624
625 625 Parameters
626 626 ----------
627 627 obj : object
628 628 The Python object whose format data will be computed.
629 629
630 630 Returns
631 631 -------
632 632 format_dict : dict
633 633 A dictionary of key/value pairs, one or each format that was
634 634 generated for the object. The keys are the format types, which
635 635 will usually be MIME type strings and the values and JSON'able
636 636 data structure containing the raw data for the representation in
637 637 that format.
638 638 include : list or tuple, optional
639 639 A list of format type strings (MIME types) to include in the
640 640 format data dict. If this is set *only* the format types included
641 641 in this list will be computed.
642 642 exclude : list or tuple, optional
643 643 A list of format type string (MIME types) to exclue in the format
644 644 data dict. If this is set all format types will be computed,
645 645 except for those included in this argument.
646 646 """
647 647 from IPython.core.interactiveshell import InteractiveShell
648 648
649 649 InteractiveShell.instance().display_formatter.format(
650 650 obj,
651 651 include,
652 652 exclude
653 653 )
654 654
General Comments 0
You need to be logged in to leave comments. Login now