##// END OF EJS Templates
re-enable pydb flag...
MinRK -
Show More
@@ -1,509 +1,509 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
27
28 import bdb
28 import bdb
29 import linecache
29 import linecache
30 import sys
30 import sys
31
31
32 from IPython.utils import PyColorize
32 from IPython.utils import PyColorize
33 from IPython.core import ipapi
33 from IPython.core import ipapi
34 from IPython.utils import coloransi, io
34 from IPython.utils import coloransi, io
35 from IPython.core.excolors import exception_colors
35 from IPython.core.excolors import exception_colors
36
36
37 # See if we can use pydb.
37 # See if we can use pydb.
38 has_pydb = False
38 has_pydb = False
39 prompt = 'ipdb> '
39 prompt = 'ipdb> '
40 #We have to check this directly from sys.argv, config struct not yet available
40 #We have to check this directly from sys.argv, config struct not yet available
41 if '-pydb' in sys.argv:
41 if '--pydb' in sys.argv:
42 try:
42 try:
43 import pydb
43 import pydb
44 if hasattr(pydb.pydb, "runl") and pydb.version>'1.17':
44 if hasattr(pydb.pydb, "runl") and pydb.version>'1.17':
45 # Version 1.17 is broken, and that's what ships with Ubuntu Edgy, so we
45 # Version 1.17 is broken, and that's what ships with Ubuntu Edgy, so we
46 # better protect against it.
46 # better protect against it.
47 has_pydb = True
47 has_pydb = True
48 except ImportError:
48 except ImportError:
49 print "Pydb (http://bashdb.sourceforge.net/pydb/) does not seem to be available"
49 print "Pydb (http://bashdb.sourceforge.net/pydb/) does not seem to be available"
50
50
51 if has_pydb:
51 if has_pydb:
52 from pydb import Pdb as OldPdb
52 from pydb import Pdb as OldPdb
53 #print "Using pydb for %run -d and post-mortem" #dbg
53 #print "Using pydb for %run -d and post-mortem" #dbg
54 prompt = 'ipydb> '
54 prompt = 'ipydb> '
55 else:
55 else:
56 from pdb import Pdb as OldPdb
56 from pdb import Pdb as OldPdb
57
57
58 # Allow the set_trace code to operate outside of an ipython instance, even if
58 # Allow the set_trace code to operate outside of an ipython instance, even if
59 # it does so with some limitations. The rest of this support is implemented in
59 # it does so with some limitations. The rest of this support is implemented in
60 # the Tracer constructor.
60 # the Tracer constructor.
61 def BdbQuit_excepthook(et,ev,tb):
61 def BdbQuit_excepthook(et,ev,tb):
62 if et==bdb.BdbQuit:
62 if et==bdb.BdbQuit:
63 print 'Exiting Debugger.'
63 print 'Exiting Debugger.'
64 else:
64 else:
65 BdbQuit_excepthook.excepthook_ori(et,ev,tb)
65 BdbQuit_excepthook.excepthook_ori(et,ev,tb)
66
66
67 def BdbQuit_IPython_excepthook(self,et,ev,tb,tb_offset=None):
67 def BdbQuit_IPython_excepthook(self,et,ev,tb,tb_offset=None):
68 print 'Exiting Debugger.'
68 print 'Exiting Debugger.'
69
69
70
70
71 class Tracer(object):
71 class Tracer(object):
72 """Class for local debugging, similar to pdb.set_trace.
72 """Class for local debugging, similar to pdb.set_trace.
73
73
74 Instances of this class, when called, behave like pdb.set_trace, but
74 Instances of this class, when called, behave like pdb.set_trace, but
75 providing IPython's enhanced capabilities.
75 providing IPython's enhanced capabilities.
76
76
77 This is implemented as a class which must be initialized in your own code
77 This is implemented as a class which must be initialized in your own code
78 and not as a standalone function because we need to detect at runtime
78 and not as a standalone function because we need to detect at runtime
79 whether IPython is already active or not. That detection is done in the
79 whether IPython is already active or not. That detection is done in the
80 constructor, ensuring that this code plays nicely with a running IPython,
80 constructor, ensuring that this code plays nicely with a running IPython,
81 while functioning acceptably (though with limitations) if outside of it.
81 while functioning acceptably (though with limitations) if outside of it.
82 """
82 """
83
83
84 def __init__(self,colors=None):
84 def __init__(self,colors=None):
85 """Create a local debugger instance.
85 """Create a local debugger instance.
86
86
87 :Parameters:
87 :Parameters:
88
88
89 - `colors` (None): a string containing the name of the color scheme to
89 - `colors` (None): a string containing the name of the color scheme to
90 use, it must be one of IPython's valid color schemes. If not given, the
90 use, it must be one of IPython's valid color schemes. If not given, the
91 function will default to the current IPython scheme when running inside
91 function will default to the current IPython scheme when running inside
92 IPython, and to 'NoColor' otherwise.
92 IPython, and to 'NoColor' otherwise.
93
93
94 Usage example:
94 Usage example:
95
95
96 from IPython.core.debugger import Tracer; debug_here = Tracer()
96 from IPython.core.debugger import Tracer; debug_here = Tracer()
97
97
98 ... later in your code
98 ... later in your code
99 debug_here() # -> will open up the debugger at that point.
99 debug_here() # -> will open up the debugger at that point.
100
100
101 Once the debugger activates, you can use all of its regular commands to
101 Once the debugger activates, you can use all of its regular commands to
102 step through code, set breakpoints, etc. See the pdb documentation
102 step through code, set breakpoints, etc. See the pdb documentation
103 from the Python standard library for usage details.
103 from the Python standard library for usage details.
104 """
104 """
105
105
106 try:
106 try:
107 ip = get_ipython()
107 ip = get_ipython()
108 except NameError:
108 except NameError:
109 # Outside of ipython, we set our own exception hook manually
109 # Outside of ipython, we set our own exception hook manually
110 BdbQuit_excepthook.excepthook_ori = sys.excepthook
110 BdbQuit_excepthook.excepthook_ori = sys.excepthook
111 sys.excepthook = BdbQuit_excepthook
111 sys.excepthook = BdbQuit_excepthook
112 def_colors = 'NoColor'
112 def_colors = 'NoColor'
113 try:
113 try:
114 # Limited tab completion support
114 # Limited tab completion support
115 import readline
115 import readline
116 readline.parse_and_bind('tab: complete')
116 readline.parse_and_bind('tab: complete')
117 except ImportError:
117 except ImportError:
118 pass
118 pass
119 else:
119 else:
120 # In ipython, we use its custom exception handler mechanism
120 # In ipython, we use its custom exception handler mechanism
121 def_colors = ip.colors
121 def_colors = ip.colors
122 ip.set_custom_exc((bdb.BdbQuit,), BdbQuit_IPython_excepthook)
122 ip.set_custom_exc((bdb.BdbQuit,), BdbQuit_IPython_excepthook)
123
123
124 if colors is None:
124 if colors is None:
125 colors = def_colors
125 colors = def_colors
126 self.debugger = Pdb(colors)
126 self.debugger = Pdb(colors)
127
127
128 def __call__(self):
128 def __call__(self):
129 """Starts an interactive debugger at the point where called.
129 """Starts an interactive debugger at the point where called.
130
130
131 This is similar to the pdb.set_trace() function from the std lib, but
131 This is similar to the pdb.set_trace() function from the std lib, but
132 using IPython's enhanced debugger."""
132 using IPython's enhanced debugger."""
133
133
134 self.debugger.set_trace(sys._getframe().f_back)
134 self.debugger.set_trace(sys._getframe().f_back)
135
135
136
136
137 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
137 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
138 """Make new_fn have old_fn's doc string. This is particularly useful
138 """Make new_fn have old_fn's doc string. This is particularly useful
139 for the do_... commands that hook into the help system.
139 for the do_... commands that hook into the help system.
140 Adapted from from a comp.lang.python posting
140 Adapted from from a comp.lang.python posting
141 by Duncan Booth."""
141 by Duncan Booth."""
142 def wrapper(*args, **kw):
142 def wrapper(*args, **kw):
143 return new_fn(*args, **kw)
143 return new_fn(*args, **kw)
144 if old_fn.__doc__:
144 if old_fn.__doc__:
145 wrapper.__doc__ = old_fn.__doc__ + additional_text
145 wrapper.__doc__ = old_fn.__doc__ + additional_text
146 return wrapper
146 return wrapper
147
147
148
148
149 def _file_lines(fname):
149 def _file_lines(fname):
150 """Return the contents of a named file as a list of lines.
150 """Return the contents of a named file as a list of lines.
151
151
152 This function never raises an IOError exception: if the file can't be
152 This function never raises an IOError exception: if the file can't be
153 read, it simply returns an empty list."""
153 read, it simply returns an empty list."""
154
154
155 try:
155 try:
156 outfile = open(fname)
156 outfile = open(fname)
157 except IOError:
157 except IOError:
158 return []
158 return []
159 else:
159 else:
160 out = outfile.readlines()
160 out = outfile.readlines()
161 outfile.close()
161 outfile.close()
162 return out
162 return out
163
163
164
164
165 class Pdb(OldPdb):
165 class Pdb(OldPdb):
166 """Modified Pdb class, does not load readline."""
166 """Modified Pdb class, does not load readline."""
167
167
168 def __init__(self,color_scheme='NoColor',completekey=None,
168 def __init__(self,color_scheme='NoColor',completekey=None,
169 stdin=None, stdout=None):
169 stdin=None, stdout=None):
170
170
171 # Parent constructor:
171 # Parent constructor:
172 if has_pydb and completekey is None:
172 if has_pydb and completekey is None:
173 OldPdb.__init__(self,stdin=stdin,stdout=io.stdout)
173 OldPdb.__init__(self,stdin=stdin,stdout=io.stdout)
174 else:
174 else:
175 OldPdb.__init__(self,completekey,stdin,stdout)
175 OldPdb.__init__(self,completekey,stdin,stdout)
176
176
177 self.prompt = prompt # The default prompt is '(Pdb)'
177 self.prompt = prompt # The default prompt is '(Pdb)'
178
178
179 # IPython changes...
179 # IPython changes...
180 self.is_pydb = has_pydb
180 self.is_pydb = has_pydb
181
181
182 self.shell = ipapi.get()
182 self.shell = ipapi.get()
183
183
184 if self.is_pydb:
184 if self.is_pydb:
185
185
186 # interactiveshell.py's ipalias seems to want pdb's checkline
186 # interactiveshell.py's ipalias seems to want pdb's checkline
187 # which located in pydb.fn
187 # which located in pydb.fn
188 import pydb.fns
188 import pydb.fns
189 self.checkline = lambda filename, lineno: \
189 self.checkline = lambda filename, lineno: \
190 pydb.fns.checkline(self, filename, lineno)
190 pydb.fns.checkline(self, filename, lineno)
191
191
192 self.curframe = None
192 self.curframe = None
193 self.do_restart = self.new_do_restart
193 self.do_restart = self.new_do_restart
194
194
195 self.old_all_completions = self.shell.Completer.all_completions
195 self.old_all_completions = self.shell.Completer.all_completions
196 self.shell.Completer.all_completions=self.all_completions
196 self.shell.Completer.all_completions=self.all_completions
197
197
198 self.do_list = decorate_fn_with_doc(self.list_command_pydb,
198 self.do_list = decorate_fn_with_doc(self.list_command_pydb,
199 OldPdb.do_list)
199 OldPdb.do_list)
200 self.do_l = self.do_list
200 self.do_l = self.do_list
201 self.do_frame = decorate_fn_with_doc(self.new_do_frame,
201 self.do_frame = decorate_fn_with_doc(self.new_do_frame,
202 OldPdb.do_frame)
202 OldPdb.do_frame)
203
203
204 self.aliases = {}
204 self.aliases = {}
205
205
206 # Create color table: we copy the default one from the traceback
206 # Create color table: we copy the default one from the traceback
207 # module and add a few attributes needed for debugging
207 # module and add a few attributes needed for debugging
208 self.color_scheme_table = exception_colors()
208 self.color_scheme_table = exception_colors()
209
209
210 # shorthands
210 # shorthands
211 C = coloransi.TermColors
211 C = coloransi.TermColors
212 cst = self.color_scheme_table
212 cst = self.color_scheme_table
213
213
214 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
214 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
215 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
215 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
216
216
217 cst['Linux'].colors.breakpoint_enabled = C.LightRed
217 cst['Linux'].colors.breakpoint_enabled = C.LightRed
218 cst['Linux'].colors.breakpoint_disabled = C.Red
218 cst['Linux'].colors.breakpoint_disabled = C.Red
219
219
220 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
220 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
221 cst['LightBG'].colors.breakpoint_disabled = C.Red
221 cst['LightBG'].colors.breakpoint_disabled = C.Red
222
222
223 self.set_colors(color_scheme)
223 self.set_colors(color_scheme)
224
224
225 # Add a python parser so we can syntax highlight source while
225 # Add a python parser so we can syntax highlight source while
226 # debugging.
226 # debugging.
227 self.parser = PyColorize.Parser()
227 self.parser = PyColorize.Parser()
228
228
229 def set_colors(self, scheme):
229 def set_colors(self, scheme):
230 """Shorthand access to the color table scheme selector method."""
230 """Shorthand access to the color table scheme selector method."""
231 self.color_scheme_table.set_active_scheme(scheme)
231 self.color_scheme_table.set_active_scheme(scheme)
232
232
233 def interaction(self, frame, traceback):
233 def interaction(self, frame, traceback):
234 self.shell.set_completer_frame(frame)
234 self.shell.set_completer_frame(frame)
235 OldPdb.interaction(self, frame, traceback)
235 OldPdb.interaction(self, frame, traceback)
236
236
237 def new_do_up(self, arg):
237 def new_do_up(self, arg):
238 OldPdb.do_up(self, arg)
238 OldPdb.do_up(self, arg)
239 self.shell.set_completer_frame(self.curframe)
239 self.shell.set_completer_frame(self.curframe)
240 do_u = do_up = decorate_fn_with_doc(new_do_up, OldPdb.do_up)
240 do_u = do_up = decorate_fn_with_doc(new_do_up, OldPdb.do_up)
241
241
242 def new_do_down(self, arg):
242 def new_do_down(self, arg):
243 OldPdb.do_down(self, arg)
243 OldPdb.do_down(self, arg)
244 self.shell.set_completer_frame(self.curframe)
244 self.shell.set_completer_frame(self.curframe)
245
245
246 do_d = do_down = decorate_fn_with_doc(new_do_down, OldPdb.do_down)
246 do_d = do_down = decorate_fn_with_doc(new_do_down, OldPdb.do_down)
247
247
248 def new_do_frame(self, arg):
248 def new_do_frame(self, arg):
249 OldPdb.do_frame(self, arg)
249 OldPdb.do_frame(self, arg)
250 self.shell.set_completer_frame(self.curframe)
250 self.shell.set_completer_frame(self.curframe)
251
251
252 def new_do_quit(self, arg):
252 def new_do_quit(self, arg):
253
253
254 if hasattr(self, 'old_all_completions'):
254 if hasattr(self, 'old_all_completions'):
255 self.shell.Completer.all_completions=self.old_all_completions
255 self.shell.Completer.all_completions=self.old_all_completions
256
256
257
257
258 return OldPdb.do_quit(self, arg)
258 return OldPdb.do_quit(self, arg)
259
259
260 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
260 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
261
261
262 def new_do_restart(self, arg):
262 def new_do_restart(self, arg):
263 """Restart command. In the context of ipython this is exactly the same
263 """Restart command. In the context of ipython this is exactly the same
264 thing as 'quit'."""
264 thing as 'quit'."""
265 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
265 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
266 return self.do_quit(arg)
266 return self.do_quit(arg)
267
267
268 def postloop(self):
268 def postloop(self):
269 self.shell.set_completer_frame(None)
269 self.shell.set_completer_frame(None)
270
270
271 def print_stack_trace(self):
271 def print_stack_trace(self):
272 try:
272 try:
273 for frame_lineno in self.stack:
273 for frame_lineno in self.stack:
274 self.print_stack_entry(frame_lineno, context = 5)
274 self.print_stack_entry(frame_lineno, context = 5)
275 except KeyboardInterrupt:
275 except KeyboardInterrupt:
276 pass
276 pass
277
277
278 def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ',
278 def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ',
279 context = 3):
279 context = 3):
280 #frame, lineno = frame_lineno
280 #frame, lineno = frame_lineno
281 print >>io.stdout, self.format_stack_entry(frame_lineno, '', context)
281 print >>io.stdout, self.format_stack_entry(frame_lineno, '', context)
282
282
283 # vds: >>
283 # vds: >>
284 frame, lineno = frame_lineno
284 frame, lineno = frame_lineno
285 filename = frame.f_code.co_filename
285 filename = frame.f_code.co_filename
286 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
286 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
287 # vds: <<
287 # vds: <<
288
288
289 def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3):
289 def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3):
290 import linecache, repr
290 import linecache, repr
291
291
292 ret = []
292 ret = []
293
293
294 Colors = self.color_scheme_table.active_colors
294 Colors = self.color_scheme_table.active_colors
295 ColorsNormal = Colors.Normal
295 ColorsNormal = Colors.Normal
296 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
296 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
297 tpl_call = '%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
297 tpl_call = '%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
298 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
298 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
299 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
299 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
300 ColorsNormal)
300 ColorsNormal)
301
301
302 frame, lineno = frame_lineno
302 frame, lineno = frame_lineno
303
303
304 return_value = ''
304 return_value = ''
305 if '__return__' in frame.f_locals:
305 if '__return__' in frame.f_locals:
306 rv = frame.f_locals['__return__']
306 rv = frame.f_locals['__return__']
307 #return_value += '->'
307 #return_value += '->'
308 return_value += repr.repr(rv) + '\n'
308 return_value += repr.repr(rv) + '\n'
309 ret.append(return_value)
309 ret.append(return_value)
310
310
311 #s = filename + '(' + `lineno` + ')'
311 #s = filename + '(' + `lineno` + ')'
312 filename = self.canonic(frame.f_code.co_filename)
312 filename = self.canonic(frame.f_code.co_filename)
313 link = tpl_link % filename
313 link = tpl_link % filename
314
314
315 if frame.f_code.co_name:
315 if frame.f_code.co_name:
316 func = frame.f_code.co_name
316 func = frame.f_code.co_name
317 else:
317 else:
318 func = "<lambda>"
318 func = "<lambda>"
319
319
320 call = ''
320 call = ''
321 if func != '?':
321 if func != '?':
322 if '__args__' in frame.f_locals:
322 if '__args__' in frame.f_locals:
323 args = repr.repr(frame.f_locals['__args__'])
323 args = repr.repr(frame.f_locals['__args__'])
324 else:
324 else:
325 args = '()'
325 args = '()'
326 call = tpl_call % (func, args)
326 call = tpl_call % (func, args)
327
327
328 # The level info should be generated in the same format pdb uses, to
328 # The level info should be generated in the same format pdb uses, to
329 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
329 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
330 if frame is self.curframe:
330 if frame is self.curframe:
331 ret.append('> ')
331 ret.append('> ')
332 else:
332 else:
333 ret.append(' ')
333 ret.append(' ')
334 ret.append('%s(%s)%s\n' % (link,lineno,call))
334 ret.append('%s(%s)%s\n' % (link,lineno,call))
335
335
336 start = lineno - 1 - context//2
336 start = lineno - 1 - context//2
337 lines = linecache.getlines(filename)
337 lines = linecache.getlines(filename)
338 start = max(start, 0)
338 start = max(start, 0)
339 start = min(start, len(lines) - context)
339 start = min(start, len(lines) - context)
340 lines = lines[start : start + context]
340 lines = lines[start : start + context]
341
341
342 for i,line in enumerate(lines):
342 for i,line in enumerate(lines):
343 show_arrow = (start + 1 + i == lineno)
343 show_arrow = (start + 1 + i == lineno)
344 linetpl = (frame is self.curframe or show_arrow) \
344 linetpl = (frame is self.curframe or show_arrow) \
345 and tpl_line_em \
345 and tpl_line_em \
346 or tpl_line
346 or tpl_line
347 ret.append(self.__format_line(linetpl, filename,
347 ret.append(self.__format_line(linetpl, filename,
348 start + 1 + i, line,
348 start + 1 + i, line,
349 arrow = show_arrow) )
349 arrow = show_arrow) )
350
350
351 return ''.join(ret)
351 return ''.join(ret)
352
352
353 def __format_line(self, tpl_line, filename, lineno, line, arrow = False):
353 def __format_line(self, tpl_line, filename, lineno, line, arrow = False):
354 bp_mark = ""
354 bp_mark = ""
355 bp_mark_color = ""
355 bp_mark_color = ""
356
356
357 scheme = self.color_scheme_table.active_scheme_name
357 scheme = self.color_scheme_table.active_scheme_name
358 new_line, err = self.parser.format2(line, 'str', scheme)
358 new_line, err = self.parser.format2(line, 'str', scheme)
359 if not err: line = new_line
359 if not err: line = new_line
360
360
361 bp = None
361 bp = None
362 if lineno in self.get_file_breaks(filename):
362 if lineno in self.get_file_breaks(filename):
363 bps = self.get_breaks(filename, lineno)
363 bps = self.get_breaks(filename, lineno)
364 bp = bps[-1]
364 bp = bps[-1]
365
365
366 if bp:
366 if bp:
367 Colors = self.color_scheme_table.active_colors
367 Colors = self.color_scheme_table.active_colors
368 bp_mark = str(bp.number)
368 bp_mark = str(bp.number)
369 bp_mark_color = Colors.breakpoint_enabled
369 bp_mark_color = Colors.breakpoint_enabled
370 if not bp.enabled:
370 if not bp.enabled:
371 bp_mark_color = Colors.breakpoint_disabled
371 bp_mark_color = Colors.breakpoint_disabled
372
372
373 numbers_width = 7
373 numbers_width = 7
374 if arrow:
374 if arrow:
375 # This is the line with the error
375 # This is the line with the error
376 pad = numbers_width - len(str(lineno)) - len(bp_mark)
376 pad = numbers_width - len(str(lineno)) - len(bp_mark)
377 if pad >= 3:
377 if pad >= 3:
378 marker = '-'*(pad-3) + '-> '
378 marker = '-'*(pad-3) + '-> '
379 elif pad == 2:
379 elif pad == 2:
380 marker = '> '
380 marker = '> '
381 elif pad == 1:
381 elif pad == 1:
382 marker = '>'
382 marker = '>'
383 else:
383 else:
384 marker = ''
384 marker = ''
385 num = '%s%s' % (marker, str(lineno))
385 num = '%s%s' % (marker, str(lineno))
386 line = tpl_line % (bp_mark_color + bp_mark, num, line)
386 line = tpl_line % (bp_mark_color + bp_mark, num, line)
387 else:
387 else:
388 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
388 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
389 line = tpl_line % (bp_mark_color + bp_mark, num, line)
389 line = tpl_line % (bp_mark_color + bp_mark, num, line)
390
390
391 return line
391 return line
392
392
393 def list_command_pydb(self, arg):
393 def list_command_pydb(self, arg):
394 """List command to use if we have a newer pydb installed"""
394 """List command to use if we have a newer pydb installed"""
395 filename, first, last = OldPdb.parse_list_cmd(self, arg)
395 filename, first, last = OldPdb.parse_list_cmd(self, arg)
396 if filename is not None:
396 if filename is not None:
397 self.print_list_lines(filename, first, last)
397 self.print_list_lines(filename, first, last)
398
398
399 def print_list_lines(self, filename, first, last):
399 def print_list_lines(self, filename, first, last):
400 """The printing (as opposed to the parsing part of a 'list'
400 """The printing (as opposed to the parsing part of a 'list'
401 command."""
401 command."""
402 try:
402 try:
403 Colors = self.color_scheme_table.active_colors
403 Colors = self.color_scheme_table.active_colors
404 ColorsNormal = Colors.Normal
404 ColorsNormal = Colors.Normal
405 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
405 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
406 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
406 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
407 src = []
407 src = []
408 for lineno in range(first, last+1):
408 for lineno in range(first, last+1):
409 line = linecache.getline(filename, lineno)
409 line = linecache.getline(filename, lineno)
410 if not line:
410 if not line:
411 break
411 break
412
412
413 if lineno == self.curframe.f_lineno:
413 if lineno == self.curframe.f_lineno:
414 line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True)
414 line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True)
415 else:
415 else:
416 line = self.__format_line(tpl_line, filename, lineno, line, arrow = False)
416 line = self.__format_line(tpl_line, filename, lineno, line, arrow = False)
417
417
418 src.append(line)
418 src.append(line)
419 self.lineno = lineno
419 self.lineno = lineno
420
420
421 print >>io.stdout, ''.join(src)
421 print >>io.stdout, ''.join(src)
422
422
423 except KeyboardInterrupt:
423 except KeyboardInterrupt:
424 pass
424 pass
425
425
426 def do_list(self, arg):
426 def do_list(self, arg):
427 self.lastcmd = 'list'
427 self.lastcmd = 'list'
428 last = None
428 last = None
429 if arg:
429 if arg:
430 try:
430 try:
431 x = eval(arg, {}, {})
431 x = eval(arg, {}, {})
432 if type(x) == type(()):
432 if type(x) == type(()):
433 first, last = x
433 first, last = x
434 first = int(first)
434 first = int(first)
435 last = int(last)
435 last = int(last)
436 if last < first:
436 if last < first:
437 # Assume it's a count
437 # Assume it's a count
438 last = first + last
438 last = first + last
439 else:
439 else:
440 first = max(1, int(x) - 5)
440 first = max(1, int(x) - 5)
441 except:
441 except:
442 print '*** Error in argument:', `arg`
442 print '*** Error in argument:', `arg`
443 return
443 return
444 elif self.lineno is None:
444 elif self.lineno is None:
445 first = max(1, self.curframe.f_lineno - 5)
445 first = max(1, self.curframe.f_lineno - 5)
446 else:
446 else:
447 first = self.lineno + 1
447 first = self.lineno + 1
448 if last is None:
448 if last is None:
449 last = first + 10
449 last = first + 10
450 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
450 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
451
451
452 # vds: >>
452 # vds: >>
453 lineno = first
453 lineno = first
454 filename = self.curframe.f_code.co_filename
454 filename = self.curframe.f_code.co_filename
455 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
455 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
456 # vds: <<
456 # vds: <<
457
457
458 do_l = do_list
458 do_l = do_list
459
459
460 def do_pdef(self, arg):
460 def do_pdef(self, arg):
461 """The debugger interface to magic_pdef"""
461 """The debugger interface to magic_pdef"""
462 namespaces = [('Locals', self.curframe.f_locals),
462 namespaces = [('Locals', self.curframe.f_locals),
463 ('Globals', self.curframe.f_globals)]
463 ('Globals', self.curframe.f_globals)]
464 self.shell.magic_pdef(arg, namespaces=namespaces)
464 self.shell.magic_pdef(arg, namespaces=namespaces)
465
465
466 def do_pdoc(self, arg):
466 def do_pdoc(self, arg):
467 """The debugger interface to magic_pdoc"""
467 """The debugger interface to magic_pdoc"""
468 namespaces = [('Locals', self.curframe.f_locals),
468 namespaces = [('Locals', self.curframe.f_locals),
469 ('Globals', self.curframe.f_globals)]
469 ('Globals', self.curframe.f_globals)]
470 self.shell.magic_pdoc(arg, namespaces=namespaces)
470 self.shell.magic_pdoc(arg, namespaces=namespaces)
471
471
472 def do_pinfo(self, arg):
472 def do_pinfo(self, arg):
473 """The debugger equivalant of ?obj"""
473 """The debugger equivalant of ?obj"""
474 namespaces = [('Locals', self.curframe.f_locals),
474 namespaces = [('Locals', self.curframe.f_locals),
475 ('Globals', self.curframe.f_globals)]
475 ('Globals', self.curframe.f_globals)]
476 self.shell.magic_pinfo("pinfo %s" % arg, namespaces=namespaces)
476 self.shell.magic_pinfo("pinfo %s" % arg, namespaces=namespaces)
477
477
478 def checkline(self, filename, lineno):
478 def checkline(self, filename, lineno):
479 """Check whether specified line seems to be executable.
479 """Check whether specified line seems to be executable.
480
480
481 Return `lineno` if it is, 0 if not (e.g. a docstring, comment, blank
481 Return `lineno` if it is, 0 if not (e.g. a docstring, comment, blank
482 line or EOF). Warning: testing is not comprehensive.
482 line or EOF). Warning: testing is not comprehensive.
483 """
483 """
484 #######################################################################
484 #######################################################################
485 # XXX Hack! Use python-2.5 compatible code for this call, because with
485 # XXX Hack! Use python-2.5 compatible code for this call, because with
486 # all of our changes, we've drifted from the pdb api in 2.6. For now,
486 # all of our changes, we've drifted from the pdb api in 2.6. For now,
487 # changing:
487 # changing:
488 #
488 #
489 #line = linecache.getline(filename, lineno, self.curframe.f_globals)
489 #line = linecache.getline(filename, lineno, self.curframe.f_globals)
490 # to:
490 # to:
491 #
491 #
492 line = linecache.getline(filename, lineno)
492 line = linecache.getline(filename, lineno)
493 #
493 #
494 # does the trick. But in reality, we need to fix this by reconciling
494 # does the trick. But in reality, we need to fix this by reconciling
495 # our updates with the new Pdb APIs in Python 2.6.
495 # our updates with the new Pdb APIs in Python 2.6.
496 #
496 #
497 # End hack. The rest of this method is copied verbatim from 2.6 pdb.py
497 # End hack. The rest of this method is copied verbatim from 2.6 pdb.py
498 #######################################################################
498 #######################################################################
499
499
500 if not line:
500 if not line:
501 print >>self.stdout, 'End of file'
501 print >>self.stdout, 'End of file'
502 return 0
502 return 0
503 line = line.strip()
503 line = line.strip()
504 # Don't allow setting breakpoint at a blank line
504 # Don't allow setting breakpoint at a blank line
505 if (not line or (line[0] == '#') or
505 if (not line or (line[0] == '#') or
506 (line[:3] == '"""') or line[:3] == "'''"):
506 (line[:3] == '"""') or line[:3] == "'''"):
507 print >>self.stdout, '*** Blank or comment'
507 print >>self.stdout, '*** Blank or comment'
508 return 0
508 return 0
509 return lineno
509 return lineno
@@ -1,256 +1,264 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 A mixin for :class:`~IPython.core.application.Application` classes that
3 A mixin for :class:`~IPython.core.application.Application` classes that
4 launch InteractiveShell instances, load extensions, etc.
4 launch InteractiveShell instances, load extensions, etc.
5
5
6 Authors
6 Authors
7 -------
7 -------
8
8
9 * Min Ragan-Kelley
9 * Min Ragan-Kelley
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2011 The IPython Development Team
13 # Copyright (C) 2008-2011 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 from __future__ import absolute_import
23 from __future__ import absolute_import
24
24
25 import os
25 import os
26 import sys
26 import sys
27
27
28 from IPython.config.application import boolean_flag
28 from IPython.config.application import boolean_flag
29 from IPython.config.configurable import Configurable
29 from IPython.config.configurable import Configurable
30 from IPython.config.loader import Config
30 from IPython.config.loader import Config
31 from IPython.utils.path import filefind
31 from IPython.utils.path import filefind
32 from IPython.utils.traitlets import Unicode, Instance, List, Bool
32 from IPython.utils.traitlets import Unicode, Instance, List, Bool
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Aliases and Flags
35 # Aliases and Flags
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38 shell_flags = {}
38 shell_flags = {}
39
39
40 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
40 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
41 addflag('autoindent', 'InteractiveShell.autoindent',
41 addflag('autoindent', 'InteractiveShell.autoindent',
42 'Turn on autoindenting.', 'Turn off autoindenting.'
42 'Turn on autoindenting.', 'Turn off autoindenting.'
43 )
43 )
44 addflag('automagic', 'InteractiveShell.automagic',
44 addflag('automagic', 'InteractiveShell.automagic',
45 """Turn on the auto calling of magic commands. Type %%magic at the
45 """Turn on the auto calling of magic commands. Type %%magic at the
46 IPython prompt for more information.""",
46 IPython prompt for more information.""",
47 'Turn off the auto calling of magic commands.'
47 'Turn off the auto calling of magic commands.'
48 )
48 )
49 addflag('pdb', 'InteractiveShell.pdb',
49 addflag('pdb', 'InteractiveShell.pdb',
50 "Enable auto calling the pdb debugger after every exception.",
50 "Enable auto calling the pdb debugger after every exception.",
51 "Disable auto calling the pdb debugger after every exception."
51 "Disable auto calling the pdb debugger after every exception."
52 )
52 )
53 # pydb flag doesn't do any config, as core.debugger switches on import,
54 # which is before parsing. This just allows the flag to be passed.
55 shell_flags.update(dict(
56 pydb = ({},
57 """"Use the third party 'pydb' package as debugger, instead of pdb.
58 Requires that pydb is installed."""
59 )
60 ))
53 addflag('pprint', 'PlainTextFormatter.pprint',
61 addflag('pprint', 'PlainTextFormatter.pprint',
54 "Enable auto pretty printing of results.",
62 "Enable auto pretty printing of results.",
55 "Disable auto auto pretty printing of results."
63 "Disable auto auto pretty printing of results."
56 )
64 )
57 addflag('color-info', 'InteractiveShell.color_info',
65 addflag('color-info', 'InteractiveShell.color_info',
58 """IPython can display information about objects via a set of func-
66 """IPython can display information about objects via a set of func-
59 tions, and optionally can use colors for this, syntax highlighting
67 tions, and optionally can use colors for this, syntax highlighting
60 source code and various other elements. However, because this
68 source code and various other elements. However, because this
61 information is passed through a pager (like 'less') and many pagers get
69 information is passed through a pager (like 'less') and many pagers get
62 confused with color codes, this option is off by default. You can test
70 confused with color codes, this option is off by default. You can test
63 it and turn it on permanently in your ipython_config.py file if it
71 it and turn it on permanently in your ipython_config.py file if it
64 works for you. Test it and turn it on permanently if it works with
72 works for you. Test it and turn it on permanently if it works with
65 your system. The magic function %%color_info allows you to toggle this
73 your system. The magic function %%color_info allows you to toggle this
66 interactively for testing.""",
74 interactively for testing.""",
67 "Disable using colors for info related things."
75 "Disable using colors for info related things."
68 )
76 )
69 addflag('deep-reload', 'InteractiveShell.deep_reload',
77 addflag('deep-reload', 'InteractiveShell.deep_reload',
70 """Enable deep (recursive) reloading by default. IPython can use the
78 """Enable deep (recursive) reloading by default. IPython can use the
71 deep_reload module which reloads changes in modules recursively (it
79 deep_reload module which reloads changes in modules recursively (it
72 replaces the reload() function, so you don't need to change anything to
80 replaces the reload() function, so you don't need to change anything to
73 use it). deep_reload() forces a full reload of modules whose code may
81 use it). deep_reload() forces a full reload of modules whose code may
74 have changed, which the default reload() function does not. When
82 have changed, which the default reload() function does not. When
75 deep_reload is off, IPython will use the normal reload(), but
83 deep_reload is off, IPython will use the normal reload(), but
76 deep_reload will still be available as dreload(). This feature is off
84 deep_reload will still be available as dreload(). This feature is off
77 by default [which means that you have both normal reload() and
85 by default [which means that you have both normal reload() and
78 dreload()].""",
86 dreload()].""",
79 "Disable deep (recursive) reloading by default."
87 "Disable deep (recursive) reloading by default."
80 )
88 )
81 nosep_config = Config()
89 nosep_config = Config()
82 nosep_config.InteractiveShell.separate_in = ''
90 nosep_config.InteractiveShell.separate_in = ''
83 nosep_config.InteractiveShell.separate_out = ''
91 nosep_config.InteractiveShell.separate_out = ''
84 nosep_config.InteractiveShell.separate_out2 = ''
92 nosep_config.InteractiveShell.separate_out2 = ''
85
93
86 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
94 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
87
95
88
96
89 # it's possible we don't want short aliases for *all* of these:
97 # it's possible we don't want short aliases for *all* of these:
90 shell_aliases = dict(
98 shell_aliases = dict(
91 autocall='InteractiveShell.autocall',
99 autocall='InteractiveShell.autocall',
92 colors='InteractiveShell.colors',
100 colors='InteractiveShell.colors',
93 logfile='InteractiveShell.logfile',
101 logfile='InteractiveShell.logfile',
94 logappend='InteractiveShell.logappend',
102 logappend='InteractiveShell.logappend',
95 c='InteractiveShellApp.code_to_run',
103 c='InteractiveShellApp.code_to_run',
96 ext='InteractiveShellApp.extra_extension',
104 ext='InteractiveShellApp.extra_extension',
97 )
105 )
98 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
106 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
99
107
100 #-----------------------------------------------------------------------------
108 #-----------------------------------------------------------------------------
101 # Main classes and functions
109 # Main classes and functions
102 #-----------------------------------------------------------------------------
110 #-----------------------------------------------------------------------------
103
111
104 class InteractiveShellApp(Configurable):
112 class InteractiveShellApp(Configurable):
105 """A Mixin for applications that start InteractiveShell instances.
113 """A Mixin for applications that start InteractiveShell instances.
106
114
107 Provides configurables for loading extensions and executing files
115 Provides configurables for loading extensions and executing files
108 as part of configuring a Shell environment.
116 as part of configuring a Shell environment.
109
117
110 Provides init_extensions() and init_code() methods, to be called
118 Provides init_extensions() and init_code() methods, to be called
111 after init_shell(), which must be implemented by subclasses.
119 after init_shell(), which must be implemented by subclasses.
112 """
120 """
113 extensions = List(Unicode, config=True,
121 extensions = List(Unicode, config=True,
114 help="A list of dotted module names of IPython extensions to load."
122 help="A list of dotted module names of IPython extensions to load."
115 )
123 )
116 extra_extension = Unicode('', config=True,
124 extra_extension = Unicode('', config=True,
117 help="dotted module name of an IPython extension to load."
125 help="dotted module name of an IPython extension to load."
118 )
126 )
119 def _extra_extension_changed(self, name, old, new):
127 def _extra_extension_changed(self, name, old, new):
120 if new:
128 if new:
121 # add to self.extensions
129 # add to self.extensions
122 self.extensions.append(new)
130 self.extensions.append(new)
123
131
124 exec_files = List(Unicode, config=True,
132 exec_files = List(Unicode, config=True,
125 help="""List of files to run at IPython startup."""
133 help="""List of files to run at IPython startup."""
126 )
134 )
127 file_to_run = Unicode('', config=True,
135 file_to_run = Unicode('', config=True,
128 help="""A file to be run""")
136 help="""A file to be run""")
129
137
130 exec_lines = List(Unicode, config=True,
138 exec_lines = List(Unicode, config=True,
131 help="""lines of code to run at IPython startup."""
139 help="""lines of code to run at IPython startup."""
132 )
140 )
133 code_to_run = Unicode('', config=True,
141 code_to_run = Unicode('', config=True,
134 help="Execute the given command string."
142 help="Execute the given command string."
135 )
143 )
136 pylab_import_all = Bool(True, config=True,
144 pylab_import_all = Bool(True, config=True,
137 help="""If true, an 'import *' is done from numpy and pylab,
145 help="""If true, an 'import *' is done from numpy and pylab,
138 when using pylab"""
146 when using pylab"""
139 )
147 )
140 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
148 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
141
149
142 def init_shell(self):
150 def init_shell(self):
143 raise NotImplementedError("Override in subclasses")
151 raise NotImplementedError("Override in subclasses")
144
152
145 def init_extensions(self):
153 def init_extensions(self):
146 """Load all IPython extensions in IPythonApp.extensions.
154 """Load all IPython extensions in IPythonApp.extensions.
147
155
148 This uses the :meth:`ExtensionManager.load_extensions` to load all
156 This uses the :meth:`ExtensionManager.load_extensions` to load all
149 the extensions listed in ``self.extensions``.
157 the extensions listed in ``self.extensions``.
150 """
158 """
151 if not self.extensions:
159 if not self.extensions:
152 return
160 return
153 try:
161 try:
154 self.log.debug("Loading IPython extensions...")
162 self.log.debug("Loading IPython extensions...")
155 extensions = self.extensions
163 extensions = self.extensions
156 for ext in extensions:
164 for ext in extensions:
157 try:
165 try:
158 self.log.info("Loading IPython extension: %s" % ext)
166 self.log.info("Loading IPython extension: %s" % ext)
159 self.shell.extension_manager.load_extension(ext)
167 self.shell.extension_manager.load_extension(ext)
160 except:
168 except:
161 self.log.warn("Error in loading extension: %s" % ext)
169 self.log.warn("Error in loading extension: %s" % ext)
162 self.shell.showtraceback()
170 self.shell.showtraceback()
163 except:
171 except:
164 self.log.warn("Unknown error in loading extensions:")
172 self.log.warn("Unknown error in loading extensions:")
165 self.shell.showtraceback()
173 self.shell.showtraceback()
166
174
167 def init_code(self):
175 def init_code(self):
168 """run the pre-flight code, specified via exec_lines"""
176 """run the pre-flight code, specified via exec_lines"""
169 self._run_exec_lines()
177 self._run_exec_lines()
170 self._run_exec_files()
178 self._run_exec_files()
171 self._run_cmd_line_code()
179 self._run_cmd_line_code()
172
180
173 def _run_exec_lines(self):
181 def _run_exec_lines(self):
174 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
182 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
175 if not self.exec_lines:
183 if not self.exec_lines:
176 return
184 return
177 try:
185 try:
178 self.log.debug("Running code from IPythonApp.exec_lines...")
186 self.log.debug("Running code from IPythonApp.exec_lines...")
179 for line in self.exec_lines:
187 for line in self.exec_lines:
180 try:
188 try:
181 self.log.info("Running code in user namespace: %s" %
189 self.log.info("Running code in user namespace: %s" %
182 line)
190 line)
183 self.shell.run_cell(line, store_history=False)
191 self.shell.run_cell(line, store_history=False)
184 except:
192 except:
185 self.log.warn("Error in executing line in user "
193 self.log.warn("Error in executing line in user "
186 "namespace: %s" % line)
194 "namespace: %s" % line)
187 self.shell.showtraceback()
195 self.shell.showtraceback()
188 except:
196 except:
189 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
197 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
190 self.shell.showtraceback()
198 self.shell.showtraceback()
191
199
192 def _exec_file(self, fname):
200 def _exec_file(self, fname):
193 try:
201 try:
194 full_filename = filefind(fname, [u'.', self.ipython_dir])
202 full_filename = filefind(fname, [u'.', self.ipython_dir])
195 except IOError as e:
203 except IOError as e:
196 self.log.warn("File not found: %r"%fname)
204 self.log.warn("File not found: %r"%fname)
197 return
205 return
198 # Make sure that the running script gets a proper sys.argv as if it
206 # Make sure that the running script gets a proper sys.argv as if it
199 # were run from a system shell.
207 # were run from a system shell.
200 save_argv = sys.argv
208 save_argv = sys.argv
201 sys.argv = [full_filename] + self.extra_args[1:]
209 sys.argv = [full_filename] + self.extra_args[1:]
202 try:
210 try:
203 if os.path.isfile(full_filename):
211 if os.path.isfile(full_filename):
204 if full_filename.endswith('.ipy'):
212 if full_filename.endswith('.ipy'):
205 self.log.info("Running file in user namespace: %s" %
213 self.log.info("Running file in user namespace: %s" %
206 full_filename)
214 full_filename)
207 self.shell.safe_execfile_ipy(full_filename)
215 self.shell.safe_execfile_ipy(full_filename)
208 else:
216 else:
209 # default to python, even without extension
217 # default to python, even without extension
210 self.log.info("Running file in user namespace: %s" %
218 self.log.info("Running file in user namespace: %s" %
211 full_filename)
219 full_filename)
212 # Ensure that __file__ is always defined to match Python behavior
220 # Ensure that __file__ is always defined to match Python behavior
213 self.shell.user_ns['__file__'] = fname
221 self.shell.user_ns['__file__'] = fname
214 try:
222 try:
215 self.shell.safe_execfile(full_filename, self.shell.user_ns)
223 self.shell.safe_execfile(full_filename, self.shell.user_ns)
216 finally:
224 finally:
217 del self.shell.user_ns['__file__']
225 del self.shell.user_ns['__file__']
218 finally:
226 finally:
219 sys.argv = save_argv
227 sys.argv = save_argv
220
228
221 def _run_exec_files(self):
229 def _run_exec_files(self):
222 """Run files from IPythonApp.exec_files"""
230 """Run files from IPythonApp.exec_files"""
223 if not self.exec_files:
231 if not self.exec_files:
224 return
232 return
225
233
226 self.log.debug("Running files in IPythonApp.exec_files...")
234 self.log.debug("Running files in IPythonApp.exec_files...")
227 try:
235 try:
228 for fname in self.exec_files:
236 for fname in self.exec_files:
229 self._exec_file(fname)
237 self._exec_file(fname)
230 except:
238 except:
231 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
239 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
232 self.shell.showtraceback()
240 self.shell.showtraceback()
233
241
234 def _run_cmd_line_code(self):
242 def _run_cmd_line_code(self):
235 """Run code or file specified at the command-line"""
243 """Run code or file specified at the command-line"""
236 if self.code_to_run:
244 if self.code_to_run:
237 line = self.code_to_run
245 line = self.code_to_run
238 try:
246 try:
239 self.log.info("Running code given at command line (c=): %s" %
247 self.log.info("Running code given at command line (c=): %s" %
240 line)
248 line)
241 self.shell.run_cell(line, store_history=False)
249 self.shell.run_cell(line, store_history=False)
242 except:
250 except:
243 self.log.warn("Error in executing line in user namespace: %s" %
251 self.log.warn("Error in executing line in user namespace: %s" %
244 line)
252 line)
245 self.shell.showtraceback()
253 self.shell.showtraceback()
246
254
247 # Like Python itself, ignore the second if the first of these is present
255 # Like Python itself, ignore the second if the first of these is present
248 elif self.file_to_run:
256 elif self.file_to_run:
249 fname = self.file_to_run
257 fname = self.file_to_run
250 try:
258 try:
251 self._exec_file(fname)
259 self._exec_file(fname)
252 except:
260 except:
253 self.log.warn("Error in executing file in user namespace: %s" %
261 self.log.warn("Error in executing file in user namespace: %s" %
254 fname)
262 fname)
255 self.shell.showtraceback()
263 self.shell.showtraceback()
256
264
General Comments 0
You need to be logged in to leave comments. Login now