Show More
@@ -15,7 +15,7 b' 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 |
$Id: Debugger.py 1 |
|
18 | $Id: Debugger.py 1853 2006-10-30 17:00:39Z vivainio $""" | |
19 |
|
19 | |||
20 | #***************************************************************************** |
|
20 | #***************************************************************************** | |
21 | # |
|
21 | # | |
@@ -40,13 +40,41 b' import bdb' | |||||
40 | import cmd |
|
40 | import cmd | |
41 | import linecache |
|
41 | import linecache | |
42 | import os |
|
42 | import os | |
43 | import pdb |
|
|||
44 | import sys |
|
43 | import sys | |
45 |
|
44 | |||
46 | from IPython import PyColorize, ColorANSI |
|
45 | from IPython import PyColorize, ColorANSI | |
47 | from IPython.genutils import Term |
|
46 | from IPython.genutils import Term | |
48 | from IPython.excolors import ExceptionColors |
|
47 | from IPython.excolors import ExceptionColors | |
49 |
|
48 | |||
|
49 | # See if we can use pydb. | |||
|
50 | has_pydb = False | |||
|
51 | prompt = 'ipdb>' | |||
|
52 | if sys.version[:3] >= '2.5': | |||
|
53 | try: | |||
|
54 | import pydb | |||
|
55 | if hasattr(pydb.pydb, "runl"): | |||
|
56 | has_pydb = True | |||
|
57 | from pydb import Pdb as OldPdb | |||
|
58 | prompt = 'ipydb>' | |||
|
59 | except ImportError: | |||
|
60 | pass | |||
|
61 | ||||
|
62 | if has_pydb: | |||
|
63 | from pydb import Pdb as OldPdb | |||
|
64 | else: | |||
|
65 | from pdb import Pdb as OldPdb | |||
|
66 | ||||
|
67 | def decorate_fn_with_doc(new_fn, old_fn, additional_text=""): | |||
|
68 | """Make new_fn have old_fn's doc string. This is particularly useful | |||
|
69 | for the do_... commands that hook into the help system. | |||
|
70 | Adapted from from a comp.lang.python posting | |||
|
71 | by Duncan Booth.""" | |||
|
72 | def wrapper(*args, **kw): | |||
|
73 | return new_fn(*args, **kw) | |||
|
74 | if old_fn.__doc__: | |||
|
75 | wrapper.__doc__ = old_fn.__doc__ + additional_text | |||
|
76 | return wrapper | |||
|
77 | ||||
50 | def _file_lines(fname): |
|
78 | def _file_lines(fname): | |
51 | """Return the contents of a named file as a list of lines. |
|
79 | """Return the contents of a named file as a list of lines. | |
52 |
|
80 | |||
@@ -62,7 +90,7 b' def _file_lines(fname):' | |||||
62 | outfile.close() |
|
90 | outfile.close() | |
63 | return out |
|
91 | return out | |
64 |
|
92 | |||
65 |
class Pdb( |
|
93 | class Pdb(OldPdb): | |
66 | """Modified Pdb class, does not load readline.""" |
|
94 | """Modified Pdb class, does not load readline.""" | |
67 |
|
95 | |||
68 | if sys.version[:3] >= '2.5': |
|
96 | if sys.version[:3] >= '2.5': | |
@@ -70,10 +98,33 b' class Pdb(pdb.Pdb):' | |||||
70 | stdin=None, stdout=None): |
|
98 | stdin=None, stdout=None): | |
71 |
|
99 | |||
72 | # Parent constructor: |
|
100 | # Parent constructor: | |
73 |
|
|
101 | OldPdb.__init__(self,completekey,stdin,stdout) | |
74 |
|
102 | |||
75 | # IPython changes... |
|
103 | # IPython changes... | |
76 |
self.prompt = |
|
104 | self.prompt = prompt # The default prompt is '(Pdb)' | |
|
105 | self.is_pydb = prompt == 'ipydb>' | |||
|
106 | ||||
|
107 | if self.is_pydb: | |||
|
108 | ||||
|
109 | # iplib.py's ipalias seems to want pdb's checkline | |||
|
110 | # which located in pydb.fn | |||
|
111 | import pydb.fns | |||
|
112 | self.checkline = lambda filename, lineno: \ | |||
|
113 | pydb.fns.checkline(self, filename, lineno) | |||
|
114 | ||||
|
115 | self.curframe = None | |||
|
116 | self.do_restart = self.new_do_restart | |||
|
117 | ||||
|
118 | self.old_all_completions = __IPYTHON__.Completer.all_completions | |||
|
119 | __IPYTHON__.Completer.all_completions=self.all_completions | |||
|
120 | ||||
|
121 | # Do we have access to pydb's list command parser? | |||
|
122 | self.do_list = decorate_fn_with_doc(self.list_command_pydb, | |||
|
123 | OldPdb.do_list) | |||
|
124 | self.do_l = self.do_list | |||
|
125 | self.do_frame = decorate_fn_with_doc(self.new_do_frame, | |||
|
126 | OldPdb.do_frame) | |||
|
127 | ||||
77 | self.aliases = {} |
|
128 | self.aliases = {} | |
78 |
|
129 | |||
79 | # Create color table: we copy the default one from the traceback |
|
130 | # Create color table: we copy the default one from the traceback | |
@@ -143,17 +194,34 b' class Pdb(pdb.Pdb):' | |||||
143 |
|
194 | |||
144 | def interaction(self, frame, traceback): |
|
195 | def interaction(self, frame, traceback): | |
145 | __IPYTHON__.set_completer_frame(frame) |
|
196 | __IPYTHON__.set_completer_frame(frame) | |
146 |
|
|
197 | OldPdb.interaction(self, frame, traceback) | |
|
198 | ||||
|
199 | def new_do_up(self, arg): | |||
|
200 | OldPdb.do_up(self, arg) | |||
|
201 | __IPYTHON__.set_completer_frame(self.curframe) | |||
|
202 | do_u = do_up = decorate_fn_with_doc(new_do_up, OldPdb.do_up) | |||
147 |
|
203 | |||
148 |
def |
|
204 | def new_do_down(self, arg): | |
149 |
|
|
205 | OldPdb.do_down(self, arg) | |
150 | __IPYTHON__.set_completer_frame(self.curframe) |
|
206 | __IPYTHON__.set_completer_frame(self.curframe) | |
151 | do_u = do_up |
|
|||
152 |
|
207 | |||
153 | def do_down(self, arg): |
|
208 | do_d = do_down = decorate_fn_with_doc(new_do_down, OldPdb.do_down) | |
154 | pdb.Pdb.do_down(self, arg) |
|
209 | ||
|
210 | def new_do_frame(self, arg): | |||
|
211 | OldPdb.do_frame(self, arg) | |||
155 | __IPYTHON__.set_completer_frame(self.curframe) |
|
212 | __IPYTHON__.set_completer_frame(self.curframe) | |
156 | do_d = do_down |
|
213 | ||
|
214 | def new_do_quit(self, arg): | |||
|
215 | __IPYTHON__.Completer.all_completions=self.old_all_completions | |||
|
216 | return OldPdb.do_quit(self, arg) | |||
|
217 | ||||
|
218 | do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit) | |||
|
219 | ||||
|
220 | def new_do_restart(self, arg): | |||
|
221 | """Restart command. In the context of ipython this is exactly the same | |||
|
222 | thing as 'quit'.""" | |||
|
223 | self.msg("Restart doesn't make sense here. Using 'quit' instead.") | |||
|
224 | return self.do_quit(arg) | |||
157 |
|
225 | |||
158 | def postloop(self): |
|
226 | def postloop(self): | |
159 | __IPYTHON__.set_completer_frame(None) |
|
227 | __IPYTHON__.set_completer_frame(None) | |
@@ -263,6 +331,39 b' class Pdb(pdb.Pdb):' | |||||
263 |
|
331 | |||
264 | return line |
|
332 | return line | |
265 |
|
333 | |||
|
334 | def list_command_pydb(self, arg): | |||
|
335 | """List command to use if we have a newer pydb installed""" | |||
|
336 | filename, first, last = OldPdb.parse_list_cmd(self, arg) | |||
|
337 | if filename is not None: | |||
|
338 | self.print_list_lines(filename, first, last) | |||
|
339 | ||||
|
340 | def print_list_lines(self, filename, first, last): | |||
|
341 | """The printing (as opposed to the parsing part of a 'list' | |||
|
342 | command.""" | |||
|
343 | try: | |||
|
344 | Colors = self.color_scheme_table.active_colors | |||
|
345 | ColorsNormal = Colors.Normal | |||
|
346 | tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal) | |||
|
347 | tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal) | |||
|
348 | src = [] | |||
|
349 | for lineno in range(first, last+1): | |||
|
350 | line = linecache.getline(filename, lineno) | |||
|
351 | if not line: | |||
|
352 | break | |||
|
353 | ||||
|
354 | if lineno == self.curframe.f_lineno: | |||
|
355 | line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True) | |||
|
356 | else: | |||
|
357 | line = self.__format_line(tpl_line, filename, lineno, line, arrow = False) | |||
|
358 | ||||
|
359 | src.append(line) | |||
|
360 | self.lineno = lineno | |||
|
361 | ||||
|
362 | print >>Term.cout, ''.join(src) | |||
|
363 | ||||
|
364 | except KeyboardInterrupt: | |||
|
365 | pass | |||
|
366 | ||||
266 | def do_list(self, arg): |
|
367 | def do_list(self, arg): | |
267 | self.lastcmd = 'list' |
|
368 | self.lastcmd = 'list' | |
268 | last = None |
|
369 | last = None | |
@@ -287,29 +388,24 b' class Pdb(pdb.Pdb):' | |||||
287 | first = self.lineno + 1 |
|
388 | first = self.lineno + 1 | |
288 | if last is None: |
|
389 | if last is None: | |
289 | last = first + 10 |
|
390 | last = first + 10 | |
290 |
|
|
391 | self.print_list_lines(self.curframe.f_code.co_filename, first, last) | |
291 | try: |
|
|||
292 | Colors = self.color_scheme_table.active_colors |
|
|||
293 | ColorsNormal = Colors.Normal |
|
|||
294 | tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal) |
|
|||
295 | tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal) |
|
|||
296 | src = [] |
|
|||
297 | for lineno in range(first, last+1): |
|
|||
298 | line = linecache.getline(filename, lineno) |
|
|||
299 | if not line: |
|
|||
300 | break |
|
|||
301 |
|
||||
302 | if lineno == self.curframe.f_lineno: |
|
|||
303 | line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True) |
|
|||
304 | else: |
|
|||
305 | line = self.__format_line(tpl_line, filename, lineno, line, arrow = False) |
|
|||
306 |
|
||||
307 | src.append(line) |
|
|||
308 | self.lineno = lineno |
|
|||
309 |
|
||||
310 | print >>Term.cout, ''.join(src) |
|
|||
311 |
|
||||
312 | except KeyboardInterrupt: |
|
|||
313 | pass |
|
|||
314 |
|
392 | |||
315 | do_l = do_list |
|
393 | do_l = do_list | |
|
394 | ||||
|
395 | def do_pdef(self, arg): | |||
|
396 | """The debugger interface to magic_pdef""" | |||
|
397 | namespaces = [('Locals', self.curframe.f_locals), | |||
|
398 | ('Globals', self.curframe.f_globals)] | |||
|
399 | __IPYTHON__.magic_pdef(arg, namespaces=namespaces) | |||
|
400 | ||||
|
401 | def do_pdoc(self, arg): | |||
|
402 | """The debugger interface to magic_pdoc""" | |||
|
403 | namespaces = [('Locals', self.curframe.f_locals), | |||
|
404 | ('Globals', self.curframe.f_globals)] | |||
|
405 | __IPYTHON__.magic_pdoc(arg, namespaces=namespaces) | |||
|
406 | ||||
|
407 | def do_pinfo(self, arg): | |||
|
408 | """The debugger equivalant of ?obj""" | |||
|
409 | namespaces = [('Locals', self.curframe.f_locals), | |||
|
410 | ('Globals', self.curframe.f_globals)] | |||
|
411 | __IPYTHON__.magic_pinfo("pinfo %s" % arg, namespaces=namespaces) |
@@ -6,7 +6,7 b' Requires Python 2.3 or newer.' | |||||
6 |
|
6 | |||
7 | This file contains all the classes and helper functions specific to IPython. |
|
7 | This file contains all the classes and helper functions specific to IPython. | |
8 |
|
8 | |||
9 |
$Id: iplib.py 185 |
|
9 | $Id: iplib.py 1853 2006-10-30 17:00:39Z vivainio $ | |
10 | """ |
|
10 | """ | |
11 |
|
11 | |||
12 | #***************************************************************************** |
|
12 | #***************************************************************************** | |
@@ -47,7 +47,6 b' import inspect' | |||||
47 | import keyword |
|
47 | import keyword | |
48 | import new |
|
48 | import new | |
49 | import os |
|
49 | import os | |
50 | import pdb |
|
|||
51 | import pydoc |
|
50 | import pydoc | |
52 | import re |
|
51 | import re | |
53 | import shutil |
|
52 | import shutil | |
@@ -1361,11 +1360,20 b' want to merge them back into the new files.""" % locals()' | |||||
1361 | self.SyntaxTB(etype,value,[]) |
|
1360 | self.SyntaxTB(etype,value,[]) | |
1362 |
|
1361 | |||
1363 | def debugger(self): |
|
1362 | def debugger(self): | |
1364 | """Call the pdb debugger.""" |
|
1363 | """Call the pydb/pdb debugger.""" | |
1365 |
|
1364 | |||
1366 | if not self.rc.pdb: |
|
1365 | if not self.rc.pdb: | |
1367 | return |
|
1366 | return | |
1368 | pdb.pm() |
|
1367 | have_pydb = False | |
|
1368 | if sys.version[:3] >= '2.5': | |||
|
1369 | try: | |||
|
1370 | from pydb import pm | |||
|
1371 | have_pydb = True | |||
|
1372 | except ImportError: | |||
|
1373 | pass | |||
|
1374 | if not have_pydb: | |||
|
1375 | from pdb import pm | |||
|
1376 | pm() | |||
1369 |
|
1377 | |||
1370 | def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None): |
|
1378 | def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None): | |
1371 | """Display the exception that just occurred. |
|
1379 | """Display the exception that just occurred. |
@@ -1,3 +1,9 b'' | |||||
|
1 | 2006-10-30 Ville Vainio <vivainio@gmail.com> | |||
|
2 | ||||
|
3 | * Debugger.py, iplib.py (debugger()): Add last set of Rocky | |||
|
4 | Bernsteins's patches for pydb integration. | |||
|
5 | http://bashdb.sourceforge.net/pydb/ | |||
|
6 | ||||
1 | 2006-10-28 Fernando Perez <Fernando.Perez@colorado.edu> |
|
7 | 2006-10-28 Fernando Perez <Fernando.Perez@colorado.edu> | |
2 |
|
8 | |||
3 | * IPython/UserConfig/ipythonrc-scipy: minor clenaups to remove old |
|
9 | * IPython/UserConfig/ipythonrc-scipy: minor clenaups to remove old | |
@@ -22,7 +28,7 b'' | |||||
22 | file around %run commands to prevent side effects from |
|
28 | file around %run commands to prevent side effects from | |
23 | %runned programs that might use readline (e.g. pydb). |
|
29 | %runned programs that might use readline (e.g. pydb). | |
24 |
|
30 | |||
25 |
* extensions/pydb |
|
31 | * extensions/ipy_pydb.py: Adds %pydb magic when imported, for | |
26 | invoking the pydb enhanced debugger. |
|
32 | invoking the pydb enhanced debugger. | |
27 |
|
33 | |||
28 | 2006-10-23 Walter Doerwald <walter@livinglogic.de> |
|
34 | 2006-10-23 Walter Doerwald <walter@livinglogic.de> |
General Comments 0
You need to be logged in to leave comments.
Login now