1 # pdb.py -- finally, a Python debugger!
3 # (See pdb.doc for documentation.)
13 class Pdb(bdb
.Bdb
, cmd
.Cmd
):
16 bdb
.Bdb
.__init
__(self
)
17 cmd
.Cmd
.__init
__(self
)
18 self
.prompt
= '(Pdb) '
30 def setup(self
, f
, t
):
32 self
.stack
, self
.curindex
= self
.get_stack(f
, t
)
33 self
.curframe
= self
.stack
[self
.curindex
][0]
35 # Override Bdb methods (except user_call, for now)
37 def user_line(self
, frame
):
38 # This function is called when we stop or break at this line
39 self
.interaction(frame
, None)
41 def user_return(self
, frame
, return_value
):
42 # This function is called when a return trap is set here
43 frame
.f_locals
['__return__'] = return_value
45 self
.interaction(frame
, None)
47 def user_exception(self
, frame
, (exc_type
, exc_value
, exc_traceback
)):
48 # This function is called if an exception occurs,
49 # but only if we are to stop at or just below this level
50 frame
.f_locals
['__exception__'] = exc_type
, exc_value
51 print exc_type
+ ':', repr.repr(exc_value
)
52 self
.interaction(frame
, exc_traceback
)
54 # General interaction function
56 def interaction(self
, frame
, traceback
):
57 self
.setup(frame
, traceback
)
58 self
.print_stack_entry(self
.stack
[self
.curindex
])
62 def default(self
, line
):
63 if line
[:1] == '!': line
= line
[1:]
64 locals = self
.curframe
.f_locals
65 globals = self
.curframe
.f_globals
66 globals['__privileged__'] = 1
68 exec(line
+ '\n', globals, locals)
70 print '***', sys
.exc_type
+ ':', sys
.exc_value
72 # Command definitions, called by cmdloop()
73 # The argument is the remaining string on the command line
74 # Return true to exit from the command loop
76 do_h
= cmd
.Cmd
.do_help
78 def do_break(self
, arg
):
80 print self
.get_all_breaks() # XXX
83 lineno
= int(eval(arg
))
85 print '*** Error in argument:', `arg`
87 filename
= self
.curframe
.f_code
.co_filename
88 err
= self
.set_break(filename
, lineno
)
89 if err
: print '***', err
92 def do_clear(self
, arg
):
95 reply
= raw_input('Clear all breaks? ')
98 reply
= string
.lower(string
.strip(reply
))
99 if reply
in ('y', 'yes'):
100 self
.clear_all_breaks()
103 lineno
= int(eval(arg
))
105 print '*** Error in argument:', `arg`
107 filename
= self
.curframe
.f_code
.co_filename
108 err
= self
.clear_break(filename
, lineno
)
109 if err
: print '***', err
110 do_cl
= do_clear
# 'c' is already an abbreviation for 'continue'
112 def do_where(self
, arg
):
113 self
.print_stack_trace()
116 def do_up(self
, arg
):
117 if self
.curindex
== 0:
118 print '*** Oldest frame'
120 self
.curindex
= self
.curindex
- 1
121 self
.curframe
= self
.stack
[self
.curindex
][0]
122 self
.print_stack_entry(self
.stack
[self
.curindex
])
126 def do_down(self
, arg
):
127 if self
.curindex
+ 1 == len(self
.stack
):
128 print '*** Newest frame'
130 self
.curindex
= self
.curindex
+ 1
131 self
.curframe
= self
.stack
[self
.curindex
][0]
132 self
.print_stack_entry(self
.stack
[self
.curindex
])
136 def do_step(self
, arg
):
141 def do_next(self
, arg
):
142 self
.set_next(self
.curframe
)
146 def do_return(self
, arg
):
147 self
.set_return(self
.curframe
)
151 def do_continue(self
, arg
):
154 do_c
= do_cont
= do_continue
156 def do_quit(self
, arg
):
161 def do_args(self
, arg
):
162 if self
.curframe
.f_locals
.has_key('__return__'):
163 print `self
.curframe
.f_locals
['__return__']`
165 print '*** Not arguments?!'
168 def do_retval(self
, arg
):
169 if self
.curframe
.f_locals
.has_key('__return__'):
170 print self
.curframe
.f_locals
['__return__']
172 print '*** Not yet returned!'
176 self
.curframe
.f_globals
['__privileged__'] = 1
178 value
= eval(arg
, self
.curframe
.f_globals
, \
179 self
.curframe
.f_locals
)
181 print '***', sys
.exc_type
+ ':', `sys
.exc_value`
186 def do_list(self
, arg
):
187 self
.lastcmd
= 'list'
191 x
= eval(arg
, {}, {})
192 if type(x
) == type(()):
197 # Assume it's a count
200 first
= max(1, int(x
) - 5)
202 print '*** Error in argument:', `arg`
204 elif self
.lineno
is None:
205 first
= max(1, self
.curframe
.f_lineno
- 5)
207 first
= self
.lineno
+ 1
210 filename
= self
.curframe
.f_code
.co_filename
211 breaklist
= self
.get_file_breaks(filename
)
213 for lineno
in range(first
, last
+1):
214 line
= linecache
.getline(filename
, lineno
)
219 s
= string
.rjust(`lineno`
, 3)
220 if len(s
) < 4: s
= s
+ ' '
221 if lineno
in breaklist
: s
= s
+ 'B'
223 if lineno
== self
.curframe
.f_lineno
:
225 print s
+ '\t' + line
,
227 except KeyboardInterrupt:
231 def do_whatis(self
, arg
):
234 value
= eval(arg
, self
.curframe
.f_globals
, \
235 self
.curframe
.f_locals
)
237 print '***', sys
.exc_type
+ ':', `sys
.exc_value`
241 try: code
= value
.func_code
244 print 'Function', codehack
.getcodename(code
)
246 # Is it an instance method?
247 try: code
= value
.im_func
.func_code
250 print 'Method', codehack
.getcodename(code
)
252 # None of the above...
255 # Print a traceback starting at the top stack frame.
256 # The most recently entered frame is printed last;
257 # this is different from dbx and gdb, but consistent with
258 # the Python interpreter's stack trace.
259 # It is also consistent with the up/down commands (which are
260 # compatible with dbx and gdb: up moves towards 'main()'
261 # and down moves towards the most recent stack frame).
263 def print_stack_trace(self
):
265 for frame_lineno
in self
.stack
:
266 self
.print_stack_entry(frame_lineno
)
267 except KeyboardInterrupt:
270 def print_stack_entry(self
, frame_lineno
):
271 frame
, lineno
= frame_lineno
272 if frame
is self
.curframe
:
276 print self
.format_stack_entry(frame_lineno
)
279 # Simplified interface
284 def runctx(statement
, globals, locals):
285 Pdb().runctx(statement
, globals, locals)
288 apply(Pdb().runcall
, args
)
291 # Post-Mortem interface
296 while t
.tb_next
<> None: t
= t
.tb_next
297 p
.interaction(t
.tb_frame
, t
)
301 post_mortem(sys
.last_traceback
)
304 # Main program for testing
306 TESTCMD
= 'import x; x.main()'
310 linecache
.checkcache()
316 for dirname
in sys
.path
:
317 fullname
= os
.path
.join(dirname
, 'pdb.doc')
318 if os
.path
.exists(fullname
):
319 sts
= os
.system('${PAGER-more} '+fullname
)
320 if sts
: print '*** Pager exit status:', sts
323 print 'Sorry, can\'t find the help file "pdb.doc"',
324 print 'along the Python search path'