##// END OF EJS Templates
updating my code to incorporate upstream changes; resolved a merge conflict in IPython/lib/display.py
Greg Caporaso -
r8798:c1e52e56 merge
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -0,0 +1,14 b''
1 # encoding: utf-8
2 """Terminal-based IPython entry point.
3 """
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2012, IPython Development Team.
6 #
7 # Distributed under the terms of the Modified BSD License.
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
11
12 from IPython.frontend.terminal.ipapp import launch_new_instance
13
14 launch_new_instance()
@@ -0,0 +1,73 b''
1 import os.path
2
3 import nose.tools as nt
4
5 import IPython.testing.tools as tt
6 from IPython.utils.syspathcontext import prepended_to_syspath
7 from IPython.utils.tempdir import TemporaryDirectory
8
9 ext1_content = """
10 def load_ipython_extension(ip):
11 print("Running ext1 load")
12
13 def unload_ipython_extension(ip):
14 print("Running ext1 unload")
15 """
16
17 ext2_content = """
18 def load_ipython_extension(ip):
19 print("Running ext2 load")
20 """
21
22 def test_extension_loading():
23 em = get_ipython().extension_manager
24 with TemporaryDirectory() as td:
25 ext1 = os.path.join(td, 'ext1.py')
26 with open(ext1, 'w') as f:
27 f.write(ext1_content)
28
29 ext2 = os.path.join(td, 'ext2.py')
30 with open(ext2, 'w') as f:
31 f.write(ext2_content)
32
33 with prepended_to_syspath(td):
34 assert 'ext1' not in em.loaded
35 assert 'ext2' not in em.loaded
36
37 # Load extension
38 with tt.AssertPrints("Running ext1 load"):
39 assert em.load_extension('ext1') is None
40 assert 'ext1' in em.loaded
41
42 # Should refuse to load it again
43 with tt.AssertNotPrints("Running ext1 load"):
44 assert em.load_extension('ext1') == 'already loaded'
45
46 # Reload
47 with tt.AssertPrints("Running ext1 unload"):
48 with tt.AssertPrints("Running ext1 load", suppress=False):
49 em.reload_extension('ext1')
50
51 # Unload
52 with tt.AssertPrints("Running ext1 unload"):
53 assert em.unload_extension('ext1') is None
54
55 # Can't unload again
56 with tt.AssertNotPrints("Running ext1 unload"):
57 assert em.unload_extension('ext1') == 'not loaded'
58 assert em.unload_extension('ext2') == 'not loaded'
59
60 # Load extension 2
61 with tt.AssertPrints("Running ext2 load"):
62 assert em.load_extension('ext2') is None
63
64 # Can't unload this
65 assert em.unload_extension('ext2') == 'no unload function'
66
67 # But can reload it
68 with tt.AssertPrints("Running ext2 load"):
69 em.reload_extension('ext2')
70
71 def test_non_extension():
72 em = get_ipython().extension_manager
73 nt.assert_equal(em.load_extension('sys'), "no load function")
@@ -1,529 +1,557 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Pdb debugger class.
3 Pdb debugger class.
4
4
5 Modified from the standard pdb.Pdb class to avoid including readline, so that
5 Modified from the standard pdb.Pdb class to avoid including readline, so that
6 the command line completion of other programs which include this isn't
6 the command line completion of other programs which include this isn't
7 damaged.
7 damaged.
8
8
9 In the future, this class will be expanded with improvements over the standard
9 In the future, this class will be expanded with improvements over the standard
10 pdb.
10 pdb.
11
11
12 The code in this file is mainly lifted out of cmd.py in Python 2.2, with minor
12 The code in this file is mainly lifted out of cmd.py in Python 2.2, with minor
13 changes. Licensing should therefore be under the standard Python terms. For
13 changes. Licensing should therefore be under the standard Python terms. For
14 details on the PSF (Python Software Foundation) standard license, see:
14 details on the PSF (Python Software Foundation) standard license, see:
15
15
16 http://www.python.org/2.2.3/license.html"""
16 http://www.python.org/2.2.3/license.html"""
17
17
18 #*****************************************************************************
18 #*****************************************************************************
19 #
19 #
20 # This file is licensed under the PSF license.
20 # This file is licensed under the PSF license.
21 #
21 #
22 # Copyright (C) 2001 Python Software Foundation, www.python.org
22 # Copyright (C) 2001 Python Software Foundation, www.python.org
23 # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu>
23 # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu>
24 #
24 #
25 #
25 #
26 #*****************************************************************************
26 #*****************************************************************************
27 from __future__ import print_function
27 from __future__ import print_function
28
28
29 import bdb
29 import bdb
30 import linecache
30 import linecache
31 import sys
31 import sys
32
32
33 from IPython.utils import PyColorize, ulinecache
33 from IPython.utils import PyColorize, ulinecache
34 from IPython.core import ipapi
34 from IPython.core import ipapi
35 from IPython.utils import coloransi, io, openpy, py3compat
35 from IPython.utils import coloransi, io, openpy, py3compat
36 from IPython.core.excolors import exception_colors
36 from IPython.core.excolors import exception_colors
37
37
38 # See if we can use pydb.
38 # See if we can use pydb.
39 has_pydb = False
39 has_pydb = False
40 prompt = 'ipdb> '
40 prompt = 'ipdb> '
41 #We have to check this directly from sys.argv, config struct not yet available
41 #We have to check this directly from sys.argv, config struct not yet available
42 if '--pydb' in sys.argv:
42 if '--pydb' in sys.argv:
43 try:
43 try:
44 import pydb
44 import pydb
45 if hasattr(pydb.pydb, "runl") and pydb.version>'1.17':
45 if hasattr(pydb.pydb, "runl") and pydb.version>'1.17':
46 # Version 1.17 is broken, and that's what ships with Ubuntu Edgy, so we
46 # Version 1.17 is broken, and that's what ships with Ubuntu Edgy, so we
47 # better protect against it.
47 # better protect against it.
48 has_pydb = True
48 has_pydb = True
49 except ImportError:
49 except ImportError:
50 print("Pydb (http://bashdb.sourceforge.net/pydb/) does not seem to be available")
50 print("Pydb (http://bashdb.sourceforge.net/pydb/) does not seem to be available")
51
51
52 if has_pydb:
52 if has_pydb:
53 from pydb import Pdb as OldPdb
53 from pydb import Pdb as OldPdb
54 #print "Using pydb for %run -d and post-mortem" #dbg
54 #print "Using pydb for %run -d and post-mortem" #dbg
55 prompt = 'ipydb> '
55 prompt = 'ipydb> '
56 else:
56 else:
57 from pdb import Pdb as OldPdb
57 from pdb import Pdb as OldPdb
58
58
59 # Allow the set_trace code to operate outside of an ipython instance, even if
59 # Allow the set_trace code to operate outside of an ipython instance, even if
60 # it does so with some limitations. The rest of this support is implemented in
60 # it does so with some limitations. The rest of this support is implemented in
61 # the Tracer constructor.
61 # the Tracer constructor.
62 def BdbQuit_excepthook(et,ev,tb):
62 def BdbQuit_excepthook(et,ev,tb):
63 if et==bdb.BdbQuit:
63 if et==bdb.BdbQuit:
64 print('Exiting Debugger.')
64 print('Exiting Debugger.')
65 else:
65 else:
66 BdbQuit_excepthook.excepthook_ori(et,ev,tb)
66 BdbQuit_excepthook.excepthook_ori(et,ev,tb)
67
67
68 def BdbQuit_IPython_excepthook(self,et,ev,tb,tb_offset=None):
68 def BdbQuit_IPython_excepthook(self,et,ev,tb,tb_offset=None):
69 print('Exiting Debugger.')
69 print('Exiting Debugger.')
70
70
71
71
72 class Tracer(object):
72 class Tracer(object):
73 """Class for local debugging, similar to pdb.set_trace.
73 """Class for local debugging, similar to pdb.set_trace.
74
74
75 Instances of this class, when called, behave like pdb.set_trace, but
75 Instances of this class, when called, behave like pdb.set_trace, but
76 providing IPython's enhanced capabilities.
76 providing IPython's enhanced capabilities.
77
77
78 This is implemented as a class which must be initialized in your own code
78 This is implemented as a class which must be initialized in your own code
79 and not as a standalone function because we need to detect at runtime
79 and not as a standalone function because we need to detect at runtime
80 whether IPython is already active or not. That detection is done in the
80 whether IPython is already active or not. That detection is done in the
81 constructor, ensuring that this code plays nicely with a running IPython,
81 constructor, ensuring that this code plays nicely with a running IPython,
82 while functioning acceptably (though with limitations) if outside of it.
82 while functioning acceptably (though with limitations) if outside of it.
83 """
83 """
84
84
85 def __init__(self,colors=None):
85 def __init__(self,colors=None):
86 """Create a local debugger instance.
86 """Create a local debugger instance.
87
87
88 :Parameters:
88 :Parameters:
89
89
90 - `colors` (None): a string containing the name of the color scheme to
90 - `colors` (None): a string containing the name of the color scheme to
91 use, it must be one of IPython's valid color schemes. If not given, the
91 use, it must be one of IPython's valid color schemes. If not given, the
92 function will default to the current IPython scheme when running inside
92 function will default to the current IPython scheme when running inside
93 IPython, and to 'NoColor' otherwise.
93 IPython, and to 'NoColor' otherwise.
94
94
95 Usage example:
95 Usage example:
96
96
97 from IPython.core.debugger import Tracer; debug_here = Tracer()
97 from IPython.core.debugger import Tracer; debug_here = Tracer()
98
98
99 ... later in your code
99 ... later in your code
100 debug_here() # -> will open up the debugger at that point.
100 debug_here() # -> will open up the debugger at that point.
101
101
102 Once the debugger activates, you can use all of its regular commands to
102 Once the debugger activates, you can use all of its regular commands to
103 step through code, set breakpoints, etc. See the pdb documentation
103 step through code, set breakpoints, etc. See the pdb documentation
104 from the Python standard library for usage details.
104 from the Python standard library for usage details.
105 """
105 """
106
106
107 try:
107 try:
108 ip = get_ipython()
108 ip = get_ipython()
109 except NameError:
109 except NameError:
110 # Outside of ipython, we set our own exception hook manually
110 # Outside of ipython, we set our own exception hook manually
111 BdbQuit_excepthook.excepthook_ori = sys.excepthook
111 BdbQuit_excepthook.excepthook_ori = sys.excepthook
112 sys.excepthook = BdbQuit_excepthook
112 sys.excepthook = BdbQuit_excepthook
113 def_colors = 'NoColor'
113 def_colors = 'NoColor'
114 try:
114 try:
115 # Limited tab completion support
115 # Limited tab completion support
116 import readline
116 import readline
117 readline.parse_and_bind('tab: complete')
117 readline.parse_and_bind('tab: complete')
118 except ImportError:
118 except ImportError:
119 pass
119 pass
120 else:
120 else:
121 # In ipython, we use its custom exception handler mechanism
121 # In ipython, we use its custom exception handler mechanism
122 def_colors = ip.colors
122 def_colors = ip.colors
123 ip.set_custom_exc((bdb.BdbQuit,), BdbQuit_IPython_excepthook)
123 ip.set_custom_exc((bdb.BdbQuit,), BdbQuit_IPython_excepthook)
124
124
125 if colors is None:
125 if colors is None:
126 colors = def_colors
126 colors = def_colors
127
127
128 # The stdlib debugger internally uses a modified repr from the `repr`
128 # The stdlib debugger internally uses a modified repr from the `repr`
129 # module, that limits the length of printed strings to a hardcoded
129 # module, that limits the length of printed strings to a hardcoded
130 # limit of 30 characters. That much trimming is too aggressive, let's
130 # limit of 30 characters. That much trimming is too aggressive, let's
131 # at least raise that limit to 80 chars, which should be enough for
131 # at least raise that limit to 80 chars, which should be enough for
132 # most interactive uses.
132 # most interactive uses.
133 try:
133 try:
134 from repr import aRepr
134 from repr import aRepr
135 aRepr.maxstring = 80
135 aRepr.maxstring = 80
136 except:
136 except:
137 # This is only a user-facing convenience, so any error we encounter
137 # This is only a user-facing convenience, so any error we encounter
138 # here can be warned about but can be otherwise ignored. These
138 # here can be warned about but can be otherwise ignored. These
139 # printouts will tell us about problems if this API changes
139 # printouts will tell us about problems if this API changes
140 import traceback
140 import traceback
141 traceback.print_exc()
141 traceback.print_exc()
142
142
143 self.debugger = Pdb(colors)
143 self.debugger = Pdb(colors)
144
144
145 def __call__(self):
145 def __call__(self):
146 """Starts an interactive debugger at the point where called.
146 """Starts an interactive debugger at the point where called.
147
147
148 This is similar to the pdb.set_trace() function from the std lib, but
148 This is similar to the pdb.set_trace() function from the std lib, but
149 using IPython's enhanced debugger."""
149 using IPython's enhanced debugger."""
150
150
151 self.debugger.set_trace(sys._getframe().f_back)
151 self.debugger.set_trace(sys._getframe().f_back)
152
152
153
153
154 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
154 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
155 """Make new_fn have old_fn's doc string. This is particularly useful
155 """Make new_fn have old_fn's doc string. This is particularly useful
156 for the do_... commands that hook into the help system.
156 for the do_... commands that hook into the help system.
157 Adapted from from a comp.lang.python posting
157 Adapted from from a comp.lang.python posting
158 by Duncan Booth."""
158 by Duncan Booth."""
159 def wrapper(*args, **kw):
159 def wrapper(*args, **kw):
160 return new_fn(*args, **kw)
160 return new_fn(*args, **kw)
161 if old_fn.__doc__:
161 if old_fn.__doc__:
162 wrapper.__doc__ = old_fn.__doc__ + additional_text
162 wrapper.__doc__ = old_fn.__doc__ + additional_text
163 return wrapper
163 return wrapper
164
164
165
165
166 def _file_lines(fname):
166 def _file_lines(fname):
167 """Return the contents of a named file as a list of lines.
167 """Return the contents of a named file as a list of lines.
168
168
169 This function never raises an IOError exception: if the file can't be
169 This function never raises an IOError exception: if the file can't be
170 read, it simply returns an empty list."""
170 read, it simply returns an empty list."""
171
171
172 try:
172 try:
173 outfile = open(fname)
173 outfile = open(fname)
174 except IOError:
174 except IOError:
175 return []
175 return []
176 else:
176 else:
177 out = outfile.readlines()
177 out = outfile.readlines()
178 outfile.close()
178 outfile.close()
179 return out
179 return out
180
180
181
181
182 class Pdb(OldPdb):
182 class Pdb(OldPdb):
183 """Modified Pdb class, does not load readline."""
183 """Modified Pdb class, does not load readline."""
184
184
185 def __init__(self,color_scheme='NoColor',completekey=None,
185 def __init__(self,color_scheme='NoColor',completekey=None,
186 stdin=None, stdout=None):
186 stdin=None, stdout=None):
187
187
188 # Parent constructor:
188 # Parent constructor:
189 if has_pydb and completekey is None:
189 if has_pydb and completekey is None:
190 OldPdb.__init__(self,stdin=stdin,stdout=io.stdout)
190 OldPdb.__init__(self,stdin=stdin,stdout=io.stdout)
191 else:
191 else:
192 OldPdb.__init__(self,completekey,stdin,stdout)
192 OldPdb.__init__(self,completekey,stdin,stdout)
193
193
194 self.prompt = prompt # The default prompt is '(Pdb)'
194 self.prompt = prompt # The default prompt is '(Pdb)'
195
195
196 # IPython changes...
196 # IPython changes...
197 self.is_pydb = has_pydb
197 self.is_pydb = has_pydb
198
198
199 self.shell = ipapi.get()
199 self.shell = ipapi.get()
200
200
201 if self.is_pydb:
201 if self.is_pydb:
202
202
203 # interactiveshell.py's ipalias seems to want pdb's checkline
203 # interactiveshell.py's ipalias seems to want pdb's checkline
204 # which located in pydb.fn
204 # which located in pydb.fn
205 import pydb.fns
205 import pydb.fns
206 self.checkline = lambda filename, lineno: \
206 self.checkline = lambda filename, lineno: \
207 pydb.fns.checkline(self, filename, lineno)
207 pydb.fns.checkline(self, filename, lineno)
208
208
209 self.curframe = None
209 self.curframe = None
210 self.do_restart = self.new_do_restart
210 self.do_restart = self.new_do_restart
211
211
212 self.old_all_completions = self.shell.Completer.all_completions
212 self.old_all_completions = self.shell.Completer.all_completions
213 self.shell.Completer.all_completions=self.all_completions
213 self.shell.Completer.all_completions=self.all_completions
214
214
215 self.do_list = decorate_fn_with_doc(self.list_command_pydb,
215 self.do_list = decorate_fn_with_doc(self.list_command_pydb,
216 OldPdb.do_list)
216 OldPdb.do_list)
217 self.do_l = self.do_list
217 self.do_l = self.do_list
218 self.do_frame = decorate_fn_with_doc(self.new_do_frame,
218 self.do_frame = decorate_fn_with_doc(self.new_do_frame,
219 OldPdb.do_frame)
219 OldPdb.do_frame)
220
220
221 self.aliases = {}
221 self.aliases = {}
222
222
223 # Create color table: we copy the default one from the traceback
223 # Create color table: we copy the default one from the traceback
224 # module and add a few attributes needed for debugging
224 # module and add a few attributes needed for debugging
225 self.color_scheme_table = exception_colors()
225 self.color_scheme_table = exception_colors()
226
226
227 # shorthands
227 # shorthands
228 C = coloransi.TermColors
228 C = coloransi.TermColors
229 cst = self.color_scheme_table
229 cst = self.color_scheme_table
230
230
231 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
231 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
232 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
232 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
233
233
234 cst['Linux'].colors.breakpoint_enabled = C.LightRed
234 cst['Linux'].colors.breakpoint_enabled = C.LightRed
235 cst['Linux'].colors.breakpoint_disabled = C.Red
235 cst['Linux'].colors.breakpoint_disabled = C.Red
236
236
237 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
237 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
238 cst['LightBG'].colors.breakpoint_disabled = C.Red
238 cst['LightBG'].colors.breakpoint_disabled = C.Red
239
239
240 self.set_colors(color_scheme)
240 self.set_colors(color_scheme)
241
241
242 # Add a python parser so we can syntax highlight source while
242 # Add a python parser so we can syntax highlight source while
243 # debugging.
243 # debugging.
244 self.parser = PyColorize.Parser()
244 self.parser = PyColorize.Parser()
245
245
246 def set_colors(self, scheme):
246 def set_colors(self, scheme):
247 """Shorthand access to the color table scheme selector method."""
247 """Shorthand access to the color table scheme selector method."""
248 self.color_scheme_table.set_active_scheme(scheme)
248 self.color_scheme_table.set_active_scheme(scheme)
249
249
250 def interaction(self, frame, traceback):
250 def interaction(self, frame, traceback):
251 self.shell.set_completer_frame(frame)
251 self.shell.set_completer_frame(frame)
252 OldPdb.interaction(self, frame, traceback)
252 OldPdb.interaction(self, frame, traceback)
253
253
254 def new_do_up(self, arg):
254 def new_do_up(self, arg):
255 OldPdb.do_up(self, arg)
255 OldPdb.do_up(self, arg)
256 self.shell.set_completer_frame(self.curframe)
256 self.shell.set_completer_frame(self.curframe)
257 do_u = do_up = decorate_fn_with_doc(new_do_up, OldPdb.do_up)
257 do_u = do_up = decorate_fn_with_doc(new_do_up, OldPdb.do_up)
258
258
259 def new_do_down(self, arg):
259 def new_do_down(self, arg):
260 OldPdb.do_down(self, arg)
260 OldPdb.do_down(self, arg)
261 self.shell.set_completer_frame(self.curframe)
261 self.shell.set_completer_frame(self.curframe)
262
262
263 do_d = do_down = decorate_fn_with_doc(new_do_down, OldPdb.do_down)
263 do_d = do_down = decorate_fn_with_doc(new_do_down, OldPdb.do_down)
264
264
265 def new_do_frame(self, arg):
265 def new_do_frame(self, arg):
266 OldPdb.do_frame(self, arg)
266 OldPdb.do_frame(self, arg)
267 self.shell.set_completer_frame(self.curframe)
267 self.shell.set_completer_frame(self.curframe)
268
268
269 def new_do_quit(self, arg):
269 def new_do_quit(self, arg):
270
270
271 if hasattr(self, 'old_all_completions'):
271 if hasattr(self, 'old_all_completions'):
272 self.shell.Completer.all_completions=self.old_all_completions
272 self.shell.Completer.all_completions=self.old_all_completions
273
273
274
274
275 return OldPdb.do_quit(self, arg)
275 return OldPdb.do_quit(self, arg)
276
276
277 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
277 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
278
278
279 def new_do_restart(self, arg):
279 def new_do_restart(self, arg):
280 """Restart command. In the context of ipython this is exactly the same
280 """Restart command. In the context of ipython this is exactly the same
281 thing as 'quit'."""
281 thing as 'quit'."""
282 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
282 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
283 return self.do_quit(arg)
283 return self.do_quit(arg)
284
284
285 def postloop(self):
285 def postloop(self):
286 self.shell.set_completer_frame(None)
286 self.shell.set_completer_frame(None)
287
287
288 def print_stack_trace(self):
288 def print_stack_trace(self):
289 try:
289 try:
290 for frame_lineno in self.stack:
290 for frame_lineno in self.stack:
291 self.print_stack_entry(frame_lineno, context = 5)
291 self.print_stack_entry(frame_lineno, context = 5)
292 except KeyboardInterrupt:
292 except KeyboardInterrupt:
293 pass
293 pass
294
294
295 def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ',
295 def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ',
296 context = 3):
296 context = 3):
297 #frame, lineno = frame_lineno
297 #frame, lineno = frame_lineno
298 print(self.format_stack_entry(frame_lineno, '', context), file=io.stdout)
298 print(self.format_stack_entry(frame_lineno, '', context), file=io.stdout)
299
299
300 # vds: >>
300 # vds: >>
301 frame, lineno = frame_lineno
301 frame, lineno = frame_lineno
302 filename = frame.f_code.co_filename
302 filename = frame.f_code.co_filename
303 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
303 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
304 # vds: <<
304 # vds: <<
305
305
306 def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3):
306 def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3):
307 import repr
307 import repr
308
308
309 ret = []
309 ret = []
310
310
311 Colors = self.color_scheme_table.active_colors
311 Colors = self.color_scheme_table.active_colors
312 ColorsNormal = Colors.Normal
312 ColorsNormal = Colors.Normal
313 tpl_link = u'%s%%s%s' % (Colors.filenameEm, ColorsNormal)
313 tpl_link = u'%s%%s%s' % (Colors.filenameEm, ColorsNormal)
314 tpl_call = u'%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
314 tpl_call = u'%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
315 tpl_line = u'%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
315 tpl_line = u'%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
316 tpl_line_em = u'%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
316 tpl_line_em = u'%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
317 ColorsNormal)
317 ColorsNormal)
318
318
319 frame, lineno = frame_lineno
319 frame, lineno = frame_lineno
320
320
321 return_value = ''
321 return_value = ''
322 if '__return__' in frame.f_locals:
322 if '__return__' in frame.f_locals:
323 rv = frame.f_locals['__return__']
323 rv = frame.f_locals['__return__']
324 #return_value += '->'
324 #return_value += '->'
325 return_value += repr.repr(rv) + '\n'
325 return_value += repr.repr(rv) + '\n'
326 ret.append(return_value)
326 ret.append(return_value)
327
327
328 #s = filename + '(' + `lineno` + ')'
328 #s = filename + '(' + `lineno` + ')'
329 filename = self.canonic(frame.f_code.co_filename)
329 filename = self.canonic(frame.f_code.co_filename)
330 link = tpl_link % py3compat.cast_unicode(filename)
330 link = tpl_link % py3compat.cast_unicode(filename)
331
331
332 if frame.f_code.co_name:
332 if frame.f_code.co_name:
333 func = frame.f_code.co_name
333 func = frame.f_code.co_name
334 else:
334 else:
335 func = "<lambda>"
335 func = "<lambda>"
336
336
337 call = ''
337 call = ''
338 if func != '?':
338 if func != '?':
339 if '__args__' in frame.f_locals:
339 if '__args__' in frame.f_locals:
340 args = repr.repr(frame.f_locals['__args__'])
340 args = repr.repr(frame.f_locals['__args__'])
341 else:
341 else:
342 args = '()'
342 args = '()'
343 call = tpl_call % (func, args)
343 call = tpl_call % (func, args)
344
344
345 # The level info should be generated in the same format pdb uses, to
345 # The level info should be generated in the same format pdb uses, to
346 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
346 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
347 if frame is self.curframe:
347 if frame is self.curframe:
348 ret.append('> ')
348 ret.append('> ')
349 else:
349 else:
350 ret.append(' ')
350 ret.append(' ')
351 ret.append(u'%s(%s)%s\n' % (link,lineno,call))
351 ret.append(u'%s(%s)%s\n' % (link,lineno,call))
352
352
353 start = lineno - 1 - context//2
353 start = lineno - 1 - context//2
354 lines = ulinecache.getlines(filename)
354 lines = ulinecache.getlines(filename)
355 start = max(start, 0)
355 start = max(start, 0)
356 start = min(start, len(lines) - context)
356 start = min(start, len(lines) - context)
357 lines = lines[start : start + context]
357 lines = lines[start : start + context]
358
358
359 for i,line in enumerate(lines):
359 for i,line in enumerate(lines):
360 show_arrow = (start + 1 + i == lineno)
360 show_arrow = (start + 1 + i == lineno)
361 linetpl = (frame is self.curframe or show_arrow) \
361 linetpl = (frame is self.curframe or show_arrow) \
362 and tpl_line_em \
362 and tpl_line_em \
363 or tpl_line
363 or tpl_line
364 ret.append(self.__format_line(linetpl, filename,
364 ret.append(self.__format_line(linetpl, filename,
365 start + 1 + i, line,
365 start + 1 + i, line,
366 arrow = show_arrow) )
366 arrow = show_arrow) )
367 return ''.join(ret)
367 return ''.join(ret)
368
368
369 def __format_line(self, tpl_line, filename, lineno, line, arrow = False):
369 def __format_line(self, tpl_line, filename, lineno, line, arrow = False):
370 bp_mark = ""
370 bp_mark = ""
371 bp_mark_color = ""
371 bp_mark_color = ""
372
372
373 scheme = self.color_scheme_table.active_scheme_name
373 scheme = self.color_scheme_table.active_scheme_name
374 new_line, err = self.parser.format2(line, 'str', scheme)
374 new_line, err = self.parser.format2(line, 'str', scheme)
375 if not err: line = new_line
375 if not err: line = new_line
376
376
377 bp = None
377 bp = None
378 if lineno in self.get_file_breaks(filename):
378 if lineno in self.get_file_breaks(filename):
379 bps = self.get_breaks(filename, lineno)
379 bps = self.get_breaks(filename, lineno)
380 bp = bps[-1]
380 bp = bps[-1]
381
381
382 if bp:
382 if bp:
383 Colors = self.color_scheme_table.active_colors
383 Colors = self.color_scheme_table.active_colors
384 bp_mark = str(bp.number)
384 bp_mark = str(bp.number)
385 bp_mark_color = Colors.breakpoint_enabled
385 bp_mark_color = Colors.breakpoint_enabled
386 if not bp.enabled:
386 if not bp.enabled:
387 bp_mark_color = Colors.breakpoint_disabled
387 bp_mark_color = Colors.breakpoint_disabled
388
388
389 numbers_width = 7
389 numbers_width = 7
390 if arrow:
390 if arrow:
391 # This is the line with the error
391 # This is the line with the error
392 pad = numbers_width - len(str(lineno)) - len(bp_mark)
392 pad = numbers_width - len(str(lineno)) - len(bp_mark)
393 if pad >= 3:
393 if pad >= 3:
394 marker = '-'*(pad-3) + '-> '
394 marker = '-'*(pad-3) + '-> '
395 elif pad == 2:
395 elif pad == 2:
396 marker = '> '
396 marker = '> '
397 elif pad == 1:
397 elif pad == 1:
398 marker = '>'
398 marker = '>'
399 else:
399 else:
400 marker = ''
400 marker = ''
401 num = '%s%s' % (marker, str(lineno))
401 num = '%s%s' % (marker, str(lineno))
402 line = tpl_line % (bp_mark_color + bp_mark, num, line)
402 line = tpl_line % (bp_mark_color + bp_mark, num, line)
403 else:
403 else:
404 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
404 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
405 line = tpl_line % (bp_mark_color + bp_mark, num, line)
405 line = tpl_line % (bp_mark_color + bp_mark, num, line)
406
406
407 return line
407 return line
408
408
409 def list_command_pydb(self, arg):
409 def list_command_pydb(self, arg):
410 """List command to use if we have a newer pydb installed"""
410 """List command to use if we have a newer pydb installed"""
411 filename, first, last = OldPdb.parse_list_cmd(self, arg)
411 filename, first, last = OldPdb.parse_list_cmd(self, arg)
412 if filename is not None:
412 if filename is not None:
413 self.print_list_lines(filename, first, last)
413 self.print_list_lines(filename, first, last)
414
414
415 def print_list_lines(self, filename, first, last):
415 def print_list_lines(self, filename, first, last):
416 """The printing (as opposed to the parsing part of a 'list'
416 """The printing (as opposed to the parsing part of a 'list'
417 command."""
417 command."""
418 try:
418 try:
419 Colors = self.color_scheme_table.active_colors
419 Colors = self.color_scheme_table.active_colors
420 ColorsNormal = Colors.Normal
420 ColorsNormal = Colors.Normal
421 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
421 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
422 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
422 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
423 src = []
423 src = []
424 if filename == "<string>" and hasattr(self, "_exec_filename"):
424 if filename == "<string>" and hasattr(self, "_exec_filename"):
425 filename = self._exec_filename
425 filename = self._exec_filename
426
426
427 for lineno in range(first, last+1):
427 for lineno in range(first, last+1):
428 line = ulinecache.getline(filename, lineno)
428 line = ulinecache.getline(filename, lineno)
429 if not line:
429 if not line:
430 break
430 break
431
431
432 if lineno == self.curframe.f_lineno:
432 if lineno == self.curframe.f_lineno:
433 line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True)
433 line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True)
434 else:
434 else:
435 line = self.__format_line(tpl_line, filename, lineno, line, arrow = False)
435 line = self.__format_line(tpl_line, filename, lineno, line, arrow = False)
436
436
437 src.append(line)
437 src.append(line)
438 self.lineno = lineno
438 self.lineno = lineno
439
439
440 print(''.join(src), file=io.stdout)
440 print(''.join(src), file=io.stdout)
441
441
442 except KeyboardInterrupt:
442 except KeyboardInterrupt:
443 pass
443 pass
444
444
445 def do_list(self, arg):
445 def do_list(self, arg):
446 self.lastcmd = 'list'
446 self.lastcmd = 'list'
447 last = None
447 last = None
448 if arg:
448 if arg:
449 try:
449 try:
450 x = eval(arg, {}, {})
450 x = eval(arg, {}, {})
451 if type(x) == type(()):
451 if type(x) == type(()):
452 first, last = x
452 first, last = x
453 first = int(first)
453 first = int(first)
454 last = int(last)
454 last = int(last)
455 if last < first:
455 if last < first:
456 # Assume it's a count
456 # Assume it's a count
457 last = first + last
457 last = first + last
458 else:
458 else:
459 first = max(1, int(x) - 5)
459 first = max(1, int(x) - 5)
460 except:
460 except:
461 print('*** Error in argument:', repr(arg))
461 print('*** Error in argument:', repr(arg))
462 return
462 return
463 elif self.lineno is None:
463 elif self.lineno is None:
464 first = max(1, self.curframe.f_lineno - 5)
464 first = max(1, self.curframe.f_lineno - 5)
465 else:
465 else:
466 first = self.lineno + 1
466 first = self.lineno + 1
467 if last is None:
467 if last is None:
468 last = first + 10
468 last = first + 10
469 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
469 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
470
470
471 # vds: >>
471 # vds: >>
472 lineno = first
472 lineno = first
473 filename = self.curframe.f_code.co_filename
473 filename = self.curframe.f_code.co_filename
474 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
474 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
475 # vds: <<
475 # vds: <<
476
476
477 do_l = do_list
477 do_l = do_list
478
478
479 def do_pdef(self, arg):
479 def do_pdef(self, arg):
480 """The debugger interface to magic_pdef"""
480 """Print the call signature for any callable object.
481
482 The debugger interface to %pdef"""
481 namespaces = [('Locals', self.curframe.f_locals),
483 namespaces = [('Locals', self.curframe.f_locals),
482 ('Globals', self.curframe.f_globals)]
484 ('Globals', self.curframe.f_globals)]
483 self.shell.find_line_magic('pdef')(arg, namespaces=namespaces)
485 self.shell.find_line_magic('pdef')(arg, namespaces=namespaces)
484
486
485 def do_pdoc(self, arg):
487 def do_pdoc(self, arg):
486 """The debugger interface to magic_pdoc"""
488 """Print the docstring for an object.
489
490 The debugger interface to %pdoc."""
487 namespaces = [('Locals', self.curframe.f_locals),
491 namespaces = [('Locals', self.curframe.f_locals),
488 ('Globals', self.curframe.f_globals)]
492 ('Globals', self.curframe.f_globals)]
489 self.shell.find_line_magic('pdoc')(arg, namespaces=namespaces)
493 self.shell.find_line_magic('pdoc')(arg, namespaces=namespaces)
490
494
495 def do_pfile(self, arg):
496 """Print (or run through pager) the file where an object is defined.
497
498 The debugger interface to %pfile.
499 """
500 namespaces = [('Locals', self.curframe.f_locals),
501 ('Globals', self.curframe.f_globals)]
502 self.shell.find_line_magic('pfile')(arg, namespaces=namespaces)
503
491 def do_pinfo(self, arg):
504 def do_pinfo(self, arg):
492 """The debugger equivalant of ?obj"""
505 """Provide detailed information about an object.
506
507 The debugger interface to %pinfo, i.e., obj?."""
508 namespaces = [('Locals', self.curframe.f_locals),
509 ('Globals', self.curframe.f_globals)]
510 self.shell.find_line_magic('pinfo')(arg, namespaces=namespaces)
511
512 def do_pinfo2(self, arg):
513 """Provide extra detailed information about an object.
514
515 The debugger interface to %pinfo2, i.e., obj??."""
516 namespaces = [('Locals', self.curframe.f_locals),
517 ('Globals', self.curframe.f_globals)]
518 self.shell.find_line_magic('pinfo2')(arg, namespaces=namespaces)
519
520 def do_psource(self, arg):
521 """Print (or run through pager) the source code for an object."""
493 namespaces = [('Locals', self.curframe.f_locals),
522 namespaces = [('Locals', self.curframe.f_locals),
494 ('Globals', self.curframe.f_globals)]
523 ('Globals', self.curframe.f_globals)]
495 self.shell.find_line_magic('pinfo')("pinfo %s" % arg,
524 self.shell.find_line_magic('psource')(arg, namespaces=namespaces)
496 namespaces=namespaces)
497
525
498 def checkline(self, filename, lineno):
526 def checkline(self, filename, lineno):
499 """Check whether specified line seems to be executable.
527 """Check whether specified line seems to be executable.
500
528
501 Return `lineno` if it is, 0 if not (e.g. a docstring, comment, blank
529 Return `lineno` if it is, 0 if not (e.g. a docstring, comment, blank
502 line or EOF). Warning: testing is not comprehensive.
530 line or EOF). Warning: testing is not comprehensive.
503 """
531 """
504 #######################################################################
532 #######################################################################
505 # XXX Hack! Use python-2.5 compatible code for this call, because with
533 # XXX Hack! Use python-2.5 compatible code for this call, because with
506 # all of our changes, we've drifted from the pdb api in 2.6. For now,
534 # all of our changes, we've drifted from the pdb api in 2.6. For now,
507 # changing:
535 # changing:
508 #
536 #
509 #line = linecache.getline(filename, lineno, self.curframe.f_globals)
537 #line = linecache.getline(filename, lineno, self.curframe.f_globals)
510 # to:
538 # to:
511 #
539 #
512 line = linecache.getline(filename, lineno)
540 line = linecache.getline(filename, lineno)
513 #
541 #
514 # does the trick. But in reality, we need to fix this by reconciling
542 # does the trick. But in reality, we need to fix this by reconciling
515 # our updates with the new Pdb APIs in Python 2.6.
543 # our updates with the new Pdb APIs in Python 2.6.
516 #
544 #
517 # End hack. The rest of this method is copied verbatim from 2.6 pdb.py
545 # End hack. The rest of this method is copied verbatim from 2.6 pdb.py
518 #######################################################################
546 #######################################################################
519
547
520 if not line:
548 if not line:
521 print('End of file', file=self.stdout)
549 print('End of file', file=self.stdout)
522 return 0
550 return 0
523 line = line.strip()
551 line = line.strip()
524 # Don't allow setting breakpoint at a blank line
552 # Don't allow setting breakpoint at a blank line
525 if (not line or (line[0] == '#') or
553 if (not line or (line[0] == '#') or
526 (line[:3] == '"""') or line[:3] == "'''"):
554 (line[:3] == '"""') or line[:3] == "'''"):
527 print('*** Blank or comment', file=self.stdout)
555 print('*** Blank or comment', file=self.stdout)
528 return 0
556 return 0
529 return lineno
557 return lineno
@@ -1,157 +1,184 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """A class for managing IPython extensions.
2 """A class for managing IPython extensions.
3
3
4 Authors:
4 Authors:
5
5
6 * Brian Granger
6 * Brian Granger
7 """
7 """
8
8
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2010-2011 The IPython Development Team
10 # Copyright (C) 2010-2011 The IPython Development Team
11 #
11 #
12 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Imports
17 # Imports
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 import os
20 import os
21 from shutil import copyfile
21 from shutil import copyfile
22 import sys
22 import sys
23 from urllib import urlretrieve
23 from urllib import urlretrieve
24 from urlparse import urlparse
24 from urlparse import urlparse
25
25
26 from IPython.core.error import UsageError
26 from IPython.config.configurable import Configurable
27 from IPython.config.configurable import Configurable
27 from IPython.utils.traitlets import Instance
28 from IPython.utils.traitlets import Instance
29 from IPython.utils.py3compat import PY3
30 if PY3:
31 from imp import reload
28
32
29 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
30 # Main class
34 # Main class
31 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
32
36
33 class ExtensionManager(Configurable):
37 class ExtensionManager(Configurable):
34 """A class to manage IPython extensions.
38 """A class to manage IPython extensions.
35
39
36 An IPython extension is an importable Python module that has
40 An IPython extension is an importable Python module that has
37 a function with the signature::
41 a function with the signature::
38
42
39 def load_ipython_extension(ipython):
43 def load_ipython_extension(ipython):
40 # Do things with ipython
44 # Do things with ipython
41
45
42 This function is called after your extension is imported and the
46 This function is called after your extension is imported and the
43 currently active :class:`InteractiveShell` instance is passed as
47 currently active :class:`InteractiveShell` instance is passed as
44 the only argument. You can do anything you want with IPython at
48 the only argument. You can do anything you want with IPython at
45 that point, including defining new magic and aliases, adding new
49 that point, including defining new magic and aliases, adding new
46 components, etc.
50 components, etc.
47
51
48 The :func:`load_ipython_extension` will be called again is you
52 You can also optionaly define an :func:`unload_ipython_extension(ipython)`
49 load or reload the extension again. It is up to the extension
53 function, which will be called if the user unloads or reloads the extension.
50 author to add code to manage that.
54 The extension manager will only call :func:`load_ipython_extension` again
55 if the extension is reloaded.
51
56
52 You can put your extension modules anywhere you want, as long as
57 You can put your extension modules anywhere you want, as long as
53 they can be imported by Python's standard import mechanism. However,
58 they can be imported by Python's standard import mechanism. However,
54 to make it easy to write extensions, you can also put your extensions
59 to make it easy to write extensions, you can also put your extensions
55 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
60 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
56 is added to ``sys.path`` automatically.
61 is added to ``sys.path`` automatically.
57 """
62 """
58
63
59 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
64 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
60
65
61 def __init__(self, shell=None, config=None):
66 def __init__(self, shell=None, config=None):
62 super(ExtensionManager, self).__init__(shell=shell, config=config)
67 super(ExtensionManager, self).__init__(shell=shell, config=config)
63 self.shell.on_trait_change(
68 self.shell.on_trait_change(
64 self._on_ipython_dir_changed, 'ipython_dir'
69 self._on_ipython_dir_changed, 'ipython_dir'
65 )
70 )
71 self.loaded = set()
66
72
67 def __del__(self):
73 def __del__(self):
68 self.shell.on_trait_change(
74 self.shell.on_trait_change(
69 self._on_ipython_dir_changed, 'ipython_dir', remove=True
75 self._on_ipython_dir_changed, 'ipython_dir', remove=True
70 )
76 )
71
77
72 @property
78 @property
73 def ipython_extension_dir(self):
79 def ipython_extension_dir(self):
74 return os.path.join(self.shell.ipython_dir, u'extensions')
80 return os.path.join(self.shell.ipython_dir, u'extensions')
75
81
76 def _on_ipython_dir_changed(self):
82 def _on_ipython_dir_changed(self):
77 if not os.path.isdir(self.ipython_extension_dir):
83 if not os.path.isdir(self.ipython_extension_dir):
78 os.makedirs(self.ipython_extension_dir, mode = 0o777)
84 os.makedirs(self.ipython_extension_dir, mode = 0o777)
79
85
80 def load_extension(self, module_str):
86 def load_extension(self, module_str):
81 """Load an IPython extension by its module name.
87 """Load an IPython extension by its module name.
82
88
83 If :func:`load_ipython_extension` returns anything, this function
89 Returns the string "already loaded" if the extension is already loaded,
84 will return that object.
90 "no load function" if the module doesn't have a load_ipython_extension
91 function, or None if it succeeded.
85 """
92 """
93 if module_str in self.loaded:
94 return "already loaded"
95
86 from IPython.utils.syspathcontext import prepended_to_syspath
96 from IPython.utils.syspathcontext import prepended_to_syspath
87
97
88 if module_str not in sys.modules:
98 if module_str not in sys.modules:
89 with prepended_to_syspath(self.ipython_extension_dir):
99 with prepended_to_syspath(self.ipython_extension_dir):
90 __import__(module_str)
100 __import__(module_str)
91 mod = sys.modules[module_str]
101 mod = sys.modules[module_str]
92 return self._call_load_ipython_extension(mod)
102 if self._call_load_ipython_extension(mod):
103 self.loaded.add(module_str)
104 else:
105 return "no load function"
93
106
94 def unload_extension(self, module_str):
107 def unload_extension(self, module_str):
95 """Unload an IPython extension by its module name.
108 """Unload an IPython extension by its module name.
96
109
97 This function looks up the extension's name in ``sys.modules`` and
110 This function looks up the extension's name in ``sys.modules`` and
98 simply calls ``mod.unload_ipython_extension(self)``.
111 simply calls ``mod.unload_ipython_extension(self)``.
112
113 Returns the string "no unload function" if the extension doesn't define
114 a function to unload itself, "not loaded" if the extension isn't loaded,
115 otherwise None.
99 """
116 """
117 if module_str not in self.loaded:
118 return "not loaded"
119
100 if module_str in sys.modules:
120 if module_str in sys.modules:
101 mod = sys.modules[module_str]
121 mod = sys.modules[module_str]
102 self._call_unload_ipython_extension(mod)
122 if self._call_unload_ipython_extension(mod):
123 self.loaded.discard(module_str)
124 else:
125 return "no unload function"
103
126
104 def reload_extension(self, module_str):
127 def reload_extension(self, module_str):
105 """Reload an IPython extension by calling reload.
128 """Reload an IPython extension by calling reload.
106
129
107 If the module has not been loaded before,
130 If the module has not been loaded before,
108 :meth:`InteractiveShell.load_extension` is called. Otherwise
131 :meth:`InteractiveShell.load_extension` is called. Otherwise
109 :func:`reload` is called and then the :func:`load_ipython_extension`
132 :func:`reload` is called and then the :func:`load_ipython_extension`
110 function of the module, if it exists is called.
133 function of the module, if it exists is called.
111 """
134 """
112 from IPython.utils.syspathcontext import prepended_to_syspath
135 from IPython.utils.syspathcontext import prepended_to_syspath
113
136
114 with prepended_to_syspath(self.ipython_extension_dir):
137 if (module_str in self.loaded) and (module_str in sys.modules):
115 if module_str in sys.modules:
138 self.unload_extension(module_str)
116 mod = sys.modules[module_str]
139 mod = sys.modules[module_str]
140 with prepended_to_syspath(self.ipython_extension_dir):
117 reload(mod)
141 reload(mod)
118 self._call_load_ipython_extension(mod)
142 if self._call_load_ipython_extension(mod):
119 else:
143 self.loaded.add(module_str)
120 self.load_extension(module_str)
144 else:
145 self.load_extension(module_str)
121
146
122 def _call_load_ipython_extension(self, mod):
147 def _call_load_ipython_extension(self, mod):
123 if hasattr(mod, 'load_ipython_extension'):
148 if hasattr(mod, 'load_ipython_extension'):
124 return mod.load_ipython_extension(self.shell)
149 mod.load_ipython_extension(self.shell)
150 return True
125
151
126 def _call_unload_ipython_extension(self, mod):
152 def _call_unload_ipython_extension(self, mod):
127 if hasattr(mod, 'unload_ipython_extension'):
153 if hasattr(mod, 'unload_ipython_extension'):
128 return mod.unload_ipython_extension(self.shell)
154 mod.unload_ipython_extension(self.shell)
155 return True
129
156
130 def install_extension(self, url, filename=None):
157 def install_extension(self, url, filename=None):
131 """Download and install an IPython extension.
158 """Download and install an IPython extension.
132
159
133 If filename is given, the file will be so named (inside the extension
160 If filename is given, the file will be so named (inside the extension
134 directory). Otherwise, the name from the URL will be used. The file must
161 directory). Otherwise, the name from the URL will be used. The file must
135 have a .py or .zip extension; otherwise, a ValueError will be raised.
162 have a .py or .zip extension; otherwise, a ValueError will be raised.
136
163
137 Returns the full path to the installed file.
164 Returns the full path to the installed file.
138 """
165 """
139 # Ensure the extension directory exists
166 # Ensure the extension directory exists
140 if not os.path.isdir(self.ipython_extension_dir):
167 if not os.path.isdir(self.ipython_extension_dir):
141 os.makedirs(self.ipython_extension_dir, mode = 0o777)
168 os.makedirs(self.ipython_extension_dir, mode = 0o777)
142
169
143 if os.path.isfile(url):
170 if os.path.isfile(url):
144 src_filename = os.path.basename(url)
171 src_filename = os.path.basename(url)
145 copy = copyfile
172 copy = copyfile
146 else:
173 else:
147 src_filename = urlparse(url).path.split('/')[-1]
174 src_filename = urlparse(url).path.split('/')[-1]
148 copy = urlretrieve
175 copy = urlretrieve
149
176
150 if filename is None:
177 if filename is None:
151 filename = src_filename
178 filename = src_filename
152 if os.path.splitext(filename)[1] not in ('.py', '.zip'):
179 if os.path.splitext(filename)[1] not in ('.py', '.zip'):
153 raise ValueError("The file must have a .py or .zip extension", filename)
180 raise ValueError("The file must have a .py or .zip extension", filename)
154
181
155 filename = os.path.join(self.ipython_extension_dir, filename)
182 filename = os.path.join(self.ipython_extension_dir, filename)
156 copy(url, filename)
183 copy(url, filename)
157 return filename
184 return filename
@@ -1,3006 +1,3006 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Main IPython class."""
2 """Main IPython class."""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 # Copyright (C) 2008-2011 The IPython Development Team
7 # Copyright (C) 2008-2011 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 from __future__ import with_statement
17 from __future__ import with_statement
18 from __future__ import absolute_import
18 from __future__ import absolute_import
19 from __future__ import print_function
19 from __future__ import print_function
20
20
21 import __builtin__ as builtin_mod
21 import __builtin__ as builtin_mod
22 import __future__
22 import __future__
23 import abc
23 import abc
24 import ast
24 import ast
25 import atexit
25 import atexit
26 import os
26 import os
27 import re
27 import re
28 import runpy
28 import runpy
29 import sys
29 import sys
30 import tempfile
30 import tempfile
31 import types
31 import types
32 import urllib
32 import urllib
33 from io import open as io_open
33 from io import open as io_open
34
34
35 from IPython.config.configurable import SingletonConfigurable
35 from IPython.config.configurable import SingletonConfigurable
36 from IPython.core import debugger, oinspect
36 from IPython.core import debugger, oinspect
37 from IPython.core import magic
37 from IPython.core import magic
38 from IPython.core import page
38 from IPython.core import page
39 from IPython.core import prefilter
39 from IPython.core import prefilter
40 from IPython.core import shadowns
40 from IPython.core import shadowns
41 from IPython.core import ultratb
41 from IPython.core import ultratb
42 from IPython.core.alias import AliasManager, AliasError
42 from IPython.core.alias import AliasManager, AliasError
43 from IPython.core.autocall import ExitAutocall
43 from IPython.core.autocall import ExitAutocall
44 from IPython.core.builtin_trap import BuiltinTrap
44 from IPython.core.builtin_trap import BuiltinTrap
45 from IPython.core.compilerop import CachingCompiler
45 from IPython.core.compilerop import CachingCompiler
46 from IPython.core.display_trap import DisplayTrap
46 from IPython.core.display_trap import DisplayTrap
47 from IPython.core.displayhook import DisplayHook
47 from IPython.core.displayhook import DisplayHook
48 from IPython.core.displaypub import DisplayPublisher
48 from IPython.core.displaypub import DisplayPublisher
49 from IPython.core.error import UsageError
49 from IPython.core.error import UsageError
50 from IPython.core.extensions import ExtensionManager
50 from IPython.core.extensions import ExtensionManager
51 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
51 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
52 from IPython.core.formatters import DisplayFormatter
52 from IPython.core.formatters import DisplayFormatter
53 from IPython.core.history import HistoryManager
53 from IPython.core.history import HistoryManager
54 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC, ESC_MAGIC2
54 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC, ESC_MAGIC2
55 from IPython.core.logger import Logger
55 from IPython.core.logger import Logger
56 from IPython.core.macro import Macro
56 from IPython.core.macro import Macro
57 from IPython.core.payload import PayloadManager
57 from IPython.core.payload import PayloadManager
58 from IPython.core.prefilter import PrefilterManager
58 from IPython.core.prefilter import PrefilterManager
59 from IPython.core.profiledir import ProfileDir
59 from IPython.core.profiledir import ProfileDir
60 from IPython.core.pylabtools import pylab_activate
60 from IPython.core.pylabtools import pylab_activate
61 from IPython.core.prompts import PromptManager
61 from IPython.core.prompts import PromptManager
62 from IPython.lib.latextools import LaTeXTool
62 from IPython.lib.latextools import LaTeXTool
63 from IPython.utils import PyColorize
63 from IPython.utils import PyColorize
64 from IPython.utils import io
64 from IPython.utils import io
65 from IPython.utils import py3compat
65 from IPython.utils import py3compat
66 from IPython.utils import openpy
66 from IPython.utils import openpy
67 from IPython.utils.doctestreload import doctest_reload
67 from IPython.utils.doctestreload import doctest_reload
68 from IPython.utils.io import ask_yes_no
68 from IPython.utils.io import ask_yes_no
69 from IPython.utils.ipstruct import Struct
69 from IPython.utils.ipstruct import Struct
70 from IPython.utils.path import get_home_dir, get_ipython_dir, get_py_filename, unquote_filename
70 from IPython.utils.path import get_home_dir, get_ipython_dir, get_py_filename, unquote_filename
71 from IPython.utils.pickleshare import PickleShareDB
71 from IPython.utils.pickleshare import PickleShareDB
72 from IPython.utils.process import system, getoutput
72 from IPython.utils.process import system, getoutput
73 from IPython.utils.strdispatch import StrDispatch
73 from IPython.utils.strdispatch import StrDispatch
74 from IPython.utils.syspathcontext import prepended_to_syspath
74 from IPython.utils.syspathcontext import prepended_to_syspath
75 from IPython.utils.text import (format_screen, LSString, SList,
75 from IPython.utils.text import (format_screen, LSString, SList,
76 DollarFormatter)
76 DollarFormatter)
77 from IPython.utils.traitlets import (Integer, CBool, CaselessStrEnum, Enum,
77 from IPython.utils.traitlets import (Integer, CBool, CaselessStrEnum, Enum,
78 List, Unicode, Instance, Type)
78 List, Unicode, Instance, Type)
79 from IPython.utils.warn import warn, error
79 from IPython.utils.warn import warn, error
80 import IPython.core.hooks
80 import IPython.core.hooks
81
81
82 #-----------------------------------------------------------------------------
82 #-----------------------------------------------------------------------------
83 # Globals
83 # Globals
84 #-----------------------------------------------------------------------------
84 #-----------------------------------------------------------------------------
85
85
86 # compiled regexps for autoindent management
86 # compiled regexps for autoindent management
87 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
87 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
88
88
89 #-----------------------------------------------------------------------------
89 #-----------------------------------------------------------------------------
90 # Utilities
90 # Utilities
91 #-----------------------------------------------------------------------------
91 #-----------------------------------------------------------------------------
92
92
93 def softspace(file, newvalue):
93 def softspace(file, newvalue):
94 """Copied from code.py, to remove the dependency"""
94 """Copied from code.py, to remove the dependency"""
95
95
96 oldvalue = 0
96 oldvalue = 0
97 try:
97 try:
98 oldvalue = file.softspace
98 oldvalue = file.softspace
99 except AttributeError:
99 except AttributeError:
100 pass
100 pass
101 try:
101 try:
102 file.softspace = newvalue
102 file.softspace = newvalue
103 except (AttributeError, TypeError):
103 except (AttributeError, TypeError):
104 # "attribute-less object" or "read-only attributes"
104 # "attribute-less object" or "read-only attributes"
105 pass
105 pass
106 return oldvalue
106 return oldvalue
107
107
108
108
109 def no_op(*a, **kw): pass
109 def no_op(*a, **kw): pass
110
110
111 class NoOpContext(object):
111 class NoOpContext(object):
112 def __enter__(self): pass
112 def __enter__(self): pass
113 def __exit__(self, type, value, traceback): pass
113 def __exit__(self, type, value, traceback): pass
114 no_op_context = NoOpContext()
114 no_op_context = NoOpContext()
115
115
116 class SpaceInInput(Exception): pass
116 class SpaceInInput(Exception): pass
117
117
118 class Bunch: pass
118 class Bunch: pass
119
119
120
120
121 def get_default_colors():
121 def get_default_colors():
122 if sys.platform=='darwin':
122 if sys.platform=='darwin':
123 return "LightBG"
123 return "LightBG"
124 elif os.name=='nt':
124 elif os.name=='nt':
125 return 'Linux'
125 return 'Linux'
126 else:
126 else:
127 return 'Linux'
127 return 'Linux'
128
128
129
129
130 class SeparateUnicode(Unicode):
130 class SeparateUnicode(Unicode):
131 """A Unicode subclass to validate separate_in, separate_out, etc.
131 """A Unicode subclass to validate separate_in, separate_out, etc.
132
132
133 This is a Unicode based trait that converts '0'->'' and '\\n'->'\n'.
133 This is a Unicode based trait that converts '0'->'' and '\\n'->'\n'.
134 """
134 """
135
135
136 def validate(self, obj, value):
136 def validate(self, obj, value):
137 if value == '0': value = ''
137 if value == '0': value = ''
138 value = value.replace('\\n','\n')
138 value = value.replace('\\n','\n')
139 return super(SeparateUnicode, self).validate(obj, value)
139 return super(SeparateUnicode, self).validate(obj, value)
140
140
141
141
142 class ReadlineNoRecord(object):
142 class ReadlineNoRecord(object):
143 """Context manager to execute some code, then reload readline history
143 """Context manager to execute some code, then reload readline history
144 so that interactive input to the code doesn't appear when pressing up."""
144 so that interactive input to the code doesn't appear when pressing up."""
145 def __init__(self, shell):
145 def __init__(self, shell):
146 self.shell = shell
146 self.shell = shell
147 self._nested_level = 0
147 self._nested_level = 0
148
148
149 def __enter__(self):
149 def __enter__(self):
150 if self._nested_level == 0:
150 if self._nested_level == 0:
151 try:
151 try:
152 self.orig_length = self.current_length()
152 self.orig_length = self.current_length()
153 self.readline_tail = self.get_readline_tail()
153 self.readline_tail = self.get_readline_tail()
154 except (AttributeError, IndexError): # Can fail with pyreadline
154 except (AttributeError, IndexError): # Can fail with pyreadline
155 self.orig_length, self.readline_tail = 999999, []
155 self.orig_length, self.readline_tail = 999999, []
156 self._nested_level += 1
156 self._nested_level += 1
157
157
158 def __exit__(self, type, value, traceback):
158 def __exit__(self, type, value, traceback):
159 self._nested_level -= 1
159 self._nested_level -= 1
160 if self._nested_level == 0:
160 if self._nested_level == 0:
161 # Try clipping the end if it's got longer
161 # Try clipping the end if it's got longer
162 try:
162 try:
163 e = self.current_length() - self.orig_length
163 e = self.current_length() - self.orig_length
164 if e > 0:
164 if e > 0:
165 for _ in range(e):
165 for _ in range(e):
166 self.shell.readline.remove_history_item(self.orig_length)
166 self.shell.readline.remove_history_item(self.orig_length)
167
167
168 # If it still doesn't match, just reload readline history.
168 # If it still doesn't match, just reload readline history.
169 if self.current_length() != self.orig_length \
169 if self.current_length() != self.orig_length \
170 or self.get_readline_tail() != self.readline_tail:
170 or self.get_readline_tail() != self.readline_tail:
171 self.shell.refill_readline_hist()
171 self.shell.refill_readline_hist()
172 except (AttributeError, IndexError):
172 except (AttributeError, IndexError):
173 pass
173 pass
174 # Returning False will cause exceptions to propagate
174 # Returning False will cause exceptions to propagate
175 return False
175 return False
176
176
177 def current_length(self):
177 def current_length(self):
178 return self.shell.readline.get_current_history_length()
178 return self.shell.readline.get_current_history_length()
179
179
180 def get_readline_tail(self, n=10):
180 def get_readline_tail(self, n=10):
181 """Get the last n items in readline history."""
181 """Get the last n items in readline history."""
182 end = self.shell.readline.get_current_history_length() + 1
182 end = self.shell.readline.get_current_history_length() + 1
183 start = max(end-n, 1)
183 start = max(end-n, 1)
184 ghi = self.shell.readline.get_history_item
184 ghi = self.shell.readline.get_history_item
185 return [ghi(x) for x in range(start, end)]
185 return [ghi(x) for x in range(start, end)]
186
186
187 #-----------------------------------------------------------------------------
187 #-----------------------------------------------------------------------------
188 # Main IPython class
188 # Main IPython class
189 #-----------------------------------------------------------------------------
189 #-----------------------------------------------------------------------------
190
190
191 class InteractiveShell(SingletonConfigurable):
191 class InteractiveShell(SingletonConfigurable):
192 """An enhanced, interactive shell for Python."""
192 """An enhanced, interactive shell for Python."""
193
193
194 _instance = None
194 _instance = None
195
195
196 autocall = Enum((0,1,2), default_value=0, config=True, help=
196 autocall = Enum((0,1,2), default_value=0, config=True, help=
197 """
197 """
198 Make IPython automatically call any callable object even if you didn't
198 Make IPython automatically call any callable object even if you didn't
199 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
199 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
200 automatically. The value can be '0' to disable the feature, '1' for
200 automatically. The value can be '0' to disable the feature, '1' for
201 'smart' autocall, where it is not applied if there are no more
201 'smart' autocall, where it is not applied if there are no more
202 arguments on the line, and '2' for 'full' autocall, where all callable
202 arguments on the line, and '2' for 'full' autocall, where all callable
203 objects are automatically called (even if no arguments are present).
203 objects are automatically called (even if no arguments are present).
204 """
204 """
205 )
205 )
206 # TODO: remove all autoindent logic and put into frontends.
206 # TODO: remove all autoindent logic and put into frontends.
207 # We can't do this yet because even runlines uses the autoindent.
207 # We can't do this yet because even runlines uses the autoindent.
208 autoindent = CBool(True, config=True, help=
208 autoindent = CBool(True, config=True, help=
209 """
209 """
210 Autoindent IPython code entered interactively.
210 Autoindent IPython code entered interactively.
211 """
211 """
212 )
212 )
213 automagic = CBool(True, config=True, help=
213 automagic = CBool(True, config=True, help=
214 """
214 """
215 Enable magic commands to be called without the leading %.
215 Enable magic commands to be called without the leading %.
216 """
216 """
217 )
217 )
218 cache_size = Integer(1000, config=True, help=
218 cache_size = Integer(1000, config=True, help=
219 """
219 """
220 Set the size of the output cache. The default is 1000, you can
220 Set the size of the output cache. The default is 1000, you can
221 change it permanently in your config file. Setting it to 0 completely
221 change it permanently in your config file. Setting it to 0 completely
222 disables the caching system, and the minimum value accepted is 20 (if
222 disables the caching system, and the minimum value accepted is 20 (if
223 you provide a value less than 20, it is reset to 0 and a warning is
223 you provide a value less than 20, it is reset to 0 and a warning is
224 issued). This limit is defined because otherwise you'll spend more
224 issued). This limit is defined because otherwise you'll spend more
225 time re-flushing a too small cache than working
225 time re-flushing a too small cache than working
226 """
226 """
227 )
227 )
228 color_info = CBool(True, config=True, help=
228 color_info = CBool(True, config=True, help=
229 """
229 """
230 Use colors for displaying information about objects. Because this
230 Use colors for displaying information about objects. Because this
231 information is passed through a pager (like 'less'), and some pagers
231 information is passed through a pager (like 'less'), and some pagers
232 get confused with color codes, this capability can be turned off.
232 get confused with color codes, this capability can be turned off.
233 """
233 """
234 )
234 )
235 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
235 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
236 default_value=get_default_colors(), config=True,
236 default_value=get_default_colors(), config=True,
237 help="Set the color scheme (NoColor, Linux, or LightBG)."
237 help="Set the color scheme (NoColor, Linux, or LightBG)."
238 )
238 )
239 colors_force = CBool(False, help=
239 colors_force = CBool(False, help=
240 """
240 """
241 Force use of ANSI color codes, regardless of OS and readline
241 Force use of ANSI color codes, regardless of OS and readline
242 availability.
242 availability.
243 """
243 """
244 # FIXME: This is essentially a hack to allow ZMQShell to show colors
244 # FIXME: This is essentially a hack to allow ZMQShell to show colors
245 # without readline on Win32. When the ZMQ formatting system is
245 # without readline on Win32. When the ZMQ formatting system is
246 # refactored, this should be removed.
246 # refactored, this should be removed.
247 )
247 )
248 debug = CBool(False, config=True)
248 debug = CBool(False, config=True)
249 deep_reload = CBool(False, config=True, help=
249 deep_reload = CBool(False, config=True, help=
250 """
250 """
251 Enable deep (recursive) reloading by default. IPython can use the
251 Enable deep (recursive) reloading by default. IPython can use the
252 deep_reload module which reloads changes in modules recursively (it
252 deep_reload module which reloads changes in modules recursively (it
253 replaces the reload() function, so you don't need to change anything to
253 replaces the reload() function, so you don't need to change anything to
254 use it). deep_reload() forces a full reload of modules whose code may
254 use it). deep_reload() forces a full reload of modules whose code may
255 have changed, which the default reload() function does not. When
255 have changed, which the default reload() function does not. When
256 deep_reload is off, IPython will use the normal reload(), but
256 deep_reload is off, IPython will use the normal reload(), but
257 deep_reload will still be available as dreload().
257 deep_reload will still be available as dreload().
258 """
258 """
259 )
259 )
260 disable_failing_post_execute = CBool(False, config=True,
260 disable_failing_post_execute = CBool(False, config=True,
261 help="Don't call post-execute functions that have failed in the past."
261 help="Don't call post-execute functions that have failed in the past."
262 )
262 )
263 display_formatter = Instance(DisplayFormatter)
263 display_formatter = Instance(DisplayFormatter)
264 displayhook_class = Type(DisplayHook)
264 displayhook_class = Type(DisplayHook)
265 display_pub_class = Type(DisplayPublisher)
265 display_pub_class = Type(DisplayPublisher)
266 data_pub_class = None
266 data_pub_class = None
267
267
268 exit_now = CBool(False)
268 exit_now = CBool(False)
269 exiter = Instance(ExitAutocall)
269 exiter = Instance(ExitAutocall)
270 def _exiter_default(self):
270 def _exiter_default(self):
271 return ExitAutocall(self)
271 return ExitAutocall(self)
272 # Monotonically increasing execution counter
272 # Monotonically increasing execution counter
273 execution_count = Integer(1)
273 execution_count = Integer(1)
274 filename = Unicode("<ipython console>")
274 filename = Unicode("<ipython console>")
275 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
275 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
276
276
277 # Input splitter, to split entire cells of input into either individual
277 # Input splitter, to split entire cells of input into either individual
278 # interactive statements or whole blocks.
278 # interactive statements or whole blocks.
279 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
279 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
280 (), {})
280 (), {})
281 logstart = CBool(False, config=True, help=
281 logstart = CBool(False, config=True, help=
282 """
282 """
283 Start logging to the default log file.
283 Start logging to the default log file.
284 """
284 """
285 )
285 )
286 logfile = Unicode('', config=True, help=
286 logfile = Unicode('', config=True, help=
287 """
287 """
288 The name of the logfile to use.
288 The name of the logfile to use.
289 """
289 """
290 )
290 )
291 logappend = Unicode('', config=True, help=
291 logappend = Unicode('', config=True, help=
292 """
292 """
293 Start logging to the given file in append mode.
293 Start logging to the given file in append mode.
294 """
294 """
295 )
295 )
296 object_info_string_level = Enum((0,1,2), default_value=0,
296 object_info_string_level = Enum((0,1,2), default_value=0,
297 config=True)
297 config=True)
298 pdb = CBool(False, config=True, help=
298 pdb = CBool(False, config=True, help=
299 """
299 """
300 Automatically call the pdb debugger after every exception.
300 Automatically call the pdb debugger after every exception.
301 """
301 """
302 )
302 )
303 multiline_history = CBool(sys.platform != 'win32', config=True,
303 multiline_history = CBool(sys.platform != 'win32', config=True,
304 help="Save multi-line entries as one entry in readline history"
304 help="Save multi-line entries as one entry in readline history"
305 )
305 )
306
306
307 # deprecated prompt traits:
307 # deprecated prompt traits:
308
308
309 prompt_in1 = Unicode('In [\\#]: ', config=True,
309 prompt_in1 = Unicode('In [\\#]: ', config=True,
310 help="Deprecated, use PromptManager.in_template")
310 help="Deprecated, use PromptManager.in_template")
311 prompt_in2 = Unicode(' .\\D.: ', config=True,
311 prompt_in2 = Unicode(' .\\D.: ', config=True,
312 help="Deprecated, use PromptManager.in2_template")
312 help="Deprecated, use PromptManager.in2_template")
313 prompt_out = Unicode('Out[\\#]: ', config=True,
313 prompt_out = Unicode('Out[\\#]: ', config=True,
314 help="Deprecated, use PromptManager.out_template")
314 help="Deprecated, use PromptManager.out_template")
315 prompts_pad_left = CBool(True, config=True,
315 prompts_pad_left = CBool(True, config=True,
316 help="Deprecated, use PromptManager.justify")
316 help="Deprecated, use PromptManager.justify")
317
317
318 def _prompt_trait_changed(self, name, old, new):
318 def _prompt_trait_changed(self, name, old, new):
319 table = {
319 table = {
320 'prompt_in1' : 'in_template',
320 'prompt_in1' : 'in_template',
321 'prompt_in2' : 'in2_template',
321 'prompt_in2' : 'in2_template',
322 'prompt_out' : 'out_template',
322 'prompt_out' : 'out_template',
323 'prompts_pad_left' : 'justify',
323 'prompts_pad_left' : 'justify',
324 }
324 }
325 warn("InteractiveShell.{name} is deprecated, use PromptManager.{newname}\n".format(
325 warn("InteractiveShell.{name} is deprecated, use PromptManager.{newname}\n".format(
326 name=name, newname=table[name])
326 name=name, newname=table[name])
327 )
327 )
328 # protect against weird cases where self.config may not exist:
328 # protect against weird cases where self.config may not exist:
329 if self.config is not None:
329 if self.config is not None:
330 # propagate to corresponding PromptManager trait
330 # propagate to corresponding PromptManager trait
331 setattr(self.config.PromptManager, table[name], new)
331 setattr(self.config.PromptManager, table[name], new)
332
332
333 _prompt_in1_changed = _prompt_trait_changed
333 _prompt_in1_changed = _prompt_trait_changed
334 _prompt_in2_changed = _prompt_trait_changed
334 _prompt_in2_changed = _prompt_trait_changed
335 _prompt_out_changed = _prompt_trait_changed
335 _prompt_out_changed = _prompt_trait_changed
336 _prompt_pad_left_changed = _prompt_trait_changed
336 _prompt_pad_left_changed = _prompt_trait_changed
337
337
338 show_rewritten_input = CBool(True, config=True,
338 show_rewritten_input = CBool(True, config=True,
339 help="Show rewritten input, e.g. for autocall."
339 help="Show rewritten input, e.g. for autocall."
340 )
340 )
341
341
342 quiet = CBool(False, config=True)
342 quiet = CBool(False, config=True)
343
343
344 history_length = Integer(10000, config=True)
344 history_length = Integer(10000, config=True)
345
345
346 # The readline stuff will eventually be moved to the terminal subclass
346 # The readline stuff will eventually be moved to the terminal subclass
347 # but for now, we can't do that as readline is welded in everywhere.
347 # but for now, we can't do that as readline is welded in everywhere.
348 readline_use = CBool(True, config=True)
348 readline_use = CBool(True, config=True)
349 readline_remove_delims = Unicode('-/~', config=True)
349 readline_remove_delims = Unicode('-/~', config=True)
350 # don't use \M- bindings by default, because they
350 # don't use \M- bindings by default, because they
351 # conflict with 8-bit encodings. See gh-58,gh-88
351 # conflict with 8-bit encodings. See gh-58,gh-88
352 readline_parse_and_bind = List([
352 readline_parse_and_bind = List([
353 'tab: complete',
353 'tab: complete',
354 '"\C-l": clear-screen',
354 '"\C-l": clear-screen',
355 'set show-all-if-ambiguous on',
355 'set show-all-if-ambiguous on',
356 '"\C-o": tab-insert',
356 '"\C-o": tab-insert',
357 '"\C-r": reverse-search-history',
357 '"\C-r": reverse-search-history',
358 '"\C-s": forward-search-history',
358 '"\C-s": forward-search-history',
359 '"\C-p": history-search-backward',
359 '"\C-p": history-search-backward',
360 '"\C-n": history-search-forward',
360 '"\C-n": history-search-forward',
361 '"\e[A": history-search-backward',
361 '"\e[A": history-search-backward',
362 '"\e[B": history-search-forward',
362 '"\e[B": history-search-forward',
363 '"\C-k": kill-line',
363 '"\C-k": kill-line',
364 '"\C-u": unix-line-discard',
364 '"\C-u": unix-line-discard',
365 ], allow_none=False, config=True)
365 ], allow_none=False, config=True)
366
366
367 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none'],
367 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none'],
368 default_value='last_expr', config=True,
368 default_value='last_expr', config=True,
369 help="""
369 help="""
370 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
370 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
371 run interactively (displaying output from expressions).""")
371 run interactively (displaying output from expressions).""")
372
372
373 # TODO: this part of prompt management should be moved to the frontends.
373 # TODO: this part of prompt management should be moved to the frontends.
374 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
374 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
375 separate_in = SeparateUnicode('\n', config=True)
375 separate_in = SeparateUnicode('\n', config=True)
376 separate_out = SeparateUnicode('', config=True)
376 separate_out = SeparateUnicode('', config=True)
377 separate_out2 = SeparateUnicode('', config=True)
377 separate_out2 = SeparateUnicode('', config=True)
378 wildcards_case_sensitive = CBool(True, config=True)
378 wildcards_case_sensitive = CBool(True, config=True)
379 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
379 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
380 default_value='Context', config=True)
380 default_value='Context', config=True)
381
381
382 # Subcomponents of InteractiveShell
382 # Subcomponents of InteractiveShell
383 alias_manager = Instance('IPython.core.alias.AliasManager')
383 alias_manager = Instance('IPython.core.alias.AliasManager')
384 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
384 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
385 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
385 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
386 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
386 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
387 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
387 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
388 payload_manager = Instance('IPython.core.payload.PayloadManager')
388 payload_manager = Instance('IPython.core.payload.PayloadManager')
389 history_manager = Instance('IPython.core.history.HistoryManager')
389 history_manager = Instance('IPython.core.history.HistoryManager')
390 magics_manager = Instance('IPython.core.magic.MagicsManager')
390 magics_manager = Instance('IPython.core.magic.MagicsManager')
391
391
392 profile_dir = Instance('IPython.core.application.ProfileDir')
392 profile_dir = Instance('IPython.core.application.ProfileDir')
393 @property
393 @property
394 def profile(self):
394 def profile(self):
395 if self.profile_dir is not None:
395 if self.profile_dir is not None:
396 name = os.path.basename(self.profile_dir.location)
396 name = os.path.basename(self.profile_dir.location)
397 return name.replace('profile_','')
397 return name.replace('profile_','')
398
398
399
399
400 # Private interface
400 # Private interface
401 _post_execute = Instance(dict)
401 _post_execute = Instance(dict)
402
402
403 # Tracks any GUI loop loaded for pylab
403 # Tracks any GUI loop loaded for pylab
404 pylab_gui_select = None
404 pylab_gui_select = None
405
405
406 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
406 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
407 user_module=None, user_ns=None,
407 user_module=None, user_ns=None,
408 custom_exceptions=((), None)):
408 custom_exceptions=((), None)):
409
409
410 # This is where traits with a config_key argument are updated
410 # This is where traits with a config_key argument are updated
411 # from the values on config.
411 # from the values on config.
412 super(InteractiveShell, self).__init__(config=config)
412 super(InteractiveShell, self).__init__(config=config)
413 self.configurables = [self]
413 self.configurables = [self]
414
414
415 # These are relatively independent and stateless
415 # These are relatively independent and stateless
416 self.init_ipython_dir(ipython_dir)
416 self.init_ipython_dir(ipython_dir)
417 self.init_profile_dir(profile_dir)
417 self.init_profile_dir(profile_dir)
418 self.init_instance_attrs()
418 self.init_instance_attrs()
419 self.init_environment()
419 self.init_environment()
420
420
421 # Check if we're in a virtualenv, and set up sys.path.
421 # Check if we're in a virtualenv, and set up sys.path.
422 self.init_virtualenv()
422 self.init_virtualenv()
423
423
424 # Create namespaces (user_ns, user_global_ns, etc.)
424 # Create namespaces (user_ns, user_global_ns, etc.)
425 self.init_create_namespaces(user_module, user_ns)
425 self.init_create_namespaces(user_module, user_ns)
426 # This has to be done after init_create_namespaces because it uses
426 # This has to be done after init_create_namespaces because it uses
427 # something in self.user_ns, but before init_sys_modules, which
427 # something in self.user_ns, but before init_sys_modules, which
428 # is the first thing to modify sys.
428 # is the first thing to modify sys.
429 # TODO: When we override sys.stdout and sys.stderr before this class
429 # TODO: When we override sys.stdout and sys.stderr before this class
430 # is created, we are saving the overridden ones here. Not sure if this
430 # is created, we are saving the overridden ones here. Not sure if this
431 # is what we want to do.
431 # is what we want to do.
432 self.save_sys_module_state()
432 self.save_sys_module_state()
433 self.init_sys_modules()
433 self.init_sys_modules()
434
434
435 # While we're trying to have each part of the code directly access what
435 # While we're trying to have each part of the code directly access what
436 # it needs without keeping redundant references to objects, we have too
436 # it needs without keeping redundant references to objects, we have too
437 # much legacy code that expects ip.db to exist.
437 # much legacy code that expects ip.db to exist.
438 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
438 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
439
439
440 self.init_history()
440 self.init_history()
441 self.init_encoding()
441 self.init_encoding()
442 self.init_prefilter()
442 self.init_prefilter()
443
443
444 self.init_syntax_highlighting()
444 self.init_syntax_highlighting()
445 self.init_hooks()
445 self.init_hooks()
446 self.init_pushd_popd_magic()
446 self.init_pushd_popd_magic()
447 # self.init_traceback_handlers use to be here, but we moved it below
447 # self.init_traceback_handlers use to be here, but we moved it below
448 # because it and init_io have to come after init_readline.
448 # because it and init_io have to come after init_readline.
449 self.init_user_ns()
449 self.init_user_ns()
450 self.init_logger()
450 self.init_logger()
451 self.init_alias()
451 self.init_alias()
452 self.init_builtins()
452 self.init_builtins()
453
453
454 # The following was in post_config_initialization
454 # The following was in post_config_initialization
455 self.init_inspector()
455 self.init_inspector()
456 # init_readline() must come before init_io(), because init_io uses
456 # init_readline() must come before init_io(), because init_io uses
457 # readline related things.
457 # readline related things.
458 self.init_readline()
458 self.init_readline()
459 # We save this here in case user code replaces raw_input, but it needs
459 # We save this here in case user code replaces raw_input, but it needs
460 # to be after init_readline(), because PyPy's readline works by replacing
460 # to be after init_readline(), because PyPy's readline works by replacing
461 # raw_input.
461 # raw_input.
462 if py3compat.PY3:
462 if py3compat.PY3:
463 self.raw_input_original = input
463 self.raw_input_original = input
464 else:
464 else:
465 self.raw_input_original = raw_input
465 self.raw_input_original = raw_input
466 # init_completer must come after init_readline, because it needs to
466 # init_completer must come after init_readline, because it needs to
467 # know whether readline is present or not system-wide to configure the
467 # know whether readline is present or not system-wide to configure the
468 # completers, since the completion machinery can now operate
468 # completers, since the completion machinery can now operate
469 # independently of readline (e.g. over the network)
469 # independently of readline (e.g. over the network)
470 self.init_completer()
470 self.init_completer()
471 # TODO: init_io() needs to happen before init_traceback handlers
471 # TODO: init_io() needs to happen before init_traceback handlers
472 # because the traceback handlers hardcode the stdout/stderr streams.
472 # because the traceback handlers hardcode the stdout/stderr streams.
473 # This logic in in debugger.Pdb and should eventually be changed.
473 # This logic in in debugger.Pdb and should eventually be changed.
474 self.init_io()
474 self.init_io()
475 self.init_traceback_handlers(custom_exceptions)
475 self.init_traceback_handlers(custom_exceptions)
476 self.init_prompts()
476 self.init_prompts()
477 self.init_display_formatter()
477 self.init_display_formatter()
478 self.init_display_pub()
478 self.init_display_pub()
479 self.init_data_pub()
479 self.init_data_pub()
480 self.init_displayhook()
480 self.init_displayhook()
481 self.init_reload_doctest()
481 self.init_reload_doctest()
482 self.init_latextool()
482 self.init_latextool()
483 self.init_magics()
483 self.init_magics()
484 self.init_logstart()
484 self.init_logstart()
485 self.init_pdb()
485 self.init_pdb()
486 self.init_extension_manager()
486 self.init_extension_manager()
487 self.init_payload()
487 self.init_payload()
488 self.hooks.late_startup_hook()
488 self.hooks.late_startup_hook()
489 atexit.register(self.atexit_operations)
489 atexit.register(self.atexit_operations)
490
490
491 def get_ipython(self):
491 def get_ipython(self):
492 """Return the currently running IPython instance."""
492 """Return the currently running IPython instance."""
493 return self
493 return self
494
494
495 #-------------------------------------------------------------------------
495 #-------------------------------------------------------------------------
496 # Trait changed handlers
496 # Trait changed handlers
497 #-------------------------------------------------------------------------
497 #-------------------------------------------------------------------------
498
498
499 def _ipython_dir_changed(self, name, new):
499 def _ipython_dir_changed(self, name, new):
500 if not os.path.isdir(new):
500 if not os.path.isdir(new):
501 os.makedirs(new, mode = 0o777)
501 os.makedirs(new, mode = 0o777)
502
502
503 def set_autoindent(self,value=None):
503 def set_autoindent(self,value=None):
504 """Set the autoindent flag, checking for readline support.
504 """Set the autoindent flag, checking for readline support.
505
505
506 If called with no arguments, it acts as a toggle."""
506 If called with no arguments, it acts as a toggle."""
507
507
508 if value != 0 and not self.has_readline:
508 if value != 0 and not self.has_readline:
509 if os.name == 'posix':
509 if os.name == 'posix':
510 warn("The auto-indent feature requires the readline library")
510 warn("The auto-indent feature requires the readline library")
511 self.autoindent = 0
511 self.autoindent = 0
512 return
512 return
513 if value is None:
513 if value is None:
514 self.autoindent = not self.autoindent
514 self.autoindent = not self.autoindent
515 else:
515 else:
516 self.autoindent = value
516 self.autoindent = value
517
517
518 #-------------------------------------------------------------------------
518 #-------------------------------------------------------------------------
519 # init_* methods called by __init__
519 # init_* methods called by __init__
520 #-------------------------------------------------------------------------
520 #-------------------------------------------------------------------------
521
521
522 def init_ipython_dir(self, ipython_dir):
522 def init_ipython_dir(self, ipython_dir):
523 if ipython_dir is not None:
523 if ipython_dir is not None:
524 self.ipython_dir = ipython_dir
524 self.ipython_dir = ipython_dir
525 return
525 return
526
526
527 self.ipython_dir = get_ipython_dir()
527 self.ipython_dir = get_ipython_dir()
528
528
529 def init_profile_dir(self, profile_dir):
529 def init_profile_dir(self, profile_dir):
530 if profile_dir is not None:
530 if profile_dir is not None:
531 self.profile_dir = profile_dir
531 self.profile_dir = profile_dir
532 return
532 return
533 self.profile_dir =\
533 self.profile_dir =\
534 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
534 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
535
535
536 def init_instance_attrs(self):
536 def init_instance_attrs(self):
537 self.more = False
537 self.more = False
538
538
539 # command compiler
539 # command compiler
540 self.compile = CachingCompiler()
540 self.compile = CachingCompiler()
541
541
542 # Make an empty namespace, which extension writers can rely on both
542 # Make an empty namespace, which extension writers can rely on both
543 # existing and NEVER being used by ipython itself. This gives them a
543 # existing and NEVER being used by ipython itself. This gives them a
544 # convenient location for storing additional information and state
544 # convenient location for storing additional information and state
545 # their extensions may require, without fear of collisions with other
545 # their extensions may require, without fear of collisions with other
546 # ipython names that may develop later.
546 # ipython names that may develop later.
547 self.meta = Struct()
547 self.meta = Struct()
548
548
549 # Temporary files used for various purposes. Deleted at exit.
549 # Temporary files used for various purposes. Deleted at exit.
550 self.tempfiles = []
550 self.tempfiles = []
551
551
552 # Keep track of readline usage (later set by init_readline)
552 # Keep track of readline usage (later set by init_readline)
553 self.has_readline = False
553 self.has_readline = False
554
554
555 # keep track of where we started running (mainly for crash post-mortem)
555 # keep track of where we started running (mainly for crash post-mortem)
556 # This is not being used anywhere currently.
556 # This is not being used anywhere currently.
557 self.starting_dir = os.getcwdu()
557 self.starting_dir = os.getcwdu()
558
558
559 # Indentation management
559 # Indentation management
560 self.indent_current_nsp = 0
560 self.indent_current_nsp = 0
561
561
562 # Dict to track post-execution functions that have been registered
562 # Dict to track post-execution functions that have been registered
563 self._post_execute = {}
563 self._post_execute = {}
564
564
565 def init_environment(self):
565 def init_environment(self):
566 """Any changes we need to make to the user's environment."""
566 """Any changes we need to make to the user's environment."""
567 pass
567 pass
568
568
569 def init_encoding(self):
569 def init_encoding(self):
570 # Get system encoding at startup time. Certain terminals (like Emacs
570 # Get system encoding at startup time. Certain terminals (like Emacs
571 # under Win32 have it set to None, and we need to have a known valid
571 # under Win32 have it set to None, and we need to have a known valid
572 # encoding to use in the raw_input() method
572 # encoding to use in the raw_input() method
573 try:
573 try:
574 self.stdin_encoding = sys.stdin.encoding or 'ascii'
574 self.stdin_encoding = sys.stdin.encoding or 'ascii'
575 except AttributeError:
575 except AttributeError:
576 self.stdin_encoding = 'ascii'
576 self.stdin_encoding = 'ascii'
577
577
578 def init_syntax_highlighting(self):
578 def init_syntax_highlighting(self):
579 # Python source parser/formatter for syntax highlighting
579 # Python source parser/formatter for syntax highlighting
580 pyformat = PyColorize.Parser().format
580 pyformat = PyColorize.Parser().format
581 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
581 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
582
582
583 def init_pushd_popd_magic(self):
583 def init_pushd_popd_magic(self):
584 # for pushd/popd management
584 # for pushd/popd management
585 self.home_dir = get_home_dir()
585 self.home_dir = get_home_dir()
586
586
587 self.dir_stack = []
587 self.dir_stack = []
588
588
589 def init_logger(self):
589 def init_logger(self):
590 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
590 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
591 logmode='rotate')
591 logmode='rotate')
592
592
593 def init_logstart(self):
593 def init_logstart(self):
594 """Initialize logging in case it was requested at the command line.
594 """Initialize logging in case it was requested at the command line.
595 """
595 """
596 if self.logappend:
596 if self.logappend:
597 self.magic('logstart %s append' % self.logappend)
597 self.magic('logstart %s append' % self.logappend)
598 elif self.logfile:
598 elif self.logfile:
599 self.magic('logstart %s' % self.logfile)
599 self.magic('logstart %s' % self.logfile)
600 elif self.logstart:
600 elif self.logstart:
601 self.magic('logstart')
601 self.magic('logstart')
602
602
603 def init_builtins(self):
603 def init_builtins(self):
604 # A single, static flag that we set to True. Its presence indicates
604 # A single, static flag that we set to True. Its presence indicates
605 # that an IPython shell has been created, and we make no attempts at
605 # that an IPython shell has been created, and we make no attempts at
606 # removing on exit or representing the existence of more than one
606 # removing on exit or representing the existence of more than one
607 # IPython at a time.
607 # IPython at a time.
608 builtin_mod.__dict__['__IPYTHON__'] = True
608 builtin_mod.__dict__['__IPYTHON__'] = True
609
609
610 # In 0.11 we introduced '__IPYTHON__active' as an integer we'd try to
610 # In 0.11 we introduced '__IPYTHON__active' as an integer we'd try to
611 # manage on enter/exit, but with all our shells it's virtually
611 # manage on enter/exit, but with all our shells it's virtually
612 # impossible to get all the cases right. We're leaving the name in for
612 # impossible to get all the cases right. We're leaving the name in for
613 # those who adapted their codes to check for this flag, but will
613 # those who adapted their codes to check for this flag, but will
614 # eventually remove it after a few more releases.
614 # eventually remove it after a few more releases.
615 builtin_mod.__dict__['__IPYTHON__active'] = \
615 builtin_mod.__dict__['__IPYTHON__active'] = \
616 'Deprecated, check for __IPYTHON__'
616 'Deprecated, check for __IPYTHON__'
617
617
618 self.builtin_trap = BuiltinTrap(shell=self)
618 self.builtin_trap = BuiltinTrap(shell=self)
619
619
620 def init_inspector(self):
620 def init_inspector(self):
621 # Object inspector
621 # Object inspector
622 self.inspector = oinspect.Inspector(oinspect.InspectColors,
622 self.inspector = oinspect.Inspector(oinspect.InspectColors,
623 PyColorize.ANSICodeColors,
623 PyColorize.ANSICodeColors,
624 'NoColor',
624 'NoColor',
625 self.object_info_string_level)
625 self.object_info_string_level)
626
626
627 def init_io(self):
627 def init_io(self):
628 # This will just use sys.stdout and sys.stderr. If you want to
628 # This will just use sys.stdout and sys.stderr. If you want to
629 # override sys.stdout and sys.stderr themselves, you need to do that
629 # override sys.stdout and sys.stderr themselves, you need to do that
630 # *before* instantiating this class, because io holds onto
630 # *before* instantiating this class, because io holds onto
631 # references to the underlying streams.
631 # references to the underlying streams.
632 if sys.platform == 'win32' and self.has_readline:
632 if (sys.platform == 'win32' or sys.platform == 'cli') and self.has_readline:
633 io.stdout = io.stderr = io.IOStream(self.readline._outputfile)
633 io.stdout = io.stderr = io.IOStream(self.readline._outputfile)
634 else:
634 else:
635 io.stdout = io.IOStream(sys.stdout)
635 io.stdout = io.IOStream(sys.stdout)
636 io.stderr = io.IOStream(sys.stderr)
636 io.stderr = io.IOStream(sys.stderr)
637
637
638 def init_prompts(self):
638 def init_prompts(self):
639 self.prompt_manager = PromptManager(shell=self, config=self.config)
639 self.prompt_manager = PromptManager(shell=self, config=self.config)
640 self.configurables.append(self.prompt_manager)
640 self.configurables.append(self.prompt_manager)
641 # Set system prompts, so that scripts can decide if they are running
641 # Set system prompts, so that scripts can decide if they are running
642 # interactively.
642 # interactively.
643 sys.ps1 = 'In : '
643 sys.ps1 = 'In : '
644 sys.ps2 = '...: '
644 sys.ps2 = '...: '
645 sys.ps3 = 'Out: '
645 sys.ps3 = 'Out: '
646
646
647 def init_display_formatter(self):
647 def init_display_formatter(self):
648 self.display_formatter = DisplayFormatter(config=self.config)
648 self.display_formatter = DisplayFormatter(config=self.config)
649 self.configurables.append(self.display_formatter)
649 self.configurables.append(self.display_formatter)
650
650
651 def init_display_pub(self):
651 def init_display_pub(self):
652 self.display_pub = self.display_pub_class(config=self.config)
652 self.display_pub = self.display_pub_class(config=self.config)
653 self.configurables.append(self.display_pub)
653 self.configurables.append(self.display_pub)
654
654
655 def init_data_pub(self):
655 def init_data_pub(self):
656 if not self.data_pub_class:
656 if not self.data_pub_class:
657 self.data_pub = None
657 self.data_pub = None
658 return
658 return
659 self.data_pub = self.data_pub_class(config=self.config)
659 self.data_pub = self.data_pub_class(config=self.config)
660 self.configurables.append(self.data_pub)
660 self.configurables.append(self.data_pub)
661
661
662 def init_displayhook(self):
662 def init_displayhook(self):
663 # Initialize displayhook, set in/out prompts and printing system
663 # Initialize displayhook, set in/out prompts and printing system
664 self.displayhook = self.displayhook_class(
664 self.displayhook = self.displayhook_class(
665 config=self.config,
665 config=self.config,
666 shell=self,
666 shell=self,
667 cache_size=self.cache_size,
667 cache_size=self.cache_size,
668 )
668 )
669 self.configurables.append(self.displayhook)
669 self.configurables.append(self.displayhook)
670 # This is a context manager that installs/revmoes the displayhook at
670 # This is a context manager that installs/revmoes the displayhook at
671 # the appropriate time.
671 # the appropriate time.
672 self.display_trap = DisplayTrap(hook=self.displayhook)
672 self.display_trap = DisplayTrap(hook=self.displayhook)
673
673
674 def init_reload_doctest(self):
674 def init_reload_doctest(self):
675 # Do a proper resetting of doctest, including the necessary displayhook
675 # Do a proper resetting of doctest, including the necessary displayhook
676 # monkeypatching
676 # monkeypatching
677 try:
677 try:
678 doctest_reload()
678 doctest_reload()
679 except ImportError:
679 except ImportError:
680 warn("doctest module does not exist.")
680 warn("doctest module does not exist.")
681
681
682 def init_latextool(self):
682 def init_latextool(self):
683 """Configure LaTeXTool."""
683 """Configure LaTeXTool."""
684 cfg = LaTeXTool.instance(config=self.config)
684 cfg = LaTeXTool.instance(config=self.config)
685 if cfg not in self.configurables:
685 if cfg not in self.configurables:
686 self.configurables.append(cfg)
686 self.configurables.append(cfg)
687
687
688 def init_virtualenv(self):
688 def init_virtualenv(self):
689 """Add a virtualenv to sys.path so the user can import modules from it.
689 """Add a virtualenv to sys.path so the user can import modules from it.
690 This isn't perfect: it doesn't use the Python interpreter with which the
690 This isn't perfect: it doesn't use the Python interpreter with which the
691 virtualenv was built, and it ignores the --no-site-packages option. A
691 virtualenv was built, and it ignores the --no-site-packages option. A
692 warning will appear suggesting the user installs IPython in the
692 warning will appear suggesting the user installs IPython in the
693 virtualenv, but for many cases, it probably works well enough.
693 virtualenv, but for many cases, it probably works well enough.
694
694
695 Adapted from code snippets online.
695 Adapted from code snippets online.
696
696
697 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
697 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
698 """
698 """
699 if 'VIRTUAL_ENV' not in os.environ:
699 if 'VIRTUAL_ENV' not in os.environ:
700 # Not in a virtualenv
700 # Not in a virtualenv
701 return
701 return
702
702
703 if sys.executable.startswith(os.environ['VIRTUAL_ENV']):
703 if sys.executable.startswith(os.environ['VIRTUAL_ENV']):
704 # Running properly in the virtualenv, don't need to do anything
704 # Running properly in the virtualenv, don't need to do anything
705 return
705 return
706
706
707 warn("Attempting to work in a virtualenv. If you encounter problems, please "
707 warn("Attempting to work in a virtualenv. If you encounter problems, please "
708 "install IPython inside the virtualenv.\n")
708 "install IPython inside the virtualenv.\n")
709 if sys.platform == "win32":
709 if sys.platform == "win32":
710 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
710 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
711 else:
711 else:
712 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
712 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
713 'python%d.%d' % sys.version_info[:2], 'site-packages')
713 'python%d.%d' % sys.version_info[:2], 'site-packages')
714
714
715 import site
715 import site
716 sys.path.insert(0, virtual_env)
716 sys.path.insert(0, virtual_env)
717 site.addsitedir(virtual_env)
717 site.addsitedir(virtual_env)
718
718
719 #-------------------------------------------------------------------------
719 #-------------------------------------------------------------------------
720 # Things related to injections into the sys module
720 # Things related to injections into the sys module
721 #-------------------------------------------------------------------------
721 #-------------------------------------------------------------------------
722
722
723 def save_sys_module_state(self):
723 def save_sys_module_state(self):
724 """Save the state of hooks in the sys module.
724 """Save the state of hooks in the sys module.
725
725
726 This has to be called after self.user_module is created.
726 This has to be called after self.user_module is created.
727 """
727 """
728 self._orig_sys_module_state = {}
728 self._orig_sys_module_state = {}
729 self._orig_sys_module_state['stdin'] = sys.stdin
729 self._orig_sys_module_state['stdin'] = sys.stdin
730 self._orig_sys_module_state['stdout'] = sys.stdout
730 self._orig_sys_module_state['stdout'] = sys.stdout
731 self._orig_sys_module_state['stderr'] = sys.stderr
731 self._orig_sys_module_state['stderr'] = sys.stderr
732 self._orig_sys_module_state['excepthook'] = sys.excepthook
732 self._orig_sys_module_state['excepthook'] = sys.excepthook
733 self._orig_sys_modules_main_name = self.user_module.__name__
733 self._orig_sys_modules_main_name = self.user_module.__name__
734 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
734 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
735
735
736 def restore_sys_module_state(self):
736 def restore_sys_module_state(self):
737 """Restore the state of the sys module."""
737 """Restore the state of the sys module."""
738 try:
738 try:
739 for k, v in self._orig_sys_module_state.iteritems():
739 for k, v in self._orig_sys_module_state.iteritems():
740 setattr(sys, k, v)
740 setattr(sys, k, v)
741 except AttributeError:
741 except AttributeError:
742 pass
742 pass
743 # Reset what what done in self.init_sys_modules
743 # Reset what what done in self.init_sys_modules
744 if self._orig_sys_modules_main_mod is not None:
744 if self._orig_sys_modules_main_mod is not None:
745 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
745 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
746
746
747 #-------------------------------------------------------------------------
747 #-------------------------------------------------------------------------
748 # Things related to hooks
748 # Things related to hooks
749 #-------------------------------------------------------------------------
749 #-------------------------------------------------------------------------
750
750
751 def init_hooks(self):
751 def init_hooks(self):
752 # hooks holds pointers used for user-side customizations
752 # hooks holds pointers used for user-side customizations
753 self.hooks = Struct()
753 self.hooks = Struct()
754
754
755 self.strdispatchers = {}
755 self.strdispatchers = {}
756
756
757 # Set all default hooks, defined in the IPython.hooks module.
757 # Set all default hooks, defined in the IPython.hooks module.
758 hooks = IPython.core.hooks
758 hooks = IPython.core.hooks
759 for hook_name in hooks.__all__:
759 for hook_name in hooks.__all__:
760 # default hooks have priority 100, i.e. low; user hooks should have
760 # default hooks have priority 100, i.e. low; user hooks should have
761 # 0-100 priority
761 # 0-100 priority
762 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
762 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
763
763
764 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
764 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
765 """set_hook(name,hook) -> sets an internal IPython hook.
765 """set_hook(name,hook) -> sets an internal IPython hook.
766
766
767 IPython exposes some of its internal API as user-modifiable hooks. By
767 IPython exposes some of its internal API as user-modifiable hooks. By
768 adding your function to one of these hooks, you can modify IPython's
768 adding your function to one of these hooks, you can modify IPython's
769 behavior to call at runtime your own routines."""
769 behavior to call at runtime your own routines."""
770
770
771 # At some point in the future, this should validate the hook before it
771 # At some point in the future, this should validate the hook before it
772 # accepts it. Probably at least check that the hook takes the number
772 # accepts it. Probably at least check that the hook takes the number
773 # of args it's supposed to.
773 # of args it's supposed to.
774
774
775 f = types.MethodType(hook,self)
775 f = types.MethodType(hook,self)
776
776
777 # check if the hook is for strdispatcher first
777 # check if the hook is for strdispatcher first
778 if str_key is not None:
778 if str_key is not None:
779 sdp = self.strdispatchers.get(name, StrDispatch())
779 sdp = self.strdispatchers.get(name, StrDispatch())
780 sdp.add_s(str_key, f, priority )
780 sdp.add_s(str_key, f, priority )
781 self.strdispatchers[name] = sdp
781 self.strdispatchers[name] = sdp
782 return
782 return
783 if re_key is not None:
783 if re_key is not None:
784 sdp = self.strdispatchers.get(name, StrDispatch())
784 sdp = self.strdispatchers.get(name, StrDispatch())
785 sdp.add_re(re.compile(re_key), f, priority )
785 sdp.add_re(re.compile(re_key), f, priority )
786 self.strdispatchers[name] = sdp
786 self.strdispatchers[name] = sdp
787 return
787 return
788
788
789 dp = getattr(self.hooks, name, None)
789 dp = getattr(self.hooks, name, None)
790 if name not in IPython.core.hooks.__all__:
790 if name not in IPython.core.hooks.__all__:
791 print("Warning! Hook '%s' is not one of %s" % \
791 print("Warning! Hook '%s' is not one of %s" % \
792 (name, IPython.core.hooks.__all__ ))
792 (name, IPython.core.hooks.__all__ ))
793 if not dp:
793 if not dp:
794 dp = IPython.core.hooks.CommandChainDispatcher()
794 dp = IPython.core.hooks.CommandChainDispatcher()
795
795
796 try:
796 try:
797 dp.add(f,priority)
797 dp.add(f,priority)
798 except AttributeError:
798 except AttributeError:
799 # it was not commandchain, plain old func - replace
799 # it was not commandchain, plain old func - replace
800 dp = f
800 dp = f
801
801
802 setattr(self.hooks,name, dp)
802 setattr(self.hooks,name, dp)
803
803
804 def register_post_execute(self, func):
804 def register_post_execute(self, func):
805 """Register a function for calling after code execution.
805 """Register a function for calling after code execution.
806 """
806 """
807 if not callable(func):
807 if not callable(func):
808 raise ValueError('argument %s must be callable' % func)
808 raise ValueError('argument %s must be callable' % func)
809 self._post_execute[func] = True
809 self._post_execute[func] = True
810
810
811 #-------------------------------------------------------------------------
811 #-------------------------------------------------------------------------
812 # Things related to the "main" module
812 # Things related to the "main" module
813 #-------------------------------------------------------------------------
813 #-------------------------------------------------------------------------
814
814
815 def new_main_mod(self,ns=None):
815 def new_main_mod(self,ns=None):
816 """Return a new 'main' module object for user code execution.
816 """Return a new 'main' module object for user code execution.
817 """
817 """
818 main_mod = self._user_main_module
818 main_mod = self._user_main_module
819 init_fakemod_dict(main_mod,ns)
819 init_fakemod_dict(main_mod,ns)
820 return main_mod
820 return main_mod
821
821
822 def cache_main_mod(self,ns,fname):
822 def cache_main_mod(self,ns,fname):
823 """Cache a main module's namespace.
823 """Cache a main module's namespace.
824
824
825 When scripts are executed via %run, we must keep a reference to the
825 When scripts are executed via %run, we must keep a reference to the
826 namespace of their __main__ module (a FakeModule instance) around so
826 namespace of their __main__ module (a FakeModule instance) around so
827 that Python doesn't clear it, rendering objects defined therein
827 that Python doesn't clear it, rendering objects defined therein
828 useless.
828 useless.
829
829
830 This method keeps said reference in a private dict, keyed by the
830 This method keeps said reference in a private dict, keyed by the
831 absolute path of the module object (which corresponds to the script
831 absolute path of the module object (which corresponds to the script
832 path). This way, for multiple executions of the same script we only
832 path). This way, for multiple executions of the same script we only
833 keep one copy of the namespace (the last one), thus preventing memory
833 keep one copy of the namespace (the last one), thus preventing memory
834 leaks from old references while allowing the objects from the last
834 leaks from old references while allowing the objects from the last
835 execution to be accessible.
835 execution to be accessible.
836
836
837 Note: we can not allow the actual FakeModule instances to be deleted,
837 Note: we can not allow the actual FakeModule instances to be deleted,
838 because of how Python tears down modules (it hard-sets all their
838 because of how Python tears down modules (it hard-sets all their
839 references to None without regard for reference counts). This method
839 references to None without regard for reference counts). This method
840 must therefore make a *copy* of the given namespace, to allow the
840 must therefore make a *copy* of the given namespace, to allow the
841 original module's __dict__ to be cleared and reused.
841 original module's __dict__ to be cleared and reused.
842
842
843
843
844 Parameters
844 Parameters
845 ----------
845 ----------
846 ns : a namespace (a dict, typically)
846 ns : a namespace (a dict, typically)
847
847
848 fname : str
848 fname : str
849 Filename associated with the namespace.
849 Filename associated with the namespace.
850
850
851 Examples
851 Examples
852 --------
852 --------
853
853
854 In [10]: import IPython
854 In [10]: import IPython
855
855
856 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
856 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
857
857
858 In [12]: IPython.__file__ in _ip._main_ns_cache
858 In [12]: IPython.__file__ in _ip._main_ns_cache
859 Out[12]: True
859 Out[12]: True
860 """
860 """
861 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
861 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
862
862
863 def clear_main_mod_cache(self):
863 def clear_main_mod_cache(self):
864 """Clear the cache of main modules.
864 """Clear the cache of main modules.
865
865
866 Mainly for use by utilities like %reset.
866 Mainly for use by utilities like %reset.
867
867
868 Examples
868 Examples
869 --------
869 --------
870
870
871 In [15]: import IPython
871 In [15]: import IPython
872
872
873 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
873 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
874
874
875 In [17]: len(_ip._main_ns_cache) > 0
875 In [17]: len(_ip._main_ns_cache) > 0
876 Out[17]: True
876 Out[17]: True
877
877
878 In [18]: _ip.clear_main_mod_cache()
878 In [18]: _ip.clear_main_mod_cache()
879
879
880 In [19]: len(_ip._main_ns_cache) == 0
880 In [19]: len(_ip._main_ns_cache) == 0
881 Out[19]: True
881 Out[19]: True
882 """
882 """
883 self._main_ns_cache.clear()
883 self._main_ns_cache.clear()
884
884
885 #-------------------------------------------------------------------------
885 #-------------------------------------------------------------------------
886 # Things related to debugging
886 # Things related to debugging
887 #-------------------------------------------------------------------------
887 #-------------------------------------------------------------------------
888
888
889 def init_pdb(self):
889 def init_pdb(self):
890 # Set calling of pdb on exceptions
890 # Set calling of pdb on exceptions
891 # self.call_pdb is a property
891 # self.call_pdb is a property
892 self.call_pdb = self.pdb
892 self.call_pdb = self.pdb
893
893
894 def _get_call_pdb(self):
894 def _get_call_pdb(self):
895 return self._call_pdb
895 return self._call_pdb
896
896
897 def _set_call_pdb(self,val):
897 def _set_call_pdb(self,val):
898
898
899 if val not in (0,1,False,True):
899 if val not in (0,1,False,True):
900 raise ValueError('new call_pdb value must be boolean')
900 raise ValueError('new call_pdb value must be boolean')
901
901
902 # store value in instance
902 # store value in instance
903 self._call_pdb = val
903 self._call_pdb = val
904
904
905 # notify the actual exception handlers
905 # notify the actual exception handlers
906 self.InteractiveTB.call_pdb = val
906 self.InteractiveTB.call_pdb = val
907
907
908 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
908 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
909 'Control auto-activation of pdb at exceptions')
909 'Control auto-activation of pdb at exceptions')
910
910
911 def debugger(self,force=False):
911 def debugger(self,force=False):
912 """Call the pydb/pdb debugger.
912 """Call the pydb/pdb debugger.
913
913
914 Keywords:
914 Keywords:
915
915
916 - force(False): by default, this routine checks the instance call_pdb
916 - force(False): by default, this routine checks the instance call_pdb
917 flag and does not actually invoke the debugger if the flag is false.
917 flag and does not actually invoke the debugger if the flag is false.
918 The 'force' option forces the debugger to activate even if the flag
918 The 'force' option forces the debugger to activate even if the flag
919 is false.
919 is false.
920 """
920 """
921
921
922 if not (force or self.call_pdb):
922 if not (force or self.call_pdb):
923 return
923 return
924
924
925 if not hasattr(sys,'last_traceback'):
925 if not hasattr(sys,'last_traceback'):
926 error('No traceback has been produced, nothing to debug.')
926 error('No traceback has been produced, nothing to debug.')
927 return
927 return
928
928
929 # use pydb if available
929 # use pydb if available
930 if debugger.has_pydb:
930 if debugger.has_pydb:
931 from pydb import pm
931 from pydb import pm
932 else:
932 else:
933 # fallback to our internal debugger
933 # fallback to our internal debugger
934 pm = lambda : self.InteractiveTB.debugger(force=True)
934 pm = lambda : self.InteractiveTB.debugger(force=True)
935
935
936 with self.readline_no_record:
936 with self.readline_no_record:
937 pm()
937 pm()
938
938
939 #-------------------------------------------------------------------------
939 #-------------------------------------------------------------------------
940 # Things related to IPython's various namespaces
940 # Things related to IPython's various namespaces
941 #-------------------------------------------------------------------------
941 #-------------------------------------------------------------------------
942 default_user_namespaces = True
942 default_user_namespaces = True
943
943
944 def init_create_namespaces(self, user_module=None, user_ns=None):
944 def init_create_namespaces(self, user_module=None, user_ns=None):
945 # Create the namespace where the user will operate. user_ns is
945 # Create the namespace where the user will operate. user_ns is
946 # normally the only one used, and it is passed to the exec calls as
946 # normally the only one used, and it is passed to the exec calls as
947 # the locals argument. But we do carry a user_global_ns namespace
947 # the locals argument. But we do carry a user_global_ns namespace
948 # given as the exec 'globals' argument, This is useful in embedding
948 # given as the exec 'globals' argument, This is useful in embedding
949 # situations where the ipython shell opens in a context where the
949 # situations where the ipython shell opens in a context where the
950 # distinction between locals and globals is meaningful. For
950 # distinction between locals and globals is meaningful. For
951 # non-embedded contexts, it is just the same object as the user_ns dict.
951 # non-embedded contexts, it is just the same object as the user_ns dict.
952
952
953 # FIXME. For some strange reason, __builtins__ is showing up at user
953 # FIXME. For some strange reason, __builtins__ is showing up at user
954 # level as a dict instead of a module. This is a manual fix, but I
954 # level as a dict instead of a module. This is a manual fix, but I
955 # should really track down where the problem is coming from. Alex
955 # should really track down where the problem is coming from. Alex
956 # Schmolck reported this problem first.
956 # Schmolck reported this problem first.
957
957
958 # A useful post by Alex Martelli on this topic:
958 # A useful post by Alex Martelli on this topic:
959 # Re: inconsistent value from __builtins__
959 # Re: inconsistent value from __builtins__
960 # Von: Alex Martelli <aleaxit@yahoo.com>
960 # Von: Alex Martelli <aleaxit@yahoo.com>
961 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
961 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
962 # Gruppen: comp.lang.python
962 # Gruppen: comp.lang.python
963
963
964 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
964 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
965 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
965 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
966 # > <type 'dict'>
966 # > <type 'dict'>
967 # > >>> print type(__builtins__)
967 # > >>> print type(__builtins__)
968 # > <type 'module'>
968 # > <type 'module'>
969 # > Is this difference in return value intentional?
969 # > Is this difference in return value intentional?
970
970
971 # Well, it's documented that '__builtins__' can be either a dictionary
971 # Well, it's documented that '__builtins__' can be either a dictionary
972 # or a module, and it's been that way for a long time. Whether it's
972 # or a module, and it's been that way for a long time. Whether it's
973 # intentional (or sensible), I don't know. In any case, the idea is
973 # intentional (or sensible), I don't know. In any case, the idea is
974 # that if you need to access the built-in namespace directly, you
974 # that if you need to access the built-in namespace directly, you
975 # should start with "import __builtin__" (note, no 's') which will
975 # should start with "import __builtin__" (note, no 's') which will
976 # definitely give you a module. Yeah, it's somewhat confusing:-(.
976 # definitely give you a module. Yeah, it's somewhat confusing:-(.
977
977
978 # These routines return a properly built module and dict as needed by
978 # These routines return a properly built module and dict as needed by
979 # the rest of the code, and can also be used by extension writers to
979 # the rest of the code, and can also be used by extension writers to
980 # generate properly initialized namespaces.
980 # generate properly initialized namespaces.
981 if (user_ns is not None) or (user_module is not None):
981 if (user_ns is not None) or (user_module is not None):
982 self.default_user_namespaces = False
982 self.default_user_namespaces = False
983 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
983 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
984
984
985 # A record of hidden variables we have added to the user namespace, so
985 # A record of hidden variables we have added to the user namespace, so
986 # we can list later only variables defined in actual interactive use.
986 # we can list later only variables defined in actual interactive use.
987 self.user_ns_hidden = set()
987 self.user_ns_hidden = set()
988
988
989 # Now that FakeModule produces a real module, we've run into a nasty
989 # Now that FakeModule produces a real module, we've run into a nasty
990 # problem: after script execution (via %run), the module where the user
990 # problem: after script execution (via %run), the module where the user
991 # code ran is deleted. Now that this object is a true module (needed
991 # code ran is deleted. Now that this object is a true module (needed
992 # so docetst and other tools work correctly), the Python module
992 # so docetst and other tools work correctly), the Python module
993 # teardown mechanism runs over it, and sets to None every variable
993 # teardown mechanism runs over it, and sets to None every variable
994 # present in that module. Top-level references to objects from the
994 # present in that module. Top-level references to objects from the
995 # script survive, because the user_ns is updated with them. However,
995 # script survive, because the user_ns is updated with them. However,
996 # calling functions defined in the script that use other things from
996 # calling functions defined in the script that use other things from
997 # the script will fail, because the function's closure had references
997 # the script will fail, because the function's closure had references
998 # to the original objects, which are now all None. So we must protect
998 # to the original objects, which are now all None. So we must protect
999 # these modules from deletion by keeping a cache.
999 # these modules from deletion by keeping a cache.
1000 #
1000 #
1001 # To avoid keeping stale modules around (we only need the one from the
1001 # To avoid keeping stale modules around (we only need the one from the
1002 # last run), we use a dict keyed with the full path to the script, so
1002 # last run), we use a dict keyed with the full path to the script, so
1003 # only the last version of the module is held in the cache. Note,
1003 # only the last version of the module is held in the cache. Note,
1004 # however, that we must cache the module *namespace contents* (their
1004 # however, that we must cache the module *namespace contents* (their
1005 # __dict__). Because if we try to cache the actual modules, old ones
1005 # __dict__). Because if we try to cache the actual modules, old ones
1006 # (uncached) could be destroyed while still holding references (such as
1006 # (uncached) could be destroyed while still holding references (such as
1007 # those held by GUI objects that tend to be long-lived)>
1007 # those held by GUI objects that tend to be long-lived)>
1008 #
1008 #
1009 # The %reset command will flush this cache. See the cache_main_mod()
1009 # The %reset command will flush this cache. See the cache_main_mod()
1010 # and clear_main_mod_cache() methods for details on use.
1010 # and clear_main_mod_cache() methods for details on use.
1011
1011
1012 # This is the cache used for 'main' namespaces
1012 # This is the cache used for 'main' namespaces
1013 self._main_ns_cache = {}
1013 self._main_ns_cache = {}
1014 # And this is the single instance of FakeModule whose __dict__ we keep
1014 # And this is the single instance of FakeModule whose __dict__ we keep
1015 # copying and clearing for reuse on each %run
1015 # copying and clearing for reuse on each %run
1016 self._user_main_module = FakeModule()
1016 self._user_main_module = FakeModule()
1017
1017
1018 # A table holding all the namespaces IPython deals with, so that
1018 # A table holding all the namespaces IPython deals with, so that
1019 # introspection facilities can search easily.
1019 # introspection facilities can search easily.
1020 self.ns_table = {'user_global':self.user_module.__dict__,
1020 self.ns_table = {'user_global':self.user_module.__dict__,
1021 'user_local':self.user_ns,
1021 'user_local':self.user_ns,
1022 'builtin':builtin_mod.__dict__
1022 'builtin':builtin_mod.__dict__
1023 }
1023 }
1024
1024
1025 @property
1025 @property
1026 def user_global_ns(self):
1026 def user_global_ns(self):
1027 return self.user_module.__dict__
1027 return self.user_module.__dict__
1028
1028
1029 def prepare_user_module(self, user_module=None, user_ns=None):
1029 def prepare_user_module(self, user_module=None, user_ns=None):
1030 """Prepare the module and namespace in which user code will be run.
1030 """Prepare the module and namespace in which user code will be run.
1031
1031
1032 When IPython is started normally, both parameters are None: a new module
1032 When IPython is started normally, both parameters are None: a new module
1033 is created automatically, and its __dict__ used as the namespace.
1033 is created automatically, and its __dict__ used as the namespace.
1034
1034
1035 If only user_module is provided, its __dict__ is used as the namespace.
1035 If only user_module is provided, its __dict__ is used as the namespace.
1036 If only user_ns is provided, a dummy module is created, and user_ns
1036 If only user_ns is provided, a dummy module is created, and user_ns
1037 becomes the global namespace. If both are provided (as they may be
1037 becomes the global namespace. If both are provided (as they may be
1038 when embedding), user_ns is the local namespace, and user_module
1038 when embedding), user_ns is the local namespace, and user_module
1039 provides the global namespace.
1039 provides the global namespace.
1040
1040
1041 Parameters
1041 Parameters
1042 ----------
1042 ----------
1043 user_module : module, optional
1043 user_module : module, optional
1044 The current user module in which IPython is being run. If None,
1044 The current user module in which IPython is being run. If None,
1045 a clean module will be created.
1045 a clean module will be created.
1046 user_ns : dict, optional
1046 user_ns : dict, optional
1047 A namespace in which to run interactive commands.
1047 A namespace in which to run interactive commands.
1048
1048
1049 Returns
1049 Returns
1050 -------
1050 -------
1051 A tuple of user_module and user_ns, each properly initialised.
1051 A tuple of user_module and user_ns, each properly initialised.
1052 """
1052 """
1053 if user_module is None and user_ns is not None:
1053 if user_module is None and user_ns is not None:
1054 user_ns.setdefault("__name__", "__main__")
1054 user_ns.setdefault("__name__", "__main__")
1055 class DummyMod(object):
1055 class DummyMod(object):
1056 "A dummy module used for IPython's interactive namespace."
1056 "A dummy module used for IPython's interactive namespace."
1057 pass
1057 pass
1058 user_module = DummyMod()
1058 user_module = DummyMod()
1059 user_module.__dict__ = user_ns
1059 user_module.__dict__ = user_ns
1060
1060
1061 if user_module is None:
1061 if user_module is None:
1062 user_module = types.ModuleType("__main__",
1062 user_module = types.ModuleType("__main__",
1063 doc="Automatically created module for IPython interactive environment")
1063 doc="Automatically created module for IPython interactive environment")
1064
1064
1065 # We must ensure that __builtin__ (without the final 's') is always
1065 # We must ensure that __builtin__ (without the final 's') is always
1066 # available and pointing to the __builtin__ *module*. For more details:
1066 # available and pointing to the __builtin__ *module*. For more details:
1067 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1067 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1068 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1068 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1069 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1069 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1070
1070
1071 if user_ns is None:
1071 if user_ns is None:
1072 user_ns = user_module.__dict__
1072 user_ns = user_module.__dict__
1073
1073
1074 return user_module, user_ns
1074 return user_module, user_ns
1075
1075
1076 def init_sys_modules(self):
1076 def init_sys_modules(self):
1077 # We need to insert into sys.modules something that looks like a
1077 # We need to insert into sys.modules something that looks like a
1078 # module but which accesses the IPython namespace, for shelve and
1078 # module but which accesses the IPython namespace, for shelve and
1079 # pickle to work interactively. Normally they rely on getting
1079 # pickle to work interactively. Normally they rely on getting
1080 # everything out of __main__, but for embedding purposes each IPython
1080 # everything out of __main__, but for embedding purposes each IPython
1081 # instance has its own private namespace, so we can't go shoving
1081 # instance has its own private namespace, so we can't go shoving
1082 # everything into __main__.
1082 # everything into __main__.
1083
1083
1084 # note, however, that we should only do this for non-embedded
1084 # note, however, that we should only do this for non-embedded
1085 # ipythons, which really mimic the __main__.__dict__ with their own
1085 # ipythons, which really mimic the __main__.__dict__ with their own
1086 # namespace. Embedded instances, on the other hand, should not do
1086 # namespace. Embedded instances, on the other hand, should not do
1087 # this because they need to manage the user local/global namespaces
1087 # this because they need to manage the user local/global namespaces
1088 # only, but they live within a 'normal' __main__ (meaning, they
1088 # only, but they live within a 'normal' __main__ (meaning, they
1089 # shouldn't overtake the execution environment of the script they're
1089 # shouldn't overtake the execution environment of the script they're
1090 # embedded in).
1090 # embedded in).
1091
1091
1092 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1092 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1093 main_name = self.user_module.__name__
1093 main_name = self.user_module.__name__
1094 sys.modules[main_name] = self.user_module
1094 sys.modules[main_name] = self.user_module
1095
1095
1096 def init_user_ns(self):
1096 def init_user_ns(self):
1097 """Initialize all user-visible namespaces to their minimum defaults.
1097 """Initialize all user-visible namespaces to their minimum defaults.
1098
1098
1099 Certain history lists are also initialized here, as they effectively
1099 Certain history lists are also initialized here, as they effectively
1100 act as user namespaces.
1100 act as user namespaces.
1101
1101
1102 Notes
1102 Notes
1103 -----
1103 -----
1104 All data structures here are only filled in, they are NOT reset by this
1104 All data structures here are only filled in, they are NOT reset by this
1105 method. If they were not empty before, data will simply be added to
1105 method. If they were not empty before, data will simply be added to
1106 therm.
1106 therm.
1107 """
1107 """
1108 # This function works in two parts: first we put a few things in
1108 # This function works in two parts: first we put a few things in
1109 # user_ns, and we sync that contents into user_ns_hidden so that these
1109 # user_ns, and we sync that contents into user_ns_hidden so that these
1110 # initial variables aren't shown by %who. After the sync, we add the
1110 # initial variables aren't shown by %who. After the sync, we add the
1111 # rest of what we *do* want the user to see with %who even on a new
1111 # rest of what we *do* want the user to see with %who even on a new
1112 # session (probably nothing, so theye really only see their own stuff)
1112 # session (probably nothing, so theye really only see their own stuff)
1113
1113
1114 # The user dict must *always* have a __builtin__ reference to the
1114 # The user dict must *always* have a __builtin__ reference to the
1115 # Python standard __builtin__ namespace, which must be imported.
1115 # Python standard __builtin__ namespace, which must be imported.
1116 # This is so that certain operations in prompt evaluation can be
1116 # This is so that certain operations in prompt evaluation can be
1117 # reliably executed with builtins. Note that we can NOT use
1117 # reliably executed with builtins. Note that we can NOT use
1118 # __builtins__ (note the 's'), because that can either be a dict or a
1118 # __builtins__ (note the 's'), because that can either be a dict or a
1119 # module, and can even mutate at runtime, depending on the context
1119 # module, and can even mutate at runtime, depending on the context
1120 # (Python makes no guarantees on it). In contrast, __builtin__ is
1120 # (Python makes no guarantees on it). In contrast, __builtin__ is
1121 # always a module object, though it must be explicitly imported.
1121 # always a module object, though it must be explicitly imported.
1122
1122
1123 # For more details:
1123 # For more details:
1124 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1124 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1125 ns = dict()
1125 ns = dict()
1126
1126
1127 # Put 'help' in the user namespace
1127 # Put 'help' in the user namespace
1128 try:
1128 try:
1129 from site import _Helper
1129 from site import _Helper
1130 ns['help'] = _Helper()
1130 ns['help'] = _Helper()
1131 except ImportError:
1131 except ImportError:
1132 warn('help() not available - check site.py')
1132 warn('help() not available - check site.py')
1133
1133
1134 # make global variables for user access to the histories
1134 # make global variables for user access to the histories
1135 ns['_ih'] = self.history_manager.input_hist_parsed
1135 ns['_ih'] = self.history_manager.input_hist_parsed
1136 ns['_oh'] = self.history_manager.output_hist
1136 ns['_oh'] = self.history_manager.output_hist
1137 ns['_dh'] = self.history_manager.dir_hist
1137 ns['_dh'] = self.history_manager.dir_hist
1138
1138
1139 ns['_sh'] = shadowns
1139 ns['_sh'] = shadowns
1140
1140
1141 # user aliases to input and output histories. These shouldn't show up
1141 # user aliases to input and output histories. These shouldn't show up
1142 # in %who, as they can have very large reprs.
1142 # in %who, as they can have very large reprs.
1143 ns['In'] = self.history_manager.input_hist_parsed
1143 ns['In'] = self.history_manager.input_hist_parsed
1144 ns['Out'] = self.history_manager.output_hist
1144 ns['Out'] = self.history_manager.output_hist
1145
1145
1146 # Store myself as the public api!!!
1146 # Store myself as the public api!!!
1147 ns['get_ipython'] = self.get_ipython
1147 ns['get_ipython'] = self.get_ipython
1148
1148
1149 ns['exit'] = self.exiter
1149 ns['exit'] = self.exiter
1150 ns['quit'] = self.exiter
1150 ns['quit'] = self.exiter
1151
1151
1152 # Sync what we've added so far to user_ns_hidden so these aren't seen
1152 # Sync what we've added so far to user_ns_hidden so these aren't seen
1153 # by %who
1153 # by %who
1154 self.user_ns_hidden.update(ns)
1154 self.user_ns_hidden.update(ns)
1155
1155
1156 # Anything put into ns now would show up in %who. Think twice before
1156 # Anything put into ns now would show up in %who. Think twice before
1157 # putting anything here, as we really want %who to show the user their
1157 # putting anything here, as we really want %who to show the user their
1158 # stuff, not our variables.
1158 # stuff, not our variables.
1159
1159
1160 # Finally, update the real user's namespace
1160 # Finally, update the real user's namespace
1161 self.user_ns.update(ns)
1161 self.user_ns.update(ns)
1162
1162
1163 @property
1163 @property
1164 def all_ns_refs(self):
1164 def all_ns_refs(self):
1165 """Get a list of references to all the namespace dictionaries in which
1165 """Get a list of references to all the namespace dictionaries in which
1166 IPython might store a user-created object.
1166 IPython might store a user-created object.
1167
1167
1168 Note that this does not include the displayhook, which also caches
1168 Note that this does not include the displayhook, which also caches
1169 objects from the output."""
1169 objects from the output."""
1170 return [self.user_ns, self.user_global_ns,
1170 return [self.user_ns, self.user_global_ns,
1171 self._user_main_module.__dict__] + self._main_ns_cache.values()
1171 self._user_main_module.__dict__] + self._main_ns_cache.values()
1172
1172
1173 def reset(self, new_session=True):
1173 def reset(self, new_session=True):
1174 """Clear all internal namespaces, and attempt to release references to
1174 """Clear all internal namespaces, and attempt to release references to
1175 user objects.
1175 user objects.
1176
1176
1177 If new_session is True, a new history session will be opened.
1177 If new_session is True, a new history session will be opened.
1178 """
1178 """
1179 # Clear histories
1179 # Clear histories
1180 self.history_manager.reset(new_session)
1180 self.history_manager.reset(new_session)
1181 # Reset counter used to index all histories
1181 # Reset counter used to index all histories
1182 if new_session:
1182 if new_session:
1183 self.execution_count = 1
1183 self.execution_count = 1
1184
1184
1185 # Flush cached output items
1185 # Flush cached output items
1186 if self.displayhook.do_full_cache:
1186 if self.displayhook.do_full_cache:
1187 self.displayhook.flush()
1187 self.displayhook.flush()
1188
1188
1189 # The main execution namespaces must be cleared very carefully,
1189 # The main execution namespaces must be cleared very carefully,
1190 # skipping the deletion of the builtin-related keys, because doing so
1190 # skipping the deletion of the builtin-related keys, because doing so
1191 # would cause errors in many object's __del__ methods.
1191 # would cause errors in many object's __del__ methods.
1192 if self.user_ns is not self.user_global_ns:
1192 if self.user_ns is not self.user_global_ns:
1193 self.user_ns.clear()
1193 self.user_ns.clear()
1194 ns = self.user_global_ns
1194 ns = self.user_global_ns
1195 drop_keys = set(ns.keys())
1195 drop_keys = set(ns.keys())
1196 drop_keys.discard('__builtin__')
1196 drop_keys.discard('__builtin__')
1197 drop_keys.discard('__builtins__')
1197 drop_keys.discard('__builtins__')
1198 drop_keys.discard('__name__')
1198 drop_keys.discard('__name__')
1199 for k in drop_keys:
1199 for k in drop_keys:
1200 del ns[k]
1200 del ns[k]
1201
1201
1202 self.user_ns_hidden.clear()
1202 self.user_ns_hidden.clear()
1203
1203
1204 # Restore the user namespaces to minimal usability
1204 # Restore the user namespaces to minimal usability
1205 self.init_user_ns()
1205 self.init_user_ns()
1206
1206
1207 # Restore the default and user aliases
1207 # Restore the default and user aliases
1208 self.alias_manager.clear_aliases()
1208 self.alias_manager.clear_aliases()
1209 self.alias_manager.init_aliases()
1209 self.alias_manager.init_aliases()
1210
1210
1211 # Flush the private list of module references kept for script
1211 # Flush the private list of module references kept for script
1212 # execution protection
1212 # execution protection
1213 self.clear_main_mod_cache()
1213 self.clear_main_mod_cache()
1214
1214
1215 # Clear out the namespace from the last %run
1215 # Clear out the namespace from the last %run
1216 self.new_main_mod()
1216 self.new_main_mod()
1217
1217
1218 def del_var(self, varname, by_name=False):
1218 def del_var(self, varname, by_name=False):
1219 """Delete a variable from the various namespaces, so that, as
1219 """Delete a variable from the various namespaces, so that, as
1220 far as possible, we're not keeping any hidden references to it.
1220 far as possible, we're not keeping any hidden references to it.
1221
1221
1222 Parameters
1222 Parameters
1223 ----------
1223 ----------
1224 varname : str
1224 varname : str
1225 The name of the variable to delete.
1225 The name of the variable to delete.
1226 by_name : bool
1226 by_name : bool
1227 If True, delete variables with the given name in each
1227 If True, delete variables with the given name in each
1228 namespace. If False (default), find the variable in the user
1228 namespace. If False (default), find the variable in the user
1229 namespace, and delete references to it.
1229 namespace, and delete references to it.
1230 """
1230 """
1231 if varname in ('__builtin__', '__builtins__'):
1231 if varname in ('__builtin__', '__builtins__'):
1232 raise ValueError("Refusing to delete %s" % varname)
1232 raise ValueError("Refusing to delete %s" % varname)
1233
1233
1234 ns_refs = self.all_ns_refs
1234 ns_refs = self.all_ns_refs
1235
1235
1236 if by_name: # Delete by name
1236 if by_name: # Delete by name
1237 for ns in ns_refs:
1237 for ns in ns_refs:
1238 try:
1238 try:
1239 del ns[varname]
1239 del ns[varname]
1240 except KeyError:
1240 except KeyError:
1241 pass
1241 pass
1242 else: # Delete by object
1242 else: # Delete by object
1243 try:
1243 try:
1244 obj = self.user_ns[varname]
1244 obj = self.user_ns[varname]
1245 except KeyError:
1245 except KeyError:
1246 raise NameError("name '%s' is not defined" % varname)
1246 raise NameError("name '%s' is not defined" % varname)
1247 # Also check in output history
1247 # Also check in output history
1248 ns_refs.append(self.history_manager.output_hist)
1248 ns_refs.append(self.history_manager.output_hist)
1249 for ns in ns_refs:
1249 for ns in ns_refs:
1250 to_delete = [n for n, o in ns.iteritems() if o is obj]
1250 to_delete = [n for n, o in ns.iteritems() if o is obj]
1251 for name in to_delete:
1251 for name in to_delete:
1252 del ns[name]
1252 del ns[name]
1253
1253
1254 # displayhook keeps extra references, but not in a dictionary
1254 # displayhook keeps extra references, but not in a dictionary
1255 for name in ('_', '__', '___'):
1255 for name in ('_', '__', '___'):
1256 if getattr(self.displayhook, name) is obj:
1256 if getattr(self.displayhook, name) is obj:
1257 setattr(self.displayhook, name, None)
1257 setattr(self.displayhook, name, None)
1258
1258
1259 def reset_selective(self, regex=None):
1259 def reset_selective(self, regex=None):
1260 """Clear selective variables from internal namespaces based on a
1260 """Clear selective variables from internal namespaces based on a
1261 specified regular expression.
1261 specified regular expression.
1262
1262
1263 Parameters
1263 Parameters
1264 ----------
1264 ----------
1265 regex : string or compiled pattern, optional
1265 regex : string or compiled pattern, optional
1266 A regular expression pattern that will be used in searching
1266 A regular expression pattern that will be used in searching
1267 variable names in the users namespaces.
1267 variable names in the users namespaces.
1268 """
1268 """
1269 if regex is not None:
1269 if regex is not None:
1270 try:
1270 try:
1271 m = re.compile(regex)
1271 m = re.compile(regex)
1272 except TypeError:
1272 except TypeError:
1273 raise TypeError('regex must be a string or compiled pattern')
1273 raise TypeError('regex must be a string or compiled pattern')
1274 # Search for keys in each namespace that match the given regex
1274 # Search for keys in each namespace that match the given regex
1275 # If a match is found, delete the key/value pair.
1275 # If a match is found, delete the key/value pair.
1276 for ns in self.all_ns_refs:
1276 for ns in self.all_ns_refs:
1277 for var in ns:
1277 for var in ns:
1278 if m.search(var):
1278 if m.search(var):
1279 del ns[var]
1279 del ns[var]
1280
1280
1281 def push(self, variables, interactive=True):
1281 def push(self, variables, interactive=True):
1282 """Inject a group of variables into the IPython user namespace.
1282 """Inject a group of variables into the IPython user namespace.
1283
1283
1284 Parameters
1284 Parameters
1285 ----------
1285 ----------
1286 variables : dict, str or list/tuple of str
1286 variables : dict, str or list/tuple of str
1287 The variables to inject into the user's namespace. If a dict, a
1287 The variables to inject into the user's namespace. If a dict, a
1288 simple update is done. If a str, the string is assumed to have
1288 simple update is done. If a str, the string is assumed to have
1289 variable names separated by spaces. A list/tuple of str can also
1289 variable names separated by spaces. A list/tuple of str can also
1290 be used to give the variable names. If just the variable names are
1290 be used to give the variable names. If just the variable names are
1291 give (list/tuple/str) then the variable values looked up in the
1291 give (list/tuple/str) then the variable values looked up in the
1292 callers frame.
1292 callers frame.
1293 interactive : bool
1293 interactive : bool
1294 If True (default), the variables will be listed with the ``who``
1294 If True (default), the variables will be listed with the ``who``
1295 magic.
1295 magic.
1296 """
1296 """
1297 vdict = None
1297 vdict = None
1298
1298
1299 # We need a dict of name/value pairs to do namespace updates.
1299 # We need a dict of name/value pairs to do namespace updates.
1300 if isinstance(variables, dict):
1300 if isinstance(variables, dict):
1301 vdict = variables
1301 vdict = variables
1302 elif isinstance(variables, (basestring, list, tuple)):
1302 elif isinstance(variables, (basestring, list, tuple)):
1303 if isinstance(variables, basestring):
1303 if isinstance(variables, basestring):
1304 vlist = variables.split()
1304 vlist = variables.split()
1305 else:
1305 else:
1306 vlist = variables
1306 vlist = variables
1307 vdict = {}
1307 vdict = {}
1308 cf = sys._getframe(1)
1308 cf = sys._getframe(1)
1309 for name in vlist:
1309 for name in vlist:
1310 try:
1310 try:
1311 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1311 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1312 except:
1312 except:
1313 print('Could not get variable %s from %s' %
1313 print('Could not get variable %s from %s' %
1314 (name,cf.f_code.co_name))
1314 (name,cf.f_code.co_name))
1315 else:
1315 else:
1316 raise ValueError('variables must be a dict/str/list/tuple')
1316 raise ValueError('variables must be a dict/str/list/tuple')
1317
1317
1318 # Propagate variables to user namespace
1318 # Propagate variables to user namespace
1319 self.user_ns.update(vdict)
1319 self.user_ns.update(vdict)
1320
1320
1321 # And configure interactive visibility
1321 # And configure interactive visibility
1322 user_ns_hidden = self.user_ns_hidden
1322 user_ns_hidden = self.user_ns_hidden
1323 if interactive:
1323 if interactive:
1324 user_ns_hidden.difference_update(vdict)
1324 user_ns_hidden.difference_update(vdict)
1325 else:
1325 else:
1326 user_ns_hidden.update(vdict)
1326 user_ns_hidden.update(vdict)
1327
1327
1328 def drop_by_id(self, variables):
1328 def drop_by_id(self, variables):
1329 """Remove a dict of variables from the user namespace, if they are the
1329 """Remove a dict of variables from the user namespace, if they are the
1330 same as the values in the dictionary.
1330 same as the values in the dictionary.
1331
1331
1332 This is intended for use by extensions: variables that they've added can
1332 This is intended for use by extensions: variables that they've added can
1333 be taken back out if they are unloaded, without removing any that the
1333 be taken back out if they are unloaded, without removing any that the
1334 user has overwritten.
1334 user has overwritten.
1335
1335
1336 Parameters
1336 Parameters
1337 ----------
1337 ----------
1338 variables : dict
1338 variables : dict
1339 A dictionary mapping object names (as strings) to the objects.
1339 A dictionary mapping object names (as strings) to the objects.
1340 """
1340 """
1341 for name, obj in variables.iteritems():
1341 for name, obj in variables.iteritems():
1342 if name in self.user_ns and self.user_ns[name] is obj:
1342 if name in self.user_ns and self.user_ns[name] is obj:
1343 del self.user_ns[name]
1343 del self.user_ns[name]
1344 self.user_ns_hidden.discard(name)
1344 self.user_ns_hidden.discard(name)
1345
1345
1346 #-------------------------------------------------------------------------
1346 #-------------------------------------------------------------------------
1347 # Things related to object introspection
1347 # Things related to object introspection
1348 #-------------------------------------------------------------------------
1348 #-------------------------------------------------------------------------
1349
1349
1350 def _ofind(self, oname, namespaces=None):
1350 def _ofind(self, oname, namespaces=None):
1351 """Find an object in the available namespaces.
1351 """Find an object in the available namespaces.
1352
1352
1353 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1353 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1354
1354
1355 Has special code to detect magic functions.
1355 Has special code to detect magic functions.
1356 """
1356 """
1357 oname = oname.strip()
1357 oname = oname.strip()
1358 #print '1- oname: <%r>' % oname # dbg
1358 #print '1- oname: <%r>' % oname # dbg
1359 if not oname.startswith(ESC_MAGIC) and \
1359 if not oname.startswith(ESC_MAGIC) and \
1360 not oname.startswith(ESC_MAGIC2) and \
1360 not oname.startswith(ESC_MAGIC2) and \
1361 not py3compat.isidentifier(oname, dotted=True):
1361 not py3compat.isidentifier(oname, dotted=True):
1362 return dict(found=False)
1362 return dict(found=False)
1363
1363
1364 alias_ns = None
1364 alias_ns = None
1365 if namespaces is None:
1365 if namespaces is None:
1366 # Namespaces to search in:
1366 # Namespaces to search in:
1367 # Put them in a list. The order is important so that we
1367 # Put them in a list. The order is important so that we
1368 # find things in the same order that Python finds them.
1368 # find things in the same order that Python finds them.
1369 namespaces = [ ('Interactive', self.user_ns),
1369 namespaces = [ ('Interactive', self.user_ns),
1370 ('Interactive (global)', self.user_global_ns),
1370 ('Interactive (global)', self.user_global_ns),
1371 ('Python builtin', builtin_mod.__dict__),
1371 ('Python builtin', builtin_mod.__dict__),
1372 ('Alias', self.alias_manager.alias_table),
1372 ('Alias', self.alias_manager.alias_table),
1373 ]
1373 ]
1374 alias_ns = self.alias_manager.alias_table
1374 alias_ns = self.alias_manager.alias_table
1375
1375
1376 # initialize results to 'null'
1376 # initialize results to 'null'
1377 found = False; obj = None; ospace = None; ds = None;
1377 found = False; obj = None; ospace = None; ds = None;
1378 ismagic = False; isalias = False; parent = None
1378 ismagic = False; isalias = False; parent = None
1379
1379
1380 # We need to special-case 'print', which as of python2.6 registers as a
1380 # We need to special-case 'print', which as of python2.6 registers as a
1381 # function but should only be treated as one if print_function was
1381 # function but should only be treated as one if print_function was
1382 # loaded with a future import. In this case, just bail.
1382 # loaded with a future import. In this case, just bail.
1383 if (oname == 'print' and not py3compat.PY3 and not \
1383 if (oname == 'print' and not py3compat.PY3 and not \
1384 (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)):
1384 (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)):
1385 return {'found':found, 'obj':obj, 'namespace':ospace,
1385 return {'found':found, 'obj':obj, 'namespace':ospace,
1386 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1386 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1387
1387
1388 # Look for the given name by splitting it in parts. If the head is
1388 # Look for the given name by splitting it in parts. If the head is
1389 # found, then we look for all the remaining parts as members, and only
1389 # found, then we look for all the remaining parts as members, and only
1390 # declare success if we can find them all.
1390 # declare success if we can find them all.
1391 oname_parts = oname.split('.')
1391 oname_parts = oname.split('.')
1392 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1392 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1393 for nsname,ns in namespaces:
1393 for nsname,ns in namespaces:
1394 try:
1394 try:
1395 obj = ns[oname_head]
1395 obj = ns[oname_head]
1396 except KeyError:
1396 except KeyError:
1397 continue
1397 continue
1398 else:
1398 else:
1399 #print 'oname_rest:', oname_rest # dbg
1399 #print 'oname_rest:', oname_rest # dbg
1400 for part in oname_rest:
1400 for part in oname_rest:
1401 try:
1401 try:
1402 parent = obj
1402 parent = obj
1403 obj = getattr(obj,part)
1403 obj = getattr(obj,part)
1404 except:
1404 except:
1405 # Blanket except b/c some badly implemented objects
1405 # Blanket except b/c some badly implemented objects
1406 # allow __getattr__ to raise exceptions other than
1406 # allow __getattr__ to raise exceptions other than
1407 # AttributeError, which then crashes IPython.
1407 # AttributeError, which then crashes IPython.
1408 break
1408 break
1409 else:
1409 else:
1410 # If we finish the for loop (no break), we got all members
1410 # If we finish the for loop (no break), we got all members
1411 found = True
1411 found = True
1412 ospace = nsname
1412 ospace = nsname
1413 if ns == alias_ns:
1413 if ns == alias_ns:
1414 isalias = True
1414 isalias = True
1415 break # namespace loop
1415 break # namespace loop
1416
1416
1417 # Try to see if it's magic
1417 # Try to see if it's magic
1418 if not found:
1418 if not found:
1419 obj = None
1419 obj = None
1420 if oname.startswith(ESC_MAGIC2):
1420 if oname.startswith(ESC_MAGIC2):
1421 oname = oname.lstrip(ESC_MAGIC2)
1421 oname = oname.lstrip(ESC_MAGIC2)
1422 obj = self.find_cell_magic(oname)
1422 obj = self.find_cell_magic(oname)
1423 elif oname.startswith(ESC_MAGIC):
1423 elif oname.startswith(ESC_MAGIC):
1424 oname = oname.lstrip(ESC_MAGIC)
1424 oname = oname.lstrip(ESC_MAGIC)
1425 obj = self.find_line_magic(oname)
1425 obj = self.find_line_magic(oname)
1426 else:
1426 else:
1427 # search without prefix, so run? will find %run?
1427 # search without prefix, so run? will find %run?
1428 obj = self.find_line_magic(oname)
1428 obj = self.find_line_magic(oname)
1429 if obj is None:
1429 if obj is None:
1430 obj = self.find_cell_magic(oname)
1430 obj = self.find_cell_magic(oname)
1431 if obj is not None:
1431 if obj is not None:
1432 found = True
1432 found = True
1433 ospace = 'IPython internal'
1433 ospace = 'IPython internal'
1434 ismagic = True
1434 ismagic = True
1435
1435
1436 # Last try: special-case some literals like '', [], {}, etc:
1436 # Last try: special-case some literals like '', [], {}, etc:
1437 if not found and oname_head in ["''",'""','[]','{}','()']:
1437 if not found and oname_head in ["''",'""','[]','{}','()']:
1438 obj = eval(oname_head)
1438 obj = eval(oname_head)
1439 found = True
1439 found = True
1440 ospace = 'Interactive'
1440 ospace = 'Interactive'
1441
1441
1442 return {'found':found, 'obj':obj, 'namespace':ospace,
1442 return {'found':found, 'obj':obj, 'namespace':ospace,
1443 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1443 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1444
1444
1445 def _ofind_property(self, oname, info):
1445 def _ofind_property(self, oname, info):
1446 """Second part of object finding, to look for property details."""
1446 """Second part of object finding, to look for property details."""
1447 if info.found:
1447 if info.found:
1448 # Get the docstring of the class property if it exists.
1448 # Get the docstring of the class property if it exists.
1449 path = oname.split('.')
1449 path = oname.split('.')
1450 root = '.'.join(path[:-1])
1450 root = '.'.join(path[:-1])
1451 if info.parent is not None:
1451 if info.parent is not None:
1452 try:
1452 try:
1453 target = getattr(info.parent, '__class__')
1453 target = getattr(info.parent, '__class__')
1454 # The object belongs to a class instance.
1454 # The object belongs to a class instance.
1455 try:
1455 try:
1456 target = getattr(target, path[-1])
1456 target = getattr(target, path[-1])
1457 # The class defines the object.
1457 # The class defines the object.
1458 if isinstance(target, property):
1458 if isinstance(target, property):
1459 oname = root + '.__class__.' + path[-1]
1459 oname = root + '.__class__.' + path[-1]
1460 info = Struct(self._ofind(oname))
1460 info = Struct(self._ofind(oname))
1461 except AttributeError: pass
1461 except AttributeError: pass
1462 except AttributeError: pass
1462 except AttributeError: pass
1463
1463
1464 # We return either the new info or the unmodified input if the object
1464 # We return either the new info or the unmodified input if the object
1465 # hadn't been found
1465 # hadn't been found
1466 return info
1466 return info
1467
1467
1468 def _object_find(self, oname, namespaces=None):
1468 def _object_find(self, oname, namespaces=None):
1469 """Find an object and return a struct with info about it."""
1469 """Find an object and return a struct with info about it."""
1470 inf = Struct(self._ofind(oname, namespaces))
1470 inf = Struct(self._ofind(oname, namespaces))
1471 return Struct(self._ofind_property(oname, inf))
1471 return Struct(self._ofind_property(oname, inf))
1472
1472
1473 def _inspect(self, meth, oname, namespaces=None, **kw):
1473 def _inspect(self, meth, oname, namespaces=None, **kw):
1474 """Generic interface to the inspector system.
1474 """Generic interface to the inspector system.
1475
1475
1476 This function is meant to be called by pdef, pdoc & friends."""
1476 This function is meant to be called by pdef, pdoc & friends."""
1477 info = self._object_find(oname, namespaces)
1477 info = self._object_find(oname, namespaces)
1478 if info.found:
1478 if info.found:
1479 pmethod = getattr(self.inspector, meth)
1479 pmethod = getattr(self.inspector, meth)
1480 formatter = format_screen if info.ismagic else None
1480 formatter = format_screen if info.ismagic else None
1481 if meth == 'pdoc':
1481 if meth == 'pdoc':
1482 pmethod(info.obj, oname, formatter)
1482 pmethod(info.obj, oname, formatter)
1483 elif meth == 'pinfo':
1483 elif meth == 'pinfo':
1484 pmethod(info.obj, oname, formatter, info, **kw)
1484 pmethod(info.obj, oname, formatter, info, **kw)
1485 else:
1485 else:
1486 pmethod(info.obj, oname)
1486 pmethod(info.obj, oname)
1487 else:
1487 else:
1488 print('Object `%s` not found.' % oname)
1488 print('Object `%s` not found.' % oname)
1489 return 'not found' # so callers can take other action
1489 return 'not found' # so callers can take other action
1490
1490
1491 def object_inspect(self, oname, detail_level=0):
1491 def object_inspect(self, oname, detail_level=0):
1492 with self.builtin_trap:
1492 with self.builtin_trap:
1493 info = self._object_find(oname)
1493 info = self._object_find(oname)
1494 if info.found:
1494 if info.found:
1495 return self.inspector.info(info.obj, oname, info=info,
1495 return self.inspector.info(info.obj, oname, info=info,
1496 detail_level=detail_level
1496 detail_level=detail_level
1497 )
1497 )
1498 else:
1498 else:
1499 return oinspect.object_info(name=oname, found=False)
1499 return oinspect.object_info(name=oname, found=False)
1500
1500
1501 #-------------------------------------------------------------------------
1501 #-------------------------------------------------------------------------
1502 # Things related to history management
1502 # Things related to history management
1503 #-------------------------------------------------------------------------
1503 #-------------------------------------------------------------------------
1504
1504
1505 def init_history(self):
1505 def init_history(self):
1506 """Sets up the command history, and starts regular autosaves."""
1506 """Sets up the command history, and starts regular autosaves."""
1507 self.history_manager = HistoryManager(shell=self, config=self.config)
1507 self.history_manager = HistoryManager(shell=self, config=self.config)
1508 self.configurables.append(self.history_manager)
1508 self.configurables.append(self.history_manager)
1509
1509
1510 #-------------------------------------------------------------------------
1510 #-------------------------------------------------------------------------
1511 # Things related to exception handling and tracebacks (not debugging)
1511 # Things related to exception handling and tracebacks (not debugging)
1512 #-------------------------------------------------------------------------
1512 #-------------------------------------------------------------------------
1513
1513
1514 def init_traceback_handlers(self, custom_exceptions):
1514 def init_traceback_handlers(self, custom_exceptions):
1515 # Syntax error handler.
1515 # Syntax error handler.
1516 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1516 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1517
1517
1518 # The interactive one is initialized with an offset, meaning we always
1518 # The interactive one is initialized with an offset, meaning we always
1519 # want to remove the topmost item in the traceback, which is our own
1519 # want to remove the topmost item in the traceback, which is our own
1520 # internal code. Valid modes: ['Plain','Context','Verbose']
1520 # internal code. Valid modes: ['Plain','Context','Verbose']
1521 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1521 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1522 color_scheme='NoColor',
1522 color_scheme='NoColor',
1523 tb_offset = 1,
1523 tb_offset = 1,
1524 check_cache=self.compile.check_cache)
1524 check_cache=self.compile.check_cache)
1525
1525
1526 # The instance will store a pointer to the system-wide exception hook,
1526 # The instance will store a pointer to the system-wide exception hook,
1527 # so that runtime code (such as magics) can access it. This is because
1527 # so that runtime code (such as magics) can access it. This is because
1528 # during the read-eval loop, it may get temporarily overwritten.
1528 # during the read-eval loop, it may get temporarily overwritten.
1529 self.sys_excepthook = sys.excepthook
1529 self.sys_excepthook = sys.excepthook
1530
1530
1531 # and add any custom exception handlers the user may have specified
1531 # and add any custom exception handlers the user may have specified
1532 self.set_custom_exc(*custom_exceptions)
1532 self.set_custom_exc(*custom_exceptions)
1533
1533
1534 # Set the exception mode
1534 # Set the exception mode
1535 self.InteractiveTB.set_mode(mode=self.xmode)
1535 self.InteractiveTB.set_mode(mode=self.xmode)
1536
1536
1537 def set_custom_exc(self, exc_tuple, handler):
1537 def set_custom_exc(self, exc_tuple, handler):
1538 """set_custom_exc(exc_tuple,handler)
1538 """set_custom_exc(exc_tuple,handler)
1539
1539
1540 Set a custom exception handler, which will be called if any of the
1540 Set a custom exception handler, which will be called if any of the
1541 exceptions in exc_tuple occur in the mainloop (specifically, in the
1541 exceptions in exc_tuple occur in the mainloop (specifically, in the
1542 run_code() method).
1542 run_code() method).
1543
1543
1544 Parameters
1544 Parameters
1545 ----------
1545 ----------
1546
1546
1547 exc_tuple : tuple of exception classes
1547 exc_tuple : tuple of exception classes
1548 A *tuple* of exception classes, for which to call the defined
1548 A *tuple* of exception classes, for which to call the defined
1549 handler. It is very important that you use a tuple, and NOT A
1549 handler. It is very important that you use a tuple, and NOT A
1550 LIST here, because of the way Python's except statement works. If
1550 LIST here, because of the way Python's except statement works. If
1551 you only want to trap a single exception, use a singleton tuple::
1551 you only want to trap a single exception, use a singleton tuple::
1552
1552
1553 exc_tuple == (MyCustomException,)
1553 exc_tuple == (MyCustomException,)
1554
1554
1555 handler : callable
1555 handler : callable
1556 handler must have the following signature::
1556 handler must have the following signature::
1557
1557
1558 def my_handler(self, etype, value, tb, tb_offset=None):
1558 def my_handler(self, etype, value, tb, tb_offset=None):
1559 ...
1559 ...
1560 return structured_traceback
1560 return structured_traceback
1561
1561
1562 Your handler must return a structured traceback (a list of strings),
1562 Your handler must return a structured traceback (a list of strings),
1563 or None.
1563 or None.
1564
1564
1565 This will be made into an instance method (via types.MethodType)
1565 This will be made into an instance method (via types.MethodType)
1566 of IPython itself, and it will be called if any of the exceptions
1566 of IPython itself, and it will be called if any of the exceptions
1567 listed in the exc_tuple are caught. If the handler is None, an
1567 listed in the exc_tuple are caught. If the handler is None, an
1568 internal basic one is used, which just prints basic info.
1568 internal basic one is used, which just prints basic info.
1569
1569
1570 To protect IPython from crashes, if your handler ever raises an
1570 To protect IPython from crashes, if your handler ever raises an
1571 exception or returns an invalid result, it will be immediately
1571 exception or returns an invalid result, it will be immediately
1572 disabled.
1572 disabled.
1573
1573
1574 WARNING: by putting in your own exception handler into IPython's main
1574 WARNING: by putting in your own exception handler into IPython's main
1575 execution loop, you run a very good chance of nasty crashes. This
1575 execution loop, you run a very good chance of nasty crashes. This
1576 facility should only be used if you really know what you are doing."""
1576 facility should only be used if you really know what you are doing."""
1577
1577
1578 assert type(exc_tuple)==type(()) , \
1578 assert type(exc_tuple)==type(()) , \
1579 "The custom exceptions must be given AS A TUPLE."
1579 "The custom exceptions must be given AS A TUPLE."
1580
1580
1581 def dummy_handler(self,etype,value,tb,tb_offset=None):
1581 def dummy_handler(self,etype,value,tb,tb_offset=None):
1582 print('*** Simple custom exception handler ***')
1582 print('*** Simple custom exception handler ***')
1583 print('Exception type :',etype)
1583 print('Exception type :',etype)
1584 print('Exception value:',value)
1584 print('Exception value:',value)
1585 print('Traceback :',tb)
1585 print('Traceback :',tb)
1586 #print 'Source code :','\n'.join(self.buffer)
1586 #print 'Source code :','\n'.join(self.buffer)
1587
1587
1588 def validate_stb(stb):
1588 def validate_stb(stb):
1589 """validate structured traceback return type
1589 """validate structured traceback return type
1590
1590
1591 return type of CustomTB *should* be a list of strings, but allow
1591 return type of CustomTB *should* be a list of strings, but allow
1592 single strings or None, which are harmless.
1592 single strings or None, which are harmless.
1593
1593
1594 This function will *always* return a list of strings,
1594 This function will *always* return a list of strings,
1595 and will raise a TypeError if stb is inappropriate.
1595 and will raise a TypeError if stb is inappropriate.
1596 """
1596 """
1597 msg = "CustomTB must return list of strings, not %r" % stb
1597 msg = "CustomTB must return list of strings, not %r" % stb
1598 if stb is None:
1598 if stb is None:
1599 return []
1599 return []
1600 elif isinstance(stb, basestring):
1600 elif isinstance(stb, basestring):
1601 return [stb]
1601 return [stb]
1602 elif not isinstance(stb, list):
1602 elif not isinstance(stb, list):
1603 raise TypeError(msg)
1603 raise TypeError(msg)
1604 # it's a list
1604 # it's a list
1605 for line in stb:
1605 for line in stb:
1606 # check every element
1606 # check every element
1607 if not isinstance(line, basestring):
1607 if not isinstance(line, basestring):
1608 raise TypeError(msg)
1608 raise TypeError(msg)
1609 return stb
1609 return stb
1610
1610
1611 if handler is None:
1611 if handler is None:
1612 wrapped = dummy_handler
1612 wrapped = dummy_handler
1613 else:
1613 else:
1614 def wrapped(self,etype,value,tb,tb_offset=None):
1614 def wrapped(self,etype,value,tb,tb_offset=None):
1615 """wrap CustomTB handler, to protect IPython from user code
1615 """wrap CustomTB handler, to protect IPython from user code
1616
1616
1617 This makes it harder (but not impossible) for custom exception
1617 This makes it harder (but not impossible) for custom exception
1618 handlers to crash IPython.
1618 handlers to crash IPython.
1619 """
1619 """
1620 try:
1620 try:
1621 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1621 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1622 return validate_stb(stb)
1622 return validate_stb(stb)
1623 except:
1623 except:
1624 # clear custom handler immediately
1624 # clear custom handler immediately
1625 self.set_custom_exc((), None)
1625 self.set_custom_exc((), None)
1626 print("Custom TB Handler failed, unregistering", file=io.stderr)
1626 print("Custom TB Handler failed, unregistering", file=io.stderr)
1627 # show the exception in handler first
1627 # show the exception in handler first
1628 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1628 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1629 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1629 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1630 print("The original exception:", file=io.stdout)
1630 print("The original exception:", file=io.stdout)
1631 stb = self.InteractiveTB.structured_traceback(
1631 stb = self.InteractiveTB.structured_traceback(
1632 (etype,value,tb), tb_offset=tb_offset
1632 (etype,value,tb), tb_offset=tb_offset
1633 )
1633 )
1634 return stb
1634 return stb
1635
1635
1636 self.CustomTB = types.MethodType(wrapped,self)
1636 self.CustomTB = types.MethodType(wrapped,self)
1637 self.custom_exceptions = exc_tuple
1637 self.custom_exceptions = exc_tuple
1638
1638
1639 def excepthook(self, etype, value, tb):
1639 def excepthook(self, etype, value, tb):
1640 """One more defense for GUI apps that call sys.excepthook.
1640 """One more defense for GUI apps that call sys.excepthook.
1641
1641
1642 GUI frameworks like wxPython trap exceptions and call
1642 GUI frameworks like wxPython trap exceptions and call
1643 sys.excepthook themselves. I guess this is a feature that
1643 sys.excepthook themselves. I guess this is a feature that
1644 enables them to keep running after exceptions that would
1644 enables them to keep running after exceptions that would
1645 otherwise kill their mainloop. This is a bother for IPython
1645 otherwise kill their mainloop. This is a bother for IPython
1646 which excepts to catch all of the program exceptions with a try:
1646 which excepts to catch all of the program exceptions with a try:
1647 except: statement.
1647 except: statement.
1648
1648
1649 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1649 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1650 any app directly invokes sys.excepthook, it will look to the user like
1650 any app directly invokes sys.excepthook, it will look to the user like
1651 IPython crashed. In order to work around this, we can disable the
1651 IPython crashed. In order to work around this, we can disable the
1652 CrashHandler and replace it with this excepthook instead, which prints a
1652 CrashHandler and replace it with this excepthook instead, which prints a
1653 regular traceback using our InteractiveTB. In this fashion, apps which
1653 regular traceback using our InteractiveTB. In this fashion, apps which
1654 call sys.excepthook will generate a regular-looking exception from
1654 call sys.excepthook will generate a regular-looking exception from
1655 IPython, and the CrashHandler will only be triggered by real IPython
1655 IPython, and the CrashHandler will only be triggered by real IPython
1656 crashes.
1656 crashes.
1657
1657
1658 This hook should be used sparingly, only in places which are not likely
1658 This hook should be used sparingly, only in places which are not likely
1659 to be true IPython errors.
1659 to be true IPython errors.
1660 """
1660 """
1661 self.showtraceback((etype,value,tb),tb_offset=0)
1661 self.showtraceback((etype,value,tb),tb_offset=0)
1662
1662
1663 def _get_exc_info(self, exc_tuple=None):
1663 def _get_exc_info(self, exc_tuple=None):
1664 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1664 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1665
1665
1666 Ensures sys.last_type,value,traceback hold the exc_info we found,
1666 Ensures sys.last_type,value,traceback hold the exc_info we found,
1667 from whichever source.
1667 from whichever source.
1668
1668
1669 raises ValueError if none of these contain any information
1669 raises ValueError if none of these contain any information
1670 """
1670 """
1671 if exc_tuple is None:
1671 if exc_tuple is None:
1672 etype, value, tb = sys.exc_info()
1672 etype, value, tb = sys.exc_info()
1673 else:
1673 else:
1674 etype, value, tb = exc_tuple
1674 etype, value, tb = exc_tuple
1675
1675
1676 if etype is None:
1676 if etype is None:
1677 if hasattr(sys, 'last_type'):
1677 if hasattr(sys, 'last_type'):
1678 etype, value, tb = sys.last_type, sys.last_value, \
1678 etype, value, tb = sys.last_type, sys.last_value, \
1679 sys.last_traceback
1679 sys.last_traceback
1680
1680
1681 if etype is None:
1681 if etype is None:
1682 raise ValueError("No exception to find")
1682 raise ValueError("No exception to find")
1683
1683
1684 # Now store the exception info in sys.last_type etc.
1684 # Now store the exception info in sys.last_type etc.
1685 # WARNING: these variables are somewhat deprecated and not
1685 # WARNING: these variables are somewhat deprecated and not
1686 # necessarily safe to use in a threaded environment, but tools
1686 # necessarily safe to use in a threaded environment, but tools
1687 # like pdb depend on their existence, so let's set them. If we
1687 # like pdb depend on their existence, so let's set them. If we
1688 # find problems in the field, we'll need to revisit their use.
1688 # find problems in the field, we'll need to revisit their use.
1689 sys.last_type = etype
1689 sys.last_type = etype
1690 sys.last_value = value
1690 sys.last_value = value
1691 sys.last_traceback = tb
1691 sys.last_traceback = tb
1692
1692
1693 return etype, value, tb
1693 return etype, value, tb
1694
1694
1695
1695
1696 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1696 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1697 exception_only=False):
1697 exception_only=False):
1698 """Display the exception that just occurred.
1698 """Display the exception that just occurred.
1699
1699
1700 If nothing is known about the exception, this is the method which
1700 If nothing is known about the exception, this is the method which
1701 should be used throughout the code for presenting user tracebacks,
1701 should be used throughout the code for presenting user tracebacks,
1702 rather than directly invoking the InteractiveTB object.
1702 rather than directly invoking the InteractiveTB object.
1703
1703
1704 A specific showsyntaxerror() also exists, but this method can take
1704 A specific showsyntaxerror() also exists, but this method can take
1705 care of calling it if needed, so unless you are explicitly catching a
1705 care of calling it if needed, so unless you are explicitly catching a
1706 SyntaxError exception, don't try to analyze the stack manually and
1706 SyntaxError exception, don't try to analyze the stack manually and
1707 simply call this method."""
1707 simply call this method."""
1708
1708
1709 try:
1709 try:
1710 try:
1710 try:
1711 etype, value, tb = self._get_exc_info(exc_tuple)
1711 etype, value, tb = self._get_exc_info(exc_tuple)
1712 except ValueError:
1712 except ValueError:
1713 self.write_err('No traceback available to show.\n')
1713 self.write_err('No traceback available to show.\n')
1714 return
1714 return
1715
1715
1716 if issubclass(etype, SyntaxError):
1716 if issubclass(etype, SyntaxError):
1717 # Though this won't be called by syntax errors in the input
1717 # Though this won't be called by syntax errors in the input
1718 # line, there may be SyntaxError cases with imported code.
1718 # line, there may be SyntaxError cases with imported code.
1719 self.showsyntaxerror(filename)
1719 self.showsyntaxerror(filename)
1720 elif etype is UsageError:
1720 elif etype is UsageError:
1721 self.write_err("UsageError: %s" % value)
1721 self.write_err("UsageError: %s" % value)
1722 else:
1722 else:
1723 if exception_only:
1723 if exception_only:
1724 stb = ['An exception has occurred, use %tb to see '
1724 stb = ['An exception has occurred, use %tb to see '
1725 'the full traceback.\n']
1725 'the full traceback.\n']
1726 stb.extend(self.InteractiveTB.get_exception_only(etype,
1726 stb.extend(self.InteractiveTB.get_exception_only(etype,
1727 value))
1727 value))
1728 else:
1728 else:
1729 try:
1729 try:
1730 # Exception classes can customise their traceback - we
1730 # Exception classes can customise their traceback - we
1731 # use this in IPython.parallel for exceptions occurring
1731 # use this in IPython.parallel for exceptions occurring
1732 # in the engines. This should return a list of strings.
1732 # in the engines. This should return a list of strings.
1733 stb = value._render_traceback_()
1733 stb = value._render_traceback_()
1734 except Exception:
1734 except Exception:
1735 stb = self.InteractiveTB.structured_traceback(etype,
1735 stb = self.InteractiveTB.structured_traceback(etype,
1736 value, tb, tb_offset=tb_offset)
1736 value, tb, tb_offset=tb_offset)
1737
1737
1738 self._showtraceback(etype, value, stb)
1738 self._showtraceback(etype, value, stb)
1739 if self.call_pdb:
1739 if self.call_pdb:
1740 # drop into debugger
1740 # drop into debugger
1741 self.debugger(force=True)
1741 self.debugger(force=True)
1742 return
1742 return
1743
1743
1744 # Actually show the traceback
1744 # Actually show the traceback
1745 self._showtraceback(etype, value, stb)
1745 self._showtraceback(etype, value, stb)
1746
1746
1747 except KeyboardInterrupt:
1747 except KeyboardInterrupt:
1748 self.write_err("\nKeyboardInterrupt\n")
1748 self.write_err("\nKeyboardInterrupt\n")
1749
1749
1750 def _showtraceback(self, etype, evalue, stb):
1750 def _showtraceback(self, etype, evalue, stb):
1751 """Actually show a traceback.
1751 """Actually show a traceback.
1752
1752
1753 Subclasses may override this method to put the traceback on a different
1753 Subclasses may override this method to put the traceback on a different
1754 place, like a side channel.
1754 place, like a side channel.
1755 """
1755 """
1756 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1756 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1757
1757
1758 def showsyntaxerror(self, filename=None):
1758 def showsyntaxerror(self, filename=None):
1759 """Display the syntax error that just occurred.
1759 """Display the syntax error that just occurred.
1760
1760
1761 This doesn't display a stack trace because there isn't one.
1761 This doesn't display a stack trace because there isn't one.
1762
1762
1763 If a filename is given, it is stuffed in the exception instead
1763 If a filename is given, it is stuffed in the exception instead
1764 of what was there before (because Python's parser always uses
1764 of what was there before (because Python's parser always uses
1765 "<string>" when reading from a string).
1765 "<string>" when reading from a string).
1766 """
1766 """
1767 etype, value, last_traceback = self._get_exc_info()
1767 etype, value, last_traceback = self._get_exc_info()
1768
1768
1769 if filename and issubclass(etype, SyntaxError):
1769 if filename and issubclass(etype, SyntaxError):
1770 try:
1770 try:
1771 value.filename = filename
1771 value.filename = filename
1772 except:
1772 except:
1773 # Not the format we expect; leave it alone
1773 # Not the format we expect; leave it alone
1774 pass
1774 pass
1775
1775
1776 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1776 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1777 self._showtraceback(etype, value, stb)
1777 self._showtraceback(etype, value, stb)
1778
1778
1779 # This is overridden in TerminalInteractiveShell to show a message about
1779 # This is overridden in TerminalInteractiveShell to show a message about
1780 # the %paste magic.
1780 # the %paste magic.
1781 def showindentationerror(self):
1781 def showindentationerror(self):
1782 """Called by run_cell when there's an IndentationError in code entered
1782 """Called by run_cell when there's an IndentationError in code entered
1783 at the prompt.
1783 at the prompt.
1784
1784
1785 This is overridden in TerminalInteractiveShell to show a message about
1785 This is overridden in TerminalInteractiveShell to show a message about
1786 the %paste magic."""
1786 the %paste magic."""
1787 self.showsyntaxerror()
1787 self.showsyntaxerror()
1788
1788
1789 #-------------------------------------------------------------------------
1789 #-------------------------------------------------------------------------
1790 # Things related to readline
1790 # Things related to readline
1791 #-------------------------------------------------------------------------
1791 #-------------------------------------------------------------------------
1792
1792
1793 def init_readline(self):
1793 def init_readline(self):
1794 """Command history completion/saving/reloading."""
1794 """Command history completion/saving/reloading."""
1795
1795
1796 if self.readline_use:
1796 if self.readline_use:
1797 import IPython.utils.rlineimpl as readline
1797 import IPython.utils.rlineimpl as readline
1798
1798
1799 self.rl_next_input = None
1799 self.rl_next_input = None
1800 self.rl_do_indent = False
1800 self.rl_do_indent = False
1801
1801
1802 if not self.readline_use or not readline.have_readline:
1802 if not self.readline_use or not readline.have_readline:
1803 self.has_readline = False
1803 self.has_readline = False
1804 self.readline = None
1804 self.readline = None
1805 # Set a number of methods that depend on readline to be no-op
1805 # Set a number of methods that depend on readline to be no-op
1806 self.readline_no_record = no_op_context
1806 self.readline_no_record = no_op_context
1807 self.set_readline_completer = no_op
1807 self.set_readline_completer = no_op
1808 self.set_custom_completer = no_op
1808 self.set_custom_completer = no_op
1809 if self.readline_use:
1809 if self.readline_use:
1810 warn('Readline services not available or not loaded.')
1810 warn('Readline services not available or not loaded.')
1811 else:
1811 else:
1812 self.has_readline = True
1812 self.has_readline = True
1813 self.readline = readline
1813 self.readline = readline
1814 sys.modules['readline'] = readline
1814 sys.modules['readline'] = readline
1815
1815
1816 # Platform-specific configuration
1816 # Platform-specific configuration
1817 if os.name == 'nt':
1817 if os.name == 'nt':
1818 # FIXME - check with Frederick to see if we can harmonize
1818 # FIXME - check with Frederick to see if we can harmonize
1819 # naming conventions with pyreadline to avoid this
1819 # naming conventions with pyreadline to avoid this
1820 # platform-dependent check
1820 # platform-dependent check
1821 self.readline_startup_hook = readline.set_pre_input_hook
1821 self.readline_startup_hook = readline.set_pre_input_hook
1822 else:
1822 else:
1823 self.readline_startup_hook = readline.set_startup_hook
1823 self.readline_startup_hook = readline.set_startup_hook
1824
1824
1825 # Load user's initrc file (readline config)
1825 # Load user's initrc file (readline config)
1826 # Or if libedit is used, load editrc.
1826 # Or if libedit is used, load editrc.
1827 inputrc_name = os.environ.get('INPUTRC')
1827 inputrc_name = os.environ.get('INPUTRC')
1828 if inputrc_name is None:
1828 if inputrc_name is None:
1829 inputrc_name = '.inputrc'
1829 inputrc_name = '.inputrc'
1830 if readline.uses_libedit:
1830 if readline.uses_libedit:
1831 inputrc_name = '.editrc'
1831 inputrc_name = '.editrc'
1832 inputrc_name = os.path.join(self.home_dir, inputrc_name)
1832 inputrc_name = os.path.join(self.home_dir, inputrc_name)
1833 if os.path.isfile(inputrc_name):
1833 if os.path.isfile(inputrc_name):
1834 try:
1834 try:
1835 readline.read_init_file(inputrc_name)
1835 readline.read_init_file(inputrc_name)
1836 except:
1836 except:
1837 warn('Problems reading readline initialization file <%s>'
1837 warn('Problems reading readline initialization file <%s>'
1838 % inputrc_name)
1838 % inputrc_name)
1839
1839
1840 # Configure readline according to user's prefs
1840 # Configure readline according to user's prefs
1841 # This is only done if GNU readline is being used. If libedit
1841 # This is only done if GNU readline is being used. If libedit
1842 # is being used (as on Leopard) the readline config is
1842 # is being used (as on Leopard) the readline config is
1843 # not run as the syntax for libedit is different.
1843 # not run as the syntax for libedit is different.
1844 if not readline.uses_libedit:
1844 if not readline.uses_libedit:
1845 for rlcommand in self.readline_parse_and_bind:
1845 for rlcommand in self.readline_parse_and_bind:
1846 #print "loading rl:",rlcommand # dbg
1846 #print "loading rl:",rlcommand # dbg
1847 readline.parse_and_bind(rlcommand)
1847 readline.parse_and_bind(rlcommand)
1848
1848
1849 # Remove some chars from the delimiters list. If we encounter
1849 # Remove some chars from the delimiters list. If we encounter
1850 # unicode chars, discard them.
1850 # unicode chars, discard them.
1851 delims = readline.get_completer_delims()
1851 delims = readline.get_completer_delims()
1852 if not py3compat.PY3:
1852 if not py3compat.PY3:
1853 delims = delims.encode("ascii", "ignore")
1853 delims = delims.encode("ascii", "ignore")
1854 for d in self.readline_remove_delims:
1854 for d in self.readline_remove_delims:
1855 delims = delims.replace(d, "")
1855 delims = delims.replace(d, "")
1856 delims = delims.replace(ESC_MAGIC, '')
1856 delims = delims.replace(ESC_MAGIC, '')
1857 readline.set_completer_delims(delims)
1857 readline.set_completer_delims(delims)
1858 # otherwise we end up with a monster history after a while:
1858 # otherwise we end up with a monster history after a while:
1859 readline.set_history_length(self.history_length)
1859 readline.set_history_length(self.history_length)
1860
1860
1861 self.refill_readline_hist()
1861 self.refill_readline_hist()
1862 self.readline_no_record = ReadlineNoRecord(self)
1862 self.readline_no_record = ReadlineNoRecord(self)
1863
1863
1864 # Configure auto-indent for all platforms
1864 # Configure auto-indent for all platforms
1865 self.set_autoindent(self.autoindent)
1865 self.set_autoindent(self.autoindent)
1866
1866
1867 def refill_readline_hist(self):
1867 def refill_readline_hist(self):
1868 # Load the last 1000 lines from history
1868 # Load the last 1000 lines from history
1869 self.readline.clear_history()
1869 self.readline.clear_history()
1870 stdin_encoding = sys.stdin.encoding or "utf-8"
1870 stdin_encoding = sys.stdin.encoding or "utf-8"
1871 last_cell = u""
1871 last_cell = u""
1872 for _, _, cell in self.history_manager.get_tail(1000,
1872 for _, _, cell in self.history_manager.get_tail(1000,
1873 include_latest=True):
1873 include_latest=True):
1874 # Ignore blank lines and consecutive duplicates
1874 # Ignore blank lines and consecutive duplicates
1875 cell = cell.rstrip()
1875 cell = cell.rstrip()
1876 if cell and (cell != last_cell):
1876 if cell and (cell != last_cell):
1877 if self.multiline_history:
1877 if self.multiline_history:
1878 self.readline.add_history(py3compat.unicode_to_str(cell,
1878 self.readline.add_history(py3compat.unicode_to_str(cell,
1879 stdin_encoding))
1879 stdin_encoding))
1880 else:
1880 else:
1881 for line in cell.splitlines():
1881 for line in cell.splitlines():
1882 self.readline.add_history(py3compat.unicode_to_str(line,
1882 self.readline.add_history(py3compat.unicode_to_str(line,
1883 stdin_encoding))
1883 stdin_encoding))
1884 last_cell = cell
1884 last_cell = cell
1885
1885
1886 def set_next_input(self, s):
1886 def set_next_input(self, s):
1887 """ Sets the 'default' input string for the next command line.
1887 """ Sets the 'default' input string for the next command line.
1888
1888
1889 Requires readline.
1889 Requires readline.
1890
1890
1891 Example:
1891 Example:
1892
1892
1893 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1893 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1894 [D:\ipython]|2> Hello Word_ # cursor is here
1894 [D:\ipython]|2> Hello Word_ # cursor is here
1895 """
1895 """
1896 self.rl_next_input = py3compat.cast_bytes_py2(s)
1896 self.rl_next_input = py3compat.cast_bytes_py2(s)
1897
1897
1898 # Maybe move this to the terminal subclass?
1898 # Maybe move this to the terminal subclass?
1899 def pre_readline(self):
1899 def pre_readline(self):
1900 """readline hook to be used at the start of each line.
1900 """readline hook to be used at the start of each line.
1901
1901
1902 Currently it handles auto-indent only."""
1902 Currently it handles auto-indent only."""
1903
1903
1904 if self.rl_do_indent:
1904 if self.rl_do_indent:
1905 self.readline.insert_text(self._indent_current_str())
1905 self.readline.insert_text(self._indent_current_str())
1906 if self.rl_next_input is not None:
1906 if self.rl_next_input is not None:
1907 self.readline.insert_text(self.rl_next_input)
1907 self.readline.insert_text(self.rl_next_input)
1908 self.rl_next_input = None
1908 self.rl_next_input = None
1909
1909
1910 def _indent_current_str(self):
1910 def _indent_current_str(self):
1911 """return the current level of indentation as a string"""
1911 """return the current level of indentation as a string"""
1912 return self.input_splitter.indent_spaces * ' '
1912 return self.input_splitter.indent_spaces * ' '
1913
1913
1914 #-------------------------------------------------------------------------
1914 #-------------------------------------------------------------------------
1915 # Things related to text completion
1915 # Things related to text completion
1916 #-------------------------------------------------------------------------
1916 #-------------------------------------------------------------------------
1917
1917
1918 def init_completer(self):
1918 def init_completer(self):
1919 """Initialize the completion machinery.
1919 """Initialize the completion machinery.
1920
1920
1921 This creates completion machinery that can be used by client code,
1921 This creates completion machinery that can be used by client code,
1922 either interactively in-process (typically triggered by the readline
1922 either interactively in-process (typically triggered by the readline
1923 library), programatically (such as in test suites) or out-of-prcess
1923 library), programatically (such as in test suites) or out-of-prcess
1924 (typically over the network by remote frontends).
1924 (typically over the network by remote frontends).
1925 """
1925 """
1926 from IPython.core.completer import IPCompleter
1926 from IPython.core.completer import IPCompleter
1927 from IPython.core.completerlib import (module_completer,
1927 from IPython.core.completerlib import (module_completer,
1928 magic_run_completer, cd_completer, reset_completer)
1928 magic_run_completer, cd_completer, reset_completer)
1929
1929
1930 self.Completer = IPCompleter(shell=self,
1930 self.Completer = IPCompleter(shell=self,
1931 namespace=self.user_ns,
1931 namespace=self.user_ns,
1932 global_namespace=self.user_global_ns,
1932 global_namespace=self.user_global_ns,
1933 alias_table=self.alias_manager.alias_table,
1933 alias_table=self.alias_manager.alias_table,
1934 use_readline=self.has_readline,
1934 use_readline=self.has_readline,
1935 config=self.config,
1935 config=self.config,
1936 )
1936 )
1937 self.configurables.append(self.Completer)
1937 self.configurables.append(self.Completer)
1938
1938
1939 # Add custom completers to the basic ones built into IPCompleter
1939 # Add custom completers to the basic ones built into IPCompleter
1940 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1940 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1941 self.strdispatchers['complete_command'] = sdisp
1941 self.strdispatchers['complete_command'] = sdisp
1942 self.Completer.custom_completers = sdisp
1942 self.Completer.custom_completers = sdisp
1943
1943
1944 self.set_hook('complete_command', module_completer, str_key = 'import')
1944 self.set_hook('complete_command', module_completer, str_key = 'import')
1945 self.set_hook('complete_command', module_completer, str_key = 'from')
1945 self.set_hook('complete_command', module_completer, str_key = 'from')
1946 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
1946 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
1947 self.set_hook('complete_command', cd_completer, str_key = '%cd')
1947 self.set_hook('complete_command', cd_completer, str_key = '%cd')
1948 self.set_hook('complete_command', reset_completer, str_key = '%reset')
1948 self.set_hook('complete_command', reset_completer, str_key = '%reset')
1949
1949
1950 # Only configure readline if we truly are using readline. IPython can
1950 # Only configure readline if we truly are using readline. IPython can
1951 # do tab-completion over the network, in GUIs, etc, where readline
1951 # do tab-completion over the network, in GUIs, etc, where readline
1952 # itself may be absent
1952 # itself may be absent
1953 if self.has_readline:
1953 if self.has_readline:
1954 self.set_readline_completer()
1954 self.set_readline_completer()
1955
1955
1956 def complete(self, text, line=None, cursor_pos=None):
1956 def complete(self, text, line=None, cursor_pos=None):
1957 """Return the completed text and a list of completions.
1957 """Return the completed text and a list of completions.
1958
1958
1959 Parameters
1959 Parameters
1960 ----------
1960 ----------
1961
1961
1962 text : string
1962 text : string
1963 A string of text to be completed on. It can be given as empty and
1963 A string of text to be completed on. It can be given as empty and
1964 instead a line/position pair are given. In this case, the
1964 instead a line/position pair are given. In this case, the
1965 completer itself will split the line like readline does.
1965 completer itself will split the line like readline does.
1966
1966
1967 line : string, optional
1967 line : string, optional
1968 The complete line that text is part of.
1968 The complete line that text is part of.
1969
1969
1970 cursor_pos : int, optional
1970 cursor_pos : int, optional
1971 The position of the cursor on the input line.
1971 The position of the cursor on the input line.
1972
1972
1973 Returns
1973 Returns
1974 -------
1974 -------
1975 text : string
1975 text : string
1976 The actual text that was completed.
1976 The actual text that was completed.
1977
1977
1978 matches : list
1978 matches : list
1979 A sorted list with all possible completions.
1979 A sorted list with all possible completions.
1980
1980
1981 The optional arguments allow the completion to take more context into
1981 The optional arguments allow the completion to take more context into
1982 account, and are part of the low-level completion API.
1982 account, and are part of the low-level completion API.
1983
1983
1984 This is a wrapper around the completion mechanism, similar to what
1984 This is a wrapper around the completion mechanism, similar to what
1985 readline does at the command line when the TAB key is hit. By
1985 readline does at the command line when the TAB key is hit. By
1986 exposing it as a method, it can be used by other non-readline
1986 exposing it as a method, it can be used by other non-readline
1987 environments (such as GUIs) for text completion.
1987 environments (such as GUIs) for text completion.
1988
1988
1989 Simple usage example:
1989 Simple usage example:
1990
1990
1991 In [1]: x = 'hello'
1991 In [1]: x = 'hello'
1992
1992
1993 In [2]: _ip.complete('x.l')
1993 In [2]: _ip.complete('x.l')
1994 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
1994 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
1995 """
1995 """
1996
1996
1997 # Inject names into __builtin__ so we can complete on the added names.
1997 # Inject names into __builtin__ so we can complete on the added names.
1998 with self.builtin_trap:
1998 with self.builtin_trap:
1999 return self.Completer.complete(text, line, cursor_pos)
1999 return self.Completer.complete(text, line, cursor_pos)
2000
2000
2001 def set_custom_completer(self, completer, pos=0):
2001 def set_custom_completer(self, completer, pos=0):
2002 """Adds a new custom completer function.
2002 """Adds a new custom completer function.
2003
2003
2004 The position argument (defaults to 0) is the index in the completers
2004 The position argument (defaults to 0) is the index in the completers
2005 list where you want the completer to be inserted."""
2005 list where you want the completer to be inserted."""
2006
2006
2007 newcomp = types.MethodType(completer,self.Completer)
2007 newcomp = types.MethodType(completer,self.Completer)
2008 self.Completer.matchers.insert(pos,newcomp)
2008 self.Completer.matchers.insert(pos,newcomp)
2009
2009
2010 def set_readline_completer(self):
2010 def set_readline_completer(self):
2011 """Reset readline's completer to be our own."""
2011 """Reset readline's completer to be our own."""
2012 self.readline.set_completer(self.Completer.rlcomplete)
2012 self.readline.set_completer(self.Completer.rlcomplete)
2013
2013
2014 def set_completer_frame(self, frame=None):
2014 def set_completer_frame(self, frame=None):
2015 """Set the frame of the completer."""
2015 """Set the frame of the completer."""
2016 if frame:
2016 if frame:
2017 self.Completer.namespace = frame.f_locals
2017 self.Completer.namespace = frame.f_locals
2018 self.Completer.global_namespace = frame.f_globals
2018 self.Completer.global_namespace = frame.f_globals
2019 else:
2019 else:
2020 self.Completer.namespace = self.user_ns
2020 self.Completer.namespace = self.user_ns
2021 self.Completer.global_namespace = self.user_global_ns
2021 self.Completer.global_namespace = self.user_global_ns
2022
2022
2023 #-------------------------------------------------------------------------
2023 #-------------------------------------------------------------------------
2024 # Things related to magics
2024 # Things related to magics
2025 #-------------------------------------------------------------------------
2025 #-------------------------------------------------------------------------
2026
2026
2027 def init_magics(self):
2027 def init_magics(self):
2028 from IPython.core import magics as m
2028 from IPython.core import magics as m
2029 self.magics_manager = magic.MagicsManager(shell=self,
2029 self.magics_manager = magic.MagicsManager(shell=self,
2030 confg=self.config,
2030 confg=self.config,
2031 user_magics=m.UserMagics(self))
2031 user_magics=m.UserMagics(self))
2032 self.configurables.append(self.magics_manager)
2032 self.configurables.append(self.magics_manager)
2033
2033
2034 # Expose as public API from the magics manager
2034 # Expose as public API from the magics manager
2035 self.register_magics = self.magics_manager.register
2035 self.register_magics = self.magics_manager.register
2036 self.register_magic_function = self.magics_manager.register_function
2036 self.register_magic_function = self.magics_manager.register_function
2037 self.define_magic = self.magics_manager.define_magic
2037 self.define_magic = self.magics_manager.define_magic
2038
2038
2039 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2039 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2040 m.ConfigMagics, m.DeprecatedMagics, m.DisplayMagics, m.ExecutionMagics,
2040 m.ConfigMagics, m.DeprecatedMagics, m.DisplayMagics, m.ExecutionMagics,
2041 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2041 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2042 m.NamespaceMagics, m.OSMagics, m.PylabMagics, m.ScriptMagics,
2042 m.NamespaceMagics, m.OSMagics, m.PylabMagics, m.ScriptMagics,
2043 )
2043 )
2044
2044
2045 # Register Magic Aliases
2045 # Register Magic Aliases
2046 mman = self.magics_manager
2046 mman = self.magics_manager
2047 mman.register_alias('ed', 'edit')
2047 mman.register_alias('ed', 'edit')
2048 mman.register_alias('hist', 'history')
2048 mman.register_alias('hist', 'history')
2049 mman.register_alias('rep', 'recall')
2049 mman.register_alias('rep', 'recall')
2050
2050
2051 # FIXME: Move the color initialization to the DisplayHook, which
2051 # FIXME: Move the color initialization to the DisplayHook, which
2052 # should be split into a prompt manager and displayhook. We probably
2052 # should be split into a prompt manager and displayhook. We probably
2053 # even need a centralize colors management object.
2053 # even need a centralize colors management object.
2054 self.magic('colors %s' % self.colors)
2054 self.magic('colors %s' % self.colors)
2055
2055
2056 def run_line_magic(self, magic_name, line):
2056 def run_line_magic(self, magic_name, line):
2057 """Execute the given line magic.
2057 """Execute the given line magic.
2058
2058
2059 Parameters
2059 Parameters
2060 ----------
2060 ----------
2061 magic_name : str
2061 magic_name : str
2062 Name of the desired magic function, without '%' prefix.
2062 Name of the desired magic function, without '%' prefix.
2063
2063
2064 line : str
2064 line : str
2065 The rest of the input line as a single string.
2065 The rest of the input line as a single string.
2066 """
2066 """
2067 fn = self.find_line_magic(magic_name)
2067 fn = self.find_line_magic(magic_name)
2068 if fn is None:
2068 if fn is None:
2069 cm = self.find_cell_magic(magic_name)
2069 cm = self.find_cell_magic(magic_name)
2070 etpl = "Line magic function `%%%s` not found%s."
2070 etpl = "Line magic function `%%%s` not found%s."
2071 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2071 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2072 'did you mean that instead?)' % magic_name )
2072 'did you mean that instead?)' % magic_name )
2073 error(etpl % (magic_name, extra))
2073 error(etpl % (magic_name, extra))
2074 else:
2074 else:
2075 # Note: this is the distance in the stack to the user's frame.
2075 # Note: this is the distance in the stack to the user's frame.
2076 # This will need to be updated if the internal calling logic gets
2076 # This will need to be updated if the internal calling logic gets
2077 # refactored, or else we'll be expanding the wrong variables.
2077 # refactored, or else we'll be expanding the wrong variables.
2078 stack_depth = 2
2078 stack_depth = 2
2079 magic_arg_s = self.var_expand(line, stack_depth)
2079 magic_arg_s = self.var_expand(line, stack_depth)
2080 # Put magic args in a list so we can call with f(*a) syntax
2080 # Put magic args in a list so we can call with f(*a) syntax
2081 args = [magic_arg_s]
2081 args = [magic_arg_s]
2082 kwargs = {}
2082 kwargs = {}
2083 # Grab local namespace if we need it:
2083 # Grab local namespace if we need it:
2084 if getattr(fn, "needs_local_scope", False):
2084 if getattr(fn, "needs_local_scope", False):
2085 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2085 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2086 with self.builtin_trap:
2086 with self.builtin_trap:
2087 result = fn(*args,**kwargs)
2087 result = fn(*args,**kwargs)
2088 return result
2088 return result
2089
2089
2090 def run_cell_magic(self, magic_name, line, cell):
2090 def run_cell_magic(self, magic_name, line, cell):
2091 """Execute the given cell magic.
2091 """Execute the given cell magic.
2092
2092
2093 Parameters
2093 Parameters
2094 ----------
2094 ----------
2095 magic_name : str
2095 magic_name : str
2096 Name of the desired magic function, without '%' prefix.
2096 Name of the desired magic function, without '%' prefix.
2097
2097
2098 line : str
2098 line : str
2099 The rest of the first input line as a single string.
2099 The rest of the first input line as a single string.
2100
2100
2101 cell : str
2101 cell : str
2102 The body of the cell as a (possibly multiline) string.
2102 The body of the cell as a (possibly multiline) string.
2103 """
2103 """
2104 fn = self.find_cell_magic(magic_name)
2104 fn = self.find_cell_magic(magic_name)
2105 if fn is None:
2105 if fn is None:
2106 lm = self.find_line_magic(magic_name)
2106 lm = self.find_line_magic(magic_name)
2107 etpl = "Cell magic function `%%%%%s` not found%s."
2107 etpl = "Cell magic function `%%%%%s` not found%s."
2108 extra = '' if lm is None else (' (But line magic `%%%s` exists, '
2108 extra = '' if lm is None else (' (But line magic `%%%s` exists, '
2109 'did you mean that instead?)' % magic_name )
2109 'did you mean that instead?)' % magic_name )
2110 error(etpl % (magic_name, extra))
2110 error(etpl % (magic_name, extra))
2111 else:
2111 else:
2112 # Note: this is the distance in the stack to the user's frame.
2112 # Note: this is the distance in the stack to the user's frame.
2113 # This will need to be updated if the internal calling logic gets
2113 # This will need to be updated if the internal calling logic gets
2114 # refactored, or else we'll be expanding the wrong variables.
2114 # refactored, or else we'll be expanding the wrong variables.
2115 stack_depth = 2
2115 stack_depth = 2
2116 magic_arg_s = self.var_expand(line, stack_depth)
2116 magic_arg_s = self.var_expand(line, stack_depth)
2117 with self.builtin_trap:
2117 with self.builtin_trap:
2118 result = fn(magic_arg_s, cell)
2118 result = fn(magic_arg_s, cell)
2119 return result
2119 return result
2120
2120
2121 def find_line_magic(self, magic_name):
2121 def find_line_magic(self, magic_name):
2122 """Find and return a line magic by name.
2122 """Find and return a line magic by name.
2123
2123
2124 Returns None if the magic isn't found."""
2124 Returns None if the magic isn't found."""
2125 return self.magics_manager.magics['line'].get(magic_name)
2125 return self.magics_manager.magics['line'].get(magic_name)
2126
2126
2127 def find_cell_magic(self, magic_name):
2127 def find_cell_magic(self, magic_name):
2128 """Find and return a cell magic by name.
2128 """Find and return a cell magic by name.
2129
2129
2130 Returns None if the magic isn't found."""
2130 Returns None if the magic isn't found."""
2131 return self.magics_manager.magics['cell'].get(magic_name)
2131 return self.magics_manager.magics['cell'].get(magic_name)
2132
2132
2133 def find_magic(self, magic_name, magic_kind='line'):
2133 def find_magic(self, magic_name, magic_kind='line'):
2134 """Find and return a magic of the given type by name.
2134 """Find and return a magic of the given type by name.
2135
2135
2136 Returns None if the magic isn't found."""
2136 Returns None if the magic isn't found."""
2137 return self.magics_manager.magics[magic_kind].get(magic_name)
2137 return self.magics_manager.magics[magic_kind].get(magic_name)
2138
2138
2139 def magic(self, arg_s):
2139 def magic(self, arg_s):
2140 """DEPRECATED. Use run_line_magic() instead.
2140 """DEPRECATED. Use run_line_magic() instead.
2141
2141
2142 Call a magic function by name.
2142 Call a magic function by name.
2143
2143
2144 Input: a string containing the name of the magic function to call and
2144 Input: a string containing the name of the magic function to call and
2145 any additional arguments to be passed to the magic.
2145 any additional arguments to be passed to the magic.
2146
2146
2147 magic('name -opt foo bar') is equivalent to typing at the ipython
2147 magic('name -opt foo bar') is equivalent to typing at the ipython
2148 prompt:
2148 prompt:
2149
2149
2150 In[1]: %name -opt foo bar
2150 In[1]: %name -opt foo bar
2151
2151
2152 To call a magic without arguments, simply use magic('name').
2152 To call a magic without arguments, simply use magic('name').
2153
2153
2154 This provides a proper Python function to call IPython's magics in any
2154 This provides a proper Python function to call IPython's magics in any
2155 valid Python code you can type at the interpreter, including loops and
2155 valid Python code you can type at the interpreter, including loops and
2156 compound statements.
2156 compound statements.
2157 """
2157 """
2158 # TODO: should we issue a loud deprecation warning here?
2158 # TODO: should we issue a loud deprecation warning here?
2159 magic_name, _, magic_arg_s = arg_s.partition(' ')
2159 magic_name, _, magic_arg_s = arg_s.partition(' ')
2160 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2160 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2161 return self.run_line_magic(magic_name, magic_arg_s)
2161 return self.run_line_magic(magic_name, magic_arg_s)
2162
2162
2163 #-------------------------------------------------------------------------
2163 #-------------------------------------------------------------------------
2164 # Things related to macros
2164 # Things related to macros
2165 #-------------------------------------------------------------------------
2165 #-------------------------------------------------------------------------
2166
2166
2167 def define_macro(self, name, themacro):
2167 def define_macro(self, name, themacro):
2168 """Define a new macro
2168 """Define a new macro
2169
2169
2170 Parameters
2170 Parameters
2171 ----------
2171 ----------
2172 name : str
2172 name : str
2173 The name of the macro.
2173 The name of the macro.
2174 themacro : str or Macro
2174 themacro : str or Macro
2175 The action to do upon invoking the macro. If a string, a new
2175 The action to do upon invoking the macro. If a string, a new
2176 Macro object is created by passing the string to it.
2176 Macro object is created by passing the string to it.
2177 """
2177 """
2178
2178
2179 from IPython.core import macro
2179 from IPython.core import macro
2180
2180
2181 if isinstance(themacro, basestring):
2181 if isinstance(themacro, basestring):
2182 themacro = macro.Macro(themacro)
2182 themacro = macro.Macro(themacro)
2183 if not isinstance(themacro, macro.Macro):
2183 if not isinstance(themacro, macro.Macro):
2184 raise ValueError('A macro must be a string or a Macro instance.')
2184 raise ValueError('A macro must be a string or a Macro instance.')
2185 self.user_ns[name] = themacro
2185 self.user_ns[name] = themacro
2186
2186
2187 #-------------------------------------------------------------------------
2187 #-------------------------------------------------------------------------
2188 # Things related to the running of system commands
2188 # Things related to the running of system commands
2189 #-------------------------------------------------------------------------
2189 #-------------------------------------------------------------------------
2190
2190
2191 def system_piped(self, cmd):
2191 def system_piped(self, cmd):
2192 """Call the given cmd in a subprocess, piping stdout/err
2192 """Call the given cmd in a subprocess, piping stdout/err
2193
2193
2194 Parameters
2194 Parameters
2195 ----------
2195 ----------
2196 cmd : str
2196 cmd : str
2197 Command to execute (can not end in '&', as background processes are
2197 Command to execute (can not end in '&', as background processes are
2198 not supported. Should not be a command that expects input
2198 not supported. Should not be a command that expects input
2199 other than simple text.
2199 other than simple text.
2200 """
2200 """
2201 if cmd.rstrip().endswith('&'):
2201 if cmd.rstrip().endswith('&'):
2202 # this is *far* from a rigorous test
2202 # this is *far* from a rigorous test
2203 # We do not support backgrounding processes because we either use
2203 # We do not support backgrounding processes because we either use
2204 # pexpect or pipes to read from. Users can always just call
2204 # pexpect or pipes to read from. Users can always just call
2205 # os.system() or use ip.system=ip.system_raw
2205 # os.system() or use ip.system=ip.system_raw
2206 # if they really want a background process.
2206 # if they really want a background process.
2207 raise OSError("Background processes not supported.")
2207 raise OSError("Background processes not supported.")
2208
2208
2209 # we explicitly do NOT return the subprocess status code, because
2209 # we explicitly do NOT return the subprocess status code, because
2210 # a non-None value would trigger :func:`sys.displayhook` calls.
2210 # a non-None value would trigger :func:`sys.displayhook` calls.
2211 # Instead, we store the exit_code in user_ns.
2211 # Instead, we store the exit_code in user_ns.
2212 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2212 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2213
2213
2214 def system_raw(self, cmd):
2214 def system_raw(self, cmd):
2215 """Call the given cmd in a subprocess using os.system
2215 """Call the given cmd in a subprocess using os.system
2216
2216
2217 Parameters
2217 Parameters
2218 ----------
2218 ----------
2219 cmd : str
2219 cmd : str
2220 Command to execute.
2220 Command to execute.
2221 """
2221 """
2222 cmd = self.var_expand(cmd, depth=1)
2222 cmd = self.var_expand(cmd, depth=1)
2223 # protect os.system from UNC paths on Windows, which it can't handle:
2223 # protect os.system from UNC paths on Windows, which it can't handle:
2224 if sys.platform == 'win32':
2224 if sys.platform == 'win32':
2225 from IPython.utils._process_win32 import AvoidUNCPath
2225 from IPython.utils._process_win32 import AvoidUNCPath
2226 with AvoidUNCPath() as path:
2226 with AvoidUNCPath() as path:
2227 if path is not None:
2227 if path is not None:
2228 cmd = '"pushd %s &&"%s' % (path, cmd)
2228 cmd = '"pushd %s &&"%s' % (path, cmd)
2229 cmd = py3compat.unicode_to_str(cmd)
2229 cmd = py3compat.unicode_to_str(cmd)
2230 ec = os.system(cmd)
2230 ec = os.system(cmd)
2231 else:
2231 else:
2232 cmd = py3compat.unicode_to_str(cmd)
2232 cmd = py3compat.unicode_to_str(cmd)
2233 ec = os.system(cmd)
2233 ec = os.system(cmd)
2234
2234
2235 # We explicitly do NOT return the subprocess status code, because
2235 # We explicitly do NOT return the subprocess status code, because
2236 # a non-None value would trigger :func:`sys.displayhook` calls.
2236 # a non-None value would trigger :func:`sys.displayhook` calls.
2237 # Instead, we store the exit_code in user_ns.
2237 # Instead, we store the exit_code in user_ns.
2238 self.user_ns['_exit_code'] = ec
2238 self.user_ns['_exit_code'] = ec
2239
2239
2240 # use piped system by default, because it is better behaved
2240 # use piped system by default, because it is better behaved
2241 system = system_piped
2241 system = system_piped
2242
2242
2243 def getoutput(self, cmd, split=True, depth=0):
2243 def getoutput(self, cmd, split=True, depth=0):
2244 """Get output (possibly including stderr) from a subprocess.
2244 """Get output (possibly including stderr) from a subprocess.
2245
2245
2246 Parameters
2246 Parameters
2247 ----------
2247 ----------
2248 cmd : str
2248 cmd : str
2249 Command to execute (can not end in '&', as background processes are
2249 Command to execute (can not end in '&', as background processes are
2250 not supported.
2250 not supported.
2251 split : bool, optional
2251 split : bool, optional
2252 If True, split the output into an IPython SList. Otherwise, an
2252 If True, split the output into an IPython SList. Otherwise, an
2253 IPython LSString is returned. These are objects similar to normal
2253 IPython LSString is returned. These are objects similar to normal
2254 lists and strings, with a few convenience attributes for easier
2254 lists and strings, with a few convenience attributes for easier
2255 manipulation of line-based output. You can use '?' on them for
2255 manipulation of line-based output. You can use '?' on them for
2256 details.
2256 details.
2257 depth : int, optional
2257 depth : int, optional
2258 How many frames above the caller are the local variables which should
2258 How many frames above the caller are the local variables which should
2259 be expanded in the command string? The default (0) assumes that the
2259 be expanded in the command string? The default (0) assumes that the
2260 expansion variables are in the stack frame calling this function.
2260 expansion variables are in the stack frame calling this function.
2261 """
2261 """
2262 if cmd.rstrip().endswith('&'):
2262 if cmd.rstrip().endswith('&'):
2263 # this is *far* from a rigorous test
2263 # this is *far* from a rigorous test
2264 raise OSError("Background processes not supported.")
2264 raise OSError("Background processes not supported.")
2265 out = getoutput(self.var_expand(cmd, depth=depth+1))
2265 out = getoutput(self.var_expand(cmd, depth=depth+1))
2266 if split:
2266 if split:
2267 out = SList(out.splitlines())
2267 out = SList(out.splitlines())
2268 else:
2268 else:
2269 out = LSString(out)
2269 out = LSString(out)
2270 return out
2270 return out
2271
2271
2272 #-------------------------------------------------------------------------
2272 #-------------------------------------------------------------------------
2273 # Things related to aliases
2273 # Things related to aliases
2274 #-------------------------------------------------------------------------
2274 #-------------------------------------------------------------------------
2275
2275
2276 def init_alias(self):
2276 def init_alias(self):
2277 self.alias_manager = AliasManager(shell=self, config=self.config)
2277 self.alias_manager = AliasManager(shell=self, config=self.config)
2278 self.configurables.append(self.alias_manager)
2278 self.configurables.append(self.alias_manager)
2279 self.ns_table['alias'] = self.alias_manager.alias_table,
2279 self.ns_table['alias'] = self.alias_manager.alias_table,
2280
2280
2281 #-------------------------------------------------------------------------
2281 #-------------------------------------------------------------------------
2282 # Things related to extensions
2282 # Things related to extensions
2283 #-------------------------------------------------------------------------
2283 #-------------------------------------------------------------------------
2284
2284
2285 def init_extension_manager(self):
2285 def init_extension_manager(self):
2286 self.extension_manager = ExtensionManager(shell=self, config=self.config)
2286 self.extension_manager = ExtensionManager(shell=self, config=self.config)
2287 self.configurables.append(self.extension_manager)
2287 self.configurables.append(self.extension_manager)
2288
2288
2289 #-------------------------------------------------------------------------
2289 #-------------------------------------------------------------------------
2290 # Things related to payloads
2290 # Things related to payloads
2291 #-------------------------------------------------------------------------
2291 #-------------------------------------------------------------------------
2292
2292
2293 def init_payload(self):
2293 def init_payload(self):
2294 self.payload_manager = PayloadManager(config=self.config)
2294 self.payload_manager = PayloadManager(config=self.config)
2295 self.configurables.append(self.payload_manager)
2295 self.configurables.append(self.payload_manager)
2296
2296
2297 #-------------------------------------------------------------------------
2297 #-------------------------------------------------------------------------
2298 # Things related to the prefilter
2298 # Things related to the prefilter
2299 #-------------------------------------------------------------------------
2299 #-------------------------------------------------------------------------
2300
2300
2301 def init_prefilter(self):
2301 def init_prefilter(self):
2302 self.prefilter_manager = PrefilterManager(shell=self, config=self.config)
2302 self.prefilter_manager = PrefilterManager(shell=self, config=self.config)
2303 self.configurables.append(self.prefilter_manager)
2303 self.configurables.append(self.prefilter_manager)
2304 # Ultimately this will be refactored in the new interpreter code, but
2304 # Ultimately this will be refactored in the new interpreter code, but
2305 # for now, we should expose the main prefilter method (there's legacy
2305 # for now, we should expose the main prefilter method (there's legacy
2306 # code out there that may rely on this).
2306 # code out there that may rely on this).
2307 self.prefilter = self.prefilter_manager.prefilter_lines
2307 self.prefilter = self.prefilter_manager.prefilter_lines
2308
2308
2309 def auto_rewrite_input(self, cmd):
2309 def auto_rewrite_input(self, cmd):
2310 """Print to the screen the rewritten form of the user's command.
2310 """Print to the screen the rewritten form of the user's command.
2311
2311
2312 This shows visual feedback by rewriting input lines that cause
2312 This shows visual feedback by rewriting input lines that cause
2313 automatic calling to kick in, like::
2313 automatic calling to kick in, like::
2314
2314
2315 /f x
2315 /f x
2316
2316
2317 into::
2317 into::
2318
2318
2319 ------> f(x)
2319 ------> f(x)
2320
2320
2321 after the user's input prompt. This helps the user understand that the
2321 after the user's input prompt. This helps the user understand that the
2322 input line was transformed automatically by IPython.
2322 input line was transformed automatically by IPython.
2323 """
2323 """
2324 if not self.show_rewritten_input:
2324 if not self.show_rewritten_input:
2325 return
2325 return
2326
2326
2327 rw = self.prompt_manager.render('rewrite') + cmd
2327 rw = self.prompt_manager.render('rewrite') + cmd
2328
2328
2329 try:
2329 try:
2330 # plain ascii works better w/ pyreadline, on some machines, so
2330 # plain ascii works better w/ pyreadline, on some machines, so
2331 # we use it and only print uncolored rewrite if we have unicode
2331 # we use it and only print uncolored rewrite if we have unicode
2332 rw = str(rw)
2332 rw = str(rw)
2333 print(rw, file=io.stdout)
2333 print(rw, file=io.stdout)
2334 except UnicodeEncodeError:
2334 except UnicodeEncodeError:
2335 print("------> " + cmd)
2335 print("------> " + cmd)
2336
2336
2337 #-------------------------------------------------------------------------
2337 #-------------------------------------------------------------------------
2338 # Things related to extracting values/expressions from kernel and user_ns
2338 # Things related to extracting values/expressions from kernel and user_ns
2339 #-------------------------------------------------------------------------
2339 #-------------------------------------------------------------------------
2340
2340
2341 def _simple_error(self):
2341 def _simple_error(self):
2342 etype, value = sys.exc_info()[:2]
2342 etype, value = sys.exc_info()[:2]
2343 return u'[ERROR] {e.__name__}: {v}'.format(e=etype, v=value)
2343 return u'[ERROR] {e.__name__}: {v}'.format(e=etype, v=value)
2344
2344
2345 def user_variables(self, names):
2345 def user_variables(self, names):
2346 """Get a list of variable names from the user's namespace.
2346 """Get a list of variable names from the user's namespace.
2347
2347
2348 Parameters
2348 Parameters
2349 ----------
2349 ----------
2350 names : list of strings
2350 names : list of strings
2351 A list of names of variables to be read from the user namespace.
2351 A list of names of variables to be read from the user namespace.
2352
2352
2353 Returns
2353 Returns
2354 -------
2354 -------
2355 A dict, keyed by the input names and with the repr() of each value.
2355 A dict, keyed by the input names and with the repr() of each value.
2356 """
2356 """
2357 out = {}
2357 out = {}
2358 user_ns = self.user_ns
2358 user_ns = self.user_ns
2359 for varname in names:
2359 for varname in names:
2360 try:
2360 try:
2361 value = repr(user_ns[varname])
2361 value = repr(user_ns[varname])
2362 except:
2362 except:
2363 value = self._simple_error()
2363 value = self._simple_error()
2364 out[varname] = value
2364 out[varname] = value
2365 return out
2365 return out
2366
2366
2367 def user_expressions(self, expressions):
2367 def user_expressions(self, expressions):
2368 """Evaluate a dict of expressions in the user's namespace.
2368 """Evaluate a dict of expressions in the user's namespace.
2369
2369
2370 Parameters
2370 Parameters
2371 ----------
2371 ----------
2372 expressions : dict
2372 expressions : dict
2373 A dict with string keys and string values. The expression values
2373 A dict with string keys and string values. The expression values
2374 should be valid Python expressions, each of which will be evaluated
2374 should be valid Python expressions, each of which will be evaluated
2375 in the user namespace.
2375 in the user namespace.
2376
2376
2377 Returns
2377 Returns
2378 -------
2378 -------
2379 A dict, keyed like the input expressions dict, with the repr() of each
2379 A dict, keyed like the input expressions dict, with the repr() of each
2380 value.
2380 value.
2381 """
2381 """
2382 out = {}
2382 out = {}
2383 user_ns = self.user_ns
2383 user_ns = self.user_ns
2384 global_ns = self.user_global_ns
2384 global_ns = self.user_global_ns
2385 for key, expr in expressions.iteritems():
2385 for key, expr in expressions.iteritems():
2386 try:
2386 try:
2387 value = repr(eval(expr, global_ns, user_ns))
2387 value = repr(eval(expr, global_ns, user_ns))
2388 except:
2388 except:
2389 value = self._simple_error()
2389 value = self._simple_error()
2390 out[key] = value
2390 out[key] = value
2391 return out
2391 return out
2392
2392
2393 #-------------------------------------------------------------------------
2393 #-------------------------------------------------------------------------
2394 # Things related to the running of code
2394 # Things related to the running of code
2395 #-------------------------------------------------------------------------
2395 #-------------------------------------------------------------------------
2396
2396
2397 def ex(self, cmd):
2397 def ex(self, cmd):
2398 """Execute a normal python statement in user namespace."""
2398 """Execute a normal python statement in user namespace."""
2399 with self.builtin_trap:
2399 with self.builtin_trap:
2400 exec cmd in self.user_global_ns, self.user_ns
2400 exec cmd in self.user_global_ns, self.user_ns
2401
2401
2402 def ev(self, expr):
2402 def ev(self, expr):
2403 """Evaluate python expression expr in user namespace.
2403 """Evaluate python expression expr in user namespace.
2404
2404
2405 Returns the result of evaluation
2405 Returns the result of evaluation
2406 """
2406 """
2407 with self.builtin_trap:
2407 with self.builtin_trap:
2408 return eval(expr, self.user_global_ns, self.user_ns)
2408 return eval(expr, self.user_global_ns, self.user_ns)
2409
2409
2410 def safe_execfile(self, fname, *where, **kw):
2410 def safe_execfile(self, fname, *where, **kw):
2411 """A safe version of the builtin execfile().
2411 """A safe version of the builtin execfile().
2412
2412
2413 This version will never throw an exception, but instead print
2413 This version will never throw an exception, but instead print
2414 helpful error messages to the screen. This only works on pure
2414 helpful error messages to the screen. This only works on pure
2415 Python files with the .py extension.
2415 Python files with the .py extension.
2416
2416
2417 Parameters
2417 Parameters
2418 ----------
2418 ----------
2419 fname : string
2419 fname : string
2420 The name of the file to be executed.
2420 The name of the file to be executed.
2421 where : tuple
2421 where : tuple
2422 One or two namespaces, passed to execfile() as (globals,locals).
2422 One or two namespaces, passed to execfile() as (globals,locals).
2423 If only one is given, it is passed as both.
2423 If only one is given, it is passed as both.
2424 exit_ignore : bool (False)
2424 exit_ignore : bool (False)
2425 If True, then silence SystemExit for non-zero status (it is always
2425 If True, then silence SystemExit for non-zero status (it is always
2426 silenced for zero status, as it is so common).
2426 silenced for zero status, as it is so common).
2427 raise_exceptions : bool (False)
2427 raise_exceptions : bool (False)
2428 If True raise exceptions everywhere. Meant for testing.
2428 If True raise exceptions everywhere. Meant for testing.
2429
2429
2430 """
2430 """
2431 kw.setdefault('exit_ignore', False)
2431 kw.setdefault('exit_ignore', False)
2432 kw.setdefault('raise_exceptions', False)
2432 kw.setdefault('raise_exceptions', False)
2433
2433
2434 fname = os.path.abspath(os.path.expanduser(fname))
2434 fname = os.path.abspath(os.path.expanduser(fname))
2435
2435
2436 # Make sure we can open the file
2436 # Make sure we can open the file
2437 try:
2437 try:
2438 with open(fname) as thefile:
2438 with open(fname) as thefile:
2439 pass
2439 pass
2440 except:
2440 except:
2441 warn('Could not open file <%s> for safe execution.' % fname)
2441 warn('Could not open file <%s> for safe execution.' % fname)
2442 return
2442 return
2443
2443
2444 # Find things also in current directory. This is needed to mimic the
2444 # Find things also in current directory. This is needed to mimic the
2445 # behavior of running a script from the system command line, where
2445 # behavior of running a script from the system command line, where
2446 # Python inserts the script's directory into sys.path
2446 # Python inserts the script's directory into sys.path
2447 dname = os.path.dirname(fname)
2447 dname = os.path.dirname(fname)
2448
2448
2449 with prepended_to_syspath(dname):
2449 with prepended_to_syspath(dname):
2450 try:
2450 try:
2451 py3compat.execfile(fname,*where)
2451 py3compat.execfile(fname,*where)
2452 except SystemExit as status:
2452 except SystemExit as status:
2453 # If the call was made with 0 or None exit status (sys.exit(0)
2453 # If the call was made with 0 or None exit status (sys.exit(0)
2454 # or sys.exit() ), don't bother showing a traceback, as both of
2454 # or sys.exit() ), don't bother showing a traceback, as both of
2455 # these are considered normal by the OS:
2455 # these are considered normal by the OS:
2456 # > python -c'import sys;sys.exit(0)'; echo $?
2456 # > python -c'import sys;sys.exit(0)'; echo $?
2457 # 0
2457 # 0
2458 # > python -c'import sys;sys.exit()'; echo $?
2458 # > python -c'import sys;sys.exit()'; echo $?
2459 # 0
2459 # 0
2460 # For other exit status, we show the exception unless
2460 # For other exit status, we show the exception unless
2461 # explicitly silenced, but only in short form.
2461 # explicitly silenced, but only in short form.
2462 if kw['raise_exceptions']:
2462 if kw['raise_exceptions']:
2463 raise
2463 raise
2464 if status.code not in (0, None) and not kw['exit_ignore']:
2464 if status.code not in (0, None) and not kw['exit_ignore']:
2465 self.showtraceback(exception_only=True)
2465 self.showtraceback(exception_only=True)
2466 except:
2466 except:
2467 if kw['raise_exceptions']:
2467 if kw['raise_exceptions']:
2468 raise
2468 raise
2469 self.showtraceback()
2469 self.showtraceback()
2470
2470
2471 def safe_execfile_ipy(self, fname):
2471 def safe_execfile_ipy(self, fname):
2472 """Like safe_execfile, but for .ipy files with IPython syntax.
2472 """Like safe_execfile, but for .ipy files with IPython syntax.
2473
2473
2474 Parameters
2474 Parameters
2475 ----------
2475 ----------
2476 fname : str
2476 fname : str
2477 The name of the file to execute. The filename must have a
2477 The name of the file to execute. The filename must have a
2478 .ipy extension.
2478 .ipy extension.
2479 """
2479 """
2480 fname = os.path.abspath(os.path.expanduser(fname))
2480 fname = os.path.abspath(os.path.expanduser(fname))
2481
2481
2482 # Make sure we can open the file
2482 # Make sure we can open the file
2483 try:
2483 try:
2484 with open(fname) as thefile:
2484 with open(fname) as thefile:
2485 pass
2485 pass
2486 except:
2486 except:
2487 warn('Could not open file <%s> for safe execution.' % fname)
2487 warn('Could not open file <%s> for safe execution.' % fname)
2488 return
2488 return
2489
2489
2490 # Find things also in current directory. This is needed to mimic the
2490 # Find things also in current directory. This is needed to mimic the
2491 # behavior of running a script from the system command line, where
2491 # behavior of running a script from the system command line, where
2492 # Python inserts the script's directory into sys.path
2492 # Python inserts the script's directory into sys.path
2493 dname = os.path.dirname(fname)
2493 dname = os.path.dirname(fname)
2494
2494
2495 with prepended_to_syspath(dname):
2495 with prepended_to_syspath(dname):
2496 try:
2496 try:
2497 with open(fname) as thefile:
2497 with open(fname) as thefile:
2498 # self.run_cell currently captures all exceptions
2498 # self.run_cell currently captures all exceptions
2499 # raised in user code. It would be nice if there were
2499 # raised in user code. It would be nice if there were
2500 # versions of runlines, execfile that did raise, so
2500 # versions of runlines, execfile that did raise, so
2501 # we could catch the errors.
2501 # we could catch the errors.
2502 self.run_cell(thefile.read(), store_history=False)
2502 self.run_cell(thefile.read(), store_history=False)
2503 except:
2503 except:
2504 self.showtraceback()
2504 self.showtraceback()
2505 warn('Unknown failure executing file: <%s>' % fname)
2505 warn('Unknown failure executing file: <%s>' % fname)
2506
2506
2507 def safe_run_module(self, mod_name, where):
2507 def safe_run_module(self, mod_name, where):
2508 """A safe version of runpy.run_module().
2508 """A safe version of runpy.run_module().
2509
2509
2510 This version will never throw an exception, but instead print
2510 This version will never throw an exception, but instead print
2511 helpful error messages to the screen.
2511 helpful error messages to the screen.
2512
2512
2513 Parameters
2513 Parameters
2514 ----------
2514 ----------
2515 mod_name : string
2515 mod_name : string
2516 The name of the module to be executed.
2516 The name of the module to be executed.
2517 where : dict
2517 where : dict
2518 The globals namespace.
2518 The globals namespace.
2519 """
2519 """
2520 try:
2520 try:
2521 where.update(
2521 where.update(
2522 runpy.run_module(str(mod_name), run_name="__main__",
2522 runpy.run_module(str(mod_name), run_name="__main__",
2523 alter_sys=True)
2523 alter_sys=True)
2524 )
2524 )
2525 except:
2525 except:
2526 self.showtraceback()
2526 self.showtraceback()
2527 warn('Unknown failure executing module: <%s>' % mod_name)
2527 warn('Unknown failure executing module: <%s>' % mod_name)
2528
2528
2529 def _run_cached_cell_magic(self, magic_name, line):
2529 def _run_cached_cell_magic(self, magic_name, line):
2530 """Special method to call a cell magic with the data stored in self.
2530 """Special method to call a cell magic with the data stored in self.
2531 """
2531 """
2532 cell = self._current_cell_magic_body
2532 cell = self._current_cell_magic_body
2533 self._current_cell_magic_body = None
2533 self._current_cell_magic_body = None
2534 return self.run_cell_magic(magic_name, line, cell)
2534 return self.run_cell_magic(magic_name, line, cell)
2535
2535
2536 def run_cell(self, raw_cell, store_history=False, silent=False):
2536 def run_cell(self, raw_cell, store_history=False, silent=False):
2537 """Run a complete IPython cell.
2537 """Run a complete IPython cell.
2538
2538
2539 Parameters
2539 Parameters
2540 ----------
2540 ----------
2541 raw_cell : str
2541 raw_cell : str
2542 The code (including IPython code such as %magic functions) to run.
2542 The code (including IPython code such as %magic functions) to run.
2543 store_history : bool
2543 store_history : bool
2544 If True, the raw and translated cell will be stored in IPython's
2544 If True, the raw and translated cell will be stored in IPython's
2545 history. For user code calling back into IPython's machinery, this
2545 history. For user code calling back into IPython's machinery, this
2546 should be set to False.
2546 should be set to False.
2547 silent : bool
2547 silent : bool
2548 If True, avoid side-effects, such as implicit displayhooks and
2548 If True, avoid side-effects, such as implicit displayhooks and
2549 and logging. silent=True forces store_history=False.
2549 and logging. silent=True forces store_history=False.
2550 """
2550 """
2551 if (not raw_cell) or raw_cell.isspace():
2551 if (not raw_cell) or raw_cell.isspace():
2552 return
2552 return
2553
2553
2554 if silent:
2554 if silent:
2555 store_history = False
2555 store_history = False
2556
2556
2557 self.input_splitter.push(raw_cell)
2557 self.input_splitter.push(raw_cell)
2558
2558
2559 # Check for cell magics, which leave state behind. This interface is
2559 # Check for cell magics, which leave state behind. This interface is
2560 # ugly, we need to do something cleaner later... Now the logic is
2560 # ugly, we need to do something cleaner later... Now the logic is
2561 # simply that the input_splitter remembers if there was a cell magic,
2561 # simply that the input_splitter remembers if there was a cell magic,
2562 # and in that case we grab the cell body.
2562 # and in that case we grab the cell body.
2563 if self.input_splitter.cell_magic_parts:
2563 if self.input_splitter.cell_magic_parts:
2564 self._current_cell_magic_body = \
2564 self._current_cell_magic_body = \
2565 ''.join(self.input_splitter.cell_magic_parts)
2565 ''.join(self.input_splitter.cell_magic_parts)
2566 cell = self.input_splitter.source_reset()
2566 cell = self.input_splitter.source_reset()
2567
2567
2568 with self.builtin_trap:
2568 with self.builtin_trap:
2569 prefilter_failed = False
2569 prefilter_failed = False
2570 if len(cell.splitlines()) == 1:
2570 if len(cell.splitlines()) == 1:
2571 try:
2571 try:
2572 # use prefilter_lines to handle trailing newlines
2572 # use prefilter_lines to handle trailing newlines
2573 # restore trailing newline for ast.parse
2573 # restore trailing newline for ast.parse
2574 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2574 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2575 except AliasError as e:
2575 except AliasError as e:
2576 error(e)
2576 error(e)
2577 prefilter_failed = True
2577 prefilter_failed = True
2578 except Exception:
2578 except Exception:
2579 # don't allow prefilter errors to crash IPython
2579 # don't allow prefilter errors to crash IPython
2580 self.showtraceback()
2580 self.showtraceback()
2581 prefilter_failed = True
2581 prefilter_failed = True
2582
2582
2583 # Store raw and processed history
2583 # Store raw and processed history
2584 if store_history:
2584 if store_history:
2585 self.history_manager.store_inputs(self.execution_count,
2585 self.history_manager.store_inputs(self.execution_count,
2586 cell, raw_cell)
2586 cell, raw_cell)
2587 if not silent:
2587 if not silent:
2588 self.logger.log(cell, raw_cell)
2588 self.logger.log(cell, raw_cell)
2589
2589
2590 if not prefilter_failed:
2590 if not prefilter_failed:
2591 # don't run if prefilter failed
2591 # don't run if prefilter failed
2592 cell_name = self.compile.cache(cell, self.execution_count)
2592 cell_name = self.compile.cache(cell, self.execution_count)
2593
2593
2594 with self.display_trap:
2594 with self.display_trap:
2595 try:
2595 try:
2596 code_ast = self.compile.ast_parse(cell,
2596 code_ast = self.compile.ast_parse(cell,
2597 filename=cell_name)
2597 filename=cell_name)
2598 except IndentationError:
2598 except IndentationError:
2599 self.showindentationerror()
2599 self.showindentationerror()
2600 if store_history:
2600 if store_history:
2601 self.execution_count += 1
2601 self.execution_count += 1
2602 return None
2602 return None
2603 except (OverflowError, SyntaxError, ValueError, TypeError,
2603 except (OverflowError, SyntaxError, ValueError, TypeError,
2604 MemoryError):
2604 MemoryError):
2605 self.showsyntaxerror()
2605 self.showsyntaxerror()
2606 if store_history:
2606 if store_history:
2607 self.execution_count += 1
2607 self.execution_count += 1
2608 return None
2608 return None
2609
2609
2610 interactivity = "none" if silent else self.ast_node_interactivity
2610 interactivity = "none" if silent else self.ast_node_interactivity
2611 self.run_ast_nodes(code_ast.body, cell_name,
2611 self.run_ast_nodes(code_ast.body, cell_name,
2612 interactivity=interactivity)
2612 interactivity=interactivity)
2613
2613
2614 # Execute any registered post-execution functions.
2614 # Execute any registered post-execution functions.
2615 # unless we are silent
2615 # unless we are silent
2616 post_exec = [] if silent else self._post_execute.iteritems()
2616 post_exec = [] if silent else self._post_execute.iteritems()
2617
2617
2618 for func, status in post_exec:
2618 for func, status in post_exec:
2619 if self.disable_failing_post_execute and not status:
2619 if self.disable_failing_post_execute and not status:
2620 continue
2620 continue
2621 try:
2621 try:
2622 func()
2622 func()
2623 except KeyboardInterrupt:
2623 except KeyboardInterrupt:
2624 print("\nKeyboardInterrupt", file=io.stderr)
2624 print("\nKeyboardInterrupt", file=io.stderr)
2625 except Exception:
2625 except Exception:
2626 # register as failing:
2626 # register as failing:
2627 self._post_execute[func] = False
2627 self._post_execute[func] = False
2628 self.showtraceback()
2628 self.showtraceback()
2629 print('\n'.join([
2629 print('\n'.join([
2630 "post-execution function %r produced an error." % func,
2630 "post-execution function %r produced an error." % func,
2631 "If this problem persists, you can disable failing post-exec functions with:",
2631 "If this problem persists, you can disable failing post-exec functions with:",
2632 "",
2632 "",
2633 " get_ipython().disable_failing_post_execute = True"
2633 " get_ipython().disable_failing_post_execute = True"
2634 ]), file=io.stderr)
2634 ]), file=io.stderr)
2635
2635
2636 if store_history:
2636 if store_history:
2637 # Write output to the database. Does nothing unless
2637 # Write output to the database. Does nothing unless
2638 # history output logging is enabled.
2638 # history output logging is enabled.
2639 self.history_manager.store_output(self.execution_count)
2639 self.history_manager.store_output(self.execution_count)
2640 # Each cell is a *single* input, regardless of how many lines it has
2640 # Each cell is a *single* input, regardless of how many lines it has
2641 self.execution_count += 1
2641 self.execution_count += 1
2642
2642
2643 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr'):
2643 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr'):
2644 """Run a sequence of AST nodes. The execution mode depends on the
2644 """Run a sequence of AST nodes. The execution mode depends on the
2645 interactivity parameter.
2645 interactivity parameter.
2646
2646
2647 Parameters
2647 Parameters
2648 ----------
2648 ----------
2649 nodelist : list
2649 nodelist : list
2650 A sequence of AST nodes to run.
2650 A sequence of AST nodes to run.
2651 cell_name : str
2651 cell_name : str
2652 Will be passed to the compiler as the filename of the cell. Typically
2652 Will be passed to the compiler as the filename of the cell. Typically
2653 the value returned by ip.compile.cache(cell).
2653 the value returned by ip.compile.cache(cell).
2654 interactivity : str
2654 interactivity : str
2655 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
2655 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
2656 run interactively (displaying output from expressions). 'last_expr'
2656 run interactively (displaying output from expressions). 'last_expr'
2657 will run the last node interactively only if it is an expression (i.e.
2657 will run the last node interactively only if it is an expression (i.e.
2658 expressions in loops or other blocks are not displayed. Other values
2658 expressions in loops or other blocks are not displayed. Other values
2659 for this parameter will raise a ValueError.
2659 for this parameter will raise a ValueError.
2660 """
2660 """
2661 if not nodelist:
2661 if not nodelist:
2662 return
2662 return
2663
2663
2664 if interactivity == 'last_expr':
2664 if interactivity == 'last_expr':
2665 if isinstance(nodelist[-1], ast.Expr):
2665 if isinstance(nodelist[-1], ast.Expr):
2666 interactivity = "last"
2666 interactivity = "last"
2667 else:
2667 else:
2668 interactivity = "none"
2668 interactivity = "none"
2669
2669
2670 if interactivity == 'none':
2670 if interactivity == 'none':
2671 to_run_exec, to_run_interactive = nodelist, []
2671 to_run_exec, to_run_interactive = nodelist, []
2672 elif interactivity == 'last':
2672 elif interactivity == 'last':
2673 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
2673 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
2674 elif interactivity == 'all':
2674 elif interactivity == 'all':
2675 to_run_exec, to_run_interactive = [], nodelist
2675 to_run_exec, to_run_interactive = [], nodelist
2676 else:
2676 else:
2677 raise ValueError("Interactivity was %r" % interactivity)
2677 raise ValueError("Interactivity was %r" % interactivity)
2678
2678
2679 exec_count = self.execution_count
2679 exec_count = self.execution_count
2680
2680
2681 try:
2681 try:
2682 for i, node in enumerate(to_run_exec):
2682 for i, node in enumerate(to_run_exec):
2683 mod = ast.Module([node])
2683 mod = ast.Module([node])
2684 code = self.compile(mod, cell_name, "exec")
2684 code = self.compile(mod, cell_name, "exec")
2685 if self.run_code(code):
2685 if self.run_code(code):
2686 return True
2686 return True
2687
2687
2688 for i, node in enumerate(to_run_interactive):
2688 for i, node in enumerate(to_run_interactive):
2689 mod = ast.Interactive([node])
2689 mod = ast.Interactive([node])
2690 code = self.compile(mod, cell_name, "single")
2690 code = self.compile(mod, cell_name, "single")
2691 if self.run_code(code):
2691 if self.run_code(code):
2692 return True
2692 return True
2693
2693
2694 # Flush softspace
2694 # Flush softspace
2695 if softspace(sys.stdout, 0):
2695 if softspace(sys.stdout, 0):
2696 print()
2696 print()
2697
2697
2698 except:
2698 except:
2699 # It's possible to have exceptions raised here, typically by
2699 # It's possible to have exceptions raised here, typically by
2700 # compilation of odd code (such as a naked 'return' outside a
2700 # compilation of odd code (such as a naked 'return' outside a
2701 # function) that did parse but isn't valid. Typically the exception
2701 # function) that did parse but isn't valid. Typically the exception
2702 # is a SyntaxError, but it's safest just to catch anything and show
2702 # is a SyntaxError, but it's safest just to catch anything and show
2703 # the user a traceback.
2703 # the user a traceback.
2704
2704
2705 # We do only one try/except outside the loop to minimize the impact
2705 # We do only one try/except outside the loop to minimize the impact
2706 # on runtime, and also because if any node in the node list is
2706 # on runtime, and also because if any node in the node list is
2707 # broken, we should stop execution completely.
2707 # broken, we should stop execution completely.
2708 self.showtraceback()
2708 self.showtraceback()
2709
2709
2710 return False
2710 return False
2711
2711
2712 def run_code(self, code_obj):
2712 def run_code(self, code_obj):
2713 """Execute a code object.
2713 """Execute a code object.
2714
2714
2715 When an exception occurs, self.showtraceback() is called to display a
2715 When an exception occurs, self.showtraceback() is called to display a
2716 traceback.
2716 traceback.
2717
2717
2718 Parameters
2718 Parameters
2719 ----------
2719 ----------
2720 code_obj : code object
2720 code_obj : code object
2721 A compiled code object, to be executed
2721 A compiled code object, to be executed
2722
2722
2723 Returns
2723 Returns
2724 -------
2724 -------
2725 False : successful execution.
2725 False : successful execution.
2726 True : an error occurred.
2726 True : an error occurred.
2727 """
2727 """
2728
2728
2729 # Set our own excepthook in case the user code tries to call it
2729 # Set our own excepthook in case the user code tries to call it
2730 # directly, so that the IPython crash handler doesn't get triggered
2730 # directly, so that the IPython crash handler doesn't get triggered
2731 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2731 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2732
2732
2733 # we save the original sys.excepthook in the instance, in case config
2733 # we save the original sys.excepthook in the instance, in case config
2734 # code (such as magics) needs access to it.
2734 # code (such as magics) needs access to it.
2735 self.sys_excepthook = old_excepthook
2735 self.sys_excepthook = old_excepthook
2736 outflag = 1 # happens in more places, so it's easier as default
2736 outflag = 1 # happens in more places, so it's easier as default
2737 try:
2737 try:
2738 try:
2738 try:
2739 self.hooks.pre_run_code_hook()
2739 self.hooks.pre_run_code_hook()
2740 #rprint('Running code', repr(code_obj)) # dbg
2740 #rprint('Running code', repr(code_obj)) # dbg
2741 exec code_obj in self.user_global_ns, self.user_ns
2741 exec code_obj in self.user_global_ns, self.user_ns
2742 finally:
2742 finally:
2743 # Reset our crash handler in place
2743 # Reset our crash handler in place
2744 sys.excepthook = old_excepthook
2744 sys.excepthook = old_excepthook
2745 except SystemExit:
2745 except SystemExit:
2746 self.showtraceback(exception_only=True)
2746 self.showtraceback(exception_only=True)
2747 warn("To exit: use 'exit', 'quit', or Ctrl-D.", level=1)
2747 warn("To exit: use 'exit', 'quit', or Ctrl-D.", level=1)
2748 except self.custom_exceptions:
2748 except self.custom_exceptions:
2749 etype,value,tb = sys.exc_info()
2749 etype,value,tb = sys.exc_info()
2750 self.CustomTB(etype,value,tb)
2750 self.CustomTB(etype,value,tb)
2751 except:
2751 except:
2752 self.showtraceback()
2752 self.showtraceback()
2753 else:
2753 else:
2754 outflag = 0
2754 outflag = 0
2755 return outflag
2755 return outflag
2756
2756
2757 # For backwards compatibility
2757 # For backwards compatibility
2758 runcode = run_code
2758 runcode = run_code
2759
2759
2760 #-------------------------------------------------------------------------
2760 #-------------------------------------------------------------------------
2761 # Things related to GUI support and pylab
2761 # Things related to GUI support and pylab
2762 #-------------------------------------------------------------------------
2762 #-------------------------------------------------------------------------
2763
2763
2764 def enable_gui(self, gui=None):
2764 def enable_gui(self, gui=None):
2765 raise NotImplementedError('Implement enable_gui in a subclass')
2765 raise NotImplementedError('Implement enable_gui in a subclass')
2766
2766
2767 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
2767 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
2768 """Activate pylab support at runtime.
2768 """Activate pylab support at runtime.
2769
2769
2770 This turns on support for matplotlib, preloads into the interactive
2770 This turns on support for matplotlib, preloads into the interactive
2771 namespace all of numpy and pylab, and configures IPython to correctly
2771 namespace all of numpy and pylab, and configures IPython to correctly
2772 interact with the GUI event loop. The GUI backend to be used can be
2772 interact with the GUI event loop. The GUI backend to be used can be
2773 optionally selected with the optional :param:`gui` argument.
2773 optionally selected with the optional :param:`gui` argument.
2774
2774
2775 Parameters
2775 Parameters
2776 ----------
2776 ----------
2777 gui : optional, string
2777 gui : optional, string
2778
2778
2779 If given, dictates the choice of matplotlib GUI backend to use
2779 If given, dictates the choice of matplotlib GUI backend to use
2780 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2780 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2781 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2781 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2782 matplotlib (as dictated by the matplotlib build-time options plus the
2782 matplotlib (as dictated by the matplotlib build-time options plus the
2783 user's matplotlibrc configuration file). Note that not all backends
2783 user's matplotlibrc configuration file). Note that not all backends
2784 make sense in all contexts, for example a terminal ipython can't
2784 make sense in all contexts, for example a terminal ipython can't
2785 display figures inline.
2785 display figures inline.
2786 """
2786 """
2787 from IPython.core.pylabtools import mpl_runner
2787 from IPython.core.pylabtools import mpl_runner
2788 # We want to prevent the loading of pylab to pollute the user's
2788 # We want to prevent the loading of pylab to pollute the user's
2789 # namespace as shown by the %who* magics, so we execute the activation
2789 # namespace as shown by the %who* magics, so we execute the activation
2790 # code in an empty namespace, and we update *both* user_ns and
2790 # code in an empty namespace, and we update *both* user_ns and
2791 # user_ns_hidden with this information.
2791 # user_ns_hidden with this information.
2792 ns = {}
2792 ns = {}
2793 try:
2793 try:
2794 gui = pylab_activate(ns, gui, import_all, self, welcome_message=welcome_message)
2794 gui = pylab_activate(ns, gui, import_all, self, welcome_message=welcome_message)
2795 except KeyError:
2795 except KeyError:
2796 error("Backend %r not supported" % gui)
2796 error("Backend %r not supported" % gui)
2797 return
2797 return
2798 self.user_ns.update(ns)
2798 self.user_ns.update(ns)
2799 self.user_ns_hidden.update(ns)
2799 self.user_ns_hidden.update(ns)
2800 # Now we must activate the gui pylab wants to use, and fix %run to take
2800 # Now we must activate the gui pylab wants to use, and fix %run to take
2801 # plot updates into account
2801 # plot updates into account
2802 self.enable_gui(gui)
2802 self.enable_gui(gui)
2803 self.magics_manager.registry['ExecutionMagics'].default_runner = \
2803 self.magics_manager.registry['ExecutionMagics'].default_runner = \
2804 mpl_runner(self.safe_execfile)
2804 mpl_runner(self.safe_execfile)
2805
2805
2806 #-------------------------------------------------------------------------
2806 #-------------------------------------------------------------------------
2807 # Utilities
2807 # Utilities
2808 #-------------------------------------------------------------------------
2808 #-------------------------------------------------------------------------
2809
2809
2810 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
2810 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
2811 """Expand python variables in a string.
2811 """Expand python variables in a string.
2812
2812
2813 The depth argument indicates how many frames above the caller should
2813 The depth argument indicates how many frames above the caller should
2814 be walked to look for the local namespace where to expand variables.
2814 be walked to look for the local namespace where to expand variables.
2815
2815
2816 The global namespace for expansion is always the user's interactive
2816 The global namespace for expansion is always the user's interactive
2817 namespace.
2817 namespace.
2818 """
2818 """
2819 ns = self.user_ns.copy()
2819 ns = self.user_ns.copy()
2820 ns.update(sys._getframe(depth+1).f_locals)
2820 ns.update(sys._getframe(depth+1).f_locals)
2821 try:
2821 try:
2822 # We have to use .vformat() here, because 'self' is a valid and common
2822 # We have to use .vformat() here, because 'self' is a valid and common
2823 # name, and expanding **ns for .format() would make it collide with
2823 # name, and expanding **ns for .format() would make it collide with
2824 # the 'self' argument of the method.
2824 # the 'self' argument of the method.
2825 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
2825 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
2826 except Exception:
2826 except Exception:
2827 # if formatter couldn't format, just let it go untransformed
2827 # if formatter couldn't format, just let it go untransformed
2828 pass
2828 pass
2829 return cmd
2829 return cmd
2830
2830
2831 def mktempfile(self, data=None, prefix='ipython_edit_'):
2831 def mktempfile(self, data=None, prefix='ipython_edit_'):
2832 """Make a new tempfile and return its filename.
2832 """Make a new tempfile and return its filename.
2833
2833
2834 This makes a call to tempfile.mktemp, but it registers the created
2834 This makes a call to tempfile.mktemp, but it registers the created
2835 filename internally so ipython cleans it up at exit time.
2835 filename internally so ipython cleans it up at exit time.
2836
2836
2837 Optional inputs:
2837 Optional inputs:
2838
2838
2839 - data(None): if data is given, it gets written out to the temp file
2839 - data(None): if data is given, it gets written out to the temp file
2840 immediately, and the file is closed again."""
2840 immediately, and the file is closed again."""
2841
2841
2842 filename = tempfile.mktemp('.py', prefix)
2842 filename = tempfile.mktemp('.py', prefix)
2843 self.tempfiles.append(filename)
2843 self.tempfiles.append(filename)
2844
2844
2845 if data:
2845 if data:
2846 tmp_file = open(filename,'w')
2846 tmp_file = open(filename,'w')
2847 tmp_file.write(data)
2847 tmp_file.write(data)
2848 tmp_file.close()
2848 tmp_file.close()
2849 return filename
2849 return filename
2850
2850
2851 # TODO: This should be removed when Term is refactored.
2851 # TODO: This should be removed when Term is refactored.
2852 def write(self,data):
2852 def write(self,data):
2853 """Write a string to the default output"""
2853 """Write a string to the default output"""
2854 io.stdout.write(data)
2854 io.stdout.write(data)
2855
2855
2856 # TODO: This should be removed when Term is refactored.
2856 # TODO: This should be removed when Term is refactored.
2857 def write_err(self,data):
2857 def write_err(self,data):
2858 """Write a string to the default error output"""
2858 """Write a string to the default error output"""
2859 io.stderr.write(data)
2859 io.stderr.write(data)
2860
2860
2861 def ask_yes_no(self, prompt, default=None):
2861 def ask_yes_no(self, prompt, default=None):
2862 if self.quiet:
2862 if self.quiet:
2863 return True
2863 return True
2864 return ask_yes_no(prompt,default)
2864 return ask_yes_no(prompt,default)
2865
2865
2866 def show_usage(self):
2866 def show_usage(self):
2867 """Show a usage message"""
2867 """Show a usage message"""
2868 page.page(IPython.core.usage.interactive_usage)
2868 page.page(IPython.core.usage.interactive_usage)
2869
2869
2870 def extract_input_lines(self, range_str, raw=False):
2870 def extract_input_lines(self, range_str, raw=False):
2871 """Return as a string a set of input history slices.
2871 """Return as a string a set of input history slices.
2872
2872
2873 Parameters
2873 Parameters
2874 ----------
2874 ----------
2875 range_str : string
2875 range_str : string
2876 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
2876 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
2877 since this function is for use by magic functions which get their
2877 since this function is for use by magic functions which get their
2878 arguments as strings. The number before the / is the session
2878 arguments as strings. The number before the / is the session
2879 number: ~n goes n back from the current session.
2879 number: ~n goes n back from the current session.
2880
2880
2881 Optional Parameters:
2881 Optional Parameters:
2882 - raw(False): by default, the processed input is used. If this is
2882 - raw(False): by default, the processed input is used. If this is
2883 true, the raw input history is used instead.
2883 true, the raw input history is used instead.
2884
2884
2885 Note that slices can be called with two notations:
2885 Note that slices can be called with two notations:
2886
2886
2887 N:M -> standard python form, means including items N...(M-1).
2887 N:M -> standard python form, means including items N...(M-1).
2888
2888
2889 N-M -> include items N..M (closed endpoint)."""
2889 N-M -> include items N..M (closed endpoint)."""
2890 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
2890 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
2891 return "\n".join(x for _, _, x in lines)
2891 return "\n".join(x for _, _, x in lines)
2892
2892
2893 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True):
2893 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True):
2894 """Get a code string from history, file, url, or a string or macro.
2894 """Get a code string from history, file, url, or a string or macro.
2895
2895
2896 This is mainly used by magic functions.
2896 This is mainly used by magic functions.
2897
2897
2898 Parameters
2898 Parameters
2899 ----------
2899 ----------
2900
2900
2901 target : str
2901 target : str
2902
2902
2903 A string specifying code to retrieve. This will be tried respectively
2903 A string specifying code to retrieve. This will be tried respectively
2904 as: ranges of input history (see %history for syntax), url,
2904 as: ranges of input history (see %history for syntax), url,
2905 correspnding .py file, filename, or an expression evaluating to a
2905 correspnding .py file, filename, or an expression evaluating to a
2906 string or Macro in the user namespace.
2906 string or Macro in the user namespace.
2907
2907
2908 raw : bool
2908 raw : bool
2909 If true (default), retrieve raw history. Has no effect on the other
2909 If true (default), retrieve raw history. Has no effect on the other
2910 retrieval mechanisms.
2910 retrieval mechanisms.
2911
2911
2912 py_only : bool (default False)
2912 py_only : bool (default False)
2913 Only try to fetch python code, do not try alternative methods to decode file
2913 Only try to fetch python code, do not try alternative methods to decode file
2914 if unicode fails.
2914 if unicode fails.
2915
2915
2916 Returns
2916 Returns
2917 -------
2917 -------
2918 A string of code.
2918 A string of code.
2919
2919
2920 ValueError is raised if nothing is found, and TypeError if it evaluates
2920 ValueError is raised if nothing is found, and TypeError if it evaluates
2921 to an object of another type. In each case, .args[0] is a printable
2921 to an object of another type. In each case, .args[0] is a printable
2922 message.
2922 message.
2923 """
2923 """
2924 code = self.extract_input_lines(target, raw=raw) # Grab history
2924 code = self.extract_input_lines(target, raw=raw) # Grab history
2925 if code:
2925 if code:
2926 return code
2926 return code
2927 utarget = unquote_filename(target)
2927 utarget = unquote_filename(target)
2928 try:
2928 try:
2929 if utarget.startswith(('http://', 'https://')):
2929 if utarget.startswith(('http://', 'https://')):
2930 return openpy.read_py_url(utarget, skip_encoding_cookie=skip_encoding_cookie)
2930 return openpy.read_py_url(utarget, skip_encoding_cookie=skip_encoding_cookie)
2931 except UnicodeDecodeError:
2931 except UnicodeDecodeError:
2932 if not py_only :
2932 if not py_only :
2933 response = urllib.urlopen(target)
2933 response = urllib.urlopen(target)
2934 return response.read().decode('latin1')
2934 return response.read().decode('latin1')
2935 raise ValueError(("'%s' seem to be unreadable.") % utarget)
2935 raise ValueError(("'%s' seem to be unreadable.") % utarget)
2936
2936
2937 potential_target = [target]
2937 potential_target = [target]
2938 try :
2938 try :
2939 potential_target.insert(0,get_py_filename(target))
2939 potential_target.insert(0,get_py_filename(target))
2940 except IOError:
2940 except IOError:
2941 pass
2941 pass
2942
2942
2943 for tgt in potential_target :
2943 for tgt in potential_target :
2944 if os.path.isfile(tgt): # Read file
2944 if os.path.isfile(tgt): # Read file
2945 try :
2945 try :
2946 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
2946 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
2947 except UnicodeDecodeError :
2947 except UnicodeDecodeError :
2948 if not py_only :
2948 if not py_only :
2949 with io_open(tgt,'r', encoding='latin1') as f :
2949 with io_open(tgt,'r', encoding='latin1') as f :
2950 return f.read()
2950 return f.read()
2951 raise ValueError(("'%s' seem to be unreadable.") % target)
2951 raise ValueError(("'%s' seem to be unreadable.") % target)
2952
2952
2953 try: # User namespace
2953 try: # User namespace
2954 codeobj = eval(target, self.user_ns)
2954 codeobj = eval(target, self.user_ns)
2955 except Exception:
2955 except Exception:
2956 raise ValueError(("'%s' was not found in history, as a file, url, "
2956 raise ValueError(("'%s' was not found in history, as a file, url, "
2957 "nor in the user namespace.") % target)
2957 "nor in the user namespace.") % target)
2958 if isinstance(codeobj, basestring):
2958 if isinstance(codeobj, basestring):
2959 return codeobj
2959 return codeobj
2960 elif isinstance(codeobj, Macro):
2960 elif isinstance(codeobj, Macro):
2961 return codeobj.value
2961 return codeobj.value
2962
2962
2963 raise TypeError("%s is neither a string nor a macro." % target,
2963 raise TypeError("%s is neither a string nor a macro." % target,
2964 codeobj)
2964 codeobj)
2965
2965
2966 #-------------------------------------------------------------------------
2966 #-------------------------------------------------------------------------
2967 # Things related to IPython exiting
2967 # Things related to IPython exiting
2968 #-------------------------------------------------------------------------
2968 #-------------------------------------------------------------------------
2969 def atexit_operations(self):
2969 def atexit_operations(self):
2970 """This will be executed at the time of exit.
2970 """This will be executed at the time of exit.
2971
2971
2972 Cleanup operations and saving of persistent data that is done
2972 Cleanup operations and saving of persistent data that is done
2973 unconditionally by IPython should be performed here.
2973 unconditionally by IPython should be performed here.
2974
2974
2975 For things that may depend on startup flags or platform specifics (such
2975 For things that may depend on startup flags or platform specifics (such
2976 as having readline or not), register a separate atexit function in the
2976 as having readline or not), register a separate atexit function in the
2977 code that has the appropriate information, rather than trying to
2977 code that has the appropriate information, rather than trying to
2978 clutter
2978 clutter
2979 """
2979 """
2980 # Close the history session (this stores the end time and line count)
2980 # Close the history session (this stores the end time and line count)
2981 # this must be *before* the tempfile cleanup, in case of temporary
2981 # this must be *before* the tempfile cleanup, in case of temporary
2982 # history db
2982 # history db
2983 self.history_manager.end_session()
2983 self.history_manager.end_session()
2984
2984
2985 # Cleanup all tempfiles left around
2985 # Cleanup all tempfiles left around
2986 for tfile in self.tempfiles:
2986 for tfile in self.tempfiles:
2987 try:
2987 try:
2988 os.unlink(tfile)
2988 os.unlink(tfile)
2989 except OSError:
2989 except OSError:
2990 pass
2990 pass
2991
2991
2992 # Clear all user namespaces to release all references cleanly.
2992 # Clear all user namespaces to release all references cleanly.
2993 self.reset(new_session=False)
2993 self.reset(new_session=False)
2994
2994
2995 # Run user hooks
2995 # Run user hooks
2996 self.hooks.shutdown_hook()
2996 self.hooks.shutdown_hook()
2997
2997
2998 def cleanup(self):
2998 def cleanup(self):
2999 self.restore_sys_module_state()
2999 self.restore_sys_module_state()
3000
3000
3001
3001
3002 class InteractiveShellABC(object):
3002 class InteractiveShellABC(object):
3003 """An abstract base class for InteractiveShell."""
3003 """An abstract base class for InteractiveShell."""
3004 __metaclass__ = abc.ABCMeta
3004 __metaclass__ = abc.ABCMeta
3005
3005
3006 InteractiveShellABC.register(InteractiveShell)
3006 InteractiveShellABC.register(InteractiveShell)
@@ -1,222 +1,241 b''
1 ''' A decorator-based method of constructing IPython magics with `argparse`
1 ''' A decorator-based method of constructing IPython magics with `argparse`
2 option handling.
2 option handling.
3
3
4 New magic functions can be defined like so::
4 New magic functions can be defined like so::
5
5
6 from IPython.core.magic_arguments import (argument, magic_arguments,
6 from IPython.core.magic_arguments import (argument, magic_arguments,
7 parse_argstring)
7 parse_argstring)
8
8
9 @magic_arguments()
9 @magic_arguments()
10 @argument('-o', '--option', help='An optional argument.')
10 @argument('-o', '--option', help='An optional argument.')
11 @argument('arg', type=int, help='An integer positional argument.')
11 @argument('arg', type=int, help='An integer positional argument.')
12 def magic_cool(self, arg):
12 def magic_cool(self, arg):
13 """ A really cool magic command.
13 """ A really cool magic command.
14
14
15 """
15 """
16 args = parse_argstring(magic_cool, arg)
16 args = parse_argstring(magic_cool, arg)
17 ...
17 ...
18
18
19 The `@magic_arguments` decorator marks the function as having argparse arguments.
19 The `@magic_arguments` decorator marks the function as having argparse arguments.
20 The `@argument` decorator adds an argument using the same syntax as argparse's
20 The `@argument` decorator adds an argument using the same syntax as argparse's
21 `add_argument()` method. More sophisticated uses may also require the
21 `add_argument()` method. More sophisticated uses may also require the
22 `@argument_group` or `@kwds` decorator to customize the formatting and the
22 `@argument_group` or `@kwds` decorator to customize the formatting and the
23 parsing.
23 parsing.
24
24
25 Help text for the magic is automatically generated from the docstring and the
25 Help text for the magic is automatically generated from the docstring and the
26 arguments::
26 arguments::
27
27
28 In[1]: %cool?
28 In[1]: %cool?
29 %cool [-o OPTION] arg
29 %cool [-o OPTION] arg
30
30
31 A really cool magic command.
31 A really cool magic command.
32
32
33 positional arguments:
33 positional arguments:
34 arg An integer positional argument.
34 arg An integer positional argument.
35
35
36 optional arguments:
36 optional arguments:
37 -o OPTION, --option OPTION
37 -o OPTION, --option OPTION
38 An optional argument.
38 An optional argument.
39
39
40 '''
40 '''
41 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
42 # Copyright (C) 2010-2011, IPython Development Team.
42 # Copyright (C) 2010-2011, IPython Development Team.
43 #
43 #
44 # Distributed under the terms of the Modified BSD License.
44 # Distributed under the terms of the Modified BSD License.
45 #
45 #
46 # The full license is in the file COPYING.txt, distributed with this software.
46 # The full license is in the file COPYING.txt, distributed with this software.
47 #-----------------------------------------------------------------------------
47 #-----------------------------------------------------------------------------
48
48
49 # Our own imports
49 # Our own imports
50 from IPython.external import argparse
50 from IPython.external import argparse
51 from IPython.core.error import UsageError
51 from IPython.core.error import UsageError
52 from IPython.utils.process import arg_split
52 from IPython.utils.process import arg_split
53 from IPython.utils.text import dedent
53 from IPython.utils.text import dedent
54
54
55 class MagicHelpFormatter(argparse.RawDescriptionHelpFormatter):
55 class MagicHelpFormatter(argparse.RawDescriptionHelpFormatter):
56 """ A HelpFormatter which dedents but otherwise preserves indentation.
56 """ A HelpFormatter which dedents but otherwise preserves indentation.
57 """
57 """
58 def _fill_text(self, text, width, indent):
58 def _fill_text(self, text, width, indent):
59 return argparse.RawDescriptionHelpFormatter._fill_text(self, dedent(text), width, indent)
59 return argparse.RawDescriptionHelpFormatter._fill_text(self, dedent(text), width, indent)
60
60
61 class MagicArgumentParser(argparse.ArgumentParser):
61 class MagicArgumentParser(argparse.ArgumentParser):
62 """ An ArgumentParser tweaked for use by IPython magics.
62 """ An ArgumentParser tweaked for use by IPython magics.
63 """
63 """
64 def __init__(self,
64 def __init__(self,
65 prog=None,
65 prog=None,
66 usage=None,
66 usage=None,
67 description=None,
67 description=None,
68 epilog=None,
68 epilog=None,
69 parents=None,
69 parents=None,
70 formatter_class=MagicHelpFormatter,
70 formatter_class=MagicHelpFormatter,
71 prefix_chars='-',
71 prefix_chars='-',
72 argument_default=None,
72 argument_default=None,
73 conflict_handler='error',
73 conflict_handler='error',
74 add_help=False):
74 add_help=False):
75 if parents is None:
75 if parents is None:
76 parents = []
76 parents = []
77 super(MagicArgumentParser, self).__init__(prog=prog, usage=usage,
77 super(MagicArgumentParser, self).__init__(prog=prog, usage=usage,
78 description=description, epilog=epilog,
78 description=description, epilog=epilog,
79 parents=parents, formatter_class=formatter_class,
79 parents=parents, formatter_class=formatter_class,
80 prefix_chars=prefix_chars, argument_default=argument_default,
80 prefix_chars=prefix_chars, argument_default=argument_default,
81 conflict_handler=conflict_handler, add_help=add_help)
81 conflict_handler=conflict_handler, add_help=add_help)
82
82
83 def error(self, message):
83 def error(self, message):
84 """ Raise a catchable error instead of exiting.
84 """ Raise a catchable error instead of exiting.
85 """
85 """
86 raise UsageError(message)
86 raise UsageError(message)
87
87
88 def parse_argstring(self, argstring):
88 def parse_argstring(self, argstring):
89 """ Split a string into an argument list and parse that argument list.
89 """ Split a string into an argument list and parse that argument list.
90 """
90 """
91 argv = arg_split(argstring)
91 argv = arg_split(argstring)
92 return self.parse_args(argv)
92 return self.parse_args(argv)
93
93
94
94
95 def construct_parser(magic_func):
95 def construct_parser(magic_func):
96 """ Construct an argument parser using the function decorations.
96 """ Construct an argument parser using the function decorations.
97 """
97 """
98 kwds = getattr(magic_func, 'argcmd_kwds', {})
98 kwds = getattr(magic_func, 'argcmd_kwds', {})
99 if 'description' not in kwds:
99 if 'description' not in kwds:
100 kwds['description'] = getattr(magic_func, '__doc__', None)
100 kwds['description'] = getattr(magic_func, '__doc__', None)
101 arg_name = real_name(magic_func)
101 arg_name = real_name(magic_func)
102 parser = MagicArgumentParser(arg_name, **kwds)
102 parser = MagicArgumentParser(arg_name, **kwds)
103 # Reverse the list of decorators in order to apply them in the
103 # Reverse the list of decorators in order to apply them in the
104 # order in which they appear in the source.
104 # order in which they appear in the source.
105 group = None
105 group = None
106 for deco in magic_func.decorators[::-1]:
106 for deco in magic_func.decorators[::-1]:
107 result = deco.add_to_parser(parser, group)
107 result = deco.add_to_parser(parser, group)
108 if result is not None:
108 if result is not None:
109 group = result
109 group = result
110
110
111 # Replace the starting 'usage: ' with IPython's %.
111 # Replace the starting 'usage: ' with IPython's %.
112 help_text = parser.format_help()
112 help_text = parser.format_help()
113 if help_text.startswith('usage: '):
113 if help_text.startswith('usage: '):
114 help_text = help_text.replace('usage: ', '%', 1)
114 help_text = help_text.replace('usage: ', '%', 1)
115 else:
115 else:
116 help_text = '%' + help_text
116 help_text = '%' + help_text
117
117
118 # Replace the magic function's docstring with the full help text.
118 # Replace the magic function's docstring with the full help text.
119 magic_func.__doc__ = help_text
119 magic_func.__doc__ = help_text
120
120
121 return parser
121 return parser
122
122
123
123
124 def parse_argstring(magic_func, argstring):
124 def parse_argstring(magic_func, argstring):
125 """ Parse the string of arguments for the given magic function.
125 """ Parse the string of arguments for the given magic function.
126 """
126 """
127 return magic_func.parser.parse_argstring(argstring)
127 return magic_func.parser.parse_argstring(argstring)
128
128
129
129
130 def real_name(magic_func):
130 def real_name(magic_func):
131 """ Find the real name of the magic.
131 """ Find the real name of the magic.
132 """
132 """
133 magic_name = magic_func.__name__
133 magic_name = magic_func.__name__
134 if magic_name.startswith('magic_'):
134 if magic_name.startswith('magic_'):
135 magic_name = magic_name[len('magic_'):]
135 magic_name = magic_name[len('magic_'):]
136 return getattr(magic_func, 'argcmd_name', magic_name)
136 return getattr(magic_func, 'argcmd_name', magic_name)
137
137
138
138
139 class ArgDecorator(object):
139 class ArgDecorator(object):
140 """ Base class for decorators to add ArgumentParser information to a method.
140 """ Base class for decorators to add ArgumentParser information to a method.
141 """
141 """
142
142
143 def __call__(self, func):
143 def __call__(self, func):
144 if not getattr(func, 'has_arguments', False):
144 if not getattr(func, 'has_arguments', False):
145 func.has_arguments = True
145 func.has_arguments = True
146 func.decorators = []
146 func.decorators = []
147 func.decorators.append(self)
147 func.decorators.append(self)
148 return func
148 return func
149
149
150 def add_to_parser(self, parser, group):
150 def add_to_parser(self, parser, group):
151 """ Add this object's information to the parser, if necessary.
151 """ Add this object's information to the parser, if necessary.
152 """
152 """
153 pass
153 pass
154
154
155
155
156 class magic_arguments(ArgDecorator):
156 class magic_arguments(ArgDecorator):
157 """ Mark the magic as having argparse arguments and possibly adjust the
157 """ Mark the magic as having argparse arguments and possibly adjust the
158 name.
158 name.
159 """
159 """
160
160
161 def __init__(self, name=None):
161 def __init__(self, name=None):
162 self.name = name
162 self.name = name
163
163
164 def __call__(self, func):
164 def __call__(self, func):
165 if not getattr(func, 'has_arguments', False):
165 if not getattr(func, 'has_arguments', False):
166 func.has_arguments = True
166 func.has_arguments = True
167 func.decorators = []
167 func.decorators = []
168 if self.name is not None:
168 if self.name is not None:
169 func.argcmd_name = self.name
169 func.argcmd_name = self.name
170 # This should be the first decorator in the list of decorators, thus the
170 # This should be the first decorator in the list of decorators, thus the
171 # last to execute. Build the parser.
171 # last to execute. Build the parser.
172 func.parser = construct_parser(func)
172 func.parser = construct_parser(func)
173 return func
173 return func
174
174
175
175
176 class argument(ArgDecorator):
176 class ArgMethodWrapper(ArgDecorator):
177 """ Store arguments and keywords to pass to add_argument().
177
178 """
179 Base class to define a wrapper for ArgumentParser method.
180
181 Child class must define either `_method_name` or `add_to_parser`.
178
182
179 Instances also serve to decorate command methods.
180 """
183 """
184
185 _method_name = None
186
181 def __init__(self, *args, **kwds):
187 def __init__(self, *args, **kwds):
182 self.args = args
188 self.args = args
183 self.kwds = kwds
189 self.kwds = kwds
184
190
185 def add_to_parser(self, parser, group):
191 def add_to_parser(self, parser, group):
186 """ Add this object's information to the parser.
192 """ Add this object's information to the parser.
187 """
193 """
188 if group is not None:
194 if group is not None:
189 parser = group
195 parser = group
190 parser.add_argument(*self.args, **self.kwds)
196 getattr(parser, self._method_name)(*self.args, **self.kwds)
191 return None
197 return None
192
198
193
199
194 class argument_group(ArgDecorator):
200 class argument(ArgMethodWrapper):
201 """ Store arguments and keywords to pass to add_argument().
202
203 Instances also serve to decorate command methods.
204 """
205 _method_name = 'add_argument'
206
207
208 class defaults(ArgMethodWrapper):
209 """ Store arguments and keywords to pass to set_defaults().
210
211 Instances also serve to decorate command methods.
212 """
213 _method_name = 'set_defaults'
214
215
216 class argument_group(ArgMethodWrapper):
195 """ Store arguments and keywords to pass to add_argument_group().
217 """ Store arguments and keywords to pass to add_argument_group().
196
218
197 Instances also serve to decorate command methods.
219 Instances also serve to decorate command methods.
198 """
220 """
199 def __init__(self, *args, **kwds):
200 self.args = args
201 self.kwds = kwds
202
221
203 def add_to_parser(self, parser, group):
222 def add_to_parser(self, parser, group):
204 """ Add this object's information to the parser.
223 """ Add this object's information to the parser.
205 """
224 """
206 return parser.add_argument_group(*self.args, **self.kwds)
225 return parser.add_argument_group(*self.args, **self.kwds)
207
226
208
227
209 class kwds(ArgDecorator):
228 class kwds(ArgDecorator):
210 """ Provide other keywords to the sub-parser constructor.
229 """ Provide other keywords to the sub-parser constructor.
211 """
230 """
212 def __init__(self, **kwds):
231 def __init__(self, **kwds):
213 self.kwds = kwds
232 self.kwds = kwds
214
233
215 def __call__(self, func):
234 def __call__(self, func):
216 func = super(kwds, self).__call__(func)
235 func = super(kwds, self).__call__(func)
217 func.argcmd_kwds = self.kwds
236 func.argcmd_kwds = self.kwds
218 return func
237 return func
219
238
220
239
221 __all__ = ['magic_arguments', 'argument', 'argument_group', 'kwds',
240 __all__ = ['magic_arguments', 'argument', 'argument_group', 'kwds',
222 'parse_argstring']
241 'parse_argstring']
@@ -1,612 +1,613 b''
1 """Implementation of basic magic functions.
1 """Implementation of basic magic functions.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012 The IPython Development Team.
4 # Copyright (c) 2012 The IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
14 from __future__ import print_function
15
15
16 # Stdlib
16 # Stdlib
17 import io
17 import io
18 import sys
18 import sys
19 from pprint import pformat
19 from pprint import pformat
20
20
21 # Our own packages
21 # Our own packages
22 from IPython.core import magic_arguments
22 from IPython.core import magic_arguments
23 from IPython.core.error import UsageError
23 from IPython.core.error import UsageError
24 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
24 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
25 from IPython.utils.text import format_screen, dedent, indent
25 from IPython.utils.text import format_screen, dedent, indent
26 from IPython.core import magic_arguments, page
26 from IPython.core import magic_arguments, page
27 from IPython.testing.skipdoctest import skip_doctest
27 from IPython.testing.skipdoctest import skip_doctest
28 from IPython.utils.ipstruct import Struct
28 from IPython.utils.ipstruct import Struct
29 from IPython.utils.path import unquote_filename
29 from IPython.utils.path import unquote_filename
30 from IPython.utils.warn import warn, error
30 from IPython.utils.warn import warn, error
31
31
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33 # Magics class implementation
33 # Magics class implementation
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35
35
36 @magics_class
36 @magics_class
37 class BasicMagics(Magics):
37 class BasicMagics(Magics):
38 """Magics that provide central IPython functionality.
38 """Magics that provide central IPython functionality.
39
39
40 These are various magics that don't fit into specific categories but that
40 These are various magics that don't fit into specific categories but that
41 are all part of the base 'IPython experience'."""
41 are all part of the base 'IPython experience'."""
42
42
43 @magic_arguments.magic_arguments()
43 @magic_arguments.magic_arguments()
44 @magic_arguments.argument(
44 @magic_arguments.argument(
45 '-l', '--line', action='store_true',
45 '-l', '--line', action='store_true',
46 help="""Create a line magic alias."""
46 help="""Create a line magic alias."""
47 )
47 )
48 @magic_arguments.argument(
48 @magic_arguments.argument(
49 '-c', '--cell', action='store_true',
49 '-c', '--cell', action='store_true',
50 help="""Create a cell magic alias."""
50 help="""Create a cell magic alias."""
51 )
51 )
52 @magic_arguments.argument(
52 @magic_arguments.argument(
53 'name',
53 'name',
54 help="""Name of the magic to be created."""
54 help="""Name of the magic to be created."""
55 )
55 )
56 @magic_arguments.argument(
56 @magic_arguments.argument(
57 'target',
57 'target',
58 help="""Name of the existing line or cell magic."""
58 help="""Name of the existing line or cell magic."""
59 )
59 )
60 @line_magic
60 @line_magic
61 def alias_magic(self, line=''):
61 def alias_magic(self, line=''):
62 """Create an alias for an existing line or cell magic.
62 """Create an alias for an existing line or cell magic.
63
63
64 Examples
64 Examples
65 --------
65 --------
66 ::
66 ::
67 In [1]: %alias_magic t timeit
67 In [1]: %alias_magic t timeit
68 Created `%t` as an alias for `%timeit`.
68 Created `%t` as an alias for `%timeit`.
69 Created `%%t` as an alias for `%%timeit`.
69 Created `%%t` as an alias for `%%timeit`.
70
70
71 In [2]: %t -n1 pass
71 In [2]: %t -n1 pass
72 1 loops, best of 3: 954 ns per loop
72 1 loops, best of 3: 954 ns per loop
73
73
74 In [3]: %%t -n1
74 In [3]: %%t -n1
75 ...: pass
75 ...: pass
76 ...:
76 ...:
77 1 loops, best of 3: 954 ns per loop
77 1 loops, best of 3: 954 ns per loop
78
78
79 In [4]: %alias_magic --cell whereami pwd
79 In [4]: %alias_magic --cell whereami pwd
80 UsageError: Cell magic function `%%pwd` not found.
80 UsageError: Cell magic function `%%pwd` not found.
81 In [5]: %alias_magic --line whereami pwd
81 In [5]: %alias_magic --line whereami pwd
82 Created `%whereami` as an alias for `%pwd`.
82 Created `%whereami` as an alias for `%pwd`.
83
83
84 In [6]: %whereami
84 In [6]: %whereami
85 Out[6]: u'/home/testuser'
85 Out[6]: u'/home/testuser'
86 """
86 """
87 args = magic_arguments.parse_argstring(self.alias_magic, line)
87 args = magic_arguments.parse_argstring(self.alias_magic, line)
88 shell = self.shell
88 shell = self.shell
89 mman = self.shell.magics_manager
89 mman = self.shell.magics_manager
90 escs = ''.join(magic_escapes.values())
90 escs = ''.join(magic_escapes.values())
91
91
92 target = args.target.lstrip(escs)
92 target = args.target.lstrip(escs)
93 name = args.name.lstrip(escs)
93 name = args.name.lstrip(escs)
94
94
95 # Find the requested magics.
95 # Find the requested magics.
96 m_line = shell.find_magic(target, 'line')
96 m_line = shell.find_magic(target, 'line')
97 m_cell = shell.find_magic(target, 'cell')
97 m_cell = shell.find_magic(target, 'cell')
98 if args.line and m_line is None:
98 if args.line and m_line is None:
99 raise UsageError('Line magic function `%s%s` not found.' %
99 raise UsageError('Line magic function `%s%s` not found.' %
100 (magic_escapes['line'], target))
100 (magic_escapes['line'], target))
101 if args.cell and m_cell is None:
101 if args.cell and m_cell is None:
102 raise UsageError('Cell magic function `%s%s` not found.' %
102 raise UsageError('Cell magic function `%s%s` not found.' %
103 (magic_escapes['cell'], target))
103 (magic_escapes['cell'], target))
104
104
105 # If --line and --cell are not specified, default to the ones
105 # If --line and --cell are not specified, default to the ones
106 # that are available.
106 # that are available.
107 if not args.line and not args.cell:
107 if not args.line and not args.cell:
108 if not m_line and not m_cell:
108 if not m_line and not m_cell:
109 raise UsageError(
109 raise UsageError(
110 'No line or cell magic with name `%s` found.' % target
110 'No line or cell magic with name `%s` found.' % target
111 )
111 )
112 args.line = bool(m_line)
112 args.line = bool(m_line)
113 args.cell = bool(m_cell)
113 args.cell = bool(m_cell)
114
114
115 if args.line:
115 if args.line:
116 mman.register_alias(name, target, 'line')
116 mman.register_alias(name, target, 'line')
117 print('Created `%s%s` as an alias for `%s%s`.' % (
117 print('Created `%s%s` as an alias for `%s%s`.' % (
118 magic_escapes['line'], name,
118 magic_escapes['line'], name,
119 magic_escapes['line'], target))
119 magic_escapes['line'], target))
120
120
121 if args.cell:
121 if args.cell:
122 mman.register_alias(name, target, 'cell')
122 mman.register_alias(name, target, 'cell')
123 print('Created `%s%s` as an alias for `%s%s`.' % (
123 print('Created `%s%s` as an alias for `%s%s`.' % (
124 magic_escapes['cell'], name,
124 magic_escapes['cell'], name,
125 magic_escapes['cell'], target))
125 magic_escapes['cell'], target))
126
126
127 def _lsmagic(self):
127 def _lsmagic(self):
128 mesc = magic_escapes['line']
128 mesc = magic_escapes['line']
129 cesc = magic_escapes['cell']
129 cesc = magic_escapes['cell']
130 mman = self.shell.magics_manager
130 mman = self.shell.magics_manager
131 magics = mman.lsmagic()
131 magics = mman.lsmagic()
132 out = ['Available line magics:',
132 out = ['Available line magics:',
133 mesc + (' '+mesc).join(sorted(magics['line'])),
133 mesc + (' '+mesc).join(sorted(magics['line'])),
134 '',
134 '',
135 'Available cell magics:',
135 'Available cell magics:',
136 cesc + (' '+cesc).join(sorted(magics['cell'])),
136 cesc + (' '+cesc).join(sorted(magics['cell'])),
137 '',
137 '',
138 mman.auto_status()]
138 mman.auto_status()]
139 return '\n'.join(out)
139 return '\n'.join(out)
140
140
141 @line_magic
141 @line_magic
142 def lsmagic(self, parameter_s=''):
142 def lsmagic(self, parameter_s=''):
143 """List currently available magic functions."""
143 """List currently available magic functions."""
144 print(self._lsmagic())
144 print(self._lsmagic())
145
145
146 def _magic_docs(self, brief=False, rest=False):
146 def _magic_docs(self, brief=False, rest=False):
147 """Return docstrings from magic functions."""
147 """Return docstrings from magic functions."""
148 mman = self.shell.magics_manager
148 mman = self.shell.magics_manager
149 docs = mman.lsmagic_docs(brief, missing='No documentation')
149 docs = mman.lsmagic_docs(brief, missing='No documentation')
150
150
151 if rest:
151 if rest:
152 format_string = '**%s%s**::\n\n%s\n\n'
152 format_string = '**%s%s**::\n\n%s\n\n'
153 else:
153 else:
154 format_string = '%s%s:\n%s\n'
154 format_string = '%s%s:\n%s\n'
155
155
156 return ''.join(
156 return ''.join(
157 [format_string % (magic_escapes['line'], fname,
157 [format_string % (magic_escapes['line'], fname,
158 indent(dedent(fndoc)))
158 indent(dedent(fndoc)))
159 for fname, fndoc in sorted(docs['line'].items())]
159 for fname, fndoc in sorted(docs['line'].items())]
160 +
160 +
161 [format_string % (magic_escapes['cell'], fname,
161 [format_string % (magic_escapes['cell'], fname,
162 indent(dedent(fndoc)))
162 indent(dedent(fndoc)))
163 for fname, fndoc in sorted(docs['cell'].items())]
163 for fname, fndoc in sorted(docs['cell'].items())]
164 )
164 )
165
165
166 @line_magic
166 @line_magic
167 def magic(self, parameter_s=''):
167 def magic(self, parameter_s=''):
168 """Print information about the magic function system.
168 """Print information about the magic function system.
169
169
170 Supported formats: -latex, -brief, -rest
170 Supported formats: -latex, -brief, -rest
171 """
171 """
172
172
173 mode = ''
173 mode = ''
174 try:
174 try:
175 mode = parameter_s.split()[0][1:]
175 mode = parameter_s.split()[0][1:]
176 if mode == 'rest':
176 if mode == 'rest':
177 rest_docs = []
177 rest_docs = []
178 except IndexError:
178 except IndexError:
179 pass
179 pass
180
180
181 brief = (mode == 'brief')
181 brief = (mode == 'brief')
182 rest = (mode == 'rest')
182 rest = (mode == 'rest')
183 magic_docs = self._magic_docs(brief, rest)
183 magic_docs = self._magic_docs(brief, rest)
184
184
185 if mode == 'latex':
185 if mode == 'latex':
186 print(self.format_latex(magic_docs))
186 print(self.format_latex(magic_docs))
187 return
187 return
188 else:
188 else:
189 magic_docs = format_screen(magic_docs)
189 magic_docs = format_screen(magic_docs)
190
190
191 out = ["""
191 out = ["""
192 IPython's 'magic' functions
192 IPython's 'magic' functions
193 ===========================
193 ===========================
194
194
195 The magic function system provides a series of functions which allow you to
195 The magic function system provides a series of functions which allow you to
196 control the behavior of IPython itself, plus a lot of system-type
196 control the behavior of IPython itself, plus a lot of system-type
197 features. There are two kinds of magics, line-oriented and cell-oriented.
197 features. There are two kinds of magics, line-oriented and cell-oriented.
198
198
199 Line magics are prefixed with the % character and work much like OS
199 Line magics are prefixed with the % character and work much like OS
200 command-line calls: they get as an argument the rest of the line, where
200 command-line calls: they get as an argument the rest of the line, where
201 arguments are passed without parentheses or quotes. For example, this will
201 arguments are passed without parentheses or quotes. For example, this will
202 time the given statement::
202 time the given statement::
203
203
204 %timeit range(1000)
204 %timeit range(1000)
205
205
206 Cell magics are prefixed with a double %%, and they are functions that get as
206 Cell magics are prefixed with a double %%, and they are functions that get as
207 an argument not only the rest of the line, but also the lines below it in a
207 an argument not only the rest of the line, but also the lines below it in a
208 separate argument. These magics are called with two arguments: the rest of the
208 separate argument. These magics are called with two arguments: the rest of the
209 call line and the body of the cell, consisting of the lines below the first.
209 call line and the body of the cell, consisting of the lines below the first.
210 For example::
210 For example::
211
211
212 %%timeit x = numpy.random.randn((100, 100))
212 %%timeit x = numpy.random.randn((100, 100))
213 numpy.linalg.svd(x)
213 numpy.linalg.svd(x)
214
214
215 will time the execution of the numpy svd routine, running the assignment of x
215 will time the execution of the numpy svd routine, running the assignment of x
216 as part of the setup phase, which is not timed.
216 as part of the setup phase, which is not timed.
217
217
218 In a line-oriented client (the terminal or Qt console IPython), starting a new
218 In a line-oriented client (the terminal or Qt console IPython), starting a new
219 input with %% will automatically enter cell mode, and IPython will continue
219 input with %% will automatically enter cell mode, and IPython will continue
220 reading input until a blank line is given. In the notebook, simply type the
220 reading input until a blank line is given. In the notebook, simply type the
221 whole cell as one entity, but keep in mind that the %% escape can only be at
221 whole cell as one entity, but keep in mind that the %% escape can only be at
222 the very start of the cell.
222 the very start of the cell.
223
223
224 NOTE: If you have 'automagic' enabled (via the command line option or with the
224 NOTE: If you have 'automagic' enabled (via the command line option or with the
225 %automagic function), you don't need to type in the % explicitly for line
225 %automagic function), you don't need to type in the % explicitly for line
226 magics; cell magics always require an explicit '%%' escape. By default,
226 magics; cell magics always require an explicit '%%' escape. By default,
227 IPython ships with automagic on, so you should only rarely need the % escape.
227 IPython ships with automagic on, so you should only rarely need the % escape.
228
228
229 Example: typing '%cd mydir' (without the quotes) changes you working directory
229 Example: typing '%cd mydir' (without the quotes) changes you working directory
230 to 'mydir', if it exists.
230 to 'mydir', if it exists.
231
231
232 For a list of the available magic functions, use %lsmagic. For a description
232 For a list of the available magic functions, use %lsmagic. For a description
233 of any of them, type %magic_name?, e.g. '%cd?'.
233 of any of them, type %magic_name?, e.g. '%cd?'.
234
234
235 Currently the magic system has the following functions:""",
235 Currently the magic system has the following functions:""",
236 magic_docs,
236 magic_docs,
237 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
237 "Summary of magic functions (from %slsmagic):" % magic_escapes['line'],
238 self._lsmagic(),
238 self._lsmagic(),
239 ]
239 ]
240 page.page('\n'.join(out))
240 page.page('\n'.join(out))
241
241
242
242
243 @line_magic
243 @line_magic
244 def page(self, parameter_s=''):
244 def page(self, parameter_s=''):
245 """Pretty print the object and display it through a pager.
245 """Pretty print the object and display it through a pager.
246
246
247 %page [options] OBJECT
247 %page [options] OBJECT
248
248
249 If no object is given, use _ (last output).
249 If no object is given, use _ (last output).
250
250
251 Options:
251 Options:
252
252
253 -r: page str(object), don't pretty-print it."""
253 -r: page str(object), don't pretty-print it."""
254
254
255 # After a function contributed by Olivier Aubert, slightly modified.
255 # After a function contributed by Olivier Aubert, slightly modified.
256
256
257 # Process options/args
257 # Process options/args
258 opts, args = self.parse_options(parameter_s, 'r')
258 opts, args = self.parse_options(parameter_s, 'r')
259 raw = 'r' in opts
259 raw = 'r' in opts
260
260
261 oname = args and args or '_'
261 oname = args and args or '_'
262 info = self.shell._ofind(oname)
262 info = self.shell._ofind(oname)
263 if info['found']:
263 if info['found']:
264 txt = (raw and str or pformat)( info['obj'] )
264 txt = (raw and str or pformat)( info['obj'] )
265 page.page(txt)
265 page.page(txt)
266 else:
266 else:
267 print('Object `%s` not found' % oname)
267 print('Object `%s` not found' % oname)
268
268
269 @line_magic
269 @line_magic
270 def profile(self, parameter_s=''):
270 def profile(self, parameter_s=''):
271 """Print your currently active IPython profile."""
271 """Print your currently active IPython profile."""
272 from IPython.core.application import BaseIPythonApplication
272 from IPython.core.application import BaseIPythonApplication
273 if BaseIPythonApplication.initialized():
273 if BaseIPythonApplication.initialized():
274 print(BaseIPythonApplication.instance().profile)
274 print(BaseIPythonApplication.instance().profile)
275 else:
275 else:
276 error("profile is an application-level value, but you don't appear to be in an IPython application")
276 error("profile is an application-level value, but you don't appear to be in an IPython application")
277
277
278 @line_magic
278 @line_magic
279 def pprint(self, parameter_s=''):
279 def pprint(self, parameter_s=''):
280 """Toggle pretty printing on/off."""
280 """Toggle pretty printing on/off."""
281 ptformatter = self.shell.display_formatter.formatters['text/plain']
281 ptformatter = self.shell.display_formatter.formatters['text/plain']
282 ptformatter.pprint = bool(1 - ptformatter.pprint)
282 ptformatter.pprint = bool(1 - ptformatter.pprint)
283 print('Pretty printing has been turned',
283 print('Pretty printing has been turned',
284 ['OFF','ON'][ptformatter.pprint])
284 ['OFF','ON'][ptformatter.pprint])
285
285
286 @line_magic
286 @line_magic
287 def colors(self, parameter_s=''):
287 def colors(self, parameter_s=''):
288 """Switch color scheme for prompts, info system and exception handlers.
288 """Switch color scheme for prompts, info system and exception handlers.
289
289
290 Currently implemented schemes: NoColor, Linux, LightBG.
290 Currently implemented schemes: NoColor, Linux, LightBG.
291
291
292 Color scheme names are not case-sensitive.
292 Color scheme names are not case-sensitive.
293
293
294 Examples
294 Examples
295 --------
295 --------
296 To get a plain black and white terminal::
296 To get a plain black and white terminal::
297
297
298 %colors nocolor
298 %colors nocolor
299 """
299 """
300 def color_switch_err(name):
300 def color_switch_err(name):
301 warn('Error changing %s color schemes.\n%s' %
301 warn('Error changing %s color schemes.\n%s' %
302 (name, sys.exc_info()[1]))
302 (name, sys.exc_info()[1]))
303
303
304
304
305 new_scheme = parameter_s.strip()
305 new_scheme = parameter_s.strip()
306 if not new_scheme:
306 if not new_scheme:
307 raise UsageError(
307 raise UsageError(
308 "%colors: you must specify a color scheme. See '%colors?'")
308 "%colors: you must specify a color scheme. See '%colors?'")
309 return
309 return
310 # local shortcut
310 # local shortcut
311 shell = self.shell
311 shell = self.shell
312
312
313 import IPython.utils.rlineimpl as readline
313 import IPython.utils.rlineimpl as readline
314
314
315 if not shell.colors_force and \
315 if not shell.colors_force and \
316 not readline.have_readline and sys.platform == "win32":
316 not readline.have_readline and \
317 (sys.platform == "win32" or sys.platform == "cli"):
317 msg = """\
318 msg = """\
318 Proper color support under MS Windows requires the pyreadline library.
319 Proper color support under MS Windows requires the pyreadline library.
319 You can find it at:
320 You can find it at:
320 http://ipython.org/pyreadline.html
321 http://ipython.org/pyreadline.html
321 Gary's readline needs the ctypes module, from:
322 Gary's readline needs the ctypes module, from:
322 http://starship.python.net/crew/theller/ctypes
323 http://starship.python.net/crew/theller/ctypes
323 (Note that ctypes is already part of Python versions 2.5 and newer).
324 (Note that ctypes is already part of Python versions 2.5 and newer).
324
325
325 Defaulting color scheme to 'NoColor'"""
326 Defaulting color scheme to 'NoColor'"""
326 new_scheme = 'NoColor'
327 new_scheme = 'NoColor'
327 warn(msg)
328 warn(msg)
328
329
329 # readline option is 0
330 # readline option is 0
330 if not shell.colors_force and not shell.has_readline:
331 if not shell.colors_force and not shell.has_readline:
331 new_scheme = 'NoColor'
332 new_scheme = 'NoColor'
332
333
333 # Set prompt colors
334 # Set prompt colors
334 try:
335 try:
335 shell.prompt_manager.color_scheme = new_scheme
336 shell.prompt_manager.color_scheme = new_scheme
336 except:
337 except:
337 color_switch_err('prompt')
338 color_switch_err('prompt')
338 else:
339 else:
339 shell.colors = \
340 shell.colors = \
340 shell.prompt_manager.color_scheme_table.active_scheme_name
341 shell.prompt_manager.color_scheme_table.active_scheme_name
341 # Set exception colors
342 # Set exception colors
342 try:
343 try:
343 shell.InteractiveTB.set_colors(scheme = new_scheme)
344 shell.InteractiveTB.set_colors(scheme = new_scheme)
344 shell.SyntaxTB.set_colors(scheme = new_scheme)
345 shell.SyntaxTB.set_colors(scheme = new_scheme)
345 except:
346 except:
346 color_switch_err('exception')
347 color_switch_err('exception')
347
348
348 # Set info (for 'object?') colors
349 # Set info (for 'object?') colors
349 if shell.color_info:
350 if shell.color_info:
350 try:
351 try:
351 shell.inspector.set_active_scheme(new_scheme)
352 shell.inspector.set_active_scheme(new_scheme)
352 except:
353 except:
353 color_switch_err('object inspector')
354 color_switch_err('object inspector')
354 else:
355 else:
355 shell.inspector.set_active_scheme('NoColor')
356 shell.inspector.set_active_scheme('NoColor')
356
357
357 @line_magic
358 @line_magic
358 def xmode(self, parameter_s=''):
359 def xmode(self, parameter_s=''):
359 """Switch modes for the exception handlers.
360 """Switch modes for the exception handlers.
360
361
361 Valid modes: Plain, Context and Verbose.
362 Valid modes: Plain, Context and Verbose.
362
363
363 If called without arguments, acts as a toggle."""
364 If called without arguments, acts as a toggle."""
364
365
365 def xmode_switch_err(name):
366 def xmode_switch_err(name):
366 warn('Error changing %s exception modes.\n%s' %
367 warn('Error changing %s exception modes.\n%s' %
367 (name,sys.exc_info()[1]))
368 (name,sys.exc_info()[1]))
368
369
369 shell = self.shell
370 shell = self.shell
370 new_mode = parameter_s.strip().capitalize()
371 new_mode = parameter_s.strip().capitalize()
371 try:
372 try:
372 shell.InteractiveTB.set_mode(mode=new_mode)
373 shell.InteractiveTB.set_mode(mode=new_mode)
373 print('Exception reporting mode:',shell.InteractiveTB.mode)
374 print('Exception reporting mode:',shell.InteractiveTB.mode)
374 except:
375 except:
375 xmode_switch_err('user')
376 xmode_switch_err('user')
376
377
377 @line_magic
378 @line_magic
378 def quickref(self,arg):
379 def quickref(self,arg):
379 """ Show a quick reference sheet """
380 """ Show a quick reference sheet """
380 from IPython.core.usage import quick_reference
381 from IPython.core.usage import quick_reference
381 qr = quick_reference + self._magic_docs(brief=True)
382 qr = quick_reference + self._magic_docs(brief=True)
382 page.page(qr)
383 page.page(qr)
383
384
384 @line_magic
385 @line_magic
385 def doctest_mode(self, parameter_s=''):
386 def doctest_mode(self, parameter_s=''):
386 """Toggle doctest mode on and off.
387 """Toggle doctest mode on and off.
387
388
388 This mode is intended to make IPython behave as much as possible like a
389 This mode is intended to make IPython behave as much as possible like a
389 plain Python shell, from the perspective of how its prompts, exceptions
390 plain Python shell, from the perspective of how its prompts, exceptions
390 and output look. This makes it easy to copy and paste parts of a
391 and output look. This makes it easy to copy and paste parts of a
391 session into doctests. It does so by:
392 session into doctests. It does so by:
392
393
393 - Changing the prompts to the classic ``>>>`` ones.
394 - Changing the prompts to the classic ``>>>`` ones.
394 - Changing the exception reporting mode to 'Plain'.
395 - Changing the exception reporting mode to 'Plain'.
395 - Disabling pretty-printing of output.
396 - Disabling pretty-printing of output.
396
397
397 Note that IPython also supports the pasting of code snippets that have
398 Note that IPython also supports the pasting of code snippets that have
398 leading '>>>' and '...' prompts in them. This means that you can paste
399 leading '>>>' and '...' prompts in them. This means that you can paste
399 doctests from files or docstrings (even if they have leading
400 doctests from files or docstrings (even if they have leading
400 whitespace), and the code will execute correctly. You can then use
401 whitespace), and the code will execute correctly. You can then use
401 '%history -t' to see the translated history; this will give you the
402 '%history -t' to see the translated history; this will give you the
402 input after removal of all the leading prompts and whitespace, which
403 input after removal of all the leading prompts and whitespace, which
403 can be pasted back into an editor.
404 can be pasted back into an editor.
404
405
405 With these features, you can switch into this mode easily whenever you
406 With these features, you can switch into this mode easily whenever you
406 need to do testing and changes to doctests, without having to leave
407 need to do testing and changes to doctests, without having to leave
407 your existing IPython session.
408 your existing IPython session.
408 """
409 """
409
410
410 # Shorthands
411 # Shorthands
411 shell = self.shell
412 shell = self.shell
412 pm = shell.prompt_manager
413 pm = shell.prompt_manager
413 meta = shell.meta
414 meta = shell.meta
414 disp_formatter = self.shell.display_formatter
415 disp_formatter = self.shell.display_formatter
415 ptformatter = disp_formatter.formatters['text/plain']
416 ptformatter = disp_formatter.formatters['text/plain']
416 # dstore is a data store kept in the instance metadata bag to track any
417 # dstore is a data store kept in the instance metadata bag to track any
417 # changes we make, so we can undo them later.
418 # changes we make, so we can undo them later.
418 dstore = meta.setdefault('doctest_mode',Struct())
419 dstore = meta.setdefault('doctest_mode',Struct())
419 save_dstore = dstore.setdefault
420 save_dstore = dstore.setdefault
420
421
421 # save a few values we'll need to recover later
422 # save a few values we'll need to recover later
422 mode = save_dstore('mode',False)
423 mode = save_dstore('mode',False)
423 save_dstore('rc_pprint',ptformatter.pprint)
424 save_dstore('rc_pprint',ptformatter.pprint)
424 save_dstore('xmode',shell.InteractiveTB.mode)
425 save_dstore('xmode',shell.InteractiveTB.mode)
425 save_dstore('rc_separate_out',shell.separate_out)
426 save_dstore('rc_separate_out',shell.separate_out)
426 save_dstore('rc_separate_out2',shell.separate_out2)
427 save_dstore('rc_separate_out2',shell.separate_out2)
427 save_dstore('rc_prompts_pad_left',pm.justify)
428 save_dstore('rc_prompts_pad_left',pm.justify)
428 save_dstore('rc_separate_in',shell.separate_in)
429 save_dstore('rc_separate_in',shell.separate_in)
429 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
430 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
430 save_dstore('prompt_templates',(pm.in_template, pm.in2_template, pm.out_template))
431 save_dstore('prompt_templates',(pm.in_template, pm.in2_template, pm.out_template))
431
432
432 if mode == False:
433 if mode == False:
433 # turn on
434 # turn on
434 pm.in_template = '>>> '
435 pm.in_template = '>>> '
435 pm.in2_template = '... '
436 pm.in2_template = '... '
436 pm.out_template = ''
437 pm.out_template = ''
437
438
438 # Prompt separators like plain python
439 # Prompt separators like plain python
439 shell.separate_in = ''
440 shell.separate_in = ''
440 shell.separate_out = ''
441 shell.separate_out = ''
441 shell.separate_out2 = ''
442 shell.separate_out2 = ''
442
443
443 pm.justify = False
444 pm.justify = False
444
445
445 ptformatter.pprint = False
446 ptformatter.pprint = False
446 disp_formatter.plain_text_only = True
447 disp_formatter.plain_text_only = True
447
448
448 shell.magic('xmode Plain')
449 shell.magic('xmode Plain')
449 else:
450 else:
450 # turn off
451 # turn off
451 pm.in_template, pm.in2_template, pm.out_template = dstore.prompt_templates
452 pm.in_template, pm.in2_template, pm.out_template = dstore.prompt_templates
452
453
453 shell.separate_in = dstore.rc_separate_in
454 shell.separate_in = dstore.rc_separate_in
454
455
455 shell.separate_out = dstore.rc_separate_out
456 shell.separate_out = dstore.rc_separate_out
456 shell.separate_out2 = dstore.rc_separate_out2
457 shell.separate_out2 = dstore.rc_separate_out2
457
458
458 pm.justify = dstore.rc_prompts_pad_left
459 pm.justify = dstore.rc_prompts_pad_left
459
460
460 ptformatter.pprint = dstore.rc_pprint
461 ptformatter.pprint = dstore.rc_pprint
461 disp_formatter.plain_text_only = dstore.rc_plain_text_only
462 disp_formatter.plain_text_only = dstore.rc_plain_text_only
462
463
463 shell.magic('xmode ' + dstore.xmode)
464 shell.magic('xmode ' + dstore.xmode)
464
465
465 # Store new mode and inform
466 # Store new mode and inform
466 dstore.mode = bool(1-int(mode))
467 dstore.mode = bool(1-int(mode))
467 mode_label = ['OFF','ON'][dstore.mode]
468 mode_label = ['OFF','ON'][dstore.mode]
468 print('Doctest mode is:', mode_label)
469 print('Doctest mode is:', mode_label)
469
470
470 @line_magic
471 @line_magic
471 def gui(self, parameter_s=''):
472 def gui(self, parameter_s=''):
472 """Enable or disable IPython GUI event loop integration.
473 """Enable or disable IPython GUI event loop integration.
473
474
474 %gui [GUINAME]
475 %gui [GUINAME]
475
476
476 This magic replaces IPython's threaded shells that were activated
477 This magic replaces IPython's threaded shells that were activated
477 using the (pylab/wthread/etc.) command line flags. GUI toolkits
478 using the (pylab/wthread/etc.) command line flags. GUI toolkits
478 can now be enabled at runtime and keyboard
479 can now be enabled at runtime and keyboard
479 interrupts should work without any problems. The following toolkits
480 interrupts should work without any problems. The following toolkits
480 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
481 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
481
482
482 %gui wx # enable wxPython event loop integration
483 %gui wx # enable wxPython event loop integration
483 %gui qt4|qt # enable PyQt4 event loop integration
484 %gui qt4|qt # enable PyQt4 event loop integration
484 %gui gtk # enable PyGTK event loop integration
485 %gui gtk # enable PyGTK event loop integration
485 %gui gtk3 # enable Gtk3 event loop integration
486 %gui gtk3 # enable Gtk3 event loop integration
486 %gui tk # enable Tk event loop integration
487 %gui tk # enable Tk event loop integration
487 %gui osx # enable Cocoa event loop integration
488 %gui osx # enable Cocoa event loop integration
488 # (requires %matplotlib 1.1)
489 # (requires %matplotlib 1.1)
489 %gui # disable all event loop integration
490 %gui # disable all event loop integration
490
491
491 WARNING: after any of these has been called you can simply create
492 WARNING: after any of these has been called you can simply create
492 an application object, but DO NOT start the event loop yourself, as
493 an application object, but DO NOT start the event loop yourself, as
493 we have already handled that.
494 we have already handled that.
494 """
495 """
495 opts, arg = self.parse_options(parameter_s, '')
496 opts, arg = self.parse_options(parameter_s, '')
496 if arg=='': arg = None
497 if arg=='': arg = None
497 try:
498 try:
498 return self.shell.enable_gui(arg)
499 return self.shell.enable_gui(arg)
499 except Exception as e:
500 except Exception as e:
500 # print simple error message, rather than traceback if we can't
501 # print simple error message, rather than traceback if we can't
501 # hook up the GUI
502 # hook up the GUI
502 error(str(e))
503 error(str(e))
503
504
504 @skip_doctest
505 @skip_doctest
505 @line_magic
506 @line_magic
506 def precision(self, s=''):
507 def precision(self, s=''):
507 """Set floating point precision for pretty printing.
508 """Set floating point precision for pretty printing.
508
509
509 Can set either integer precision or a format string.
510 Can set either integer precision or a format string.
510
511
511 If numpy has been imported and precision is an int,
512 If numpy has been imported and precision is an int,
512 numpy display precision will also be set, via ``numpy.set_printoptions``.
513 numpy display precision will also be set, via ``numpy.set_printoptions``.
513
514
514 If no argument is given, defaults will be restored.
515 If no argument is given, defaults will be restored.
515
516
516 Examples
517 Examples
517 --------
518 --------
518 ::
519 ::
519
520
520 In [1]: from math import pi
521 In [1]: from math import pi
521
522
522 In [2]: %precision 3
523 In [2]: %precision 3
523 Out[2]: u'%.3f'
524 Out[2]: u'%.3f'
524
525
525 In [3]: pi
526 In [3]: pi
526 Out[3]: 3.142
527 Out[3]: 3.142
527
528
528 In [4]: %precision %i
529 In [4]: %precision %i
529 Out[4]: u'%i'
530 Out[4]: u'%i'
530
531
531 In [5]: pi
532 In [5]: pi
532 Out[5]: 3
533 Out[5]: 3
533
534
534 In [6]: %precision %e
535 In [6]: %precision %e
535 Out[6]: u'%e'
536 Out[6]: u'%e'
536
537
537 In [7]: pi**10
538 In [7]: pi**10
538 Out[7]: 9.364805e+04
539 Out[7]: 9.364805e+04
539
540
540 In [8]: %precision
541 In [8]: %precision
541 Out[8]: u'%r'
542 Out[8]: u'%r'
542
543
543 In [9]: pi**10
544 In [9]: pi**10
544 Out[9]: 93648.047476082982
545 Out[9]: 93648.047476082982
545 """
546 """
546 ptformatter = self.shell.display_formatter.formatters['text/plain']
547 ptformatter = self.shell.display_formatter.formatters['text/plain']
547 ptformatter.float_precision = s
548 ptformatter.float_precision = s
548 return ptformatter.float_format
549 return ptformatter.float_format
549
550
550 @magic_arguments.magic_arguments()
551 @magic_arguments.magic_arguments()
551 @magic_arguments.argument(
552 @magic_arguments.argument(
552 '-e', '--export', action='store_true', default=False,
553 '-e', '--export', action='store_true', default=False,
553 help='Export IPython history as a notebook. The filename argument '
554 help='Export IPython history as a notebook. The filename argument '
554 'is used to specify the notebook name and format. For example '
555 'is used to specify the notebook name and format. For example '
555 'a filename of notebook.ipynb will result in a notebook name '
556 'a filename of notebook.ipynb will result in a notebook name '
556 'of "notebook" and a format of "xml". Likewise using a ".json" '
557 'of "notebook" and a format of "xml". Likewise using a ".json" '
557 'or ".py" file extension will write the notebook in the json '
558 'or ".py" file extension will write the notebook in the json '
558 'or py formats.'
559 'or py formats.'
559 )
560 )
560 @magic_arguments.argument(
561 @magic_arguments.argument(
561 '-f', '--format',
562 '-f', '--format',
562 help='Convert an existing IPython notebook to a new format. This option '
563 help='Convert an existing IPython notebook to a new format. This option '
563 'specifies the new format and can have the values: xml, json, py. '
564 'specifies the new format and can have the values: xml, json, py. '
564 'The target filename is chosen automatically based on the new '
565 'The target filename is chosen automatically based on the new '
565 'format. The filename argument gives the name of the source file.'
566 'format. The filename argument gives the name of the source file.'
566 )
567 )
567 @magic_arguments.argument(
568 @magic_arguments.argument(
568 'filename', type=unicode,
569 'filename', type=unicode,
569 help='Notebook name or filename'
570 help='Notebook name or filename'
570 )
571 )
571 @line_magic
572 @line_magic
572 def notebook(self, s):
573 def notebook(self, s):
573 """Export and convert IPython notebooks.
574 """Export and convert IPython notebooks.
574
575
575 This function can export the current IPython history to a notebook file
576 This function can export the current IPython history to a notebook file
576 or can convert an existing notebook file into a different format. For
577 or can convert an existing notebook file into a different format. For
577 example, to export the history to "foo.ipynb" do "%notebook -e foo.ipynb".
578 example, to export the history to "foo.ipynb" do "%notebook -e foo.ipynb".
578 To export the history to "foo.py" do "%notebook -e foo.py". To convert
579 To export the history to "foo.py" do "%notebook -e foo.py". To convert
579 "foo.ipynb" to "foo.json" do "%notebook -f json foo.ipynb". Possible
580 "foo.ipynb" to "foo.json" do "%notebook -f json foo.ipynb". Possible
580 formats include (json/ipynb, py).
581 formats include (json/ipynb, py).
581 """
582 """
582 args = magic_arguments.parse_argstring(self.notebook, s)
583 args = magic_arguments.parse_argstring(self.notebook, s)
583
584
584 from IPython.nbformat import current
585 from IPython.nbformat import current
585 args.filename = unquote_filename(args.filename)
586 args.filename = unquote_filename(args.filename)
586 if args.export:
587 if args.export:
587 fname, name, format = current.parse_filename(args.filename)
588 fname, name, format = current.parse_filename(args.filename)
588 cells = []
589 cells = []
589 hist = list(self.shell.history_manager.get_range())
590 hist = list(self.shell.history_manager.get_range())
590 for session, prompt_number, input in hist[:-1]:
591 for session, prompt_number, input in hist[:-1]:
591 cells.append(current.new_code_cell(prompt_number=prompt_number,
592 cells.append(current.new_code_cell(prompt_number=prompt_number,
592 input=input))
593 input=input))
593 worksheet = current.new_worksheet(cells=cells)
594 worksheet = current.new_worksheet(cells=cells)
594 nb = current.new_notebook(name=name,worksheets=[worksheet])
595 nb = current.new_notebook(name=name,worksheets=[worksheet])
595 with io.open(fname, 'w', encoding='utf-8') as f:
596 with io.open(fname, 'w', encoding='utf-8') as f:
596 current.write(nb, f, format);
597 current.write(nb, f, format);
597 elif args.format is not None:
598 elif args.format is not None:
598 old_fname, old_name, old_format = current.parse_filename(args.filename)
599 old_fname, old_name, old_format = current.parse_filename(args.filename)
599 new_format = args.format
600 new_format = args.format
600 if new_format == u'xml':
601 if new_format == u'xml':
601 raise ValueError('Notebooks cannot be written as xml.')
602 raise ValueError('Notebooks cannot be written as xml.')
602 elif new_format == u'ipynb' or new_format == u'json':
603 elif new_format == u'ipynb' or new_format == u'json':
603 new_fname = old_name + u'.ipynb'
604 new_fname = old_name + u'.ipynb'
604 new_format = u'json'
605 new_format = u'json'
605 elif new_format == u'py':
606 elif new_format == u'py':
606 new_fname = old_name + u'.py'
607 new_fname = old_name + u'.py'
607 else:
608 else:
608 raise ValueError('Invalid notebook format: %s' % new_format)
609 raise ValueError('Invalid notebook format: %s' % new_format)
609 with io.open(old_fname, 'r', encoding='utf-8') as f:
610 with io.open(old_fname, 'r', encoding='utf-8') as f:
610 nb = current.read(f, old_format)
611 nb = current.read(f, old_format)
611 with io.open(new_fname, 'w', encoding='utf-8') as f:
612 with io.open(new_fname, 'w', encoding='utf-8') as f:
612 current.write(nb, f, new_format)
613 current.write(nb, f, new_format)
@@ -1,1030 +1,1035 b''
1 """Implementation of execution-related magic functions.
1 """Implementation of execution-related magic functions.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012 The IPython Development Team.
4 # Copyright (c) 2012 The IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 # Stdlib
15 # Stdlib
16 import __builtin__ as builtin_mod
16 import __builtin__ as builtin_mod
17 import bdb
17 import bdb
18 import os
18 import os
19 import sys
19 import sys
20 import time
20 import time
21 from StringIO import StringIO
21 from StringIO import StringIO
22
22
23 # cProfile was added in Python2.5
23 # cProfile was added in Python2.5
24 try:
24 try:
25 import cProfile as profile
25 import cProfile as profile
26 import pstats
26 import pstats
27 except ImportError:
27 except ImportError:
28 # profile isn't bundled by default in Debian for license reasons
28 # profile isn't bundled by default in Debian for license reasons
29 try:
29 try:
30 import profile, pstats
30 import profile, pstats
31 except ImportError:
31 except ImportError:
32 profile = pstats = None
32 profile = pstats = None
33
33
34 # Our own packages
34 # Our own packages
35 from IPython.core import debugger, oinspect
35 from IPython.core import debugger, oinspect
36 from IPython.core import magic_arguments
36 from IPython.core import magic_arguments
37 from IPython.core import page
37 from IPython.core import page
38 from IPython.core.error import UsageError
38 from IPython.core.error import UsageError
39 from IPython.core.macro import Macro
39 from IPython.core.macro import Macro
40 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
40 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
41 line_cell_magic, on_off, needs_local_scope)
41 line_cell_magic, on_off, needs_local_scope)
42 from IPython.testing.skipdoctest import skip_doctest
42 from IPython.testing.skipdoctest import skip_doctest
43 from IPython.utils import py3compat
43 from IPython.utils import py3compat
44 from IPython.utils.io import capture_output
44 from IPython.utils.io import capture_output
45 from IPython.utils.ipstruct import Struct
45 from IPython.utils.ipstruct import Struct
46 from IPython.utils.module_paths import find_mod
46 from IPython.utils.module_paths import find_mod
47 from IPython.utils.path import get_py_filename, unquote_filename, shellglob
47 from IPython.utils.path import get_py_filename, unquote_filename, shellglob
48 from IPython.utils.timing import clock, clock2
48 from IPython.utils.timing import clock, clock2
49 from IPython.utils.warn import warn, error
49 from IPython.utils.warn import warn, error
50
50
51
51
52 #-----------------------------------------------------------------------------
52 #-----------------------------------------------------------------------------
53 # Magic implementation classes
53 # Magic implementation classes
54 #-----------------------------------------------------------------------------
54 #-----------------------------------------------------------------------------
55
55
56 @magics_class
56 @magics_class
57 class ExecutionMagics(Magics):
57 class ExecutionMagics(Magics):
58 """Magics related to code execution, debugging, profiling, etc.
58 """Magics related to code execution, debugging, profiling, etc.
59
59
60 """
60 """
61
61
62 def __init__(self, shell):
62 def __init__(self, shell):
63 super(ExecutionMagics, self).__init__(shell)
63 super(ExecutionMagics, self).__init__(shell)
64 if profile is None:
64 if profile is None:
65 self.prun = self.profile_missing_notice
65 self.prun = self.profile_missing_notice
66 # Default execution function used to actually run user code.
66 # Default execution function used to actually run user code.
67 self.default_runner = None
67 self.default_runner = None
68
68
69 def profile_missing_notice(self, *args, **kwargs):
69 def profile_missing_notice(self, *args, **kwargs):
70 error("""\
70 error("""\
71 The profile module could not be found. It has been removed from the standard
71 The profile module could not be found. It has been removed from the standard
72 python packages because of its non-free license. To use profiling, install the
72 python packages because of its non-free license. To use profiling, install the
73 python-profiler package from non-free.""")
73 python-profiler package from non-free.""")
74
74
75 @skip_doctest
75 @skip_doctest
76 @line_cell_magic
76 @line_cell_magic
77 def prun(self, parameter_s='', cell=None, user_mode=True,
77 def prun(self, parameter_s='', cell=None, user_mode=True,
78 opts=None,arg_lst=None,prog_ns=None):
78 opts=None,arg_lst=None,prog_ns=None):
79
79
80 """Run a statement through the python code profiler.
80 """Run a statement through the python code profiler.
81
81
82 Usage, in line mode:
82 Usage, in line mode:
83 %prun [options] statement
83 %prun [options] statement
84
84
85 Usage, in cell mode:
85 Usage, in cell mode:
86 %%prun [options] [statement]
86 %%prun [options] [statement]
87 code...
87 code...
88 code...
88 code...
89
89
90 In cell mode, the additional code lines are appended to the (possibly
90 In cell mode, the additional code lines are appended to the (possibly
91 empty) statement in the first line. Cell mode allows you to easily
91 empty) statement in the first line. Cell mode allows you to easily
92 profile multiline blocks without having to put them in a separate
92 profile multiline blocks without having to put them in a separate
93 function.
93 function.
94
94
95 The given statement (which doesn't require quote marks) is run via the
95 The given statement (which doesn't require quote marks) is run via the
96 python profiler in a manner similar to the profile.run() function.
96 python profiler in a manner similar to the profile.run() function.
97 Namespaces are internally managed to work correctly; profile.run
97 Namespaces are internally managed to work correctly; profile.run
98 cannot be used in IPython because it makes certain assumptions about
98 cannot be used in IPython because it makes certain assumptions about
99 namespaces which do not hold under IPython.
99 namespaces which do not hold under IPython.
100
100
101 Options:
101 Options:
102
102
103 -l <limit>: you can place restrictions on what or how much of the
103 -l <limit>: you can place restrictions on what or how much of the
104 profile gets printed. The limit value can be:
104 profile gets printed. The limit value can be:
105
105
106 * A string: only information for function names containing this string
106 * A string: only information for function names containing this string
107 is printed.
107 is printed.
108
108
109 * An integer: only these many lines are printed.
109 * An integer: only these many lines are printed.
110
110
111 * A float (between 0 and 1): this fraction of the report is printed
111 * A float (between 0 and 1): this fraction of the report is printed
112 (for example, use a limit of 0.4 to see the topmost 40% only).
112 (for example, use a limit of 0.4 to see the topmost 40% only).
113
113
114 You can combine several limits with repeated use of the option. For
114 You can combine several limits with repeated use of the option. For
115 example, '-l __init__ -l 5' will print only the topmost 5 lines of
115 example, '-l __init__ -l 5' will print only the topmost 5 lines of
116 information about class constructors.
116 information about class constructors.
117
117
118 -r: return the pstats.Stats object generated by the profiling. This
118 -r: return the pstats.Stats object generated by the profiling. This
119 object has all the information about the profile in it, and you can
119 object has all the information about the profile in it, and you can
120 later use it for further analysis or in other functions.
120 later use it for further analysis or in other functions.
121
121
122 -s <key>: sort profile by given key. You can provide more than one key
122 -s <key>: sort profile by given key. You can provide more than one key
123 by using the option several times: '-s key1 -s key2 -s key3...'. The
123 by using the option several times: '-s key1 -s key2 -s key3...'. The
124 default sorting key is 'time'.
124 default sorting key is 'time'.
125
125
126 The following is copied verbatim from the profile documentation
126 The following is copied verbatim from the profile documentation
127 referenced below:
127 referenced below:
128
128
129 When more than one key is provided, additional keys are used as
129 When more than one key is provided, additional keys are used as
130 secondary criteria when the there is equality in all keys selected
130 secondary criteria when the there is equality in all keys selected
131 before them.
131 before them.
132
132
133 Abbreviations can be used for any key names, as long as the
133 Abbreviations can be used for any key names, as long as the
134 abbreviation is unambiguous. The following are the keys currently
134 abbreviation is unambiguous. The following are the keys currently
135 defined:
135 defined:
136
136
137 Valid Arg Meaning
137 Valid Arg Meaning
138 "calls" call count
138 "calls" call count
139 "cumulative" cumulative time
139 "cumulative" cumulative time
140 "file" file name
140 "file" file name
141 "module" file name
141 "module" file name
142 "pcalls" primitive call count
142 "pcalls" primitive call count
143 "line" line number
143 "line" line number
144 "name" function name
144 "name" function name
145 "nfl" name/file/line
145 "nfl" name/file/line
146 "stdname" standard name
146 "stdname" standard name
147 "time" internal time
147 "time" internal time
148
148
149 Note that all sorts on statistics are in descending order (placing
149 Note that all sorts on statistics are in descending order (placing
150 most time consuming items first), where as name, file, and line number
150 most time consuming items first), where as name, file, and line number
151 searches are in ascending order (i.e., alphabetical). The subtle
151 searches are in ascending order (i.e., alphabetical). The subtle
152 distinction between "nfl" and "stdname" is that the standard name is a
152 distinction between "nfl" and "stdname" is that the standard name is a
153 sort of the name as printed, which means that the embedded line
153 sort of the name as printed, which means that the embedded line
154 numbers get compared in an odd way. For example, lines 3, 20, and 40
154 numbers get compared in an odd way. For example, lines 3, 20, and 40
155 would (if the file names were the same) appear in the string order
155 would (if the file names were the same) appear in the string order
156 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
156 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
157 line numbers. In fact, sort_stats("nfl") is the same as
157 line numbers. In fact, sort_stats("nfl") is the same as
158 sort_stats("name", "file", "line").
158 sort_stats("name", "file", "line").
159
159
160 -T <filename>: save profile results as shown on screen to a text
160 -T <filename>: save profile results as shown on screen to a text
161 file. The profile is still shown on screen.
161 file. The profile is still shown on screen.
162
162
163 -D <filename>: save (via dump_stats) profile statistics to given
163 -D <filename>: save (via dump_stats) profile statistics to given
164 filename. This data is in a format understood by the pstats module, and
164 filename. This data is in a format understood by the pstats module, and
165 is generated by a call to the dump_stats() method of profile
165 is generated by a call to the dump_stats() method of profile
166 objects. The profile is still shown on screen.
166 objects. The profile is still shown on screen.
167
167
168 -q: suppress output to the pager. Best used with -T and/or -D above.
168 -q: suppress output to the pager. Best used with -T and/or -D above.
169
169
170 If you want to run complete programs under the profiler's control, use
170 If you want to run complete programs under the profiler's control, use
171 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
171 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
172 contains profiler specific options as described here.
172 contains profiler specific options as described here.
173
173
174 You can read the complete documentation for the profile module with::
174 You can read the complete documentation for the profile module with::
175
175
176 In [1]: import profile; profile.help()
176 In [1]: import profile; profile.help()
177 """
177 """
178
178
179 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
179 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
180
180
181 if user_mode: # regular user call
181 if user_mode: # regular user call
182 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:q',
182 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:q',
183 list_all=True, posix=False)
183 list_all=True, posix=False)
184 namespace = self.shell.user_ns
184 namespace = self.shell.user_ns
185 if cell is not None:
185 if cell is not None:
186 arg_str += '\n' + cell
186 arg_str += '\n' + cell
187 else: # called to run a program by %run -p
187 else: # called to run a program by %run -p
188 try:
188 try:
189 filename = get_py_filename(arg_lst[0])
189 filename = get_py_filename(arg_lst[0])
190 except IOError as e:
190 except IOError as e:
191 try:
191 try:
192 msg = str(e)
192 msg = str(e)
193 except UnicodeError:
193 except UnicodeError:
194 msg = e.message
194 msg = e.message
195 error(msg)
195 error(msg)
196 return
196 return
197
197
198 arg_str = 'execfile(filename,prog_ns)'
198 arg_str = 'execfile(filename,prog_ns)'
199 namespace = {
199 namespace = {
200 'execfile': self.shell.safe_execfile,
200 'execfile': self.shell.safe_execfile,
201 'prog_ns': prog_ns,
201 'prog_ns': prog_ns,
202 'filename': filename
202 'filename': filename
203 }
203 }
204
204
205 opts.merge(opts_def)
205 opts.merge(opts_def)
206
206
207 prof = profile.Profile()
207 prof = profile.Profile()
208 try:
208 try:
209 prof = prof.runctx(arg_str,namespace,namespace)
209 prof = prof.runctx(arg_str,namespace,namespace)
210 sys_exit = ''
210 sys_exit = ''
211 except SystemExit:
211 except SystemExit:
212 sys_exit = """*** SystemExit exception caught in code being profiled."""
212 sys_exit = """*** SystemExit exception caught in code being profiled."""
213
213
214 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
214 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
215
215
216 lims = opts.l
216 lims = opts.l
217 if lims:
217 if lims:
218 lims = [] # rebuild lims with ints/floats/strings
218 lims = [] # rebuild lims with ints/floats/strings
219 for lim in opts.l:
219 for lim in opts.l:
220 try:
220 try:
221 lims.append(int(lim))
221 lims.append(int(lim))
222 except ValueError:
222 except ValueError:
223 try:
223 try:
224 lims.append(float(lim))
224 lims.append(float(lim))
225 except ValueError:
225 except ValueError:
226 lims.append(lim)
226 lims.append(lim)
227
227
228 # Trap output.
228 # Trap output.
229 stdout_trap = StringIO()
229 stdout_trap = StringIO()
230 stats_stream = stats.stream
230 stats_stream = stats.stream
231 try:
231 try:
232 stats.stream = stdout_trap
232 stats.stream = stdout_trap
233 stats.print_stats(*lims)
233 stats.print_stats(*lims)
234 finally:
234 finally:
235 stats.stream = stats_stream
235 stats.stream = stats_stream
236
236
237 output = stdout_trap.getvalue()
237 output = stdout_trap.getvalue()
238 output = output.rstrip()
238 output = output.rstrip()
239
239
240 if 'q' not in opts:
240 if 'q' not in opts:
241 page.page(output)
241 page.page(output)
242 print sys_exit,
242 print sys_exit,
243
243
244 dump_file = opts.D[0]
244 dump_file = opts.D[0]
245 text_file = opts.T[0]
245 text_file = opts.T[0]
246 if dump_file:
246 if dump_file:
247 dump_file = unquote_filename(dump_file)
247 dump_file = unquote_filename(dump_file)
248 prof.dump_stats(dump_file)
248 prof.dump_stats(dump_file)
249 print '\n*** Profile stats marshalled to file',\
249 print '\n*** Profile stats marshalled to file',\
250 repr(dump_file)+'.',sys_exit
250 repr(dump_file)+'.',sys_exit
251 if text_file:
251 if text_file:
252 text_file = unquote_filename(text_file)
252 text_file = unquote_filename(text_file)
253 pfile = open(text_file,'w')
253 pfile = open(text_file,'w')
254 pfile.write(output)
254 pfile.write(output)
255 pfile.close()
255 pfile.close()
256 print '\n*** Profile printout saved to text file',\
256 print '\n*** Profile printout saved to text file',\
257 repr(text_file)+'.',sys_exit
257 repr(text_file)+'.',sys_exit
258
258
259 if 'r' in opts:
259 if 'r' in opts:
260 return stats
260 return stats
261 else:
261 else:
262 return None
262 return None
263
263
264 @line_magic
264 @line_magic
265 def pdb(self, parameter_s=''):
265 def pdb(self, parameter_s=''):
266 """Control the automatic calling of the pdb interactive debugger.
266 """Control the automatic calling of the pdb interactive debugger.
267
267
268 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
268 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
269 argument it works as a toggle.
269 argument it works as a toggle.
270
270
271 When an exception is triggered, IPython can optionally call the
271 When an exception is triggered, IPython can optionally call the
272 interactive pdb debugger after the traceback printout. %pdb toggles
272 interactive pdb debugger after the traceback printout. %pdb toggles
273 this feature on and off.
273 this feature on and off.
274
274
275 The initial state of this feature is set in your configuration
275 The initial state of this feature is set in your configuration
276 file (the option is ``InteractiveShell.pdb``).
276 file (the option is ``InteractiveShell.pdb``).
277
277
278 If you want to just activate the debugger AFTER an exception has fired,
278 If you want to just activate the debugger AFTER an exception has fired,
279 without having to type '%pdb on' and rerunning your code, you can use
279 without having to type '%pdb on' and rerunning your code, you can use
280 the %debug magic."""
280 the %debug magic."""
281
281
282 par = parameter_s.strip().lower()
282 par = parameter_s.strip().lower()
283
283
284 if par:
284 if par:
285 try:
285 try:
286 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
286 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
287 except KeyError:
287 except KeyError:
288 print ('Incorrect argument. Use on/1, off/0, '
288 print ('Incorrect argument. Use on/1, off/0, '
289 'or nothing for a toggle.')
289 'or nothing for a toggle.')
290 return
290 return
291 else:
291 else:
292 # toggle
292 # toggle
293 new_pdb = not self.shell.call_pdb
293 new_pdb = not self.shell.call_pdb
294
294
295 # set on the shell
295 # set on the shell
296 self.shell.call_pdb = new_pdb
296 self.shell.call_pdb = new_pdb
297 print 'Automatic pdb calling has been turned',on_off(new_pdb)
297 print 'Automatic pdb calling has been turned',on_off(new_pdb)
298
298
299 @line_magic
299 @line_magic
300 def debug(self, parameter_s=''):
300 def debug(self, parameter_s=''):
301 """Activate the interactive debugger in post-mortem mode.
301 """Activate the interactive debugger in post-mortem mode.
302
302
303 If an exception has just occurred, this lets you inspect its stack
303 If an exception has just occurred, this lets you inspect its stack
304 frames interactively. Note that this will always work only on the last
304 frames interactively. Note that this will always work only on the last
305 traceback that occurred, so you must call this quickly after an
305 traceback that occurred, so you must call this quickly after an
306 exception that you wish to inspect has fired, because if another one
306 exception that you wish to inspect has fired, because if another one
307 occurs, it clobbers the previous one.
307 occurs, it clobbers the previous one.
308
308
309 If you want IPython to automatically do this on every exception, see
309 If you want IPython to automatically do this on every exception, see
310 the %pdb magic for more details.
310 the %pdb magic for more details.
311 """
311 """
312 self.shell.debugger(force=True)
312 self.shell.debugger(force=True)
313
313
314 @line_magic
314 @line_magic
315 def tb(self, s):
315 def tb(self, s):
316 """Print the last traceback with the currently active exception mode.
316 """Print the last traceback with the currently active exception mode.
317
317
318 See %xmode for changing exception reporting modes."""
318 See %xmode for changing exception reporting modes."""
319 self.shell.showtraceback()
319 self.shell.showtraceback()
320
320
321 @skip_doctest
321 @skip_doctest
322 @line_magic
322 @line_magic
323 def run(self, parameter_s='', runner=None,
323 def run(self, parameter_s='', runner=None,
324 file_finder=get_py_filename):
324 file_finder=get_py_filename):
325 """Run the named file inside IPython as a program.
325 """Run the named file inside IPython as a program.
326
326
327 Usage:\\
327 Usage:\\
328 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options] -G] file [args]
328 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options] -G] file [args]
329
329
330 Parameters after the filename are passed as command-line arguments to
330 Parameters after the filename are passed as command-line arguments to
331 the program (put in sys.argv). Then, control returns to IPython's
331 the program (put in sys.argv). Then, control returns to IPython's
332 prompt.
332 prompt.
333
333
334 This is similar to running at a system prompt:\\
334 This is similar to running at a system prompt:\\
335 $ python file args\\
335 $ python file args\\
336 but with the advantage of giving you IPython's tracebacks, and of
336 but with the advantage of giving you IPython's tracebacks, and of
337 loading all variables into your interactive namespace for further use
337 loading all variables into your interactive namespace for further use
338 (unless -p is used, see below).
338 (unless -p is used, see below).
339
339
340 The file is executed in a namespace initially consisting only of
340 The file is executed in a namespace initially consisting only of
341 __name__=='__main__' and sys.argv constructed as indicated. It thus
341 __name__=='__main__' and sys.argv constructed as indicated. It thus
342 sees its environment as if it were being run as a stand-alone program
342 sees its environment as if it were being run as a stand-alone program
343 (except for sharing global objects such as previously imported
343 (except for sharing global objects such as previously imported
344 modules). But after execution, the IPython interactive namespace gets
344 modules). But after execution, the IPython interactive namespace gets
345 updated with all variables defined in the program (except for __name__
345 updated with all variables defined in the program (except for __name__
346 and sys.argv). This allows for very convenient loading of code for
346 and sys.argv). This allows for very convenient loading of code for
347 interactive work, while giving each program a 'clean sheet' to run in.
347 interactive work, while giving each program a 'clean sheet' to run in.
348
348
349 Arguments are expanded using shell-like glob match. Patterns
349 Arguments are expanded using shell-like glob match. Patterns
350 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
350 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
351 tilde '~' will be expanded into user's home directory. Unlike
351 tilde '~' will be expanded into user's home directory. Unlike
352 real shells, quotation does not suppress expansions. Use
352 real shells, quotation does not suppress expansions. Use
353 *two* back slashes (e.g., '\\\\*') to suppress expansions.
353 *two* back slashes (e.g., '\\\\*') to suppress expansions.
354 To completely disable these expansions, you can use -G flag.
354 To completely disable these expansions, you can use -G flag.
355
355
356 Options:
356 Options:
357
357
358 -n: __name__ is NOT set to '__main__', but to the running file's name
358 -n: __name__ is NOT set to '__main__', but to the running file's name
359 without extension (as python does under import). This allows running
359 without extension (as python does under import). This allows running
360 scripts and reloading the definitions in them without calling code
360 scripts and reloading the definitions in them without calling code
361 protected by an ' if __name__ == "__main__" ' clause.
361 protected by an ' if __name__ == "__main__" ' clause.
362
362
363 -i: run the file in IPython's namespace instead of an empty one. This
363 -i: run the file in IPython's namespace instead of an empty one. This
364 is useful if you are experimenting with code written in a text editor
364 is useful if you are experimenting with code written in a text editor
365 which depends on variables defined interactively.
365 which depends on variables defined interactively.
366
366
367 -e: ignore sys.exit() calls or SystemExit exceptions in the script
367 -e: ignore sys.exit() calls or SystemExit exceptions in the script
368 being run. This is particularly useful if IPython is being used to
368 being run. This is particularly useful if IPython is being used to
369 run unittests, which always exit with a sys.exit() call. In such
369 run unittests, which always exit with a sys.exit() call. In such
370 cases you are interested in the output of the test results, not in
370 cases you are interested in the output of the test results, not in
371 seeing a traceback of the unittest module.
371 seeing a traceback of the unittest module.
372
372
373 -t: print timing information at the end of the run. IPython will give
373 -t: print timing information at the end of the run. IPython will give
374 you an estimated CPU time consumption for your script, which under
374 you an estimated CPU time consumption for your script, which under
375 Unix uses the resource module to avoid the wraparound problems of
375 Unix uses the resource module to avoid the wraparound problems of
376 time.clock(). Under Unix, an estimate of time spent on system tasks
376 time.clock(). Under Unix, an estimate of time spent on system tasks
377 is also given (for Windows platforms this is reported as 0.0).
377 is also given (for Windows platforms this is reported as 0.0).
378
378
379 If -t is given, an additional -N<N> option can be given, where <N>
379 If -t is given, an additional -N<N> option can be given, where <N>
380 must be an integer indicating how many times you want the script to
380 must be an integer indicating how many times you want the script to
381 run. The final timing report will include total and per run results.
381 run. The final timing report will include total and per run results.
382
382
383 For example (testing the script uniq_stable.py)::
383 For example (testing the script uniq_stable.py)::
384
384
385 In [1]: run -t uniq_stable
385 In [1]: run -t uniq_stable
386
386
387 IPython CPU timings (estimated):\\
387 IPython CPU timings (estimated):\\
388 User : 0.19597 s.\\
388 User : 0.19597 s.\\
389 System: 0.0 s.\\
389 System: 0.0 s.\\
390
390
391 In [2]: run -t -N5 uniq_stable
391 In [2]: run -t -N5 uniq_stable
392
392
393 IPython CPU timings (estimated):\\
393 IPython CPU timings (estimated):\\
394 Total runs performed: 5\\
394 Total runs performed: 5\\
395 Times : Total Per run\\
395 Times : Total Per run\\
396 User : 0.910862 s, 0.1821724 s.\\
396 User : 0.910862 s, 0.1821724 s.\\
397 System: 0.0 s, 0.0 s.
397 System: 0.0 s, 0.0 s.
398
398
399 -d: run your program under the control of pdb, the Python debugger.
399 -d: run your program under the control of pdb, the Python debugger.
400 This allows you to execute your program step by step, watch variables,
400 This allows you to execute your program step by step, watch variables,
401 etc. Internally, what IPython does is similar to calling:
401 etc. Internally, what IPython does is similar to calling:
402
402
403 pdb.run('execfile("YOURFILENAME")')
403 pdb.run('execfile("YOURFILENAME")')
404
404
405 with a breakpoint set on line 1 of your file. You can change the line
405 with a breakpoint set on line 1 of your file. You can change the line
406 number for this automatic breakpoint to be <N> by using the -bN option
406 number for this automatic breakpoint to be <N> by using the -bN option
407 (where N must be an integer). For example::
407 (where N must be an integer). For example::
408
408
409 %run -d -b40 myscript
409 %run -d -b40 myscript
410
410
411 will set the first breakpoint at line 40 in myscript.py. Note that
411 will set the first breakpoint at line 40 in myscript.py. Note that
412 the first breakpoint must be set on a line which actually does
412 the first breakpoint must be set on a line which actually does
413 something (not a comment or docstring) for it to stop execution.
413 something (not a comment or docstring) for it to stop execution.
414
414
415 When the pdb debugger starts, you will see a (Pdb) prompt. You must
415 When the pdb debugger starts, you will see a (Pdb) prompt. You must
416 first enter 'c' (without quotes) to start execution up to the first
416 first enter 'c' (without quotes) to start execution up to the first
417 breakpoint.
417 breakpoint.
418
418
419 Entering 'help' gives information about the use of the debugger. You
419 Entering 'help' gives information about the use of the debugger. You
420 can easily see pdb's full documentation with "import pdb;pdb.help()"
420 can easily see pdb's full documentation with "import pdb;pdb.help()"
421 at a prompt.
421 at a prompt.
422
422
423 -p: run program under the control of the Python profiler module (which
423 -p: run program under the control of the Python profiler module (which
424 prints a detailed report of execution times, function calls, etc).
424 prints a detailed report of execution times, function calls, etc).
425
425
426 You can pass other options after -p which affect the behavior of the
426 You can pass other options after -p which affect the behavior of the
427 profiler itself. See the docs for %prun for details.
427 profiler itself. See the docs for %prun for details.
428
428
429 In this mode, the program's variables do NOT propagate back to the
429 In this mode, the program's variables do NOT propagate back to the
430 IPython interactive namespace (because they remain in the namespace
430 IPython interactive namespace (because they remain in the namespace
431 where the profiler executes them).
431 where the profiler executes them).
432
432
433 Internally this triggers a call to %prun, see its documentation for
433 Internally this triggers a call to %prun, see its documentation for
434 details on the options available specifically for profiling.
434 details on the options available specifically for profiling.
435
435
436 There is one special usage for which the text above doesn't apply:
436 There is one special usage for which the text above doesn't apply:
437 if the filename ends with .ipy, the file is run as ipython script,
437 if the filename ends with .ipy, the file is run as ipython script,
438 just as if the commands were written on IPython prompt.
438 just as if the commands were written on IPython prompt.
439
439
440 -m: specify module name to load instead of script path. Similar to
440 -m: specify module name to load instead of script path. Similar to
441 the -m option for the python interpreter. Use this option last if you
441 the -m option for the python interpreter. Use this option last if you
442 want to combine with other %run options. Unlike the python interpreter
442 want to combine with other %run options. Unlike the python interpreter
443 only source modules are allowed no .pyc or .pyo files.
443 only source modules are allowed no .pyc or .pyo files.
444 For example::
444 For example::
445
445
446 %run -m example
446 %run -m example
447
447
448 will run the example module.
448 will run the example module.
449
449
450 -G: disable shell-like glob expansion of arguments.
450 -G: disable shell-like glob expansion of arguments.
451
451
452 """
452 """
453
453
454 # get arguments and set sys.argv for program to be run.
454 # get arguments and set sys.argv for program to be run.
455 opts, arg_lst = self.parse_options(parameter_s,
455 opts, arg_lst = self.parse_options(parameter_s,
456 'nidtN:b:pD:l:rs:T:em:G',
456 'nidtN:b:pD:l:rs:T:em:G',
457 mode='list', list_all=1)
457 mode='list', list_all=1)
458 if "m" in opts:
458 if "m" in opts:
459 modulename = opts["m"][0]
459 modulename = opts["m"][0]
460 modpath = find_mod(modulename)
460 modpath = find_mod(modulename)
461 if modpath is None:
461 if modpath is None:
462 warn('%r is not a valid modulename on sys.path'%modulename)
462 warn('%r is not a valid modulename on sys.path'%modulename)
463 return
463 return
464 arg_lst = [modpath] + arg_lst
464 arg_lst = [modpath] + arg_lst
465 try:
465 try:
466 filename = file_finder(arg_lst[0])
466 filename = file_finder(arg_lst[0])
467 except IndexError:
467 except IndexError:
468 warn('you must provide at least a filename.')
468 warn('you must provide at least a filename.')
469 print '\n%run:\n', oinspect.getdoc(self.run)
469 print '\n%run:\n', oinspect.getdoc(self.run)
470 return
470 return
471 except IOError as e:
471 except IOError as e:
472 try:
472 try:
473 msg = str(e)
473 msg = str(e)
474 except UnicodeError:
474 except UnicodeError:
475 msg = e.message
475 msg = e.message
476 error(msg)
476 error(msg)
477 return
477 return
478
478
479 if filename.lower().endswith('.ipy'):
479 if filename.lower().endswith('.ipy'):
480 self.shell.safe_execfile_ipy(filename)
480 self.shell.safe_execfile_ipy(filename)
481 return
481 return
482
482
483 # Control the response to exit() calls made by the script being run
483 # Control the response to exit() calls made by the script being run
484 exit_ignore = 'e' in opts
484 exit_ignore = 'e' in opts
485
485
486 # Make sure that the running script gets a proper sys.argv as if it
486 # Make sure that the running script gets a proper sys.argv as if it
487 # were run from a system shell.
487 # were run from a system shell.
488 save_argv = sys.argv # save it for later restoring
488 save_argv = sys.argv # save it for later restoring
489
489
490 if 'G' in opts:
490 if 'G' in opts:
491 args = arg_lst[1:]
491 args = arg_lst[1:]
492 else:
492 else:
493 # tilde and glob expansion
493 # tilde and glob expansion
494 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
494 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
495
495
496 sys.argv = [filename] + args # put in the proper filename
496 sys.argv = [filename] + args # put in the proper filename
497 # protect sys.argv from potential unicode strings on Python 2:
497 # protect sys.argv from potential unicode strings on Python 2:
498 if not py3compat.PY3:
498 if not py3compat.PY3:
499 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
499 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
500
500
501 if 'i' in opts:
501 if 'i' in opts:
502 # Run in user's interactive namespace
502 # Run in user's interactive namespace
503 prog_ns = self.shell.user_ns
503 prog_ns = self.shell.user_ns
504 __name__save = self.shell.user_ns['__name__']
504 __name__save = self.shell.user_ns['__name__']
505 prog_ns['__name__'] = '__main__'
505 prog_ns['__name__'] = '__main__'
506 main_mod = self.shell.new_main_mod(prog_ns)
506 main_mod = self.shell.new_main_mod(prog_ns)
507 else:
507 else:
508 # Run in a fresh, empty namespace
508 # Run in a fresh, empty namespace
509 if 'n' in opts:
509 if 'n' in opts:
510 name = os.path.splitext(os.path.basename(filename))[0]
510 name = os.path.splitext(os.path.basename(filename))[0]
511 else:
511 else:
512 name = '__main__'
512 name = '__main__'
513
513
514 main_mod = self.shell.new_main_mod()
514 main_mod = self.shell.new_main_mod()
515 prog_ns = main_mod.__dict__
515 prog_ns = main_mod.__dict__
516 prog_ns['__name__'] = name
516 prog_ns['__name__'] = name
517
517
518 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
518 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
519 # set the __file__ global in the script's namespace
519 # set the __file__ global in the script's namespace
520 prog_ns['__file__'] = filename
520 prog_ns['__file__'] = filename
521
521
522 # pickle fix. See interactiveshell for an explanation. But we need to
522 # pickle fix. See interactiveshell for an explanation. But we need to
523 # make sure that, if we overwrite __main__, we replace it at the end
523 # make sure that, if we overwrite __main__, we replace it at the end
524 main_mod_name = prog_ns['__name__']
524 main_mod_name = prog_ns['__name__']
525
525
526 if main_mod_name == '__main__':
526 if main_mod_name == '__main__':
527 restore_main = sys.modules['__main__']
527 restore_main = sys.modules['__main__']
528 else:
528 else:
529 restore_main = False
529 restore_main = False
530
530
531 # This needs to be undone at the end to prevent holding references to
531 # This needs to be undone at the end to prevent holding references to
532 # every single object ever created.
532 # every single object ever created.
533 sys.modules[main_mod_name] = main_mod
533 sys.modules[main_mod_name] = main_mod
534
534
535 try:
535 try:
536 stats = None
536 stats = None
537 with self.shell.readline_no_record:
537 with self.shell.readline_no_record:
538 if 'p' in opts:
538 if 'p' in opts:
539 stats = self.prun('', None, False, opts, arg_lst, prog_ns)
539 stats = self.prun('', None, False, opts, arg_lst, prog_ns)
540 else:
540 else:
541 if 'd' in opts:
541 if 'd' in opts:
542 deb = debugger.Pdb(self.shell.colors)
542 deb = debugger.Pdb(self.shell.colors)
543 # reset Breakpoint state, which is moronically kept
543 # reset Breakpoint state, which is moronically kept
544 # in a class
544 # in a class
545 bdb.Breakpoint.next = 1
545 bdb.Breakpoint.next = 1
546 bdb.Breakpoint.bplist = {}
546 bdb.Breakpoint.bplist = {}
547 bdb.Breakpoint.bpbynumber = [None]
547 bdb.Breakpoint.bpbynumber = [None]
548 # Set an initial breakpoint to stop execution
548 # Set an initial breakpoint to stop execution
549 maxtries = 10
549 maxtries = 10
550 bp = int(opts.get('b', [1])[0])
550 bp = int(opts.get('b', [1])[0])
551 checkline = deb.checkline(filename, bp)
551 checkline = deb.checkline(filename, bp)
552 if not checkline:
552 if not checkline:
553 for bp in range(bp + 1, bp + maxtries + 1):
553 for bp in range(bp + 1, bp + maxtries + 1):
554 if deb.checkline(filename, bp):
554 if deb.checkline(filename, bp):
555 break
555 break
556 else:
556 else:
557 msg = ("\nI failed to find a valid line to set "
557 msg = ("\nI failed to find a valid line to set "
558 "a breakpoint\n"
558 "a breakpoint\n"
559 "after trying up to line: %s.\n"
559 "after trying up to line: %s.\n"
560 "Please set a valid breakpoint manually "
560 "Please set a valid breakpoint manually "
561 "with the -b option." % bp)
561 "with the -b option." % bp)
562 error(msg)
562 error(msg)
563 return
563 return
564 # if we find a good linenumber, set the breakpoint
564 # if we find a good linenumber, set the breakpoint
565 deb.do_break('%s:%s' % (filename, bp))
565 deb.do_break('%s:%s' % (filename, bp))
566
567 # Mimic Pdb._runscript(...)
568 deb._wait_for_mainpyfile = True
569 deb.mainpyfile = deb.canonic(filename)
570
566 # Start file run
571 # Start file run
567 print "NOTE: Enter 'c' at the",
572 print "NOTE: Enter 'c' at the",
568 print "%s prompt to start your script." % deb.prompt
573 print "%s prompt to start your script." % deb.prompt
569 ns = {'execfile': py3compat.execfile, 'prog_ns': prog_ns}
574 ns = {'execfile': py3compat.execfile, 'prog_ns': prog_ns}
570 try:
575 try:
571 #save filename so it can be used by methods on the deb object
576 #save filename so it can be used by methods on the deb object
572 deb._exec_filename = filename
577 deb._exec_filename = filename
573 deb.run('execfile("%s", prog_ns)' % filename, ns)
578 deb.run('execfile("%s", prog_ns)' % filename, ns)
574
579
575 except:
580 except:
576 etype, value, tb = sys.exc_info()
581 etype, value, tb = sys.exc_info()
577 # Skip three frames in the traceback: the %run one,
582 # Skip three frames in the traceback: the %run one,
578 # one inside bdb.py, and the command-line typed by the
583 # one inside bdb.py, and the command-line typed by the
579 # user (run by exec in pdb itself).
584 # user (run by exec in pdb itself).
580 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
585 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
581 else:
586 else:
582 if runner is None:
587 if runner is None:
583 runner = self.default_runner
588 runner = self.default_runner
584 if runner is None:
589 if runner is None:
585 runner = self.shell.safe_execfile
590 runner = self.shell.safe_execfile
586 if 't' in opts:
591 if 't' in opts:
587 # timed execution
592 # timed execution
588 try:
593 try:
589 nruns = int(opts['N'][0])
594 nruns = int(opts['N'][0])
590 if nruns < 1:
595 if nruns < 1:
591 error('Number of runs must be >=1')
596 error('Number of runs must be >=1')
592 return
597 return
593 except (KeyError):
598 except (KeyError):
594 nruns = 1
599 nruns = 1
595 twall0 = time.time()
600 twall0 = time.time()
596 if nruns == 1:
601 if nruns == 1:
597 t0 = clock2()
602 t0 = clock2()
598 runner(filename, prog_ns, prog_ns,
603 runner(filename, prog_ns, prog_ns,
599 exit_ignore=exit_ignore)
604 exit_ignore=exit_ignore)
600 t1 = clock2()
605 t1 = clock2()
601 t_usr = t1[0] - t0[0]
606 t_usr = t1[0] - t0[0]
602 t_sys = t1[1] - t0[1]
607 t_sys = t1[1] - t0[1]
603 print "\nIPython CPU timings (estimated):"
608 print "\nIPython CPU timings (estimated):"
604 print " User : %10.2f s." % t_usr
609 print " User : %10.2f s." % t_usr
605 print " System : %10.2f s." % t_sys
610 print " System : %10.2f s." % t_sys
606 else:
611 else:
607 runs = range(nruns)
612 runs = range(nruns)
608 t0 = clock2()
613 t0 = clock2()
609 for nr in runs:
614 for nr in runs:
610 runner(filename, prog_ns, prog_ns,
615 runner(filename, prog_ns, prog_ns,
611 exit_ignore=exit_ignore)
616 exit_ignore=exit_ignore)
612 t1 = clock2()
617 t1 = clock2()
613 t_usr = t1[0] - t0[0]
618 t_usr = t1[0] - t0[0]
614 t_sys = t1[1] - t0[1]
619 t_sys = t1[1] - t0[1]
615 print "\nIPython CPU timings (estimated):"
620 print "\nIPython CPU timings (estimated):"
616 print "Total runs performed:", nruns
621 print "Total runs performed:", nruns
617 print " Times : %10.2f %10.2f" % ('Total', 'Per run')
622 print " Times : %10.2f %10.2f" % ('Total', 'Per run')
618 print " User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns)
623 print " User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns)
619 print " System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns)
624 print " System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns)
620 twall1 = time.time()
625 twall1 = time.time()
621 print "Wall time: %10.2f s." % (twall1 - twall0)
626 print "Wall time: %10.2f s." % (twall1 - twall0)
622
627
623 else:
628 else:
624 # regular execution
629 # regular execution
625 runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore)
630 runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore)
626
631
627 if 'i' in opts:
632 if 'i' in opts:
628 self.shell.user_ns['__name__'] = __name__save
633 self.shell.user_ns['__name__'] = __name__save
629 else:
634 else:
630 # The shell MUST hold a reference to prog_ns so after %run
635 # The shell MUST hold a reference to prog_ns so after %run
631 # exits, the python deletion mechanism doesn't zero it out
636 # exits, the python deletion mechanism doesn't zero it out
632 # (leaving dangling references).
637 # (leaving dangling references).
633 self.shell.cache_main_mod(prog_ns, filename)
638 self.shell.cache_main_mod(prog_ns, filename)
634 # update IPython interactive namespace
639 # update IPython interactive namespace
635
640
636 # Some forms of read errors on the file may mean the
641 # Some forms of read errors on the file may mean the
637 # __name__ key was never set; using pop we don't have to
642 # __name__ key was never set; using pop we don't have to
638 # worry about a possible KeyError.
643 # worry about a possible KeyError.
639 prog_ns.pop('__name__', None)
644 prog_ns.pop('__name__', None)
640
645
641 self.shell.user_ns.update(prog_ns)
646 self.shell.user_ns.update(prog_ns)
642 finally:
647 finally:
643 # It's a bit of a mystery why, but __builtins__ can change from
648 # It's a bit of a mystery why, but __builtins__ can change from
644 # being a module to becoming a dict missing some key data after
649 # being a module to becoming a dict missing some key data after
645 # %run. As best I can see, this is NOT something IPython is doing
650 # %run. As best I can see, this is NOT something IPython is doing
646 # at all, and similar problems have been reported before:
651 # at all, and similar problems have been reported before:
647 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
652 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
648 # Since this seems to be done by the interpreter itself, the best
653 # Since this seems to be done by the interpreter itself, the best
649 # we can do is to at least restore __builtins__ for the user on
654 # we can do is to at least restore __builtins__ for the user on
650 # exit.
655 # exit.
651 self.shell.user_ns['__builtins__'] = builtin_mod
656 self.shell.user_ns['__builtins__'] = builtin_mod
652
657
653 # Ensure key global structures are restored
658 # Ensure key global structures are restored
654 sys.argv = save_argv
659 sys.argv = save_argv
655 if restore_main:
660 if restore_main:
656 sys.modules['__main__'] = restore_main
661 sys.modules['__main__'] = restore_main
657 else:
662 else:
658 # Remove from sys.modules the reference to main_mod we'd
663 # Remove from sys.modules the reference to main_mod we'd
659 # added. Otherwise it will trap references to objects
664 # added. Otherwise it will trap references to objects
660 # contained therein.
665 # contained therein.
661 del sys.modules[main_mod_name]
666 del sys.modules[main_mod_name]
662
667
663 return stats
668 return stats
664
669
665 @skip_doctest
670 @skip_doctest
666 @line_cell_magic
671 @line_cell_magic
667 def timeit(self, line='', cell=None):
672 def timeit(self, line='', cell=None):
668 """Time execution of a Python statement or expression
673 """Time execution of a Python statement or expression
669
674
670 Usage, in line mode:
675 Usage, in line mode:
671 %timeit [-n<N> -r<R> [-t|-c]] statement
676 %timeit [-n<N> -r<R> [-t|-c]] statement
672 or in cell mode:
677 or in cell mode:
673 %%timeit [-n<N> -r<R> [-t|-c]] setup_code
678 %%timeit [-n<N> -r<R> [-t|-c]] setup_code
674 code
679 code
675 code...
680 code...
676
681
677 Time execution of a Python statement or expression using the timeit
682 Time execution of a Python statement or expression using the timeit
678 module. This function can be used both as a line and cell magic:
683 module. This function can be used both as a line and cell magic:
679
684
680 - In line mode you can time a single-line statement (though multiple
685 - In line mode you can time a single-line statement (though multiple
681 ones can be chained with using semicolons).
686 ones can be chained with using semicolons).
682
687
683 - In cell mode, the statement in the first line is used as setup code
688 - In cell mode, the statement in the first line is used as setup code
684 (executed but not timed) and the body of the cell is timed. The cell
689 (executed but not timed) and the body of the cell is timed. The cell
685 body has access to any variables created in the setup code.
690 body has access to any variables created in the setup code.
686
691
687 Options:
692 Options:
688 -n<N>: execute the given statement <N> times in a loop. If this value
693 -n<N>: execute the given statement <N> times in a loop. If this value
689 is not given, a fitting value is chosen.
694 is not given, a fitting value is chosen.
690
695
691 -r<R>: repeat the loop iteration <R> times and take the best result.
696 -r<R>: repeat the loop iteration <R> times and take the best result.
692 Default: 3
697 Default: 3
693
698
694 -t: use time.time to measure the time, which is the default on Unix.
699 -t: use time.time to measure the time, which is the default on Unix.
695 This function measures wall time.
700 This function measures wall time.
696
701
697 -c: use time.clock to measure the time, which is the default on
702 -c: use time.clock to measure the time, which is the default on
698 Windows and measures wall time. On Unix, resource.getrusage is used
703 Windows and measures wall time. On Unix, resource.getrusage is used
699 instead and returns the CPU user time.
704 instead and returns the CPU user time.
700
705
701 -p<P>: use a precision of <P> digits to display the timing result.
706 -p<P>: use a precision of <P> digits to display the timing result.
702 Default: 3
707 Default: 3
703
708
704
709
705 Examples
710 Examples
706 --------
711 --------
707 ::
712 ::
708
713
709 In [1]: %timeit pass
714 In [1]: %timeit pass
710 10000000 loops, best of 3: 53.3 ns per loop
715 10000000 loops, best of 3: 53.3 ns per loop
711
716
712 In [2]: u = None
717 In [2]: u = None
713
718
714 In [3]: %timeit u is None
719 In [3]: %timeit u is None
715 10000000 loops, best of 3: 184 ns per loop
720 10000000 loops, best of 3: 184 ns per loop
716
721
717 In [4]: %timeit -r 4 u == None
722 In [4]: %timeit -r 4 u == None
718 1000000 loops, best of 4: 242 ns per loop
723 1000000 loops, best of 4: 242 ns per loop
719
724
720 In [5]: import time
725 In [5]: import time
721
726
722 In [6]: %timeit -n1 time.sleep(2)
727 In [6]: %timeit -n1 time.sleep(2)
723 1 loops, best of 3: 2 s per loop
728 1 loops, best of 3: 2 s per loop
724
729
725
730
726 The times reported by %timeit will be slightly higher than those
731 The times reported by %timeit will be slightly higher than those
727 reported by the timeit.py script when variables are accessed. This is
732 reported by the timeit.py script when variables are accessed. This is
728 due to the fact that %timeit executes the statement in the namespace
733 due to the fact that %timeit executes the statement in the namespace
729 of the shell, compared with timeit.py, which uses a single setup
734 of the shell, compared with timeit.py, which uses a single setup
730 statement to import function or create variables. Generally, the bias
735 statement to import function or create variables. Generally, the bias
731 does not matter as long as results from timeit.py are not mixed with
736 does not matter as long as results from timeit.py are not mixed with
732 those from %timeit."""
737 those from %timeit."""
733
738
734 import timeit
739 import timeit
735 import math
740 import math
736
741
737 # XXX: Unfortunately the unicode 'micro' symbol can cause problems in
742 # XXX: Unfortunately the unicode 'micro' symbol can cause problems in
738 # certain terminals. Until we figure out a robust way of
743 # certain terminals. Until we figure out a robust way of
739 # auto-detecting if the terminal can deal with it, use plain 'us' for
744 # auto-detecting if the terminal can deal with it, use plain 'us' for
740 # microseconds. I am really NOT happy about disabling the proper
745 # microseconds. I am really NOT happy about disabling the proper
741 # 'micro' prefix, but crashing is worse... If anyone knows what the
746 # 'micro' prefix, but crashing is worse... If anyone knows what the
742 # right solution for this is, I'm all ears...
747 # right solution for this is, I'm all ears...
743 #
748 #
744 # Note: using
749 # Note: using
745 #
750 #
746 # s = u'\xb5'
751 # s = u'\xb5'
747 # s.encode(sys.getdefaultencoding())
752 # s.encode(sys.getdefaultencoding())
748 #
753 #
749 # is not sufficient, as I've seen terminals where that fails but
754 # is not sufficient, as I've seen terminals where that fails but
750 # print s
755 # print s
751 #
756 #
752 # succeeds
757 # succeeds
753 #
758 #
754 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
759 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
755
760
756 #units = [u"s", u"ms",u'\xb5',"ns"]
761 #units = [u"s", u"ms",u'\xb5',"ns"]
757 units = [u"s", u"ms",u'us',"ns"]
762 units = [u"s", u"ms",u'us',"ns"]
758
763
759 scaling = [1, 1e3, 1e6, 1e9]
764 scaling = [1, 1e3, 1e6, 1e9]
760
765
761 opts, stmt = self.parse_options(line,'n:r:tcp:',
766 opts, stmt = self.parse_options(line,'n:r:tcp:',
762 posix=False, strict=False)
767 posix=False, strict=False)
763 if stmt == "" and cell is None:
768 if stmt == "" and cell is None:
764 return
769 return
765 timefunc = timeit.default_timer
770 timefunc = timeit.default_timer
766 number = int(getattr(opts, "n", 0))
771 number = int(getattr(opts, "n", 0))
767 repeat = int(getattr(opts, "r", timeit.default_repeat))
772 repeat = int(getattr(opts, "r", timeit.default_repeat))
768 precision = int(getattr(opts, "p", 3))
773 precision = int(getattr(opts, "p", 3))
769 if hasattr(opts, "t"):
774 if hasattr(opts, "t"):
770 timefunc = time.time
775 timefunc = time.time
771 if hasattr(opts, "c"):
776 if hasattr(opts, "c"):
772 timefunc = clock
777 timefunc = clock
773
778
774 timer = timeit.Timer(timer=timefunc)
779 timer = timeit.Timer(timer=timefunc)
775 # this code has tight coupling to the inner workings of timeit.Timer,
780 # this code has tight coupling to the inner workings of timeit.Timer,
776 # but is there a better way to achieve that the code stmt has access
781 # but is there a better way to achieve that the code stmt has access
777 # to the shell namespace?
782 # to the shell namespace?
778 transform = self.shell.input_splitter.transform_cell
783 transform = self.shell.input_splitter.transform_cell
779 if cell is None:
784 if cell is None:
780 # called as line magic
785 # called as line magic
781 setup = 'pass'
786 setup = 'pass'
782 stmt = timeit.reindent(transform(stmt), 8)
787 stmt = timeit.reindent(transform(stmt), 8)
783 else:
788 else:
784 setup = timeit.reindent(transform(stmt), 4)
789 setup = timeit.reindent(transform(stmt), 4)
785 stmt = timeit.reindent(transform(cell), 8)
790 stmt = timeit.reindent(transform(cell), 8)
786
791
787 # From Python 3.3, this template uses new-style string formatting.
792 # From Python 3.3, this template uses new-style string formatting.
788 if sys.version_info >= (3, 3):
793 if sys.version_info >= (3, 3):
789 src = timeit.template.format(stmt=stmt, setup=setup)
794 src = timeit.template.format(stmt=stmt, setup=setup)
790 else:
795 else:
791 src = timeit.template % dict(stmt=stmt, setup=setup)
796 src = timeit.template % dict(stmt=stmt, setup=setup)
792
797
793 # Track compilation time so it can be reported if too long
798 # Track compilation time so it can be reported if too long
794 # Minimum time above which compilation time will be reported
799 # Minimum time above which compilation time will be reported
795 tc_min = 0.1
800 tc_min = 0.1
796
801
797 t0 = clock()
802 t0 = clock()
798 code = compile(src, "<magic-timeit>", "exec")
803 code = compile(src, "<magic-timeit>", "exec")
799 tc = clock()-t0
804 tc = clock()-t0
800
805
801 ns = {}
806 ns = {}
802 exec code in self.shell.user_ns, ns
807 exec code in self.shell.user_ns, ns
803 timer.inner = ns["inner"]
808 timer.inner = ns["inner"]
804
809
805 if number == 0:
810 if number == 0:
806 # determine number so that 0.2 <= total time < 2.0
811 # determine number so that 0.2 <= total time < 2.0
807 number = 1
812 number = 1
808 for i in range(1, 10):
813 for i in range(1, 10):
809 if timer.timeit(number) >= 0.2:
814 if timer.timeit(number) >= 0.2:
810 break
815 break
811 number *= 10
816 number *= 10
812
817
813 best = min(timer.repeat(repeat, number)) / number
818 best = min(timer.repeat(repeat, number)) / number
814
819
815 if best > 0.0 and best < 1000.0:
820 if best > 0.0 and best < 1000.0:
816 order = min(-int(math.floor(math.log10(best)) // 3), 3)
821 order = min(-int(math.floor(math.log10(best)) // 3), 3)
817 elif best >= 1000.0:
822 elif best >= 1000.0:
818 order = 0
823 order = 0
819 else:
824 else:
820 order = 3
825 order = 3
821 print u"%d loops, best of %d: %.*g %s per loop" % (number, repeat,
826 print u"%d loops, best of %d: %.*g %s per loop" % (number, repeat,
822 precision,
827 precision,
823 best * scaling[order],
828 best * scaling[order],
824 units[order])
829 units[order])
825 if tc > tc_min:
830 if tc > tc_min:
826 print "Compiler time: %.2f s" % tc
831 print "Compiler time: %.2f s" % tc
827
832
828 @skip_doctest
833 @skip_doctest
829 @needs_local_scope
834 @needs_local_scope
830 @line_magic
835 @line_magic
831 def time(self,parameter_s, local_ns=None):
836 def time(self,parameter_s, local_ns=None):
832 """Time execution of a Python statement or expression.
837 """Time execution of a Python statement or expression.
833
838
834 The CPU and wall clock times are printed, and the value of the
839 The CPU and wall clock times are printed, and the value of the
835 expression (if any) is returned. Note that under Win32, system time
840 expression (if any) is returned. Note that under Win32, system time
836 is always reported as 0, since it can not be measured.
841 is always reported as 0, since it can not be measured.
837
842
838 This function provides very basic timing functionality. In Python
843 This function provides very basic timing functionality. In Python
839 2.3, the timeit module offers more control and sophistication, so this
844 2.3, the timeit module offers more control and sophistication, so this
840 could be rewritten to use it (patches welcome).
845 could be rewritten to use it (patches welcome).
841
846
842 Examples
847 Examples
843 --------
848 --------
844 ::
849 ::
845
850
846 In [1]: time 2**128
851 In [1]: time 2**128
847 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
852 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
848 Wall time: 0.00
853 Wall time: 0.00
849 Out[1]: 340282366920938463463374607431768211456L
854 Out[1]: 340282366920938463463374607431768211456L
850
855
851 In [2]: n = 1000000
856 In [2]: n = 1000000
852
857
853 In [3]: time sum(range(n))
858 In [3]: time sum(range(n))
854 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
859 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
855 Wall time: 1.37
860 Wall time: 1.37
856 Out[3]: 499999500000L
861 Out[3]: 499999500000L
857
862
858 In [4]: time print 'hello world'
863 In [4]: time print 'hello world'
859 hello world
864 hello world
860 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
865 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
861 Wall time: 0.00
866 Wall time: 0.00
862
867
863 Note that the time needed by Python to compile the given expression
868 Note that the time needed by Python to compile the given expression
864 will be reported if it is more than 0.1s. In this example, the
869 will be reported if it is more than 0.1s. In this example, the
865 actual exponentiation is done by Python at compilation time, so while
870 actual exponentiation is done by Python at compilation time, so while
866 the expression can take a noticeable amount of time to compute, that
871 the expression can take a noticeable amount of time to compute, that
867 time is purely due to the compilation:
872 time is purely due to the compilation:
868
873
869 In [5]: time 3**9999;
874 In [5]: time 3**9999;
870 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
875 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
871 Wall time: 0.00 s
876 Wall time: 0.00 s
872
877
873 In [6]: time 3**999999;
878 In [6]: time 3**999999;
874 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
879 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
875 Wall time: 0.00 s
880 Wall time: 0.00 s
876 Compiler : 0.78 s
881 Compiler : 0.78 s
877 """
882 """
878
883
879 # fail immediately if the given expression can't be compiled
884 # fail immediately if the given expression can't be compiled
880
885
881 expr = self.shell.prefilter(parameter_s,False)
886 expr = self.shell.prefilter(parameter_s,False)
882
887
883 # Minimum time above which compilation time will be reported
888 # Minimum time above which compilation time will be reported
884 tc_min = 0.1
889 tc_min = 0.1
885
890
886 try:
891 try:
887 mode = 'eval'
892 mode = 'eval'
888 t0 = clock()
893 t0 = clock()
889 code = compile(expr,'<timed eval>',mode)
894 code = compile(expr,'<timed eval>',mode)
890 tc = clock()-t0
895 tc = clock()-t0
891 except SyntaxError:
896 except SyntaxError:
892 mode = 'exec'
897 mode = 'exec'
893 t0 = clock()
898 t0 = clock()
894 code = compile(expr,'<timed exec>',mode)
899 code = compile(expr,'<timed exec>',mode)
895 tc = clock()-t0
900 tc = clock()-t0
896 # skew measurement as little as possible
901 # skew measurement as little as possible
897 glob = self.shell.user_ns
902 glob = self.shell.user_ns
898 wtime = time.time
903 wtime = time.time
899 # time execution
904 # time execution
900 wall_st = wtime()
905 wall_st = wtime()
901 if mode=='eval':
906 if mode=='eval':
902 st = clock2()
907 st = clock2()
903 out = eval(code, glob, local_ns)
908 out = eval(code, glob, local_ns)
904 end = clock2()
909 end = clock2()
905 else:
910 else:
906 st = clock2()
911 st = clock2()
907 exec code in glob, local_ns
912 exec code in glob, local_ns
908 end = clock2()
913 end = clock2()
909 out = None
914 out = None
910 wall_end = wtime()
915 wall_end = wtime()
911 # Compute actual times and report
916 # Compute actual times and report
912 wall_time = wall_end-wall_st
917 wall_time = wall_end-wall_st
913 cpu_user = end[0]-st[0]
918 cpu_user = end[0]-st[0]
914 cpu_sys = end[1]-st[1]
919 cpu_sys = end[1]-st[1]
915 cpu_tot = cpu_user+cpu_sys
920 cpu_tot = cpu_user+cpu_sys
916 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
921 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
917 (cpu_user,cpu_sys,cpu_tot)
922 (cpu_user,cpu_sys,cpu_tot)
918 print "Wall time: %.2f s" % wall_time
923 print "Wall time: %.2f s" % wall_time
919 if tc > tc_min:
924 if tc > tc_min:
920 print "Compiler : %.2f s" % tc
925 print "Compiler : %.2f s" % tc
921 return out
926 return out
922
927
923 @skip_doctest
928 @skip_doctest
924 @line_magic
929 @line_magic
925 def macro(self, parameter_s=''):
930 def macro(self, parameter_s=''):
926 """Define a macro for future re-execution. It accepts ranges of history,
931 """Define a macro for future re-execution. It accepts ranges of history,
927 filenames or string objects.
932 filenames or string objects.
928
933
929 Usage:\\
934 Usage:\\
930 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
935 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
931
936
932 Options:
937 Options:
933
938
934 -r: use 'raw' input. By default, the 'processed' history is used,
939 -r: use 'raw' input. By default, the 'processed' history is used,
935 so that magics are loaded in their transformed version to valid
940 so that magics are loaded in their transformed version to valid
936 Python. If this option is given, the raw input as typed as the
941 Python. If this option is given, the raw input as typed as the
937 command line is used instead.
942 command line is used instead.
938
943
939 This will define a global variable called `name` which is a string
944 This will define a global variable called `name` which is a string
940 made of joining the slices and lines you specify (n1,n2,... numbers
945 made of joining the slices and lines you specify (n1,n2,... numbers
941 above) from your input history into a single string. This variable
946 above) from your input history into a single string. This variable
942 acts like an automatic function which re-executes those lines as if
947 acts like an automatic function which re-executes those lines as if
943 you had typed them. You just type 'name' at the prompt and the code
948 you had typed them. You just type 'name' at the prompt and the code
944 executes.
949 executes.
945
950
946 The syntax for indicating input ranges is described in %history.
951 The syntax for indicating input ranges is described in %history.
947
952
948 Note: as a 'hidden' feature, you can also use traditional python slice
953 Note: as a 'hidden' feature, you can also use traditional python slice
949 notation, where N:M means numbers N through M-1.
954 notation, where N:M means numbers N through M-1.
950
955
951 For example, if your history contains (%hist prints it)::
956 For example, if your history contains (%hist prints it)::
952
957
953 44: x=1
958 44: x=1
954 45: y=3
959 45: y=3
955 46: z=x+y
960 46: z=x+y
956 47: print x
961 47: print x
957 48: a=5
962 48: a=5
958 49: print 'x',x,'y',y
963 49: print 'x',x,'y',y
959
964
960 you can create a macro with lines 44 through 47 (included) and line 49
965 you can create a macro with lines 44 through 47 (included) and line 49
961 called my_macro with::
966 called my_macro with::
962
967
963 In [55]: %macro my_macro 44-47 49
968 In [55]: %macro my_macro 44-47 49
964
969
965 Now, typing `my_macro` (without quotes) will re-execute all this code
970 Now, typing `my_macro` (without quotes) will re-execute all this code
966 in one pass.
971 in one pass.
967
972
968 You don't need to give the line-numbers in order, and any given line
973 You don't need to give the line-numbers in order, and any given line
969 number can appear multiple times. You can assemble macros with any
974 number can appear multiple times. You can assemble macros with any
970 lines from your input history in any order.
975 lines from your input history in any order.
971
976
972 The macro is a simple object which holds its value in an attribute,
977 The macro is a simple object which holds its value in an attribute,
973 but IPython's display system checks for macros and executes them as
978 but IPython's display system checks for macros and executes them as
974 code instead of printing them when you type their name.
979 code instead of printing them when you type their name.
975
980
976 You can view a macro's contents by explicitly printing it with::
981 You can view a macro's contents by explicitly printing it with::
977
982
978 print macro_name
983 print macro_name
979
984
980 """
985 """
981 opts,args = self.parse_options(parameter_s,'r',mode='list')
986 opts,args = self.parse_options(parameter_s,'r',mode='list')
982 if not args: # List existing macros
987 if not args: # List existing macros
983 return sorted(k for k,v in self.shell.user_ns.iteritems() if\
988 return sorted(k for k,v in self.shell.user_ns.iteritems() if\
984 isinstance(v, Macro))
989 isinstance(v, Macro))
985 if len(args) == 1:
990 if len(args) == 1:
986 raise UsageError(
991 raise UsageError(
987 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
992 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
988 name, codefrom = args[0], " ".join(args[1:])
993 name, codefrom = args[0], " ".join(args[1:])
989
994
990 #print 'rng',ranges # dbg
995 #print 'rng',ranges # dbg
991 try:
996 try:
992 lines = self.shell.find_user_code(codefrom, 'r' in opts)
997 lines = self.shell.find_user_code(codefrom, 'r' in opts)
993 except (ValueError, TypeError) as e:
998 except (ValueError, TypeError) as e:
994 print e.args[0]
999 print e.args[0]
995 return
1000 return
996 macro = Macro(lines)
1001 macro = Macro(lines)
997 self.shell.define_macro(name, macro)
1002 self.shell.define_macro(name, macro)
998 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
1003 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
999 print '=== Macro contents: ==='
1004 print '=== Macro contents: ==='
1000 print macro,
1005 print macro,
1001
1006
1002 @magic_arguments.magic_arguments()
1007 @magic_arguments.magic_arguments()
1003 @magic_arguments.argument('output', type=str, default='', nargs='?',
1008 @magic_arguments.argument('output', type=str, default='', nargs='?',
1004 help="""The name of the variable in which to store output.
1009 help="""The name of the variable in which to store output.
1005 This is a utils.io.CapturedIO object with stdout/err attributes
1010 This is a utils.io.CapturedIO object with stdout/err attributes
1006 for the text of the captured output.
1011 for the text of the captured output.
1007
1012
1008 CapturedOutput also has a show() method for displaying the output,
1013 CapturedOutput also has a show() method for displaying the output,
1009 and __call__ as well, so you can use that to quickly display the
1014 and __call__ as well, so you can use that to quickly display the
1010 output.
1015 output.
1011
1016
1012 If unspecified, captured output is discarded.
1017 If unspecified, captured output is discarded.
1013 """
1018 """
1014 )
1019 )
1015 @magic_arguments.argument('--no-stderr', action="store_true",
1020 @magic_arguments.argument('--no-stderr', action="store_true",
1016 help="""Don't capture stderr."""
1021 help="""Don't capture stderr."""
1017 )
1022 )
1018 @magic_arguments.argument('--no-stdout', action="store_true",
1023 @magic_arguments.argument('--no-stdout', action="store_true",
1019 help="""Don't capture stdout."""
1024 help="""Don't capture stdout."""
1020 )
1025 )
1021 @cell_magic
1026 @cell_magic
1022 def capture(self, line, cell):
1027 def capture(self, line, cell):
1023 """run the cell, capturing stdout/err"""
1028 """run the cell, capturing stdout/err"""
1024 args = magic_arguments.parse_argstring(self.capture, line)
1029 args = magic_arguments.parse_argstring(self.capture, line)
1025 out = not args.no_stdout
1030 out = not args.no_stdout
1026 err = not args.no_stderr
1031 err = not args.no_stderr
1027 with capture_output(out, err) as io:
1032 with capture_output(out, err) as io:
1028 self.shell.run_cell(cell)
1033 self.shell.run_cell(cell)
1029 if args.output:
1034 if args.output:
1030 self.shell.user_ns[args.output] = io
1035 self.shell.user_ns[args.output] = io
@@ -1,76 +1,92 b''
1 """Implementation of magic functions for the extension machinery.
1 """Implementation of magic functions for the extension machinery.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012 The IPython Development Team.
4 # Copyright (c) 2012 The IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 # Stdlib
15 # Stdlib
16 import os
16 import os
17
17
18 # Our own packages
18 # Our own packages
19 from IPython.core.error import UsageError
19 from IPython.core.error import UsageError
20 from IPython.core.magic import Magics, magics_class, line_magic
20 from IPython.core.magic import Magics, magics_class, line_magic
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Magic implementation classes
23 # Magic implementation classes
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 @magics_class
26 @magics_class
27 class ExtensionMagics(Magics):
27 class ExtensionMagics(Magics):
28 """Magics to manage the IPython extensions system."""
28 """Magics to manage the IPython extensions system."""
29
29
30 @line_magic
30 @line_magic
31 def install_ext(self, parameter_s=''):
31 def install_ext(self, parameter_s=''):
32 """Download and install an extension from a URL, e.g.::
32 """Download and install an extension from a URL, e.g.::
33
33
34 %install_ext https://bitbucket.org/birkenfeld/ipython-physics/raw/d1310a2ab15d/physics.py
34 %install_ext https://bitbucket.org/birkenfeld/ipython-physics/raw/d1310a2ab15d/physics.py
35
35
36 The URL should point to an importable Python module - either a .py file
36 The URL should point to an importable Python module - either a .py file
37 or a .zip file.
37 or a .zip file.
38
38
39 Parameters:
39 Parameters:
40
40
41 -n filename : Specify a name for the file, rather than taking it from
41 -n filename : Specify a name for the file, rather than taking it from
42 the URL.
42 the URL.
43 """
43 """
44 opts, args = self.parse_options(parameter_s, 'n:')
44 opts, args = self.parse_options(parameter_s, 'n:')
45 try:
45 try:
46 filename = self.shell.extension_manager.install_extension(args,
46 filename = self.shell.extension_manager.install_extension(args,
47 opts.get('n'))
47 opts.get('n'))
48 except ValueError as e:
48 except ValueError as e:
49 print e
49 print e
50 return
50 return
51
51
52 filename = os.path.basename(filename)
52 filename = os.path.basename(filename)
53 print "Installed %s. To use it, type:" % filename
53 print "Installed %s. To use it, type:" % filename
54 print " %%load_ext %s" % os.path.splitext(filename)[0]
54 print " %%load_ext %s" % os.path.splitext(filename)[0]
55
55
56
56
57 @line_magic
57 @line_magic
58 def load_ext(self, module_str):
58 def load_ext(self, module_str):
59 """Load an IPython extension by its module name."""
59 """Load an IPython extension by its module name."""
60 if not module_str:
60 if not module_str:
61 raise UsageError('Missing module name.')
61 raise UsageError('Missing module name.')
62 return self.shell.extension_manager.load_extension(module_str)
62 res = self.shell.extension_manager.load_extension(module_str)
63
64 if res == 'already loaded':
65 print "The %s extension is already loaded. To reload it, use:" % module_str
66 print " %reload_ext", module_str
67 elif res == 'no load function':
68 print "The %s module is not an IPython extension." % module_str
63
69
64 @line_magic
70 @line_magic
65 def unload_ext(self, module_str):
71 def unload_ext(self, module_str):
66 """Unload an IPython extension by its module name."""
72 """Unload an IPython extension by its module name.
73
74 Not all extensions can be unloaded, only those which define an
75 ``unload_ipython_extension`` function.
76 """
67 if not module_str:
77 if not module_str:
68 raise UsageError('Missing module name.')
78 raise UsageError('Missing module name.')
69 self.shell.extension_manager.unload_extension(module_str)
79
80 res = self.shell.extension_manager.unload_extension(module_str)
81
82 if res == 'no unload function':
83 print "The %s extension doesn't define how to unload it." % module_str
84 elif res == "not loaded":
85 print "The %s extension is not loaded." % module_str
70
86
71 @line_magic
87 @line_magic
72 def reload_ext(self, module_str):
88 def reload_ext(self, module_str):
73 """Reload an IPython extension by its module name."""
89 """Reload an IPython extension by its module name."""
74 if not module_str:
90 if not module_str:
75 raise UsageError('Missing module name.')
91 raise UsageError('Missing module name.')
76 self.shell.extension_manager.reload_extension(module_str)
92 self.shell.extension_manager.reload_extension(module_str)
@@ -1,289 +1,307 b''
1 """Implementation of magic functions related to History.
1 """Implementation of magic functions related to History.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012, IPython Development Team.
4 # Copyright (c) 2012, IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
14 from __future__ import print_function
15
15
16 # Stdlib
16 # Stdlib
17 import os
17 import os
18 from io import open as io_open
18 from io import open as io_open
19 from IPython.external.argparse import Action
19
20
20 # Our own packages
21 # Our own packages
21 from IPython.core.error import StdinNotImplementedError
22 from IPython.core.error import StdinNotImplementedError
22 from IPython.core.magic import Magics, magics_class, line_magic
23 from IPython.core.magic import Magics, magics_class, line_magic
24 from IPython.core.magic_arguments import (argument, magic_arguments,
25 parse_argstring)
23 from IPython.testing.skipdoctest import skip_doctest
26 from IPython.testing.skipdoctest import skip_doctest
24 from IPython.utils import io
27 from IPython.utils import io
25
28
26 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
27 # Magics class implementation
30 # Magics class implementation
28 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
29
32
33
34 _unspecified = object()
35
36
30 @magics_class
37 @magics_class
31 class HistoryMagics(Magics):
38 class HistoryMagics(Magics):
32
39
40 @magic_arguments()
41 @argument(
42 '-n', dest='print_nums', action='store_true', default=False,
43 help="""
44 print line numbers for each input.
45 This feature is only available if numbered prompts are in use.
46 """)
47 @argument(
48 '-o', dest='get_output', action='store_true', default=False,
49 help="also print outputs for each input.")
50 @argument(
51 '-p', dest='pyprompts', action='store_true', default=False,
52 help="""
53 print classic '>>>' python prompts before each input.
54 This is useful for making documentation, and in conjunction
55 with -o, for producing doctest-ready output.
56 """)
57 @argument(
58 '-t', dest='raw', action='store_false', default=True,
59 help="""
60 print the 'translated' history, as IPython understands it.
61 IPython filters your input and converts it all into valid Python
62 source before executing it (things like magics or aliases are turned
63 into function calls, for example). With this option, you'll see the
64 native history instead of the user-entered version: '%%cd /' will be
65 seen as 'get_ipython().magic("%%cd /")' instead of '%%cd /'.
66 """)
67 @argument(
68 '-f', dest='filename',
69 help="""
70 FILENAME: instead of printing the output to the screen, redirect
71 it to the given file. The file is always overwritten, though *when
72 it can*, IPython asks for confirmation first. In particular, running
73 the command 'history -f FILENAME' from the IPython Notebook
74 interface will replace FILENAME even if it already exists *without*
75 confirmation.
76 """)
77 @argument(
78 '-g', dest='pattern', nargs='*', default=None,
79 help="""
80 treat the arg as a glob pattern to search for in (full) history.
81 This includes the saved history (almost all commands ever written).
82 The pattern may contain '?' to match one unknown character and '*'
83 to match any number of unknown characters. Use '%%hist -g' to show
84 full saved history (may be very long).
85 """)
86 @argument(
87 '-l', dest='limit', type=int, nargs='?', default=_unspecified,
88 help="""
89 get the last n lines from all sessions. Specify n as a single
90 arg, or the default is the last 10 lines.
91 """)
92 @argument('range', nargs='*')
33 @skip_doctest
93 @skip_doctest
34 @line_magic
94 @line_magic
35 def history(self, parameter_s = ''):
95 def history(self, parameter_s = ''):
36 """Print input history (_i<n> variables), with most recent last.
96 """Print input history (_i<n> variables), with most recent last.
37
97
38 %history [-o -p -t -n] [-f filename] [range | -g pattern | -l number]
39
40 By default, input history is printed without line numbers so it can be
98 By default, input history is printed without line numbers so it can be
41 directly pasted into an editor. Use -n to show them.
99 directly pasted into an editor. Use -n to show them.
42
100
43 By default, all input history from the current session is displayed.
101 By default, all input history from the current session is displayed.
44 Ranges of history can be indicated using the syntax:
102 Ranges of history can be indicated using the syntax:
45 4 : Line 4, current session
103 4 : Line 4, current session
46 4-6 : Lines 4-6, current session
104 4-6 : Lines 4-6, current session
47 243/1-5: Lines 1-5, session 243
105 243/1-5: Lines 1-5, session 243
48 ~2/7 : Line 7, session 2 before current
106 ~2/7 : Line 7, session 2 before current
49 ~8/1-~6/5 : From the first line of 8 sessions ago, to the fifth line
107 ~8/1-~6/5 : From the first line of 8 sessions ago, to the fifth line
50 of 6 sessions ago.
108 of 6 sessions ago.
51 Multiple ranges can be entered, separated by spaces
109 Multiple ranges can be entered, separated by spaces
52
110
53 The same syntax is used by %macro, %save, %edit, %rerun
111 The same syntax is used by %macro, %save, %edit, %rerun
54
112
55 Options:
56
57 -n: print line numbers for each input.
58 This feature is only available if numbered prompts are in use.
59
60 -o: also print outputs for each input.
61
62 -p: print classic '>>>' python prompts before each input. This is
63 useful for making documentation, and in conjunction with -o, for
64 producing doctest-ready output.
65
66 -r: (default) print the 'raw' history, i.e. the actual commands you
67 typed.
68
69 -t: print the 'translated' history, as IPython understands it.
70 IPython filters your input and converts it all into valid Python
71 source before executing it (things like magics or aliases are turned
72 into function calls, for example). With this option, you'll see the
73 native history instead of the user-entered version: '%cd /' will be
74 seen as 'get_ipython().magic("%cd /")' instead of '%cd /'.
75
76 -g: treat the arg as a pattern to grep for in (full) history.
77 This includes the saved history (almost all commands ever written).
78 The pattern may contain '?' to match one unknown character and '*'
79 to match any number of unknown characters. Use '%hist -g' to show
80 full saved history (may be very long).
81
82 -l: get the last n lines from all sessions. Specify n as a single
83 arg, or the default is the last 10 lines.
84
85 -f FILENAME: instead of printing the output to the screen, redirect
86 it to the given file. The file is always overwritten, though *when
87 it can*, IPython asks for confirmation first. In particular, running
88 the command 'history -f FILENAME' from the IPython Notebook
89 interface will replace FILENAME even if it already exists *without*
90 confirmation.
91
92 Examples
113 Examples
93 --------
114 --------
94 ::
115 ::
95
116
96 In [6]: %history -n 4-6
117 In [6]: %history -n 4-6
97 4:a = 12
118 4:a = 12
98 5:print a**2
119 5:print a**2
99 6:%history -n 4-6
120 6:%history -n 4-6
100
121
101 """
122 """
102
123
103 if not self.shell.displayhook.do_full_cache:
124 args = parse_argstring(self.history, parameter_s)
104 print('This feature is only available if numbered prompts '
105 'are in use.')
106 return
107 opts,args = self.parse_options(parameter_s,'noprtglf:',mode='string')
108
125
109 # For brevity
126 # For brevity
110 history_manager = self.shell.history_manager
127 history_manager = self.shell.history_manager
111
128
112 def _format_lineno(session, line):
129 def _format_lineno(session, line):
113 """Helper function to format line numbers properly."""
130 """Helper function to format line numbers properly."""
114 if session in (0, history_manager.session_number):
131 if session in (0, history_manager.session_number):
115 return str(line)
132 return str(line)
116 return "%s/%s" % (session, line)
133 return "%s/%s" % (session, line)
117
134
118 # Check if output to specific file was requested.
135 # Check if output to specific file was requested.
119 try:
136 outfname = args.filename
120 outfname = opts['f']
137 if not outfname:
121 except KeyError:
122 outfile = io.stdout # default
138 outfile = io.stdout # default
123 # We don't want to close stdout at the end!
139 # We don't want to close stdout at the end!
124 close_at_end = False
140 close_at_end = False
125 else:
141 else:
126 if os.path.exists(outfname):
142 if os.path.exists(outfname):
127 try:
143 try:
128 ans = io.ask_yes_no("File %r exists. Overwrite?" % outfname)
144 ans = io.ask_yes_no("File %r exists. Overwrite?" % outfname)
129 except StdinNotImplementedError:
145 except StdinNotImplementedError:
130 ans = True
146 ans = True
131 if not ans:
147 if not ans:
132 print('Aborting.')
148 print('Aborting.')
133 return
149 return
134 print("Overwriting file.")
150 print("Overwriting file.")
135 outfile = io_open(outfname, 'w', encoding='utf-8')
151 outfile = io_open(outfname, 'w', encoding='utf-8')
136 close_at_end = True
152 close_at_end = True
137
153
138 print_nums = 'n' in opts
154 print_nums = args.print_nums
139 get_output = 'o' in opts
155 get_output = args.get_output
140 pyprompts = 'p' in opts
156 pyprompts = args.pyprompts
141 # Raw history is the default
157 raw = args.raw
142 raw = not('t' in opts)
143
158
144 pattern = None
159 pattern = None
160 limit = None if args.limit is _unspecified else args.limit
145
161
146 if 'g' in opts: # Glob search
162 if args.pattern is not None:
147 pattern = "*" + args + "*" if args else "*"
163 if args.pattern:
148 hist = history_manager.search(pattern, raw=raw, output=get_output)
164 pattern = "*" + " ".join(args.pattern) + "*"
165 else:
166 pattern = "*"
167 hist = history_manager.search(pattern, raw=raw, output=get_output,
168 n=limit)
149 print_nums = True
169 print_nums = True
150 elif 'l' in opts: # Get 'tail'
170 elif args.limit is not _unspecified:
151 try:
171 n = 10 if limit is None else limit
152 n = int(args)
153 except (ValueError, IndexError):
154 n = 10
155 hist = history_manager.get_tail(n, raw=raw, output=get_output)
172 hist = history_manager.get_tail(n, raw=raw, output=get_output)
156 else:
173 else:
157 if args: # Get history by ranges
174 if args.range: # Get history by ranges
158 hist = history_manager.get_range_by_str(args, raw, get_output)
175 hist = history_manager.get_range_by_str(" ".join(args.range),
176 raw, get_output)
159 else: # Just get history for the current session
177 else: # Just get history for the current session
160 hist = history_manager.get_range(raw=raw, output=get_output)
178 hist = history_manager.get_range(raw=raw, output=get_output)
161
179
162 # We could be displaying the entire history, so let's not try to pull
180 # We could be displaying the entire history, so let's not try to pull
163 # it into a list in memory. Anything that needs more space will just
181 # it into a list in memory. Anything that needs more space will just
164 # misalign.
182 # misalign.
165 width = 4
183 width = 4
166
184
167 for session, lineno, inline in hist:
185 for session, lineno, inline in hist:
168 # Print user history with tabs expanded to 4 spaces. The GUI
186 # Print user history with tabs expanded to 4 spaces. The GUI
169 # clients use hard tabs for easier usability in auto-indented code,
187 # clients use hard tabs for easier usability in auto-indented code,
170 # but we want to produce PEP-8 compliant history for safe pasting
188 # but we want to produce PEP-8 compliant history for safe pasting
171 # into an editor.
189 # into an editor.
172 if get_output:
190 if get_output:
173 inline, output = inline
191 inline, output = inline
174 inline = inline.expandtabs(4).rstrip()
192 inline = inline.expandtabs(4).rstrip()
175
193
176 multiline = "\n" in inline
194 multiline = "\n" in inline
177 line_sep = '\n' if multiline else ' '
195 line_sep = '\n' if multiline else ' '
178 if print_nums:
196 if print_nums:
179 print(u'%s:%s' % (_format_lineno(session, lineno).rjust(width),
197 print(u'%s:%s' % (_format_lineno(session, lineno).rjust(width),
180 line_sep), file=outfile, end=u'')
198 line_sep), file=outfile, end=u'')
181 if pyprompts:
199 if pyprompts:
182 print(u">>> ", end=u"", file=outfile)
200 print(u">>> ", end=u"", file=outfile)
183 if multiline:
201 if multiline:
184 inline = "\n... ".join(inline.splitlines()) + "\n..."
202 inline = "\n... ".join(inline.splitlines()) + "\n..."
185 print(inline, file=outfile)
203 print(inline, file=outfile)
186 if get_output and output:
204 if get_output and output:
187 print(output, file=outfile)
205 print(output, file=outfile)
188
206
189 if close_at_end:
207 if close_at_end:
190 outfile.close()
208 outfile.close()
191
209
192 @line_magic
210 @line_magic
193 def recall(self, arg):
211 def recall(self, arg):
194 r"""Repeat a command, or get command to input line for editing.
212 r"""Repeat a command, or get command to input line for editing.
195
213
196 %recall and %rep are equivalent.
214 %recall and %rep are equivalent.
197
215
198 - %recall (no arguments):
216 - %recall (no arguments):
199
217
200 Place a string version of last computation result (stored in the
218 Place a string version of last computation result (stored in the
201 special '_' variable) to the next input prompt. Allows you to create
219 special '_' variable) to the next input prompt. Allows you to create
202 elaborate command lines without using copy-paste::
220 elaborate command lines without using copy-paste::
203
221
204 In[1]: l = ["hei", "vaan"]
222 In[1]: l = ["hei", "vaan"]
205 In[2]: "".join(l)
223 In[2]: "".join(l)
206 Out[2]: heivaan
224 Out[2]: heivaan
207 In[3]: %recall
225 In[3]: %recall
208 In[4]: heivaan_ <== cursor blinking
226 In[4]: heivaan_ <== cursor blinking
209
227
210 %recall 45
228 %recall 45
211
229
212 Place history line 45 on the next input prompt. Use %hist to find
230 Place history line 45 on the next input prompt. Use %hist to find
213 out the number.
231 out the number.
214
232
215 %recall 1-4
233 %recall 1-4
216
234
217 Combine the specified lines into one cell, and place it on the next
235 Combine the specified lines into one cell, and place it on the next
218 input prompt. See %history for the slice syntax.
236 input prompt. See %history for the slice syntax.
219
237
220 %recall foo+bar
238 %recall foo+bar
221
239
222 If foo+bar can be evaluated in the user namespace, the result is
240 If foo+bar can be evaluated in the user namespace, the result is
223 placed at the next input prompt. Otherwise, the history is searched
241 placed at the next input prompt. Otherwise, the history is searched
224 for lines which contain that substring, and the most recent one is
242 for lines which contain that substring, and the most recent one is
225 placed at the next input prompt.
243 placed at the next input prompt.
226 """
244 """
227 if not arg: # Last output
245 if not arg: # Last output
228 self.shell.set_next_input(str(self.shell.user_ns["_"]))
246 self.shell.set_next_input(str(self.shell.user_ns["_"]))
229 return
247 return
230 # Get history range
248 # Get history range
231 histlines = self.shell.history_manager.get_range_by_str(arg)
249 histlines = self.shell.history_manager.get_range_by_str(arg)
232 cmd = "\n".join(x[2] for x in histlines)
250 cmd = "\n".join(x[2] for x in histlines)
233 if cmd:
251 if cmd:
234 self.shell.set_next_input(cmd.rstrip())
252 self.shell.set_next_input(cmd.rstrip())
235 return
253 return
236
254
237 try: # Variable in user namespace
255 try: # Variable in user namespace
238 cmd = str(eval(arg, self.shell.user_ns))
256 cmd = str(eval(arg, self.shell.user_ns))
239 except Exception: # Search for term in history
257 except Exception: # Search for term in history
240 histlines = self.shell.history_manager.search("*"+arg+"*")
258 histlines = self.shell.history_manager.search("*"+arg+"*")
241 for h in reversed([x[2] for x in histlines]):
259 for h in reversed([x[2] for x in histlines]):
242 if 'recall' in h or 'rep' in h:
260 if 'recall' in h or 'rep' in h:
243 continue
261 continue
244 self.shell.set_next_input(h.rstrip())
262 self.shell.set_next_input(h.rstrip())
245 return
263 return
246 else:
264 else:
247 self.shell.set_next_input(cmd.rstrip())
265 self.shell.set_next_input(cmd.rstrip())
248 print("Couldn't evaluate or find in history:", arg)
266 print("Couldn't evaluate or find in history:", arg)
249
267
250 @line_magic
268 @line_magic
251 def rerun(self, parameter_s=''):
269 def rerun(self, parameter_s=''):
252 """Re-run previous input
270 """Re-run previous input
253
271
254 By default, you can specify ranges of input history to be repeated
272 By default, you can specify ranges of input history to be repeated
255 (as with %history). With no arguments, it will repeat the last line.
273 (as with %history). With no arguments, it will repeat the last line.
256
274
257 Options:
275 Options:
258
276
259 -l <n> : Repeat the last n lines of input, not including the
277 -l <n> : Repeat the last n lines of input, not including the
260 current command.
278 current command.
261
279
262 -g foo : Repeat the most recent line which contains foo
280 -g foo : Repeat the most recent line which contains foo
263 """
281 """
264 opts, args = self.parse_options(parameter_s, 'l:g:', mode='string')
282 opts, args = self.parse_options(parameter_s, 'l:g:', mode='string')
265 if "l" in opts: # Last n lines
283 if "l" in opts: # Last n lines
266 n = int(opts['l'])
284 n = int(opts['l'])
267 hist = self.shell.history_manager.get_tail(n)
285 hist = self.shell.history_manager.get_tail(n)
268 elif "g" in opts: # Search
286 elif "g" in opts: # Search
269 p = "*"+opts['g']+"*"
287 p = "*"+opts['g']+"*"
270 hist = list(self.shell.history_manager.search(p))
288 hist = list(self.shell.history_manager.search(p))
271 for l in reversed(hist):
289 for l in reversed(hist):
272 if "rerun" not in l[2]:
290 if "rerun" not in l[2]:
273 hist = [l] # The last match which isn't a %rerun
291 hist = [l] # The last match which isn't a %rerun
274 break
292 break
275 else:
293 else:
276 hist = [] # No matches except %rerun
294 hist = [] # No matches except %rerun
277 elif args: # Specify history ranges
295 elif args: # Specify history ranges
278 hist = self.shell.history_manager.get_range_by_str(args)
296 hist = self.shell.history_manager.get_range_by_str(args)
279 else: # Last line
297 else: # Last line
280 hist = self.shell.history_manager.get_tail(1)
298 hist = self.shell.history_manager.get_tail(1)
281 hist = [x[2] for x in hist]
299 hist = [x[2] for x in hist]
282 if not hist:
300 if not hist:
283 print("No lines in history match specification")
301 print("No lines in history match specification")
284 return
302 return
285 histlines = "\n".join(hist)
303 histlines = "\n".join(hist)
286 print("=== Executing: ===")
304 print("=== Executing: ===")
287 print(histlines)
305 print(histlines)
288 print("=== Output: ===")
306 print("=== Output: ===")
289 self.shell.run_cell("\n".join(hist), store_history=False)
307 self.shell.run_cell("\n".join(hist), store_history=False)
@@ -1,703 +1,703 b''
1 """Implementation of namespace-related magic functions.
1 """Implementation of namespace-related magic functions.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012 The IPython Development Team.
4 # Copyright (c) 2012 The IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 # Stdlib
15 # Stdlib
16 import gc
16 import gc
17 import re
17 import re
18 import sys
18 import sys
19
19
20 # Our own packages
20 # Our own packages
21 from IPython.core import page
21 from IPython.core import page
22 from IPython.core.error import StdinNotImplementedError, UsageError
22 from IPython.core.error import StdinNotImplementedError, UsageError
23 from IPython.core.magic import Magics, magics_class, line_magic
23 from IPython.core.magic import Magics, magics_class, line_magic
24 from IPython.testing.skipdoctest import skip_doctest
24 from IPython.testing.skipdoctest import skip_doctest
25 from IPython.utils.encoding import DEFAULT_ENCODING
25 from IPython.utils.encoding import DEFAULT_ENCODING
26 from IPython.utils.openpy import read_py_file
26 from IPython.utils.openpy import read_py_file
27 from IPython.utils.path import get_py_filename
27 from IPython.utils.path import get_py_filename
28
28
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 # Magic implementation classes
30 # Magic implementation classes
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32
32
33 @magics_class
33 @magics_class
34 class NamespaceMagics(Magics):
34 class NamespaceMagics(Magics):
35 """Magics to manage various aspects of the user's namespace.
35 """Magics to manage various aspects of the user's namespace.
36
36
37 These include listing variables, introspecting into them, etc.
37 These include listing variables, introspecting into them, etc.
38 """
38 """
39
39
40 @line_magic
40 @line_magic
41 def pinfo(self, parameter_s='', namespaces=None):
41 def pinfo(self, parameter_s='', namespaces=None):
42 """Provide detailed information about an object.
42 """Provide detailed information about an object.
43
43
44 '%pinfo object' is just a synonym for object? or ?object."""
44 '%pinfo object' is just a synonym for object? or ?object."""
45
45
46 #print 'pinfo par: <%s>' % parameter_s # dbg
46 #print 'pinfo par: <%s>' % parameter_s # dbg
47 # detail_level: 0 -> obj? , 1 -> obj??
47 # detail_level: 0 -> obj? , 1 -> obj??
48 detail_level = 0
48 detail_level = 0
49 # We need to detect if we got called as 'pinfo pinfo foo', which can
49 # We need to detect if we got called as 'pinfo pinfo foo', which can
50 # happen if the user types 'pinfo foo?' at the cmd line.
50 # happen if the user types 'pinfo foo?' at the cmd line.
51 pinfo,qmark1,oname,qmark2 = \
51 pinfo,qmark1,oname,qmark2 = \
52 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
52 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
53 if pinfo or qmark1 or qmark2:
53 if pinfo or qmark1 or qmark2:
54 detail_level = 1
54 detail_level = 1
55 if "*" in oname:
55 if "*" in oname:
56 self.psearch(oname)
56 self.psearch(oname)
57 else:
57 else:
58 self.shell._inspect('pinfo', oname, detail_level=detail_level,
58 self.shell._inspect('pinfo', oname, detail_level=detail_level,
59 namespaces=namespaces)
59 namespaces=namespaces)
60
60
61 @line_magic
61 @line_magic
62 def pinfo2(self, parameter_s='', namespaces=None):
62 def pinfo2(self, parameter_s='', namespaces=None):
63 """Provide extra detailed information about an object.
63 """Provide extra detailed information about an object.
64
64
65 '%pinfo2 object' is just a synonym for object?? or ??object."""
65 '%pinfo2 object' is just a synonym for object?? or ??object."""
66 self.shell._inspect('pinfo', parameter_s, detail_level=1,
66 self.shell._inspect('pinfo', parameter_s, detail_level=1,
67 namespaces=namespaces)
67 namespaces=namespaces)
68
68
69 @skip_doctest
69 @skip_doctest
70 @line_magic
70 @line_magic
71 def pdef(self, parameter_s='', namespaces=None):
71 def pdef(self, parameter_s='', namespaces=None):
72 """Print the definition header for any callable object.
72 """Print the call signature for any callable object.
73
73
74 If the object is a class, print the constructor information.
74 If the object is a class, print the constructor information.
75
75
76 Examples
76 Examples
77 --------
77 --------
78 ::
78 ::
79
79
80 In [3]: %pdef urllib.urlopen
80 In [3]: %pdef urllib.urlopen
81 urllib.urlopen(url, data=None, proxies=None)
81 urllib.urlopen(url, data=None, proxies=None)
82 """
82 """
83 self.shell._inspect('pdef',parameter_s, namespaces)
83 self.shell._inspect('pdef',parameter_s, namespaces)
84
84
85 @line_magic
85 @line_magic
86 def pdoc(self, parameter_s='', namespaces=None):
86 def pdoc(self, parameter_s='', namespaces=None):
87 """Print the docstring for an object.
87 """Print the docstring for an object.
88
88
89 If the given object is a class, it will print both the class and the
89 If the given object is a class, it will print both the class and the
90 constructor docstrings."""
90 constructor docstrings."""
91 self.shell._inspect('pdoc',parameter_s, namespaces)
91 self.shell._inspect('pdoc',parameter_s, namespaces)
92
92
93 @line_magic
93 @line_magic
94 def psource(self, parameter_s='', namespaces=None):
94 def psource(self, parameter_s='', namespaces=None):
95 """Print (or run through pager) the source code for an object."""
95 """Print (or run through pager) the source code for an object."""
96 if not parameter_s:
96 if not parameter_s:
97 raise UsageError('Missing object name.')
97 raise UsageError('Missing object name.')
98 self.shell._inspect('psource',parameter_s, namespaces)
98 self.shell._inspect('psource',parameter_s, namespaces)
99
99
100 @line_magic
100 @line_magic
101 def pfile(self, parameter_s=''):
101 def pfile(self, parameter_s='', namespaces=None):
102 """Print (or run through pager) the file where an object is defined.
102 """Print (or run through pager) the file where an object is defined.
103
103
104 The file opens at the line where the object definition begins. IPython
104 The file opens at the line where the object definition begins. IPython
105 will honor the environment variable PAGER if set, and otherwise will
105 will honor the environment variable PAGER if set, and otherwise will
106 do its best to print the file in a convenient form.
106 do its best to print the file in a convenient form.
107
107
108 If the given argument is not an object currently defined, IPython will
108 If the given argument is not an object currently defined, IPython will
109 try to interpret it as a filename (automatically adding a .py extension
109 try to interpret it as a filename (automatically adding a .py extension
110 if needed). You can thus use %pfile as a syntax highlighting code
110 if needed). You can thus use %pfile as a syntax highlighting code
111 viewer."""
111 viewer."""
112
112
113 # first interpret argument as an object name
113 # first interpret argument as an object name
114 out = self.shell._inspect('pfile',parameter_s)
114 out = self.shell._inspect('pfile',parameter_s, namespaces)
115 # if not, try the input as a filename
115 # if not, try the input as a filename
116 if out == 'not found':
116 if out == 'not found':
117 try:
117 try:
118 filename = get_py_filename(parameter_s)
118 filename = get_py_filename(parameter_s)
119 except IOError as msg:
119 except IOError as msg:
120 print msg
120 print msg
121 return
121 return
122 page.page(self.shell.pycolorize(read_py_file(filename, skip_encoding_cookie=False)))
122 page.page(self.shell.pycolorize(read_py_file(filename, skip_encoding_cookie=False)))
123
123
124 @line_magic
124 @line_magic
125 def psearch(self, parameter_s=''):
125 def psearch(self, parameter_s=''):
126 """Search for object in namespaces by wildcard.
126 """Search for object in namespaces by wildcard.
127
127
128 %psearch [options] PATTERN [OBJECT TYPE]
128 %psearch [options] PATTERN [OBJECT TYPE]
129
129
130 Note: ? can be used as a synonym for %psearch, at the beginning or at
130 Note: ? can be used as a synonym for %psearch, at the beginning or at
131 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
131 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
132 rest of the command line must be unchanged (options come first), so
132 rest of the command line must be unchanged (options come first), so
133 for example the following forms are equivalent
133 for example the following forms are equivalent
134
134
135 %psearch -i a* function
135 %psearch -i a* function
136 -i a* function?
136 -i a* function?
137 ?-i a* function
137 ?-i a* function
138
138
139 Arguments:
139 Arguments:
140
140
141 PATTERN
141 PATTERN
142
142
143 where PATTERN is a string containing * as a wildcard similar to its
143 where PATTERN is a string containing * as a wildcard similar to its
144 use in a shell. The pattern is matched in all namespaces on the
144 use in a shell. The pattern is matched in all namespaces on the
145 search path. By default objects starting with a single _ are not
145 search path. By default objects starting with a single _ are not
146 matched, many IPython generated objects have a single
146 matched, many IPython generated objects have a single
147 underscore. The default is case insensitive matching. Matching is
147 underscore. The default is case insensitive matching. Matching is
148 also done on the attributes of objects and not only on the objects
148 also done on the attributes of objects and not only on the objects
149 in a module.
149 in a module.
150
150
151 [OBJECT TYPE]
151 [OBJECT TYPE]
152
152
153 Is the name of a python type from the types module. The name is
153 Is the name of a python type from the types module. The name is
154 given in lowercase without the ending type, ex. StringType is
154 given in lowercase without the ending type, ex. StringType is
155 written string. By adding a type here only objects matching the
155 written string. By adding a type here only objects matching the
156 given type are matched. Using all here makes the pattern match all
156 given type are matched. Using all here makes the pattern match all
157 types (this is the default).
157 types (this is the default).
158
158
159 Options:
159 Options:
160
160
161 -a: makes the pattern match even objects whose names start with a
161 -a: makes the pattern match even objects whose names start with a
162 single underscore. These names are normally omitted from the
162 single underscore. These names are normally omitted from the
163 search.
163 search.
164
164
165 -i/-c: make the pattern case insensitive/sensitive. If neither of
165 -i/-c: make the pattern case insensitive/sensitive. If neither of
166 these options are given, the default is read from your configuration
166 these options are given, the default is read from your configuration
167 file, with the option ``InteractiveShell.wildcards_case_sensitive``.
167 file, with the option ``InteractiveShell.wildcards_case_sensitive``.
168 If this option is not specified in your configuration file, IPython's
168 If this option is not specified in your configuration file, IPython's
169 internal default is to do a case sensitive search.
169 internal default is to do a case sensitive search.
170
170
171 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
171 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
172 specify can be searched in any of the following namespaces:
172 specify can be searched in any of the following namespaces:
173 'builtin', 'user', 'user_global','internal', 'alias', where
173 'builtin', 'user', 'user_global','internal', 'alias', where
174 'builtin' and 'user' are the search defaults. Note that you should
174 'builtin' and 'user' are the search defaults. Note that you should
175 not use quotes when specifying namespaces.
175 not use quotes when specifying namespaces.
176
176
177 'Builtin' contains the python module builtin, 'user' contains all
177 'Builtin' contains the python module builtin, 'user' contains all
178 user data, 'alias' only contain the shell aliases and no python
178 user data, 'alias' only contain the shell aliases and no python
179 objects, 'internal' contains objects used by IPython. The
179 objects, 'internal' contains objects used by IPython. The
180 'user_global' namespace is only used by embedded IPython instances,
180 'user_global' namespace is only used by embedded IPython instances,
181 and it contains module-level globals. You can add namespaces to the
181 and it contains module-level globals. You can add namespaces to the
182 search with -s or exclude them with -e (these options can be given
182 search with -s or exclude them with -e (these options can be given
183 more than once).
183 more than once).
184
184
185 Examples
185 Examples
186 --------
186 --------
187 ::
187 ::
188
188
189 %psearch a* -> objects beginning with an a
189 %psearch a* -> objects beginning with an a
190 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
190 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
191 %psearch a* function -> all functions beginning with an a
191 %psearch a* function -> all functions beginning with an a
192 %psearch re.e* -> objects beginning with an e in module re
192 %psearch re.e* -> objects beginning with an e in module re
193 %psearch r*.e* -> objects that start with e in modules starting in r
193 %psearch r*.e* -> objects that start with e in modules starting in r
194 %psearch r*.* string -> all strings in modules beginning with r
194 %psearch r*.* string -> all strings in modules beginning with r
195
195
196 Case sensitive search::
196 Case sensitive search::
197
197
198 %psearch -c a* list all object beginning with lower case a
198 %psearch -c a* list all object beginning with lower case a
199
199
200 Show objects beginning with a single _::
200 Show objects beginning with a single _::
201
201
202 %psearch -a _* list objects beginning with a single underscore
202 %psearch -a _* list objects beginning with a single underscore
203 """
203 """
204 try:
204 try:
205 parameter_s.encode('ascii')
205 parameter_s.encode('ascii')
206 except UnicodeEncodeError:
206 except UnicodeEncodeError:
207 print 'Python identifiers can only contain ascii characters.'
207 print 'Python identifiers can only contain ascii characters.'
208 return
208 return
209
209
210 # default namespaces to be searched
210 # default namespaces to be searched
211 def_search = ['user_local', 'user_global', 'builtin']
211 def_search = ['user_local', 'user_global', 'builtin']
212
212
213 # Process options/args
213 # Process options/args
214 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
214 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
215 opt = opts.get
215 opt = opts.get
216 shell = self.shell
216 shell = self.shell
217 psearch = shell.inspector.psearch
217 psearch = shell.inspector.psearch
218
218
219 # select case options
219 # select case options
220 if 'i' in opts:
220 if 'i' in opts:
221 ignore_case = True
221 ignore_case = True
222 elif 'c' in opts:
222 elif 'c' in opts:
223 ignore_case = False
223 ignore_case = False
224 else:
224 else:
225 ignore_case = not shell.wildcards_case_sensitive
225 ignore_case = not shell.wildcards_case_sensitive
226
226
227 # Build list of namespaces to search from user options
227 # Build list of namespaces to search from user options
228 def_search.extend(opt('s',[]))
228 def_search.extend(opt('s',[]))
229 ns_exclude = ns_exclude=opt('e',[])
229 ns_exclude = ns_exclude=opt('e',[])
230 ns_search = [nm for nm in def_search if nm not in ns_exclude]
230 ns_search = [nm for nm in def_search if nm not in ns_exclude]
231
231
232 # Call the actual search
232 # Call the actual search
233 try:
233 try:
234 psearch(args,shell.ns_table,ns_search,
234 psearch(args,shell.ns_table,ns_search,
235 show_all=opt('a'),ignore_case=ignore_case)
235 show_all=opt('a'),ignore_case=ignore_case)
236 except:
236 except:
237 shell.showtraceback()
237 shell.showtraceback()
238
238
239 @skip_doctest
239 @skip_doctest
240 @line_magic
240 @line_magic
241 def who_ls(self, parameter_s=''):
241 def who_ls(self, parameter_s=''):
242 """Return a sorted list of all interactive variables.
242 """Return a sorted list of all interactive variables.
243
243
244 If arguments are given, only variables of types matching these
244 If arguments are given, only variables of types matching these
245 arguments are returned.
245 arguments are returned.
246
246
247 Examples
247 Examples
248 --------
248 --------
249
249
250 Define two variables and list them with who_ls::
250 Define two variables and list them with who_ls::
251
251
252 In [1]: alpha = 123
252 In [1]: alpha = 123
253
253
254 In [2]: beta = 'test'
254 In [2]: beta = 'test'
255
255
256 In [3]: %who_ls
256 In [3]: %who_ls
257 Out[3]: ['alpha', 'beta']
257 Out[3]: ['alpha', 'beta']
258
258
259 In [4]: %who_ls int
259 In [4]: %who_ls int
260 Out[4]: ['alpha']
260 Out[4]: ['alpha']
261
261
262 In [5]: %who_ls str
262 In [5]: %who_ls str
263 Out[5]: ['beta']
263 Out[5]: ['beta']
264 """
264 """
265
265
266 user_ns = self.shell.user_ns
266 user_ns = self.shell.user_ns
267 user_ns_hidden = self.shell.user_ns_hidden
267 user_ns_hidden = self.shell.user_ns_hidden
268 out = [ i for i in user_ns
268 out = [ i for i in user_ns
269 if not i.startswith('_') \
269 if not i.startswith('_') \
270 and not i in user_ns_hidden ]
270 and not i in user_ns_hidden ]
271
271
272 typelist = parameter_s.split()
272 typelist = parameter_s.split()
273 if typelist:
273 if typelist:
274 typeset = set(typelist)
274 typeset = set(typelist)
275 out = [i for i in out if type(user_ns[i]).__name__ in typeset]
275 out = [i for i in out if type(user_ns[i]).__name__ in typeset]
276
276
277 out.sort()
277 out.sort()
278 return out
278 return out
279
279
280 @skip_doctest
280 @skip_doctest
281 @line_magic
281 @line_magic
282 def who(self, parameter_s=''):
282 def who(self, parameter_s=''):
283 """Print all interactive variables, with some minimal formatting.
283 """Print all interactive variables, with some minimal formatting.
284
284
285 If any arguments are given, only variables whose type matches one of
285 If any arguments are given, only variables whose type matches one of
286 these are printed. For example::
286 these are printed. For example::
287
287
288 %who function str
288 %who function str
289
289
290 will only list functions and strings, excluding all other types of
290 will only list functions and strings, excluding all other types of
291 variables. To find the proper type names, simply use type(var) at a
291 variables. To find the proper type names, simply use type(var) at a
292 command line to see how python prints type names. For example:
292 command line to see how python prints type names. For example:
293
293
294 ::
294 ::
295
295
296 In [1]: type('hello')\\
296 In [1]: type('hello')\\
297 Out[1]: <type 'str'>
297 Out[1]: <type 'str'>
298
298
299 indicates that the type name for strings is 'str'.
299 indicates that the type name for strings is 'str'.
300
300
301 ``%who`` always excludes executed names loaded through your configuration
301 ``%who`` always excludes executed names loaded through your configuration
302 file and things which are internal to IPython.
302 file and things which are internal to IPython.
303
303
304 This is deliberate, as typically you may load many modules and the
304 This is deliberate, as typically you may load many modules and the
305 purpose of %who is to show you only what you've manually defined.
305 purpose of %who is to show you only what you've manually defined.
306
306
307 Examples
307 Examples
308 --------
308 --------
309
309
310 Define two variables and list them with who::
310 Define two variables and list them with who::
311
311
312 In [1]: alpha = 123
312 In [1]: alpha = 123
313
313
314 In [2]: beta = 'test'
314 In [2]: beta = 'test'
315
315
316 In [3]: %who
316 In [3]: %who
317 alpha beta
317 alpha beta
318
318
319 In [4]: %who int
319 In [4]: %who int
320 alpha
320 alpha
321
321
322 In [5]: %who str
322 In [5]: %who str
323 beta
323 beta
324 """
324 """
325
325
326 varlist = self.who_ls(parameter_s)
326 varlist = self.who_ls(parameter_s)
327 if not varlist:
327 if not varlist:
328 if parameter_s:
328 if parameter_s:
329 print 'No variables match your requested type.'
329 print 'No variables match your requested type.'
330 else:
330 else:
331 print 'Interactive namespace is empty.'
331 print 'Interactive namespace is empty.'
332 return
332 return
333
333
334 # if we have variables, move on...
334 # if we have variables, move on...
335 count = 0
335 count = 0
336 for i in varlist:
336 for i in varlist:
337 print i+'\t',
337 print i+'\t',
338 count += 1
338 count += 1
339 if count > 8:
339 if count > 8:
340 count = 0
340 count = 0
341 print
341 print
342 print
342 print
343
343
344 @skip_doctest
344 @skip_doctest
345 @line_magic
345 @line_magic
346 def whos(self, parameter_s=''):
346 def whos(self, parameter_s=''):
347 """Like %who, but gives some extra information about each variable.
347 """Like %who, but gives some extra information about each variable.
348
348
349 The same type filtering of %who can be applied here.
349 The same type filtering of %who can be applied here.
350
350
351 For all variables, the type is printed. Additionally it prints:
351 For all variables, the type is printed. Additionally it prints:
352
352
353 - For {},[],(): their length.
353 - For {},[],(): their length.
354
354
355 - For numpy arrays, a summary with shape, number of
355 - For numpy arrays, a summary with shape, number of
356 elements, typecode and size in memory.
356 elements, typecode and size in memory.
357
357
358 - Everything else: a string representation, snipping their middle if
358 - Everything else: a string representation, snipping their middle if
359 too long.
359 too long.
360
360
361 Examples
361 Examples
362 --------
362 --------
363
363
364 Define two variables and list them with whos::
364 Define two variables and list them with whos::
365
365
366 In [1]: alpha = 123
366 In [1]: alpha = 123
367
367
368 In [2]: beta = 'test'
368 In [2]: beta = 'test'
369
369
370 In [3]: %whos
370 In [3]: %whos
371 Variable Type Data/Info
371 Variable Type Data/Info
372 --------------------------------
372 --------------------------------
373 alpha int 123
373 alpha int 123
374 beta str test
374 beta str test
375 """
375 """
376
376
377 varnames = self.who_ls(parameter_s)
377 varnames = self.who_ls(parameter_s)
378 if not varnames:
378 if not varnames:
379 if parameter_s:
379 if parameter_s:
380 print 'No variables match your requested type.'
380 print 'No variables match your requested type.'
381 else:
381 else:
382 print 'Interactive namespace is empty.'
382 print 'Interactive namespace is empty.'
383 return
383 return
384
384
385 # if we have variables, move on...
385 # if we have variables, move on...
386
386
387 # for these types, show len() instead of data:
387 # for these types, show len() instead of data:
388 seq_types = ['dict', 'list', 'tuple']
388 seq_types = ['dict', 'list', 'tuple']
389
389
390 # for numpy arrays, display summary info
390 # for numpy arrays, display summary info
391 ndarray_type = None
391 ndarray_type = None
392 if 'numpy' in sys.modules:
392 if 'numpy' in sys.modules:
393 try:
393 try:
394 from numpy import ndarray
394 from numpy import ndarray
395 except ImportError:
395 except ImportError:
396 pass
396 pass
397 else:
397 else:
398 ndarray_type = ndarray.__name__
398 ndarray_type = ndarray.__name__
399
399
400 # Find all variable names and types so we can figure out column sizes
400 # Find all variable names and types so we can figure out column sizes
401 def get_vars(i):
401 def get_vars(i):
402 return self.shell.user_ns[i]
402 return self.shell.user_ns[i]
403
403
404 # some types are well known and can be shorter
404 # some types are well known and can be shorter
405 abbrevs = {'IPython.core.macro.Macro' : 'Macro'}
405 abbrevs = {'IPython.core.macro.Macro' : 'Macro'}
406 def type_name(v):
406 def type_name(v):
407 tn = type(v).__name__
407 tn = type(v).__name__
408 return abbrevs.get(tn,tn)
408 return abbrevs.get(tn,tn)
409
409
410 varlist = map(get_vars,varnames)
410 varlist = map(get_vars,varnames)
411
411
412 typelist = []
412 typelist = []
413 for vv in varlist:
413 for vv in varlist:
414 tt = type_name(vv)
414 tt = type_name(vv)
415
415
416 if tt=='instance':
416 if tt=='instance':
417 typelist.append( abbrevs.get(str(vv.__class__),
417 typelist.append( abbrevs.get(str(vv.__class__),
418 str(vv.__class__)))
418 str(vv.__class__)))
419 else:
419 else:
420 typelist.append(tt)
420 typelist.append(tt)
421
421
422 # column labels and # of spaces as separator
422 # column labels and # of spaces as separator
423 varlabel = 'Variable'
423 varlabel = 'Variable'
424 typelabel = 'Type'
424 typelabel = 'Type'
425 datalabel = 'Data/Info'
425 datalabel = 'Data/Info'
426 colsep = 3
426 colsep = 3
427 # variable format strings
427 # variable format strings
428 vformat = "{0:<{varwidth}}{1:<{typewidth}}"
428 vformat = "{0:<{varwidth}}{1:<{typewidth}}"
429 aformat = "%s: %s elems, type `%s`, %s bytes"
429 aformat = "%s: %s elems, type `%s`, %s bytes"
430 # find the size of the columns to format the output nicely
430 # find the size of the columns to format the output nicely
431 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
431 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
432 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
432 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
433 # table header
433 # table header
434 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
434 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
435 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
435 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
436 # and the table itself
436 # and the table itself
437 kb = 1024
437 kb = 1024
438 Mb = 1048576 # kb**2
438 Mb = 1048576 # kb**2
439 for vname,var,vtype in zip(varnames,varlist,typelist):
439 for vname,var,vtype in zip(varnames,varlist,typelist):
440 print vformat.format(vname, vtype, varwidth=varwidth, typewidth=typewidth),
440 print vformat.format(vname, vtype, varwidth=varwidth, typewidth=typewidth),
441 if vtype in seq_types:
441 if vtype in seq_types:
442 print "n="+str(len(var))
442 print "n="+str(len(var))
443 elif vtype == ndarray_type:
443 elif vtype == ndarray_type:
444 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
444 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
445 if vtype==ndarray_type:
445 if vtype==ndarray_type:
446 # numpy
446 # numpy
447 vsize = var.size
447 vsize = var.size
448 vbytes = vsize*var.itemsize
448 vbytes = vsize*var.itemsize
449 vdtype = var.dtype
449 vdtype = var.dtype
450
450
451 if vbytes < 100000:
451 if vbytes < 100000:
452 print aformat % (vshape, vsize, vdtype, vbytes)
452 print aformat % (vshape, vsize, vdtype, vbytes)
453 else:
453 else:
454 print aformat % (vshape, vsize, vdtype, vbytes),
454 print aformat % (vshape, vsize, vdtype, vbytes),
455 if vbytes < Mb:
455 if vbytes < Mb:
456 print '(%s kb)' % (vbytes/kb,)
456 print '(%s kb)' % (vbytes/kb,)
457 else:
457 else:
458 print '(%s Mb)' % (vbytes/Mb,)
458 print '(%s Mb)' % (vbytes/Mb,)
459 else:
459 else:
460 try:
460 try:
461 vstr = str(var)
461 vstr = str(var)
462 except UnicodeEncodeError:
462 except UnicodeEncodeError:
463 vstr = unicode(var).encode(DEFAULT_ENCODING,
463 vstr = unicode(var).encode(DEFAULT_ENCODING,
464 'backslashreplace')
464 'backslashreplace')
465 except:
465 except:
466 vstr = "<object with id %d (str() failed)>" % id(var)
466 vstr = "<object with id %d (str() failed)>" % id(var)
467 vstr = vstr.replace('\n', '\\n')
467 vstr = vstr.replace('\n', '\\n')
468 if len(vstr) < 50:
468 if len(vstr) < 50:
469 print vstr
469 print vstr
470 else:
470 else:
471 print vstr[:25] + "<...>" + vstr[-25:]
471 print vstr[:25] + "<...>" + vstr[-25:]
472
472
473 @line_magic
473 @line_magic
474 def reset(self, parameter_s=''):
474 def reset(self, parameter_s=''):
475 """Resets the namespace by removing all names defined by the user, if
475 """Resets the namespace by removing all names defined by the user, if
476 called without arguments, or by removing some types of objects, such
476 called without arguments, or by removing some types of objects, such
477 as everything currently in IPython's In[] and Out[] containers (see
477 as everything currently in IPython's In[] and Out[] containers (see
478 the parameters for details).
478 the parameters for details).
479
479
480 Parameters
480 Parameters
481 ----------
481 ----------
482 -f : force reset without asking for confirmation.
482 -f : force reset without asking for confirmation.
483
483
484 -s : 'Soft' reset: Only clears your namespace, leaving history intact.
484 -s : 'Soft' reset: Only clears your namespace, leaving history intact.
485 References to objects may be kept. By default (without this option),
485 References to objects may be kept. By default (without this option),
486 we do a 'hard' reset, giving you a new session and removing all
486 we do a 'hard' reset, giving you a new session and removing all
487 references to objects from the current session.
487 references to objects from the current session.
488
488
489 in : reset input history
489 in : reset input history
490
490
491 out : reset output history
491 out : reset output history
492
492
493 dhist : reset directory history
493 dhist : reset directory history
494
494
495 array : reset only variables that are NumPy arrays
495 array : reset only variables that are NumPy arrays
496
496
497 See Also
497 See Also
498 --------
498 --------
499 magic_reset_selective : invoked as ``%reset_selective``
499 magic_reset_selective : invoked as ``%reset_selective``
500
500
501 Examples
501 Examples
502 --------
502 --------
503 ::
503 ::
504
504
505 In [6]: a = 1
505 In [6]: a = 1
506
506
507 In [7]: a
507 In [7]: a
508 Out[7]: 1
508 Out[7]: 1
509
509
510 In [8]: 'a' in _ip.user_ns
510 In [8]: 'a' in _ip.user_ns
511 Out[8]: True
511 Out[8]: True
512
512
513 In [9]: %reset -f
513 In [9]: %reset -f
514
514
515 In [1]: 'a' in _ip.user_ns
515 In [1]: 'a' in _ip.user_ns
516 Out[1]: False
516 Out[1]: False
517
517
518 In [2]: %reset -f in
518 In [2]: %reset -f in
519 Flushing input history
519 Flushing input history
520
520
521 In [3]: %reset -f dhist in
521 In [3]: %reset -f dhist in
522 Flushing directory history
522 Flushing directory history
523 Flushing input history
523 Flushing input history
524
524
525 Notes
525 Notes
526 -----
526 -----
527 Calling this magic from clients that do not implement standard input,
527 Calling this magic from clients that do not implement standard input,
528 such as the ipython notebook interface, will reset the namespace
528 such as the ipython notebook interface, will reset the namespace
529 without confirmation.
529 without confirmation.
530 """
530 """
531 opts, args = self.parse_options(parameter_s,'sf', mode='list')
531 opts, args = self.parse_options(parameter_s,'sf', mode='list')
532 if 'f' in opts:
532 if 'f' in opts:
533 ans = True
533 ans = True
534 else:
534 else:
535 try:
535 try:
536 ans = self.shell.ask_yes_no(
536 ans = self.shell.ask_yes_no(
537 "Once deleted, variables cannot be recovered. Proceed (y/[n])?",
537 "Once deleted, variables cannot be recovered. Proceed (y/[n])?",
538 default='n')
538 default='n')
539 except StdinNotImplementedError:
539 except StdinNotImplementedError:
540 ans = True
540 ans = True
541 if not ans:
541 if not ans:
542 print 'Nothing done.'
542 print 'Nothing done.'
543 return
543 return
544
544
545 if 's' in opts: # Soft reset
545 if 's' in opts: # Soft reset
546 user_ns = self.shell.user_ns
546 user_ns = self.shell.user_ns
547 for i in self.who_ls():
547 for i in self.who_ls():
548 del(user_ns[i])
548 del(user_ns[i])
549 elif len(args) == 0: # Hard reset
549 elif len(args) == 0: # Hard reset
550 self.shell.reset(new_session = False)
550 self.shell.reset(new_session = False)
551
551
552 # reset in/out/dhist/array: previously extensinions/clearcmd.py
552 # reset in/out/dhist/array: previously extensinions/clearcmd.py
553 ip = self.shell
553 ip = self.shell
554 user_ns = self.shell.user_ns # local lookup, heavily used
554 user_ns = self.shell.user_ns # local lookup, heavily used
555
555
556 for target in args:
556 for target in args:
557 target = target.lower() # make matches case insensitive
557 target = target.lower() # make matches case insensitive
558 if target == 'out':
558 if target == 'out':
559 print "Flushing output cache (%d entries)" % len(user_ns['_oh'])
559 print "Flushing output cache (%d entries)" % len(user_ns['_oh'])
560 self.shell.displayhook.flush()
560 self.shell.displayhook.flush()
561
561
562 elif target == 'in':
562 elif target == 'in':
563 print "Flushing input history"
563 print "Flushing input history"
564 pc = self.shell.displayhook.prompt_count + 1
564 pc = self.shell.displayhook.prompt_count + 1
565 for n in range(1, pc):
565 for n in range(1, pc):
566 key = '_i'+repr(n)
566 key = '_i'+repr(n)
567 user_ns.pop(key,None)
567 user_ns.pop(key,None)
568 user_ns.update(dict(_i=u'',_ii=u'',_iii=u''))
568 user_ns.update(dict(_i=u'',_ii=u'',_iii=u''))
569 hm = ip.history_manager
569 hm = ip.history_manager
570 # don't delete these, as %save and %macro depending on the
570 # don't delete these, as %save and %macro depending on the
571 # length of these lists to be preserved
571 # length of these lists to be preserved
572 hm.input_hist_parsed[:] = [''] * pc
572 hm.input_hist_parsed[:] = [''] * pc
573 hm.input_hist_raw[:] = [''] * pc
573 hm.input_hist_raw[:] = [''] * pc
574 # hm has internal machinery for _i,_ii,_iii, clear it out
574 # hm has internal machinery for _i,_ii,_iii, clear it out
575 hm._i = hm._ii = hm._iii = hm._i00 = u''
575 hm._i = hm._ii = hm._iii = hm._i00 = u''
576
576
577 elif target == 'array':
577 elif target == 'array':
578 # Support cleaning up numpy arrays
578 # Support cleaning up numpy arrays
579 try:
579 try:
580 from numpy import ndarray
580 from numpy import ndarray
581 # This must be done with items and not iteritems because
581 # This must be done with items and not iteritems because
582 # we're going to modify the dict in-place.
582 # we're going to modify the dict in-place.
583 for x,val in user_ns.items():
583 for x,val in user_ns.items():
584 if isinstance(val,ndarray):
584 if isinstance(val,ndarray):
585 del user_ns[x]
585 del user_ns[x]
586 except ImportError:
586 except ImportError:
587 print "reset array only works if Numpy is available."
587 print "reset array only works if Numpy is available."
588
588
589 elif target == 'dhist':
589 elif target == 'dhist':
590 print "Flushing directory history"
590 print "Flushing directory history"
591 del user_ns['_dh'][:]
591 del user_ns['_dh'][:]
592
592
593 else:
593 else:
594 print "Don't know how to reset ",
594 print "Don't know how to reset ",
595 print target + ", please run `%reset?` for details"
595 print target + ", please run `%reset?` for details"
596
596
597 gc.collect()
597 gc.collect()
598
598
599 @line_magic
599 @line_magic
600 def reset_selective(self, parameter_s=''):
600 def reset_selective(self, parameter_s=''):
601 """Resets the namespace by removing names defined by the user.
601 """Resets the namespace by removing names defined by the user.
602
602
603 Input/Output history are left around in case you need them.
603 Input/Output history are left around in case you need them.
604
604
605 %reset_selective [-f] regex
605 %reset_selective [-f] regex
606
606
607 No action is taken if regex is not included
607 No action is taken if regex is not included
608
608
609 Options
609 Options
610 -f : force reset without asking for confirmation.
610 -f : force reset without asking for confirmation.
611
611
612 See Also
612 See Also
613 --------
613 --------
614 magic_reset : invoked as ``%reset``
614 magic_reset : invoked as ``%reset``
615
615
616 Examples
616 Examples
617 --------
617 --------
618
618
619 We first fully reset the namespace so your output looks identical to
619 We first fully reset the namespace so your output looks identical to
620 this example for pedagogical reasons; in practice you do not need a
620 this example for pedagogical reasons; in practice you do not need a
621 full reset::
621 full reset::
622
622
623 In [1]: %reset -f
623 In [1]: %reset -f
624
624
625 Now, with a clean namespace we can make a few variables and use
625 Now, with a clean namespace we can make a few variables and use
626 ``%reset_selective`` to only delete names that match our regexp::
626 ``%reset_selective`` to only delete names that match our regexp::
627
627
628 In [2]: a=1; b=2; c=3; b1m=4; b2m=5; b3m=6; b4m=7; b2s=8
628 In [2]: a=1; b=2; c=3; b1m=4; b2m=5; b3m=6; b4m=7; b2s=8
629
629
630 In [3]: who_ls
630 In [3]: who_ls
631 Out[3]: ['a', 'b', 'b1m', 'b2m', 'b2s', 'b3m', 'b4m', 'c']
631 Out[3]: ['a', 'b', 'b1m', 'b2m', 'b2s', 'b3m', 'b4m', 'c']
632
632
633 In [4]: %reset_selective -f b[2-3]m
633 In [4]: %reset_selective -f b[2-3]m
634
634
635 In [5]: who_ls
635 In [5]: who_ls
636 Out[5]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
636 Out[5]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
637
637
638 In [6]: %reset_selective -f d
638 In [6]: %reset_selective -f d
639
639
640 In [7]: who_ls
640 In [7]: who_ls
641 Out[7]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
641 Out[7]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
642
642
643 In [8]: %reset_selective -f c
643 In [8]: %reset_selective -f c
644
644
645 In [9]: who_ls
645 In [9]: who_ls
646 Out[9]: ['a', 'b', 'b1m', 'b2s', 'b4m']
646 Out[9]: ['a', 'b', 'b1m', 'b2s', 'b4m']
647
647
648 In [10]: %reset_selective -f b
648 In [10]: %reset_selective -f b
649
649
650 In [11]: who_ls
650 In [11]: who_ls
651 Out[11]: ['a']
651 Out[11]: ['a']
652
652
653 Notes
653 Notes
654 -----
654 -----
655 Calling this magic from clients that do not implement standard input,
655 Calling this magic from clients that do not implement standard input,
656 such as the ipython notebook interface, will reset the namespace
656 such as the ipython notebook interface, will reset the namespace
657 without confirmation.
657 without confirmation.
658 """
658 """
659
659
660 opts, regex = self.parse_options(parameter_s,'f')
660 opts, regex = self.parse_options(parameter_s,'f')
661
661
662 if 'f' in opts:
662 if 'f' in opts:
663 ans = True
663 ans = True
664 else:
664 else:
665 try:
665 try:
666 ans = self.shell.ask_yes_no(
666 ans = self.shell.ask_yes_no(
667 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ",
667 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ",
668 default='n')
668 default='n')
669 except StdinNotImplementedError:
669 except StdinNotImplementedError:
670 ans = True
670 ans = True
671 if not ans:
671 if not ans:
672 print 'Nothing done.'
672 print 'Nothing done.'
673 return
673 return
674 user_ns = self.shell.user_ns
674 user_ns = self.shell.user_ns
675 if not regex:
675 if not regex:
676 print 'No regex pattern specified. Nothing done.'
676 print 'No regex pattern specified. Nothing done.'
677 return
677 return
678 else:
678 else:
679 try:
679 try:
680 m = re.compile(regex)
680 m = re.compile(regex)
681 except TypeError:
681 except TypeError:
682 raise TypeError('regex must be a string or compiled pattern')
682 raise TypeError('regex must be a string or compiled pattern')
683 for i in self.who_ls():
683 for i in self.who_ls():
684 if m.search(i):
684 if m.search(i):
685 del(user_ns[i])
685 del(user_ns[i])
686
686
687 @line_magic
687 @line_magic
688 def xdel(self, parameter_s=''):
688 def xdel(self, parameter_s=''):
689 """Delete a variable, trying to clear it from anywhere that
689 """Delete a variable, trying to clear it from anywhere that
690 IPython's machinery has references to it. By default, this uses
690 IPython's machinery has references to it. By default, this uses
691 the identity of the named object in the user namespace to remove
691 the identity of the named object in the user namespace to remove
692 references held under other names. The object is also removed
692 references held under other names. The object is also removed
693 from the output history.
693 from the output history.
694
694
695 Options
695 Options
696 -n : Delete the specified name from all namespaces, without
696 -n : Delete the specified name from all namespaces, without
697 checking their identity.
697 checking their identity.
698 """
698 """
699 opts, varname = self.parse_options(parameter_s,'n')
699 opts, varname = self.parse_options(parameter_s,'n')
700 try:
700 try:
701 self.shell.del_var(varname, ('n' in opts))
701 self.shell.del_var(varname, ('n' in opts))
702 except (NameError, ValueError) as e:
702 except (NameError, ValueError) as e:
703 print type(e).__name__ +": "+ str(e)
703 print type(e).__name__ +": "+ str(e)
@@ -1,873 +1,873 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tools for inspecting Python objects.
2 """Tools for inspecting Python objects.
3
3
4 Uses syntax highlighting for presenting the various information elements.
4 Uses syntax highlighting for presenting the various information elements.
5
5
6 Similar in spirit to the inspect module, but all calls take a name argument to
6 Similar in spirit to the inspect module, but all calls take a name argument to
7 reference the name under which an object is being read.
7 reference the name under which an object is being read.
8 """
8 """
9
9
10 #*****************************************************************************
10 #*****************************************************************************
11 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
11 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
12 #
12 #
13 # Distributed under the terms of the BSD License. The full license is in
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
14 # the file COPYING, distributed as part of this software.
15 #*****************************************************************************
15 #*****************************************************************************
16 from __future__ import print_function
16 from __future__ import print_function
17
17
18 __all__ = ['Inspector','InspectColors']
18 __all__ = ['Inspector','InspectColors']
19
19
20 # stdlib modules
20 # stdlib modules
21 import __builtin__
21 import __builtin__
22 import inspect
22 import inspect
23 import linecache
23 import linecache
24 import os
24 import os
25 import sys
25 import sys
26 import types
26 import types
27 import io as stdlib_io
27 import io as stdlib_io
28
28
29 from collections import namedtuple
29 from collections import namedtuple
30 try:
30 try:
31 from itertools import izip_longest
31 from itertools import izip_longest
32 except ImportError:
32 except ImportError:
33 from itertools import zip_longest as izip_longest
33 from itertools import zip_longest as izip_longest
34
34
35 # IPython's own
35 # IPython's own
36 from IPython.core import page
36 from IPython.core import page
37 from IPython.testing.skipdoctest import skip_doctest_py3
37 from IPython.testing.skipdoctest import skip_doctest_py3
38 from IPython.utils import PyColorize
38 from IPython.utils import PyColorize
39 from IPython.utils import io
39 from IPython.utils import io
40 from IPython.utils import openpy
40 from IPython.utils import openpy
41 from IPython.utils import py3compat
41 from IPython.utils import py3compat
42 from IPython.utils.text import indent
42 from IPython.utils.text import indent
43 from IPython.utils.wildcard import list_namespace
43 from IPython.utils.wildcard import list_namespace
44 from IPython.utils.coloransi import *
44 from IPython.utils.coloransi import *
45 from IPython.utils.py3compat import cast_unicode
45 from IPython.utils.py3compat import cast_unicode
46
46
47 #****************************************************************************
47 #****************************************************************************
48 # Builtin color schemes
48 # Builtin color schemes
49
49
50 Colors = TermColors # just a shorthand
50 Colors = TermColors # just a shorthand
51
51
52 # Build a few color schemes
52 # Build a few color schemes
53 NoColor = ColorScheme(
53 NoColor = ColorScheme(
54 'NoColor',{
54 'NoColor',{
55 'header' : Colors.NoColor,
55 'header' : Colors.NoColor,
56 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
56 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
57 } )
57 } )
58
58
59 LinuxColors = ColorScheme(
59 LinuxColors = ColorScheme(
60 'Linux',{
60 'Linux',{
61 'header' : Colors.LightRed,
61 'header' : Colors.LightRed,
62 'normal' : Colors.Normal # color off (usu. Colors.Normal)
62 'normal' : Colors.Normal # color off (usu. Colors.Normal)
63 } )
63 } )
64
64
65 LightBGColors = ColorScheme(
65 LightBGColors = ColorScheme(
66 'LightBG',{
66 'LightBG',{
67 'header' : Colors.Red,
67 'header' : Colors.Red,
68 'normal' : Colors.Normal # color off (usu. Colors.Normal)
68 'normal' : Colors.Normal # color off (usu. Colors.Normal)
69 } )
69 } )
70
70
71 # Build table of color schemes (needed by the parser)
71 # Build table of color schemes (needed by the parser)
72 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
72 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
73 'Linux')
73 'Linux')
74
74
75 #****************************************************************************
75 #****************************************************************************
76 # Auxiliary functions and objects
76 # Auxiliary functions and objects
77
77
78 # See the messaging spec for the definition of all these fields. This list
78 # See the messaging spec for the definition of all these fields. This list
79 # effectively defines the order of display
79 # effectively defines the order of display
80 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
80 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
81 'length', 'file', 'definition', 'docstring', 'source',
81 'length', 'file', 'definition', 'docstring', 'source',
82 'init_definition', 'class_docstring', 'init_docstring',
82 'init_definition', 'class_docstring', 'init_docstring',
83 'call_def', 'call_docstring',
83 'call_def', 'call_docstring',
84 # These won't be printed but will be used to determine how to
84 # These won't be printed but will be used to determine how to
85 # format the object
85 # format the object
86 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
86 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
87 ]
87 ]
88
88
89
89
90 def object_info(**kw):
90 def object_info(**kw):
91 """Make an object info dict with all fields present."""
91 """Make an object info dict with all fields present."""
92 infodict = dict(izip_longest(info_fields, [None]))
92 infodict = dict(izip_longest(info_fields, [None]))
93 infodict.update(kw)
93 infodict.update(kw)
94 return infodict
94 return infodict
95
95
96
96
97 def get_encoding(obj):
97 def get_encoding(obj):
98 """Get encoding for python source file defining obj
98 """Get encoding for python source file defining obj
99
99
100 Returns None if obj is not defined in a sourcefile.
100 Returns None if obj is not defined in a sourcefile.
101 """
101 """
102 ofile = find_file(obj)
102 ofile = find_file(obj)
103 # run contents of file through pager starting at line where the object
103 # run contents of file through pager starting at line where the object
104 # is defined, as long as the file isn't binary and is actually on the
104 # is defined, as long as the file isn't binary and is actually on the
105 # filesystem.
105 # filesystem.
106 if ofile is None:
106 if ofile is None:
107 return None
107 return None
108 elif ofile.endswith(('.so', '.dll', '.pyd')):
108 elif ofile.endswith(('.so', '.dll', '.pyd')):
109 return None
109 return None
110 elif not os.path.isfile(ofile):
110 elif not os.path.isfile(ofile):
111 return None
111 return None
112 else:
112 else:
113 # Print only text files, not extension binaries. Note that
113 # Print only text files, not extension binaries. Note that
114 # getsourcelines returns lineno with 1-offset and page() uses
114 # getsourcelines returns lineno with 1-offset and page() uses
115 # 0-offset, so we must adjust.
115 # 0-offset, so we must adjust.
116 buffer = stdlib_io.open(ofile, 'rb') # Tweaked to use io.open for Python 2
116 buffer = stdlib_io.open(ofile, 'rb') # Tweaked to use io.open for Python 2
117 encoding, lines = openpy.detect_encoding(buffer.readline)
117 encoding, lines = openpy.detect_encoding(buffer.readline)
118 return encoding
118 return encoding
119
119
120 def getdoc(obj):
120 def getdoc(obj):
121 """Stable wrapper around inspect.getdoc.
121 """Stable wrapper around inspect.getdoc.
122
122
123 This can't crash because of attribute problems.
123 This can't crash because of attribute problems.
124
124
125 It also attempts to call a getdoc() method on the given object. This
125 It also attempts to call a getdoc() method on the given object. This
126 allows objects which provide their docstrings via non-standard mechanisms
126 allows objects which provide their docstrings via non-standard mechanisms
127 (like Pyro proxies) to still be inspected by ipython's ? system."""
127 (like Pyro proxies) to still be inspected by ipython's ? system."""
128 # Allow objects to offer customized documentation via a getdoc method:
128 # Allow objects to offer customized documentation via a getdoc method:
129 try:
129 try:
130 ds = obj.getdoc()
130 ds = obj.getdoc()
131 except Exception:
131 except Exception:
132 pass
132 pass
133 else:
133 else:
134 # if we get extra info, we add it to the normal docstring.
134 # if we get extra info, we add it to the normal docstring.
135 if isinstance(ds, basestring):
135 if isinstance(ds, basestring):
136 return inspect.cleandoc(ds)
136 return inspect.cleandoc(ds)
137
137
138 try:
138 try:
139 docstr = inspect.getdoc(obj)
139 docstr = inspect.getdoc(obj)
140 encoding = get_encoding(obj)
140 encoding = get_encoding(obj)
141 return py3compat.cast_unicode(docstr, encoding=encoding)
141 return py3compat.cast_unicode(docstr, encoding=encoding)
142 except Exception:
142 except Exception:
143 # Harden against an inspect failure, which can occur with
143 # Harden against an inspect failure, which can occur with
144 # SWIG-wrapped extensions.
144 # SWIG-wrapped extensions.
145 raise
145 raise
146 return None
146 return None
147
147
148
148
149 def getsource(obj,is_binary=False):
149 def getsource(obj,is_binary=False):
150 """Wrapper around inspect.getsource.
150 """Wrapper around inspect.getsource.
151
151
152 This can be modified by other projects to provide customized source
152 This can be modified by other projects to provide customized source
153 extraction.
153 extraction.
154
154
155 Inputs:
155 Inputs:
156
156
157 - obj: an object whose source code we will attempt to extract.
157 - obj: an object whose source code we will attempt to extract.
158
158
159 Optional inputs:
159 Optional inputs:
160
160
161 - is_binary: whether the object is known to come from a binary source.
161 - is_binary: whether the object is known to come from a binary source.
162 This implementation will skip returning any output for binary objects, but
162 This implementation will skip returning any output for binary objects, but
163 custom extractors may know how to meaningfully process them."""
163 custom extractors may know how to meaningfully process them."""
164
164
165 if is_binary:
165 if is_binary:
166 return None
166 return None
167 else:
167 else:
168 # get source if obj was decorated with @decorator
168 # get source if obj was decorated with @decorator
169 if hasattr(obj,"__wrapped__"):
169 if hasattr(obj,"__wrapped__"):
170 obj = obj.__wrapped__
170 obj = obj.__wrapped__
171 try:
171 try:
172 src = inspect.getsource(obj)
172 src = inspect.getsource(obj)
173 except TypeError:
173 except TypeError:
174 if hasattr(obj,'__class__'):
174 if hasattr(obj,'__class__'):
175 src = inspect.getsource(obj.__class__)
175 src = inspect.getsource(obj.__class__)
176 encoding = get_encoding(obj)
176 encoding = get_encoding(obj)
177 return cast_unicode(src, encoding=encoding)
177 return cast_unicode(src, encoding=encoding)
178
178
179 def getargspec(obj):
179 def getargspec(obj):
180 """Get the names and default values of a function's arguments.
180 """Get the names and default values of a function's arguments.
181
181
182 A tuple of four things is returned: (args, varargs, varkw, defaults).
182 A tuple of four things is returned: (args, varargs, varkw, defaults).
183 'args' is a list of the argument names (it may contain nested lists).
183 'args' is a list of the argument names (it may contain nested lists).
184 'varargs' and 'varkw' are the names of the * and ** arguments or None.
184 'varargs' and 'varkw' are the names of the * and ** arguments or None.
185 'defaults' is an n-tuple of the default values of the last n arguments.
185 'defaults' is an n-tuple of the default values of the last n arguments.
186
186
187 Modified version of inspect.getargspec from the Python Standard
187 Modified version of inspect.getargspec from the Python Standard
188 Library."""
188 Library."""
189
189
190 if inspect.isfunction(obj):
190 if inspect.isfunction(obj):
191 func_obj = obj
191 func_obj = obj
192 elif inspect.ismethod(obj):
192 elif inspect.ismethod(obj):
193 func_obj = obj.im_func
193 func_obj = obj.im_func
194 elif hasattr(obj, '__call__'):
194 elif hasattr(obj, '__call__'):
195 func_obj = obj.__call__
195 func_obj = obj.__call__
196 else:
196 else:
197 raise TypeError('arg is not a Python function')
197 raise TypeError('arg is not a Python function')
198 args, varargs, varkw = inspect.getargs(func_obj.func_code)
198 args, varargs, varkw = inspect.getargs(func_obj.func_code)
199 return args, varargs, varkw, func_obj.func_defaults
199 return args, varargs, varkw, func_obj.func_defaults
200
200
201
201
202 def format_argspec(argspec):
202 def format_argspec(argspec):
203 """Format argspect, convenience wrapper around inspect's.
203 """Format argspect, convenience wrapper around inspect's.
204
204
205 This takes a dict instead of ordered arguments and calls
205 This takes a dict instead of ordered arguments and calls
206 inspect.format_argspec with the arguments in the necessary order.
206 inspect.format_argspec with the arguments in the necessary order.
207 """
207 """
208 return inspect.formatargspec(argspec['args'], argspec['varargs'],
208 return inspect.formatargspec(argspec['args'], argspec['varargs'],
209 argspec['varkw'], argspec['defaults'])
209 argspec['varkw'], argspec['defaults'])
210
210
211
211
212 def call_tip(oinfo, format_call=True):
212 def call_tip(oinfo, format_call=True):
213 """Extract call tip data from an oinfo dict.
213 """Extract call tip data from an oinfo dict.
214
214
215 Parameters
215 Parameters
216 ----------
216 ----------
217 oinfo : dict
217 oinfo : dict
218
218
219 format_call : bool, optional
219 format_call : bool, optional
220 If True, the call line is formatted and returned as a string. If not, a
220 If True, the call line is formatted and returned as a string. If not, a
221 tuple of (name, argspec) is returned.
221 tuple of (name, argspec) is returned.
222
222
223 Returns
223 Returns
224 -------
224 -------
225 call_info : None, str or (str, dict) tuple.
225 call_info : None, str or (str, dict) tuple.
226 When format_call is True, the whole call information is formattted as a
226 When format_call is True, the whole call information is formattted as a
227 single string. Otherwise, the object's name and its argspec dict are
227 single string. Otherwise, the object's name and its argspec dict are
228 returned. If no call information is available, None is returned.
228 returned. If no call information is available, None is returned.
229
229
230 docstring : str or None
230 docstring : str or None
231 The most relevant docstring for calling purposes is returned, if
231 The most relevant docstring for calling purposes is returned, if
232 available. The priority is: call docstring for callable instances, then
232 available. The priority is: call docstring for callable instances, then
233 constructor docstring for classes, then main object's docstring otherwise
233 constructor docstring for classes, then main object's docstring otherwise
234 (regular functions).
234 (regular functions).
235 """
235 """
236 # Get call definition
236 # Get call definition
237 argspec = oinfo.get('argspec')
237 argspec = oinfo.get('argspec')
238 if argspec is None:
238 if argspec is None:
239 call_line = None
239 call_line = None
240 else:
240 else:
241 # Callable objects will have 'self' as their first argument, prune
241 # Callable objects will have 'self' as their first argument, prune
242 # it out if it's there for clarity (since users do *not* pass an
242 # it out if it's there for clarity (since users do *not* pass an
243 # extra first argument explicitly).
243 # extra first argument explicitly).
244 try:
244 try:
245 has_self = argspec['args'][0] == 'self'
245 has_self = argspec['args'][0] == 'self'
246 except (KeyError, IndexError):
246 except (KeyError, IndexError):
247 pass
247 pass
248 else:
248 else:
249 if has_self:
249 if has_self:
250 argspec['args'] = argspec['args'][1:]
250 argspec['args'] = argspec['args'][1:]
251
251
252 call_line = oinfo['name']+format_argspec(argspec)
252 call_line = oinfo['name']+format_argspec(argspec)
253
253
254 # Now get docstring.
254 # Now get docstring.
255 # The priority is: call docstring, constructor docstring, main one.
255 # The priority is: call docstring, constructor docstring, main one.
256 doc = oinfo.get('call_docstring')
256 doc = oinfo.get('call_docstring')
257 if doc is None:
257 if doc is None:
258 doc = oinfo.get('init_docstring')
258 doc = oinfo.get('init_docstring')
259 if doc is None:
259 if doc is None:
260 doc = oinfo.get('docstring','')
260 doc = oinfo.get('docstring','')
261
261
262 return call_line, doc
262 return call_line, doc
263
263
264
264
265 def find_file(obj):
265 def find_file(obj):
266 """Find the absolute path to the file where an object was defined.
266 """Find the absolute path to the file where an object was defined.
267
267
268 This is essentially a robust wrapper around `inspect.getabsfile`.
268 This is essentially a robust wrapper around `inspect.getabsfile`.
269
269
270 Returns None if no file can be found.
270 Returns None if no file can be found.
271
271
272 Parameters
272 Parameters
273 ----------
273 ----------
274 obj : any Python object
274 obj : any Python object
275
275
276 Returns
276 Returns
277 -------
277 -------
278 fname : str
278 fname : str
279 The absolute path to the file where the object was defined.
279 The absolute path to the file where the object was defined.
280 """
280 """
281 # get source if obj was decorated with @decorator
281 # get source if obj was decorated with @decorator
282 if hasattr(obj, '__wrapped__'):
282 if hasattr(obj, '__wrapped__'):
283 obj = obj.__wrapped__
283 obj = obj.__wrapped__
284
284
285 fname = None
285 fname = None
286 try:
286 try:
287 fname = inspect.getabsfile(obj)
287 fname = inspect.getabsfile(obj)
288 except TypeError:
288 except TypeError:
289 # For an instance, the file that matters is where its class was
289 # For an instance, the file that matters is where its class was
290 # declared.
290 # declared.
291 if hasattr(obj, '__class__'):
291 if hasattr(obj, '__class__'):
292 try:
292 try:
293 fname = inspect.getabsfile(obj.__class__)
293 fname = inspect.getabsfile(obj.__class__)
294 except TypeError:
294 except TypeError:
295 # Can happen for builtins
295 # Can happen for builtins
296 pass
296 pass
297 except:
297 except:
298 pass
298 pass
299 return fname
299 return fname
300
300
301
301
302 def find_source_lines(obj):
302 def find_source_lines(obj):
303 """Find the line number in a file where an object was defined.
303 """Find the line number in a file where an object was defined.
304
304
305 This is essentially a robust wrapper around `inspect.getsourcelines`.
305 This is essentially a robust wrapper around `inspect.getsourcelines`.
306
306
307 Returns None if no file can be found.
307 Returns None if no file can be found.
308
308
309 Parameters
309 Parameters
310 ----------
310 ----------
311 obj : any Python object
311 obj : any Python object
312
312
313 Returns
313 Returns
314 -------
314 -------
315 lineno : int
315 lineno : int
316 The line number where the object definition starts.
316 The line number where the object definition starts.
317 """
317 """
318 # get source if obj was decorated with @decorator
318 # get source if obj was decorated with @decorator
319 if hasattr(obj, '__wrapped__'):
319 if hasattr(obj, '__wrapped__'):
320 obj = obj.__wrapped__
320 obj = obj.__wrapped__
321
321
322 try:
322 try:
323 try:
323 try:
324 lineno = inspect.getsourcelines(obj)[1]
324 lineno = inspect.getsourcelines(obj)[1]
325 except TypeError:
325 except TypeError:
326 # For instances, try the class object like getsource() does
326 # For instances, try the class object like getsource() does
327 if hasattr(obj, '__class__'):
327 if hasattr(obj, '__class__'):
328 lineno = inspect.getsourcelines(obj.__class__)[1]
328 lineno = inspect.getsourcelines(obj.__class__)[1]
329 except:
329 except:
330 return None
330 return None
331
331
332 return lineno
332 return lineno
333
333
334
334
335 class Inspector:
335 class Inspector:
336 def __init__(self, color_table=InspectColors,
336 def __init__(self, color_table=InspectColors,
337 code_color_table=PyColorize.ANSICodeColors,
337 code_color_table=PyColorize.ANSICodeColors,
338 scheme='NoColor',
338 scheme='NoColor',
339 str_detail_level=0):
339 str_detail_level=0):
340 self.color_table = color_table
340 self.color_table = color_table
341 self.parser = PyColorize.Parser(code_color_table,out='str')
341 self.parser = PyColorize.Parser(code_color_table,out='str')
342 self.format = self.parser.format
342 self.format = self.parser.format
343 self.str_detail_level = str_detail_level
343 self.str_detail_level = str_detail_level
344 self.set_active_scheme(scheme)
344 self.set_active_scheme(scheme)
345
345
346 def _getdef(self,obj,oname=''):
346 def _getdef(self,obj,oname=''):
347 """Return the definition header for any callable object.
347 """Return the call signature for any callable object.
348
348
349 If any exception is generated, None is returned instead and the
349 If any exception is generated, None is returned instead and the
350 exception is suppressed."""
350 exception is suppressed."""
351
351
352 try:
352 try:
353 hdef = oname + inspect.formatargspec(*getargspec(obj))
353 hdef = oname + inspect.formatargspec(*getargspec(obj))
354 return cast_unicode(hdef)
354 return cast_unicode(hdef)
355 except:
355 except:
356 return None
356 return None
357
357
358 def __head(self,h):
358 def __head(self,h):
359 """Return a header string with proper colors."""
359 """Return a header string with proper colors."""
360 return '%s%s%s' % (self.color_table.active_colors.header,h,
360 return '%s%s%s' % (self.color_table.active_colors.header,h,
361 self.color_table.active_colors.normal)
361 self.color_table.active_colors.normal)
362
362
363 def set_active_scheme(self, scheme):
363 def set_active_scheme(self, scheme):
364 self.color_table.set_active_scheme(scheme)
364 self.color_table.set_active_scheme(scheme)
365 self.parser.color_table.set_active_scheme(scheme)
365 self.parser.color_table.set_active_scheme(scheme)
366
366
367 def noinfo(self, msg, oname):
367 def noinfo(self, msg, oname):
368 """Generic message when no information is found."""
368 """Generic message when no information is found."""
369 print('No %s found' % msg, end=' ')
369 print('No %s found' % msg, end=' ')
370 if oname:
370 if oname:
371 print('for %s' % oname)
371 print('for %s' % oname)
372 else:
372 else:
373 print()
373 print()
374
374
375 def pdef(self, obj, oname=''):
375 def pdef(self, obj, oname=''):
376 """Print the definition header for any callable object.
376 """Print the call signature for any callable object.
377
377
378 If the object is a class, print the constructor information."""
378 If the object is a class, print the constructor information."""
379
379
380 if not callable(obj):
380 if not callable(obj):
381 print('Object is not callable.')
381 print('Object is not callable.')
382 return
382 return
383
383
384 header = ''
384 header = ''
385
385
386 if inspect.isclass(obj):
386 if inspect.isclass(obj):
387 header = self.__head('Class constructor information:\n')
387 header = self.__head('Class constructor information:\n')
388 obj = obj.__init__
388 obj = obj.__init__
389 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
389 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
390 obj = obj.__call__
390 obj = obj.__call__
391
391
392 output = self._getdef(obj,oname)
392 output = self._getdef(obj,oname)
393 if output is None:
393 if output is None:
394 self.noinfo('definition header',oname)
394 self.noinfo('definition header',oname)
395 else:
395 else:
396 print(header,self.format(output), end=' ', file=io.stdout)
396 print(header,self.format(output), end=' ', file=io.stdout)
397
397
398 # In Python 3, all classes are new-style, so they all have __init__.
398 # In Python 3, all classes are new-style, so they all have __init__.
399 @skip_doctest_py3
399 @skip_doctest_py3
400 def pdoc(self,obj,oname='',formatter = None):
400 def pdoc(self,obj,oname='',formatter = None):
401 """Print the docstring for any object.
401 """Print the docstring for any object.
402
402
403 Optional:
403 Optional:
404 -formatter: a function to run the docstring through for specially
404 -formatter: a function to run the docstring through for specially
405 formatted docstrings.
405 formatted docstrings.
406
406
407 Examples
407 Examples
408 --------
408 --------
409
409
410 In [1]: class NoInit:
410 In [1]: class NoInit:
411 ...: pass
411 ...: pass
412
412
413 In [2]: class NoDoc:
413 In [2]: class NoDoc:
414 ...: def __init__(self):
414 ...: def __init__(self):
415 ...: pass
415 ...: pass
416
416
417 In [3]: %pdoc NoDoc
417 In [3]: %pdoc NoDoc
418 No documentation found for NoDoc
418 No documentation found for NoDoc
419
419
420 In [4]: %pdoc NoInit
420 In [4]: %pdoc NoInit
421 No documentation found for NoInit
421 No documentation found for NoInit
422
422
423 In [5]: obj = NoInit()
423 In [5]: obj = NoInit()
424
424
425 In [6]: %pdoc obj
425 In [6]: %pdoc obj
426 No documentation found for obj
426 No documentation found for obj
427
427
428 In [5]: obj2 = NoDoc()
428 In [5]: obj2 = NoDoc()
429
429
430 In [6]: %pdoc obj2
430 In [6]: %pdoc obj2
431 No documentation found for obj2
431 No documentation found for obj2
432 """
432 """
433
433
434 head = self.__head # For convenience
434 head = self.__head # For convenience
435 lines = []
435 lines = []
436 ds = getdoc(obj)
436 ds = getdoc(obj)
437 if formatter:
437 if formatter:
438 ds = formatter(ds)
438 ds = formatter(ds)
439 if ds:
439 if ds:
440 lines.append(head("Class Docstring:"))
440 lines.append(head("Class Docstring:"))
441 lines.append(indent(ds))
441 lines.append(indent(ds))
442 if inspect.isclass(obj) and hasattr(obj, '__init__'):
442 if inspect.isclass(obj) and hasattr(obj, '__init__'):
443 init_ds = getdoc(obj.__init__)
443 init_ds = getdoc(obj.__init__)
444 if init_ds is not None:
444 if init_ds is not None:
445 lines.append(head("Constructor Docstring:"))
445 lines.append(head("Constructor Docstring:"))
446 lines.append(indent(init_ds))
446 lines.append(indent(init_ds))
447 elif hasattr(obj,'__call__'):
447 elif hasattr(obj,'__call__'):
448 call_ds = getdoc(obj.__call__)
448 call_ds = getdoc(obj.__call__)
449 if call_ds:
449 if call_ds:
450 lines.append(head("Calling Docstring:"))
450 lines.append(head("Calling Docstring:"))
451 lines.append(indent(call_ds))
451 lines.append(indent(call_ds))
452
452
453 if not lines:
453 if not lines:
454 self.noinfo('documentation',oname)
454 self.noinfo('documentation',oname)
455 else:
455 else:
456 page.page('\n'.join(lines))
456 page.page('\n'.join(lines))
457
457
458 def psource(self,obj,oname=''):
458 def psource(self,obj,oname=''):
459 """Print the source code for an object."""
459 """Print the source code for an object."""
460
460
461 # Flush the source cache because inspect can return out-of-date source
461 # Flush the source cache because inspect can return out-of-date source
462 linecache.checkcache()
462 linecache.checkcache()
463 try:
463 try:
464 src = getsource(obj)
464 src = getsource(obj)
465 except:
465 except:
466 self.noinfo('source',oname)
466 self.noinfo('source',oname)
467 else:
467 else:
468 page.page(self.format(src))
468 page.page(self.format(src))
469
469
470 def pfile(self, obj, oname=''):
470 def pfile(self, obj, oname=''):
471 """Show the whole file where an object was defined."""
471 """Show the whole file where an object was defined."""
472
472
473 lineno = find_source_lines(obj)
473 lineno = find_source_lines(obj)
474 if lineno is None:
474 if lineno is None:
475 self.noinfo('file', oname)
475 self.noinfo('file', oname)
476 return
476 return
477
477
478 ofile = find_file(obj)
478 ofile = find_file(obj)
479 # run contents of file through pager starting at line where the object
479 # run contents of file through pager starting at line where the object
480 # is defined, as long as the file isn't binary and is actually on the
480 # is defined, as long as the file isn't binary and is actually on the
481 # filesystem.
481 # filesystem.
482 if ofile.endswith(('.so', '.dll', '.pyd')):
482 if ofile.endswith(('.so', '.dll', '.pyd')):
483 print('File %r is binary, not printing.' % ofile)
483 print('File %r is binary, not printing.' % ofile)
484 elif not os.path.isfile(ofile):
484 elif not os.path.isfile(ofile):
485 print('File %r does not exist, not printing.' % ofile)
485 print('File %r does not exist, not printing.' % ofile)
486 else:
486 else:
487 # Print only text files, not extension binaries. Note that
487 # Print only text files, not extension binaries. Note that
488 # getsourcelines returns lineno with 1-offset and page() uses
488 # getsourcelines returns lineno with 1-offset and page() uses
489 # 0-offset, so we must adjust.
489 # 0-offset, so we must adjust.
490 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
490 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
491
491
492 def _format_fields(self, fields, title_width=12):
492 def _format_fields(self, fields, title_width=12):
493 """Formats a list of fields for display.
493 """Formats a list of fields for display.
494
494
495 Parameters
495 Parameters
496 ----------
496 ----------
497 fields : list
497 fields : list
498 A list of 2-tuples: (field_title, field_content)
498 A list of 2-tuples: (field_title, field_content)
499 title_width : int
499 title_width : int
500 How many characters to pad titles to. Default 12.
500 How many characters to pad titles to. Default 12.
501 """
501 """
502 out = []
502 out = []
503 header = self.__head
503 header = self.__head
504 for title, content in fields:
504 for title, content in fields:
505 if len(content.splitlines()) > 1:
505 if len(content.splitlines()) > 1:
506 title = header(title + ":") + "\n"
506 title = header(title + ":") + "\n"
507 else:
507 else:
508 title = header((title+":").ljust(title_width))
508 title = header((title+":").ljust(title_width))
509 out.append(cast_unicode(title) + cast_unicode(content))
509 out.append(cast_unicode(title) + cast_unicode(content))
510 return "\n".join(out)
510 return "\n".join(out)
511
511
512 # The fields to be displayed by pinfo: (fancy_name, key_in_info_dict)
512 # The fields to be displayed by pinfo: (fancy_name, key_in_info_dict)
513 pinfo_fields1 = [("Type", "type_name"),
513 pinfo_fields1 = [("Type", "type_name"),
514 ]
514 ]
515
515
516 pinfo_fields2 = [("String Form", "string_form"),
516 pinfo_fields2 = [("String Form", "string_form"),
517 ]
517 ]
518
518
519 pinfo_fields3 = [("Length", "length"),
519 pinfo_fields3 = [("Length", "length"),
520 ("File", "file"),
520 ("File", "file"),
521 ("Definition", "definition"),
521 ("Definition", "definition"),
522 ]
522 ]
523
523
524 pinfo_fields_obj = [("Class Docstring", "class_docstring"),
524 pinfo_fields_obj = [("Class Docstring", "class_docstring"),
525 ("Constructor Docstring","init_docstring"),
525 ("Constructor Docstring","init_docstring"),
526 ("Call def", "call_def"),
526 ("Call def", "call_def"),
527 ("Call docstring", "call_docstring")]
527 ("Call docstring", "call_docstring")]
528
528
529 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
529 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
530 """Show detailed information about an object.
530 """Show detailed information about an object.
531
531
532 Optional arguments:
532 Optional arguments:
533
533
534 - oname: name of the variable pointing to the object.
534 - oname: name of the variable pointing to the object.
535
535
536 - formatter: special formatter for docstrings (see pdoc)
536 - formatter: special formatter for docstrings (see pdoc)
537
537
538 - info: a structure with some information fields which may have been
538 - info: a structure with some information fields which may have been
539 precomputed already.
539 precomputed already.
540
540
541 - detail_level: if set to 1, more information is given.
541 - detail_level: if set to 1, more information is given.
542 """
542 """
543 info = self.info(obj, oname=oname, formatter=formatter,
543 info = self.info(obj, oname=oname, formatter=formatter,
544 info=info, detail_level=detail_level)
544 info=info, detail_level=detail_level)
545 displayfields = []
545 displayfields = []
546 def add_fields(fields):
546 def add_fields(fields):
547 for title, key in fields:
547 for title, key in fields:
548 field = info[key]
548 field = info[key]
549 if field is not None:
549 if field is not None:
550 displayfields.append((title, field.rstrip()))
550 displayfields.append((title, field.rstrip()))
551
551
552 add_fields(self.pinfo_fields1)
552 add_fields(self.pinfo_fields1)
553
553
554 # Base class for old-style instances
554 # Base class for old-style instances
555 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
555 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
556 displayfields.append(("Base Class", info['base_class'].rstrip()))
556 displayfields.append(("Base Class", info['base_class'].rstrip()))
557
557
558 add_fields(self.pinfo_fields2)
558 add_fields(self.pinfo_fields2)
559
559
560 # Namespace
560 # Namespace
561 if info['namespace'] != 'Interactive':
561 if info['namespace'] != 'Interactive':
562 displayfields.append(("Namespace", info['namespace'].rstrip()))
562 displayfields.append(("Namespace", info['namespace'].rstrip()))
563
563
564 add_fields(self.pinfo_fields3)
564 add_fields(self.pinfo_fields3)
565
565
566 # Source or docstring, depending on detail level and whether
566 # Source or docstring, depending on detail level and whether
567 # source found.
567 # source found.
568 if detail_level > 0 and info['source'] is not None:
568 if detail_level > 0 and info['source'] is not None:
569 displayfields.append(("Source",
569 displayfields.append(("Source",
570 self.format(cast_unicode(info['source']))))
570 self.format(cast_unicode(info['source']))))
571 elif info['docstring'] is not None:
571 elif info['docstring'] is not None:
572 displayfields.append(("Docstring", info["docstring"]))
572 displayfields.append(("Docstring", info["docstring"]))
573
573
574 # Constructor info for classes
574 # Constructor info for classes
575 if info['isclass']:
575 if info['isclass']:
576 if info['init_definition'] or info['init_docstring']:
576 if info['init_definition'] or info['init_docstring']:
577 displayfields.append(("Constructor information", ""))
577 displayfields.append(("Constructor information", ""))
578 if info['init_definition'] is not None:
578 if info['init_definition'] is not None:
579 displayfields.append((" Definition",
579 displayfields.append((" Definition",
580 info['init_definition'].rstrip()))
580 info['init_definition'].rstrip()))
581 if info['init_docstring'] is not None:
581 if info['init_docstring'] is not None:
582 displayfields.append((" Docstring",
582 displayfields.append((" Docstring",
583 indent(info['init_docstring'])))
583 indent(info['init_docstring'])))
584
584
585 # Info for objects:
585 # Info for objects:
586 else:
586 else:
587 add_fields(self.pinfo_fields_obj)
587 add_fields(self.pinfo_fields_obj)
588
588
589 # Finally send to printer/pager:
589 # Finally send to printer/pager:
590 if displayfields:
590 if displayfields:
591 page.page(self._format_fields(displayfields))
591 page.page(self._format_fields(displayfields))
592
592
593 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
593 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
594 """Compute a dict with detailed information about an object.
594 """Compute a dict with detailed information about an object.
595
595
596 Optional arguments:
596 Optional arguments:
597
597
598 - oname: name of the variable pointing to the object.
598 - oname: name of the variable pointing to the object.
599
599
600 - formatter: special formatter for docstrings (see pdoc)
600 - formatter: special formatter for docstrings (see pdoc)
601
601
602 - info: a structure with some information fields which may have been
602 - info: a structure with some information fields which may have been
603 precomputed already.
603 precomputed already.
604
604
605 - detail_level: if set to 1, more information is given.
605 - detail_level: if set to 1, more information is given.
606 """
606 """
607
607
608 obj_type = type(obj)
608 obj_type = type(obj)
609
609
610 header = self.__head
610 header = self.__head
611 if info is None:
611 if info is None:
612 ismagic = 0
612 ismagic = 0
613 isalias = 0
613 isalias = 0
614 ospace = ''
614 ospace = ''
615 else:
615 else:
616 ismagic = info.ismagic
616 ismagic = info.ismagic
617 isalias = info.isalias
617 isalias = info.isalias
618 ospace = info.namespace
618 ospace = info.namespace
619
619
620 # Get docstring, special-casing aliases:
620 # Get docstring, special-casing aliases:
621 if isalias:
621 if isalias:
622 if not callable(obj):
622 if not callable(obj):
623 try:
623 try:
624 ds = "Alias to the system command:\n %s" % obj[1]
624 ds = "Alias to the system command:\n %s" % obj[1]
625 except:
625 except:
626 ds = "Alias: " + str(obj)
626 ds = "Alias: " + str(obj)
627 else:
627 else:
628 ds = "Alias to " + str(obj)
628 ds = "Alias to " + str(obj)
629 if obj.__doc__:
629 if obj.__doc__:
630 ds += "\nDocstring:\n" + obj.__doc__
630 ds += "\nDocstring:\n" + obj.__doc__
631 else:
631 else:
632 ds = getdoc(obj)
632 ds = getdoc(obj)
633 if ds is None:
633 if ds is None:
634 ds = '<no docstring>'
634 ds = '<no docstring>'
635 if formatter is not None:
635 if formatter is not None:
636 ds = formatter(ds)
636 ds = formatter(ds)
637
637
638 # store output in a dict, we initialize it here and fill it as we go
638 # store output in a dict, we initialize it here and fill it as we go
639 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
639 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
640
640
641 string_max = 200 # max size of strings to show (snipped if longer)
641 string_max = 200 # max size of strings to show (snipped if longer)
642 shalf = int((string_max -5)/2)
642 shalf = int((string_max -5)/2)
643
643
644 if ismagic:
644 if ismagic:
645 obj_type_name = 'Magic function'
645 obj_type_name = 'Magic function'
646 elif isalias:
646 elif isalias:
647 obj_type_name = 'System alias'
647 obj_type_name = 'System alias'
648 else:
648 else:
649 obj_type_name = obj_type.__name__
649 obj_type_name = obj_type.__name__
650 out['type_name'] = obj_type_name
650 out['type_name'] = obj_type_name
651
651
652 try:
652 try:
653 bclass = obj.__class__
653 bclass = obj.__class__
654 out['base_class'] = str(bclass)
654 out['base_class'] = str(bclass)
655 except: pass
655 except: pass
656
656
657 # String form, but snip if too long in ? form (full in ??)
657 # String form, but snip if too long in ? form (full in ??)
658 if detail_level >= self.str_detail_level:
658 if detail_level >= self.str_detail_level:
659 try:
659 try:
660 ostr = str(obj)
660 ostr = str(obj)
661 str_head = 'string_form'
661 str_head = 'string_form'
662 if not detail_level and len(ostr)>string_max:
662 if not detail_level and len(ostr)>string_max:
663 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
663 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
664 ostr = ("\n" + " " * len(str_head.expandtabs())).\
664 ostr = ("\n" + " " * len(str_head.expandtabs())).\
665 join(q.strip() for q in ostr.split("\n"))
665 join(q.strip() for q in ostr.split("\n"))
666 out[str_head] = ostr
666 out[str_head] = ostr
667 except:
667 except:
668 pass
668 pass
669
669
670 if ospace:
670 if ospace:
671 out['namespace'] = ospace
671 out['namespace'] = ospace
672
672
673 # Length (for strings and lists)
673 # Length (for strings and lists)
674 try:
674 try:
675 out['length'] = str(len(obj))
675 out['length'] = str(len(obj))
676 except: pass
676 except: pass
677
677
678 # Filename where object was defined
678 # Filename where object was defined
679 binary_file = False
679 binary_file = False
680 fname = find_file(obj)
680 fname = find_file(obj)
681 if fname is None:
681 if fname is None:
682 # if anything goes wrong, we don't want to show source, so it's as
682 # if anything goes wrong, we don't want to show source, so it's as
683 # if the file was binary
683 # if the file was binary
684 binary_file = True
684 binary_file = True
685 else:
685 else:
686 if fname.endswith(('.so', '.dll', '.pyd')):
686 if fname.endswith(('.so', '.dll', '.pyd')):
687 binary_file = True
687 binary_file = True
688 elif fname.endswith('<string>'):
688 elif fname.endswith('<string>'):
689 fname = 'Dynamically generated function. No source code available.'
689 fname = 'Dynamically generated function. No source code available.'
690 out['file'] = fname
690 out['file'] = fname
691
691
692 # reconstruct the function definition and print it:
692 # reconstruct the function definition and print it:
693 defln = self._getdef(obj, oname)
693 defln = self._getdef(obj, oname)
694 if defln:
694 if defln:
695 out['definition'] = self.format(defln)
695 out['definition'] = self.format(defln)
696
696
697 # Docstrings only in detail 0 mode, since source contains them (we
697 # Docstrings only in detail 0 mode, since source contains them (we
698 # avoid repetitions). If source fails, we add them back, see below.
698 # avoid repetitions). If source fails, we add them back, see below.
699 if ds and detail_level == 0:
699 if ds and detail_level == 0:
700 out['docstring'] = ds
700 out['docstring'] = ds
701
701
702 # Original source code for any callable
702 # Original source code for any callable
703 if detail_level:
703 if detail_level:
704 # Flush the source cache because inspect can return out-of-date
704 # Flush the source cache because inspect can return out-of-date
705 # source
705 # source
706 linecache.checkcache()
706 linecache.checkcache()
707 source = None
707 source = None
708 try:
708 try:
709 try:
709 try:
710 source = getsource(obj, binary_file)
710 source = getsource(obj, binary_file)
711 except TypeError:
711 except TypeError:
712 if hasattr(obj, '__class__'):
712 if hasattr(obj, '__class__'):
713 source = getsource(obj.__class__, binary_file)
713 source = getsource(obj.__class__, binary_file)
714 if source is not None:
714 if source is not None:
715 out['source'] = source.rstrip()
715 out['source'] = source.rstrip()
716 except Exception:
716 except Exception:
717 pass
717 pass
718
718
719 if ds and source is None:
719 if ds and source is None:
720 out['docstring'] = ds
720 out['docstring'] = ds
721
721
722
722
723 # Constructor docstring for classes
723 # Constructor docstring for classes
724 if inspect.isclass(obj):
724 if inspect.isclass(obj):
725 out['isclass'] = True
725 out['isclass'] = True
726 # reconstruct the function definition and print it:
726 # reconstruct the function definition and print it:
727 try:
727 try:
728 obj_init = obj.__init__
728 obj_init = obj.__init__
729 except AttributeError:
729 except AttributeError:
730 init_def = init_ds = None
730 init_def = init_ds = None
731 else:
731 else:
732 init_def = self._getdef(obj_init,oname)
732 init_def = self._getdef(obj_init,oname)
733 init_ds = getdoc(obj_init)
733 init_ds = getdoc(obj_init)
734 # Skip Python's auto-generated docstrings
734 # Skip Python's auto-generated docstrings
735 if init_ds and \
735 if init_ds and \
736 init_ds.startswith('x.__init__(...) initializes'):
736 init_ds.startswith('x.__init__(...) initializes'):
737 init_ds = None
737 init_ds = None
738
738
739 if init_def or init_ds:
739 if init_def or init_ds:
740 if init_def:
740 if init_def:
741 out['init_definition'] = self.format(init_def)
741 out['init_definition'] = self.format(init_def)
742 if init_ds:
742 if init_ds:
743 out['init_docstring'] = init_ds
743 out['init_docstring'] = init_ds
744
744
745 # and class docstring for instances:
745 # and class docstring for instances:
746 else:
746 else:
747 # First, check whether the instance docstring is identical to the
747 # First, check whether the instance docstring is identical to the
748 # class one, and print it separately if they don't coincide. In
748 # class one, and print it separately if they don't coincide. In
749 # most cases they will, but it's nice to print all the info for
749 # most cases they will, but it's nice to print all the info for
750 # objects which use instance-customized docstrings.
750 # objects which use instance-customized docstrings.
751 if ds:
751 if ds:
752 try:
752 try:
753 cls = getattr(obj,'__class__')
753 cls = getattr(obj,'__class__')
754 except:
754 except:
755 class_ds = None
755 class_ds = None
756 else:
756 else:
757 class_ds = getdoc(cls)
757 class_ds = getdoc(cls)
758 # Skip Python's auto-generated docstrings
758 # Skip Python's auto-generated docstrings
759 if class_ds and \
759 if class_ds and \
760 (class_ds.startswith('function(code, globals[,') or \
760 (class_ds.startswith('function(code, globals[,') or \
761 class_ds.startswith('instancemethod(function, instance,') or \
761 class_ds.startswith('instancemethod(function, instance,') or \
762 class_ds.startswith('module(name[,') ):
762 class_ds.startswith('module(name[,') ):
763 class_ds = None
763 class_ds = None
764 if class_ds and ds != class_ds:
764 if class_ds and ds != class_ds:
765 out['class_docstring'] = class_ds
765 out['class_docstring'] = class_ds
766
766
767 # Next, try to show constructor docstrings
767 # Next, try to show constructor docstrings
768 try:
768 try:
769 init_ds = getdoc(obj.__init__)
769 init_ds = getdoc(obj.__init__)
770 # Skip Python's auto-generated docstrings
770 # Skip Python's auto-generated docstrings
771 if init_ds and \
771 if init_ds and \
772 init_ds.startswith('x.__init__(...) initializes'):
772 init_ds.startswith('x.__init__(...) initializes'):
773 init_ds = None
773 init_ds = None
774 except AttributeError:
774 except AttributeError:
775 init_ds = None
775 init_ds = None
776 if init_ds:
776 if init_ds:
777 out['init_docstring'] = init_ds
777 out['init_docstring'] = init_ds
778
778
779 # Call form docstring for callable instances
779 # Call form docstring for callable instances
780 if hasattr(obj, '__call__'):
780 if hasattr(obj, '__call__'):
781 call_def = self._getdef(obj.__call__, oname)
781 call_def = self._getdef(obj.__call__, oname)
782 if call_def is not None:
782 if call_def is not None:
783 out['call_def'] = self.format(call_def)
783 out['call_def'] = self.format(call_def)
784 call_ds = getdoc(obj.__call__)
784 call_ds = getdoc(obj.__call__)
785 # Skip Python's auto-generated docstrings
785 # Skip Python's auto-generated docstrings
786 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
786 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
787 call_ds = None
787 call_ds = None
788 if call_ds:
788 if call_ds:
789 out['call_docstring'] = call_ds
789 out['call_docstring'] = call_ds
790
790
791 # Compute the object's argspec as a callable. The key is to decide
791 # Compute the object's argspec as a callable. The key is to decide
792 # whether to pull it from the object itself, from its __init__ or
792 # whether to pull it from the object itself, from its __init__ or
793 # from its __call__ method.
793 # from its __call__ method.
794
794
795 if inspect.isclass(obj):
795 if inspect.isclass(obj):
796 # Old-style classes need not have an __init__
796 # Old-style classes need not have an __init__
797 callable_obj = getattr(obj, "__init__", None)
797 callable_obj = getattr(obj, "__init__", None)
798 elif callable(obj):
798 elif callable(obj):
799 callable_obj = obj
799 callable_obj = obj
800 else:
800 else:
801 callable_obj = None
801 callable_obj = None
802
802
803 if callable_obj:
803 if callable_obj:
804 try:
804 try:
805 args, varargs, varkw, defaults = getargspec(callable_obj)
805 args, varargs, varkw, defaults = getargspec(callable_obj)
806 except (TypeError, AttributeError):
806 except (TypeError, AttributeError):
807 # For extensions/builtins we can't retrieve the argspec
807 # For extensions/builtins we can't retrieve the argspec
808 pass
808 pass
809 else:
809 else:
810 out['argspec'] = dict(args=args, varargs=varargs,
810 out['argspec'] = dict(args=args, varargs=varargs,
811 varkw=varkw, defaults=defaults)
811 varkw=varkw, defaults=defaults)
812
812
813 return object_info(**out)
813 return object_info(**out)
814
814
815
815
816 def psearch(self,pattern,ns_table,ns_search=[],
816 def psearch(self,pattern,ns_table,ns_search=[],
817 ignore_case=False,show_all=False):
817 ignore_case=False,show_all=False):
818 """Search namespaces with wildcards for objects.
818 """Search namespaces with wildcards for objects.
819
819
820 Arguments:
820 Arguments:
821
821
822 - pattern: string containing shell-like wildcards to use in namespace
822 - pattern: string containing shell-like wildcards to use in namespace
823 searches and optionally a type specification to narrow the search to
823 searches and optionally a type specification to narrow the search to
824 objects of that type.
824 objects of that type.
825
825
826 - ns_table: dict of name->namespaces for search.
826 - ns_table: dict of name->namespaces for search.
827
827
828 Optional arguments:
828 Optional arguments:
829
829
830 - ns_search: list of namespace names to include in search.
830 - ns_search: list of namespace names to include in search.
831
831
832 - ignore_case(False): make the search case-insensitive.
832 - ignore_case(False): make the search case-insensitive.
833
833
834 - show_all(False): show all names, including those starting with
834 - show_all(False): show all names, including those starting with
835 underscores.
835 underscores.
836 """
836 """
837 #print 'ps pattern:<%r>' % pattern # dbg
837 #print 'ps pattern:<%r>' % pattern # dbg
838
838
839 # defaults
839 # defaults
840 type_pattern = 'all'
840 type_pattern = 'all'
841 filter = ''
841 filter = ''
842
842
843 cmds = pattern.split()
843 cmds = pattern.split()
844 len_cmds = len(cmds)
844 len_cmds = len(cmds)
845 if len_cmds == 1:
845 if len_cmds == 1:
846 # Only filter pattern given
846 # Only filter pattern given
847 filter = cmds[0]
847 filter = cmds[0]
848 elif len_cmds == 2:
848 elif len_cmds == 2:
849 # Both filter and type specified
849 # Both filter and type specified
850 filter,type_pattern = cmds
850 filter,type_pattern = cmds
851 else:
851 else:
852 raise ValueError('invalid argument string for psearch: <%s>' %
852 raise ValueError('invalid argument string for psearch: <%s>' %
853 pattern)
853 pattern)
854
854
855 # filter search namespaces
855 # filter search namespaces
856 for name in ns_search:
856 for name in ns_search:
857 if name not in ns_table:
857 if name not in ns_table:
858 raise ValueError('invalid namespace <%s>. Valid names: %s' %
858 raise ValueError('invalid namespace <%s>. Valid names: %s' %
859 (name,ns_table.keys()))
859 (name,ns_table.keys()))
860
860
861 #print 'type_pattern:',type_pattern # dbg
861 #print 'type_pattern:',type_pattern # dbg
862 search_result, namespaces_seen = set(), set()
862 search_result, namespaces_seen = set(), set()
863 for ns_name in ns_search:
863 for ns_name in ns_search:
864 ns = ns_table[ns_name]
864 ns = ns_table[ns_name]
865 # Normally, locals and globals are the same, so we just check one.
865 # Normally, locals and globals are the same, so we just check one.
866 if id(ns) in namespaces_seen:
866 if id(ns) in namespaces_seen:
867 continue
867 continue
868 namespaces_seen.add(id(ns))
868 namespaces_seen.add(id(ns))
869 tmp_res = list_namespace(ns, type_pattern, filter,
869 tmp_res = list_namespace(ns, type_pattern, filter,
870 ignore_case=ignore_case, show_all=show_all)
870 ignore_case=ignore_case, show_all=show_all)
871 search_result.update(tmp_res)
871 search_result.update(tmp_res)
872
872
873 page.page('\n'.join(sorted(search_result)))
873 page.page('\n'.join(sorted(search_result)))
@@ -1,272 +1,300 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Tests for code execution (%run and related), which is particularly tricky.
2 """Tests for code execution (%run and related), which is particularly tricky.
3
3
4 Because of how %run manages namespaces, and the fact that we are trying here to
4 Because of how %run manages namespaces, and the fact that we are trying here to
5 verify subtle object deletion and reference counting issues, the %run tests
5 verify subtle object deletion and reference counting issues, the %run tests
6 will be kept in this separate file. This makes it easier to aggregate in one
6 will be kept in this separate file. This makes it easier to aggregate in one
7 place the tricks needed to handle it; most other magics are much easier to test
7 place the tricks needed to handle it; most other magics are much easier to test
8 and we do so in a common test_magic file.
8 and we do so in a common test_magic file.
9 """
9 """
10 from __future__ import absolute_import
10 from __future__ import absolute_import
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 import os
16 import os
17 import sys
17 import sys
18 import tempfile
18 import tempfile
19
19
20 import nose.tools as nt
20 import nose.tools as nt
21 from nose import SkipTest
21 from nose import SkipTest
22
22
23 from IPython.testing import decorators as dec
23 from IPython.testing import decorators as dec
24 from IPython.testing import tools as tt
24 from IPython.testing import tools as tt
25 from IPython.utils import py3compat
25 from IPython.utils import py3compat
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Test functions begin
28 # Test functions begin
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31 def doctest_refbug():
31 def doctest_refbug():
32 """Very nasty problem with references held by multiple runs of a script.
32 """Very nasty problem with references held by multiple runs of a script.
33 See: https://github.com/ipython/ipython/issues/141
33 See: https://github.com/ipython/ipython/issues/141
34
34
35 In [1]: _ip.clear_main_mod_cache()
35 In [1]: _ip.clear_main_mod_cache()
36 # random
36 # random
37
37
38 In [2]: %run refbug
38 In [2]: %run refbug
39
39
40 In [3]: call_f()
40 In [3]: call_f()
41 lowercased: hello
41 lowercased: hello
42
42
43 In [4]: %run refbug
43 In [4]: %run refbug
44
44
45 In [5]: call_f()
45 In [5]: call_f()
46 lowercased: hello
46 lowercased: hello
47 lowercased: hello
47 lowercased: hello
48 """
48 """
49
49
50
50
51 def doctest_run_builtins():
51 def doctest_run_builtins():
52 r"""Check that %run doesn't damage __builtins__.
52 r"""Check that %run doesn't damage __builtins__.
53
53
54 In [1]: import tempfile
54 In [1]: import tempfile
55
55
56 In [2]: bid1 = id(__builtins__)
56 In [2]: bid1 = id(__builtins__)
57
57
58 In [3]: fname = tempfile.mkstemp('.py')[1]
58 In [3]: fname = tempfile.mkstemp('.py')[1]
59
59
60 In [3]: f = open(fname,'w')
60 In [3]: f = open(fname,'w')
61
61
62 In [4]: dummy= f.write('pass\n')
62 In [4]: dummy= f.write('pass\n')
63
63
64 In [5]: f.flush()
64 In [5]: f.flush()
65
65
66 In [6]: t1 = type(__builtins__)
66 In [6]: t1 = type(__builtins__)
67
67
68 In [7]: %run $fname
68 In [7]: %run $fname
69
69
70 In [7]: f.close()
70 In [7]: f.close()
71
71
72 In [8]: bid2 = id(__builtins__)
72 In [8]: bid2 = id(__builtins__)
73
73
74 In [9]: t2 = type(__builtins__)
74 In [9]: t2 = type(__builtins__)
75
75
76 In [10]: t1 == t2
76 In [10]: t1 == t2
77 Out[10]: True
77 Out[10]: True
78
78
79 In [10]: bid1 == bid2
79 In [10]: bid1 == bid2
80 Out[10]: True
80 Out[10]: True
81
81
82 In [12]: try:
82 In [12]: try:
83 ....: os.unlink(fname)
83 ....: os.unlink(fname)
84 ....: except:
84 ....: except:
85 ....: pass
85 ....: pass
86 ....:
86 ....:
87 """
87 """
88
88
89
89
90 def doctest_run_option_parser():
90 def doctest_run_option_parser():
91 r"""Test option parser in %run.
91 r"""Test option parser in %run.
92
92
93 In [1]: %run print_argv.py
93 In [1]: %run print_argv.py
94 []
94 []
95
95
96 In [2]: %run print_argv.py print*.py
96 In [2]: %run print_argv.py print*.py
97 ['print_argv.py']
97 ['print_argv.py']
98
98
99 In [3]: %run print_argv.py print\\*.py
99 In [3]: %run -G print_argv.py print*.py
100 ['print*.py']
100 ['print*.py']
101
101
102 In [4]: %run print_argv.py 'print*.py'
102 """
103
104
105 @dec.skip_win32
106 def doctest_run_option_parser_for_posix():
107 r"""Test option parser in %run (Linux/OSX specific).
108
109 You need double quote to escape glob in POSIX systems:
110
111 In [1]: %run print_argv.py print\\*.py
112 ['print*.py']
113
114 You can't use quote to escape glob in POSIX systems:
115
116 In [2]: %run print_argv.py 'print*.py'
103 ['print_argv.py']
117 ['print_argv.py']
104
118
105 In [5]: %run -G print_argv.py print*.py
119 """
120
121
122 @dec.skip_if_not_win32
123 def doctest_run_option_parser_for_windows():
124 r"""Test option parser in %run (Windows specific).
125
126 In Windows, you can't escape ``*` `by backslash:
127
128 In [1]: %run print_argv.py print\\*.py
129 ['print\\*.py']
130
131 You can use quote to escape glob:
132
133 In [2]: %run print_argv.py 'print*.py'
106 ['print*.py']
134 ['print*.py']
107
135
108 """
136 """
109
137
110
138
111 @py3compat.doctest_refactor_print
139 @py3compat.doctest_refactor_print
112 def doctest_reset_del():
140 def doctest_reset_del():
113 """Test that resetting doesn't cause errors in __del__ methods.
141 """Test that resetting doesn't cause errors in __del__ methods.
114
142
115 In [2]: class A(object):
143 In [2]: class A(object):
116 ...: def __del__(self):
144 ...: def __del__(self):
117 ...: print str("Hi")
145 ...: print str("Hi")
118 ...:
146 ...:
119
147
120 In [3]: a = A()
148 In [3]: a = A()
121
149
122 In [4]: get_ipython().reset()
150 In [4]: get_ipython().reset()
123 Hi
151 Hi
124
152
125 In [5]: 1+1
153 In [5]: 1+1
126 Out[5]: 2
154 Out[5]: 2
127 """
155 """
128
156
129 # For some tests, it will be handy to organize them in a class with a common
157 # For some tests, it will be handy to organize them in a class with a common
130 # setup that makes a temp file
158 # setup that makes a temp file
131
159
132 class TestMagicRunPass(tt.TempFileMixin):
160 class TestMagicRunPass(tt.TempFileMixin):
133
161
134 def setup(self):
162 def setup(self):
135 """Make a valid python temp file."""
163 """Make a valid python temp file."""
136 self.mktmp('pass\n')
164 self.mktmp('pass\n')
137
165
138 def run_tmpfile(self):
166 def run_tmpfile(self):
139 _ip = get_ipython()
167 _ip = get_ipython()
140 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
168 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
141 # See below and ticket https://bugs.launchpad.net/bugs/366353
169 # See below and ticket https://bugs.launchpad.net/bugs/366353
142 _ip.magic('run %s' % self.fname)
170 _ip.magic('run %s' % self.fname)
143
171
144 def run_tmpfile_p(self):
172 def run_tmpfile_p(self):
145 _ip = get_ipython()
173 _ip = get_ipython()
146 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
174 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
147 # See below and ticket https://bugs.launchpad.net/bugs/366353
175 # See below and ticket https://bugs.launchpad.net/bugs/366353
148 _ip.magic('run -p %s' % self.fname)
176 _ip.magic('run -p %s' % self.fname)
149
177
150 def test_builtins_id(self):
178 def test_builtins_id(self):
151 """Check that %run doesn't damage __builtins__ """
179 """Check that %run doesn't damage __builtins__ """
152 _ip = get_ipython()
180 _ip = get_ipython()
153 # Test that the id of __builtins__ is not modified by %run
181 # Test that the id of __builtins__ is not modified by %run
154 bid1 = id(_ip.user_ns['__builtins__'])
182 bid1 = id(_ip.user_ns['__builtins__'])
155 self.run_tmpfile()
183 self.run_tmpfile()
156 bid2 = id(_ip.user_ns['__builtins__'])
184 bid2 = id(_ip.user_ns['__builtins__'])
157 nt.assert_equal(bid1, bid2)
185 nt.assert_equal(bid1, bid2)
158
186
159 def test_builtins_type(self):
187 def test_builtins_type(self):
160 """Check that the type of __builtins__ doesn't change with %run.
188 """Check that the type of __builtins__ doesn't change with %run.
161
189
162 However, the above could pass if __builtins__ was already modified to
190 However, the above could pass if __builtins__ was already modified to
163 be a dict (it should be a module) by a previous use of %run. So we
191 be a dict (it should be a module) by a previous use of %run. So we
164 also check explicitly that it really is a module:
192 also check explicitly that it really is a module:
165 """
193 """
166 _ip = get_ipython()
194 _ip = get_ipython()
167 self.run_tmpfile()
195 self.run_tmpfile()
168 nt.assert_equal(type(_ip.user_ns['__builtins__']),type(sys))
196 nt.assert_equal(type(_ip.user_ns['__builtins__']),type(sys))
169
197
170 def test_prompts(self):
198 def test_prompts(self):
171 """Test that prompts correctly generate after %run"""
199 """Test that prompts correctly generate after %run"""
172 self.run_tmpfile()
200 self.run_tmpfile()
173 _ip = get_ipython()
201 _ip = get_ipython()
174 p2 = _ip.prompt_manager.render('in2').strip()
202 p2 = _ip.prompt_manager.render('in2').strip()
175 nt.assert_equal(p2[:3], '...')
203 nt.assert_equal(p2[:3], '...')
176
204
177 def test_run_profile( self ):
205 def test_run_profile( self ):
178 """Test that the option -p, which invokes the profiler, do not
206 """Test that the option -p, which invokes the profiler, do not
179 crash by invoking execfile"""
207 crash by invoking execfile"""
180 _ip = get_ipython()
208 _ip = get_ipython()
181 self.run_tmpfile_p()
209 self.run_tmpfile_p()
182
210
183
211
184 class TestMagicRunSimple(tt.TempFileMixin):
212 class TestMagicRunSimple(tt.TempFileMixin):
185
213
186 def test_simpledef(self):
214 def test_simpledef(self):
187 """Test that simple class definitions work."""
215 """Test that simple class definitions work."""
188 src = ("class foo: pass\n"
216 src = ("class foo: pass\n"
189 "def f(): return foo()")
217 "def f(): return foo()")
190 self.mktmp(src)
218 self.mktmp(src)
191 _ip.magic('run %s' % self.fname)
219 _ip.magic('run %s' % self.fname)
192 _ip.run_cell('t = isinstance(f(), foo)')
220 _ip.run_cell('t = isinstance(f(), foo)')
193 nt.assert_true(_ip.user_ns['t'])
221 nt.assert_true(_ip.user_ns['t'])
194
222
195 def test_obj_del(self):
223 def test_obj_del(self):
196 """Test that object's __del__ methods are called on exit."""
224 """Test that object's __del__ methods are called on exit."""
197 if sys.platform == 'win32':
225 if sys.platform == 'win32':
198 try:
226 try:
199 import win32api
227 import win32api
200 except ImportError:
228 except ImportError:
201 raise SkipTest("Test requires pywin32")
229 raise SkipTest("Test requires pywin32")
202 src = ("class A(object):\n"
230 src = ("class A(object):\n"
203 " def __del__(self):\n"
231 " def __del__(self):\n"
204 " print 'object A deleted'\n"
232 " print 'object A deleted'\n"
205 "a = A()\n")
233 "a = A()\n")
206 self.mktmp(py3compat.doctest_refactor_print(src))
234 self.mktmp(py3compat.doctest_refactor_print(src))
207 if dec.module_not_available('sqlite3'):
235 if dec.module_not_available('sqlite3'):
208 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
236 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
209 else:
237 else:
210 err = None
238 err = None
211 tt.ipexec_validate(self.fname, 'object A deleted', err)
239 tt.ipexec_validate(self.fname, 'object A deleted', err)
212
240
213 @dec.skip_known_failure
241 @dec.skip_known_failure
214 def test_aggressive_namespace_cleanup(self):
242 def test_aggressive_namespace_cleanup(self):
215 """Test that namespace cleanup is not too aggressive GH-238
243 """Test that namespace cleanup is not too aggressive GH-238
216
244
217 Returning from another run magic deletes the namespace"""
245 Returning from another run magic deletes the namespace"""
218 # see ticket https://github.com/ipython/ipython/issues/238
246 # see ticket https://github.com/ipython/ipython/issues/238
219 class secondtmp(tt.TempFileMixin): pass
247 class secondtmp(tt.TempFileMixin): pass
220 empty = secondtmp()
248 empty = secondtmp()
221 empty.mktmp('')
249 empty.mktmp('')
222 src = ("ip = get_ipython()\n"
250 src = ("ip = get_ipython()\n"
223 "for i in range(5):\n"
251 "for i in range(5):\n"
224 " try:\n"
252 " try:\n"
225 " ip.magic('run %s')\n"
253 " ip.magic('run %s')\n"
226 " except NameError as e:\n"
254 " except NameError as e:\n"
227 " print i;break\n" % empty.fname)
255 " print i;break\n" % empty.fname)
228 self.mktmp(py3compat.doctest_refactor_print(src))
256 self.mktmp(py3compat.doctest_refactor_print(src))
229 _ip.magic('run %s' % self.fname)
257 _ip.magic('run %s' % self.fname)
230 _ip.run_cell('ip == get_ipython()')
258 _ip.run_cell('ip == get_ipython()')
231 nt.assert_equal(_ip.user_ns['i'], 5)
259 nt.assert_equal(_ip.user_ns['i'], 5)
232
260
233 @dec.skip_win32
261 @dec.skip_win32
234 def test_tclass(self):
262 def test_tclass(self):
235 mydir = os.path.dirname(__file__)
263 mydir = os.path.dirname(__file__)
236 tc = os.path.join(mydir, 'tclass')
264 tc = os.path.join(mydir, 'tclass')
237 src = ("%%run '%s' C-first\n"
265 src = ("%%run '%s' C-first\n"
238 "%%run '%s' C-second\n"
266 "%%run '%s' C-second\n"
239 "%%run '%s' C-third\n") % (tc, tc, tc)
267 "%%run '%s' C-third\n") % (tc, tc, tc)
240 self.mktmp(src, '.ipy')
268 self.mktmp(src, '.ipy')
241 out = """\
269 out = """\
242 ARGV 1-: ['C-first']
270 ARGV 1-: ['C-first']
243 ARGV 1-: ['C-second']
271 ARGV 1-: ['C-second']
244 tclass.py: deleting object: C-first
272 tclass.py: deleting object: C-first
245 ARGV 1-: ['C-third']
273 ARGV 1-: ['C-third']
246 tclass.py: deleting object: C-second
274 tclass.py: deleting object: C-second
247 tclass.py: deleting object: C-third
275 tclass.py: deleting object: C-third
248 """
276 """
249 if dec.module_not_available('sqlite3'):
277 if dec.module_not_available('sqlite3'):
250 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
278 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
251 else:
279 else:
252 err = None
280 err = None
253 tt.ipexec_validate(self.fname, out, err)
281 tt.ipexec_validate(self.fname, out, err)
254
282
255 def test_run_i_after_reset(self):
283 def test_run_i_after_reset(self):
256 """Check that %run -i still works after %reset (gh-693)"""
284 """Check that %run -i still works after %reset (gh-693)"""
257 src = "yy = zz\n"
285 src = "yy = zz\n"
258 self.mktmp(src)
286 self.mktmp(src)
259 _ip.run_cell("zz = 23")
287 _ip.run_cell("zz = 23")
260 _ip.magic('run -i %s' % self.fname)
288 _ip.magic('run -i %s' % self.fname)
261 nt.assert_equal(_ip.user_ns['yy'], 23)
289 nt.assert_equal(_ip.user_ns['yy'], 23)
262 _ip.magic('reset -f')
290 _ip.magic('reset -f')
263 _ip.run_cell("zz = 23")
291 _ip.run_cell("zz = 23")
264 _ip.magic('run -i %s' % self.fname)
292 _ip.magic('run -i %s' % self.fname)
265 nt.assert_equal(_ip.user_ns['yy'], 23)
293 nt.assert_equal(_ip.user_ns['yy'], 23)
266
294
267 def test_unicode(self):
295 def test_unicode(self):
268 """Check that files in odd encodings are accepted."""
296 """Check that files in odd encodings are accepted."""
269 mydir = os.path.dirname(__file__)
297 mydir = os.path.dirname(__file__)
270 na = os.path.join(mydir, 'nonascii.py')
298 na = os.path.join(mydir, 'nonascii.py')
271 _ip.magic('run "%s"' % na)
299 _ip.magic('run "%s"' % na)
272 nt.assert_equal(_ip.user_ns['u'], u'Ўт№Ф')
300 nt.assert_equal(_ip.user_ns['u'], u'Ўт№Ф')
@@ -1,527 +1,521 b''
1 """IPython extension to reload modules before executing user code.
1 """IPython extension to reload modules before executing user code.
2
2
3 ``autoreload`` reloads modules automatically before entering the execution of
3 ``autoreload`` reloads modules automatically before entering the execution of
4 code typed at the IPython prompt.
4 code typed at the IPython prompt.
5
5
6 This makes for example the following workflow possible:
6 This makes for example the following workflow possible:
7
7
8 .. sourcecode:: ipython
8 .. sourcecode:: ipython
9
9
10 In [1]: %load_ext autoreload
10 In [1]: %load_ext autoreload
11
11
12 In [2]: %autoreload 2
12 In [2]: %autoreload 2
13
13
14 In [3]: from foo import some_function
14 In [3]: from foo import some_function
15
15
16 In [4]: some_function()
16 In [4]: some_function()
17 Out[4]: 42
17 Out[4]: 42
18
18
19 In [5]: # open foo.py in an editor and change some_function to return 43
19 In [5]: # open foo.py in an editor and change some_function to return 43
20
20
21 In [6]: some_function()
21 In [6]: some_function()
22 Out[6]: 43
22 Out[6]: 43
23
23
24 The module was reloaded without reloading it explicitly, and the object
24 The module was reloaded without reloading it explicitly, and the object
25 imported with ``from foo import ...`` was also updated.
25 imported with ``from foo import ...`` was also updated.
26
26
27 Usage
27 Usage
28 =====
28 =====
29
29
30 The following magic commands are provided:
30 The following magic commands are provided:
31
31
32 ``%autoreload``
32 ``%autoreload``
33
33
34 Reload all modules (except those excluded by ``%aimport``)
34 Reload all modules (except those excluded by ``%aimport``)
35 automatically now.
35 automatically now.
36
36
37 ``%autoreload 0``
37 ``%autoreload 0``
38
38
39 Disable automatic reloading.
39 Disable automatic reloading.
40
40
41 ``%autoreload 1``
41 ``%autoreload 1``
42
42
43 Reload all modules imported with ``%aimport`` every time before
43 Reload all modules imported with ``%aimport`` every time before
44 executing the Python code typed.
44 executing the Python code typed.
45
45
46 ``%autoreload 2``
46 ``%autoreload 2``
47
47
48 Reload all modules (except those excluded by ``%aimport``) every
48 Reload all modules (except those excluded by ``%aimport``) every
49 time before executing the Python code typed.
49 time before executing the Python code typed.
50
50
51 ``%aimport``
51 ``%aimport``
52
52
53 List modules which are to be automatically imported or not to be imported.
53 List modules which are to be automatically imported or not to be imported.
54
54
55 ``%aimport foo``
55 ``%aimport foo``
56
56
57 Import module 'foo' and mark it to be autoreloaded for ``%autoreload 1``
57 Import module 'foo' and mark it to be autoreloaded for ``%autoreload 1``
58
58
59 ``%aimport -foo``
59 ``%aimport -foo``
60
60
61 Mark module 'foo' to not be autoreloaded.
61 Mark module 'foo' to not be autoreloaded.
62
62
63 Caveats
63 Caveats
64 =======
64 =======
65
65
66 Reloading Python modules in a reliable way is in general difficult,
66 Reloading Python modules in a reliable way is in general difficult,
67 and unexpected things may occur. ``%autoreload`` tries to work around
67 and unexpected things may occur. ``%autoreload`` tries to work around
68 common pitfalls by replacing function code objects and parts of
68 common pitfalls by replacing function code objects and parts of
69 classes previously in the module with new versions. This makes the
69 classes previously in the module with new versions. This makes the
70 following things to work:
70 following things to work:
71
71
72 - Functions and classes imported via 'from xxx import foo' are upgraded
72 - Functions and classes imported via 'from xxx import foo' are upgraded
73 to new versions when 'xxx' is reloaded.
73 to new versions when 'xxx' is reloaded.
74
74
75 - Methods and properties of classes are upgraded on reload, so that
75 - Methods and properties of classes are upgraded on reload, so that
76 calling 'c.foo()' on an object 'c' created before the reload causes
76 calling 'c.foo()' on an object 'c' created before the reload causes
77 the new code for 'foo' to be executed.
77 the new code for 'foo' to be executed.
78
78
79 Some of the known remaining caveats are:
79 Some of the known remaining caveats are:
80
80
81 - Replacing code objects does not always succeed: changing a @property
81 - Replacing code objects does not always succeed: changing a @property
82 in a class to an ordinary method or a method to a member variable
82 in a class to an ordinary method or a method to a member variable
83 can cause problems (but in old objects only).
83 can cause problems (but in old objects only).
84
84
85 - Functions that are removed (eg. via monkey-patching) from a module
85 - Functions that are removed (eg. via monkey-patching) from a module
86 before it is reloaded are not upgraded.
86 before it is reloaded are not upgraded.
87
87
88 - C extension modules cannot be reloaded, and so cannot be autoreloaded.
88 - C extension modules cannot be reloaded, and so cannot be autoreloaded.
89 """
89 """
90 from __future__ import print_function
90 from __future__ import print_function
91
91
92 skip_doctest = True
92 skip_doctest = True
93
93
94 #-----------------------------------------------------------------------------
94 #-----------------------------------------------------------------------------
95 # Copyright (C) 2000 Thomas Heller
95 # Copyright (C) 2000 Thomas Heller
96 # Copyright (C) 2008 Pauli Virtanen <pav@iki.fi>
96 # Copyright (C) 2008 Pauli Virtanen <pav@iki.fi>
97 # Copyright (C) 2012 The IPython Development Team
97 # Copyright (C) 2012 The IPython Development Team
98 #
98 #
99 # Distributed under the terms of the BSD License. The full license is in
99 # Distributed under the terms of the BSD License. The full license is in
100 # the file COPYING, distributed as part of this software.
100 # the file COPYING, distributed as part of this software.
101 #-----------------------------------------------------------------------------
101 #-----------------------------------------------------------------------------
102 #
102 #
103 # This IPython module is written by Pauli Virtanen, based on the autoreload
103 # This IPython module is written by Pauli Virtanen, based on the autoreload
104 # code by Thomas Heller.
104 # code by Thomas Heller.
105
105
106 #-----------------------------------------------------------------------------
106 #-----------------------------------------------------------------------------
107 # Imports
107 # Imports
108 #-----------------------------------------------------------------------------
108 #-----------------------------------------------------------------------------
109
109
110 import imp
110 import imp
111 import os
111 import os
112 import sys
112 import sys
113 import traceback
113 import traceback
114 import types
114 import types
115 import weakref
115 import weakref
116
116
117 try:
117 try:
118 # Reload is not defined by default in Python3.
118 # Reload is not defined by default in Python3.
119 reload
119 reload
120 except NameError:
120 except NameError:
121 from imp import reload
121 from imp import reload
122
122
123 from IPython.utils import pyfile
123 from IPython.utils import pyfile
124 from IPython.utils.py3compat import PY3
124 from IPython.utils.py3compat import PY3
125
125
126 #------------------------------------------------------------------------------
126 #------------------------------------------------------------------------------
127 # Autoreload functionality
127 # Autoreload functionality
128 #------------------------------------------------------------------------------
128 #------------------------------------------------------------------------------
129
129
130 def _get_compiled_ext():
130 def _get_compiled_ext():
131 """Official way to get the extension of compiled files (.pyc or .pyo)"""
131 """Official way to get the extension of compiled files (.pyc or .pyo)"""
132 for ext, mode, typ in imp.get_suffixes():
132 for ext, mode, typ in imp.get_suffixes():
133 if typ == imp.PY_COMPILED:
133 if typ == imp.PY_COMPILED:
134 return ext
134 return ext
135
135
136
136
137 PY_COMPILED_EXT = _get_compiled_ext()
137 PY_COMPILED_EXT = _get_compiled_ext()
138
138
139
139
140 class ModuleReloader(object):
140 class ModuleReloader(object):
141 enabled = False
141 enabled = False
142 """Whether this reloader is enabled"""
142 """Whether this reloader is enabled"""
143
143
144 failed = {}
144 failed = {}
145 """Modules that failed to reload: {module: mtime-on-failed-reload, ...}"""
145 """Modules that failed to reload: {module: mtime-on-failed-reload, ...}"""
146
146
147 modules = {}
147 modules = {}
148 """Modules specially marked as autoreloadable."""
148 """Modules specially marked as autoreloadable."""
149
149
150 skip_modules = {}
150 skip_modules = {}
151 """Modules specially marked as not autoreloadable."""
151 """Modules specially marked as not autoreloadable."""
152
152
153 check_all = True
153 check_all = True
154 """Autoreload all modules, not just those listed in 'modules'"""
154 """Autoreload all modules, not just those listed in 'modules'"""
155
155
156 old_objects = {}
156 old_objects = {}
157 """(module-name, name) -> weakref, for replacing old code objects"""
157 """(module-name, name) -> weakref, for replacing old code objects"""
158
158
159 def mark_module_skipped(self, module_name):
159 def mark_module_skipped(self, module_name):
160 """Skip reloading the named module in the future"""
160 """Skip reloading the named module in the future"""
161 try:
161 try:
162 del self.modules[module_name]
162 del self.modules[module_name]
163 except KeyError:
163 except KeyError:
164 pass
164 pass
165 self.skip_modules[module_name] = True
165 self.skip_modules[module_name] = True
166
166
167 def mark_module_reloadable(self, module_name):
167 def mark_module_reloadable(self, module_name):
168 """Reload the named module in the future (if it is imported)"""
168 """Reload the named module in the future (if it is imported)"""
169 try:
169 try:
170 del self.skip_modules[module_name]
170 del self.skip_modules[module_name]
171 except KeyError:
171 except KeyError:
172 pass
172 pass
173 self.modules[module_name] = True
173 self.modules[module_name] = True
174
174
175 def aimport_module(self, module_name):
175 def aimport_module(self, module_name):
176 """Import a module, and mark it reloadable
176 """Import a module, and mark it reloadable
177
177
178 Returns
178 Returns
179 -------
179 -------
180 top_module : module
180 top_module : module
181 The imported module if it is top-level, or the top-level
181 The imported module if it is top-level, or the top-level
182 top_name : module
182 top_name : module
183 Name of top_module
183 Name of top_module
184
184
185 """
185 """
186 self.mark_module_reloadable(module_name)
186 self.mark_module_reloadable(module_name)
187
187
188 __import__(module_name)
188 __import__(module_name)
189 top_name = module_name.split('.')[0]
189 top_name = module_name.split('.')[0]
190 top_module = sys.modules[top_name]
190 top_module = sys.modules[top_name]
191 return top_module, top_name
191 return top_module, top_name
192
192
193 def check(self, check_all=False):
193 def check(self, check_all=False):
194 """Check whether some modules need to be reloaded."""
194 """Check whether some modules need to be reloaded."""
195
195
196 if not self.enabled and not check_all:
196 if not self.enabled and not check_all:
197 return
197 return
198
198
199 if check_all or self.check_all:
199 if check_all or self.check_all:
200 modules = sys.modules.keys()
200 modules = sys.modules.keys()
201 else:
201 else:
202 modules = self.modules.keys()
202 modules = self.modules.keys()
203
203
204 for modname in modules:
204 for modname in modules:
205 m = sys.modules.get(modname, None)
205 m = sys.modules.get(modname, None)
206
206
207 if modname in self.skip_modules:
207 if modname in self.skip_modules:
208 continue
208 continue
209
209
210 if not hasattr(m, '__file__'):
210 if not hasattr(m, '__file__'):
211 continue
211 continue
212
212
213 if m.__name__ == '__main__':
213 if m.__name__ == '__main__':
214 # we cannot reload(__main__)
214 # we cannot reload(__main__)
215 continue
215 continue
216
216
217 filename = m.__file__
217 filename = m.__file__
218 path, ext = os.path.splitext(filename)
218 path, ext = os.path.splitext(filename)
219
219
220 if ext.lower() == '.py':
220 if ext.lower() == '.py':
221 ext = PY_COMPILED_EXT
221 ext = PY_COMPILED_EXT
222 pyc_filename = pyfile.cache_from_source(filename)
222 pyc_filename = pyfile.cache_from_source(filename)
223 py_filename = filename
223 py_filename = filename
224 else:
224 else:
225 pyc_filename = filename
225 pyc_filename = filename
226 try:
226 try:
227 py_filename = pyfile.source_from_cache(filename)
227 py_filename = pyfile.source_from_cache(filename)
228 except ValueError:
228 except ValueError:
229 continue
229 continue
230
230
231 try:
231 try:
232 pymtime = os.stat(py_filename).st_mtime
232 pymtime = os.stat(py_filename).st_mtime
233 if pymtime <= os.stat(pyc_filename).st_mtime:
233 if pymtime <= os.stat(pyc_filename).st_mtime:
234 continue
234 continue
235 if self.failed.get(py_filename, None) == pymtime:
235 if self.failed.get(py_filename, None) == pymtime:
236 continue
236 continue
237 except OSError:
237 except OSError:
238 continue
238 continue
239
239
240 try:
240 try:
241 superreload(m, reload, self.old_objects)
241 superreload(m, reload, self.old_objects)
242 if py_filename in self.failed:
242 if py_filename in self.failed:
243 del self.failed[py_filename]
243 del self.failed[py_filename]
244 except:
244 except:
245 print("[autoreload of %s failed: %s]" % (
245 print("[autoreload of %s failed: %s]" % (
246 modname, traceback.format_exc(1)), file=sys.stderr)
246 modname, traceback.format_exc(1)), file=sys.stderr)
247 self.failed[py_filename] = pymtime
247 self.failed[py_filename] = pymtime
248
248
249 #------------------------------------------------------------------------------
249 #------------------------------------------------------------------------------
250 # superreload
250 # superreload
251 #------------------------------------------------------------------------------
251 #------------------------------------------------------------------------------
252
252
253 if PY3:
253 if PY3:
254 func_attrs = ['__code__', '__defaults__', '__doc__',
254 func_attrs = ['__code__', '__defaults__', '__doc__',
255 '__closure__', '__globals__', '__dict__']
255 '__closure__', '__globals__', '__dict__']
256 else:
256 else:
257 func_attrs = ['func_code', 'func_defaults', 'func_doc',
257 func_attrs = ['func_code', 'func_defaults', 'func_doc',
258 'func_closure', 'func_globals', 'func_dict']
258 'func_closure', 'func_globals', 'func_dict']
259
259
260
260
261 def update_function(old, new):
261 def update_function(old, new):
262 """Upgrade the code object of a function"""
262 """Upgrade the code object of a function"""
263 for name in func_attrs:
263 for name in func_attrs:
264 try:
264 try:
265 setattr(old, name, getattr(new, name))
265 setattr(old, name, getattr(new, name))
266 except (AttributeError, TypeError):
266 except (AttributeError, TypeError):
267 pass
267 pass
268
268
269
269
270 def update_class(old, new):
270 def update_class(old, new):
271 """Replace stuff in the __dict__ of a class, and upgrade
271 """Replace stuff in the __dict__ of a class, and upgrade
272 method code objects"""
272 method code objects"""
273 for key in old.__dict__.keys():
273 for key in old.__dict__.keys():
274 old_obj = getattr(old, key)
274 old_obj = getattr(old, key)
275
275
276 try:
276 try:
277 new_obj = getattr(new, key)
277 new_obj = getattr(new, key)
278 except AttributeError:
278 except AttributeError:
279 # obsolete attribute: remove it
279 # obsolete attribute: remove it
280 try:
280 try:
281 delattr(old, key)
281 delattr(old, key)
282 except (AttributeError, TypeError):
282 except (AttributeError, TypeError):
283 pass
283 pass
284 continue
284 continue
285
285
286 if update_generic(old_obj, new_obj): continue
286 if update_generic(old_obj, new_obj): continue
287
287
288 try:
288 try:
289 setattr(old, key, getattr(new, key))
289 setattr(old, key, getattr(new, key))
290 except (AttributeError, TypeError):
290 except (AttributeError, TypeError):
291 pass # skip non-writable attributes
291 pass # skip non-writable attributes
292
292
293
293
294 def update_property(old, new):
294 def update_property(old, new):
295 """Replace get/set/del functions of a property"""
295 """Replace get/set/del functions of a property"""
296 update_generic(old.fdel, new.fdel)
296 update_generic(old.fdel, new.fdel)
297 update_generic(old.fget, new.fget)
297 update_generic(old.fget, new.fget)
298 update_generic(old.fset, new.fset)
298 update_generic(old.fset, new.fset)
299
299
300
300
301 def isinstance2(a, b, typ):
301 def isinstance2(a, b, typ):
302 return isinstance(a, typ) and isinstance(b, typ)
302 return isinstance(a, typ) and isinstance(b, typ)
303
303
304
304
305 UPDATE_RULES = [
305 UPDATE_RULES = [
306 (lambda a, b: isinstance2(a, b, type),
306 (lambda a, b: isinstance2(a, b, type),
307 update_class),
307 update_class),
308 (lambda a, b: isinstance2(a, b, types.FunctionType),
308 (lambda a, b: isinstance2(a, b, types.FunctionType),
309 update_function),
309 update_function),
310 (lambda a, b: isinstance2(a, b, property),
310 (lambda a, b: isinstance2(a, b, property),
311 update_property),
311 update_property),
312 ]
312 ]
313
313
314
314
315 if PY3:
315 if PY3:
316 UPDATE_RULES.extend([(lambda a, b: isinstance2(a, b, types.MethodType),
316 UPDATE_RULES.extend([(lambda a, b: isinstance2(a, b, types.MethodType),
317 lambda a, b: update_function(a.__func__, b.__func__)),
317 lambda a, b: update_function(a.__func__, b.__func__)),
318 ])
318 ])
319 else:
319 else:
320 UPDATE_RULES.extend([(lambda a, b: isinstance2(a, b, types.ClassType),
320 UPDATE_RULES.extend([(lambda a, b: isinstance2(a, b, types.ClassType),
321 update_class),
321 update_class),
322 (lambda a, b: isinstance2(a, b, types.MethodType),
322 (lambda a, b: isinstance2(a, b, types.MethodType),
323 lambda a, b: update_function(a.im_func, b.im_func)),
323 lambda a, b: update_function(a.im_func, b.im_func)),
324 ])
324 ])
325
325
326
326
327 def update_generic(a, b):
327 def update_generic(a, b):
328 for type_check, update in UPDATE_RULES:
328 for type_check, update in UPDATE_RULES:
329 if type_check(a, b):
329 if type_check(a, b):
330 update(a, b)
330 update(a, b)
331 return True
331 return True
332 return False
332 return False
333
333
334
334
335 class StrongRef(object):
335 class StrongRef(object):
336 def __init__(self, obj):
336 def __init__(self, obj):
337 self.obj = obj
337 self.obj = obj
338 def __call__(self):
338 def __call__(self):
339 return self.obj
339 return self.obj
340
340
341
341
342 def superreload(module, reload=reload, old_objects={}):
342 def superreload(module, reload=reload, old_objects={}):
343 """Enhanced version of the builtin reload function.
343 """Enhanced version of the builtin reload function.
344
344
345 superreload remembers objects previously in the module, and
345 superreload remembers objects previously in the module, and
346
346
347 - upgrades the class dictionary of every old class in the module
347 - upgrades the class dictionary of every old class in the module
348 - upgrades the code object of every old function and method
348 - upgrades the code object of every old function and method
349 - clears the module's namespace before reloading
349 - clears the module's namespace before reloading
350
350
351 """
351 """
352
352
353 # collect old objects in the module
353 # collect old objects in the module
354 for name, obj in module.__dict__.items():
354 for name, obj in module.__dict__.items():
355 if not hasattr(obj, '__module__') or obj.__module__ != module.__name__:
355 if not hasattr(obj, '__module__') or obj.__module__ != module.__name__:
356 continue
356 continue
357 key = (module.__name__, name)
357 key = (module.__name__, name)
358 try:
358 try:
359 old_objects.setdefault(key, []).append(weakref.ref(obj))
359 old_objects.setdefault(key, []).append(weakref.ref(obj))
360 except TypeError:
360 except TypeError:
361 # weakref doesn't work for all types;
361 # weakref doesn't work for all types;
362 # create strong references for 'important' cases
362 # create strong references for 'important' cases
363 if not PY3 and isinstance(obj, types.ClassType):
363 if not PY3 and isinstance(obj, types.ClassType):
364 old_objects.setdefault(key, []).append(StrongRef(obj))
364 old_objects.setdefault(key, []).append(StrongRef(obj))
365
365
366 # reload module
366 # reload module
367 try:
367 try:
368 # clear namespace first from old cruft
368 # clear namespace first from old cruft
369 old_dict = module.__dict__.copy()
369 old_dict = module.__dict__.copy()
370 old_name = module.__name__
370 old_name = module.__name__
371 module.__dict__.clear()
371 module.__dict__.clear()
372 module.__dict__['__name__'] = old_name
372 module.__dict__['__name__'] = old_name
373 module.__dict__['__loader__'] = old_dict['__loader__']
373 module.__dict__['__loader__'] = old_dict['__loader__']
374 except (TypeError, AttributeError, KeyError):
374 except (TypeError, AttributeError, KeyError):
375 pass
375 pass
376
376
377 try:
377 try:
378 module = reload(module)
378 module = reload(module)
379 except:
379 except:
380 # restore module dictionary on failed reload
380 # restore module dictionary on failed reload
381 module.__dict__.update(old_dict)
381 module.__dict__.update(old_dict)
382 raise
382 raise
383
383
384 # iterate over all objects and update functions & classes
384 # iterate over all objects and update functions & classes
385 for name, new_obj in module.__dict__.items():
385 for name, new_obj in module.__dict__.items():
386 key = (module.__name__, name)
386 key = (module.__name__, name)
387 if key not in old_objects: continue
387 if key not in old_objects: continue
388
388
389 new_refs = []
389 new_refs = []
390 for old_ref in old_objects[key]:
390 for old_ref in old_objects[key]:
391 old_obj = old_ref()
391 old_obj = old_ref()
392 if old_obj is None: continue
392 if old_obj is None: continue
393 new_refs.append(old_ref)
393 new_refs.append(old_ref)
394 update_generic(old_obj, new_obj)
394 update_generic(old_obj, new_obj)
395
395
396 if new_refs:
396 if new_refs:
397 old_objects[key] = new_refs
397 old_objects[key] = new_refs
398 else:
398 else:
399 del old_objects[key]
399 del old_objects[key]
400
400
401 return module
401 return module
402
402
403 #------------------------------------------------------------------------------
403 #------------------------------------------------------------------------------
404 # IPython connectivity
404 # IPython connectivity
405 #------------------------------------------------------------------------------
405 #------------------------------------------------------------------------------
406
406
407 from IPython.core.hooks import TryNext
407 from IPython.core.hooks import TryNext
408 from IPython.core.magic import Magics, magics_class, line_magic
408 from IPython.core.magic import Magics, magics_class, line_magic
409
409
410 @magics_class
410 @magics_class
411 class AutoreloadMagics(Magics):
411 class AutoreloadMagics(Magics):
412 def __init__(self, *a, **kw):
412 def __init__(self, *a, **kw):
413 super(AutoreloadMagics, self).__init__(*a, **kw)
413 super(AutoreloadMagics, self).__init__(*a, **kw)
414 self._reloader = ModuleReloader()
414 self._reloader = ModuleReloader()
415 self._reloader.check_all = False
415 self._reloader.check_all = False
416
416
417 @line_magic
417 @line_magic
418 def autoreload(self, parameter_s=''):
418 def autoreload(self, parameter_s=''):
419 r"""%autoreload => Reload modules automatically
419 r"""%autoreload => Reload modules automatically
420
420
421 %autoreload
421 %autoreload
422 Reload all modules (except those excluded by %aimport) automatically
422 Reload all modules (except those excluded by %aimport) automatically
423 now.
423 now.
424
424
425 %autoreload 0
425 %autoreload 0
426 Disable automatic reloading.
426 Disable automatic reloading.
427
427
428 %autoreload 1
428 %autoreload 1
429 Reload all modules imported with %aimport every time before executing
429 Reload all modules imported with %aimport every time before executing
430 the Python code typed.
430 the Python code typed.
431
431
432 %autoreload 2
432 %autoreload 2
433 Reload all modules (except those excluded by %aimport) every time
433 Reload all modules (except those excluded by %aimport) every time
434 before executing the Python code typed.
434 before executing the Python code typed.
435
435
436 Reloading Python modules in a reliable way is in general
436 Reloading Python modules in a reliable way is in general
437 difficult, and unexpected things may occur. %autoreload tries to
437 difficult, and unexpected things may occur. %autoreload tries to
438 work around common pitfalls by replacing function code objects and
438 work around common pitfalls by replacing function code objects and
439 parts of classes previously in the module with new versions. This
439 parts of classes previously in the module with new versions. This
440 makes the following things to work:
440 makes the following things to work:
441
441
442 - Functions and classes imported via 'from xxx import foo' are upgraded
442 - Functions and classes imported via 'from xxx import foo' are upgraded
443 to new versions when 'xxx' is reloaded.
443 to new versions when 'xxx' is reloaded.
444
444
445 - Methods and properties of classes are upgraded on reload, so that
445 - Methods and properties of classes are upgraded on reload, so that
446 calling 'c.foo()' on an object 'c' created before the reload causes
446 calling 'c.foo()' on an object 'c' created before the reload causes
447 the new code for 'foo' to be executed.
447 the new code for 'foo' to be executed.
448
448
449 Some of the known remaining caveats are:
449 Some of the known remaining caveats are:
450
450
451 - Replacing code objects does not always succeed: changing a @property
451 - Replacing code objects does not always succeed: changing a @property
452 in a class to an ordinary method or a method to a member variable
452 in a class to an ordinary method or a method to a member variable
453 can cause problems (but in old objects only).
453 can cause problems (but in old objects only).
454
454
455 - Functions that are removed (eg. via monkey-patching) from a module
455 - Functions that are removed (eg. via monkey-patching) from a module
456 before it is reloaded are not upgraded.
456 before it is reloaded are not upgraded.
457
457
458 - C extension modules cannot be reloaded, and so cannot be
458 - C extension modules cannot be reloaded, and so cannot be
459 autoreloaded.
459 autoreloaded.
460
460
461 """
461 """
462 if parameter_s == '':
462 if parameter_s == '':
463 self._reloader.check(True)
463 self._reloader.check(True)
464 elif parameter_s == '0':
464 elif parameter_s == '0':
465 self._reloader.enabled = False
465 self._reloader.enabled = False
466 elif parameter_s == '1':
466 elif parameter_s == '1':
467 self._reloader.check_all = False
467 self._reloader.check_all = False
468 self._reloader.enabled = True
468 self._reloader.enabled = True
469 elif parameter_s == '2':
469 elif parameter_s == '2':
470 self._reloader.check_all = True
470 self._reloader.check_all = True
471 self._reloader.enabled = True
471 self._reloader.enabled = True
472
472
473 @line_magic
473 @line_magic
474 def aimport(self, parameter_s='', stream=None):
474 def aimport(self, parameter_s='', stream=None):
475 """%aimport => Import modules for automatic reloading.
475 """%aimport => Import modules for automatic reloading.
476
476
477 %aimport
477 %aimport
478 List modules to automatically import and not to import.
478 List modules to automatically import and not to import.
479
479
480 %aimport foo
480 %aimport foo
481 Import module 'foo' and mark it to be autoreloaded for %autoreload 1
481 Import module 'foo' and mark it to be autoreloaded for %autoreload 1
482
482
483 %aimport -foo
483 %aimport -foo
484 Mark module 'foo' to not be autoreloaded for %autoreload 1
484 Mark module 'foo' to not be autoreloaded for %autoreload 1
485 """
485 """
486 modname = parameter_s
486 modname = parameter_s
487 if not modname:
487 if not modname:
488 to_reload = self._reloader.modules.keys()
488 to_reload = self._reloader.modules.keys()
489 to_reload.sort()
489 to_reload.sort()
490 to_skip = self._reloader.skip_modules.keys()
490 to_skip = self._reloader.skip_modules.keys()
491 to_skip.sort()
491 to_skip.sort()
492 if stream is None:
492 if stream is None:
493 stream = sys.stdout
493 stream = sys.stdout
494 if self._reloader.check_all:
494 if self._reloader.check_all:
495 stream.write("Modules to reload:\nall-except-skipped\n")
495 stream.write("Modules to reload:\nall-except-skipped\n")
496 else:
496 else:
497 stream.write("Modules to reload:\n%s\n" % ' '.join(to_reload))
497 stream.write("Modules to reload:\n%s\n" % ' '.join(to_reload))
498 stream.write("\nModules to skip:\n%s\n" % ' '.join(to_skip))
498 stream.write("\nModules to skip:\n%s\n" % ' '.join(to_skip))
499 elif modname.startswith('-'):
499 elif modname.startswith('-'):
500 modname = modname[1:]
500 modname = modname[1:]
501 self._reloader.mark_module_skipped(modname)
501 self._reloader.mark_module_skipped(modname)
502 else:
502 else:
503 top_module, top_name = self._reloader.aimport_module(modname)
503 top_module, top_name = self._reloader.aimport_module(modname)
504
504
505 # Inject module to user namespace
505 # Inject module to user namespace
506 self.shell.push({top_name: top_module})
506 self.shell.push({top_name: top_module})
507
507
508 def pre_run_code_hook(self, ip):
508 def pre_run_code_hook(self, ip):
509 if not self._reloader.enabled:
509 if not self._reloader.enabled:
510 raise TryNext
510 raise TryNext
511 try:
511 try:
512 self._reloader.check()
512 self._reloader.check()
513 except:
513 except:
514 pass
514 pass
515
515
516
516
517 _loaded = False
518
519
520 def load_ipython_extension(ip):
517 def load_ipython_extension(ip):
521 """Load the extension in IPython."""
518 """Load the extension in IPython."""
522 global _loaded
519 auto_reload = AutoreloadMagics(ip)
523 if not _loaded:
520 ip.register_magics(auto_reload)
524 auto_reload = AutoreloadMagics(ip)
521 ip.set_hook('pre_run_code_hook', auto_reload.pre_run_code_hook)
525 ip.register_magics(auto_reload)
526 ip.set_hook('pre_run_code_hook', auto_reload.pre_run_code_hook)
527 _loaded = True
@@ -1,283 +1,279 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Cython related magics.
3 Cython related magics.
4
4
5 Author:
5 Author:
6 * Brian Granger
6 * Brian Granger
7
7
8 Parts of this code were taken from Cython.inline.
8 Parts of this code were taken from Cython.inline.
9 """
9 """
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2010-2011, IPython Development Team.
11 # Copyright (C) 2010-2011, IPython Development Team.
12 #
12 #
13 # Distributed under the terms of the Modified BSD License.
13 # Distributed under the terms of the Modified BSD License.
14 #
14 #
15 # The full license is in the file COPYING.txt, distributed with this software.
15 # The full license is in the file COPYING.txt, distributed with this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 from __future__ import print_function
18 from __future__ import print_function
19
19
20 import imp
20 import imp
21 import io
21 import io
22 import os
22 import os
23 import re
23 import re
24 import sys
24 import sys
25 import time
25 import time
26
26
27 try:
27 try:
28 import hashlib
28 import hashlib
29 except ImportError:
29 except ImportError:
30 import md5 as hashlib
30 import md5 as hashlib
31
31
32 from distutils.core import Distribution, Extension
32 from distutils.core import Distribution, Extension
33 from distutils.command.build_ext import build_ext
33 from distutils.command.build_ext import build_ext
34
34
35 from IPython.core import display
35 from IPython.core import display
36 from IPython.core import magic_arguments
36 from IPython.core import magic_arguments
37 from IPython.core.magic import Magics, magics_class, cell_magic
37 from IPython.core.magic import Magics, magics_class, cell_magic
38 from IPython.testing.skipdoctest import skip_doctest
38 from IPython.testing.skipdoctest import skip_doctest
39 from IPython.utils import py3compat
39 from IPython.utils import py3compat
40
40
41 import Cython
41 import Cython
42 from Cython.Compiler.Errors import CompileError
42 from Cython.Compiler.Errors import CompileError
43 from Cython.Build.Dependencies import cythonize
43 from Cython.Build.Dependencies import cythonize
44
44
45
45
46 @magics_class
46 @magics_class
47 class CythonMagics(Magics):
47 class CythonMagics(Magics):
48
48
49 def __init__(self, shell):
49 def __init__(self, shell):
50 super(CythonMagics,self).__init__(shell)
50 super(CythonMagics,self).__init__(shell)
51 self._reloads = {}
51 self._reloads = {}
52 self._code_cache = {}
52 self._code_cache = {}
53
53
54 def _import_all(self, module):
54 def _import_all(self, module):
55 for k,v in module.__dict__.items():
55 for k,v in module.__dict__.items():
56 if not k.startswith('__'):
56 if not k.startswith('__'):
57 self.shell.push({k:v})
57 self.shell.push({k:v})
58
58
59 @cell_magic
59 @cell_magic
60 def cython_inline(self, line, cell):
60 def cython_inline(self, line, cell):
61 """Compile and run a Cython code cell using Cython.inline.
61 """Compile and run a Cython code cell using Cython.inline.
62
62
63 This magic simply passes the body of the cell to Cython.inline
63 This magic simply passes the body of the cell to Cython.inline
64 and returns the result. If the variables `a` and `b` are defined
64 and returns the result. If the variables `a` and `b` are defined
65 in the user's namespace, here is a simple example that returns
65 in the user's namespace, here is a simple example that returns
66 their sum::
66 their sum::
67
67
68 %%cython_inline
68 %%cython_inline
69 return a+b
69 return a+b
70
70
71 For most purposes, we recommend the usage of the `%%cython` magic.
71 For most purposes, we recommend the usage of the `%%cython` magic.
72 """
72 """
73 locs = self.shell.user_global_ns
73 locs = self.shell.user_global_ns
74 globs = self.shell.user_ns
74 globs = self.shell.user_ns
75 return Cython.inline(cell, locals=locs, globals=globs)
75 return Cython.inline(cell, locals=locs, globals=globs)
76
76
77 @cell_magic
77 @cell_magic
78 def cython_pyximport(self, line, cell):
78 def cython_pyximport(self, line, cell):
79 """Compile and import a Cython code cell using pyximport.
79 """Compile and import a Cython code cell using pyximport.
80
80
81 The contents of the cell are written to a `.pyx` file in the current
81 The contents of the cell are written to a `.pyx` file in the current
82 working directory, which is then imported using `pyximport`. This
82 working directory, which is then imported using `pyximport`. This
83 magic requires a module name to be passed::
83 magic requires a module name to be passed::
84
84
85 %%cython_pyximport modulename
85 %%cython_pyximport modulename
86 def f(x):
86 def f(x):
87 return 2.0*x
87 return 2.0*x
88
88
89 The compiled module is then imported and all of its symbols are
89 The compiled module is then imported and all of its symbols are
90 injected into the user's namespace. For most purposes, we recommend
90 injected into the user's namespace. For most purposes, we recommend
91 the usage of the `%%cython` magic.
91 the usage of the `%%cython` magic.
92 """
92 """
93 module_name = line.strip()
93 module_name = line.strip()
94 if not module_name:
94 if not module_name:
95 raise ValueError('module name must be given')
95 raise ValueError('module name must be given')
96 fname = module_name + '.pyx'
96 fname = module_name + '.pyx'
97 with io.open(fname, 'w', encoding='utf-8') as f:
97 with io.open(fname, 'w', encoding='utf-8') as f:
98 f.write(cell)
98 f.write(cell)
99 if 'pyximport' not in sys.modules:
99 if 'pyximport' not in sys.modules:
100 import pyximport
100 import pyximport
101 pyximport.install(reload_support=True)
101 pyximport.install(reload_support=True)
102 if module_name in self._reloads:
102 if module_name in self._reloads:
103 module = self._reloads[module_name]
103 module = self._reloads[module_name]
104 reload(module)
104 reload(module)
105 else:
105 else:
106 __import__(module_name)
106 __import__(module_name)
107 module = sys.modules[module_name]
107 module = sys.modules[module_name]
108 self._reloads[module_name] = module
108 self._reloads[module_name] = module
109 self._import_all(module)
109 self._import_all(module)
110
110
111 @magic_arguments.magic_arguments()
111 @magic_arguments.magic_arguments()
112 @magic_arguments.argument(
112 @magic_arguments.argument(
113 '-c', '--compile-args', action='append', default=[],
113 '-c', '--compile-args', action='append', default=[],
114 help="Extra flags to pass to compiler via the `extra_compile_args` "
114 help="Extra flags to pass to compiler via the `extra_compile_args` "
115 "Extension flag (can be specified multiple times)."
115 "Extension flag (can be specified multiple times)."
116 )
116 )
117 @magic_arguments.argument(
117 @magic_arguments.argument(
118 '-la', '--link-args', action='append', default=[],
118 '-la', '--link-args', action='append', default=[],
119 help="Extra flags to pass to linker via the `extra_link_args` "
119 help="Extra flags to pass to linker via the `extra_link_args` "
120 "Extension flag (can be specified multiple times)."
120 "Extension flag (can be specified multiple times)."
121 )
121 )
122 @magic_arguments.argument(
122 @magic_arguments.argument(
123 '-l', '--lib', action='append', default=[],
123 '-l', '--lib', action='append', default=[],
124 help="Add a library to link the extension against (can be specified "
124 help="Add a library to link the extension against (can be specified "
125 "multiple times)."
125 "multiple times)."
126 )
126 )
127 @magic_arguments.argument(
127 @magic_arguments.argument(
128 '-L', dest='library_dirs', metavar='dir', action='append', default=[],
128 '-L', dest='library_dirs', metavar='dir', action='append', default=[],
129 help="Add a path to the list of libary directories (can be specified "
129 help="Add a path to the list of libary directories (can be specified "
130 "multiple times)."
130 "multiple times)."
131 )
131 )
132 @magic_arguments.argument(
132 @magic_arguments.argument(
133 '-I', '--include', action='append', default=[],
133 '-I', '--include', action='append', default=[],
134 help="Add a path to the list of include directories (can be specified "
134 help="Add a path to the list of include directories (can be specified "
135 "multiple times)."
135 "multiple times)."
136 )
136 )
137 @magic_arguments.argument(
137 @magic_arguments.argument(
138 '-+', '--cplus', action='store_true', default=False,
138 '-+', '--cplus', action='store_true', default=False,
139 help="Output a C++ rather than C file."
139 help="Output a C++ rather than C file."
140 )
140 )
141 @magic_arguments.argument(
141 @magic_arguments.argument(
142 '-f', '--force', action='store_true', default=False,
142 '-f', '--force', action='store_true', default=False,
143 help="Force the compilation of a new module, even if the source has been "
143 help="Force the compilation of a new module, even if the source has been "
144 "previously compiled."
144 "previously compiled."
145 )
145 )
146 @magic_arguments.argument(
146 @magic_arguments.argument(
147 '-a', '--annotate', action='store_true', default=False,
147 '-a', '--annotate', action='store_true', default=False,
148 help="Produce a colorized HTML version of the source."
148 help="Produce a colorized HTML version of the source."
149 )
149 )
150 @cell_magic
150 @cell_magic
151 def cython(self, line, cell):
151 def cython(self, line, cell):
152 """Compile and import everything from a Cython code cell.
152 """Compile and import everything from a Cython code cell.
153
153
154 The contents of the cell are written to a `.pyx` file in the
154 The contents of the cell are written to a `.pyx` file in the
155 directory `IPYTHONDIR/cython` using a filename with the hash of the
155 directory `IPYTHONDIR/cython` using a filename with the hash of the
156 code. This file is then cythonized and compiled. The resulting module
156 code. This file is then cythonized and compiled. The resulting module
157 is imported and all of its symbols are injected into the user's
157 is imported and all of its symbols are injected into the user's
158 namespace. The usage is similar to that of `%%cython_pyximport` but
158 namespace. The usage is similar to that of `%%cython_pyximport` but
159 you don't have to pass a module name::
159 you don't have to pass a module name::
160
160
161 %%cython
161 %%cython
162 def f(x):
162 def f(x):
163 return 2.0*x
163 return 2.0*x
164 """
164 """
165 args = magic_arguments.parse_argstring(self.cython, line)
165 args = magic_arguments.parse_argstring(self.cython, line)
166 code = cell if cell.endswith('\n') else cell+'\n'
166 code = cell if cell.endswith('\n') else cell+'\n'
167 lib_dir = os.path.join(self.shell.ipython_dir, 'cython')
167 lib_dir = os.path.join(self.shell.ipython_dir, 'cython')
168 quiet = True
168 quiet = True
169 key = code, sys.version_info, sys.executable, Cython.__version__
169 key = code, sys.version_info, sys.executable, Cython.__version__
170
170
171 if not os.path.exists(lib_dir):
171 if not os.path.exists(lib_dir):
172 os.makedirs(lib_dir)
172 os.makedirs(lib_dir)
173
173
174 if args.force:
174 if args.force:
175 # Force a new module name by adding the current time to the
175 # Force a new module name by adding the current time to the
176 # key which is hashed to determine the module name.
176 # key which is hashed to determine the module name.
177 key += time.time(),
177 key += time.time(),
178
178
179 module_name = "_cython_magic_" + hashlib.md5(str(key).encode('utf-8')).hexdigest()
179 module_name = "_cython_magic_" + hashlib.md5(str(key).encode('utf-8')).hexdigest()
180 module_path = os.path.join(lib_dir, module_name + self.so_ext)
180 module_path = os.path.join(lib_dir, module_name + self.so_ext)
181
181
182 have_module = os.path.isfile(module_path)
182 have_module = os.path.isfile(module_path)
183 need_cythonize = not have_module
183 need_cythonize = not have_module
184
184
185 if args.annotate:
185 if args.annotate:
186 html_file = os.path.join(lib_dir, module_name + '.html')
186 html_file = os.path.join(lib_dir, module_name + '.html')
187 if not os.path.isfile(html_file):
187 if not os.path.isfile(html_file):
188 need_cythonize = True
188 need_cythonize = True
189
189
190 if need_cythonize:
190 if need_cythonize:
191 c_include_dirs = args.include
191 c_include_dirs = args.include
192 if 'numpy' in code:
192 if 'numpy' in code:
193 import numpy
193 import numpy
194 c_include_dirs.append(numpy.get_include())
194 c_include_dirs.append(numpy.get_include())
195 pyx_file = os.path.join(lib_dir, module_name + '.pyx')
195 pyx_file = os.path.join(lib_dir, module_name + '.pyx')
196 pyx_file = py3compat.cast_bytes_py2(pyx_file, encoding=sys.getfilesystemencoding())
196 pyx_file = py3compat.cast_bytes_py2(pyx_file, encoding=sys.getfilesystemencoding())
197 with io.open(pyx_file, 'w', encoding='utf-8') as f:
197 with io.open(pyx_file, 'w', encoding='utf-8') as f:
198 f.write(code)
198 f.write(code)
199 extension = Extension(
199 extension = Extension(
200 name = module_name,
200 name = module_name,
201 sources = [pyx_file],
201 sources = [pyx_file],
202 include_dirs = c_include_dirs,
202 include_dirs = c_include_dirs,
203 library_dirs = args.library_dirs,
203 library_dirs = args.library_dirs,
204 extra_compile_args = args.compile_args,
204 extra_compile_args = args.compile_args,
205 extra_link_args = args.link_args,
205 extra_link_args = args.link_args,
206 libraries = args.lib,
206 libraries = args.lib,
207 language = 'c++' if args.cplus else 'c',
207 language = 'c++' if args.cplus else 'c',
208 )
208 )
209 build_extension = self._get_build_extension()
209 build_extension = self._get_build_extension()
210 try:
210 try:
211 opts = dict(
211 opts = dict(
212 quiet=quiet,
212 quiet=quiet,
213 annotate = args.annotate,
213 annotate = args.annotate,
214 force = True,
214 force = True,
215 )
215 )
216 build_extension.extensions = cythonize([extension], **opts)
216 build_extension.extensions = cythonize([extension], **opts)
217 except CompileError:
217 except CompileError:
218 return
218 return
219
219
220 if not have_module:
220 if not have_module:
221 build_extension.build_temp = os.path.dirname(pyx_file)
221 build_extension.build_temp = os.path.dirname(pyx_file)
222 build_extension.build_lib = lib_dir
222 build_extension.build_lib = lib_dir
223 build_extension.run()
223 build_extension.run()
224 self._code_cache[key] = module_name
224 self._code_cache[key] = module_name
225
225
226 module = imp.load_dynamic(module_name, module_path)
226 module = imp.load_dynamic(module_name, module_path)
227 self._import_all(module)
227 self._import_all(module)
228
228
229 if args.annotate:
229 if args.annotate:
230 try:
230 try:
231 with io.open(html_file, encoding='utf-8') as f:
231 with io.open(html_file, encoding='utf-8') as f:
232 annotated_html = f.read()
232 annotated_html = f.read()
233 except IOError as e:
233 except IOError as e:
234 # File could not be opened. Most likely the user has a version
234 # File could not be opened. Most likely the user has a version
235 # of Cython before 0.15.1 (when `cythonize` learned the
235 # of Cython before 0.15.1 (when `cythonize` learned the
236 # `force` keyword argument) and has already compiled this
236 # `force` keyword argument) and has already compiled this
237 # exact source without annotation.
237 # exact source without annotation.
238 print('Cython completed successfully but the annotated '
238 print('Cython completed successfully but the annotated '
239 'source could not be read.', file=sys.stderr)
239 'source could not be read.', file=sys.stderr)
240 print(e, file=sys.stderr)
240 print(e, file=sys.stderr)
241 else:
241 else:
242 return display.HTML(self.clean_annotated_html(annotated_html))
242 return display.HTML(self.clean_annotated_html(annotated_html))
243
243
244 @property
244 @property
245 def so_ext(self):
245 def so_ext(self):
246 """The extension suffix for compiled modules."""
246 """The extension suffix for compiled modules."""
247 try:
247 try:
248 return self._so_ext
248 return self._so_ext
249 except AttributeError:
249 except AttributeError:
250 self._so_ext = self._get_build_extension().get_ext_filename('')
250 self._so_ext = self._get_build_extension().get_ext_filename('')
251 return self._so_ext
251 return self._so_ext
252
252
253 def _get_build_extension(self):
253 def _get_build_extension(self):
254 dist = Distribution()
254 dist = Distribution()
255 config_files = dist.find_config_files()
255 config_files = dist.find_config_files()
256 try:
256 try:
257 config_files.remove('setup.cfg')
257 config_files.remove('setup.cfg')
258 except ValueError:
258 except ValueError:
259 pass
259 pass
260 dist.parse_config_files(config_files)
260 dist.parse_config_files(config_files)
261 build_extension = build_ext(dist)
261 build_extension = build_ext(dist)
262 build_extension.finalize_options()
262 build_extension.finalize_options()
263 return build_extension
263 return build_extension
264
264
265 @staticmethod
265 @staticmethod
266 def clean_annotated_html(html):
266 def clean_annotated_html(html):
267 """Clean up the annotated HTML source.
267 """Clean up the annotated HTML source.
268
268
269 Strips the link to the generated C or C++ file, which we do not
269 Strips the link to the generated C or C++ file, which we do not
270 present to the user.
270 present to the user.
271 """
271 """
272 r = re.compile('<p>Raw output: <a href="(.*)">(.*)</a>')
272 r = re.compile('<p>Raw output: <a href="(.*)">(.*)</a>')
273 html = '\n'.join(l for l in html.splitlines() if not r.match(l))
273 html = '\n'.join(l for l in html.splitlines() if not r.match(l))
274 return html
274 return html
275
275
276 _loaded = False
277
276
278 def load_ipython_extension(ip):
277 def load_ipython_extension(ip):
279 """Load the extension in IPython."""
278 """Load the extension in IPython."""
280 global _loaded
279 ip.register_magics(CythonMagics)
281 if not _loaded:
282 ip.register_magics(CythonMagics)
283 _loaded = True
@@ -1,371 +1,367 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 ===========
3 ===========
4 octavemagic
4 octavemagic
5 ===========
5 ===========
6
6
7 Magics for interacting with Octave via oct2py.
7 Magics for interacting with Octave via oct2py.
8
8
9 .. note::
9 .. note::
10
10
11 The ``oct2py`` module needs to be installed separately and
11 The ``oct2py`` module needs to be installed separately and
12 can be obtained using ``easy_install`` or ``pip``.
12 can be obtained using ``easy_install`` or ``pip``.
13
13
14 Usage
14 Usage
15 =====
15 =====
16
16
17 ``%octave``
17 ``%octave``
18
18
19 {OCTAVE_DOC}
19 {OCTAVE_DOC}
20
20
21 ``%octave_push``
21 ``%octave_push``
22
22
23 {OCTAVE_PUSH_DOC}
23 {OCTAVE_PUSH_DOC}
24
24
25 ``%octave_pull``
25 ``%octave_pull``
26
26
27 {OCTAVE_PULL_DOC}
27 {OCTAVE_PULL_DOC}
28
28
29 """
29 """
30
30
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32 # Copyright (C) 2012 The IPython Development Team
32 # Copyright (C) 2012 The IPython Development Team
33 #
33 #
34 # Distributed under the terms of the BSD License. The full license is in
34 # Distributed under the terms of the BSD License. The full license is in
35 # the file COPYING, distributed as part of this software.
35 # the file COPYING, distributed as part of this software.
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38 import tempfile
38 import tempfile
39 from glob import glob
39 from glob import glob
40 from shutil import rmtree
40 from shutil import rmtree
41
41
42 import numpy as np
42 import numpy as np
43 import oct2py
43 import oct2py
44 from xml.dom import minidom
44 from xml.dom import minidom
45
45
46 from IPython.core.displaypub import publish_display_data
46 from IPython.core.displaypub import publish_display_data
47 from IPython.core.magic import (Magics, magics_class, line_magic,
47 from IPython.core.magic import (Magics, magics_class, line_magic,
48 line_cell_magic, needs_local_scope)
48 line_cell_magic, needs_local_scope)
49 from IPython.testing.skipdoctest import skip_doctest
49 from IPython.testing.skipdoctest import skip_doctest
50 from IPython.core.magic_arguments import (
50 from IPython.core.magic_arguments import (
51 argument, magic_arguments, parse_argstring
51 argument, magic_arguments, parse_argstring
52 )
52 )
53 from IPython.utils.py3compat import unicode_to_str
53 from IPython.utils.py3compat import unicode_to_str
54
54
55 class OctaveMagicError(oct2py.Oct2PyError):
55 class OctaveMagicError(oct2py.Oct2PyError):
56 pass
56 pass
57
57
58 _mimetypes = {'png' : 'image/png',
58 _mimetypes = {'png' : 'image/png',
59 'svg' : 'image/svg+xml',
59 'svg' : 'image/svg+xml',
60 'jpg' : 'image/jpeg',
60 'jpg' : 'image/jpeg',
61 'jpeg': 'image/jpeg'}
61 'jpeg': 'image/jpeg'}
62
62
63 @magics_class
63 @magics_class
64 class OctaveMagics(Magics):
64 class OctaveMagics(Magics):
65 """A set of magics useful for interactive work with Octave via oct2py.
65 """A set of magics useful for interactive work with Octave via oct2py.
66 """
66 """
67 def __init__(self, shell):
67 def __init__(self, shell):
68 """
68 """
69 Parameters
69 Parameters
70 ----------
70 ----------
71 shell : IPython shell
71 shell : IPython shell
72
72
73 """
73 """
74 super(OctaveMagics, self).__init__(shell)
74 super(OctaveMagics, self).__init__(shell)
75 self._oct = oct2py.Oct2Py()
75 self._oct = oct2py.Oct2Py()
76 self._plot_format = 'png'
76 self._plot_format = 'png'
77
77
78 # Allow publish_display_data to be overridden for
78 # Allow publish_display_data to be overridden for
79 # testing purposes.
79 # testing purposes.
80 self._publish_display_data = publish_display_data
80 self._publish_display_data = publish_display_data
81
81
82
82
83 def _fix_gnuplot_svg_size(self, image, size=None):
83 def _fix_gnuplot_svg_size(self, image, size=None):
84 """
84 """
85 GnuPlot SVGs do not have height/width attributes. Set
85 GnuPlot SVGs do not have height/width attributes. Set
86 these to be the same as the viewBox, so that the browser
86 these to be the same as the viewBox, so that the browser
87 scales the image correctly.
87 scales the image correctly.
88
88
89 Parameters
89 Parameters
90 ----------
90 ----------
91 image : str
91 image : str
92 SVG data.
92 SVG data.
93 size : tuple of int
93 size : tuple of int
94 Image width, height.
94 Image width, height.
95
95
96 """
96 """
97 (svg,) = minidom.parseString(image).getElementsByTagName('svg')
97 (svg,) = minidom.parseString(image).getElementsByTagName('svg')
98 viewbox = svg.getAttribute('viewBox').split(' ')
98 viewbox = svg.getAttribute('viewBox').split(' ')
99
99
100 if size is not None:
100 if size is not None:
101 width, height = size
101 width, height = size
102 else:
102 else:
103 width, height = viewbox[2:]
103 width, height = viewbox[2:]
104
104
105 svg.setAttribute('width', '%dpx' % width)
105 svg.setAttribute('width', '%dpx' % width)
106 svg.setAttribute('height', '%dpx' % height)
106 svg.setAttribute('height', '%dpx' % height)
107 return svg.toxml()
107 return svg.toxml()
108
108
109
109
110 @skip_doctest
110 @skip_doctest
111 @line_magic
111 @line_magic
112 def octave_push(self, line):
112 def octave_push(self, line):
113 '''
113 '''
114 Line-level magic that pushes a variable to Octave.
114 Line-level magic that pushes a variable to Octave.
115
115
116 `line` should be made up of whitespace separated variable names in the
116 `line` should be made up of whitespace separated variable names in the
117 IPython namespace::
117 IPython namespace::
118
118
119 In [7]: import numpy as np
119 In [7]: import numpy as np
120
120
121 In [8]: X = np.arange(5)
121 In [8]: X = np.arange(5)
122
122
123 In [9]: X.mean()
123 In [9]: X.mean()
124 Out[9]: 2.0
124 Out[9]: 2.0
125
125
126 In [10]: %octave_push X
126 In [10]: %octave_push X
127
127
128 In [11]: %octave mean(X)
128 In [11]: %octave mean(X)
129 Out[11]: 2.0
129 Out[11]: 2.0
130
130
131 '''
131 '''
132 inputs = line.split(' ')
132 inputs = line.split(' ')
133 for input in inputs:
133 for input in inputs:
134 input = unicode_to_str(input)
134 input = unicode_to_str(input)
135 self._oct.put(input, self.shell.user_ns[input])
135 self._oct.put(input, self.shell.user_ns[input])
136
136
137
137
138 @skip_doctest
138 @skip_doctest
139 @line_magic
139 @line_magic
140 def octave_pull(self, line):
140 def octave_pull(self, line):
141 '''
141 '''
142 Line-level magic that pulls a variable from Octave.
142 Line-level magic that pulls a variable from Octave.
143
143
144 In [18]: _ = %octave x = [1 2; 3 4]; y = 'hello'
144 In [18]: _ = %octave x = [1 2; 3 4]; y = 'hello'
145
145
146 In [19]: %octave_pull x y
146 In [19]: %octave_pull x y
147
147
148 In [20]: x
148 In [20]: x
149 Out[20]:
149 Out[20]:
150 array([[ 1., 2.],
150 array([[ 1., 2.],
151 [ 3., 4.]])
151 [ 3., 4.]])
152
152
153 In [21]: y
153 In [21]: y
154 Out[21]: 'hello'
154 Out[21]: 'hello'
155
155
156 '''
156 '''
157 outputs = line.split(' ')
157 outputs = line.split(' ')
158 for output in outputs:
158 for output in outputs:
159 output = unicode_to_str(output)
159 output = unicode_to_str(output)
160 self.shell.push({output: self._oct.get(output)})
160 self.shell.push({output: self._oct.get(output)})
161
161
162
162
163 @skip_doctest
163 @skip_doctest
164 @magic_arguments()
164 @magic_arguments()
165 @argument(
165 @argument(
166 '-i', '--input', action='append',
166 '-i', '--input', action='append',
167 help='Names of input variables to be pushed to Octave. Multiple names '
167 help='Names of input variables to be pushed to Octave. Multiple names '
168 'can be passed, separated by commas with no whitespace.'
168 'can be passed, separated by commas with no whitespace.'
169 )
169 )
170 @argument(
170 @argument(
171 '-o', '--output', action='append',
171 '-o', '--output', action='append',
172 help='Names of variables to be pulled from Octave after executing cell '
172 help='Names of variables to be pulled from Octave after executing cell '
173 'body. Multiple names can be passed, separated by commas with no '
173 'body. Multiple names can be passed, separated by commas with no '
174 'whitespace.'
174 'whitespace.'
175 )
175 )
176 @argument(
176 @argument(
177 '-s', '--size', action='store',
177 '-s', '--size', action='store',
178 help='Pixel size of plots, "width,height". Default is "-s 400,250".'
178 help='Pixel size of plots, "width,height". Default is "-s 400,250".'
179 )
179 )
180 @argument(
180 @argument(
181 '-f', '--format', action='store',
181 '-f', '--format', action='store',
182 help='Plot format (png, svg or jpg).'
182 help='Plot format (png, svg or jpg).'
183 )
183 )
184
184
185 @needs_local_scope
185 @needs_local_scope
186 @argument(
186 @argument(
187 'code',
187 'code',
188 nargs='*',
188 nargs='*',
189 )
189 )
190 @line_cell_magic
190 @line_cell_magic
191 def octave(self, line, cell=None, local_ns=None):
191 def octave(self, line, cell=None, local_ns=None):
192 '''
192 '''
193 Execute code in Octave, and pull some of the results back into the
193 Execute code in Octave, and pull some of the results back into the
194 Python namespace.
194 Python namespace.
195
195
196 In [9]: %octave X = [1 2; 3 4]; mean(X)
196 In [9]: %octave X = [1 2; 3 4]; mean(X)
197 Out[9]: array([[ 2., 3.]])
197 Out[9]: array([[ 2., 3.]])
198
198
199 As a cell, this will run a block of Octave code, without returning any
199 As a cell, this will run a block of Octave code, without returning any
200 value::
200 value::
201
201
202 In [10]: %%octave
202 In [10]: %%octave
203 ....: p = [-2, -1, 0, 1, 2]
203 ....: p = [-2, -1, 0, 1, 2]
204 ....: polyout(p, 'x')
204 ....: polyout(p, 'x')
205
205
206 -2*x^4 - 1*x^3 + 0*x^2 + 1*x^1 + 2
206 -2*x^4 - 1*x^3 + 0*x^2 + 1*x^1 + 2
207
207
208 In the notebook, plots are published as the output of the cell, e.g.
208 In the notebook, plots are published as the output of the cell, e.g.
209
209
210 %octave plot([1 2 3], [4 5 6])
210 %octave plot([1 2 3], [4 5 6])
211
211
212 will create a line plot.
212 will create a line plot.
213
213
214 Objects can be passed back and forth between Octave and IPython via the
214 Objects can be passed back and forth between Octave and IPython via the
215 -i and -o flags in line::
215 -i and -o flags in line::
216
216
217 In [14]: Z = np.array([1, 4, 5, 10])
217 In [14]: Z = np.array([1, 4, 5, 10])
218
218
219 In [15]: %octave -i Z mean(Z)
219 In [15]: %octave -i Z mean(Z)
220 Out[15]: array([ 5.])
220 Out[15]: array([ 5.])
221
221
222
222
223 In [16]: %octave -o W W = Z * mean(Z)
223 In [16]: %octave -o W W = Z * mean(Z)
224 Out[16]: array([ 5., 20., 25., 50.])
224 Out[16]: array([ 5., 20., 25., 50.])
225
225
226 In [17]: W
226 In [17]: W
227 Out[17]: array([ 5., 20., 25., 50.])
227 Out[17]: array([ 5., 20., 25., 50.])
228
228
229 The size and format of output plots can be specified::
229 The size and format of output plots can be specified::
230
230
231 In [18]: %%octave -s 600,800 -f svg
231 In [18]: %%octave -s 600,800 -f svg
232 ...: plot([1, 2, 3]);
232 ...: plot([1, 2, 3]);
233
233
234 '''
234 '''
235 args = parse_argstring(self.octave, line)
235 args = parse_argstring(self.octave, line)
236
236
237 # arguments 'code' in line are prepended to the cell lines
237 # arguments 'code' in line are prepended to the cell lines
238 if cell is None:
238 if cell is None:
239 code = ''
239 code = ''
240 return_output = True
240 return_output = True
241 else:
241 else:
242 code = cell
242 code = cell
243 return_output = False
243 return_output = False
244
244
245 code = ' '.join(args.code) + code
245 code = ' '.join(args.code) + code
246
246
247 # if there is no local namespace then default to an empty dict
247 # if there is no local namespace then default to an empty dict
248 if local_ns is None:
248 if local_ns is None:
249 local_ns = {}
249 local_ns = {}
250
250
251 if args.input:
251 if args.input:
252 for input in ','.join(args.input).split(','):
252 for input in ','.join(args.input).split(','):
253 input = unicode_to_str(input)
253 input = unicode_to_str(input)
254 try:
254 try:
255 val = local_ns[input]
255 val = local_ns[input]
256 except KeyError:
256 except KeyError:
257 val = self.shell.user_ns[input]
257 val = self.shell.user_ns[input]
258 self._oct.put(input, val)
258 self._oct.put(input, val)
259
259
260 # generate plots in a temporary directory
260 # generate plots in a temporary directory
261 plot_dir = tempfile.mkdtemp()
261 plot_dir = tempfile.mkdtemp()
262 if args.size is not None:
262 if args.size is not None:
263 size = args.size
263 size = args.size
264 else:
264 else:
265 size = '400,240'
265 size = '400,240'
266
266
267 if args.format is not None:
267 if args.format is not None:
268 plot_format = args.format
268 plot_format = args.format
269 else:
269 else:
270 plot_format = 'png'
270 plot_format = 'png'
271
271
272 pre_call = '''
272 pre_call = '''
273 global __ipy_figures = [];
273 global __ipy_figures = [];
274 page_screen_output(0);
274 page_screen_output(0);
275
275
276 function fig_create(src, event)
276 function fig_create(src, event)
277 global __ipy_figures;
277 global __ipy_figures;
278 __ipy_figures(size(__ipy_figures) + 1) = src;
278 __ipy_figures(size(__ipy_figures) + 1) = src;
279 set(src, "visible", "off");
279 set(src, "visible", "off");
280 end
280 end
281
281
282 set(0, 'DefaultFigureCreateFcn', @fig_create);
282 set(0, 'DefaultFigureCreateFcn', @fig_create);
283
283
284 close all;
284 close all;
285 clear ans;
285 clear ans;
286
286
287 # ___<end_pre_call>___ #
287 # ___<end_pre_call>___ #
288 '''
288 '''
289
289
290 post_call = '''
290 post_call = '''
291 # ___<start_post_call>___ #
291 # ___<start_post_call>___ #
292
292
293 # Save output of the last execution
293 # Save output of the last execution
294 if exist("ans") == 1
294 if exist("ans") == 1
295 _ = ans;
295 _ = ans;
296 else
296 else
297 _ = nan;
297 _ = nan;
298 end
298 end
299
299
300 for f = __ipy_figures
300 for f = __ipy_figures
301 outfile = sprintf('%(plot_dir)s/__ipy_oct_fig_%%03d.png', f);
301 outfile = sprintf('%(plot_dir)s/__ipy_oct_fig_%%03d.png', f);
302 try
302 try
303 print(f, outfile, '-d%(plot_format)s', '-tight', '-S%(size)s');
303 print(f, outfile, '-d%(plot_format)s', '-tight', '-S%(size)s');
304 end
304 end
305 end
305 end
306
306
307 ''' % locals()
307 ''' % locals()
308
308
309 code = ' '.join((pre_call, code, post_call))
309 code = ' '.join((pre_call, code, post_call))
310 try:
310 try:
311 text_output = self._oct.run(code, verbose=False)
311 text_output = self._oct.run(code, verbose=False)
312 except (oct2py.Oct2PyError) as exception:
312 except (oct2py.Oct2PyError) as exception:
313 msg = exception.message
313 msg = exception.message
314 msg = msg.split('# ___<end_pre_call>___ #')[1]
314 msg = msg.split('# ___<end_pre_call>___ #')[1]
315 msg = msg.split('# ___<start_post_call>___ #')[0]
315 msg = msg.split('# ___<start_post_call>___ #')[0]
316 raise OctaveMagicError('Octave could not complete execution. '
316 raise OctaveMagicError('Octave could not complete execution. '
317 'Traceback (currently broken in oct2py): %s'
317 'Traceback (currently broken in oct2py): %s'
318 % msg)
318 % msg)
319
319
320 key = 'OctaveMagic.Octave'
320 key = 'OctaveMagic.Octave'
321 display_data = []
321 display_data = []
322
322
323 # Publish text output
323 # Publish text output
324 if text_output:
324 if text_output:
325 display_data.append((key, {'text/plain': text_output}))
325 display_data.append((key, {'text/plain': text_output}))
326
326
327 # Publish images
327 # Publish images
328 images = [open(imgfile, 'rb').read() for imgfile in \
328 images = [open(imgfile, 'rb').read() for imgfile in \
329 glob("%s/*" % plot_dir)]
329 glob("%s/*" % plot_dir)]
330 rmtree(plot_dir)
330 rmtree(plot_dir)
331
331
332 plot_mime_type = _mimetypes.get(plot_format, 'image/png')
332 plot_mime_type = _mimetypes.get(plot_format, 'image/png')
333 width, height = [int(s) for s in size.split(',')]
333 width, height = [int(s) for s in size.split(',')]
334 for image in images:
334 for image in images:
335 if plot_format == 'svg':
335 if plot_format == 'svg':
336 image = self._fix_gnuplot_svg_size(image, size=(width, height))
336 image = self._fix_gnuplot_svg_size(image, size=(width, height))
337 display_data.append((key, {plot_mime_type: image}))
337 display_data.append((key, {plot_mime_type: image}))
338
338
339 if args.output:
339 if args.output:
340 for output in ','.join(args.output).split(','):
340 for output in ','.join(args.output).split(','):
341 output = unicode_to_str(output)
341 output = unicode_to_str(output)
342 self.shell.push({output: self._oct.get(output)})
342 self.shell.push({output: self._oct.get(output)})
343
343
344 for source, data in display_data:
344 for source, data in display_data:
345 self._publish_display_data(source, data)
345 self._publish_display_data(source, data)
346
346
347 if return_output:
347 if return_output:
348 ans = self._oct.get('_')
348 ans = self._oct.get('_')
349
349
350 # Unfortunately, Octave doesn't have a "None" object,
350 # Unfortunately, Octave doesn't have a "None" object,
351 # so we can't return any NaN outputs
351 # so we can't return any NaN outputs
352 if np.isscalar(ans) and np.isnan(ans):
352 if np.isscalar(ans) and np.isnan(ans):
353 ans = None
353 ans = None
354
354
355 return ans
355 return ans
356
356
357
357
358 __doc__ = __doc__.format(
358 __doc__ = __doc__.format(
359 OCTAVE_DOC = ' '*8 + OctaveMagics.octave.__doc__,
359 OCTAVE_DOC = ' '*8 + OctaveMagics.octave.__doc__,
360 OCTAVE_PUSH_DOC = ' '*8 + OctaveMagics.octave_push.__doc__,
360 OCTAVE_PUSH_DOC = ' '*8 + OctaveMagics.octave_push.__doc__,
361 OCTAVE_PULL_DOC = ' '*8 + OctaveMagics.octave_pull.__doc__
361 OCTAVE_PULL_DOC = ' '*8 + OctaveMagics.octave_pull.__doc__
362 )
362 )
363
363
364
364
365 _loaded = False
366 def load_ipython_extension(ip):
365 def load_ipython_extension(ip):
367 """Load the extension in IPython."""
366 """Load the extension in IPython."""
368 global _loaded
367 ip.register_magics(OctaveMagics)
369 if not _loaded:
370 ip.register_magics(OctaveMagics)
371 _loaded = True
@@ -1,597 +1,593 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 ======
3 ======
4 Rmagic
4 Rmagic
5 ======
5 ======
6
6
7 Magic command interface for interactive work with R via rpy2
7 Magic command interface for interactive work with R via rpy2
8
8
9 Usage
9 Usage
10 =====
10 =====
11
11
12 ``%R``
12 ``%R``
13
13
14 {R_DOC}
14 {R_DOC}
15
15
16 ``%Rpush``
16 ``%Rpush``
17
17
18 {RPUSH_DOC}
18 {RPUSH_DOC}
19
19
20 ``%Rpull``
20 ``%Rpull``
21
21
22 {RPULL_DOC}
22 {RPULL_DOC}
23
23
24 ``%Rget``
24 ``%Rget``
25
25
26 {RGET_DOC}
26 {RGET_DOC}
27
27
28 """
28 """
29
29
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31 # Copyright (C) 2012 The IPython Development Team
31 # Copyright (C) 2012 The IPython Development Team
32 #
32 #
33 # Distributed under the terms of the BSD License. The full license is in
33 # Distributed under the terms of the BSD License. The full license is in
34 # the file COPYING, distributed as part of this software.
34 # the file COPYING, distributed as part of this software.
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36
36
37 import sys
37 import sys
38 import tempfile
38 import tempfile
39 from glob import glob
39 from glob import glob
40 from shutil import rmtree
40 from shutil import rmtree
41 from getopt import getopt
41 from getopt import getopt
42
42
43 # numpy and rpy2 imports
43 # numpy and rpy2 imports
44
44
45 import numpy as np
45 import numpy as np
46
46
47 import rpy2.rinterface as ri
47 import rpy2.rinterface as ri
48 import rpy2.robjects as ro
48 import rpy2.robjects as ro
49 from rpy2.robjects.numpy2ri import numpy2ri
49 from rpy2.robjects.numpy2ri import numpy2ri
50 ro.conversion.py2ri = numpy2ri
50 ro.conversion.py2ri = numpy2ri
51
51
52 # IPython imports
52 # IPython imports
53
53
54 from IPython.core.displaypub import publish_display_data
54 from IPython.core.displaypub import publish_display_data
55 from IPython.core.magic import (Magics, magics_class, cell_magic, line_magic,
55 from IPython.core.magic import (Magics, magics_class, cell_magic, line_magic,
56 line_cell_magic, needs_local_scope)
56 line_cell_magic, needs_local_scope)
57 from IPython.testing.skipdoctest import skip_doctest
57 from IPython.testing.skipdoctest import skip_doctest
58 from IPython.core.magic_arguments import (
58 from IPython.core.magic_arguments import (
59 argument, magic_arguments, parse_argstring
59 argument, magic_arguments, parse_argstring
60 )
60 )
61 from IPython.utils.py3compat import str_to_unicode, unicode_to_str, PY3
61 from IPython.utils.py3compat import str_to_unicode, unicode_to_str, PY3
62
62
63 class RInterpreterError(ri.RRuntimeError):
63 class RInterpreterError(ri.RRuntimeError):
64 """An error when running R code in a %%R magic cell."""
64 """An error when running R code in a %%R magic cell."""
65 def __init__(self, line, err, stdout):
65 def __init__(self, line, err, stdout):
66 self.line = line
66 self.line = line
67 self.err = err.rstrip()
67 self.err = err.rstrip()
68 self.stdout = stdout.rstrip()
68 self.stdout = stdout.rstrip()
69
69
70 def __unicode__(self):
70 def __unicode__(self):
71 s = 'Failed to parse and evaluate line %r.\nR error message: %r' % \
71 s = 'Failed to parse and evaluate line %r.\nR error message: %r' % \
72 (self.line, self.err)
72 (self.line, self.err)
73 if self.stdout and (self.stdout != self.err):
73 if self.stdout and (self.stdout != self.err):
74 s += '\nR stdout:\n' + self.stdout
74 s += '\nR stdout:\n' + self.stdout
75 return s
75 return s
76
76
77 if PY3:
77 if PY3:
78 __str__ = __unicode__
78 __str__ = __unicode__
79 else:
79 else:
80 def __str__(self):
80 def __str__(self):
81 return unicode_to_str(unicode(self), 'utf-8')
81 return unicode_to_str(unicode(self), 'utf-8')
82
82
83 def Rconverter(Robj, dataframe=False):
83 def Rconverter(Robj, dataframe=False):
84 """
84 """
85 Convert an object in R's namespace to one suitable
85 Convert an object in R's namespace to one suitable
86 for ipython's namespace.
86 for ipython's namespace.
87
87
88 For a data.frame, it tries to return a structured array.
88 For a data.frame, it tries to return a structured array.
89 It first checks for colnames, then names.
89 It first checks for colnames, then names.
90 If all are NULL, it returns np.asarray(Robj), else
90 If all are NULL, it returns np.asarray(Robj), else
91 it tries to construct a recarray
91 it tries to construct a recarray
92
92
93 Parameters
93 Parameters
94 ----------
94 ----------
95
95
96 Robj: an R object returned from rpy2
96 Robj: an R object returned from rpy2
97 """
97 """
98 is_data_frame = ro.r('is.data.frame')
98 is_data_frame = ro.r('is.data.frame')
99 colnames = ro.r('colnames')
99 colnames = ro.r('colnames')
100 rownames = ro.r('rownames') # with pandas, these could be used for the index
100 rownames = ro.r('rownames') # with pandas, these could be used for the index
101 names = ro.r('names')
101 names = ro.r('names')
102
102
103 if dataframe:
103 if dataframe:
104 as_data_frame = ro.r('as.data.frame')
104 as_data_frame = ro.r('as.data.frame')
105 cols = colnames(Robj)
105 cols = colnames(Robj)
106 _names = names(Robj)
106 _names = names(Robj)
107 if cols != ri.NULL:
107 if cols != ri.NULL:
108 Robj = as_data_frame(Robj)
108 Robj = as_data_frame(Robj)
109 names = tuple(np.array(cols))
109 names = tuple(np.array(cols))
110 elif _names != ri.NULL:
110 elif _names != ri.NULL:
111 names = tuple(np.array(_names))
111 names = tuple(np.array(_names))
112 else: # failed to find names
112 else: # failed to find names
113 return np.asarray(Robj)
113 return np.asarray(Robj)
114 Robj = np.rec.fromarrays(Robj, names = names)
114 Robj = np.rec.fromarrays(Robj, names = names)
115 return np.asarray(Robj)
115 return np.asarray(Robj)
116
116
117 @magics_class
117 @magics_class
118 class RMagics(Magics):
118 class RMagics(Magics):
119 """A set of magics useful for interactive work with R via rpy2.
119 """A set of magics useful for interactive work with R via rpy2.
120 """
120 """
121
121
122 def __init__(self, shell, Rconverter=Rconverter,
122 def __init__(self, shell, Rconverter=Rconverter,
123 pyconverter=np.asarray,
123 pyconverter=np.asarray,
124 cache_display_data=False):
124 cache_display_data=False):
125 """
125 """
126 Parameters
126 Parameters
127 ----------
127 ----------
128
128
129 shell : IPython shell
129 shell : IPython shell
130
130
131 pyconverter : callable
131 pyconverter : callable
132 To be called on values in ipython namespace before
132 To be called on values in ipython namespace before
133 assigning to variables in rpy2.
133 assigning to variables in rpy2.
134
134
135 cache_display_data : bool
135 cache_display_data : bool
136 If True, the published results of the final call to R are
136 If True, the published results of the final call to R are
137 cached in the variable 'display_cache'.
137 cached in the variable 'display_cache'.
138
138
139 """
139 """
140 super(RMagics, self).__init__(shell)
140 super(RMagics, self).__init__(shell)
141 self.cache_display_data = cache_display_data
141 self.cache_display_data = cache_display_data
142
142
143 self.r = ro.R()
143 self.r = ro.R()
144
144
145 self.Rstdout_cache = []
145 self.Rstdout_cache = []
146 self.pyconverter = pyconverter
146 self.pyconverter = pyconverter
147 self.Rconverter = Rconverter
147 self.Rconverter = Rconverter
148
148
149 def eval(self, line):
149 def eval(self, line):
150 '''
150 '''
151 Parse and evaluate a line with rpy2.
151 Parse and evaluate a line with rpy2.
152 Returns the output to R's stdout() connection
152 Returns the output to R's stdout() connection
153 and the value of eval(parse(line)).
153 and the value of eval(parse(line)).
154 '''
154 '''
155 old_writeconsole = ri.get_writeconsole()
155 old_writeconsole = ri.get_writeconsole()
156 ri.set_writeconsole(self.write_console)
156 ri.set_writeconsole(self.write_console)
157 try:
157 try:
158 value = ri.baseenv['eval'](ri.parse(line))
158 value = ri.baseenv['eval'](ri.parse(line))
159 except (ri.RRuntimeError, ValueError) as exception:
159 except (ri.RRuntimeError, ValueError) as exception:
160 warning_or_other_msg = self.flush() # otherwise next return seems to have copy of error
160 warning_or_other_msg = self.flush() # otherwise next return seems to have copy of error
161 raise RInterpreterError(line, str_to_unicode(str(exception)), warning_or_other_msg)
161 raise RInterpreterError(line, str_to_unicode(str(exception)), warning_or_other_msg)
162 text_output = self.flush()
162 text_output = self.flush()
163 ri.set_writeconsole(old_writeconsole)
163 ri.set_writeconsole(old_writeconsole)
164 return text_output, value
164 return text_output, value
165
165
166 def write_console(self, output):
166 def write_console(self, output):
167 '''
167 '''
168 A hook to capture R's stdout in a cache.
168 A hook to capture R's stdout in a cache.
169 '''
169 '''
170 self.Rstdout_cache.append(output)
170 self.Rstdout_cache.append(output)
171
171
172 def flush(self):
172 def flush(self):
173 '''
173 '''
174 Flush R's stdout cache to a string, returning the string.
174 Flush R's stdout cache to a string, returning the string.
175 '''
175 '''
176 value = ''.join([str_to_unicode(s, 'utf-8') for s in self.Rstdout_cache])
176 value = ''.join([str_to_unicode(s, 'utf-8') for s in self.Rstdout_cache])
177 self.Rstdout_cache = []
177 self.Rstdout_cache = []
178 return value
178 return value
179
179
180 @skip_doctest
180 @skip_doctest
181 @line_magic
181 @line_magic
182 def Rpush(self, line):
182 def Rpush(self, line):
183 '''
183 '''
184 A line-level magic for R that pushes
184 A line-level magic for R that pushes
185 variables from python to rpy2. The line should be made up
185 variables from python to rpy2. The line should be made up
186 of whitespace separated variable names in the IPython
186 of whitespace separated variable names in the IPython
187 namespace::
187 namespace::
188
188
189 In [7]: import numpy as np
189 In [7]: import numpy as np
190
190
191 In [8]: X = np.array([4.5,6.3,7.9])
191 In [8]: X = np.array([4.5,6.3,7.9])
192
192
193 In [9]: X.mean()
193 In [9]: X.mean()
194 Out[9]: 6.2333333333333343
194 Out[9]: 6.2333333333333343
195
195
196 In [10]: %Rpush X
196 In [10]: %Rpush X
197
197
198 In [11]: %R mean(X)
198 In [11]: %R mean(X)
199 Out[11]: array([ 6.23333333])
199 Out[11]: array([ 6.23333333])
200
200
201 '''
201 '''
202
202
203 inputs = line.split(' ')
203 inputs = line.split(' ')
204 for input in inputs:
204 for input in inputs:
205 self.r.assign(input, self.pyconverter(self.shell.user_ns[input]))
205 self.r.assign(input, self.pyconverter(self.shell.user_ns[input]))
206
206
207 @skip_doctest
207 @skip_doctest
208 @magic_arguments()
208 @magic_arguments()
209 @argument(
209 @argument(
210 '-d', '--as_dataframe', action='store_true',
210 '-d', '--as_dataframe', action='store_true',
211 default=False,
211 default=False,
212 help='Convert objects to data.frames before returning to ipython.'
212 help='Convert objects to data.frames before returning to ipython.'
213 )
213 )
214 @argument(
214 @argument(
215 'outputs',
215 'outputs',
216 nargs='*',
216 nargs='*',
217 )
217 )
218 @line_magic
218 @line_magic
219 def Rpull(self, line):
219 def Rpull(self, line):
220 '''
220 '''
221 A line-level magic for R that pulls
221 A line-level magic for R that pulls
222 variables from python to rpy2::
222 variables from python to rpy2::
223
223
224 In [18]: _ = %R x = c(3,4,6.7); y = c(4,6,7); z = c('a',3,4)
224 In [18]: _ = %R x = c(3,4,6.7); y = c(4,6,7); z = c('a',3,4)
225
225
226 In [19]: %Rpull x y z
226 In [19]: %Rpull x y z
227
227
228 In [20]: x
228 In [20]: x
229 Out[20]: array([ 3. , 4. , 6.7])
229 Out[20]: array([ 3. , 4. , 6.7])
230
230
231 In [21]: y
231 In [21]: y
232 Out[21]: array([ 4., 6., 7.])
232 Out[21]: array([ 4., 6., 7.])
233
233
234 In [22]: z
234 In [22]: z
235 Out[22]:
235 Out[22]:
236 array(['a', '3', '4'],
236 array(['a', '3', '4'],
237 dtype='|S1')
237 dtype='|S1')
238
238
239
239
240 If --as_dataframe, then each object is returned as a structured array
240 If --as_dataframe, then each object is returned as a structured array
241 after first passed through "as.data.frame" in R before
241 after first passed through "as.data.frame" in R before
242 being calling self.Rconverter.
242 being calling self.Rconverter.
243 This is useful when a structured array is desired as output, or
243 This is useful when a structured array is desired as output, or
244 when the object in R has mixed data types.
244 when the object in R has mixed data types.
245 See the %%R docstring for more examples.
245 See the %%R docstring for more examples.
246
246
247 Notes
247 Notes
248 -----
248 -----
249
249
250 Beware that R names can have '.' so this is not fool proof.
250 Beware that R names can have '.' so this is not fool proof.
251 To avoid this, don't name your R objects with '.'s...
251 To avoid this, don't name your R objects with '.'s...
252
252
253 '''
253 '''
254 args = parse_argstring(self.Rpull, line)
254 args = parse_argstring(self.Rpull, line)
255 outputs = args.outputs
255 outputs = args.outputs
256 for output in outputs:
256 for output in outputs:
257 self.shell.push({output:self.Rconverter(self.r(output),dataframe=args.as_dataframe)})
257 self.shell.push({output:self.Rconverter(self.r(output),dataframe=args.as_dataframe)})
258
258
259 @skip_doctest
259 @skip_doctest
260 @magic_arguments()
260 @magic_arguments()
261 @argument(
261 @argument(
262 '-d', '--as_dataframe', action='store_true',
262 '-d', '--as_dataframe', action='store_true',
263 default=False,
263 default=False,
264 help='Convert objects to data.frames before returning to ipython.'
264 help='Convert objects to data.frames before returning to ipython.'
265 )
265 )
266 @argument(
266 @argument(
267 'output',
267 'output',
268 nargs=1,
268 nargs=1,
269 type=str,
269 type=str,
270 )
270 )
271 @line_magic
271 @line_magic
272 def Rget(self, line):
272 def Rget(self, line):
273 '''
273 '''
274 Return an object from rpy2, possibly as a structured array (if possible).
274 Return an object from rpy2, possibly as a structured array (if possible).
275 Similar to Rpull except only one argument is accepted and the value is
275 Similar to Rpull except only one argument is accepted and the value is
276 returned rather than pushed to self.shell.user_ns::
276 returned rather than pushed to self.shell.user_ns::
277
277
278 In [3]: dtype=[('x', '<i4'), ('y', '<f8'), ('z', '|S1')]
278 In [3]: dtype=[('x', '<i4'), ('y', '<f8'), ('z', '|S1')]
279
279
280 In [4]: datapy = np.array([(1, 2.9, 'a'), (2, 3.5, 'b'), (3, 2.1, 'c'), (4, 5, 'e')], dtype=dtype)
280 In [4]: datapy = np.array([(1, 2.9, 'a'), (2, 3.5, 'b'), (3, 2.1, 'c'), (4, 5, 'e')], dtype=dtype)
281
281
282 In [5]: %R -i datapy
282 In [5]: %R -i datapy
283
283
284 In [6]: %Rget datapy
284 In [6]: %Rget datapy
285 Out[6]:
285 Out[6]:
286 array([['1', '2', '3', '4'],
286 array([['1', '2', '3', '4'],
287 ['2', '3', '2', '5'],
287 ['2', '3', '2', '5'],
288 ['a', 'b', 'c', 'e']],
288 ['a', 'b', 'c', 'e']],
289 dtype='|S1')
289 dtype='|S1')
290
290
291 In [7]: %Rget -d datapy
291 In [7]: %Rget -d datapy
292 Out[7]:
292 Out[7]:
293 array([(1, 2.9, 'a'), (2, 3.5, 'b'), (3, 2.1, 'c'), (4, 5.0, 'e')],
293 array([(1, 2.9, 'a'), (2, 3.5, 'b'), (3, 2.1, 'c'), (4, 5.0, 'e')],
294 dtype=[('x', '<i4'), ('y', '<f8'), ('z', '|S1')])
294 dtype=[('x', '<i4'), ('y', '<f8'), ('z', '|S1')])
295
295
296 '''
296 '''
297 args = parse_argstring(self.Rget, line)
297 args = parse_argstring(self.Rget, line)
298 output = args.output
298 output = args.output
299 return self.Rconverter(self.r(output[0]),dataframe=args.as_dataframe)
299 return self.Rconverter(self.r(output[0]),dataframe=args.as_dataframe)
300
300
301
301
302 @skip_doctest
302 @skip_doctest
303 @magic_arguments()
303 @magic_arguments()
304 @argument(
304 @argument(
305 '-i', '--input', action='append',
305 '-i', '--input', action='append',
306 help='Names of input variable from shell.user_ns to be assigned to R variables of the same names after calling self.pyconverter. Multiple names can be passed separated only by commas with no whitespace.'
306 help='Names of input variable from shell.user_ns to be assigned to R variables of the same names after calling self.pyconverter. Multiple names can be passed separated only by commas with no whitespace.'
307 )
307 )
308 @argument(
308 @argument(
309 '-o', '--output', action='append',
309 '-o', '--output', action='append',
310 help='Names of variables to be pushed from rpy2 to shell.user_ns after executing cell body and applying self.Rconverter. Multiple names can be passed separated only by commas with no whitespace.'
310 help='Names of variables to be pushed from rpy2 to shell.user_ns after executing cell body and applying self.Rconverter. Multiple names can be passed separated only by commas with no whitespace.'
311 )
311 )
312 @argument(
312 @argument(
313 '-w', '--width', type=int,
313 '-w', '--width', type=int,
314 help='Width of png plotting device sent as an argument to *png* in R.'
314 help='Width of png plotting device sent as an argument to *png* in R.'
315 )
315 )
316 @argument(
316 @argument(
317 '-h', '--height', type=int,
317 '-h', '--height', type=int,
318 help='Height of png plotting device sent as an argument to *png* in R.'
318 help='Height of png plotting device sent as an argument to *png* in R.'
319 )
319 )
320
320
321 @argument(
321 @argument(
322 '-d', '--dataframe', action='append',
322 '-d', '--dataframe', action='append',
323 help='Convert these objects to data.frames and return as structured arrays.'
323 help='Convert these objects to data.frames and return as structured arrays.'
324 )
324 )
325 @argument(
325 @argument(
326 '-u', '--units', type=int,
326 '-u', '--units', type=int,
327 help='Units of png plotting device sent as an argument to *png* in R. One of ["px", "in", "cm", "mm"].'
327 help='Units of png plotting device sent as an argument to *png* in R. One of ["px", "in", "cm", "mm"].'
328 )
328 )
329 @argument(
329 @argument(
330 '-p', '--pointsize', type=int,
330 '-p', '--pointsize', type=int,
331 help='Pointsize of png plotting device sent as an argument to *png* in R.'
331 help='Pointsize of png plotting device sent as an argument to *png* in R.'
332 )
332 )
333 @argument(
333 @argument(
334 '-b', '--bg',
334 '-b', '--bg',
335 help='Background of png plotting device sent as an argument to *png* in R.'
335 help='Background of png plotting device sent as an argument to *png* in R.'
336 )
336 )
337 @argument(
337 @argument(
338 '-n', '--noreturn',
338 '-n', '--noreturn',
339 help='Force the magic to not return anything.',
339 help='Force the magic to not return anything.',
340 action='store_true',
340 action='store_true',
341 default=False
341 default=False
342 )
342 )
343 @argument(
343 @argument(
344 'code',
344 'code',
345 nargs='*',
345 nargs='*',
346 )
346 )
347 @needs_local_scope
347 @needs_local_scope
348 @line_cell_magic
348 @line_cell_magic
349 def R(self, line, cell=None, local_ns=None):
349 def R(self, line, cell=None, local_ns=None):
350 '''
350 '''
351 Execute code in R, and pull some of the results back into the Python namespace.
351 Execute code in R, and pull some of the results back into the Python namespace.
352
352
353 In line mode, this will evaluate an expression and convert the returned value to a Python object.
353 In line mode, this will evaluate an expression and convert the returned value to a Python object.
354 The return value is determined by rpy2's behaviour of returning the result of evaluating the
354 The return value is determined by rpy2's behaviour of returning the result of evaluating the
355 final line.
355 final line.
356
356
357 Multiple R lines can be executed by joining them with semicolons::
357 Multiple R lines can be executed by joining them with semicolons::
358
358
359 In [9]: %R X=c(1,4,5,7); sd(X); mean(X)
359 In [9]: %R X=c(1,4,5,7); sd(X); mean(X)
360 Out[9]: array([ 4.25])
360 Out[9]: array([ 4.25])
361
361
362 As a cell, this will run a block of R code, without bringing anything back by default::
362 As a cell, this will run a block of R code, without bringing anything back by default::
363
363
364 In [10]: %%R
364 In [10]: %%R
365 ....: Y = c(2,4,3,9)
365 ....: Y = c(2,4,3,9)
366 ....: print(summary(lm(Y~X)))
366 ....: print(summary(lm(Y~X)))
367 ....:
367 ....:
368
368
369 Call:
369 Call:
370 lm(formula = Y ~ X)
370 lm(formula = Y ~ X)
371
371
372 Residuals:
372 Residuals:
373 1 2 3 4
373 1 2 3 4
374 0.88 -0.24 -2.28 1.64
374 0.88 -0.24 -2.28 1.64
375
375
376 Coefficients:
376 Coefficients:
377 Estimate Std. Error t value Pr(>|t|)
377 Estimate Std. Error t value Pr(>|t|)
378 (Intercept) 0.0800 2.3000 0.035 0.975
378 (Intercept) 0.0800 2.3000 0.035 0.975
379 X 1.0400 0.4822 2.157 0.164
379 X 1.0400 0.4822 2.157 0.164
380
380
381 Residual standard error: 2.088 on 2 degrees of freedom
381 Residual standard error: 2.088 on 2 degrees of freedom
382 Multiple R-squared: 0.6993,Adjusted R-squared: 0.549
382 Multiple R-squared: 0.6993,Adjusted R-squared: 0.549
383 F-statistic: 4.651 on 1 and 2 DF, p-value: 0.1638
383 F-statistic: 4.651 on 1 and 2 DF, p-value: 0.1638
384
384
385 In the notebook, plots are published as the output of the cell.
385 In the notebook, plots are published as the output of the cell.
386
386
387 %R plot(X, Y)
387 %R plot(X, Y)
388
388
389 will create a scatter plot of X bs Y.
389 will create a scatter plot of X bs Y.
390
390
391 If cell is not None and line has some R code, it is prepended to
391 If cell is not None and line has some R code, it is prepended to
392 the R code in cell.
392 the R code in cell.
393
393
394 Objects can be passed back and forth between rpy2 and python via the -i -o flags in line::
394 Objects can be passed back and forth between rpy2 and python via the -i -o flags in line::
395
395
396 In [14]: Z = np.array([1,4,5,10])
396 In [14]: Z = np.array([1,4,5,10])
397
397
398 In [15]: %R -i Z mean(Z)
398 In [15]: %R -i Z mean(Z)
399 Out[15]: array([ 5.])
399 Out[15]: array([ 5.])
400
400
401
401
402 In [16]: %R -o W W=Z*mean(Z)
402 In [16]: %R -o W W=Z*mean(Z)
403 Out[16]: array([ 5., 20., 25., 50.])
403 Out[16]: array([ 5., 20., 25., 50.])
404
404
405 In [17]: W
405 In [17]: W
406 Out[17]: array([ 5., 20., 25., 50.])
406 Out[17]: array([ 5., 20., 25., 50.])
407
407
408 The return value is determined by these rules:
408 The return value is determined by these rules:
409
409
410 * If the cell is not None, the magic returns None.
410 * If the cell is not None, the magic returns None.
411
411
412 * If the cell evaluates as False, the resulting value is returned
412 * If the cell evaluates as False, the resulting value is returned
413 unless the final line prints something to the console, in
413 unless the final line prints something to the console, in
414 which case None is returned.
414 which case None is returned.
415
415
416 * If the final line results in a NULL value when evaluated
416 * If the final line results in a NULL value when evaluated
417 by rpy2, then None is returned.
417 by rpy2, then None is returned.
418
418
419 * No attempt is made to convert the final value to a structured array.
419 * No attempt is made to convert the final value to a structured array.
420 Use the --dataframe flag or %Rget to push / return a structured array.
420 Use the --dataframe flag or %Rget to push / return a structured array.
421
421
422 * If the -n flag is present, there is no return value.
422 * If the -n flag is present, there is no return value.
423
423
424 * A trailing ';' will also result in no return value as the last
424 * A trailing ';' will also result in no return value as the last
425 value in the line is an empty string.
425 value in the line is an empty string.
426
426
427 The --dataframe argument will attempt to return structured arrays.
427 The --dataframe argument will attempt to return structured arrays.
428 This is useful for dataframes with
428 This is useful for dataframes with
429 mixed data types. Note also that for a data.frame,
429 mixed data types. Note also that for a data.frame,
430 if it is returned as an ndarray, it is transposed::
430 if it is returned as an ndarray, it is transposed::
431
431
432 In [18]: dtype=[('x', '<i4'), ('y', '<f8'), ('z', '|S1')]
432 In [18]: dtype=[('x', '<i4'), ('y', '<f8'), ('z', '|S1')]
433
433
434 In [19]: datapy = np.array([(1, 2.9, 'a'), (2, 3.5, 'b'), (3, 2.1, 'c'), (4, 5, 'e')], dtype=dtype)
434 In [19]: datapy = np.array([(1, 2.9, 'a'), (2, 3.5, 'b'), (3, 2.1, 'c'), (4, 5, 'e')], dtype=dtype)
435
435
436 In [20]: %%R -o datar
436 In [20]: %%R -o datar
437 datar = datapy
437 datar = datapy
438 ....:
438 ....:
439
439
440 In [21]: datar
440 In [21]: datar
441 Out[21]:
441 Out[21]:
442 array([['1', '2', '3', '4'],
442 array([['1', '2', '3', '4'],
443 ['2', '3', '2', '5'],
443 ['2', '3', '2', '5'],
444 ['a', 'b', 'c', 'e']],
444 ['a', 'b', 'c', 'e']],
445 dtype='|S1')
445 dtype='|S1')
446
446
447 In [22]: %%R -d datar
447 In [22]: %%R -d datar
448 datar = datapy
448 datar = datapy
449 ....:
449 ....:
450
450
451 In [23]: datar
451 In [23]: datar
452 Out[23]:
452 Out[23]:
453 array([(1, 2.9, 'a'), (2, 3.5, 'b'), (3, 2.1, 'c'), (4, 5.0, 'e')],
453 array([(1, 2.9, 'a'), (2, 3.5, 'b'), (3, 2.1, 'c'), (4, 5.0, 'e')],
454 dtype=[('x', '<i4'), ('y', '<f8'), ('z', '|S1')])
454 dtype=[('x', '<i4'), ('y', '<f8'), ('z', '|S1')])
455
455
456 The --dataframe argument first tries colnames, then names.
456 The --dataframe argument first tries colnames, then names.
457 If both are NULL, it returns an ndarray (i.e. unstructured)::
457 If both are NULL, it returns an ndarray (i.e. unstructured)::
458
458
459 In [1]: %R mydata=c(4,6,8.3); NULL
459 In [1]: %R mydata=c(4,6,8.3); NULL
460
460
461 In [2]: %R -d mydata
461 In [2]: %R -d mydata
462
462
463 In [3]: mydata
463 In [3]: mydata
464 Out[3]: array([ 4. , 6. , 8.3])
464 Out[3]: array([ 4. , 6. , 8.3])
465
465
466 In [4]: %R names(mydata) = c('a','b','c'); NULL
466 In [4]: %R names(mydata) = c('a','b','c'); NULL
467
467
468 In [5]: %R -d mydata
468 In [5]: %R -d mydata
469
469
470 In [6]: mydata
470 In [6]: mydata
471 Out[6]:
471 Out[6]:
472 array((4.0, 6.0, 8.3),
472 array((4.0, 6.0, 8.3),
473 dtype=[('a', '<f8'), ('b', '<f8'), ('c', '<f8')])
473 dtype=[('a', '<f8'), ('b', '<f8'), ('c', '<f8')])
474
474
475 In [7]: %R -o mydata
475 In [7]: %R -o mydata
476
476
477 In [8]: mydata
477 In [8]: mydata
478 Out[8]: array([ 4. , 6. , 8.3])
478 Out[8]: array([ 4. , 6. , 8.3])
479
479
480 '''
480 '''
481
481
482 args = parse_argstring(self.R, line)
482 args = parse_argstring(self.R, line)
483
483
484 # arguments 'code' in line are prepended to
484 # arguments 'code' in line are prepended to
485 # the cell lines
485 # the cell lines
486
486
487 if cell is None:
487 if cell is None:
488 code = ''
488 code = ''
489 return_output = True
489 return_output = True
490 line_mode = True
490 line_mode = True
491 else:
491 else:
492 code = cell
492 code = cell
493 return_output = False
493 return_output = False
494 line_mode = False
494 line_mode = False
495
495
496 code = ' '.join(args.code) + code
496 code = ' '.join(args.code) + code
497
497
498 # if there is no local namespace then default to an empty dict
498 # if there is no local namespace then default to an empty dict
499 if local_ns is None:
499 if local_ns is None:
500 local_ns = {}
500 local_ns = {}
501
501
502 if args.input:
502 if args.input:
503 for input in ','.join(args.input).split(','):
503 for input in ','.join(args.input).split(','):
504 try:
504 try:
505 val = local_ns[input]
505 val = local_ns[input]
506 except KeyError:
506 except KeyError:
507 val = self.shell.user_ns[input]
507 val = self.shell.user_ns[input]
508 self.r.assign(input, self.pyconverter(val))
508 self.r.assign(input, self.pyconverter(val))
509
509
510 png_argdict = dict([(n, getattr(args, n)) for n in ['units', 'height', 'width', 'bg', 'pointsize']])
510 png_argdict = dict([(n, getattr(args, n)) for n in ['units', 'height', 'width', 'bg', 'pointsize']])
511 png_args = ','.join(['%s=%s' % (o,v) for o, v in png_argdict.items() if v is not None])
511 png_args = ','.join(['%s=%s' % (o,v) for o, v in png_argdict.items() if v is not None])
512 # execute the R code in a temporary directory
512 # execute the R code in a temporary directory
513
513
514 tmpd = tempfile.mkdtemp()
514 tmpd = tempfile.mkdtemp()
515 self.r('png("%s/Rplots%%03d.png",%s)' % (tmpd, png_args))
515 self.r('png("%s/Rplots%%03d.png",%s)' % (tmpd, png_args))
516
516
517 text_output = ''
517 text_output = ''
518 if line_mode:
518 if line_mode:
519 for line in code.split(';'):
519 for line in code.split(';'):
520 text_result, result = self.eval(line)
520 text_result, result = self.eval(line)
521 text_output += text_result
521 text_output += text_result
522 if text_result:
522 if text_result:
523 # the last line printed something to the console so we won't return it
523 # the last line printed something to the console so we won't return it
524 return_output = False
524 return_output = False
525 else:
525 else:
526 text_result, result = self.eval(code)
526 text_result, result = self.eval(code)
527 text_output += text_result
527 text_output += text_result
528
528
529 self.r('dev.off()')
529 self.r('dev.off()')
530
530
531 # read out all the saved .png files
531 # read out all the saved .png files
532
532
533 images = [open(imgfile, 'rb').read() for imgfile in glob("%s/Rplots*png" % tmpd)]
533 images = [open(imgfile, 'rb').read() for imgfile in glob("%s/Rplots*png" % tmpd)]
534
534
535 # now publish the images
535 # now publish the images
536 # mimicking IPython/zmq/pylab/backend_inline.py
536 # mimicking IPython/zmq/pylab/backend_inline.py
537 fmt = 'png'
537 fmt = 'png'
538 mimetypes = { 'png' : 'image/png', 'svg' : 'image/svg+xml' }
538 mimetypes = { 'png' : 'image/png', 'svg' : 'image/svg+xml' }
539 mime = mimetypes[fmt]
539 mime = mimetypes[fmt]
540
540
541 # publish the printed R objects, if any
541 # publish the printed R objects, if any
542
542
543 display_data = []
543 display_data = []
544 if text_output:
544 if text_output:
545 display_data.append(('RMagic.R', {'text/plain':text_output}))
545 display_data.append(('RMagic.R', {'text/plain':text_output}))
546
546
547 # flush text streams before sending figures, helps a little with output
547 # flush text streams before sending figures, helps a little with output
548 for image in images:
548 for image in images:
549 # synchronization in the console (though it's a bandaid, not a real sln)
549 # synchronization in the console (though it's a bandaid, not a real sln)
550 sys.stdout.flush(); sys.stderr.flush()
550 sys.stdout.flush(); sys.stderr.flush()
551 display_data.append(('RMagic.R', {mime: image}))
551 display_data.append(('RMagic.R', {mime: image}))
552
552
553 # kill the temporary directory
553 # kill the temporary directory
554 rmtree(tmpd)
554 rmtree(tmpd)
555
555
556 # try to turn every output into a numpy array
556 # try to turn every output into a numpy array
557 # this means that output are assumed to be castable
557 # this means that output are assumed to be castable
558 # as numpy arrays
558 # as numpy arrays
559
559
560 if args.output:
560 if args.output:
561 for output in ','.join(args.output).split(','):
561 for output in ','.join(args.output).split(','):
562 self.shell.push({output:self.Rconverter(self.r(output), dataframe=False)})
562 self.shell.push({output:self.Rconverter(self.r(output), dataframe=False)})
563
563
564 if args.dataframe:
564 if args.dataframe:
565 for output in ','.join(args.dataframe).split(','):
565 for output in ','.join(args.dataframe).split(','):
566 self.shell.push({output:self.Rconverter(self.r(output), dataframe=True)})
566 self.shell.push({output:self.Rconverter(self.r(output), dataframe=True)})
567
567
568 for tag, disp_d in display_data:
568 for tag, disp_d in display_data:
569 publish_display_data(tag, disp_d)
569 publish_display_data(tag, disp_d)
570
570
571 # this will keep a reference to the display_data
571 # this will keep a reference to the display_data
572 # which might be useful to other objects who happen to use
572 # which might be useful to other objects who happen to use
573 # this method
573 # this method
574
574
575 if self.cache_display_data:
575 if self.cache_display_data:
576 self.display_cache = display_data
576 self.display_cache = display_data
577
577
578 # if in line mode and return_output, return the result as an ndarray
578 # if in line mode and return_output, return the result as an ndarray
579 if return_output and not args.noreturn:
579 if return_output and not args.noreturn:
580 if result != ri.NULL:
580 if result != ri.NULL:
581 return self.Rconverter(result, dataframe=False)
581 return self.Rconverter(result, dataframe=False)
582
582
583 __doc__ = __doc__.format(
583 __doc__ = __doc__.format(
584 R_DOC = ' '*8 + RMagics.R.__doc__,
584 R_DOC = ' '*8 + RMagics.R.__doc__,
585 RPUSH_DOC = ' '*8 + RMagics.Rpush.__doc__,
585 RPUSH_DOC = ' '*8 + RMagics.Rpush.__doc__,
586 RPULL_DOC = ' '*8 + RMagics.Rpull.__doc__,
586 RPULL_DOC = ' '*8 + RMagics.Rpull.__doc__,
587 RGET_DOC = ' '*8 + RMagics.Rget.__doc__
587 RGET_DOC = ' '*8 + RMagics.Rget.__doc__
588 )
588 )
589
589
590
590
591 _loaded = False
592 def load_ipython_extension(ip):
591 def load_ipython_extension(ip):
593 """Load the extension in IPython."""
592 """Load the extension in IPython."""
594 global _loaded
593 ip.register_magics(RMagics)
595 if not _loaded:
596 ip.register_magics(RMagics)
597 _loaded = True
@@ -1,220 +1,214 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 %store magic for lightweight persistence.
3 %store magic for lightweight persistence.
4
4
5 Stores variables, aliases and macros in IPython's database.
5 Stores variables, aliases and macros in IPython's database.
6
6
7 To automatically restore stored variables at startup, add this to your
7 To automatically restore stored variables at startup, add this to your
8 :file:`ipython_config.py` file::
8 :file:`ipython_config.py` file::
9
9
10 c.StoreMagic.autorestore = True
10 c.StoreMagic.autorestore = True
11 """
11 """
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (c) 2012, The IPython Development Team.
13 # Copyright (c) 2012, The IPython Development Team.
14 #
14 #
15 # Distributed under the terms of the Modified BSD License.
15 # Distributed under the terms of the Modified BSD License.
16 #
16 #
17 # The full license is in the file COPYING.txt, distributed with this software.
17 # The full license is in the file COPYING.txt, distributed with this software.
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Imports
21 # Imports
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 # Stdlib
24 # Stdlib
25 import inspect, os, sys, textwrap
25 import inspect, os, sys, textwrap
26
26
27 # Our own
27 # Our own
28 from IPython.core.error import UsageError
28 from IPython.core.error import UsageError
29 from IPython.core.fakemodule import FakeModule
29 from IPython.core.fakemodule import FakeModule
30 from IPython.core.magic import Magics, magics_class, line_magic
30 from IPython.core.magic import Magics, magics_class, line_magic
31 from IPython.testing.skipdoctest import skip_doctest
31 from IPython.testing.skipdoctest import skip_doctest
32
32
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34 # Functions and classes
34 # Functions and classes
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36
36
37 def restore_aliases(ip):
37 def restore_aliases(ip):
38 staliases = ip.db.get('stored_aliases', {})
38 staliases = ip.db.get('stored_aliases', {})
39 for k,v in staliases.items():
39 for k,v in staliases.items():
40 #print "restore alias",k,v # dbg
40 #print "restore alias",k,v # dbg
41 #self.alias_table[k] = v
41 #self.alias_table[k] = v
42 ip.alias_manager.define_alias(k,v)
42 ip.alias_manager.define_alias(k,v)
43
43
44
44
45 def refresh_variables(ip):
45 def refresh_variables(ip):
46 db = ip.db
46 db = ip.db
47 for key in db.keys('autorestore/*'):
47 for key in db.keys('autorestore/*'):
48 # strip autorestore
48 # strip autorestore
49 justkey = os.path.basename(key)
49 justkey = os.path.basename(key)
50 try:
50 try:
51 obj = db[key]
51 obj = db[key]
52 except KeyError:
52 except KeyError:
53 print "Unable to restore variable '%s', ignoring (use %%store -d to forget!)" % justkey
53 print "Unable to restore variable '%s', ignoring (use %%store -d to forget!)" % justkey
54 print "The error was:", sys.exc_info()[0]
54 print "The error was:", sys.exc_info()[0]
55 else:
55 else:
56 #print "restored",justkey,"=",obj #dbg
56 #print "restored",justkey,"=",obj #dbg
57 ip.user_ns[justkey] = obj
57 ip.user_ns[justkey] = obj
58
58
59
59
60 def restore_dhist(ip):
60 def restore_dhist(ip):
61 ip.user_ns['_dh'] = ip.db.get('dhist',[])
61 ip.user_ns['_dh'] = ip.db.get('dhist',[])
62
62
63
63
64 def restore_data(ip):
64 def restore_data(ip):
65 refresh_variables(ip)
65 refresh_variables(ip)
66 restore_aliases(ip)
66 restore_aliases(ip)
67 restore_dhist(ip)
67 restore_dhist(ip)
68
68
69
69
70 @magics_class
70 @magics_class
71 class StoreMagics(Magics):
71 class StoreMagics(Magics):
72 """Lightweight persistence for python variables.
72 """Lightweight persistence for python variables.
73
73
74 Provides the %store magic."""
74 Provides the %store magic."""
75
75
76 @skip_doctest
76 @skip_doctest
77 @line_magic
77 @line_magic
78 def store(self, parameter_s=''):
78 def store(self, parameter_s=''):
79 """Lightweight persistence for python variables.
79 """Lightweight persistence for python variables.
80
80
81 Example::
81 Example::
82
82
83 In [1]: l = ['hello',10,'world']
83 In [1]: l = ['hello',10,'world']
84 In [2]: %store l
84 In [2]: %store l
85 In [3]: exit
85 In [3]: exit
86
86
87 (IPython session is closed and started again...)
87 (IPython session is closed and started again...)
88
88
89 ville@badger:~$ ipython
89 ville@badger:~$ ipython
90 In [1]: l
90 In [1]: l
91 Out[1]: ['hello', 10, 'world']
91 Out[1]: ['hello', 10, 'world']
92
92
93 Usage:
93 Usage:
94
94
95 * ``%store`` - Show list of all variables and their current
95 * ``%store`` - Show list of all variables and their current
96 values
96 values
97 * ``%store spam`` - Store the *current* value of the variable spam
97 * ``%store spam`` - Store the *current* value of the variable spam
98 to disk
98 to disk
99 * ``%store -d spam`` - Remove the variable and its value from storage
99 * ``%store -d spam`` - Remove the variable and its value from storage
100 * ``%store -z`` - Remove all variables from storage
100 * ``%store -z`` - Remove all variables from storage
101 * ``%store -r`` - Refresh all variables from store (delete
101 * ``%store -r`` - Refresh all variables from store (delete
102 current vals)
102 current vals)
103 * ``%store foo >a.txt`` - Store value of foo to new file a.txt
103 * ``%store foo >a.txt`` - Store value of foo to new file a.txt
104 * ``%store foo >>a.txt`` - Append value of foo to file a.txt
104 * ``%store foo >>a.txt`` - Append value of foo to file a.txt
105
105
106 It should be noted that if you change the value of a variable, you
106 It should be noted that if you change the value of a variable, you
107 need to %store it again if you want to persist the new value.
107 need to %store it again if you want to persist the new value.
108
108
109 Note also that the variables will need to be pickleable; most basic
109 Note also that the variables will need to be pickleable; most basic
110 python types can be safely %store'd.
110 python types can be safely %store'd.
111
111
112 Also aliases can be %store'd across sessions.
112 Also aliases can be %store'd across sessions.
113 """
113 """
114
114
115 opts,argsl = self.parse_options(parameter_s,'drz',mode='string')
115 opts,argsl = self.parse_options(parameter_s,'drz',mode='string')
116 args = argsl.split(None,1)
116 args = argsl.split(None,1)
117 ip = self.shell
117 ip = self.shell
118 db = ip.db
118 db = ip.db
119 # delete
119 # delete
120 if 'd' in opts:
120 if 'd' in opts:
121 try:
121 try:
122 todel = args[0]
122 todel = args[0]
123 except IndexError:
123 except IndexError:
124 raise UsageError('You must provide the variable to forget')
124 raise UsageError('You must provide the variable to forget')
125 else:
125 else:
126 try:
126 try:
127 del db['autorestore/' + todel]
127 del db['autorestore/' + todel]
128 except:
128 except:
129 raise UsageError("Can't delete variable '%s'" % todel)
129 raise UsageError("Can't delete variable '%s'" % todel)
130 # reset
130 # reset
131 elif 'z' in opts:
131 elif 'z' in opts:
132 for k in db.keys('autorestore/*'):
132 for k in db.keys('autorestore/*'):
133 del db[k]
133 del db[k]
134
134
135 elif 'r' in opts:
135 elif 'r' in opts:
136 refresh_variables(ip)
136 refresh_variables(ip)
137
137
138
138
139 # run without arguments -> list variables & values
139 # run without arguments -> list variables & values
140 elif not args:
140 elif not args:
141 vars = db.keys('autorestore/*')
141 vars = db.keys('autorestore/*')
142 vars.sort()
142 vars.sort()
143 if vars:
143 if vars:
144 size = max(map(len, vars))
144 size = max(map(len, vars))
145 else:
145 else:
146 size = 0
146 size = 0
147
147
148 print 'Stored variables and their in-db values:'
148 print 'Stored variables and their in-db values:'
149 fmt = '%-'+str(size)+'s -> %s'
149 fmt = '%-'+str(size)+'s -> %s'
150 get = db.get
150 get = db.get
151 for var in vars:
151 for var in vars:
152 justkey = os.path.basename(var)
152 justkey = os.path.basename(var)
153 # print 30 first characters from every var
153 # print 30 first characters from every var
154 print fmt % (justkey, repr(get(var, '<unavailable>'))[:50])
154 print fmt % (justkey, repr(get(var, '<unavailable>'))[:50])
155
155
156 # default action - store the variable
156 # default action - store the variable
157 else:
157 else:
158 # %store foo >file.txt or >>file.txt
158 # %store foo >file.txt or >>file.txt
159 if len(args) > 1 and args[1].startswith('>'):
159 if len(args) > 1 and args[1].startswith('>'):
160 fnam = os.path.expanduser(args[1].lstrip('>').lstrip())
160 fnam = os.path.expanduser(args[1].lstrip('>').lstrip())
161 if args[1].startswith('>>'):
161 if args[1].startswith('>>'):
162 fil = open(fnam, 'a')
162 fil = open(fnam, 'a')
163 else:
163 else:
164 fil = open(fnam, 'w')
164 fil = open(fnam, 'w')
165 obj = ip.ev(args[0])
165 obj = ip.ev(args[0])
166 print "Writing '%s' (%s) to file '%s'." % (args[0],
166 print "Writing '%s' (%s) to file '%s'." % (args[0],
167 obj.__class__.__name__, fnam)
167 obj.__class__.__name__, fnam)
168
168
169
169
170 if not isinstance (obj, basestring):
170 if not isinstance (obj, basestring):
171 from pprint import pprint
171 from pprint import pprint
172 pprint(obj, fil)
172 pprint(obj, fil)
173 else:
173 else:
174 fil.write(obj)
174 fil.write(obj)
175 if not obj.endswith('\n'):
175 if not obj.endswith('\n'):
176 fil.write('\n')
176 fil.write('\n')
177
177
178 fil.close()
178 fil.close()
179 return
179 return
180
180
181 # %store foo
181 # %store foo
182 try:
182 try:
183 obj = ip.user_ns[args[0]]
183 obj = ip.user_ns[args[0]]
184 except KeyError:
184 except KeyError:
185 # it might be an alias
185 # it might be an alias
186 # This needs to be refactored to use the new AliasManager stuff.
186 # This needs to be refactored to use the new AliasManager stuff.
187 if args[0] in ip.alias_manager:
187 if args[0] in ip.alias_manager:
188 name = args[0]
188 name = args[0]
189 nargs, cmd = ip.alias_manager.alias_table[ name ]
189 nargs, cmd = ip.alias_manager.alias_table[ name ]
190 staliases = db.get('stored_aliases',{})
190 staliases = db.get('stored_aliases',{})
191 staliases[ name ] = cmd
191 staliases[ name ] = cmd
192 db['stored_aliases'] = staliases
192 db['stored_aliases'] = staliases
193 print "Alias stored: %s (%s)" % (name, cmd)
193 print "Alias stored: %s (%s)" % (name, cmd)
194 return
194 return
195 else:
195 else:
196 raise UsageError("Unknown variable '%s'" % args[0])
196 raise UsageError("Unknown variable '%s'" % args[0])
197
197
198 else:
198 else:
199 if isinstance(inspect.getmodule(obj), FakeModule):
199 if isinstance(inspect.getmodule(obj), FakeModule):
200 print textwrap.dedent("""\
200 print textwrap.dedent("""\
201 Warning:%s is %s
201 Warning:%s is %s
202 Proper storage of interactively declared classes (or instances
202 Proper storage of interactively declared classes (or instances
203 of those classes) is not possible! Only instances
203 of those classes) is not possible! Only instances
204 of classes in real modules on file system can be %%store'd.
204 of classes in real modules on file system can be %%store'd.
205 """ % (args[0], obj) )
205 """ % (args[0], obj) )
206 return
206 return
207 #pickled = pickle.dumps(obj)
207 #pickled = pickle.dumps(obj)
208 db[ 'autorestore/' + args[0] ] = obj
208 db[ 'autorestore/' + args[0] ] = obj
209 print "Stored '%s' (%s)" % (args[0], obj.__class__.__name__)
209 print "Stored '%s' (%s)" % (args[0], obj.__class__.__name__)
210
210
211
211
212 _loaded = False
213
214
215 def load_ipython_extension(ip):
212 def load_ipython_extension(ip):
216 """Load the extension in IPython."""
213 """Load the extension in IPython."""
217 global _loaded
214 ip.register_magics(StoreMagics)
218 if not _loaded:
219 ip.register_magics(StoreMagics)
220 _loaded = True
@@ -1,354 +1,356 b''
1 """Basic ssh tunnel utilities, and convenience functions for tunneling
1 """Basic ssh tunnel utilities, and convenience functions for tunneling
2 zeromq connections.
2 zeromq connections.
3
3
4 Authors
4 Authors
5 -------
5 -------
6 * Min RK
6 * Min RK
7 """
7 """
8
8
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2010-2011 The IPython Development Team
10 # Copyright (C) 2010-2011 The IPython Development Team
11 #
11 #
12 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16
16
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 from __future__ import print_function
22 from __future__ import print_function
23
23
24 import os,sys, atexit
24 import os,sys, atexit
25 import signal
25 import socket
26 import socket
26 from multiprocessing import Process
27 from multiprocessing import Process
27 from getpass import getpass, getuser
28 from getpass import getpass, getuser
28 import warnings
29 import warnings
29
30
30 try:
31 try:
31 with warnings.catch_warnings():
32 with warnings.catch_warnings():
32 warnings.simplefilter('ignore', DeprecationWarning)
33 warnings.simplefilter('ignore', DeprecationWarning)
33 import paramiko
34 import paramiko
34 except ImportError:
35 except ImportError:
35 paramiko = None
36 paramiko = None
36 else:
37 else:
37 from forward import forward_tunnel
38 from forward import forward_tunnel
38
39
39 try:
40 try:
40 from IPython.external import pexpect
41 from IPython.external import pexpect
41 except ImportError:
42 except ImportError:
42 pexpect = None
43 pexpect = None
43
44
44 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
45 # Code
46 # Code
46 #-----------------------------------------------------------------------------
47 #-----------------------------------------------------------------------------
47
48
48 # select_random_ports copied from IPython.parallel.util
49 # select_random_ports copied from IPython.parallel.util
49 _random_ports = set()
50 _random_ports = set()
50
51
51 def select_random_ports(n):
52 def select_random_ports(n):
52 """Selects and return n random ports that are available."""
53 """Selects and return n random ports that are available."""
53 ports = []
54 ports = []
54 for i in xrange(n):
55 for i in xrange(n):
55 sock = socket.socket()
56 sock = socket.socket()
56 sock.bind(('', 0))
57 sock.bind(('', 0))
57 while sock.getsockname()[1] in _random_ports:
58 while sock.getsockname()[1] in _random_ports:
58 sock.close()
59 sock.close()
59 sock = socket.socket()
60 sock = socket.socket()
60 sock.bind(('', 0))
61 sock.bind(('', 0))
61 ports.append(sock)
62 ports.append(sock)
62 for i, sock in enumerate(ports):
63 for i, sock in enumerate(ports):
63 port = sock.getsockname()[1]
64 port = sock.getsockname()[1]
64 sock.close()
65 sock.close()
65 ports[i] = port
66 ports[i] = port
66 _random_ports.add(port)
67 _random_ports.add(port)
67 return ports
68 return ports
68
69
69
70
70 #-----------------------------------------------------------------------------
71 #-----------------------------------------------------------------------------
71 # Check for passwordless login
72 # Check for passwordless login
72 #-----------------------------------------------------------------------------
73 #-----------------------------------------------------------------------------
73
74
74 def try_passwordless_ssh(server, keyfile, paramiko=None):
75 def try_passwordless_ssh(server, keyfile, paramiko=None):
75 """Attempt to make an ssh connection without a password.
76 """Attempt to make an ssh connection without a password.
76 This is mainly used for requiring password input only once
77 This is mainly used for requiring password input only once
77 when many tunnels may be connected to the same server.
78 when many tunnels may be connected to the same server.
78
79
79 If paramiko is None, the default for the platform is chosen.
80 If paramiko is None, the default for the platform is chosen.
80 """
81 """
81 if paramiko is None:
82 if paramiko is None:
82 paramiko = sys.platform == 'win32'
83 paramiko = sys.platform == 'win32'
83 if not paramiko:
84 if not paramiko:
84 f = _try_passwordless_openssh
85 f = _try_passwordless_openssh
85 else:
86 else:
86 f = _try_passwordless_paramiko
87 f = _try_passwordless_paramiko
87 return f(server, keyfile)
88 return f(server, keyfile)
88
89
89 def _try_passwordless_openssh(server, keyfile):
90 def _try_passwordless_openssh(server, keyfile):
90 """Try passwordless login with shell ssh command."""
91 """Try passwordless login with shell ssh command."""
91 if pexpect is None:
92 if pexpect is None:
92 raise ImportError("pexpect unavailable, use paramiko")
93 raise ImportError("pexpect unavailable, use paramiko")
93 cmd = 'ssh -f '+ server
94 cmd = 'ssh -f '+ server
94 if keyfile:
95 if keyfile:
95 cmd += ' -i ' + keyfile
96 cmd += ' -i ' + keyfile
96 cmd += ' exit'
97 cmd += ' exit'
97 p = pexpect.spawn(cmd)
98 p = pexpect.spawn(cmd)
98 while True:
99 while True:
99 try:
100 try:
100 p.expect('[Pp]assword:', timeout=.1)
101 p.expect('[Pp]assword:', timeout=.1)
101 except pexpect.TIMEOUT:
102 except pexpect.TIMEOUT:
102 continue
103 continue
103 except pexpect.EOF:
104 except pexpect.EOF:
104 return True
105 return True
105 else:
106 else:
106 return False
107 return False
107
108
108 def _try_passwordless_paramiko(server, keyfile):
109 def _try_passwordless_paramiko(server, keyfile):
109 """Try passwordless login with paramiko."""
110 """Try passwordless login with paramiko."""
110 if paramiko is None:
111 if paramiko is None:
111 msg = "Paramiko unavaliable, "
112 msg = "Paramiko unavaliable, "
112 if sys.platform == 'win32':
113 if sys.platform == 'win32':
113 msg += "Paramiko is required for ssh tunneled connections on Windows."
114 msg += "Paramiko is required for ssh tunneled connections on Windows."
114 else:
115 else:
115 msg += "use OpenSSH."
116 msg += "use OpenSSH."
116 raise ImportError(msg)
117 raise ImportError(msg)
117 username, server, port = _split_server(server)
118 username, server, port = _split_server(server)
118 client = paramiko.SSHClient()
119 client = paramiko.SSHClient()
119 client.load_system_host_keys()
120 client.load_system_host_keys()
120 client.set_missing_host_key_policy(paramiko.WarningPolicy())
121 client.set_missing_host_key_policy(paramiko.WarningPolicy())
121 try:
122 try:
122 client.connect(server, port, username=username, key_filename=keyfile,
123 client.connect(server, port, username=username, key_filename=keyfile,
123 look_for_keys=True)
124 look_for_keys=True)
124 except paramiko.AuthenticationException:
125 except paramiko.AuthenticationException:
125 return False
126 return False
126 else:
127 else:
127 client.close()
128 client.close()
128 return True
129 return True
129
130
130
131
131 def tunnel_connection(socket, addr, server, keyfile=None, password=None, paramiko=None, timeout=60):
132 def tunnel_connection(socket, addr, server, keyfile=None, password=None, paramiko=None, timeout=60):
132 """Connect a socket to an address via an ssh tunnel.
133 """Connect a socket to an address via an ssh tunnel.
133
134
134 This is a wrapper for socket.connect(addr), when addr is not accessible
135 This is a wrapper for socket.connect(addr), when addr is not accessible
135 from the local machine. It simply creates an ssh tunnel using the remaining args,
136 from the local machine. It simply creates an ssh tunnel using the remaining args,
136 and calls socket.connect('tcp://localhost:lport') where lport is the randomly
137 and calls socket.connect('tcp://localhost:lport') where lport is the randomly
137 selected local port of the tunnel.
138 selected local port of the tunnel.
138
139
139 """
140 """
140 new_url, tunnel = open_tunnel(addr, server, keyfile=keyfile, password=password, paramiko=paramiko, timeout=timeout)
141 new_url, tunnel = open_tunnel(addr, server, keyfile=keyfile, password=password, paramiko=paramiko, timeout=timeout)
141 socket.connect(new_url)
142 socket.connect(new_url)
142 return tunnel
143 return tunnel
143
144
144
145
145 def open_tunnel(addr, server, keyfile=None, password=None, paramiko=None, timeout=60):
146 def open_tunnel(addr, server, keyfile=None, password=None, paramiko=None, timeout=60):
146 """Open a tunneled connection from a 0MQ url.
147 """Open a tunneled connection from a 0MQ url.
147
148
148 For use inside tunnel_connection.
149 For use inside tunnel_connection.
149
150
150 Returns
151 Returns
151 -------
152 -------
152
153
153 (url, tunnel): The 0MQ url that has been forwarded, and the tunnel object
154 (url, tunnel): The 0MQ url that has been forwarded, and the tunnel object
154 """
155 """
155
156
156 lport = select_random_ports(1)[0]
157 lport = select_random_ports(1)[0]
157 transport, addr = addr.split('://')
158 transport, addr = addr.split('://')
158 ip,rport = addr.split(':')
159 ip,rport = addr.split(':')
159 rport = int(rport)
160 rport = int(rport)
160 if paramiko is None:
161 if paramiko is None:
161 paramiko = sys.platform == 'win32'
162 paramiko = sys.platform == 'win32'
162 if paramiko:
163 if paramiko:
163 tunnelf = paramiko_tunnel
164 tunnelf = paramiko_tunnel
164 else:
165 else:
165 tunnelf = openssh_tunnel
166 tunnelf = openssh_tunnel
166
167
167 tunnel = tunnelf(lport, rport, server, remoteip=ip, keyfile=keyfile, password=password, timeout=timeout)
168 tunnel = tunnelf(lport, rport, server, remoteip=ip, keyfile=keyfile, password=password, timeout=timeout)
168 return 'tcp://127.0.0.1:%i'%lport, tunnel
169 return 'tcp://127.0.0.1:%i'%lport, tunnel
169
170
170 def openssh_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, password=None, timeout=60):
171 def openssh_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, password=None, timeout=60):
171 """Create an ssh tunnel using command-line ssh that connects port lport
172 """Create an ssh tunnel using command-line ssh that connects port lport
172 on this machine to localhost:rport on server. The tunnel
173 on this machine to localhost:rport on server. The tunnel
173 will automatically close when not in use, remaining open
174 will automatically close when not in use, remaining open
174 for a minimum of timeout seconds for an initial connection.
175 for a minimum of timeout seconds for an initial connection.
175
176
176 This creates a tunnel redirecting `localhost:lport` to `remoteip:rport`,
177 This creates a tunnel redirecting `localhost:lport` to `remoteip:rport`,
177 as seen from `server`.
178 as seen from `server`.
178
179
179 keyfile and password may be specified, but ssh config is checked for defaults.
180 keyfile and password may be specified, but ssh config is checked for defaults.
180
181
181 Parameters
182 Parameters
182 ----------
183 ----------
183
184
184 lport : int
185 lport : int
185 local port for connecting to the tunnel from this machine.
186 local port for connecting to the tunnel from this machine.
186 rport : int
187 rport : int
187 port on the remote machine to connect to.
188 port on the remote machine to connect to.
188 server : str
189 server : str
189 The ssh server to connect to. The full ssh server string will be parsed.
190 The ssh server to connect to. The full ssh server string will be parsed.
190 user@server:port
191 user@server:port
191 remoteip : str [Default: 127.0.0.1]
192 remoteip : str [Default: 127.0.0.1]
192 The remote ip, specifying the destination of the tunnel.
193 The remote ip, specifying the destination of the tunnel.
193 Default is localhost, which means that the tunnel would redirect
194 Default is localhost, which means that the tunnel would redirect
194 localhost:lport on this machine to localhost:rport on the *server*.
195 localhost:lport on this machine to localhost:rport on the *server*.
195
196
196 keyfile : str; path to public key file
197 keyfile : str; path to public key file
197 This specifies a key to be used in ssh login, default None.
198 This specifies a key to be used in ssh login, default None.
198 Regular default ssh keys will be used without specifying this argument.
199 Regular default ssh keys will be used without specifying this argument.
199 password : str;
200 password : str;
200 Your ssh password to the ssh server. Note that if this is left None,
201 Your ssh password to the ssh server. Note that if this is left None,
201 you will be prompted for it if passwordless key based login is unavailable.
202 you will be prompted for it if passwordless key based login is unavailable.
202 timeout : int [default: 60]
203 timeout : int [default: 60]
203 The time (in seconds) after which no activity will result in the tunnel
204 The time (in seconds) after which no activity will result in the tunnel
204 closing. This prevents orphaned tunnels from running forever.
205 closing. This prevents orphaned tunnels from running forever.
205 """
206 """
206 if pexpect is None:
207 if pexpect is None:
207 raise ImportError("pexpect unavailable, use paramiko_tunnel")
208 raise ImportError("pexpect unavailable, use paramiko_tunnel")
208 ssh="ssh "
209 ssh="ssh "
209 if keyfile:
210 if keyfile:
210 ssh += "-i " + keyfile
211 ssh += "-i " + keyfile
211
212
212 if ':' in server:
213 if ':' in server:
213 server, port = server.split(':')
214 server, port = server.split(':')
214 ssh += " -p %s" % port
215 ssh += " -p %s" % port
215
216
216 cmd = "%s -f -L 127.0.0.1:%i:%s:%i %s sleep %i" % (
217 cmd = "%s -f -L 127.0.0.1:%i:%s:%i %s sleep %i" % (
217 ssh, lport, remoteip, rport, server, timeout)
218 ssh, lport, remoteip, rport, server, timeout)
218 tunnel = pexpect.spawn(cmd)
219 tunnel = pexpect.spawn(cmd)
219 failed = False
220 failed = False
220 while True:
221 while True:
221 try:
222 try:
222 tunnel.expect('[Pp]assword:', timeout=.1)
223 tunnel.expect('[Pp]assword:', timeout=.1)
223 except pexpect.TIMEOUT:
224 except pexpect.TIMEOUT:
224 continue
225 continue
225 except pexpect.EOF:
226 except pexpect.EOF:
226 if tunnel.exitstatus:
227 if tunnel.exitstatus:
227 print (tunnel.exitstatus)
228 print (tunnel.exitstatus)
228 print (tunnel.before)
229 print (tunnel.before)
229 print (tunnel.after)
230 print (tunnel.after)
230 raise RuntimeError("tunnel '%s' failed to start"%(cmd))
231 raise RuntimeError("tunnel '%s' failed to start"%(cmd))
231 else:
232 else:
232 return tunnel.pid
233 return tunnel.pid
233 else:
234 else:
234 if failed:
235 if failed:
235 print("Password rejected, try again")
236 print("Password rejected, try again")
236 password=None
237 password=None
237 if password is None:
238 if password is None:
238 password = getpass("%s's password: "%(server))
239 password = getpass("%s's password: "%(server))
239 tunnel.sendline(password)
240 tunnel.sendline(password)
240 failed = True
241 failed = True
241
242
242 def _split_server(server):
243 def _split_server(server):
243 if '@' in server:
244 if '@' in server:
244 username,server = server.split('@', 1)
245 username,server = server.split('@', 1)
245 else:
246 else:
246 username = getuser()
247 username = getuser()
247 if ':' in server:
248 if ':' in server:
248 server, port = server.split(':')
249 server, port = server.split(':')
249 port = int(port)
250 port = int(port)
250 else:
251 else:
251 port = 22
252 port = 22
252 return username, server, port
253 return username, server, port
253
254
254 def paramiko_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, password=None, timeout=60):
255 def paramiko_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, password=None, timeout=60):
255 """launch a tunner with paramiko in a subprocess. This should only be used
256 """launch a tunner with paramiko in a subprocess. This should only be used
256 when shell ssh is unavailable (e.g. Windows).
257 when shell ssh is unavailable (e.g. Windows).
257
258
258 This creates a tunnel redirecting `localhost:lport` to `remoteip:rport`,
259 This creates a tunnel redirecting `localhost:lport` to `remoteip:rport`,
259 as seen from `server`.
260 as seen from `server`.
260
261
261 If you are familiar with ssh tunnels, this creates the tunnel:
262 If you are familiar with ssh tunnels, this creates the tunnel:
262
263
263 ssh server -L localhost:lport:remoteip:rport
264 ssh server -L localhost:lport:remoteip:rport
264
265
265 keyfile and password may be specified, but ssh config is checked for defaults.
266 keyfile and password may be specified, but ssh config is checked for defaults.
266
267
267
268
268 Parameters
269 Parameters
269 ----------
270 ----------
270
271
271 lport : int
272 lport : int
272 local port for connecting to the tunnel from this machine.
273 local port for connecting to the tunnel from this machine.
273 rport : int
274 rport : int
274 port on the remote machine to connect to.
275 port on the remote machine to connect to.
275 server : str
276 server : str
276 The ssh server to connect to. The full ssh server string will be parsed.
277 The ssh server to connect to. The full ssh server string will be parsed.
277 user@server:port
278 user@server:port
278 remoteip : str [Default: 127.0.0.1]
279 remoteip : str [Default: 127.0.0.1]
279 The remote ip, specifying the destination of the tunnel.
280 The remote ip, specifying the destination of the tunnel.
280 Default is localhost, which means that the tunnel would redirect
281 Default is localhost, which means that the tunnel would redirect
281 localhost:lport on this machine to localhost:rport on the *server*.
282 localhost:lport on this machine to localhost:rport on the *server*.
282
283
283 keyfile : str; path to public key file
284 keyfile : str; path to public key file
284 This specifies a key to be used in ssh login, default None.
285 This specifies a key to be used in ssh login, default None.
285 Regular default ssh keys will be used without specifying this argument.
286 Regular default ssh keys will be used without specifying this argument.
286 password : str;
287 password : str;
287 Your ssh password to the ssh server. Note that if this is left None,
288 Your ssh password to the ssh server. Note that if this is left None,
288 you will be prompted for it if passwordless key based login is unavailable.
289 you will be prompted for it if passwordless key based login is unavailable.
289 timeout : int [default: 60]
290 timeout : int [default: 60]
290 The time (in seconds) after which no activity will result in the tunnel
291 The time (in seconds) after which no activity will result in the tunnel
291 closing. This prevents orphaned tunnels from running forever.
292 closing. This prevents orphaned tunnels from running forever.
292
293
293 """
294 """
294 if paramiko is None:
295 if paramiko is None:
295 raise ImportError("Paramiko not available")
296 raise ImportError("Paramiko not available")
296
297
297 if password is None:
298 if password is None:
298 if not _try_passwordless_paramiko(server, keyfile):
299 if not _try_passwordless_paramiko(server, keyfile):
299 password = getpass("%s's password: "%(server))
300 password = getpass("%s's password: "%(server))
300
301
301 p = Process(target=_paramiko_tunnel,
302 p = Process(target=_paramiko_tunnel,
302 args=(lport, rport, server, remoteip),
303 args=(lport, rport, server, remoteip),
303 kwargs=dict(keyfile=keyfile, password=password))
304 kwargs=dict(keyfile=keyfile, password=password))
304 p.daemon=False
305 p.daemon=False
305 p.start()
306 p.start()
306 atexit.register(_shutdown_process, p)
307 atexit.register(_shutdown_process, p)
307 return p
308 return p
308
309
309 def _shutdown_process(p):
310 def _shutdown_process(p):
310 if p.is_alive():
311 if p.is_alive():
311 p.terminate()
312 p.terminate()
312
313
313 def _paramiko_tunnel(lport, rport, server, remoteip, keyfile=None, password=None):
314 def _paramiko_tunnel(lport, rport, server, remoteip, keyfile=None, password=None):
314 """Function for actually starting a paramiko tunnel, to be passed
315 """Function for actually starting a paramiko tunnel, to be passed
315 to multiprocessing.Process(target=this), and not called directly.
316 to multiprocessing.Process(target=this), and not called directly.
316 """
317 """
317 username, server, port = _split_server(server)
318 username, server, port = _split_server(server)
318 client = paramiko.SSHClient()
319 client = paramiko.SSHClient()
319 client.load_system_host_keys()
320 client.load_system_host_keys()
320 client.set_missing_host_key_policy(paramiko.WarningPolicy())
321 client.set_missing_host_key_policy(paramiko.WarningPolicy())
321
322
322 try:
323 try:
323 client.connect(server, port, username=username, key_filename=keyfile,
324 client.connect(server, port, username=username, key_filename=keyfile,
324 look_for_keys=True, password=password)
325 look_for_keys=True, password=password)
325 # except paramiko.AuthenticationException:
326 # except paramiko.AuthenticationException:
326 # if password is None:
327 # if password is None:
327 # password = getpass("%s@%s's password: "%(username, server))
328 # password = getpass("%s@%s's password: "%(username, server))
328 # client.connect(server, port, username=username, password=password)
329 # client.connect(server, port, username=username, password=password)
329 # else:
330 # else:
330 # raise
331 # raise
331 except Exception as e:
332 except Exception as e:
332 print ('*** Failed to connect to %s:%d: %r' % (server, port, e))
333 print ('*** Failed to connect to %s:%d: %r' % (server, port, e))
333 sys.exit(1)
334 sys.exit(1)
334
335
335 # print ('Now forwarding port %d to %s:%d ...' % (lport, server, rport))
336 # Don't let SIGINT kill the tunnel subprocess
336
337 signal.signal(signal.SIGINT, signal.SIG_IGN)
338
337 try:
339 try:
338 forward_tunnel(lport, remoteip, rport, client.get_transport())
340 forward_tunnel(lport, remoteip, rport, client.get_transport())
339 except KeyboardInterrupt:
341 except KeyboardInterrupt:
340 print ('SIGINT: Port forwarding stopped cleanly')
342 print ('SIGINT: Port forwarding stopped cleanly')
341 sys.exit(0)
343 sys.exit(0)
342 except Exception as e:
344 except Exception as e:
343 print ("Port forwarding stopped uncleanly: %s"%e)
345 print ("Port forwarding stopped uncleanly: %s"%e)
344 sys.exit(255)
346 sys.exit(255)
345
347
346 if sys.platform == 'win32':
348 if sys.platform == 'win32':
347 ssh_tunnel = paramiko_tunnel
349 ssh_tunnel = paramiko_tunnel
348 else:
350 else:
349 ssh_tunnel = openssh_tunnel
351 ssh_tunnel = openssh_tunnel
350
352
351
353
352 __all__ = ['tunnel_connection', 'ssh_tunnel', 'openssh_tunnel', 'paramiko_tunnel', 'try_passwordless_ssh']
354 __all__ = ['tunnel_connection', 'ssh_tunnel', 'openssh_tunnel', 'paramiko_tunnel', 'try_passwordless_ssh']
353
355
354
356
@@ -1,619 +1,622 b''
1 # coding: utf-8
1 # coding: utf-8
2 """A tornado based IPython notebook server.
2 """A tornado based IPython notebook server.
3
3
4 Authors:
4 Authors:
5
5
6 * Brian Granger
6 * Brian Granger
7 """
7 """
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2008-2011 The IPython Development Team
9 # Copyright (C) 2008-2011 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 # stdlib
19 # stdlib
20 import errno
20 import errno
21 import logging
21 import logging
22 import os
22 import os
23 import random
23 import random
24 import re
24 import re
25 import select
25 import select
26 import signal
26 import signal
27 import socket
27 import socket
28 import sys
28 import sys
29 import threading
29 import threading
30 import time
30 import time
31 import uuid
31 import uuid
32 import webbrowser
32 import webbrowser
33
33
34 # Third party
34 # Third party
35 import zmq
35 import zmq
36
36
37 # Install the pyzmq ioloop. This has to be done before anything else from
37 # Install the pyzmq ioloop. This has to be done before anything else from
38 # tornado is imported.
38 # tornado is imported.
39 from zmq.eventloop import ioloop
39 from zmq.eventloop import ioloop
40 ioloop.install()
40 ioloop.install()
41
41
42 from tornado import httpserver
42 from tornado import httpserver
43 from tornado import web
43 from tornado import web
44
44
45 # Our own libraries
45 # Our own libraries
46 from .kernelmanager import MappingKernelManager
46 from .kernelmanager import MappingKernelManager
47 from .handlers import (LoginHandler, LogoutHandler,
47 from .handlers import (LoginHandler, LogoutHandler,
48 ProjectDashboardHandler, NewHandler, NamedNotebookHandler,
48 ProjectDashboardHandler, NewHandler, NamedNotebookHandler,
49 MainKernelHandler, KernelHandler, KernelActionHandler, IOPubHandler,
49 MainKernelHandler, KernelHandler, KernelActionHandler, IOPubHandler,
50 ShellHandler, NotebookRootHandler, NotebookHandler, NotebookCopyHandler,
50 ShellHandler, NotebookRootHandler, NotebookHandler, NotebookCopyHandler,
51 RSTHandler, AuthenticatedFileHandler, PrintNotebookHandler,
51 RSTHandler, AuthenticatedFileHandler, PrintNotebookHandler,
52 MainClusterHandler, ClusterProfileHandler, ClusterActionHandler,
52 MainClusterHandler, ClusterProfileHandler, ClusterActionHandler,
53 FileFindHandler,
53 FileFindHandler,
54 )
54 )
55 from .nbmanager import NotebookManager
55 from .nbmanager import NotebookManager
56 from .filenbmanager import FileNotebookManager
56 from .filenbmanager import FileNotebookManager
57 from .clustermanager import ClusterManager
57 from .clustermanager import ClusterManager
58
58
59 from IPython.config.application import catch_config_error, boolean_flag
59 from IPython.config.application import catch_config_error, boolean_flag
60 from IPython.core.application import BaseIPythonApplication
60 from IPython.core.application import BaseIPythonApplication
61 from IPython.core.profiledir import ProfileDir
61 from IPython.core.profiledir import ProfileDir
62 from IPython.frontend.consoleapp import IPythonConsoleApp
62 from IPython.frontend.consoleapp import IPythonConsoleApp
63 from IPython.lib.kernel import swallow_argv
63 from IPython.lib.kernel import swallow_argv
64 from IPython.zmq.session import Session, default_secure
64 from IPython.zmq.session import Session, default_secure
65 from IPython.zmq.zmqshell import ZMQInteractiveShell
65 from IPython.zmq.zmqshell import ZMQInteractiveShell
66 from IPython.zmq.ipkernel import (
66 from IPython.zmq.ipkernel import (
67 flags as ipkernel_flags,
67 flags as ipkernel_flags,
68 aliases as ipkernel_aliases,
68 aliases as ipkernel_aliases,
69 IPKernelApp
69 IPKernelApp
70 )
70 )
71 from IPython.utils.importstring import import_item
71 from IPython.utils.importstring import import_item
72 from IPython.utils.traitlets import (
72 from IPython.utils.traitlets import (
73 Dict, Unicode, Integer, List, Enum, Bool,
73 Dict, Unicode, Integer, List, Enum, Bool,
74 DottedObjectName
74 DottedObjectName
75 )
75 )
76 from IPython.utils import py3compat
76 from IPython.utils import py3compat
77 from IPython.utils.path import filefind
77 from IPython.utils.path import filefind
78
78
79 #-----------------------------------------------------------------------------
79 #-----------------------------------------------------------------------------
80 # Module globals
80 # Module globals
81 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
82
82
83 _kernel_id_regex = r"(?P<kernel_id>\w+-\w+-\w+-\w+-\w+)"
83 _kernel_id_regex = r"(?P<kernel_id>\w+-\w+-\w+-\w+-\w+)"
84 _kernel_action_regex = r"(?P<action>restart|interrupt)"
84 _kernel_action_regex = r"(?P<action>restart|interrupt)"
85 _notebook_id_regex = r"(?P<notebook_id>\w+-\w+-\w+-\w+-\w+)"
85 _notebook_id_regex = r"(?P<notebook_id>\w+-\w+-\w+-\w+-\w+)"
86 _profile_regex = r"(?P<profile>[^\/]+)" # there is almost no text that is invalid
86 _profile_regex = r"(?P<profile>[^\/]+)" # there is almost no text that is invalid
87 _cluster_action_regex = r"(?P<action>start|stop)"
87 _cluster_action_regex = r"(?P<action>start|stop)"
88
88
89
89
90 LOCALHOST = '127.0.0.1'
90 LOCALHOST = '127.0.0.1'
91
91
92 _examples = """
92 _examples = """
93 ipython notebook # start the notebook
93 ipython notebook # start the notebook
94 ipython notebook --profile=sympy # use the sympy profile
94 ipython notebook --profile=sympy # use the sympy profile
95 ipython notebook --pylab=inline # pylab in inline plotting mode
95 ipython notebook --pylab=inline # pylab in inline plotting mode
96 ipython notebook --certfile=mycert.pem # use SSL/TLS certificate
96 ipython notebook --certfile=mycert.pem # use SSL/TLS certificate
97 ipython notebook --port=5555 --ip=* # Listen on port 5555, all interfaces
97 ipython notebook --port=5555 --ip=* # Listen on port 5555, all interfaces
98 """
98 """
99
99
100 #-----------------------------------------------------------------------------
100 #-----------------------------------------------------------------------------
101 # Helper functions
101 # Helper functions
102 #-----------------------------------------------------------------------------
102 #-----------------------------------------------------------------------------
103
103
104 def url_path_join(a,b):
104 def url_path_join(a,b):
105 if a.endswith('/') and b.startswith('/'):
105 if a.endswith('/') and b.startswith('/'):
106 return a[:-1]+b
106 return a[:-1]+b
107 else:
107 else:
108 return a+b
108 return a+b
109
109
110 def random_ports(port, n):
110 def random_ports(port, n):
111 """Generate a list of n random ports near the given port.
111 """Generate a list of n random ports near the given port.
112
112
113 The first 5 ports will be sequential, and the remaining n-5 will be
113 The first 5 ports will be sequential, and the remaining n-5 will be
114 randomly selected in the range [port-2*n, port+2*n].
114 randomly selected in the range [port-2*n, port+2*n].
115 """
115 """
116 for i in range(min(5, n)):
116 for i in range(min(5, n)):
117 yield port + i
117 yield port + i
118 for i in range(n-5):
118 for i in range(n-5):
119 yield port + random.randint(-2*n, 2*n)
119 yield port + random.randint(-2*n, 2*n)
120
120
121 #-----------------------------------------------------------------------------
121 #-----------------------------------------------------------------------------
122 # The Tornado web application
122 # The Tornado web application
123 #-----------------------------------------------------------------------------
123 #-----------------------------------------------------------------------------
124
124
125 class NotebookWebApplication(web.Application):
125 class NotebookWebApplication(web.Application):
126
126
127 def __init__(self, ipython_app, kernel_manager, notebook_manager,
127 def __init__(self, ipython_app, kernel_manager, notebook_manager,
128 cluster_manager, log,
128 cluster_manager, log,
129 base_project_url, settings_overrides):
129 base_project_url, settings_overrides):
130 handlers = [
130 handlers = [
131 (r"/", ProjectDashboardHandler),
131 (r"/", ProjectDashboardHandler),
132 (r"/login", LoginHandler),
132 (r"/login", LoginHandler),
133 (r"/logout", LogoutHandler),
133 (r"/logout", LogoutHandler),
134 (r"/new", NewHandler),
134 (r"/new", NewHandler),
135 (r"/%s" % _notebook_id_regex, NamedNotebookHandler),
135 (r"/%s" % _notebook_id_regex, NamedNotebookHandler),
136 (r"/%s/copy" % _notebook_id_regex, NotebookCopyHandler),
136 (r"/%s/copy" % _notebook_id_regex, NotebookCopyHandler),
137 (r"/%s/print" % _notebook_id_regex, PrintNotebookHandler),
137 (r"/%s/print" % _notebook_id_regex, PrintNotebookHandler),
138 (r"/kernels", MainKernelHandler),
138 (r"/kernels", MainKernelHandler),
139 (r"/kernels/%s" % _kernel_id_regex, KernelHandler),
139 (r"/kernels/%s" % _kernel_id_regex, KernelHandler),
140 (r"/kernels/%s/%s" % (_kernel_id_regex, _kernel_action_regex), KernelActionHandler),
140 (r"/kernels/%s/%s" % (_kernel_id_regex, _kernel_action_regex), KernelActionHandler),
141 (r"/kernels/%s/iopub" % _kernel_id_regex, IOPubHandler),
141 (r"/kernels/%s/iopub" % _kernel_id_regex, IOPubHandler),
142 (r"/kernels/%s/shell" % _kernel_id_regex, ShellHandler),
142 (r"/kernels/%s/shell" % _kernel_id_regex, ShellHandler),
143 (r"/notebooks", NotebookRootHandler),
143 (r"/notebooks", NotebookRootHandler),
144 (r"/notebooks/%s" % _notebook_id_regex, NotebookHandler),
144 (r"/notebooks/%s" % _notebook_id_regex, NotebookHandler),
145 (r"/rstservice/render", RSTHandler),
145 (r"/rstservice/render", RSTHandler),
146 (r"/files/(.*)", AuthenticatedFileHandler, {'path' : notebook_manager.notebook_dir}),
146 (r"/files/(.*)", AuthenticatedFileHandler, {'path' : notebook_manager.notebook_dir}),
147 (r"/clusters", MainClusterHandler),
147 (r"/clusters", MainClusterHandler),
148 (r"/clusters/%s/%s" % (_profile_regex, _cluster_action_regex), ClusterActionHandler),
148 (r"/clusters/%s/%s" % (_profile_regex, _cluster_action_regex), ClusterActionHandler),
149 (r"/clusters/%s" % _profile_regex, ClusterProfileHandler),
149 (r"/clusters/%s" % _profile_regex, ClusterProfileHandler),
150 ]
150 ]
151
151
152 # Python < 2.6.5 doesn't accept unicode keys in f(**kwargs), and
152 # Python < 2.6.5 doesn't accept unicode keys in f(**kwargs), and
153 # base_project_url will always be unicode, which will in turn
153 # base_project_url will always be unicode, which will in turn
154 # make the patterns unicode, and ultimately result in unicode
154 # make the patterns unicode, and ultimately result in unicode
155 # keys in kwargs to handler._execute(**kwargs) in tornado.
155 # keys in kwargs to handler._execute(**kwargs) in tornado.
156 # This enforces that base_project_url be ascii in that situation.
156 # This enforces that base_project_url be ascii in that situation.
157 #
157 #
158 # Note that the URLs these patterns check against are escaped,
158 # Note that the URLs these patterns check against are escaped,
159 # and thus guaranteed to be ASCII: 'héllo' is really 'h%C3%A9llo'.
159 # and thus guaranteed to be ASCII: 'héllo' is really 'h%C3%A9llo'.
160 base_project_url = py3compat.unicode_to_str(base_project_url, 'ascii')
160 base_project_url = py3compat.unicode_to_str(base_project_url, 'ascii')
161
161
162 settings = dict(
162 settings = dict(
163 template_path=os.path.join(os.path.dirname(__file__), "templates"),
163 template_path=os.path.join(os.path.dirname(__file__), "templates"),
164 static_path=ipython_app.static_file_path,
164 static_path=ipython_app.static_file_path,
165 static_handler_class = FileFindHandler,
165 static_handler_class = FileFindHandler,
166 cookie_secret=os.urandom(1024),
166 cookie_secret=os.urandom(1024),
167 login_url="%s/login"%(base_project_url.rstrip('/')),
167 login_url="%s/login"%(base_project_url.rstrip('/')),
168 cookie_name='username-%s' % uuid.uuid4(),
168 cookie_name='username-%s' % uuid.uuid4(),
169 )
169 )
170
170
171 # allow custom overrides for the tornado web app.
171 # allow custom overrides for the tornado web app.
172 settings.update(settings_overrides)
172 settings.update(settings_overrides)
173
173
174 # prepend base_project_url onto the patterns that we match
174 # prepend base_project_url onto the patterns that we match
175 new_handlers = []
175 new_handlers = []
176 for handler in handlers:
176 for handler in handlers:
177 pattern = url_path_join(base_project_url, handler[0])
177 pattern = url_path_join(base_project_url, handler[0])
178 new_handler = tuple([pattern]+list(handler[1:]))
178 new_handler = tuple([pattern]+list(handler[1:]))
179 new_handlers.append( new_handler )
179 new_handlers.append( new_handler )
180
180
181 super(NotebookWebApplication, self).__init__(new_handlers, **settings)
181 super(NotebookWebApplication, self).__init__(new_handlers, **settings)
182
182
183 self.kernel_manager = kernel_manager
183 self.kernel_manager = kernel_manager
184 self.notebook_manager = notebook_manager
184 self.notebook_manager = notebook_manager
185 self.cluster_manager = cluster_manager
185 self.cluster_manager = cluster_manager
186 self.ipython_app = ipython_app
186 self.ipython_app = ipython_app
187 self.read_only = self.ipython_app.read_only
187 self.read_only = self.ipython_app.read_only
188 self.log = log
188 self.log = log
189
189
190
190
191 #-----------------------------------------------------------------------------
191 #-----------------------------------------------------------------------------
192 # Aliases and Flags
192 # Aliases and Flags
193 #-----------------------------------------------------------------------------
193 #-----------------------------------------------------------------------------
194
194
195 flags = dict(ipkernel_flags)
195 flags = dict(ipkernel_flags)
196 flags['no-browser']=(
196 flags['no-browser']=(
197 {'NotebookApp' : {'open_browser' : False}},
197 {'NotebookApp' : {'open_browser' : False}},
198 "Don't open the notebook in a browser after startup."
198 "Don't open the notebook in a browser after startup."
199 )
199 )
200 flags['no-mathjax']=(
200 flags['no-mathjax']=(
201 {'NotebookApp' : {'enable_mathjax' : False}},
201 {'NotebookApp' : {'enable_mathjax' : False}},
202 """Disable MathJax
202 """Disable MathJax
203
203
204 MathJax is the javascript library IPython uses to render math/LaTeX. It is
204 MathJax is the javascript library IPython uses to render math/LaTeX. It is
205 very large, so you may want to disable it if you have a slow internet
205 very large, so you may want to disable it if you have a slow internet
206 connection, or for offline use of the notebook.
206 connection, or for offline use of the notebook.
207
207
208 When disabled, equations etc. will appear as their untransformed TeX source.
208 When disabled, equations etc. will appear as their untransformed TeX source.
209 """
209 """
210 )
210 )
211 flags['read-only'] = (
211 flags['read-only'] = (
212 {'NotebookApp' : {'read_only' : True}},
212 {'NotebookApp' : {'read_only' : True}},
213 """Allow read-only access to notebooks.
213 """Allow read-only access to notebooks.
214
214
215 When using a password to protect the notebook server, this flag
215 When using a password to protect the notebook server, this flag
216 allows unauthenticated clients to view the notebook list, and
216 allows unauthenticated clients to view the notebook list, and
217 individual notebooks, but not edit them, start kernels, or run
217 individual notebooks, but not edit them, start kernels, or run
218 code.
218 code.
219
219
220 If no password is set, the server will be entirely read-only.
220 If no password is set, the server will be entirely read-only.
221 """
221 """
222 )
222 )
223
223
224 # Add notebook manager flags
224 # Add notebook manager flags
225 flags.update(boolean_flag('script', 'FileNotebookManager.save_script',
225 flags.update(boolean_flag('script', 'FileNotebookManager.save_script',
226 'Auto-save a .py script everytime the .ipynb notebook is saved',
226 'Auto-save a .py script everytime the .ipynb notebook is saved',
227 'Do not auto-save .py scripts for every notebook'))
227 'Do not auto-save .py scripts for every notebook'))
228
228
229 # the flags that are specific to the frontend
229 # the flags that are specific to the frontend
230 # these must be scrubbed before being passed to the kernel,
230 # these must be scrubbed before being passed to the kernel,
231 # or it will raise an error on unrecognized flags
231 # or it will raise an error on unrecognized flags
232 notebook_flags = ['no-browser', 'no-mathjax', 'read-only', 'script', 'no-script']
232 notebook_flags = ['no-browser', 'no-mathjax', 'read-only', 'script', 'no-script']
233
233
234 aliases = dict(ipkernel_aliases)
234 aliases = dict(ipkernel_aliases)
235
235
236 aliases.update({
236 aliases.update({
237 'ip': 'NotebookApp.ip',
237 'ip': 'NotebookApp.ip',
238 'port': 'NotebookApp.port',
238 'port': 'NotebookApp.port',
239 'port-retries': 'NotebookApp.port_retries',
239 'port-retries': 'NotebookApp.port_retries',
240 'keyfile': 'NotebookApp.keyfile',
240 'keyfile': 'NotebookApp.keyfile',
241 'certfile': 'NotebookApp.certfile',
241 'certfile': 'NotebookApp.certfile',
242 'notebook-dir': 'NotebookManager.notebook_dir',
242 'notebook-dir': 'NotebookManager.notebook_dir',
243 'browser': 'NotebookApp.browser',
243 'browser': 'NotebookApp.browser',
244 })
244 })
245
245
246 # remove ipkernel flags that are singletons, and don't make sense in
246 # remove ipkernel flags that are singletons, and don't make sense in
247 # multi-kernel evironment:
247 # multi-kernel evironment:
248 aliases.pop('f', None)
248 aliases.pop('f', None)
249
249
250 notebook_aliases = [u'port', u'port-retries', u'ip', u'keyfile', u'certfile',
250 notebook_aliases = [u'port', u'port-retries', u'ip', u'keyfile', u'certfile',
251 u'notebook-dir']
251 u'notebook-dir']
252
252
253 #-----------------------------------------------------------------------------
253 #-----------------------------------------------------------------------------
254 # NotebookApp
254 # NotebookApp
255 #-----------------------------------------------------------------------------
255 #-----------------------------------------------------------------------------
256
256
257 class NotebookApp(BaseIPythonApplication):
257 class NotebookApp(BaseIPythonApplication):
258
258
259 name = 'ipython-notebook'
259 name = 'ipython-notebook'
260 default_config_file_name='ipython_notebook_config.py'
260 default_config_file_name='ipython_notebook_config.py'
261
261
262 description = """
262 description = """
263 The IPython HTML Notebook.
263 The IPython HTML Notebook.
264
264
265 This launches a Tornado based HTML Notebook Server that serves up an
265 This launches a Tornado based HTML Notebook Server that serves up an
266 HTML5/Javascript Notebook client.
266 HTML5/Javascript Notebook client.
267 """
267 """
268 examples = _examples
268 examples = _examples
269
269
270 classes = IPythonConsoleApp.classes + [MappingKernelManager, NotebookManager,
270 classes = IPythonConsoleApp.classes + [MappingKernelManager, NotebookManager,
271 FileNotebookManager]
271 FileNotebookManager]
272 flags = Dict(flags)
272 flags = Dict(flags)
273 aliases = Dict(aliases)
273 aliases = Dict(aliases)
274
274
275 kernel_argv = List(Unicode)
275 kernel_argv = List(Unicode)
276
276
277 log_level = Enum((0,10,20,30,40,50,'DEBUG','INFO','WARN','ERROR','CRITICAL'),
277 log_level = Enum((0,10,20,30,40,50,'DEBUG','INFO','WARN','ERROR','CRITICAL'),
278 default_value=logging.INFO,
278 default_value=logging.INFO,
279 config=True,
279 config=True,
280 help="Set the log level by value or name.")
280 help="Set the log level by value or name.")
281
281
282 # create requested profiles by default, if they don't exist:
282 # create requested profiles by default, if they don't exist:
283 auto_create = Bool(True)
283 auto_create = Bool(True)
284
284
285 # file to be opened in the notebook server
285 # file to be opened in the notebook server
286 file_to_run = Unicode('')
286 file_to_run = Unicode('')
287
287
288 # Network related information.
288 # Network related information.
289
289
290 ip = Unicode(LOCALHOST, config=True,
290 ip = Unicode(LOCALHOST, config=True,
291 help="The IP address the notebook server will listen on."
291 help="The IP address the notebook server will listen on."
292 )
292 )
293
293
294 def _ip_changed(self, name, old, new):
294 def _ip_changed(self, name, old, new):
295 if new == u'*': self.ip = u''
295 if new == u'*': self.ip = u''
296
296
297 port = Integer(8888, config=True,
297 port = Integer(8888, config=True,
298 help="The port the notebook server will listen on."
298 help="The port the notebook server will listen on."
299 )
299 )
300 port_retries = Integer(50, config=True,
300 port_retries = Integer(50, config=True,
301 help="The number of additional ports to try if the specified port is not available."
301 help="The number of additional ports to try if the specified port is not available."
302 )
302 )
303
303
304 certfile = Unicode(u'', config=True,
304 certfile = Unicode(u'', config=True,
305 help="""The full path to an SSL/TLS certificate file."""
305 help="""The full path to an SSL/TLS certificate file."""
306 )
306 )
307
307
308 keyfile = Unicode(u'', config=True,
308 keyfile = Unicode(u'', config=True,
309 help="""The full path to a private key file for usage with SSL/TLS."""
309 help="""The full path to a private key file for usage with SSL/TLS."""
310 )
310 )
311
311
312 password = Unicode(u'', config=True,
312 password = Unicode(u'', config=True,
313 help="""Hashed password to use for web authentication.
313 help="""Hashed password to use for web authentication.
314
314
315 To generate, type in a python/IPython shell:
315 To generate, type in a python/IPython shell:
316
316
317 from IPython.lib import passwd; passwd()
317 from IPython.lib import passwd; passwd()
318
318
319 The string should be of the form type:salt:hashed-password.
319 The string should be of the form type:salt:hashed-password.
320 """
320 """
321 )
321 )
322
322
323 open_browser = Bool(True, config=True,
323 open_browser = Bool(True, config=True,
324 help="""Whether to open in a browser after starting.
324 help="""Whether to open in a browser after starting.
325 The specific browser used is platform dependent and
325 The specific browser used is platform dependent and
326 determined by the python standard library `webbrowser`
326 determined by the python standard library `webbrowser`
327 module, unless it is overridden using the --browser
327 module, unless it is overridden using the --browser
328 (NotebookApp.browser) configuration option.
328 (NotebookApp.browser) configuration option.
329 """)
329 """)
330
330
331 browser = Unicode(u'', config=True,
331 browser = Unicode(u'', config=True,
332 help="""Specify what command to use to invoke a web
332 help="""Specify what command to use to invoke a web
333 browser when opening the notebook. If not specified, the
333 browser when opening the notebook. If not specified, the
334 default browser will be determined by the `webbrowser`
334 default browser will be determined by the `webbrowser`
335 standard library module, which allows setting of the
335 standard library module, which allows setting of the
336 BROWSER environment variable to override it.
336 BROWSER environment variable to override it.
337 """)
337 """)
338
338
339 read_only = Bool(False, config=True,
339 read_only = Bool(False, config=True,
340 help="Whether to prevent editing/execution of notebooks."
340 help="Whether to prevent editing/execution of notebooks."
341 )
341 )
342
342
343 webapp_settings = Dict(config=True,
343 webapp_settings = Dict(config=True,
344 help="Supply overrides for the tornado.web.Application that the "
344 help="Supply overrides for the tornado.web.Application that the "
345 "IPython notebook uses.")
345 "IPython notebook uses.")
346
346
347 enable_mathjax = Bool(True, config=True,
347 enable_mathjax = Bool(True, config=True,
348 help="""Whether to enable MathJax for typesetting math/TeX
348 help="""Whether to enable MathJax for typesetting math/TeX
349
349
350 MathJax is the javascript library IPython uses to render math/LaTeX. It is
350 MathJax is the javascript library IPython uses to render math/LaTeX. It is
351 very large, so you may want to disable it if you have a slow internet
351 very large, so you may want to disable it if you have a slow internet
352 connection, or for offline use of the notebook.
352 connection, or for offline use of the notebook.
353
353
354 When disabled, equations etc. will appear as their untransformed TeX source.
354 When disabled, equations etc. will appear as their untransformed TeX source.
355 """
355 """
356 )
356 )
357 def _enable_mathjax_changed(self, name, old, new):
357 def _enable_mathjax_changed(self, name, old, new):
358 """set mathjax url to empty if mathjax is disabled"""
358 """set mathjax url to empty if mathjax is disabled"""
359 if not new:
359 if not new:
360 self.mathjax_url = u''
360 self.mathjax_url = u''
361
361
362 base_project_url = Unicode('/', config=True,
362 base_project_url = Unicode('/', config=True,
363 help='''The base URL for the notebook server''')
363 help='''The base URL for the notebook server''')
364 base_kernel_url = Unicode('/', config=True,
364 base_kernel_url = Unicode('/', config=True,
365 help='''The base URL for the kernel server''')
365 help='''The base URL for the kernel server''')
366 websocket_host = Unicode("", config=True,
366 websocket_host = Unicode("", config=True,
367 help="""The hostname for the websocket server."""
367 help="""The hostname for the websocket server."""
368 )
368 )
369
369
370 extra_static_paths = List(Unicode, config=True,
370 extra_static_paths = List(Unicode, config=True,
371 help="""Extra paths to search for serving static files.
371 help="""Extra paths to search for serving static files.
372
372
373 This allows adding javascript/css to be available from the notebook server machine,
373 This allows adding javascript/css to be available from the notebook server machine,
374 or overriding individual files in the IPython"""
374 or overriding individual files in the IPython"""
375 )
375 )
376 def _extra_static_paths_default(self):
376 def _extra_static_paths_default(self):
377 return [os.path.join(self.profile_dir.location, 'static')]
377 return [os.path.join(self.profile_dir.location, 'static')]
378
378
379 @property
379 @property
380 def static_file_path(self):
380 def static_file_path(self):
381 """return extra paths + the default location"""
381 """return extra paths + the default location"""
382 return self.extra_static_paths + [os.path.join(os.path.dirname(__file__), "static")]
382 return self.extra_static_paths + [os.path.join(os.path.dirname(__file__), "static")]
383
383
384 mathjax_url = Unicode("", config=True,
384 mathjax_url = Unicode("", config=True,
385 help="""The url for MathJax.js."""
385 help="""The url for MathJax.js."""
386 )
386 )
387 def _mathjax_url_default(self):
387 def _mathjax_url_default(self):
388 if not self.enable_mathjax:
388 if not self.enable_mathjax:
389 return u''
389 return u''
390 static_url_prefix = self.webapp_settings.get("static_url_prefix",
390 static_url_prefix = self.webapp_settings.get("static_url_prefix",
391 "/static/")
391 "/static/")
392 try:
392 try:
393 mathjax = filefind(os.path.join('mathjax', 'MathJax.js'), self.static_file_path)
393 mathjax = filefind(os.path.join('mathjax', 'MathJax.js'), self.static_file_path)
394 except IOError:
394 except IOError:
395 if self.certfile:
395 if self.certfile:
396 # HTTPS: load from Rackspace CDN, because SSL certificate requires it
396 # HTTPS: load from Rackspace CDN, because SSL certificate requires it
397 base = u"https://c328740.ssl.cf1.rackcdn.com"
397 base = u"https://c328740.ssl.cf1.rackcdn.com"
398 else:
398 else:
399 base = u"http://cdn.mathjax.org"
399 base = u"http://cdn.mathjax.org"
400
400
401 url = base + u"/mathjax/latest/MathJax.js"
401 url = base + u"/mathjax/latest/MathJax.js"
402 self.log.info("Using MathJax from CDN: %s", url)
402 self.log.info("Using MathJax from CDN: %s", url)
403 return url
403 return url
404 else:
404 else:
405 self.log.info("Using local MathJax from %s" % mathjax)
405 self.log.info("Using local MathJax from %s" % mathjax)
406 return static_url_prefix+u"mathjax/MathJax.js"
406 return static_url_prefix+u"mathjax/MathJax.js"
407
407
408 def _mathjax_url_changed(self, name, old, new):
408 def _mathjax_url_changed(self, name, old, new):
409 if new and not self.enable_mathjax:
409 if new and not self.enable_mathjax:
410 # enable_mathjax=False overrides mathjax_url
410 # enable_mathjax=False overrides mathjax_url
411 self.mathjax_url = u''
411 self.mathjax_url = u''
412 else:
412 else:
413 self.log.info("Using MathJax: %s", new)
413 self.log.info("Using MathJax: %s", new)
414
414
415 notebook_manager_class = DottedObjectName('IPython.frontend.html.notebook.filenbmanager.FileNotebookManager',
415 notebook_manager_class = DottedObjectName('IPython.frontend.html.notebook.filenbmanager.FileNotebookManager',
416 config=True,
416 config=True,
417 help='The notebook manager class to use.')
417 help='The notebook manager class to use.')
418
418
419 def parse_command_line(self, argv=None):
419 def parse_command_line(self, argv=None):
420 super(NotebookApp, self).parse_command_line(argv)
420 super(NotebookApp, self).parse_command_line(argv)
421 if argv is None:
421 if argv is None:
422 argv = sys.argv[1:]
422 argv = sys.argv[1:]
423
423
424 # Scrub frontend-specific flags
424 # Scrub frontend-specific flags
425 self.kernel_argv = swallow_argv(argv, notebook_aliases, notebook_flags)
425 self.kernel_argv = swallow_argv(argv, notebook_aliases, notebook_flags)
426 # Kernel should inherit default config file from frontend
426 # Kernel should inherit default config file from frontend
427 self.kernel_argv.append("--KernelApp.parent_appname='%s'"%self.name)
427 self.kernel_argv.append("--KernelApp.parent_appname='%s'"%self.name)
428
428
429 if self.extra_args:
429 if self.extra_args:
430 f = os.path.abspath(self.extra_args[0])
430 f = os.path.abspath(self.extra_args[0])
431 if os.path.isdir(f):
431 if os.path.isdir(f):
432 nbdir = f
432 nbdir = f
433 else:
433 else:
434 self.file_to_run = f
434 self.file_to_run = f
435 nbdir = os.path.dirname(f)
435 nbdir = os.path.dirname(f)
436 self.config.NotebookManager.notebook_dir = nbdir
436 self.config.NotebookManager.notebook_dir = nbdir
437
437
438 def init_configurables(self):
438 def init_configurables(self):
439 # force Session default to be secure
439 # force Session default to be secure
440 default_secure(self.config)
440 default_secure(self.config)
441 self.kernel_manager = MappingKernelManager(
441 self.kernel_manager = MappingKernelManager(
442 config=self.config, log=self.log, kernel_argv=self.kernel_argv,
442 config=self.config, log=self.log, kernel_argv=self.kernel_argv,
443 connection_dir = self.profile_dir.security_dir,
443 connection_dir = self.profile_dir.security_dir,
444 )
444 )
445 kls = import_item(self.notebook_manager_class)
445 kls = import_item(self.notebook_manager_class)
446 self.notebook_manager = kls(config=self.config, log=self.log)
446 self.notebook_manager = kls(config=self.config, log=self.log)
447 self.notebook_manager.log_info()
447 self.notebook_manager.log_info()
448 self.notebook_manager.load_notebook_names()
448 self.notebook_manager.load_notebook_names()
449 self.cluster_manager = ClusterManager(config=self.config, log=self.log)
449 self.cluster_manager = ClusterManager(config=self.config, log=self.log)
450 self.cluster_manager.update_profiles()
450 self.cluster_manager.update_profiles()
451
451
452 def init_logging(self):
452 def init_logging(self):
453 # This prevents double log messages because tornado use a root logger that
453 # This prevents double log messages because tornado use a root logger that
454 # self.log is a child of. The logging module dipatches log messages to a log
454 # self.log is a child of. The logging module dipatches log messages to a log
455 # and all of its ancenstors until propagate is set to False.
455 # and all of its ancenstors until propagate is set to False.
456 self.log.propagate = False
456 self.log.propagate = False
457
457
458 def init_webapp(self):
458 def init_webapp(self):
459 """initialize tornado webapp and httpserver"""
459 """initialize tornado webapp and httpserver"""
460 self.web_app = NotebookWebApplication(
460 self.web_app = NotebookWebApplication(
461 self, self.kernel_manager, self.notebook_manager,
461 self, self.kernel_manager, self.notebook_manager,
462 self.cluster_manager, self.log,
462 self.cluster_manager, self.log,
463 self.base_project_url, self.webapp_settings
463 self.base_project_url, self.webapp_settings
464 )
464 )
465 if self.certfile:
465 if self.certfile:
466 ssl_options = dict(certfile=self.certfile)
466 ssl_options = dict(certfile=self.certfile)
467 if self.keyfile:
467 if self.keyfile:
468 ssl_options['keyfile'] = self.keyfile
468 ssl_options['keyfile'] = self.keyfile
469 else:
469 else:
470 ssl_options = None
470 ssl_options = None
471 self.web_app.password = self.password
471 self.web_app.password = self.password
472 self.http_server = httpserver.HTTPServer(self.web_app, ssl_options=ssl_options)
472 self.http_server = httpserver.HTTPServer(self.web_app, ssl_options=ssl_options)
473 if ssl_options is None and not self.ip and not (self.read_only and not self.password):
473 if not self.ip:
474 self.log.critical('WARNING: the notebook server is listening on all IP addresses '
474 warning = "WARNING: The notebook server is listening on all IP addresses"
475 'but not using any encryption or authentication. This is highly '
475 if ssl_options is None:
476 'insecure and not recommended.')
476 self.log.critical(warning + " and not using encryption. This"
477
477 "is not recommended.")
478 if not self.password and not self.read_only:
479 self.log.critical(warning + "and not using authentication."
480 "This is highly insecure and not recommended.")
478 success = None
481 success = None
479 for port in random_ports(self.port, self.port_retries+1):
482 for port in random_ports(self.port, self.port_retries+1):
480 try:
483 try:
481 self.http_server.listen(port, self.ip)
484 self.http_server.listen(port, self.ip)
482 except socket.error as e:
485 except socket.error as e:
483 if e.errno != errno.EADDRINUSE:
486 if e.errno != errno.EADDRINUSE:
484 raise
487 raise
485 self.log.info('The port %i is already in use, trying another random port.' % port)
488 self.log.info('The port %i is already in use, trying another random port.' % port)
486 else:
489 else:
487 self.port = port
490 self.port = port
488 success = True
491 success = True
489 break
492 break
490 if not success:
493 if not success:
491 self.log.critical('ERROR: the notebook server could not be started because '
494 self.log.critical('ERROR: the notebook server could not be started because '
492 'no available port could be found.')
495 'no available port could be found.')
493 self.exit(1)
496 self.exit(1)
494
497
495 def init_signal(self):
498 def init_signal(self):
496 # FIXME: remove this check when pyzmq dependency is >= 2.1.11
499 # FIXME: remove this check when pyzmq dependency is >= 2.1.11
497 # safely extract zmq version info:
500 # safely extract zmq version info:
498 try:
501 try:
499 zmq_v = zmq.pyzmq_version_info()
502 zmq_v = zmq.pyzmq_version_info()
500 except AttributeError:
503 except AttributeError:
501 zmq_v = [ int(n) for n in re.findall(r'\d+', zmq.__version__) ]
504 zmq_v = [ int(n) for n in re.findall(r'\d+', zmq.__version__) ]
502 if 'dev' in zmq.__version__:
505 if 'dev' in zmq.__version__:
503 zmq_v.append(999)
506 zmq_v.append(999)
504 zmq_v = tuple(zmq_v)
507 zmq_v = tuple(zmq_v)
505 if zmq_v >= (2,1,9) and not sys.platform.startswith('win'):
508 if zmq_v >= (2,1,9) and not sys.platform.startswith('win'):
506 # This won't work with 2.1.7 and
509 # This won't work with 2.1.7 and
507 # 2.1.9-10 will log ugly 'Interrupted system call' messages,
510 # 2.1.9-10 will log ugly 'Interrupted system call' messages,
508 # but it will work
511 # but it will work
509 signal.signal(signal.SIGINT, self._handle_sigint)
512 signal.signal(signal.SIGINT, self._handle_sigint)
510 signal.signal(signal.SIGTERM, self._signal_stop)
513 signal.signal(signal.SIGTERM, self._signal_stop)
511
514
512 def _handle_sigint(self, sig, frame):
515 def _handle_sigint(self, sig, frame):
513 """SIGINT handler spawns confirmation dialog"""
516 """SIGINT handler spawns confirmation dialog"""
514 # register more forceful signal handler for ^C^C case
517 # register more forceful signal handler for ^C^C case
515 signal.signal(signal.SIGINT, self._signal_stop)
518 signal.signal(signal.SIGINT, self._signal_stop)
516 # request confirmation dialog in bg thread, to avoid
519 # request confirmation dialog in bg thread, to avoid
517 # blocking the App
520 # blocking the App
518 thread = threading.Thread(target=self._confirm_exit)
521 thread = threading.Thread(target=self._confirm_exit)
519 thread.daemon = True
522 thread.daemon = True
520 thread.start()
523 thread.start()
521
524
522 def _restore_sigint_handler(self):
525 def _restore_sigint_handler(self):
523 """callback for restoring original SIGINT handler"""
526 """callback for restoring original SIGINT handler"""
524 signal.signal(signal.SIGINT, self._handle_sigint)
527 signal.signal(signal.SIGINT, self._handle_sigint)
525
528
526 def _confirm_exit(self):
529 def _confirm_exit(self):
527 """confirm shutdown on ^C
530 """confirm shutdown on ^C
528
531
529 A second ^C, or answering 'y' within 5s will cause shutdown,
532 A second ^C, or answering 'y' within 5s will cause shutdown,
530 otherwise original SIGINT handler will be restored.
533 otherwise original SIGINT handler will be restored.
531
534
532 This doesn't work on Windows.
535 This doesn't work on Windows.
533 """
536 """
534 # FIXME: remove this delay when pyzmq dependency is >= 2.1.11
537 # FIXME: remove this delay when pyzmq dependency is >= 2.1.11
535 time.sleep(0.1)
538 time.sleep(0.1)
536 sys.stdout.write("Shutdown Notebook Server (y/[n])? ")
539 sys.stdout.write("Shutdown Notebook Server (y/[n])? ")
537 sys.stdout.flush()
540 sys.stdout.flush()
538 r,w,x = select.select([sys.stdin], [], [], 5)
541 r,w,x = select.select([sys.stdin], [], [], 5)
539 if r:
542 if r:
540 line = sys.stdin.readline()
543 line = sys.stdin.readline()
541 if line.lower().startswith('y'):
544 if line.lower().startswith('y'):
542 self.log.critical("Shutdown confirmed")
545 self.log.critical("Shutdown confirmed")
543 ioloop.IOLoop.instance().stop()
546 ioloop.IOLoop.instance().stop()
544 return
547 return
545 else:
548 else:
546 print "No answer for 5s:",
549 print "No answer for 5s:",
547 print "resuming operation..."
550 print "resuming operation..."
548 # no answer, or answer is no:
551 # no answer, or answer is no:
549 # set it back to original SIGINT handler
552 # set it back to original SIGINT handler
550 # use IOLoop.add_callback because signal.signal must be called
553 # use IOLoop.add_callback because signal.signal must be called
551 # from main thread
554 # from main thread
552 ioloop.IOLoop.instance().add_callback(self._restore_sigint_handler)
555 ioloop.IOLoop.instance().add_callback(self._restore_sigint_handler)
553
556
554 def _signal_stop(self, sig, frame):
557 def _signal_stop(self, sig, frame):
555 self.log.critical("received signal %s, stopping", sig)
558 self.log.critical("received signal %s, stopping", sig)
556 ioloop.IOLoop.instance().stop()
559 ioloop.IOLoop.instance().stop()
557
560
558 @catch_config_error
561 @catch_config_error
559 def initialize(self, argv=None):
562 def initialize(self, argv=None):
560 self.init_logging()
563 self.init_logging()
561 super(NotebookApp, self).initialize(argv)
564 super(NotebookApp, self).initialize(argv)
562 self.init_configurables()
565 self.init_configurables()
563 self.init_webapp()
566 self.init_webapp()
564 self.init_signal()
567 self.init_signal()
565
568
566 def cleanup_kernels(self):
569 def cleanup_kernels(self):
567 """shutdown all kernels
570 """shutdown all kernels
568
571
569 The kernels will shutdown themselves when this process no longer exists,
572 The kernels will shutdown themselves when this process no longer exists,
570 but explicit shutdown allows the KernelManagers to cleanup the connection files.
573 but explicit shutdown allows the KernelManagers to cleanup the connection files.
571 """
574 """
572 self.log.info('Shutting down kernels')
575 self.log.info('Shutting down kernels')
573 km = self.kernel_manager
576 km = self.kernel_manager
574 # copy list, since shutdown_kernel deletes keys
577 # copy list, since shutdown_kernel deletes keys
575 for kid in list(km.kernel_ids):
578 for kid in list(km.kernel_ids):
576 km.shutdown_kernel(kid)
579 km.shutdown_kernel(kid)
577
580
578 def start(self):
581 def start(self):
579 ip = self.ip if self.ip else '[all ip addresses on your system]'
582 ip = self.ip if self.ip else '[all ip addresses on your system]'
580 proto = 'https' if self.certfile else 'http'
583 proto = 'https' if self.certfile else 'http'
581 info = self.log.info
584 info = self.log.info
582 info("The IPython Notebook is running at: %s://%s:%i%s" %
585 info("The IPython Notebook is running at: %s://%s:%i%s" %
583 (proto, ip, self.port,self.base_project_url) )
586 (proto, ip, self.port,self.base_project_url) )
584 info("Use Control-C to stop this server and shut down all kernels.")
587 info("Use Control-C to stop this server and shut down all kernels.")
585
588
586 if self.open_browser or self.file_to_run:
589 if self.open_browser or self.file_to_run:
587 ip = self.ip or '127.0.0.1'
590 ip = self.ip or '127.0.0.1'
588 try:
591 try:
589 browser = webbrowser.get(self.browser or None)
592 browser = webbrowser.get(self.browser or None)
590 except webbrowser.Error as e:
593 except webbrowser.Error as e:
591 self.log.warn('No web browser found: %s.' % e)
594 self.log.warn('No web browser found: %s.' % e)
592 browser = None
595 browser = None
593
596
594 if self.file_to_run:
597 if self.file_to_run:
595 name, _ = os.path.splitext(os.path.basename(self.file_to_run))
598 name, _ = os.path.splitext(os.path.basename(self.file_to_run))
596 url = self.notebook_manager.rev_mapping.get(name, '')
599 url = self.notebook_manager.rev_mapping.get(name, '')
597 else:
600 else:
598 url = ''
601 url = ''
599 if browser:
602 if browser:
600 b = lambda : browser.open("%s://%s:%i%s%s" % (proto, ip,
603 b = lambda : browser.open("%s://%s:%i%s%s" % (proto, ip,
601 self.port, self.base_project_url, url), new=2)
604 self.port, self.base_project_url, url), new=2)
602 threading.Thread(target=b).start()
605 threading.Thread(target=b).start()
603 try:
606 try:
604 ioloop.IOLoop.instance().start()
607 ioloop.IOLoop.instance().start()
605 except KeyboardInterrupt:
608 except KeyboardInterrupt:
606 info("Interrupted...")
609 info("Interrupted...")
607 finally:
610 finally:
608 self.cleanup_kernels()
611 self.cleanup_kernels()
609
612
610
613
611 #-----------------------------------------------------------------------------
614 #-----------------------------------------------------------------------------
612 # Main entry point
615 # Main entry point
613 #-----------------------------------------------------------------------------
616 #-----------------------------------------------------------------------------
614
617
615 def launch_new_instance():
618 def launch_new_instance():
616 app = NotebookApp.instance()
619 app = NotebookApp.instance()
617 app.initialize()
620 app.initialize()
618 app.start()
621 app.start()
619
622
@@ -1,220 +1,218 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2008-2011 The IPython Development Team
2 // Copyright (C) 2008-2011 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // Cell
9 // Cell
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13
13
14 var utils = IPython.utils;
14 var utils = IPython.utils;
15
15
16
16
17 var Cell = function () {
17 var Cell = function () {
18 this.placeholder = this.placeholder || '';
18 this.placeholder = this.placeholder || '';
19 this.read_only = false;
19 this.read_only = false;
20 this.selected = false;
20 this.selected = false;
21 this.element = null;
21 this.element = null;
22 this.metadata = {};
22 this.metadata = {};
23 // load this from metadata later ?
23 // load this from metadata later ?
24 this.user_highlight == 'auto';
24 this.user_highlight == 'auto';
25 this.create_element();
25 this.create_element();
26 if (this.element !== null) {
26 if (this.element !== null) {
27 this.element.data("cell", this);
27 this.element.data("cell", this);
28 this.bind_events();
28 this.bind_events();
29 }
29 }
30 this.cell_id = utils.uuid();
30 this.cell_id = utils.uuid();
31 };
31 };
32
32
33
33
34 // Subclasses must implement create_element.
34 // Subclasses must implement create_element.
35 Cell.prototype.create_element = function () {};
35 Cell.prototype.create_element = function () {};
36
36
37
37
38 Cell.prototype.bind_events = function () {
38 Cell.prototype.bind_events = function () {
39 var that = this;
39 var that = this;
40 // We trigger events so that Cell doesn't have to depend on Notebook.
40 // We trigger events so that Cell doesn't have to depend on Notebook.
41 that.element.click(function (event) {
41 that.element.click(function (event) {
42 if (that.selected === false) {
42 if (that.selected === false) {
43 $([IPython.events]).trigger('select.Cell', {'cell':that});
43 $([IPython.events]).trigger('select.Cell', {'cell':that});
44 }
44 }
45 });
45 });
46 that.element.focusin(function (event) {
46 that.element.focusin(function (event) {
47 if (that.selected === false) {
47 if (that.selected === false) {
48 $([IPython.events]).trigger('select.Cell', {'cell':that});
48 $([IPython.events]).trigger('select.Cell', {'cell':that});
49 }
49 }
50 });
50 });
51 };
51 };
52
52
53
54 // typeset with MathJax if MathJax is available
55 Cell.prototype.typeset = function () {
53 Cell.prototype.typeset = function () {
56 if (window.MathJax){
54 if (window.MathJax){
57 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
55 var cell_math = this.element.get(0);
56 MathJax.Hub.Queue(["Typeset",MathJax.Hub,cell_math]);
58 }
57 }
59 };
58 };
60
59
61
62 Cell.prototype.select = function () {
60 Cell.prototype.select = function () {
63 this.element.addClass('ui-widget-content ui-corner-all');
61 this.element.addClass('ui-widget-content ui-corner-all');
64 this.selected = true;
62 this.selected = true;
65 };
63 };
66
64
67
65
68 Cell.prototype.unselect = function () {
66 Cell.prototype.unselect = function () {
69 this.element.removeClass('ui-widget-content ui-corner-all');
67 this.element.removeClass('ui-widget-content ui-corner-all');
70 this.selected = false;
68 this.selected = false;
71 };
69 };
72
70
73
71
74 Cell.prototype.get_text = function () {
72 Cell.prototype.get_text = function () {
75 };
73 };
76
74
77
75
78 Cell.prototype.set_text = function (text) {
76 Cell.prototype.set_text = function (text) {
79 };
77 };
80
78
81
79
82 Cell.prototype.refresh = function () {
80 Cell.prototype.refresh = function () {
83 this.code_mirror.refresh();
81 this.code_mirror.refresh();
84 };
82 };
85
83
86
84
87 Cell.prototype.edit = function () {
85 Cell.prototype.edit = function () {
88 };
86 };
89
87
90
88
91 Cell.prototype.render = function () {
89 Cell.prototype.render = function () {
92 };
90 };
93
91
94
92
95 Cell.prototype.toJSON = function () {
93 Cell.prototype.toJSON = function () {
96 var data = {};
94 var data = {};
97 data.metadata = this.metadata;
95 data.metadata = this.metadata;
98 return data;
96 return data;
99 };
97 };
100
98
101
99
102 Cell.prototype.fromJSON = function (data) {
100 Cell.prototype.fromJSON = function (data) {
103 if (data.metadata !== undefined) {
101 if (data.metadata !== undefined) {
104 this.metadata = data.metadata;
102 this.metadata = data.metadata;
105 }
103 }
106 };
104 };
107
105
108
106
109 Cell.prototype.is_splittable = function () {
107 Cell.prototype.is_splittable = function () {
110 return true;
108 return true;
111 };
109 };
112
110
113
111
114 Cell.prototype.get_pre_cursor = function () {
112 Cell.prototype.get_pre_cursor = function () {
115 var cursor = this.code_mirror.getCursor();
113 var cursor = this.code_mirror.getCursor();
116 var text = this.code_mirror.getRange({line:0,ch:0}, cursor);
114 var text = this.code_mirror.getRange({line:0,ch:0}, cursor);
117 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
115 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
118 return text;
116 return text;
119 }
117 }
120
118
121
119
122 Cell.prototype.get_post_cursor = function () {
120 Cell.prototype.get_post_cursor = function () {
123 var cursor = this.code_mirror.getCursor();
121 var cursor = this.code_mirror.getCursor();
124 var last_line_num = this.code_mirror.lineCount()-1;
122 var last_line_num = this.code_mirror.lineCount()-1;
125 var last_line_len = this.code_mirror.getLine(last_line_num).length;
123 var last_line_len = this.code_mirror.getLine(last_line_num).length;
126 var end = {line:last_line_num, ch:last_line_len}
124 var end = {line:last_line_num, ch:last_line_len}
127 var text = this.code_mirror.getRange(cursor, end);
125 var text = this.code_mirror.getRange(cursor, end);
128 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
126 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
129 return text;
127 return text;
130 };
128 };
131
129
132
130
133 Cell.prototype.grow = function(element) {
131 Cell.prototype.grow = function(element) {
134 // Grow the cell by hand. This is used upon reloading from JSON, when the
132 // Grow the cell by hand. This is used upon reloading from JSON, when the
135 // autogrow handler is not called.
133 // autogrow handler is not called.
136 var dom = element.get(0);
134 var dom = element.get(0);
137 var lines_count = 0;
135 var lines_count = 0;
138 // modified split rule from
136 // modified split rule from
139 // http://stackoverflow.com/questions/2035910/how-to-get-the-number-of-lines-in-a-textarea/2036424#2036424
137 // http://stackoverflow.com/questions/2035910/how-to-get-the-number-of-lines-in-a-textarea/2036424#2036424
140 var lines = dom.value.split(/\r|\r\n|\n/);
138 var lines = dom.value.split(/\r|\r\n|\n/);
141 lines_count = lines.length;
139 lines_count = lines.length;
142 if (lines_count >= 1) {
140 if (lines_count >= 1) {
143 dom.rows = lines_count;
141 dom.rows = lines_count;
144 } else {
142 } else {
145 dom.rows = 1;
143 dom.rows = 1;
146 }
144 }
147 };
145 };
148
146
149
147
150 Cell.prototype.toggle_line_numbers = function () {
148 Cell.prototype.toggle_line_numbers = function () {
151 if (this.code_mirror.getOption('lineNumbers') == false) {
149 if (this.code_mirror.getOption('lineNumbers') == false) {
152 this.code_mirror.setOption('lineNumbers', true);
150 this.code_mirror.setOption('lineNumbers', true);
153 } else {
151 } else {
154 this.code_mirror.setOption('lineNumbers', false);
152 this.code_mirror.setOption('lineNumbers', false);
155 }
153 }
156 this.code_mirror.refresh();
154 this.code_mirror.refresh();
157 };
155 };
158
156
159 Cell.prototype.force_highlight = function(mode) {
157 Cell.prototype.force_highlight = function(mode) {
160 this.user_highlight = mode;
158 this.user_highlight = mode;
161 this.auto_highlight();
159 this.auto_highlight();
162 };
160 };
163
161
164 Cell.prototype._auto_highlight = function (modes) {
162 Cell.prototype._auto_highlight = function (modes) {
165 //Here we handle manually selected modes
163 //Here we handle manually selected modes
166 if( this.user_highlight != undefined && this.user_highlight != 'auto' )
164 if( this.user_highlight != undefined && this.user_highlight != 'auto' )
167 {
165 {
168 var mode = this.user_highlight;
166 var mode = this.user_highlight;
169 CodeMirror.autoLoadMode(this.code_mirror, mode);
167 CodeMirror.autoLoadMode(this.code_mirror, mode);
170 this.code_mirror.setOption('mode', mode);
168 this.code_mirror.setOption('mode', mode);
171 return;
169 return;
172 }
170 }
173 var first_line = this.code_mirror.getLine(0);
171 var first_line = this.code_mirror.getLine(0);
174 // loop on every pairs
172 // loop on every pairs
175 for( var mode in modes) {
173 for( var mode in modes) {
176 var regs = modes[mode]['reg'];
174 var regs = modes[mode]['reg'];
177 // only one key every time but regexp can't be keys...
175 // only one key every time but regexp can't be keys...
178 for(var reg in regs ) {
176 for(var reg in regs ) {
179 // here we handle non magic_modes
177 // here we handle non magic_modes
180 if(first_line.match(regs[reg]) != null) {
178 if(first_line.match(regs[reg]) != null) {
181 if (mode.search('magic_') != 0) {
179 if (mode.search('magic_') != 0) {
182 this.code_mirror.setOption('mode',mode);
180 this.code_mirror.setOption('mode',mode);
183 CodeMirror.autoLoadMode(this.code_mirror, mode);
181 CodeMirror.autoLoadMode(this.code_mirror, mode);
184 return;
182 return;
185 }
183 }
186 var open = modes[mode]['open']|| "%%";
184 var open = modes[mode]['open']|| "%%";
187 var close = modes[mode]['close']|| "%%end";
185 var close = modes[mode]['close']|| "%%end";
188 var mmode = mode;
186 var mmode = mode;
189 mode = mmode.substr(6);
187 mode = mmode.substr(6);
190 CodeMirror.autoLoadMode(this.code_mirror, mode);
188 CodeMirror.autoLoadMode(this.code_mirror, mode);
191 // create on the fly a mode that swhitch between
189 // create on the fly a mode that swhitch between
192 // plain/text and smth else otherwise `%%` is
190 // plain/text and smth else otherwise `%%` is
193 // source of some highlight issues.
191 // source of some highlight issues.
194 // we use patchedGetMode to circumvent a bug in CM
192 // we use patchedGetMode to circumvent a bug in CM
195 CodeMirror.defineMode(mmode , function(config) {
193 CodeMirror.defineMode(mmode , function(config) {
196 return CodeMirror.multiplexingMode(
194 return CodeMirror.multiplexingMode(
197 CodeMirror.patchedGetMode(config, 'text/plain'),
195 CodeMirror.patchedGetMode(config, 'text/plain'),
198 // always set someting on close
196 // always set someting on close
199 {open: open, close: close,
197 {open: open, close: close,
200 mode: CodeMirror.patchedGetMode(config, mode),
198 mode: CodeMirror.patchedGetMode(config, mode),
201 delimStyle: "delimit"
199 delimStyle: "delimit"
202 }
200 }
203 );
201 );
204 });
202 });
205 this.code_mirror.setOption('mode', mmode);
203 this.code_mirror.setOption('mode', mmode);
206 return;
204 return;
207 }
205 }
208 }
206 }
209 }
207 }
210 // fallback on default (python)
208 // fallback on default (python)
211 var default_mode = this.default_mode || 'text/plain';
209 var default_mode = this.default_mode || 'text/plain';
212 this.code_mirror.setOption('mode', default_mode);
210 this.code_mirror.setOption('mode', default_mode);
213 };
211 };
214
212
215 IPython.Cell = Cell;
213 IPython.Cell = Cell;
216
214
217 return IPython;
215 return IPython;
218
216
219 }(IPython));
217 }(IPython));
220
218
@@ -1,343 +1,344 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2008-2011 The IPython Development Team
2 // Copyright (C) 2008-2011 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // CodeCell
9 // CodeCell
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13 "use strict";
13 "use strict";
14
14
15 var utils = IPython.utils;
15 var utils = IPython.utils;
16 var key = IPython.utils.keycodes;
16 var key = IPython.utils.keycodes;
17 CodeMirror.modeURL = "/static/codemirror/mode/%N/%N.js";
17 CodeMirror.modeURL = "/static/codemirror/mode/%N/%N.js";
18
18
19 var CodeCell = function (kernel) {
19 var CodeCell = function (kernel) {
20 // The kernel doesn't have to be set at creation time, in that case
20 // The kernel doesn't have to be set at creation time, in that case
21 // it will be null and set_kernel has to be called later.
21 // it will be null and set_kernel has to be called later.
22 this.kernel = kernel || null;
22 this.kernel = kernel || null;
23 this.code_mirror = null;
23 this.code_mirror = null;
24 this.input_prompt_number = null;
24 this.input_prompt_number = null;
25 this.tooltip_on_tab = true;
25 this.tooltip_on_tab = true;
26 this.collapsed = false;
26 this.collapsed = false;
27 this.default_mode = 'python';
27 this.default_mode = 'python';
28 IPython.Cell.apply(this, arguments);
28 IPython.Cell.apply(this, arguments);
29
29
30 var that = this;
30 var that = this;
31 this.element.focusout(
31 this.element.focusout(
32 function() { that.auto_highlight(); }
32 function() { that.auto_highlight(); }
33 );
33 );
34 };
34 };
35
35
36
36
37 CodeCell.prototype = new IPython.Cell();
37 CodeCell.prototype = new IPython.Cell();
38
38
39
39
40 CodeCell.prototype.auto_highlight = function () {
40 CodeCell.prototype.auto_highlight = function () {
41 this._auto_highlight(IPython.config.cell_magic_highlight)
41 this._auto_highlight(IPython.config.cell_magic_highlight)
42 };
42 };
43
43
44 CodeCell.prototype.create_element = function () {
44 CodeCell.prototype.create_element = function () {
45 var cell = $('<div></div>').addClass('cell border-box-sizing code_cell vbox');
45 var cell = $('<div></div>').addClass('cell border-box-sizing code_cell vbox');
46 cell.attr('tabindex','2');
46 cell.attr('tabindex','2');
47 var input = $('<div></div>').addClass('input hbox');
47 var input = $('<div></div>').addClass('input hbox');
48 input.append($('<div/>').addClass('prompt input_prompt'));
48 input.append($('<div/>').addClass('prompt input_prompt'));
49 var input_area = $('<div/>').addClass('input_area box-flex1');
49 var input_area = $('<div/>').addClass('input_area box-flex1');
50 this.code_mirror = CodeMirror(input_area.get(0), {
50 this.code_mirror = CodeMirror(input_area.get(0), {
51 indentUnit : 4,
51 indentUnit : 4,
52 mode: 'python',
52 mode: 'python',
53 theme: 'ipython',
53 theme: 'ipython',
54 readOnly: this.read_only,
54 readOnly: this.read_only,
55 extraKeys: {"Tab": "indentMore","Shift-Tab" : "indentLess",'Backspace':"delSpaceToPrevTabStop"},
55 extraKeys: {"Tab": "indentMore","Shift-Tab" : "indentLess",'Backspace':"delSpaceToPrevTabStop"},
56 onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
56 onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
57 });
57 });
58 input.append(input_area);
58 input.append(input_area);
59 var output = $('<div></div>');
59 var output = $('<div></div>');
60 cell.append(input).append(output);
60 cell.append(input).append(output);
61 this.element = cell;
61 this.element = cell;
62 this.output_area = new IPython.OutputArea(output, true);
62 this.output_area = new IPython.OutputArea(output, true);
63
63
64 // construct a completer only if class exist
64 // construct a completer only if class exist
65 // otherwise no print view
65 // otherwise no print view
66 if (IPython.Completer !== undefined)
66 if (IPython.Completer !== undefined)
67 {
67 {
68 this.completer = new IPython.Completer(this);
68 this.completer = new IPython.Completer(this);
69 }
69 }
70 };
70 };
71
71
72 CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
72 CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
73 // This method gets called in CodeMirror's onKeyDown/onKeyPress
73 // This method gets called in CodeMirror's onKeyDown/onKeyPress
74 // handlers and is used to provide custom key handling. Its return
74 // handlers and is used to provide custom key handling. Its return
75 // value is used to determine if CodeMirror should ignore the event:
75 // value is used to determine if CodeMirror should ignore the event:
76 // true = ignore, false = don't ignore.
76 // true = ignore, false = don't ignore.
77
77
78 if (this.read_only){
78 if (this.read_only){
79 return false;
79 return false;
80 }
80 }
81
81
82 var that = this;
82 var that = this;
83 // whatever key is pressed, first, cancel the tooltip request before
83 // whatever key is pressed, first, cancel the tooltip request before
84 // they are sent, and remove tooltip if any, except for tab again
84 // they are sent, and remove tooltip if any, except for tab again
85 if (event.type === 'keydown' && event.which != key.TAB ) {
85 if (event.type === 'keydown' && event.which != key.TAB ) {
86 IPython.tooltip.remove_and_cancel_tooltip();
86 IPython.tooltip.remove_and_cancel_tooltip();
87 };
87 };
88
88
89 var cur = editor.getCursor();
89 var cur = editor.getCursor();
90 if (event.keyCode === key.ENTER){
90 if (event.keyCode === key.ENTER){
91 this.auto_highlight();
91 this.auto_highlight();
92 }
92 }
93
93
94 if (event.keyCode === key.ENTER && (event.shiftKey || event.ctrlKey)) {
94 if (event.keyCode === key.ENTER && (event.shiftKey || event.ctrlKey)) {
95 // Always ignore shift-enter in CodeMirror as we handle it.
95 // Always ignore shift-enter in CodeMirror as we handle it.
96 return true;
96 return true;
97 } else if (event.which === 40 && event.type === 'keypress' && IPython.tooltip.time_before_tooltip >= 0) {
97 } else if (event.which === 40 && event.type === 'keypress' && IPython.tooltip.time_before_tooltip >= 0) {
98 // triger on keypress (!) otherwise inconsistent event.which depending on plateform
98 // triger on keypress (!) otherwise inconsistent event.which depending on plateform
99 // browser and keyboard layout !
99 // browser and keyboard layout !
100 // Pressing '(' , request tooltip, don't forget to reappend it
100 // Pressing '(' , request tooltip, don't forget to reappend it
101 IPython.tooltip.pending(that);
101 IPython.tooltip.pending(that);
102 } else if (event.which === key.UPARROW && event.type === 'keydown') {
102 } else if (event.which === key.UPARROW && event.type === 'keydown') {
103 // If we are not at the top, let CM handle the up arrow and
103 // If we are not at the top, let CM handle the up arrow and
104 // prevent the global keydown handler from handling it.
104 // prevent the global keydown handler from handling it.
105 if (!that.at_top()) {
105 if (!that.at_top()) {
106 event.stop();
106 event.stop();
107 return false;
107 return false;
108 } else {
108 } else {
109 return true;
109 return true;
110 };
110 };
111 } else if (event.which === key.ESC) {
111 } else if (event.which === key.ESC) {
112 IPython.tooltip.remove_and_cancel_tooltip(true);
112 IPython.tooltip.remove_and_cancel_tooltip(true);
113 return true;
113 return true;
114 } else if (event.which === key.DOWNARROW && event.type === 'keydown') {
114 } else if (event.which === key.DOWNARROW && event.type === 'keydown') {
115 // If we are not at the bottom, let CM handle the down arrow and
115 // If we are not at the bottom, let CM handle the down arrow and
116 // prevent the global keydown handler from handling it.
116 // prevent the global keydown handler from handling it.
117 if (!that.at_bottom()) {
117 if (!that.at_bottom()) {
118 event.stop();
118 event.stop();
119 return false;
119 return false;
120 } else {
120 } else {
121 return true;
121 return true;
122 };
122 };
123 } else if (event.keyCode === key.TAB && event.type == 'keydown') {
123 } else if (event.keyCode === key.TAB && event.type == 'keydown') {
124 // Tab completion.
124 // Tab completion.
125 //Do not trim here because of tooltip
125 //Do not trim here because of tooltip
126 if (editor.somethingSelected()){return false}
126 var pre_cursor = editor.getRange({line:cur.line,ch:0},cur);
127 var pre_cursor = editor.getRange({line:cur.line,ch:0},cur);
127 if (pre_cursor.trim() === "") {
128 if (pre_cursor.trim() === "") {
128 // Don't autocomplete if the part of the line before the cursor
129 // Don't autocomplete if the part of the line before the cursor
129 // is empty. In this case, let CodeMirror handle indentation.
130 // is empty. In this case, let CodeMirror handle indentation.
130 return false;
131 return false;
131 } else if ((pre_cursor.substr(-1) === "("|| pre_cursor.substr(-1) === " ") && that.tooltip_on_tab ) {
132 } else if ((pre_cursor.substr(-1) === "("|| pre_cursor.substr(-1) === " ") && that.tooltip_on_tab ) {
132 IPython.tooltip.request(that);
133 IPython.tooltip.request(that);
133 // Prevent the event from bubbling up.
134 // Prevent the event from bubbling up.
134 event.stop();
135 event.stop();
135 // Prevent CodeMirror from handling the tab.
136 // Prevent CodeMirror from handling the tab.
136 return true;
137 return true;
137 } else {
138 } else {
138 event.stop();
139 event.stop();
139 this.completer.startCompletion();
140 this.completer.startCompletion();
140 return true;
141 return true;
141 };
142 };
142 } else {
143 } else {
143 // keypress/keyup also trigger on TAB press, and we don't want to
144 // keypress/keyup also trigger on TAB press, and we don't want to
144 // use those to disable tab completion.
145 // use those to disable tab completion.
145 return false;
146 return false;
146 };
147 };
147 return false;
148 return false;
148 };
149 };
149
150
150
151
151 // Kernel related calls.
152 // Kernel related calls.
152
153
153 CodeCell.prototype.set_kernel = function (kernel) {
154 CodeCell.prototype.set_kernel = function (kernel) {
154 this.kernel = kernel;
155 this.kernel = kernel;
155 }
156 }
156
157
157
158
158 CodeCell.prototype.execute = function () {
159 CodeCell.prototype.execute = function () {
159 this.output_area.clear_output(true, true, true);
160 this.output_area.clear_output(true, true, true);
160 this.set_input_prompt('*');
161 this.set_input_prompt('*');
161 this.element.addClass("running");
162 this.element.addClass("running");
162 var callbacks = {
163 var callbacks = {
163 'execute_reply': $.proxy(this._handle_execute_reply, this),
164 'execute_reply': $.proxy(this._handle_execute_reply, this),
164 'output': $.proxy(this.output_area.handle_output, this.output_area),
165 'output': $.proxy(this.output_area.handle_output, this.output_area),
165 'clear_output': $.proxy(this.output_area.handle_clear_output, this.output_area),
166 'clear_output': $.proxy(this.output_area.handle_clear_output, this.output_area),
166 'set_next_input': $.proxy(this._handle_set_next_input, this)
167 'set_next_input': $.proxy(this._handle_set_next_input, this)
167 };
168 };
168 var msg_id = this.kernel.execute(this.get_text(), callbacks, {silent: false});
169 var msg_id = this.kernel.execute(this.get_text(), callbacks, {silent: false});
169 };
170 };
170
171
171
172
172 CodeCell.prototype._handle_execute_reply = function (content) {
173 CodeCell.prototype._handle_execute_reply = function (content) {
173 this.set_input_prompt(content.execution_count);
174 this.set_input_prompt(content.execution_count);
174 this.element.removeClass("running");
175 this.element.removeClass("running");
175 $([IPython.events]).trigger('set_dirty.Notebook', {'value': true});
176 $([IPython.events]).trigger('set_dirty.Notebook', {'value': true});
176 }
177 }
177
178
178 CodeCell.prototype._handle_set_next_input = function (text) {
179 CodeCell.prototype._handle_set_next_input = function (text) {
179 var data = {'cell': this, 'text': text}
180 var data = {'cell': this, 'text': text}
180 $([IPython.events]).trigger('set_next_input.Notebook', data);
181 $([IPython.events]).trigger('set_next_input.Notebook', data);
181 }
182 }
182
183
183 // Basic cell manipulation.
184 // Basic cell manipulation.
184
185
185 CodeCell.prototype.select = function () {
186 CodeCell.prototype.select = function () {
186 IPython.Cell.prototype.select.apply(this);
187 IPython.Cell.prototype.select.apply(this);
187 this.code_mirror.refresh();
188 this.code_mirror.refresh();
188 this.code_mirror.focus();
189 this.code_mirror.focus();
189 this.auto_highlight();
190 this.auto_highlight();
190 // We used to need an additional refresh() after the focus, but
191 // We used to need an additional refresh() after the focus, but
191 // it appears that this has been fixed in CM. This bug would show
192 // it appears that this has been fixed in CM. This bug would show
192 // up on FF when a newly loaded markdown cell was edited.
193 // up on FF when a newly loaded markdown cell was edited.
193 };
194 };
194
195
195
196
196 CodeCell.prototype.select_all = function () {
197 CodeCell.prototype.select_all = function () {
197 var start = {line: 0, ch: 0};
198 var start = {line: 0, ch: 0};
198 var nlines = this.code_mirror.lineCount();
199 var nlines = this.code_mirror.lineCount();
199 var last_line = this.code_mirror.getLine(nlines-1);
200 var last_line = this.code_mirror.getLine(nlines-1);
200 var end = {line: nlines-1, ch: last_line.length};
201 var end = {line: nlines-1, ch: last_line.length};
201 this.code_mirror.setSelection(start, end);
202 this.code_mirror.setSelection(start, end);
202 };
203 };
203
204
204
205
205 CodeCell.prototype.collapse = function () {
206 CodeCell.prototype.collapse = function () {
206 this.collapsed = true;
207 this.collapsed = true;
207 this.output_area.collapse();
208 this.output_area.collapse();
208 };
209 };
209
210
210
211
211 CodeCell.prototype.expand = function () {
212 CodeCell.prototype.expand = function () {
212 this.collapsed = false;
213 this.collapsed = false;
213 this.output_area.expand();
214 this.output_area.expand();
214 };
215 };
215
216
216
217
217 CodeCell.prototype.toggle_output = function () {
218 CodeCell.prototype.toggle_output = function () {
218 this.collapsed = Boolean(1 - this.collapsed);
219 this.collapsed = Boolean(1 - this.collapsed);
219 this.output_area.toggle_output();
220 this.output_area.toggle_output();
220 };
221 };
221
222
222
223
223 CodeCell.prototype.toggle_output_scroll = function () {
224 CodeCell.prototype.toggle_output_scroll = function () {
224 this.output_area.toggle_scroll();
225 this.output_area.toggle_scroll();
225 };
226 };
226
227
227
228
228
229
229
230
230
231
231 CodeCell.input_prompt_classical = function (prompt_value, lines_number) {
232 CodeCell.input_prompt_classical = function (prompt_value, lines_number) {
232 var ns = prompt_value || "&nbsp;";
233 var ns = prompt_value || "&nbsp;";
233 return 'In&nbsp;[' + ns + ']:'
234 return 'In&nbsp;[' + ns + ']:'
234 };
235 };
235
236
236 CodeCell.input_prompt_continuation = function (prompt_value, lines_number) {
237 CodeCell.input_prompt_continuation = function (prompt_value, lines_number) {
237 var html = [CodeCell.input_prompt_classical(prompt_value, lines_number)];
238 var html = [CodeCell.input_prompt_classical(prompt_value, lines_number)];
238 for(var i=1; i < lines_number; i++){html.push(['...:'])};
239 for(var i=1; i < lines_number; i++){html.push(['...:'])};
239 return html.join('</br>')
240 return html.join('</br>')
240 };
241 };
241
242
242 CodeCell.input_prompt_function = CodeCell.input_prompt_classical;
243 CodeCell.input_prompt_function = CodeCell.input_prompt_classical;
243
244
244
245
245 CodeCell.prototype.set_input_prompt = function (number) {
246 CodeCell.prototype.set_input_prompt = function (number) {
246 var nline = 1
247 var nline = 1
247 if( this.code_mirror != undefined) {
248 if( this.code_mirror != undefined) {
248 nline = this.code_mirror.lineCount();
249 nline = this.code_mirror.lineCount();
249 }
250 }
250 this.input_prompt_number = number;
251 this.input_prompt_number = number;
251 var prompt_html = CodeCell.input_prompt_function(this.input_prompt_number, nline);
252 var prompt_html = CodeCell.input_prompt_function(this.input_prompt_number, nline);
252 this.element.find('div.input_prompt').html(prompt_html);
253 this.element.find('div.input_prompt').html(prompt_html);
253 };
254 };
254
255
255
256
256 CodeCell.prototype.clear_input = function () {
257 CodeCell.prototype.clear_input = function () {
257 this.code_mirror.setValue('');
258 this.code_mirror.setValue('');
258 };
259 };
259
260
260
261
261 CodeCell.prototype.get_text = function () {
262 CodeCell.prototype.get_text = function () {
262 return this.code_mirror.getValue();
263 return this.code_mirror.getValue();
263 };
264 };
264
265
265
266
266 CodeCell.prototype.set_text = function (code) {
267 CodeCell.prototype.set_text = function (code) {
267 return this.code_mirror.setValue(code);
268 return this.code_mirror.setValue(code);
268 };
269 };
269
270
270
271
271 CodeCell.prototype.at_top = function () {
272 CodeCell.prototype.at_top = function () {
272 var cursor = this.code_mirror.getCursor();
273 var cursor = this.code_mirror.getCursor();
273 if (cursor.line === 0 && cursor.ch === 0) {
274 if (cursor.line === 0 && cursor.ch === 0) {
274 return true;
275 return true;
275 } else {
276 } else {
276 return false;
277 return false;
277 }
278 }
278 };
279 };
279
280
280
281
281 CodeCell.prototype.at_bottom = function () {
282 CodeCell.prototype.at_bottom = function () {
282 var cursor = this.code_mirror.getCursor();
283 var cursor = this.code_mirror.getCursor();
283 if (cursor.line === (this.code_mirror.lineCount()-1) && cursor.ch === this.code_mirror.getLine(cursor.line).length) {
284 if (cursor.line === (this.code_mirror.lineCount()-1) && cursor.ch === this.code_mirror.getLine(cursor.line).length) {
284 return true;
285 return true;
285 } else {
286 } else {
286 return false;
287 return false;
287 }
288 }
288 };
289 };
289
290
290
291
291 CodeCell.prototype.clear_output = function (stdout, stderr, other) {
292 CodeCell.prototype.clear_output = function (stdout, stderr, other) {
292 this.output_area.clear_output(stdout, stderr, other);
293 this.output_area.clear_output(stdout, stderr, other);
293 };
294 };
294
295
295
296
296 // JSON serialization
297 // JSON serialization
297
298
298 CodeCell.prototype.fromJSON = function (data) {
299 CodeCell.prototype.fromJSON = function (data) {
299 IPython.Cell.prototype.fromJSON.apply(this, arguments);
300 IPython.Cell.prototype.fromJSON.apply(this, arguments);
300 if (data.cell_type === 'code') {
301 if (data.cell_type === 'code') {
301 if (data.input !== undefined) {
302 if (data.input !== undefined) {
302 this.set_text(data.input);
303 this.set_text(data.input);
303 // make this value the starting point, so that we can only undo
304 // make this value the starting point, so that we can only undo
304 // to this state, instead of a blank cell
305 // to this state, instead of a blank cell
305 this.code_mirror.clearHistory();
306 this.code_mirror.clearHistory();
306 this.auto_highlight();
307 this.auto_highlight();
307 }
308 }
308 if (data.prompt_number !== undefined) {
309 if (data.prompt_number !== undefined) {
309 this.set_input_prompt(data.prompt_number);
310 this.set_input_prompt(data.prompt_number);
310 } else {
311 } else {
311 this.set_input_prompt();
312 this.set_input_prompt();
312 };
313 };
313 this.output_area.fromJSON(data.outputs);
314 this.output_area.fromJSON(data.outputs);
314 if (data.collapsed !== undefined) {
315 if (data.collapsed !== undefined) {
315 if (data.collapsed) {
316 if (data.collapsed) {
316 this.collapse();
317 this.collapse();
317 } else {
318 } else {
318 this.expand();
319 this.expand();
319 };
320 };
320 };
321 };
321 };
322 };
322 };
323 };
323
324
324
325
325 CodeCell.prototype.toJSON = function () {
326 CodeCell.prototype.toJSON = function () {
326 var data = IPython.Cell.prototype.toJSON.apply(this);
327 var data = IPython.Cell.prototype.toJSON.apply(this);
327 data.input = this.get_text();
328 data.input = this.get_text();
328 data.cell_type = 'code';
329 data.cell_type = 'code';
329 if (this.input_prompt_number) {
330 if (this.input_prompt_number) {
330 data.prompt_number = this.input_prompt_number;
331 data.prompt_number = this.input_prompt_number;
331 };
332 };
332 var outputs = this.output_area.toJSON();
333 var outputs = this.output_area.toJSON();
333 data.outputs = outputs;
334 data.outputs = outputs;
334 data.language = 'python';
335 data.language = 'python';
335 data.collapsed = this.collapsed;
336 data.collapsed = this.collapsed;
336 return data;
337 return data;
337 };
338 };
338
339
339
340
340 IPython.CodeCell = CodeCell;
341 IPython.CodeCell = CodeCell;
341
342
342 return IPython;
343 return IPython;
343 }(IPython));
344 }(IPython));
@@ -1,391 +1,394 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2008-2011 The IPython Development Team
2 // Copyright (C) 2008-2011 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // Kernel
9 // Kernel
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13
13
14 var utils = IPython.utils;
14 var utils = IPython.utils;
15
15
16 // Initialization and connection.
16 // Initialization and connection.
17
17
18 var Kernel = function (base_url) {
18 var Kernel = function (base_url) {
19 this.kernel_id = null;
19 this.kernel_id = null;
20 this.shell_channel = null;
20 this.shell_channel = null;
21 this.iopub_channel = null;
21 this.iopub_channel = null;
22 this.base_url = base_url;
22 this.base_url = base_url;
23 this.running = false;
23 this.running = false;
24 this.username = "username";
24 this.username = "username";
25 this.session_id = utils.uuid();
25 this.session_id = utils.uuid();
26 this._msg_callbacks = {};
26 this._msg_callbacks = {};
27
27
28 if (typeof(WebSocket) !== 'undefined') {
28 if (typeof(WebSocket) !== 'undefined') {
29 this.WebSocket = WebSocket;
29 this.WebSocket = WebSocket;
30 } else if (typeof(MozWebSocket) !== 'undefined') {
30 } else if (typeof(MozWebSocket) !== 'undefined') {
31 this.WebSocket = MozWebSocket;
31 this.WebSocket = MozWebSocket;
32 } else {
32 } else {
33 alert('Your browser does not have WebSocket support, please try Chrome, Safari or Firefox ≥ 6. Firefox 4 and 5 are also supported by you have to enable WebSockets in about:config.');
33 alert('Your browser does not have WebSocket support, please try Chrome, Safari or Firefox ≥ 6. Firefox 4 and 5 are also supported by you have to enable WebSockets in about:config.');
34 };
34 };
35 };
35 };
36
36
37
37
38 Kernel.prototype._get_msg = function (msg_type, content) {
38 Kernel.prototype._get_msg = function (msg_type, content) {
39 var msg = {
39 var msg = {
40 header : {
40 header : {
41 msg_id : utils.uuid(),
41 msg_id : utils.uuid(),
42 username : this.username,
42 username : this.username,
43 session : this.session_id,
43 session : this.session_id,
44 msg_type : msg_type
44 msg_type : msg_type
45 },
45 },
46 metadata : {},
46 metadata : {},
47 content : content,
47 content : content,
48 parent_header : {}
48 parent_header : {}
49 };
49 };
50 return msg;
50 return msg;
51 };
51 };
52
52
53 Kernel.prototype.start = function (notebook_id) {
53 Kernel.prototype.start = function (notebook_id) {
54 var that = this;
54 var that = this;
55 if (!this.running) {
55 if (!this.running) {
56 var qs = $.param({notebook:notebook_id});
56 var qs = $.param({notebook:notebook_id});
57 var url = this.base_url + '?' + qs;
57 var url = this.base_url + '?' + qs;
58 $.post(url,
58 $.post(url,
59 $.proxy(that._kernel_started,that),
59 $.proxy(that._kernel_started,that),
60 'json'
60 'json'
61 );
61 );
62 };
62 };
63 };
63 };
64
64
65
65
66 Kernel.prototype.restart = function () {
66 Kernel.prototype.restart = function () {
67 $([IPython.events]).trigger({type: 'status_restarting.Kernel', kernel: this});
67 $([IPython.events]).trigger('status_restarting.Kernel', {kernel: this});
68 var that = this;
68 var that = this;
69 if (this.running) {
69 if (this.running) {
70 this.stop_channels();
70 this.stop_channels();
71 var url = this.kernel_url + "/restart";
71 var url = this.kernel_url + "/restart";
72 $.post(url,
72 $.post(url,
73 $.proxy(that._kernel_started, that),
73 $.proxy(that._kernel_started, that),
74 'json'
74 'json'
75 );
75 );
76 };
76 };
77 };
77 };
78
78
79
79
80 Kernel.prototype._kernel_started = function (json) {
80 Kernel.prototype._kernel_started = function (json) {
81 console.log("Kernel started: ", json.kernel_id);
81 console.log("Kernel started: ", json.kernel_id);
82 this.running = true;
82 this.running = true;
83 this.kernel_id = json.kernel_id;
83 this.kernel_id = json.kernel_id;
84 this.ws_url = json.ws_url;
84 this.ws_url = json.ws_url;
85 this.kernel_url = this.base_url + "/" + this.kernel_id;
85 this.kernel_url = this.base_url + "/" + this.kernel_id;
86 this.start_channels();
86 this.start_channels();
87 this.shell_channel.onmessage = $.proxy(this._handle_shell_reply,this);
87 this.shell_channel.onmessage = $.proxy(this._handle_shell_reply,this);
88 this.iopub_channel.onmessage = $.proxy(this._handle_iopub_reply,this);
88 this.iopub_channel.onmessage = $.proxy(this._handle_iopub_reply,this);
89 $([IPython.events]).trigger('status_started.Kernel', {kernel: this});
89 };
90 };
90
91
91
92
92 Kernel.prototype._websocket_closed = function(ws_url, early){
93 Kernel.prototype._websocket_closed = function(ws_url, early){
93 var msg;
94 var msg;
94 var parent_item = $('body');
95 var parent_item = $('body');
95 if (early) {
96 if (early) {
96 msg = "Websocket connection to " + ws_url + " could not be established." +
97 msg = "Websocket connection to " + ws_url + " could not be established." +
97 " You will NOT be able to run code." +
98 " You will NOT be able to run code." +
98 " Your browser may not be compatible with the websocket version in the server," +
99 " Your browser may not be compatible with the websocket version in the server," +
99 " or if the url does not look right, there could be an error in the" +
100 " or if the url does not look right, there could be an error in the" +
100 " server's configuration.";
101 " server's configuration.";
101 } else {
102 } else {
102 IPython.notification_area.widget('kernel').set_message('Reconnecting Websockets', 1000);
103 IPython.notification_area.widget('kernel').set_message('Reconnecting Websockets', 1000);
103 this.start_channels();
104 this.start_channels();
104 return;
105 return;
105 }
106 }
106 var dialog = $('<div/>');
107 var dialog = $('<div/>');
107 dialog.html(msg);
108 dialog.html(msg);
108 parent_item.append(dialog);
109 parent_item.append(dialog);
109 dialog.dialog({
110 dialog.dialog({
110 resizable: false,
111 resizable: false,
111 modal: true,
112 modal: true,
112 title: "Websocket closed",
113 title: "Websocket closed",
113 closeText: "",
114 closeText: "",
114 close: function(event, ui) {$(this).dialog('destroy').remove();},
115 close: function(event, ui) {$(this).dialog('destroy').remove();},
115 buttons : {
116 buttons : {
116 "OK": function () {
117 "OK": function () {
117 $(this).dialog('close');
118 $(this).dialog('close');
118 }
119 }
119 }
120 }
120 });
121 });
121
122
122 };
123 };
123
124
124 Kernel.prototype.start_channels = function () {
125 Kernel.prototype.start_channels = function () {
125 var that = this;
126 var that = this;
126 this.stop_channels();
127 this.stop_channels();
127 var ws_url = this.ws_url + this.kernel_url;
128 var ws_url = this.ws_url + this.kernel_url;
128 console.log("Starting WS:", ws_url);
129 console.log("Starting WS:", ws_url);
129 this.shell_channel = new this.WebSocket(ws_url + "/shell");
130 this.shell_channel = new this.WebSocket(ws_url + "/shell");
130 this.iopub_channel = new this.WebSocket(ws_url + "/iopub");
131 this.iopub_channel = new this.WebSocket(ws_url + "/iopub");
131 send_cookie = function(){
132 send_cookie = function(){
132 this.send(document.cookie);
133 this.send(document.cookie);
133 };
134 };
134 var already_called_onclose = false; // only alert once
135 var already_called_onclose = false; // only alert once
135 ws_closed_early = function(evt){
136 ws_closed_early = function(evt){
136 if (already_called_onclose){
137 if (already_called_onclose){
137 return;
138 return;
138 }
139 }
139 already_called_onclose = true;
140 already_called_onclose = true;
140 if ( ! evt.wasClean ){
141 if ( ! evt.wasClean ){
141 that._websocket_closed(ws_url, true);
142 that._websocket_closed(ws_url, true);
142 }
143 }
143 };
144 };
144 ws_closed_late = function(evt){
145 ws_closed_late = function(evt){
145 if (already_called_onclose){
146 if (already_called_onclose){
146 return;
147 return;
147 }
148 }
148 already_called_onclose = true;
149 already_called_onclose = true;
149 if ( ! evt.wasClean ){
150 if ( ! evt.wasClean ){
150 that._websocket_closed(ws_url, false);
151 that._websocket_closed(ws_url, false);
151 }
152 }
152 };
153 };
153 this.shell_channel.onopen = send_cookie;
154 this.shell_channel.onopen = send_cookie;
154 this.shell_channel.onclose = ws_closed_early;
155 this.shell_channel.onclose = ws_closed_early;
155 this.iopub_channel.onopen = send_cookie;
156 this.iopub_channel.onopen = send_cookie;
156 this.iopub_channel.onclose = ws_closed_early;
157 this.iopub_channel.onclose = ws_closed_early;
157 // switch from early-close to late-close message after 1s
158 // switch from early-close to late-close message after 1s
158 setTimeout(function(){
159 setTimeout(function(){
159 that.shell_channel.onclose = ws_closed_late;
160 that.shell_channel.onclose = ws_closed_late;
160 that.iopub_channel.onclose = ws_closed_late;
161 that.iopub_channel.onclose = ws_closed_late;
161 }, 1000);
162 }, 1000);
162 };
163 };
163
164
164
165
165 Kernel.prototype.stop_channels = function () {
166 Kernel.prototype.stop_channels = function () {
166 if (this.shell_channel !== null) {
167 if (this.shell_channel !== null) {
167 this.shell_channel.onclose = function (evt) {};
168 this.shell_channel.onclose = function (evt) {};
168 this.shell_channel.close();
169 this.shell_channel.close();
169 this.shell_channel = null;
170 this.shell_channel = null;
170 };
171 };
171 if (this.iopub_channel !== null) {
172 if (this.iopub_channel !== null) {
172 this.iopub_channel.onclose = function (evt) {};
173 this.iopub_channel.onclose = function (evt) {};
173 this.iopub_channel.close();
174 this.iopub_channel.close();
174 this.iopub_channel = null;
175 this.iopub_channel = null;
175 };
176 };
176 };
177 };
177
178
178 // Main public methods.
179 // Main public methods.
179
180
180 Kernel.prototype.object_info_request = function (objname, callbacks) {
181 Kernel.prototype.object_info_request = function (objname, callbacks) {
181 // When calling this method pass a callbacks structure of the form:
182 // When calling this method pass a callbacks structure of the form:
182 //
183 //
183 // callbacks = {
184 // callbacks = {
184 // 'object_info_reply': object_into_reply_callback
185 // 'object_info_reply': object_into_reply_callback
185 // }
186 // }
186 //
187 //
187 // The object_info_reply_callback will be passed the content object of the
188 // The object_info_reply_callback will be passed the content object of the
188 // object_into_reply message documented here:
189 // object_into_reply message documented here:
189 //
190 //
190 // http://ipython.org/ipython-doc/dev/development/messaging.html#object-information
191 // http://ipython.org/ipython-doc/dev/development/messaging.html#object-information
191 if(typeof(objname)!=null && objname!=null)
192 if(typeof(objname)!=null && objname!=null)
192 {
193 {
193 var content = {
194 var content = {
194 oname : objname.toString(),
195 oname : objname.toString(),
195 };
196 };
196 var msg = this._get_msg("object_info_request", content);
197 var msg = this._get_msg("object_info_request", content);
197 this.shell_channel.send(JSON.stringify(msg));
198 this.shell_channel.send(JSON.stringify(msg));
198 this.set_callbacks_for_msg(msg.header.msg_id, callbacks);
199 this.set_callbacks_for_msg(msg.header.msg_id, callbacks);
199 return msg.header.msg_id;
200 return msg.header.msg_id;
200 }
201 }
201 return;
202 return;
202 }
203 }
203
204
204 Kernel.prototype.execute = function (code, callbacks, options) {
205 Kernel.prototype.execute = function (code, callbacks, options) {
205 // The options object should contain the options for the execute call. Its default
206 // The options object should contain the options for the execute call. Its default
206 // values are:
207 // values are:
207 //
208 //
208 // options = {
209 // options = {
209 // silent : true,
210 // silent : true,
210 // user_variables : [],
211 // user_variables : [],
211 // user_expressions : {},
212 // user_expressions : {},
212 // allow_stdin : false
213 // allow_stdin : false
213 // }
214 // }
214 //
215 //
215 // When calling this method pass a callbacks structure of the form:
216 // When calling this method pass a callbacks structure of the form:
216 //
217 //
217 // callbacks = {
218 // callbacks = {
218 // 'execute_reply': execute_reply_callback,
219 // 'execute_reply': execute_reply_callback,
219 // 'output': output_callback,
220 // 'output': output_callback,
220 // 'clear_output': clear_output_callback,
221 // 'clear_output': clear_output_callback,
221 // 'set_next_input': set_next_input_callback
222 // 'set_next_input': set_next_input_callback
222 // }
223 // }
223 //
224 //
224 // The execute_reply_callback will be passed the content and metadata objects of the execute_reply
225 // The execute_reply_callback will be passed the content and metadata objects of the execute_reply
225 // message documented here:
226 // message documented here:
226 //
227 //
227 // http://ipython.org/ipython-doc/dev/development/messaging.html#execute
228 // http://ipython.org/ipython-doc/dev/development/messaging.html#execute
228 //
229 //
229 // The output_callback will be passed msg_type ('stream','display_data','pyout','pyerr')
230 // The output_callback will be passed msg_type ('stream','display_data','pyout','pyerr')
230 // of the output and the content and metadata objects of the PUB/SUB channel that contains the
231 // of the output and the content and metadata objects of the PUB/SUB channel that contains the
231 // output:
232 // output:
232 //
233 //
233 // http://ipython.org/ipython-doc/dev/development/messaging.html#messages-on-the-pub-sub-socket
234 // http://ipython.org/ipython-doc/dev/development/messaging.html#messages-on-the-pub-sub-socket
234 //
235 //
235 // The clear_output_callback will be passed a content object that contains
236 // The clear_output_callback will be passed a content object that contains
236 // stdout, stderr and other fields that are booleans, as well as the metadata object.
237 // stdout, stderr and other fields that are booleans, as well as the metadata object.
237 //
238 //
238 // The set_next_input_callback will be passed the text that should become the next
239 // The set_next_input_callback will be passed the text that should become the next
239 // input cell.
240 // input cell.
240
241
241 var content = {
242 var content = {
242 code : code,
243 code : code,
243 silent : true,
244 silent : true,
244 user_variables : [],
245 user_variables : [],
245 user_expressions : {},
246 user_expressions : {},
246 allow_stdin : false
247 allow_stdin : false
247 };
248 };
248 $.extend(true, content, options)
249 $.extend(true, content, options)
250 $([IPython.events]).trigger('execution_request.Kernel', {kernel: this, content:content});
249 var msg = this._get_msg("execute_request", content);
251 var msg = this._get_msg("execute_request", content);
250 this.shell_channel.send(JSON.stringify(msg));
252 this.shell_channel.send(JSON.stringify(msg));
251 this.set_callbacks_for_msg(msg.header.msg_id, callbacks);
253 this.set_callbacks_for_msg(msg.header.msg_id, callbacks);
252 return msg.header.msg_id;
254 return msg.header.msg_id;
253 };
255 };
254
256
255
257
256 Kernel.prototype.complete = function (line, cursor_pos, callbacks) {
258 Kernel.prototype.complete = function (line, cursor_pos, callbacks) {
257 // When calling this method pass a callbacks structure of the form:
259 // When calling this method pass a callbacks structure of the form:
258 //
260 //
259 // callbacks = {
261 // callbacks = {
260 // 'complete_reply': complete_reply_callback
262 // 'complete_reply': complete_reply_callback
261 // }
263 // }
262 //
264 //
263 // The complete_reply_callback will be passed the content object of the
265 // The complete_reply_callback will be passed the content object of the
264 // complete_reply message documented here:
266 // complete_reply message documented here:
265 //
267 //
266 // http://ipython.org/ipython-doc/dev/development/messaging.html#complete
268 // http://ipython.org/ipython-doc/dev/development/messaging.html#complete
267 callbacks = callbacks || {};
269 callbacks = callbacks || {};
268 var content = {
270 var content = {
269 text : '',
271 text : '',
270 line : line,
272 line : line,
271 cursor_pos : cursor_pos
273 cursor_pos : cursor_pos
272 };
274 };
273 var msg = this._get_msg("complete_request", content);
275 var msg = this._get_msg("complete_request", content);
274 this.shell_channel.send(JSON.stringify(msg));
276 this.shell_channel.send(JSON.stringify(msg));
275 this.set_callbacks_for_msg(msg.header.msg_id, callbacks);
277 this.set_callbacks_for_msg(msg.header.msg_id, callbacks);
276 return msg.header.msg_id;
278 return msg.header.msg_id;
277 };
279 };
278
280
279
281
280 Kernel.prototype.interrupt = function () {
282 Kernel.prototype.interrupt = function () {
281 if (this.running) {
283 if (this.running) {
282 $([IPython.events]).trigger({type: 'status_interrupting.Kernel', kernel: this});
284 $([IPython.events]).trigger('status_interrupting.Kernel', {kernel: this});
283 $.post(this.kernel_url + "/interrupt");
285 $.post(this.kernel_url + "/interrupt");
284 };
286 };
285 };
287 };
286
288
287
289
288 Kernel.prototype.kill = function () {
290 Kernel.prototype.kill = function () {
289 if (this.running) {
291 if (this.running) {
290 this.running = false;
292 this.running = false;
291 var settings = {
293 var settings = {
292 cache : false,
294 cache : false,
293 type : "DELETE"
295 type : "DELETE"
294 };
296 };
295 $.ajax(this.kernel_url, settings);
297 $.ajax(this.kernel_url, settings);
296 };
298 };
297 };
299 };
298
300
299
301
300 // Reply handlers.
302 // Reply handlers.
301
303
302 Kernel.prototype.get_callbacks_for_msg = function (msg_id) {
304 Kernel.prototype.get_callbacks_for_msg = function (msg_id) {
303 var callbacks = this._msg_callbacks[msg_id];
305 var callbacks = this._msg_callbacks[msg_id];
304 return callbacks;
306 return callbacks;
305 };
307 };
306
308
307
309
308 Kernel.prototype.set_callbacks_for_msg = function (msg_id, callbacks) {
310 Kernel.prototype.set_callbacks_for_msg = function (msg_id, callbacks) {
309 this._msg_callbacks[msg_id] = callbacks || {};
311 this._msg_callbacks[msg_id] = callbacks || {};
310 }
312 }
311
313
312
314
313 Kernel.prototype._handle_shell_reply = function (e) {
315 Kernel.prototype._handle_shell_reply = function (e) {
314 reply = $.parseJSON(e.data);
316 reply = $.parseJSON(e.data);
317 $([IPython.events]).trigger('shell_reply.Kernel', {kernel: this, reply:reply});
315 var header = reply.header;
318 var header = reply.header;
316 var content = reply.content;
319 var content = reply.content;
317 var metadata = reply.metadata;
320 var metadata = reply.metadata;
318 var msg_type = header.msg_type;
321 var msg_type = header.msg_type;
319 var callbacks = this.get_callbacks_for_msg(reply.parent_header.msg_id);
322 var callbacks = this.get_callbacks_for_msg(reply.parent_header.msg_id);
320 if (callbacks !== undefined) {
323 if (callbacks !== undefined) {
321 var cb = callbacks[msg_type];
324 var cb = callbacks[msg_type];
322 if (cb !== undefined) {
325 if (cb !== undefined) {
323 cb(content, metadata);
326 cb(content, metadata);
324 }
327 }
325 };
328 };
326
329
327 if (content.payload !== undefined) {
330 if (content.payload !== undefined) {
328 var payload = content.payload || [];
331 var payload = content.payload || [];
329 this._handle_payload(callbacks, payload);
332 this._handle_payload(callbacks, payload);
330 }
333 }
331 };
334 };
332
335
333
336
334 Kernel.prototype._handle_payload = function (callbacks, payload) {
337 Kernel.prototype._handle_payload = function (callbacks, payload) {
335 var l = payload.length;
338 var l = payload.length;
336 // Payloads are handled by triggering events because we don't want the Kernel
339 // Payloads are handled by triggering events because we don't want the Kernel
337 // to depend on the Notebook or Pager classes.
340 // to depend on the Notebook or Pager classes.
338 for (var i=0; i<l; i++) {
341 for (var i=0; i<l; i++) {
339 if (payload[i].source === 'IPython.zmq.page.page') {
342 if (payload[i].source === 'IPython.zmq.page.page') {
340 var data = {'text':payload[i].text}
343 var data = {'text':payload[i].text}
341 $([IPython.events]).trigger('open_with_text.Pager', data);
344 $([IPython.events]).trigger('open_with_text.Pager', data);
342 } else if (payload[i].source === 'IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input') {
345 } else if (payload[i].source === 'IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input') {
343 if (callbacks.set_next_input !== undefined) {
346 if (callbacks.set_next_input !== undefined) {
344 callbacks.set_next_input(payload[i].text)
347 callbacks.set_next_input(payload[i].text)
345 }
348 }
346 }
349 }
347 };
350 };
348 };
351 };
349
352
350
353
351 Kernel.prototype._handle_iopub_reply = function (e) {
354 Kernel.prototype._handle_iopub_reply = function (e) {
352 var reply = $.parseJSON(e.data);
355 var reply = $.parseJSON(e.data);
353 var content = reply.content;
356 var content = reply.content;
354 var msg_type = reply.header.msg_type;
357 var msg_type = reply.header.msg_type;
355 var metadata = reply.metadata;
358 var metadata = reply.metadata;
356 var callbacks = this.get_callbacks_for_msg(reply.parent_header.msg_id);
359 var callbacks = this.get_callbacks_for_msg(reply.parent_header.msg_id);
357 if (msg_type !== 'status' && callbacks === undefined) {
360 if (msg_type !== 'status' && callbacks === undefined) {
358 // Message not from one of this notebook's cells and there are no
361 // Message not from one of this notebook's cells and there are no
359 // callbacks to handle it.
362 // callbacks to handle it.
360 return;
363 return;
361 }
364 }
362 var output_types = ['stream','display_data','pyout','pyerr'];
365 var output_types = ['stream','display_data','pyout','pyerr'];
363 if (output_types.indexOf(msg_type) >= 0) {
366 if (output_types.indexOf(msg_type) >= 0) {
364 var cb = callbacks['output'];
367 var cb = callbacks['output'];
365 if (cb !== undefined) {
368 if (cb !== undefined) {
366 cb(msg_type, content, metadata);
369 cb(msg_type, content, metadata);
367 }
370 }
368 } else if (msg_type === 'status') {
371 } else if (msg_type === 'status') {
369 if (content.execution_state === 'busy') {
372 if (content.execution_state === 'busy') {
370 $([IPython.events]).trigger({type: 'status_busy.Kernel', kernel: this});
373 $([IPython.events]).trigger('status_busy.Kernel', {kernel: this});
371 } else if (content.execution_state === 'idle') {
374 } else if (content.execution_state === 'idle') {
372 $([IPython.events]).trigger({type: 'status_idle.Kernel', kernel: this});
375 $([IPython.events]).trigger('status_idle.Kernel', {kernel: this});
373 } else if (content.execution_state === 'dead') {
376 } else if (content.execution_state === 'dead') {
374 this.stop_channels();
377 this.stop_channels();
375 $([IPython.events]).trigger({type: 'status_dead.Kernel', kernel: this});
378 $([IPython.events]).trigger('status_dead.Kernel', {kernel: this});
376 };
379 };
377 } else if (msg_type === 'clear_output') {
380 } else if (msg_type === 'clear_output') {
378 var cb = callbacks['clear_output'];
381 var cb = callbacks['clear_output'];
379 if (cb !== undefined) {
382 if (cb !== undefined) {
380 cb(content, metadata);
383 cb(content, metadata);
381 }
384 }
382 };
385 };
383 };
386 };
384
387
385
388
386 IPython.Kernel = Kernel;
389 IPython.Kernel = Kernel;
387
390
388 return IPython;
391 return IPython;
389
392
390 }(IPython));
393 }(IPython));
391
394
@@ -1,179 +1,179 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2011 The IPython Development Team
2 // Copyright (C) 2011 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // ToolBar
9 // ToolBar
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13
13
14 var MainToolBar = function (selector) {
14 var MainToolBar = function (selector) {
15 this.selector = selector;
15 this.selector = selector;
16 IPython.ToolBar.apply(this, arguments);
16 IPython.ToolBar.apply(this, arguments);
17 this.construct();
17 this.construct();
18 this.add_drop_down_list();
18 this.add_drop_down_list();
19 this.bind_events();
19 this.bind_events();
20 };
20 };
21
21
22 MainToolBar.prototype = new IPython.ToolBar();
22 MainToolBar.prototype = new IPython.ToolBar();
23
23
24 MainToolBar.prototype.construct = function () {
24 MainToolBar.prototype.construct = function () {
25 this.add_buttons_group([
25 this.add_buttons_group([
26 {
26 {
27 id : 'save_b',
27 id : 'save_b',
28 label : 'Save',
28 label : 'Save',
29 icon : 'ui-icon-disk',
29 icon : 'ui-icon-disk',
30 callback : function () {
30 callback : function () {
31 IPython.notebook.save_notebook();
31 IPython.notebook.save_notebook();
32 }
32 }
33 }
33 }
34 ]);
34 ]);
35 this.add_buttons_group([
35 this.add_buttons_group([
36 {
36 {
37 id : 'cut_b',
37 id : 'cut_b',
38 label : 'Cut Cell',
38 label : 'Cut Cell',
39 icon : 'ui-icon-scissors',
39 icon : 'ui-icon-scissors',
40 callback : function () {
40 callback : function () {
41 IPython.notebook.cut_cell();
41 IPython.notebook.cut_cell();
42 }
42 }
43 },
43 },
44 {
44 {
45 id : 'copy_b',
45 id : 'copy_b',
46 label : 'Copy Cell',
46 label : 'Copy Cell',
47 icon : 'ui-icon-copy',
47 icon : 'ui-icon-copy',
48 callback : function () {
48 callback : function () {
49 IPython.notebook.copy_cell();
49 IPython.notebook.copy_cell();
50 }
50 }
51 },
51 },
52 {
52 {
53 id : 'paste_b',
53 id : 'paste_b',
54 label : 'Paste Cell',
54 label : 'Paste Cell Below',
55 icon : 'ui-icon-clipboard',
55 icon : 'ui-icon-clipboard',
56 callback : function () {
56 callback : function () {
57 IPython.notebook.paste_cell();
57 IPython.notebook.paste_cell_below();
58 }
58 }
59 }
59 }
60 ],'cut_copy_paste');
60 ],'cut_copy_paste');
61
61
62 this.add_buttons_group([
62 this.add_buttons_group([
63 {
63 {
64 id : 'move_up_b',
64 id : 'move_up_b',
65 label : 'Move Cell Up',
65 label : 'Move Cell Up',
66 icon : 'ui-icon-arrowthick-1-n',
66 icon : 'ui-icon-arrowthick-1-n',
67 callback : function () {
67 callback : function () {
68 IPython.notebook.move_cell_up();
68 IPython.notebook.move_cell_up();
69 }
69 }
70 },
70 },
71 {
71 {
72 id : 'move_down_b',
72 id : 'move_down_b',
73 label : 'Move Cell Down',
73 label : 'Move Cell Down',
74 icon : 'ui-icon-arrowthick-1-s',
74 icon : 'ui-icon-arrowthick-1-s',
75 callback : function () {
75 callback : function () {
76 IPython.notebook.move_cell_down();
76 IPython.notebook.move_cell_down();
77 }
77 }
78 }
78 }
79 ],'move_up_down');
79 ],'move_up_down');
80
80
81 this.add_buttons_group([
81 this.add_buttons_group([
82 {
82 {
83 id : 'insert_above_b',
83 id : 'insert_above_b',
84 label : 'Insert Cell Above',
84 label : 'Insert Cell Above',
85 icon : 'ui-icon-arrowthickstop-1-n',
85 icon : 'ui-icon-arrowthickstop-1-n',
86 callback : function () {
86 callback : function () {
87 IPython.notebook.insert_cell_above('code');
87 IPython.notebook.insert_cell_above('code');
88 }
88 }
89 },
89 },
90 {
90 {
91 id : 'insert_below_b',
91 id : 'insert_below_b',
92 label : 'Insert Cell Below',
92 label : 'Insert Cell Below',
93 icon : 'ui-icon-arrowthickstop-1-s',
93 icon : 'ui-icon-arrowthickstop-1-s',
94 callback : function () {
94 callback : function () {
95 IPython.notebook.insert_cell_below('code');
95 IPython.notebook.insert_cell_below('code');
96 }
96 }
97 }
97 }
98 ],'insert_above_below');
98 ],'insert_above_below');
99
99
100 this.add_buttons_group([
100 this.add_buttons_group([
101 {
101 {
102 id : 'run_b',
102 id : 'run_b',
103 label : 'Run Cell',
103 label : 'Run Cell',
104 icon : 'ui-icon-play',
104 icon : 'ui-icon-play',
105 callback : function () {
105 callback : function () {
106 IPython.notebook.execute_selected_cell();
106 IPython.notebook.execute_selected_cell();
107 }
107 }
108 },
108 },
109 {
109 {
110 id : 'interrupt_b',
110 id : 'interrupt_b',
111 label : 'Interrupt',
111 label : 'Interrupt',
112 icon : 'ui-icon-stop',
112 icon : 'ui-icon-stop',
113 callback : function () {
113 callback : function () {
114 IPython.notebook.kernel.interrupt();
114 IPython.notebook.kernel.interrupt();
115 }
115 }
116 }
116 }
117 ],'run_int');
117 ],'run_int');
118
118
119
119
120 };
120 };
121
121
122 MainToolBar.prototype.add_drop_down_list = function () {
122 MainToolBar.prototype.add_drop_down_list = function () {
123 var select = $(this.selector)
123 var select = $(this.selector)
124 .append($('<select/>')
124 .append($('<select/>')
125 .attr('id','cell_type')
125 .attr('id','cell_type')
126 .addClass('ui-widget ui-widget-content')
126 .addClass('ui-widget ui-widget-content')
127 .append($('<option/>').attr('value','code').text('Code'))
127 .append($('<option/>').attr('value','code').text('Code'))
128 .append($('<option/>').attr('value','markdown').text('Markdown'))
128 .append($('<option/>').attr('value','markdown').text('Markdown'))
129 .append($('<option/>').attr('value','raw').text('Raw Text'))
129 .append($('<option/>').attr('value','raw').text('Raw Text'))
130 .append($('<option/>').attr('value','heading1').text('Heading 1'))
130 .append($('<option/>').attr('value','heading1').text('Heading 1'))
131 .append($('<option/>').attr('value','heading2').text('Heading 2'))
131 .append($('<option/>').attr('value','heading2').text('Heading 2'))
132 .append($('<option/>').attr('value','heading3').text('Heading 3'))
132 .append($('<option/>').attr('value','heading3').text('Heading 3'))
133 .append($('<option/>').attr('value','heading4').text('Heading 4'))
133 .append($('<option/>').attr('value','heading4').text('Heading 4'))
134 .append($('<option/>').attr('value','heading5').text('Heading 5'))
134 .append($('<option/>').attr('value','heading5').text('Heading 5'))
135 .append($('<option/>').attr('value','heading6').text('Heading 6'))
135 .append($('<option/>').attr('value','heading6').text('Heading 6'))
136 .append($('<option/>').attr('value','heading7').text('Heading 7'))
136 .append($('<option/>').attr('value','heading7').text('Heading 7'))
137 .append($('<option/>').attr('value','heading8').text('Heading 8'))
137 .append($('<option/>').attr('value','heading8').text('Heading 8'))
138 );
138 );
139 };
139 };
140
140
141 MainToolBar.prototype.bind_events = function () {
141 MainToolBar.prototype.bind_events = function () {
142 var that = this;
142 var that = this;
143
143
144 this.element.find('#cell_type').change(function () {
144 this.element.find('#cell_type').change(function () {
145 var cell_type = $(this).val();
145 var cell_type = $(this).val();
146 if (cell_type === 'code') {
146 if (cell_type === 'code') {
147 IPython.notebook.to_code();
147 IPython.notebook.to_code();
148 } else if (cell_type === 'markdown') {
148 } else if (cell_type === 'markdown') {
149 IPython.notebook.to_markdown();
149 IPython.notebook.to_markdown();
150 } else if (cell_type === 'raw') {
150 } else if (cell_type === 'raw') {
151 IPython.notebook.to_raw();
151 IPython.notebook.to_raw();
152 } else if (cell_type === 'heading1') {
152 } else if (cell_type === 'heading1') {
153 IPython.notebook.to_heading(undefined, 1);
153 IPython.notebook.to_heading(undefined, 1);
154 } else if (cell_type === 'heading2') {
154 } else if (cell_type === 'heading2') {
155 IPython.notebook.to_heading(undefined, 2);
155 IPython.notebook.to_heading(undefined, 2);
156 } else if (cell_type === 'heading3') {
156 } else if (cell_type === 'heading3') {
157 IPython.notebook.to_heading(undefined, 3);
157 IPython.notebook.to_heading(undefined, 3);
158 } else if (cell_type === 'heading4') {
158 } else if (cell_type === 'heading4') {
159 IPython.notebook.to_heading(undefined, 4);
159 IPython.notebook.to_heading(undefined, 4);
160 } else if (cell_type === 'heading5') {
160 } else if (cell_type === 'heading5') {
161 IPython.notebook.to_heading(undefined, 5);
161 IPython.notebook.to_heading(undefined, 5);
162 } else if (cell_type === 'heading6') {
162 } else if (cell_type === 'heading6') {
163 IPython.notebook.to_heading(undefined, 6);
163 IPython.notebook.to_heading(undefined, 6);
164 }
164 }
165 });
165 });
166 $([IPython.events]).on('selected_cell_type_changed.Notebook', function (event, data) {
166 $([IPython.events]).on('selected_cell_type_changed.Notebook', function (event, data) {
167 if (data.cell_type === 'heading') {
167 if (data.cell_type === 'heading') {
168 that.element.find('#cell_type').val(data.cell_type+data.level);
168 that.element.find('#cell_type').val(data.cell_type+data.level);
169 } else {
169 } else {
170 that.element.find('#cell_type').val(data.cell_type);
170 that.element.find('#cell_type').val(data.cell_type);
171 }
171 }
172 });
172 });
173 };
173 };
174
174
175 IPython.MainToolBar = MainToolBar;
175 IPython.MainToolBar = MainToolBar;
176
176
177 return IPython;
177 return IPython;
178
178
179 }(IPython));
179 }(IPython));
@@ -1,243 +1,241 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2008-2012 The IPython Development Team
2 // Copyright (C) 2008-2012 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // MathJax utility functions
9 // MathJax utility functions
10 //============================================================================
10 //============================================================================
11
11
12 IPython.namespace('IPython.mathjaxutils');
12 IPython.namespace('IPython.mathjaxutils');
13
13
14 IPython.mathjaxutils = (function (IPython) {
14 IPython.mathjaxutils = (function (IPython) {
15
15
16 var init = function () {
16 var init = function () {
17 if (window.MathJax) {
17 if (window.MathJax) {
18 // MathJax loaded
18 // MathJax loaded
19 MathJax.Hub.Config({
19 MathJax.Hub.Config({
20 TeX: { equationNumbers: { autoNumber: "AMS", useLabelIds: true } },
21 tex2jax: {
20 tex2jax: {
22 inlineMath: [ ['$','$'], ["\\(","\\)"] ],
21 inlineMath: [ ['$','$'], ["\\(","\\)"] ],
23 displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
22 displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
24 processEnvironments: true
23 processEnvironments: true
25 },
24 },
26 displayAlign: 'left', // Change this to 'center' to center equations.
25 displayAlign: 'left', // Change this to 'center' to center equations.
27 "HTML-CSS": {
26 "HTML-CSS": {
28 styles: {'.MathJax_Display': {"margin": 0}}
27 styles: {'.MathJax_Display': {"margin": 0}}
29 }
28 }
30 });
29 });
30 MathJax.Hub.Configured();
31 } else if (window.mathjax_url != "") {
31 } else if (window.mathjax_url != "") {
32 // Don't have MathJax, but should. Show dialog.
32 // Don't have MathJax, but should. Show dialog.
33 var dialog = $('<div></div>')
33 var dialog = $('<div></div>')
34 .append(
34 .append(
35 $("<p></p>").addClass('dialog').html(
35 $("<p></p>").addClass('dialog').html(
36 "Math/LaTeX rendering will be disabled."
36 "Math/LaTeX rendering will be disabled."
37 )
37 )
38 ).append(
38 ).append(
39 $("<p></p>").addClass('dialog').html(
39 $("<p></p>").addClass('dialog').html(
40 "If you have administrative access to the notebook server and" +
40 "If you have administrative access to the notebook server and" +
41 " a working internet connection, you can install a local copy" +
41 " a working internet connection, you can install a local copy" +
42 " of MathJax for offline use with the following command on the server" +
42 " of MathJax for offline use with the following command on the server" +
43 " at a Python or IPython prompt:"
43 " at a Python or IPython prompt:"
44 )
44 )
45 ).append(
45 ).append(
46 $("<pre></pre>").addClass('dialog').html(
46 $("<pre></pre>").addClass('dialog').html(
47 ">>> from IPython.external import mathjax; mathjax.install_mathjax()"
47 ">>> from IPython.external import mathjax; mathjax.install_mathjax()"
48 )
48 )
49 ).append(
49 ).append(
50 $("<p></p>").addClass('dialog').html(
50 $("<p></p>").addClass('dialog').html(
51 "This will try to install MathJax into the IPython source directory."
51 "This will try to install MathJax into the IPython source directory."
52 )
52 )
53 ).append(
53 ).append(
54 $("<p></p>").addClass('dialog').html(
54 $("<p></p>").addClass('dialog').html(
55 "If IPython is installed to a location that requires" +
55 "If IPython is installed to a location that requires" +
56 " administrative privileges to write, you will need to make this call as" +
56 " administrative privileges to write, you will need to make this call as" +
57 " an administrator, via 'sudo'."
57 " an administrator, via 'sudo'."
58 )
58 )
59 ).append(
59 ).append(
60 $("<p></p>").addClass('dialog').html(
60 $("<p></p>").addClass('dialog').html(
61 "When you start the notebook server, you can instruct it to disable MathJax support altogether:"
61 "When you start the notebook server, you can instruct it to disable MathJax support altogether:"
62 )
62 )
63 ).append(
63 ).append(
64 $("<pre></pre>").addClass('dialog').html(
64 $("<pre></pre>").addClass('dialog').html(
65 "$ ipython notebook --no-mathjax"
65 "$ ipython notebook --no-mathjax"
66 )
66 )
67 ).append(
67 ).append(
68 $("<p></p>").addClass('dialog').html(
68 $("<p></p>").addClass('dialog').html(
69 "which will prevent this dialog from appearing."
69 "which will prevent this dialog from appearing."
70 )
70 )
71 ).dialog({
71 ).dialog({
72 title: "Failed to retrieve MathJax from '" + window.mathjax_url + "'",
72 title: "Failed to retrieve MathJax from '" + window.mathjax_url + "'",
73 width: "70%",
73 width: "70%",
74 modal: true,
74 modal: true,
75 })
75 })
76 } else {
76 } else {
77 // No MathJax, but none expected. No dialog.
77 // No MathJax, but none expected. No dialog.
78 };
78 };
79 };
79 };
80
80
81 // Some magic for deferring mathematical expressions to MathJax
81 // Some magic for deferring mathematical expressions to MathJax
82 // by hiding them from the Markdown parser.
82 // by hiding them from the Markdown parser.
83 // Some of the code here is adapted with permission from Davide Cervone
83 // Some of the code here is adapted with permission from Davide Cervone
84 // under the terms of the Apache2 license governing the MathJax project.
84 // under the terms of the Apache2 license governing the MathJax project.
85 // Other minor modifications are also due to StackExchange and are used with
85 // Other minor modifications are also due to StackExchange and are used with
86 // permission.
86 // permission.
87
87
88 var inline = "$"; // the inline math delimiter
88 var inline = "$"; // the inline math delimiter
89 var blocks, start, end, last, braces; // used in searching for math
89 var blocks, start, end, last, braces; // used in searching for math
90 var math; // stores math until pagedown (Markdown parser) is done
90 var math; // stores math until pagedown (Markdown parser) is done
91 var HUB = MathJax.Hub;
92
91
93 // MATHSPLIT contains the pattern for math delimiters and special symbols
92 // MATHSPLIT contains the pattern for math delimiters and special symbols
94 // needed for searching for math in the text input.
93 // needed for searching for math in the text input.
95 var MATHSPLIT = /(\$\$?|\\(?:begin|end)\{[a-z]*\*?\}|\\[\\{}$]|[{}]|(?:\n\s*)+|@@\d+@@)/i;
94 var MATHSPLIT = /(\$\$?|\\(?:begin|end)\{[a-z]*\*?\}|\\[\\{}$]|[{}]|(?:\n\s*)+|@@\d+@@)/i;
96
95
97 // The math is in blocks i through j, so
96 // The math is in blocks i through j, so
98 // collect it into one block and clear the others.
97 // collect it into one block and clear the others.
99 // Replace &, <, and > by named entities.
98 // Replace &, <, and > by named entities.
100 // For IE, put <br> at the ends of comments since IE removes \n.
99 // For IE, put <br> at the ends of comments since IE removes \n.
101 // Clear the current math positions and store the index of the
100 // Clear the current math positions and store the index of the
102 // math, then push the math string onto the storage array.
101 // math, then push the math string onto the storage array.
103 // The preProcess function is called on all blocks if it has been passed in
102 // The preProcess function is called on all blocks if it has been passed in
104 var process_math = function (i, j, pre_process) {
103 var process_math = function (i, j, pre_process) {
104 var hub = MathJax.Hub;
105 var block = blocks.slice(i, j + 1).join("").replace(/&/g, "&amp;") // use HTML entity for &
105 var block = blocks.slice(i, j + 1).join("").replace(/&/g, "&amp;") // use HTML entity for &
106 .replace(/</g, "&lt;") // use HTML entity for <
106 .replace(/</g, "&lt;") // use HTML entity for <
107 .replace(/>/g, "&gt;") // use HTML entity for >
107 .replace(/>/g, "&gt;") // use HTML entity for >
108 ;
108 ;
109 if (HUB.Browser.isMSIE) {
109 if (hub.Browser.isMSIE) {
110 block = block.replace(/(%[^\n]*)\n/g, "$1<br/>\n")
110 block = block.replace(/(%[^\n]*)\n/g, "$1<br/>\n")
111 }
111 }
112 while (j > i) {
112 while (j > i) {
113 blocks[j] = "";
113 blocks[j] = "";
114 j--;
114 j--;
115 }
115 }
116 blocks[i] = "@@" + math.length + "@@"; // replace the current block text with a unique tag to find later
116 blocks[i] = "@@" + math.length + "@@"; // replace the current block text with a unique tag to find later
117 if (pre_process)
117 if (pre_process)
118 block = pre_process(block);
118 block = pre_process(block);
119 math.push(block);
119 math.push(block);
120 start = end = last = null;
120 start = end = last = null;
121 }
121 }
122
122
123 // Break up the text into its component parts and search
123 // Break up the text into its component parts and search
124 // through them for math delimiters, braces, linebreaks, etc.
124 // through them for math delimiters, braces, linebreaks, etc.
125 // Math delimiters must match and braces must balance.
125 // Math delimiters must match and braces must balance.
126 // Don't allow math to pass through a double linebreak
126 // Don't allow math to pass through a double linebreak
127 // (which will be a paragraph).
127 // (which will be a paragraph).
128 //
128 //
129 var remove_math = function (text) {
129 var remove_math = function (text) {
130 if (!window.MathJax) {
131 return text;
132 }
133
130 start = end = last = null; // for tracking math delimiters
134 start = end = last = null; // for tracking math delimiters
131 math = []; // stores math strings for later
135 math = []; // stores math strings for later
132
136
133 // Except for extreme edge cases, this should catch precisely those pieces of the markdown
137 // Except for extreme edge cases, this should catch precisely those pieces of the markdown
134 // source that will later be turned into code spans. While MathJax will not TeXify code spans,
138 // source that will later be turned into code spans. While MathJax will not TeXify code spans,
135 // we still have to consider them at this point; the following issue has happened several times:
139 // we still have to consider them at this point; the following issue has happened several times:
136 //
140 //
137 // `$foo` and `$bar` are varibales. --> <code>$foo ` and `$bar</code> are variables.
141 // `$foo` and `$bar` are varibales. --> <code>$foo ` and `$bar</code> are variables.
138
142
139 var hasCodeSpans = /`/.test(text),
143 var hasCodeSpans = /`/.test(text),
140 de_tilde;
144 de_tilde;
141 if (hasCodeSpans) {
145 if (hasCodeSpans) {
142 text = text.replace(/~/g, "~T").replace(/(^|[^\\])(`+)([^\n]*?[^`\n])\2(?!`)/gm, function (wholematch) {
146 text = text.replace(/~/g, "~T").replace(/(^|[^\\])(`+)([^\n]*?[^`\n])\2(?!`)/gm, function (wholematch) {
143 return wholematch.replace(/\$/g, "~D");
147 return wholematch.replace(/\$/g, "~D");
144 });
148 });
145 de_tilde = function (text) { return text.replace(/~([TD])/g, function (wholematch, character) { return { T: "~", D: "$" }[character]; }) };
149 de_tilde = function (text) { return text.replace(/~([TD])/g, function (wholematch, character) { return { T: "~", D: "$" }[character]; }) };
146 } else {
150 } else {
147 de_tilde = function (text) { return text; };
151 de_tilde = function (text) { return text; };
148 }
152 }
149
153
150 blocks = IPython.utils.regex_split(text.replace(/\r\n?/g, "\n"),MATHSPLIT);
154 blocks = IPython.utils.regex_split(text.replace(/\r\n?/g, "\n"),MATHSPLIT);
151
155
152 for (var i = 1, m = blocks.length; i < m; i += 2) {
156 for (var i = 1, m = blocks.length; i < m; i += 2) {
153 var block = blocks[i];
157 var block = blocks[i];
154 if (block.charAt(0) === "@") {
158 if (block.charAt(0) === "@") {
155 //
159 //
156 // Things that look like our math markers will get
160 // Things that look like our math markers will get
157 // stored and then retrieved along with the math.
161 // stored and then retrieved along with the math.
158 //
162 //
159 blocks[i] = "@@" + math.length + "@@";
163 blocks[i] = "@@" + math.length + "@@";
160 math.push(block);
164 math.push(block);
161 }
165 }
162 else if (start) {
166 else if (start) {
163 //
167 //
164 // If we are in math, look for the end delimiter,
168 // If we are in math, look for the end delimiter,
165 // but don't go past double line breaks, and
169 // but don't go past double line breaks, and
166 // and balance braces within the math.
170 // and balance braces within the math.
167 //
171 //
168 if (block === end) {
172 if (block === end) {
169 if (braces) {
173 if (braces) {
170 last = i
174 last = i
171 }
175 }
172 else {
176 else {
173 process_math(start, i, de_tilde)
177 process_math(start, i, de_tilde)
174 }
178 }
175 }
179 }
176 else if (block.match(/\n.*\n/)) {
180 else if (block.match(/\n.*\n/)) {
177 if (last) {
181 if (last) {
178 i = last;
182 i = last;
179 process_math(start, i, de_tilde)
183 process_math(start, i, de_tilde)
180 }
184 }
181 start = end = last = null;
185 start = end = last = null;
182 braces = 0;
186 braces = 0;
183 }
187 }
184 else if (block === "{") {
188 else if (block === "{") {
185 braces++
189 braces++
186 }
190 }
187 else if (block === "}" && braces) {
191 else if (block === "}" && braces) {
188 braces--
192 braces--
189 }
193 }
190 }
194 }
191 else {
195 else {
192 //
196 //
193 // Look for math start delimiters and when
197 // Look for math start delimiters and when
194 // found, set up the end delimiter.
198 // found, set up the end delimiter.
195 //
199 //
196 if (block === inline || block === "$$") {
200 if (block === inline || block === "$$") {
197 start = i;
201 start = i;
198 end = block;
202 end = block;
199 braces = 0;
203 braces = 0;
200 }
204 }
201 else if (block.substr(1, 5) === "begin") {
205 else if (block.substr(1, 5) === "begin") {
202 start = i;
206 start = i;
203 end = "\\end" + block.substr(6);
207 end = "\\end" + block.substr(6);
204 braces = 0;
208 braces = 0;
205 }
209 }
206 }
210 }
207 }
211 }
208 if (last) {
212 if (last) {
209 process_math(start, last, de_tilde)
213 process_math(start, last, de_tilde)
210 }
214 }
211 return de_tilde(blocks.join(""));
215 return de_tilde(blocks.join(""));
212 }
216 }
213
217
214 //
218 //
215 // Put back the math strings that were saved,
219 // Put back the math strings that were saved,
216 // and clear the math array (no need to keep it around).
220 // and clear the math array (no need to keep it around).
217 //
221 //
218 var replace_math = function (text) {
222 var replace_math = function (text) {
223 if (!window.MathJax) {
224 return text;
225 }
226
219 text = text.replace(/@@(\d+)@@/g, function (match, n) {
227 text = text.replace(/@@(\d+)@@/g, function (match, n) {
220 return math[n]
228 return math[n]
221 });
229 });
222 math = null;
230 math = null;
223 return text;
231 return text;
224 }
232 }
225
233
226 var queue_render = function () {
227 // see https://groups.google.com/forum/?fromgroups=#!topic/mathjax-users/cpwy5eCH1ZQ
228 MathJax.Hub.Queue(
229 ["resetEquationNumbers",MathJax.InputJax.TeX],
230 ["PreProcess",MathJax.Hub],
231 ["Reprocess",MathJax.Hub]
232 );
233 }
234
235 return {
234 return {
236 init : init,
235 init : init,
237 process_math : process_math,
236 process_math : process_math,
238 remove_math : remove_math,
237 remove_math : remove_math,
239 replace_math : replace_math,
238 replace_math : replace_math
240 queue_render : queue_render
241 };
239 };
242
240
243 }(IPython)); No newline at end of file
241 }(IPython));
@@ -1,192 +1,198 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2008-2011 The IPython Development Team
2 // Copyright (C) 2008-2011 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // MenuBar
9 // MenuBar
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13
13
14 var MenuBar = function (selector) {
14 var MenuBar = function (selector) {
15 this.selector = selector;
15 this.selector = selector;
16 if (this.selector !== undefined) {
16 if (this.selector !== undefined) {
17 this.element = $(selector);
17 this.element = $(selector);
18 this.style();
18 this.style();
19 this.bind_events();
19 this.bind_events();
20 }
20 }
21 };
21 };
22
22
23
23
24 MenuBar.prototype.style = function () {
24 MenuBar.prototype.style = function () {
25 this.element.addClass('border-box-sizing');
25 this.element.addClass('border-box-sizing');
26 $('ul#menus').menubar({
26 $('ul#menus').menubar({
27 select : function (event, ui) {
27 select : function (event, ui) {
28 // The selected cell loses focus when the menu is entered, so we
28 // The selected cell loses focus when the menu is entered, so we
29 // re-select it upon selection.
29 // re-select it upon selection.
30 var i = IPython.notebook.get_selected_index();
30 var i = IPython.notebook.get_selected_index();
31 IPython.notebook.select(i);
31 IPython.notebook.select(i);
32 }
32 }
33 });
33 });
34 };
34 };
35
35
36
36
37 MenuBar.prototype.bind_events = function () {
37 MenuBar.prototype.bind_events = function () {
38 // File
38 // File
39 this.element.find('#new_notebook').click(function () {
39 this.element.find('#new_notebook').click(function () {
40 window.open($('body').data('baseProjectUrl')+'new');
40 window.open($('body').data('baseProjectUrl')+'new');
41 });
41 });
42 this.element.find('#open_notebook').click(function () {
42 this.element.find('#open_notebook').click(function () {
43 window.open($('body').data('baseProjectUrl'));
43 window.open($('body').data('baseProjectUrl'));
44 });
44 });
45 this.element.find('#rename_notebook').click(function () {
45 this.element.find('#rename_notebook').click(function () {
46 IPython.save_widget.rename_notebook();
46 IPython.save_widget.rename_notebook();
47 });
47 });
48 this.element.find('#copy_notebook').click(function () {
48 this.element.find('#copy_notebook').click(function () {
49 var notebook_id = IPython.notebook.get_notebook_id();
49 var notebook_id = IPython.notebook.get_notebook_id();
50 var url = $('body').data('baseProjectUrl') + notebook_id + '/copy';
50 var url = $('body').data('baseProjectUrl') + notebook_id + '/copy';
51 window.open(url,'_blank');
51 window.open(url,'_blank');
52 return false;
52 return false;
53 });
53 });
54 this.element.find('#save_notebook').click(function () {
54 this.element.find('#save_notebook').click(function () {
55 IPython.notebook.save_notebook();
55 IPython.notebook.save_notebook();
56 });
56 });
57 this.element.find('#download_ipynb').click(function () {
57 this.element.find('#download_ipynb').click(function () {
58 var notebook_id = IPython.notebook.get_notebook_id();
58 var notebook_id = IPython.notebook.get_notebook_id();
59 var url = $('body').data('baseProjectUrl') + 'notebooks/' +
59 var url = $('body').data('baseProjectUrl') + 'notebooks/' +
60 notebook_id + '?format=json';
60 notebook_id + '?format=json';
61 window.open(url,'_newtab');
61 window.open(url,'_newtab');
62 });
62 });
63 this.element.find('#download_py').click(function () {
63 this.element.find('#download_py').click(function () {
64 var notebook_id = IPython.notebook.get_notebook_id();
64 var notebook_id = IPython.notebook.get_notebook_id();
65 var url = $('body').data('baseProjectUrl') + 'notebooks/' +
65 var url = $('body').data('baseProjectUrl') + 'notebooks/' +
66 notebook_id + '?format=py';
66 notebook_id + '?format=py';
67 window.open(url,'_newtab');
67 window.open(url,'_newtab');
68 });
68 });
69 this.element.find('button#print_notebook').click(function () {
69 this.element.find('button#print_notebook').click(function () {
70 IPython.print_widget.print_notebook();
70 IPython.print_widget.print_notebook();
71 });
71 });
72 this.element.find('#kill_and_exit').click(function () {
72 this.element.find('#kill_and_exit').click(function () {
73 IPython.notebook.kernel.kill();
73 IPython.notebook.kernel.kill();
74 setTimeout(function(){window.close();}, 200);
74 setTimeout(function(){window.close();}, 200);
75 });
75 });
76 // Edit
76 // Edit
77 this.element.find('#cut_cell').click(function () {
77 this.element.find('#cut_cell').click(function () {
78 IPython.notebook.cut_cell();
78 IPython.notebook.cut_cell();
79 });
79 });
80 this.element.find('#copy_cell').click(function () {
80 this.element.find('#copy_cell').click(function () {
81 IPython.notebook.copy_cell();
81 IPython.notebook.copy_cell();
82 });
82 });
83 this.element.find('#delete_cell').click(function () {
83 this.element.find('#delete_cell').click(function () {
84 IPython.notebook.delete_cell();
84 IPython.notebook.delete_cell();
85 });
85 });
86 this.element.find('#split_cell').click(function () {
86 this.element.find('#split_cell').click(function () {
87 IPython.notebook.split_cell();
87 IPython.notebook.split_cell();
88 });
88 });
89 this.element.find('#merge_cell_above').click(function () {
89 this.element.find('#merge_cell_above').click(function () {
90 IPython.notebook.merge_cell_above();
90 IPython.notebook.merge_cell_above();
91 });
91 });
92 this.element.find('#merge_cell_below').click(function () {
92 this.element.find('#merge_cell_below').click(function () {
93 IPython.notebook.merge_cell_below();
93 IPython.notebook.merge_cell_below();
94 });
94 });
95 this.element.find('#move_cell_up').click(function () {
95 this.element.find('#move_cell_up').click(function () {
96 IPython.notebook.move_cell_up();
96 IPython.notebook.move_cell_up();
97 });
97 });
98 this.element.find('#move_cell_down').click(function () {
98 this.element.find('#move_cell_down').click(function () {
99 IPython.notebook.move_cell_down();
99 IPython.notebook.move_cell_down();
100 });
100 });
101 this.element.find('#select_previous').click(function () {
101 this.element.find('#select_previous').click(function () {
102 IPython.notebook.select_prev();
102 IPython.notebook.select_prev();
103 });
103 });
104 this.element.find('#select_next').click(function () {
104 this.element.find('#select_next').click(function () {
105 IPython.notebook.select_next();
105 IPython.notebook.select_next();
106 });
106 });
107 // View
107 // View
108 this.element.find('#toggle_header').click(function () {
108 this.element.find('#toggle_header').click(function () {
109 $('div#header').toggle();
109 $('div#header').toggle();
110 IPython.layout_manager.do_resize();
110 IPython.layout_manager.do_resize();
111 });
111 });
112 this.element.find('#toggle_toolbar').click(function () {
112 this.element.find('#toggle_toolbar').click(function () {
113 IPython.toolbar.toggle();
113 IPython.toolbar.toggle();
114 });
114 });
115 // Insert
115 // Insert
116 this.element.find('#insert_cell_above').click(function () {
116 this.element.find('#insert_cell_above').click(function () {
117 IPython.notebook.insert_cell_above('code');
117 IPython.notebook.insert_cell_above('code');
118 });
118 });
119 this.element.find('#insert_cell_below').click(function () {
119 this.element.find('#insert_cell_below').click(function () {
120 IPython.notebook.insert_cell_below('code');
120 IPython.notebook.insert_cell_below('code');
121 });
121 });
122 // Cell
122 // Cell
123 this.element.find('#run_cell').click(function () {
123 this.element.find('#run_cell').click(function () {
124 IPython.notebook.execute_selected_cell();
124 IPython.notebook.execute_selected_cell();
125 });
125 });
126 this.element.find('#run_cell_in_place').click(function () {
126 this.element.find('#run_cell_in_place').click(function () {
127 IPython.notebook.execute_selected_cell({terminal:true});
127 IPython.notebook.execute_selected_cell({terminal:true});
128 });
128 });
129 this.element.find('#run_all_cells').click(function () {
129 this.element.find('#run_all_cells').click(function () {
130 IPython.notebook.execute_all_cells();
130 IPython.notebook.execute_all_cells();
131 });
131 }).attr('title', 'Run all cells in the notebook');
132 this.element.find('#run_all_cells_above').click(function () {
133 IPython.notebook.execute_cells_above();
134 }).attr('title', 'Run all cells above (but not including) this cell');
135 this.element.find('#run_all_cells_below').click(function () {
136 IPython.notebook.execute_cells_below();
137 }).attr('title', 'Run this cell and all cells below it');
132 this.element.find('#to_code').click(function () {
138 this.element.find('#to_code').click(function () {
133 IPython.notebook.to_code();
139 IPython.notebook.to_code();
134 });
140 });
135 this.element.find('#to_markdown').click(function () {
141 this.element.find('#to_markdown').click(function () {
136 IPython.notebook.to_markdown();
142 IPython.notebook.to_markdown();
137 });
143 });
138 this.element.find('#to_raw').click(function () {
144 this.element.find('#to_raw').click(function () {
139 IPython.notebook.to_raw();
145 IPython.notebook.to_raw();
140 });
146 });
141 this.element.find('#to_heading1').click(function () {
147 this.element.find('#to_heading1').click(function () {
142 IPython.notebook.to_heading(undefined, 1);
148 IPython.notebook.to_heading(undefined, 1);
143 });
149 });
144 this.element.find('#to_heading2').click(function () {
150 this.element.find('#to_heading2').click(function () {
145 IPython.notebook.to_heading(undefined, 2);
151 IPython.notebook.to_heading(undefined, 2);
146 });
152 });
147 this.element.find('#to_heading3').click(function () {
153 this.element.find('#to_heading3').click(function () {
148 IPython.notebook.to_heading(undefined, 3);
154 IPython.notebook.to_heading(undefined, 3);
149 });
155 });
150 this.element.find('#to_heading4').click(function () {
156 this.element.find('#to_heading4').click(function () {
151 IPython.notebook.to_heading(undefined, 4);
157 IPython.notebook.to_heading(undefined, 4);
152 });
158 });
153 this.element.find('#to_heading5').click(function () {
159 this.element.find('#to_heading5').click(function () {
154 IPython.notebook.to_heading(undefined, 5);
160 IPython.notebook.to_heading(undefined, 5);
155 });
161 });
156 this.element.find('#to_heading6').click(function () {
162 this.element.find('#to_heading6').click(function () {
157 IPython.notebook.to_heading(undefined, 6);
163 IPython.notebook.to_heading(undefined, 6);
158 });
164 });
159 this.element.find('#toggle_output').click(function () {
165 this.element.find('#toggle_output').click(function () {
160 IPython.notebook.toggle_output();
166 IPython.notebook.toggle_output();
161 });
167 });
162 this.element.find('#collapse_all_output').click(function () {
168 this.element.find('#collapse_all_output').click(function () {
163 IPython.notebook.collapse_all_output();
169 IPython.notebook.collapse_all_output();
164 });
170 });
165 this.element.find('#scroll_all_output').click(function () {
171 this.element.find('#scroll_all_output').click(function () {
166 IPython.notebook.scroll_all_output();
172 IPython.notebook.scroll_all_output();
167 });
173 });
168 this.element.find('#expand_all_output').click(function () {
174 this.element.find('#expand_all_output').click(function () {
169 IPython.notebook.expand_all_output();
175 IPython.notebook.expand_all_output();
170 });
176 });
171 this.element.find('#clear_all_output').click(function () {
177 this.element.find('#clear_all_output').click(function () {
172 IPython.notebook.clear_all_output();
178 IPython.notebook.clear_all_output();
173 });
179 });
174 // Kernel
180 // Kernel
175 this.element.find('#int_kernel').click(function () {
181 this.element.find('#int_kernel').click(function () {
176 IPython.notebook.kernel.interrupt();
182 IPython.notebook.kernel.interrupt();
177 });
183 });
178 this.element.find('#restart_kernel').click(function () {
184 this.element.find('#restart_kernel').click(function () {
179 IPython.notebook.restart_kernel();
185 IPython.notebook.restart_kernel();
180 });
186 });
181 // Help
187 // Help
182 this.element.find('#keyboard_shortcuts').click(function () {
188 this.element.find('#keyboard_shortcuts').click(function () {
183 IPython.quick_help.show_keyboard_shortcuts();
189 IPython.quick_help.show_keyboard_shortcuts();
184 });
190 });
185 };
191 };
186
192
187
193
188 IPython.MenuBar = MenuBar;
194 IPython.MenuBar = MenuBar;
189
195
190 return IPython;
196 return IPython;
191
197
192 }(IPython));
198 }(IPython));
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now