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