##// END OF EJS Templates
Added diagnostics printout at the end of the test suite....
Added diagnostics printout at the end of the test suite. This will make it easier for us to understand problem reports from users.

File last commit:

r2415:21955d0e
r2496:f440a2cd
Show More
pretty.py
167 lines | 5.8 KiB | text/x-python | PythonLexer
"""Use pretty.py for configurable pretty-printing.
To enable this extension in your configuration
file, add the following to :file:`ipython_config.py`::
c.Global.extensions = ['IPython.extensions.pretty']
def dict_pprinter(obj, p, cycle):
return p.text("<dict>")
c.PrettyResultDisplay.verbose = True
c.PrettyResultDisplay.defaults_for_type = [
(dict, dict_pprinter)
]
c.PrettyResultDisplay.defaults_for_type_by_name = [
('numpy', 'dtype', 'IPython.extensions.pretty.dtype_pprinter')
]
This extension can also be loaded by using the ``%load_ext`` magic::
%load_ext IPython.extensions.pretty
If this extension is enabled, you can always add additional pretty printers
by doing::
ip = get_ipython()
prd = ip.get_component('pretty_result_display')
import numpy
from IPython.extensions.pretty import dtype_pprinter
prd.for_type(numpy.dtype, dtype_pprinter)
# If you don't want to have numpy imported until it needs to be:
prd.for_type_by_name('numpy', 'dtype', dtype_pprinter)
"""
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
from IPython.core.error import TryNext
from IPython.external import pretty
from IPython.core.component import Component
from IPython.utils.traitlets import Bool, List
from IPython.utils.genutils import Term
from IPython.utils.autoattr import auto_attr
from IPython.utils.importstring import import_item
#-----------------------------------------------------------------------------
# Code
#-----------------------------------------------------------------------------
_loaded = False
class PrettyResultDisplay(Component):
"""A component for pretty printing on steroids."""
verbose = Bool(False, config=True)
# A list of (type, func_name), like
# [(dict, 'my_dict_printer')]
# The final argument can also be a callable
defaults_for_type = List(default_value=[], config=True)
# A list of (module_name, type_name, func_name), like
# [('numpy', 'dtype', 'IPython.extensions.pretty.dtype_pprinter')]
# The final argument can also be a callable
defaults_for_type_by_name = List(default_value=[], config=True)
def __init__(self, parent, name=None, config=None):
super(PrettyResultDisplay, self).__init__(parent, name=name, config=config)
self._setup_defaults()
def _setup_defaults(self):
"""Initialize the default pretty printers."""
for typ, func_name in self.defaults_for_type:
func = self._resolve_func_name(func_name)
self.for_type(typ, func)
for type_module, type_name, func_name in self.defaults_for_type_by_name:
func = self._resolve_func_name(func_name)
self.for_type_by_name(type_module, type_name, func)
def _resolve_func_name(self, func_name):
if callable(func_name):
return func_name
elif isinstance(func_name, basestring):
return import_item(func_name)
else:
raise TypeError('func_name must be a str or callable, got: %r' % func_name)
# Access other components like this rather than by a regular attribute.
# This won't lookup the InteractiveShell object until it is used and
# then it is cached. This is both efficient and couples this class
# more loosely to InteractiveShell.
@auto_attr
def shell(self):
return Component.get_instances(
root=self.root,
klass='IPython.core.iplib.InteractiveShell')[0]
def __call__(self, otherself, arg):
"""Uber-pretty-printing display hook.
Called for displaying the result to the user.
"""
if self.shell.pprint:
out = pretty.pretty(arg, verbose=self.verbose)
if '\n' in out:
# So that multi-line strings line up with the left column of
# the screen, instead of having the output prompt mess up
# their first line.
Term.cout.write('\n')
print >>Term.cout, out
else:
raise TryNext
def for_type(self, typ, func):
"""Add a pretty printer for a type."""
return pretty.for_type(typ, func)
def for_type_by_name(self, type_module, type_name, func):
"""Add a pretty printer for a type by its name and module name."""
return pretty.for_type_by_name(type_module, type_name, func)
#-----------------------------------------------------------------------------
# Initialization code for the extension
#-----------------------------------------------------------------------------
def load_ipython_extension(ip=None):
"""Load the extension in IPython as a hook."""
if ip is None: ip = get_ipython()
global _loaded
if not _loaded:
prd = PrettyResultDisplay(ip, name='pretty_result_display')
ip.set_hook('result_display', prd, priority=99)
_loaded = True
return prd
def unload_ipython_extension(ip):
"""Unload the extension."""
# The hook system does not have a way to remove a hook so this is a pass
pass
#-----------------------------------------------------------------------------
# Example pretty printers
#-----------------------------------------------------------------------------
def dtype_pprinter(obj, p, cycle):
""" A pretty-printer for numpy dtype objects.
"""
if cycle:
return p.text('dtype(...)')
if hasattr(obj, 'fields'):
if obj.fields is None:
p.text(repr(obj))
else:
p.begin_group(7, 'dtype([')
for i, field in enumerate(obj.descr):
if i > 0:
p.text(',')
p.breakable()
p.pretty(field)
p.end_group(7, '])')