##// END OF EJS Templates
Completed work on pretty.py extension....
Brian Granger -
Show More
1 NO CONTENT: new file 100644
@@ -1,193 +1,222 b''
1 1 """Use pretty.py for configurable pretty-printing.
2 2
3 3 To enable this extension in your configuration
4 4 file, add the following to :file:`ipython_config.py`::
5 5
6 6 c.Global.extensions = ['IPython.extensions.pretty']
7 def dict_pprinter(obj, p, cycle):
8 return p.text("<dict>")
7 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 14 ('numpy', 'dtype', 'IPython.extensions.pretty.dtype_pprinter')
10 15 ]
11 16
12 17 This extension can also be loaded by using the ``%load_ext`` magic::
13 18
14 19 %load_ext IPython.extensions.pretty
15 20
16 21 If this extension is enabled, you can always add additional pretty printers
17 22 by doing::
18 23
19 24 ip = get_ipython()
20 25 prd = ip.get_component('pretty_result_display')
21 26 import numpy
22 27 from IPython.extensions.pretty import dtype_pprinter
23 28 prd.for_type(numpy.dtype, dtype_pprinter)
24 29
25 30 # If you don't want to have numpy imported until it needs to be:
26 31 prd.for_type_by_name('numpy', 'dtype', dtype_pprinter)
27 32 """
28 33
29 34 #-----------------------------------------------------------------------------
30 35 # Imports
31 36 #-----------------------------------------------------------------------------
32 37
33 38 from IPython.core.error import TryNext
34 39 from IPython.external import pretty
35 40 from IPython.core.component import Component
36 41 from IPython.utils.traitlets import Bool, List
37 42 from IPython.utils.genutils import Term
38 43 from IPython.utils.autoattr import auto_attr
39 44 from IPython.utils.importstring import import_item
40 45
41 46 #-----------------------------------------------------------------------------
42 47 # Code
43 48 #-----------------------------------------------------------------------------
44 49
50
45 51 _loaded = False
46 52
47 53
48 54 class PrettyResultDisplay(Component):
55 """A component for pretty printing on steroids."""
49 56
50 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 64 # A list of (module_name, type_name, func_name), like
52 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 69 def __init__(self, parent, name=None, config=None):
56 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 74 """Initialize the default pretty printers."""
61 for type_module, type_name, func_name in self.defaults:
62 func = import_item(func_name)
75 for typ, func_name in self.defaults_for_type:
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 80 self.for_type_by_name(type_module, type_name, func)
64 81
65 # Access other components like this rather than by regular attribute
66 # access.
82 def _resolve_func_name(self, func_name):
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 94 @auto_attr
68 95 def shell(self):
69 96 return Component.get_instances(
70 97 root=self.root,
71 98 klass='IPython.core.iplib.InteractiveShell')[0]
72 99
73 100 def __call__(self, otherself, arg):
74 101 """Uber-pretty-printing display hook.
75 102
76 103 Called for displaying the result to the user.
77 104 """
78 105
79 106 if self.shell.pprint:
80 107 out = pretty.pretty(arg, verbose=self.verbose)
81 108 if '\n' in out:
82 109 # So that multi-line strings line up with the left column of
83 110 # the screen, instead of having the output prompt mess up
84 111 # their first line.
85 112 Term.cout.write('\n')
86 113 print >>Term.cout, out
87 114 else:
88 115 raise TryNext
89 116
90 117 def for_type(self, typ, func):
91 118 """Add a pretty printer for a type."""
92 119 return pretty.for_type(typ, func)
93 120
94 121 def for_type_by_name(self, type_module, type_name, func):
95 122 """Add a pretty printer for a type by its name and module name."""
96 print type_module, type_name, func
97 return pretty.for_type_by_name(type_name, type_name, func)
123 return pretty.for_type_by_name(type_module, type_name, func)
98 124
99 125
100 126 #-----------------------------------------------------------------------------
101 127 # Initialization code for the extension
102 128 #-----------------------------------------------------------------------------
103 129
104 130
105 131 def load_ipython_extension(ip):
132 """Load the extension in IPython as a hook."""
106 133 global _loaded
107 134 if not _loaded:
108 135 prd = PrettyResultDisplay(ip, name='pretty_result_display')
109 136 ip.set_hook('result_display', prd, priority=99)
110 137 _loaded = True
111 138
112 139 def unload_ipython_extension(ip):
140 """Unload the extension."""
113 141 # The hook system does not have a way to remove a hook so this is a pass
114 142 pass
115 143
116 144
117 145 #-----------------------------------------------------------------------------
118 146 # Example pretty printers
119 147 #-----------------------------------------------------------------------------
120 148
121 149
122 150 def dtype_pprinter(obj, p, cycle):
123 151 """ A pretty-printer for numpy dtype objects.
124 152 """
125 153 if cycle:
126 154 return p.text('dtype(...)')
127 if obj.fields is None:
128 p.text(repr(obj))
129 else:
130 p.begin_group(7, 'dtype([')
131 for i, field in enumerate(obj.descr):
132 if i > 0:
133 p.text(',')
134 p.breakable()
135 p.pretty(field)
136 p.end_group(7, '])')
155 if hasattr(obj, 'fields'):
156 if obj.fields is None:
157 p.text(repr(obj))
158 else:
159 p.begin_group(7, 'dtype([')
160 for i, field in enumerate(obj.descr):
161 if i > 0:
162 p.text(',')
163 p.breakable()
164 p.pretty(field)
165 p.end_group(7, '])')
137 166
138 167
139 168 #-----------------------------------------------------------------------------
140 169 # Tests
141 170 #-----------------------------------------------------------------------------
142 171
143 172
144 173 def test_pretty():
145 174 """
146 175 In [1]: from IPython.extensions import ipy_pretty
147 176
148 177 In [2]: ipy_pretty.activate()
149 178
150 179 In [3]: class A(object):
151 180 ...: def __repr__(self):
152 181 ...: return 'A()'
153 182 ...:
154 183 ...:
155 184
156 185 In [4]: a = A()
157 186
158 187 In [5]: a
159 188 Out[5]: A()
160 189
161 190 In [6]: def a_pretty_printer(obj, p, cycle):
162 191 ...: p.text('<A>')
163 192 ...:
164 193 ...:
165 194
166 195 In [7]: ipy_pretty.for_type(A, a_pretty_printer)
167 196
168 197 In [8]: a
169 198 Out[8]: <A>
170 199
171 200 In [9]: class B(object):
172 201 ...: def __repr__(self):
173 202 ...: return 'B()'
174 203 ...:
175 204 ...:
176 205
177 206 In [10]: B.__module__, B.__name__
178 207 Out[10]: ('__main__', 'B')
179 208
180 209 In [11]: def b_pretty_printer(obj, p, cycle):
181 210 ....: p.text('<B>')
182 211 ....:
183 212 ....:
184 213
185 214 In [12]: ipy_pretty.for_type_by_name('__main__', 'B', b_pretty_printer)
186 215
187 216 In [13]: b = B()
188 217
189 218 In [14]: b
190 219 Out[14]: <B>
191 220 """
192 221 assert False, "This should only be doctested, not run."
193 222
@@ -1,64 +1,71 b''
1 1 .. _module_reorg:
2 2
3 3 ===========================
4 4 IPython module organization
5 5 ===========================
6 6
7 7 As of the 0.11 release of IPython, the top-level packages and modules have
8 8 been completely reorganized. This section describes the purpose of the
9 9 top-level IPython subpackages.
10 10
11 11 Subpackage descriptions
12 12 =======================
13 13
14 14 * :mod:`IPython.config`. This package contains the configuration system of
15 15 IPython, as well as default configuration files for the different IPython
16 16 applications.
17 17
18 18 * :mod:`IPython.core`. This sub-package contains the core of the IPython
19 19 interpreter, but none of its extended capabilities.
20 20
21 21 * :mod:`IPython.deathrow`. This is for code that is outdated, untested,
22 22 rotting, or that belongs in a separate third party project. Eventually all
23 23 this code will either i) be revived by someone willing to maintain it with
24 24 tests and docs and re-included into IPython or 2) be removed from IPython
25 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 30 * :mod:`IPython.extensions`. This package contains fully supported IPython
29 31 extensions. These extensions adhere to the official IPython extension API
30 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 37 * :mod:`IPython.external`. This package contains third party packages and
33 38 modules that IPython ships internally to reduce the number of dependencies.
34 39 Usually, these are short, single file modules.
35 40
36 41 * :mod:`IPython.frontend`. This package contains the various IPython
37 42 frontends. Currently, the code in this subpackage is very experimental and
38 43 may be broken.
39 44
40 45 * :mod:`IPython.gui`. Another semi-experimental wxPython based IPython GUI.
41 46
42 47 * :mod:`IPython.kernel`. This contains IPython's parallel computing system.
43 48
44 49 * :mod:`IPython.lib`. IPython has many extended capabilities that are not part
45 50 of the IPython core. These things will go here and in. Modules in this
46 51 package are similar to extensions, but don't adhere to the official
47 52 IPython extension API.
48 53
49 54 * :mod:`IPython.quarantine`. This is for code that doesn't meet IPython's
50 55 standards, but that we plan on keeping. To be moved out of this sub-package
51 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 61 * :mod:`IPython.scripts`. This package contains a variety of top-level
55 62 command line scripts. Eventually, these should be moved to the
56 63 :file:`scripts` subdirectory of the appropriate IPython subpackage.
57 64
58 65 * :mod:`IPython.utils`. This sub-package will contain anything that might
59 66 eventually be found in the Python standard library, like things in
60 67 :mod:`genutils`. Each sub-module in this sub-package should contain
61 68 functions and classes that serve a single purpose and that don't
62 69 depend on things in the rest of IPython.
63 70
64 71
General Comments 0
You need to be logged in to leave comments. Login now