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