##// END OF EJS Templates
Completed work on pretty.py extension....
Brian Granger -
Show More
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
@@ -4,8 +4,13 b' To enable this extension in your configuration'
4 file, add the following to :file:`ipython_config.py`::
4 file, add the following to :file:`ipython_config.py`::
5
5
6 c.Global.extensions = ['IPython.extensions.pretty']
6 c.Global.extensions = ['IPython.extensions.pretty']
7 def dict_pprinter(obj, p, cycle):
8 return p.text("<dict>")
7 c.PrettyResultDisplay.verbose = True
9 c.PrettyResultDisplay.verbose = True
8 c.PrettyResultDisplay.defaults = [
10 c.PrettyResultDisplay.defaults_for_type = [
11 (dict, dict_pprinter)
12 ]
13 c.PrettyResultDisplay.defaults_for_type_by_name = [
9 ('numpy', 'dtype', 'IPython.extensions.pretty.dtype_pprinter')
14 ('numpy', 'dtype', 'IPython.extensions.pretty.dtype_pprinter')
10 ]
15 ]
11
16
@@ -42,28 +47,50 b' from IPython.utils.importstring import import_item'
42 # Code
47 # Code
43 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
44
49
50
45 _loaded = False
51 _loaded = False
46
52
47
53
48 class PrettyResultDisplay(Component):
54 class PrettyResultDisplay(Component):
55 """A component for pretty printing on steroids."""
49
56
50 verbose = Bool(False, config=True)
57 verbose = Bool(False, config=True)
58
59 # A list of (type, func_name), like
60 # [(dict, 'my_dict_printer')]
61 # The final argument can also be a callable
62 defaults_for_type = List(default_value=[], config=True)
63
51 # A list of (module_name, type_name, func_name), like
64 # A list of (module_name, type_name, func_name), like
52 # [('numpy', 'dtype', 'IPython.extensions.pretty.dtype_pprinter')]
65 # [('numpy', 'dtype', 'IPython.extensions.pretty.dtype_pprinter')]
53 defaults = List(default_value=[], config=True)
66 # The final argument can also be a callable
67 defaults_for_type_by_name = List(default_value=[], config=True)
54
68
55 def __init__(self, parent, name=None, config=None):
69 def __init__(self, parent, name=None, config=None):
56 super(PrettyResultDisplay, self).__init__(parent, name=name, config=config)
70 super(PrettyResultDisplay, self).__init__(parent, name=name, config=config)
57 self.setup_defaults()
71 self._setup_defaults()
58
72
59 def setup_defaults(self):
73 def _setup_defaults(self):
60 """Initialize the default pretty printers."""
74 """Initialize the default pretty printers."""
61 for type_module, type_name, func_name in self.defaults:
75 for typ, func_name in self.defaults_for_type:
62 func = import_item(func_name)
76 func = self._resolve_func_name(func_name)
77 self.for_type(typ, func)
78 for type_module, type_name, func_name in self.defaults_for_type_by_name:
79 func = self._resolve_func_name(func_name)
63 self.for_type_by_name(type_module, type_name, func)
80 self.for_type_by_name(type_module, type_name, func)
64
81
65 # Access other components like this rather than by regular attribute
82 def _resolve_func_name(self, func_name):
66 # access.
83 if callable(func_name):
84 return func_name
85 elif isinstance(func_name, basestring):
86 return import_item(func_name)
87 else:
88 raise TypeError('func_name must be a str or callable, got: %r' % func_name)
89
90 # Access other components like this rather than by a regular attribute.
91 # This won't lookup the InteractiveShell object until it is used and
92 # then it is cached. This is both efficient and couples this class
93 # more loosely to InteractiveShell.
67 @auto_attr
94 @auto_attr
68 def shell(self):
95 def shell(self):
69 return Component.get_instances(
96 return Component.get_instances(
@@ -93,8 +120,7 b' class PrettyResultDisplay(Component):'
93
120
94 def for_type_by_name(self, type_module, type_name, func):
121 def for_type_by_name(self, type_module, type_name, func):
95 """Add a pretty printer for a type by its name and module name."""
122 """Add a pretty printer for a type by its name and module name."""
96 print type_module, type_name, func
123 return pretty.for_type_by_name(type_module, type_name, func)
97 return pretty.for_type_by_name(type_name, type_name, func)
98
124
99
125
100 #-----------------------------------------------------------------------------
126 #-----------------------------------------------------------------------------
@@ -103,6 +129,7 b' class PrettyResultDisplay(Component):'
103
129
104
130
105 def load_ipython_extension(ip):
131 def load_ipython_extension(ip):
132 """Load the extension in IPython as a hook."""
106 global _loaded
133 global _loaded
107 if not _loaded:
134 if not _loaded:
108 prd = PrettyResultDisplay(ip, name='pretty_result_display')
135 prd = PrettyResultDisplay(ip, name='pretty_result_display')
@@ -110,6 +137,7 b' def load_ipython_extension(ip):'
110 _loaded = True
137 _loaded = True
111
138
112 def unload_ipython_extension(ip):
139 def unload_ipython_extension(ip):
140 """Unload the extension."""
113 # The hook system does not have a way to remove a hook so this is a pass
141 # The hook system does not have a way to remove a hook so this is a pass
114 pass
142 pass
115
143
@@ -124,16 +152,17 b' def dtype_pprinter(obj, p, cycle):'
124 """
152 """
125 if cycle:
153 if cycle:
126 return p.text('dtype(...)')
154 return p.text('dtype(...)')
127 if obj.fields is None:
155 if hasattr(obj, 'fields'):
128 p.text(repr(obj))
156 if obj.fields is None:
129 else:
157 p.text(repr(obj))
130 p.begin_group(7, 'dtype([')
158 else:
131 for i, field in enumerate(obj.descr):
159 p.begin_group(7, 'dtype([')
132 if i > 0:
160 for i, field in enumerate(obj.descr):
133 p.text(',')
161 if i > 0:
134 p.breakable()
162 p.text(',')
135 p.pretty(field)
163 p.breakable()
136 p.end_group(7, '])')
164 p.pretty(field)
165 p.end_group(7, '])')
137
166
138
167
139 #-----------------------------------------------------------------------------
168 #-----------------------------------------------------------------------------
@@ -23,11 +23,16 b' Subpackage descriptions'
23 this code will either i) be revived by someone willing to maintain it with
23 this code will either i) be revived by someone willing to maintain it with
24 tests and docs and re-included into IPython or 2) be removed from IPython
24 tests and docs and re-included into IPython or 2) be removed from IPython
25 proper, but put into a separate third-party Python package. No new code will
25 proper, but put into a separate third-party Python package. No new code will
26 be allowed here.
26 be allowed here. If your favorite extension has been moved here please
27 contact the IPython developer mailing list to help us determine the best
28 course of action.
27
29
28 * :mod:`IPython.extensions`. This package contains fully supported IPython
30 * :mod:`IPython.extensions`. This package contains fully supported IPython
29 extensions. These extensions adhere to the official IPython extension API
31 extensions. These extensions adhere to the official IPython extension API
30 and can be enabled by adding them to a field in the configuration file.
32 and can be enabled by adding them to a field in the configuration file.
33 If your extension is no longer in this location, please look in
34 :mod:`IPython.quarantine` and :mod:`IPython.deathrow` and contact the
35 IPython developer mailing list.
31
36
32 * :mod:`IPython.external`. This package contains third party packages and
37 * :mod:`IPython.external`. This package contains third party packages and
33 modules that IPython ships internally to reduce the number of dependencies.
38 modules that IPython ships internally to reduce the number of dependencies.
@@ -49,7 +54,9 b' Subpackage descriptions'
49 * :mod:`IPython.quarantine`. This is for code that doesn't meet IPython's
54 * :mod:`IPython.quarantine`. This is for code that doesn't meet IPython's
50 standards, but that we plan on keeping. To be moved out of this sub-package
55 standards, but that we plan on keeping. To be moved out of this sub-package
51 a module needs to have approval of the core IPython developers, tests and
56 a module needs to have approval of the core IPython developers, tests and
52 documentation.
57 documentation. If your favorite extension has been moved here please contact
58 the IPython developer mailing list to help us determine the best course of
59 action.
53
60
54 * :mod:`IPython.scripts`. This package contains a variety of top-level
61 * :mod:`IPython.scripts`. This package contains a variety of top-level
55 command line scripts. Eventually, these should be moved to the
62 command line scripts. Eventually, these should be moved to the
General Comments 0
You need to be logged in to leave comments. Login now