]> git.lizzy.rs Git - plan9front.git/blob - sys/lib/python/pdb.py
add hg and python
[plan9front.git] / sys / lib / python / pdb.py
1 #! /usr/bin/env python
2
3 """A Python debugger."""
4
5 # (See pdb.doc for documentation.)
6
7 import sys
8 import linecache
9 import cmd
10 import bdb
11 from repr import Repr
12 import os
13 import re
14 import pprint
15 import traceback
16 # Create a custom safe Repr instance and increase its maxstring.
17 # The default of 30 truncates error messages too easily.
18 _repr = Repr()
19 _repr.maxstring = 200
20 _saferepr = _repr.repr
21
22 __all__ = ["run", "pm", "Pdb", "runeval", "runctx", "runcall", "set_trace",
23            "post_mortem", "help"]
24
25 def find_function(funcname, filename):
26     cre = re.compile(r'def\s+%s\s*[(]' % funcname)
27     try:
28         fp = open(filename)
29     except IOError:
30         return None
31     # consumer of this info expects the first line to be 1
32     lineno = 1
33     answer = None
34     while 1:
35         line = fp.readline()
36         if line == '':
37             break
38         if cre.match(line):
39             answer = funcname, filename, lineno
40             break
41         lineno = lineno + 1
42     fp.close()
43     return answer
44
45
46 # Interaction prompt line will separate file and call info from code
47 # text using value of line_prefix string.  A newline and arrow may
48 # be to your liking.  You can set it once pdb is imported using the
49 # command "pdb.line_prefix = '\n% '".
50 # line_prefix = ': '    # Use this to get the old situation back
51 line_prefix = '\n-> '   # Probably a better default
52
53 class Pdb(bdb.Bdb, cmd.Cmd):
54
55     def __init__(self, completekey='tab', stdin=None, stdout=None):
56         bdb.Bdb.__init__(self)
57         cmd.Cmd.__init__(self, completekey, stdin, stdout)
58         if stdout:
59             self.use_rawinput = 0
60         self.prompt = '(Pdb) '
61         self.aliases = {}
62         self.mainpyfile = ''
63         self._wait_for_mainpyfile = 0
64         # Try to load readline if it exists
65         try:
66             import readline
67         except ImportError:
68             pass
69
70         # Read $HOME/.pdbrc and ./.pdbrc
71         self.rcLines = []
72         if 'HOME' in os.environ:
73             envHome = os.environ['HOME']
74             try:
75                 rcFile = open(os.path.join(envHome, ".pdbrc"))
76             except IOError:
77                 pass
78             else:
79                 for line in rcFile.readlines():
80                     self.rcLines.append(line)
81                 rcFile.close()
82         try:
83             rcFile = open(".pdbrc")
84         except IOError:
85             pass
86         else:
87             for line in rcFile.readlines():
88                 self.rcLines.append(line)
89             rcFile.close()
90
91         self.commands = {} # associates a command list to breakpoint numbers
92         self.commands_doprompt = {} # for each bp num, tells if the prompt must be disp. after execing the cmd list
93         self.commands_silent = {} # for each bp num, tells if the stack trace must be disp. after execing the cmd list
94         self.commands_defining = False # True while in the process of defining a command list
95         self.commands_bnum = None # The breakpoint number for which we are defining a list
96
97     def reset(self):
98         bdb.Bdb.reset(self)
99         self.forget()
100
101     def forget(self):
102         self.lineno = None
103         self.stack = []
104         self.curindex = 0
105         self.curframe = None
106
107     def setup(self, f, t):
108         self.forget()
109         self.stack, self.curindex = self.get_stack(f, t)
110         self.curframe = self.stack[self.curindex][0]
111         self.execRcLines()
112
113     # Can be executed earlier than 'setup' if desired
114     def execRcLines(self):
115         if self.rcLines:
116             # Make local copy because of recursion
117             rcLines = self.rcLines
118             # executed only once
119             self.rcLines = []
120             for line in rcLines:
121                 line = line[:-1]
122                 if len(line) > 0 and line[0] != '#':
123                     self.onecmd(line)
124
125     # Override Bdb methods
126
127     def user_call(self, frame, argument_list):
128         """This method is called when there is the remote possibility
129         that we ever need to stop in this function."""
130         if self._wait_for_mainpyfile:
131             return
132         if self.stop_here(frame):
133             print >>self.stdout, '--Call--'
134             self.interaction(frame, None)
135
136     def user_line(self, frame):
137         """This function is called when we stop or break at this line."""
138         if self._wait_for_mainpyfile:
139             if (self.mainpyfile != self.canonic(frame.f_code.co_filename)
140                 or frame.f_lineno<= 0):
141                 return
142             self._wait_for_mainpyfile = 0
143         if self.bp_commands(frame):
144             self.interaction(frame, None)
145
146     def bp_commands(self,frame):
147         """ Call every command that was set for the current active breakpoint (if there is one)
148         Returns True if the normal interaction function must be called, False otherwise """
149         #self.currentbp is set in bdb.py in bdb.break_here if a breakpoint was hit
150         if getattr(self,"currentbp",False) and self.currentbp in self.commands:
151             currentbp = self.currentbp
152             self.currentbp = 0
153             lastcmd_back = self.lastcmd
154             self.setup(frame, None)
155             for line in self.commands[currentbp]:
156                 self.onecmd(line)
157             self.lastcmd = lastcmd_back
158             if not self.commands_silent[currentbp]:
159                 self.print_stack_entry(self.stack[self.curindex])
160             if self.commands_doprompt[currentbp]:
161                 self.cmdloop()
162             self.forget()
163             return
164         return 1
165
166     def user_return(self, frame, return_value):
167         """This function is called when a return trap is set here."""
168         frame.f_locals['__return__'] = return_value
169         print >>self.stdout, '--Return--'
170         self.interaction(frame, None)
171
172     def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
173         """This function is called if an exception occurs,
174         but only if we are to stop at or just below this level."""
175         frame.f_locals['__exception__'] = exc_type, exc_value
176         if type(exc_type) == type(''):
177             exc_type_name = exc_type
178         else: exc_type_name = exc_type.__name__
179         print >>self.stdout, exc_type_name + ':', _saferepr(exc_value)
180         self.interaction(frame, exc_traceback)
181
182     # General interaction function
183
184     def interaction(self, frame, traceback):
185         self.setup(frame, traceback)
186         self.print_stack_entry(self.stack[self.curindex])
187         self.cmdloop()
188         self.forget()
189
190     def default(self, line):
191         if line[:1] == '!': line = line[1:]
192         locals = self.curframe.f_locals
193         globals = self.curframe.f_globals
194         try:
195             code = compile(line + '\n', '<stdin>', 'single')
196             exec code in globals, locals
197         except:
198             t, v = sys.exc_info()[:2]
199             if type(t) == type(''):
200                 exc_type_name = t
201             else: exc_type_name = t.__name__
202             print >>self.stdout, '***', exc_type_name + ':', v
203
204     def precmd(self, line):
205         """Handle alias expansion and ';;' separator."""
206         if not line.strip():
207             return line
208         args = line.split()
209         while args[0] in self.aliases:
210             line = self.aliases[args[0]]
211             ii = 1
212             for tmpArg in args[1:]:
213                 line = line.replace("%" + str(ii),
214                                       tmpArg)
215                 ii = ii + 1
216             line = line.replace("%*", ' '.join(args[1:]))
217             args = line.split()
218         # split into ';;' separated commands
219         # unless it's an alias command
220         if args[0] != 'alias':
221             marker = line.find(';;')
222             if marker >= 0:
223                 # queue up everything after marker
224                 next = line[marker+2:].lstrip()
225                 self.cmdqueue.append(next)
226                 line = line[:marker].rstrip()
227         return line
228
229     def onecmd(self, line):
230         """Interpret the argument as though it had been typed in response
231         to the prompt.
232
233         Checks whether this line is typed at the normal prompt or in
234         a breakpoint command list definition.
235         """
236         if not self.commands_defining:
237             return cmd.Cmd.onecmd(self, line)
238         else:
239             return self.handle_command_def(line)
240
241     def handle_command_def(self,line):
242         """ Handles one command line during command list definition. """
243         cmd, arg, line = self.parseline(line)
244         if cmd == 'silent':
245             self.commands_silent[self.commands_bnum] = True
246             return # continue to handle other cmd def in the cmd list
247         elif cmd == 'end':
248             self.cmdqueue = []
249             return 1 # end of cmd list
250         cmdlist = self.commands[self.commands_bnum]
251         if (arg):
252             cmdlist.append(cmd+' '+arg)
253         else:
254             cmdlist.append(cmd)
255         # Determine if we must stop
256         try:
257             func = getattr(self, 'do_' + cmd)
258         except AttributeError:
259             func = self.default
260         if func.func_name in self.commands_resuming : # one of the resuming commands.
261             self.commands_doprompt[self.commands_bnum] = False
262             self.cmdqueue = []
263             return 1
264         return
265
266     # Command definitions, called by cmdloop()
267     # The argument is the remaining string on the command line
268     # Return true to exit from the command loop
269
270     do_h = cmd.Cmd.do_help
271
272     def do_commands(self, arg):
273         """Defines a list of commands associated to a breakpoint
274         Those commands will be executed whenever the breakpoint causes the program to stop execution."""
275         if not arg:
276             bnum = len(bdb.Breakpoint.bpbynumber)-1
277         else:
278             try:
279                 bnum = int(arg)
280             except:
281                 print >>self.stdout, "Usage : commands [bnum]\n        ...\n        end"
282                 return
283         self.commands_bnum = bnum
284         self.commands[bnum] = []
285         self.commands_doprompt[bnum] = True
286         self.commands_silent[bnum] = False
287         prompt_back = self.prompt
288         self.prompt = '(com) '
289         self.commands_defining = True
290         self.cmdloop()
291         self.commands_defining = False
292         self.prompt = prompt_back
293
294     def do_break(self, arg, temporary = 0):
295         # break [ ([filename:]lineno | function) [, "condition"] ]
296         if not arg:
297             if self.breaks:  # There's at least one
298                 print >>self.stdout, "Num Type         Disp Enb   Where"
299                 for bp in bdb.Breakpoint.bpbynumber:
300                     if bp:
301                         bp.bpprint(self.stdout)
302             return
303         # parse arguments; comma has lowest precedence
304         # and cannot occur in filename
305         filename = None
306         lineno = None
307         cond = None
308         comma = arg.find(',')
309         if comma > 0:
310             # parse stuff after comma: "condition"
311             cond = arg[comma+1:].lstrip()
312             arg = arg[:comma].rstrip()
313         # parse stuff before comma: [filename:]lineno | function
314         colon = arg.rfind(':')
315         funcname = None
316         if colon >= 0:
317             filename = arg[:colon].rstrip()
318             f = self.lookupmodule(filename)
319             if not f:
320                 print >>self.stdout, '*** ', repr(filename),
321                 print >>self.stdout, 'not found from sys.path'
322                 return
323             else:
324                 filename = f
325             arg = arg[colon+1:].lstrip()
326             try:
327                 lineno = int(arg)
328             except ValueError, msg:
329                 print >>self.stdout, '*** Bad lineno:', arg
330                 return
331         else:
332             # no colon; can be lineno or function
333             try:
334                 lineno = int(arg)
335             except ValueError:
336                 try:
337                     func = eval(arg,
338                                 self.curframe.f_globals,
339                                 self.curframe.f_locals)
340                 except:
341                     func = arg
342                 try:
343                     if hasattr(func, 'im_func'):
344                         func = func.im_func
345                     code = func.func_code
346                     #use co_name to identify the bkpt (function names
347                     #could be aliased, but co_name is invariant)
348                     funcname = code.co_name
349                     lineno = code.co_firstlineno
350                     filename = code.co_filename
351                 except:
352                     # last thing to try
353                     (ok, filename, ln) = self.lineinfo(arg)
354                     if not ok:
355                         print >>self.stdout, '*** The specified object',
356                         print >>self.stdout, repr(arg),
357                         print >>self.stdout, 'is not a function'
358                         print >>self.stdout, 'or was not found along sys.path.'
359                         return
360                     funcname = ok # ok contains a function name
361                     lineno = int(ln)
362         if not filename:
363             filename = self.defaultFile()
364         # Check for reasonable breakpoint
365         line = self.checkline(filename, lineno)
366         if line:
367             # now set the break point
368             err = self.set_break(filename, line, temporary, cond, funcname)
369             if err: print >>self.stdout, '***', err
370             else:
371                 bp = self.get_breaks(filename, line)[-1]
372                 print >>self.stdout, "Breakpoint %d at %s:%d" % (bp.number,
373                                                                  bp.file,
374                                                                  bp.line)
375
376     # To be overridden in derived debuggers
377     def defaultFile(self):
378         """Produce a reasonable default."""
379         filename = self.curframe.f_code.co_filename
380         if filename == '<string>' and self.mainpyfile:
381             filename = self.mainpyfile
382         return filename
383
384     do_b = do_break
385
386     def do_tbreak(self, arg):
387         self.do_break(arg, 1)
388
389     def lineinfo(self, identifier):
390         failed = (None, None, None)
391         # Input is identifier, may be in single quotes
392         idstring = identifier.split("'")
393         if len(idstring) == 1:
394             # not in single quotes
395             id = idstring[0].strip()
396         elif len(idstring) == 3:
397             # quoted
398             id = idstring[1].strip()
399         else:
400             return failed
401         if id == '': return failed
402         parts = id.split('.')
403         # Protection for derived debuggers
404         if parts[0] == 'self':
405             del parts[0]
406             if len(parts) == 0:
407                 return failed
408         # Best first guess at file to look at
409         fname = self.defaultFile()
410         if len(parts) == 1:
411             item = parts[0]
412         else:
413             # More than one part.
414             # First is module, second is method/class
415             f = self.lookupmodule(parts[0])
416             if f:
417                 fname = f
418             item = parts[1]
419         answer = find_function(item, fname)
420         return answer or failed
421
422     def checkline(self, filename, lineno):
423         """Check whether specified line seems to be executable.
424
425         Return `lineno` if it is, 0 if not (e.g. a docstring, comment, blank
426         line or EOF). Warning: testing is not comprehensive.
427         """
428         line = linecache.getline(filename, lineno)
429         if not line:
430             print >>self.stdout, 'End of file'
431             return 0
432         line = line.strip()
433         # Don't allow setting breakpoint at a blank line
434         if (not line or (line[0] == '#') or
435              (line[:3] == '"""') or line[:3] == "'''"):
436             print >>self.stdout, '*** Blank or comment'
437             return 0
438         return lineno
439
440     def do_enable(self, arg):
441         args = arg.split()
442         for i in args:
443             try:
444                 i = int(i)
445             except ValueError:
446                 print >>self.stdout, 'Breakpoint index %r is not a number' % i
447                 continue
448
449             if not (0 <= i < len(bdb.Breakpoint.bpbynumber)):
450                 print >>self.stdout, 'No breakpoint numbered', i
451                 continue
452
453             bp = bdb.Breakpoint.bpbynumber[i]
454             if bp:
455                 bp.enable()
456
457     def do_disable(self, arg):
458         args = arg.split()
459         for i in args:
460             try:
461                 i = int(i)
462             except ValueError:
463                 print >>self.stdout, 'Breakpoint index %r is not a number' % i
464                 continue
465
466             if not (0 <= i < len(bdb.Breakpoint.bpbynumber)):
467                 print >>self.stdout, 'No breakpoint numbered', i
468                 continue
469
470             bp = bdb.Breakpoint.bpbynumber[i]
471             if bp:
472                 bp.disable()
473
474     def do_condition(self, arg):
475         # arg is breakpoint number and condition
476         args = arg.split(' ', 1)
477         try:
478             bpnum = int(args[0].strip())
479         except ValueError:
480             # something went wrong
481             print >>self.stdout, \
482                 'Breakpoint index %r is not a number' % args[0]
483             return
484         try:
485             cond = args[1]
486         except:
487             cond = None
488         try:
489             bp = bdb.Breakpoint.bpbynumber[bpnum]
490         except IndexError:
491             print >>self.stdout, 'Breakpoint index %r is not valid' % args[0]
492             return
493         if bp:
494             bp.cond = cond
495             if not cond:
496                 print >>self.stdout, 'Breakpoint', bpnum,
497                 print >>self.stdout, 'is now unconditional.'
498
499     def do_ignore(self,arg):
500         """arg is bp number followed by ignore count."""
501         args = arg.split()
502         try:
503             bpnum = int(args[0].strip())
504         except ValueError:
505             # something went wrong
506             print >>self.stdout, \
507                 'Breakpoint index %r is not a number' % args[0]
508             return
509         try:
510             count = int(args[1].strip())
511         except:
512             count = 0
513         try:
514             bp = bdb.Breakpoint.bpbynumber[bpnum]
515         except IndexError:
516             print >>self.stdout, 'Breakpoint index %r is not valid' % args[0]
517             return
518         if bp:
519             bp.ignore = count
520             if count > 0:
521                 reply = 'Will ignore next '
522                 if count > 1:
523                     reply = reply + '%d crossings' % count
524                 else:
525                     reply = reply + '1 crossing'
526                 print >>self.stdout, reply + ' of breakpoint %d.' % bpnum
527             else:
528                 print >>self.stdout, 'Will stop next time breakpoint',
529                 print >>self.stdout, bpnum, 'is reached.'
530
531     def do_clear(self, arg):
532         """Three possibilities, tried in this order:
533         clear -> clear all breaks, ask for confirmation
534         clear file:lineno -> clear all breaks at file:lineno
535         clear bpno bpno ... -> clear breakpoints by number"""
536         if not arg:
537             try:
538                 reply = raw_input('Clear all breaks? ')
539             except EOFError:
540                 reply = 'no'
541             reply = reply.strip().lower()
542             if reply in ('y', 'yes'):
543                 self.clear_all_breaks()
544             return
545         if ':' in arg:
546             # Make sure it works for "clear C:\foo\bar.py:12"
547             i = arg.rfind(':')
548             filename = arg[:i]
549             arg = arg[i+1:]
550             try:
551                 lineno = int(arg)
552             except ValueError:
553                 err = "Invalid line number (%s)" % arg
554             else:
555                 err = self.clear_break(filename, lineno)
556             if err: print >>self.stdout, '***', err
557             return
558         numberlist = arg.split()
559         for i in numberlist:
560             try:
561                 i = int(i)
562             except ValueError:
563                 print >>self.stdout, 'Breakpoint index %r is not a number' % i
564                 continue
565
566             if not (0 <= i < len(bdb.Breakpoint.bpbynumber)):
567                 print >>self.stdout, 'No breakpoint numbered', i
568                 continue
569             err = self.clear_bpbynumber(i)
570             if err:
571                 print >>self.stdout, '***', err
572             else:
573                 print >>self.stdout, 'Deleted breakpoint', i
574     do_cl = do_clear # 'c' is already an abbreviation for 'continue'
575
576     def do_where(self, arg):
577         self.print_stack_trace()
578     do_w = do_where
579     do_bt = do_where
580
581     def do_up(self, arg):
582         if self.curindex == 0:
583             print >>self.stdout, '*** Oldest frame'
584         else:
585             self.curindex = self.curindex - 1
586             self.curframe = self.stack[self.curindex][0]
587             self.print_stack_entry(self.stack[self.curindex])
588             self.lineno = None
589     do_u = do_up
590
591     def do_down(self, arg):
592         if self.curindex + 1 == len(self.stack):
593             print >>self.stdout, '*** Newest frame'
594         else:
595             self.curindex = self.curindex + 1
596             self.curframe = self.stack[self.curindex][0]
597             self.print_stack_entry(self.stack[self.curindex])
598             self.lineno = None
599     do_d = do_down
600
601     def do_step(self, arg):
602         self.set_step()
603         return 1
604     do_s = do_step
605
606     def do_next(self, arg):
607         self.set_next(self.curframe)
608         return 1
609     do_n = do_next
610
611     def do_return(self, arg):
612         self.set_return(self.curframe)
613         return 1
614     do_r = do_return
615
616     def do_continue(self, arg):
617         self.set_continue()
618         return 1
619     do_c = do_cont = do_continue
620
621     def do_jump(self, arg):
622         if self.curindex + 1 != len(self.stack):
623             print >>self.stdout, "*** You can only jump within the bottom frame"
624             return
625         try:
626             arg = int(arg)
627         except ValueError:
628             print >>self.stdout, "*** The 'jump' command requires a line number."
629         else:
630             try:
631                 # Do the jump, fix up our copy of the stack, and display the
632                 # new position
633                 self.curframe.f_lineno = arg
634                 self.stack[self.curindex] = self.stack[self.curindex][0], arg
635                 self.print_stack_entry(self.stack[self.curindex])
636             except ValueError, e:
637                 print >>self.stdout, '*** Jump failed:', e
638     do_j = do_jump
639
640     def do_debug(self, arg):
641         sys.settrace(None)
642         globals = self.curframe.f_globals
643         locals = self.curframe.f_locals
644         p = Pdb()
645         p.prompt = "(%s) " % self.prompt.strip()
646         print >>self.stdout, "ENTERING RECURSIVE DEBUGGER"
647         sys.call_tracing(p.run, (arg, globals, locals))
648         print >>self.stdout, "LEAVING RECURSIVE DEBUGGER"
649         sys.settrace(self.trace_dispatch)
650         self.lastcmd = p.lastcmd
651
652     def do_quit(self, arg):
653         self._user_requested_quit = 1
654         self.set_quit()
655         return 1
656
657     do_q = do_quit
658     do_exit = do_quit
659
660     def do_EOF(self, arg):
661         print >>self.stdout
662         self._user_requested_quit = 1
663         self.set_quit()
664         return 1
665
666     def do_args(self, arg):
667         f = self.curframe
668         co = f.f_code
669         dict = f.f_locals
670         n = co.co_argcount
671         if co.co_flags & 4: n = n+1
672         if co.co_flags & 8: n = n+1
673         for i in range(n):
674             name = co.co_varnames[i]
675             print >>self.stdout, name, '=',
676             if name in dict: print >>self.stdout, dict[name]
677             else: print >>self.stdout, "*** undefined ***"
678     do_a = do_args
679
680     def do_retval(self, arg):
681         if '__return__' in self.curframe.f_locals:
682             print >>self.stdout, self.curframe.f_locals['__return__']
683         else:
684             print >>self.stdout, '*** Not yet returned!'
685     do_rv = do_retval
686
687     def _getval(self, arg):
688         try:
689             return eval(arg, self.curframe.f_globals,
690                         self.curframe.f_locals)
691         except:
692             t, v = sys.exc_info()[:2]
693             if isinstance(t, str):
694                 exc_type_name = t
695             else: exc_type_name = t.__name__
696             print >>self.stdout, '***', exc_type_name + ':', repr(v)
697             raise
698
699     def do_p(self, arg):
700         try:
701             print >>self.stdout, repr(self._getval(arg))
702         except:
703             pass
704
705     def do_pp(self, arg):
706         try:
707             pprint.pprint(self._getval(arg), self.stdout)
708         except:
709             pass
710
711     def do_list(self, arg):
712         self.lastcmd = 'list'
713         last = None
714         if arg:
715             try:
716                 x = eval(arg, {}, {})
717                 if type(x) == type(()):
718                     first, last = x
719                     first = int(first)
720                     last = int(last)
721                     if last < first:
722                         # Assume it's a count
723                         last = first + last
724                 else:
725                     first = max(1, int(x) - 5)
726             except:
727                 print >>self.stdout, '*** Error in argument:', repr(arg)
728                 return
729         elif self.lineno is None:
730             first = max(1, self.curframe.f_lineno - 5)
731         else:
732             first = self.lineno + 1
733         if last is None:
734             last = first + 10
735         filename = self.curframe.f_code.co_filename
736         breaklist = self.get_file_breaks(filename)
737         try:
738             for lineno in range(first, last+1):
739                 line = linecache.getline(filename, lineno)
740                 if not line:
741                     print >>self.stdout, '[EOF]'
742                     break
743                 else:
744                     s = repr(lineno).rjust(3)
745                     if len(s) < 4: s = s + ' '
746                     if lineno in breaklist: s = s + 'B'
747                     else: s = s + ' '
748                     if lineno == self.curframe.f_lineno:
749                         s = s + '->'
750                     print >>self.stdout, s + '\t' + line,
751                     self.lineno = lineno
752         except KeyboardInterrupt:
753             pass
754     do_l = do_list
755
756     def do_whatis(self, arg):
757         try:
758             value = eval(arg, self.curframe.f_globals,
759                             self.curframe.f_locals)
760         except:
761             t, v = sys.exc_info()[:2]
762             if type(t) == type(''):
763                 exc_type_name = t
764             else: exc_type_name = t.__name__
765             print >>self.stdout, '***', exc_type_name + ':', repr(v)
766             return
767         code = None
768         # Is it a function?
769         try: code = value.func_code
770         except: pass
771         if code:
772             print >>self.stdout, 'Function', code.co_name
773             return
774         # Is it an instance method?
775         try: code = value.im_func.func_code
776         except: pass
777         if code:
778             print >>self.stdout, 'Method', code.co_name
779             return
780         # None of the above...
781         print >>self.stdout, type(value)
782
783     def do_alias(self, arg):
784         args = arg.split()
785         if len(args) == 0:
786             keys = self.aliases.keys()
787             keys.sort()
788             for alias in keys:
789                 print >>self.stdout, "%s = %s" % (alias, self.aliases[alias])
790             return
791         if args[0] in self.aliases and len(args) == 1:
792             print >>self.stdout, "%s = %s" % (args[0], self.aliases[args[0]])
793         else:
794             self.aliases[args[0]] = ' '.join(args[1:])
795
796     def do_unalias(self, arg):
797         args = arg.split()
798         if len(args) == 0: return
799         if args[0] in self.aliases:
800             del self.aliases[args[0]]
801
802     #list of all the commands making the program resume execution.
803     commands_resuming = ['do_continue', 'do_step', 'do_next', 'do_return',
804                          'do_quit', 'do_jump']
805
806     # Print a traceback starting at the top stack frame.
807     # The most recently entered frame is printed last;
808     # this is different from dbx and gdb, but consistent with
809     # the Python interpreter's stack trace.
810     # It is also consistent with the up/down commands (which are
811     # compatible with dbx and gdb: up moves towards 'main()'
812     # and down moves towards the most recent stack frame).
813
814     def print_stack_trace(self):
815         try:
816             for frame_lineno in self.stack:
817                 self.print_stack_entry(frame_lineno)
818         except KeyboardInterrupt:
819             pass
820
821     def print_stack_entry(self, frame_lineno, prompt_prefix=line_prefix):
822         frame, lineno = frame_lineno
823         if frame is self.curframe:
824             print >>self.stdout, '>',
825         else:
826             print >>self.stdout, ' ',
827         print >>self.stdout, self.format_stack_entry(frame_lineno,
828                                                      prompt_prefix)
829
830
831     # Help methods (derived from pdb.doc)
832
833     def help_help(self):
834         self.help_h()
835
836     def help_h(self):
837         print >>self.stdout, """h(elp)
838 Without argument, print the list of available commands.
839 With a command name as argument, print help about that command
840 "help pdb" pipes the full documentation file to the $PAGER
841 "help exec" gives help on the ! command"""
842
843     def help_where(self):
844         self.help_w()
845
846     def help_w(self):
847         print >>self.stdout, """w(here)
848 Print a stack trace, with the most recent frame at the bottom.
849 An arrow indicates the "current frame", which determines the
850 context of most commands.  'bt' is an alias for this command."""
851
852     help_bt = help_w
853
854     def help_down(self):
855         self.help_d()
856
857     def help_d(self):
858         print >>self.stdout, """d(own)
859 Move the current frame one level down in the stack trace
860 (to a newer frame)."""
861
862     def help_up(self):
863         self.help_u()
864
865     def help_u(self):
866         print >>self.stdout, """u(p)
867 Move the current frame one level up in the stack trace
868 (to an older frame)."""
869
870     def help_break(self):
871         self.help_b()
872
873     def help_b(self):
874         print >>self.stdout, """b(reak) ([file:]lineno | function) [, condition]
875 With a line number argument, set a break there in the current
876 file.  With a function name, set a break at first executable line
877 of that function.  Without argument, list all breaks.  If a second
878 argument is present, it is a string specifying an expression
879 which must evaluate to true before the breakpoint is honored.
880
881 The line number may be prefixed with a filename and a colon,
882 to specify a breakpoint in another file (probably one that
883 hasn't been loaded yet).  The file is searched for on sys.path;
884 the .py suffix may be omitted."""
885
886     def help_clear(self):
887         self.help_cl()
888
889     def help_cl(self):
890         print >>self.stdout, "cl(ear) filename:lineno"
891         print >>self.stdout, """cl(ear) [bpnumber [bpnumber...]]
892 With a space separated list of breakpoint numbers, clear
893 those breakpoints.  Without argument, clear all breaks (but
894 first ask confirmation).  With a filename:lineno argument,
895 clear all breaks at that line in that file.
896
897 Note that the argument is different from previous versions of
898 the debugger (in python distributions 1.5.1 and before) where
899 a linenumber was used instead of either filename:lineno or
900 breakpoint numbers."""
901
902     def help_tbreak(self):
903         print >>self.stdout, """tbreak  same arguments as break, but breakpoint is
904 removed when first hit."""
905
906     def help_enable(self):
907         print >>self.stdout, """enable bpnumber [bpnumber ...]
908 Enables the breakpoints given as a space separated list of
909 bp numbers."""
910
911     def help_disable(self):
912         print >>self.stdout, """disable bpnumber [bpnumber ...]
913 Disables the breakpoints given as a space separated list of
914 bp numbers."""
915
916     def help_ignore(self):
917         print >>self.stdout, """ignore bpnumber count
918 Sets the ignore count for the given breakpoint number.  A breakpoint
919 becomes active when the ignore count is zero.  When non-zero, the
920 count is decremented each time the breakpoint is reached and the
921 breakpoint is not disabled and any associated condition evaluates
922 to true."""
923
924     def help_condition(self):
925         print >>self.stdout, """condition bpnumber str_condition
926 str_condition is a string specifying an expression which
927 must evaluate to true before the breakpoint is honored.
928 If str_condition is absent, any existing condition is removed;
929 i.e., the breakpoint is made unconditional."""
930
931     def help_step(self):
932         self.help_s()
933
934     def help_s(self):
935         print >>self.stdout, """s(tep)
936 Execute the current line, stop at the first possible occasion
937 (either in a function that is called or in the current function)."""
938
939     def help_next(self):
940         self.help_n()
941
942     def help_n(self):
943         print >>self.stdout, """n(ext)
944 Continue execution until the next line in the current function
945 is reached or it returns."""
946
947     def help_return(self):
948         self.help_r()
949
950     def help_r(self):
951         print >>self.stdout, """r(eturn)
952 Continue execution until the current function returns."""
953
954     def help_continue(self):
955         self.help_c()
956
957     def help_cont(self):
958         self.help_c()
959
960     def help_c(self):
961         print >>self.stdout, """c(ont(inue))
962 Continue execution, only stop when a breakpoint is encountered."""
963
964     def help_jump(self):
965         self.help_j()
966
967     def help_j(self):
968         print >>self.stdout, """j(ump) lineno
969 Set the next line that will be executed."""
970
971     def help_debug(self):
972         print >>self.stdout, """debug code
973 Enter a recursive debugger that steps through the code argument
974 (which is an arbitrary expression or statement to be executed
975 in the current environment)."""
976
977     def help_list(self):
978         self.help_l()
979
980     def help_l(self):
981         print >>self.stdout, """l(ist) [first [,last]]
982 List source code for the current file.
983 Without arguments, list 11 lines around the current line
984 or continue the previous listing.
985 With one argument, list 11 lines starting at that line.
986 With two arguments, list the given range;
987 if the second argument is less than the first, it is a count."""
988
989     def help_args(self):
990         self.help_a()
991
992     def help_a(self):
993         print >>self.stdout, """a(rgs)
994 Print the arguments of the current function."""
995
996     def help_p(self):
997         print >>self.stdout, """p expression
998 Print the value of the expression."""
999
1000     def help_pp(self):
1001         print >>self.stdout, """pp expression
1002 Pretty-print the value of the expression."""
1003
1004     def help_exec(self):
1005         print >>self.stdout, """(!) statement
1006 Execute the (one-line) statement in the context of
1007 the current stack frame.
1008 The exclamation point can be omitted unless the first word
1009 of the statement resembles a debugger command.
1010 To assign to a global variable you must always prefix the
1011 command with a 'global' command, e.g.:
1012 (Pdb) global list_options; list_options = ['-l']
1013 (Pdb)"""
1014
1015     def help_quit(self):
1016         self.help_q()
1017
1018     def help_q(self):
1019         print >>self.stdout, """q(uit) or exit - Quit from the debugger.
1020 The program being executed is aborted."""
1021
1022     help_exit = help_q
1023
1024     def help_whatis(self):
1025         print >>self.stdout, """whatis arg
1026 Prints the type of the argument."""
1027
1028     def help_EOF(self):
1029         print >>self.stdout, """EOF
1030 Handles the receipt of EOF as a command."""
1031
1032     def help_alias(self):
1033         print >>self.stdout, """alias [name [command [parameter parameter ...] ]]
1034 Creates an alias called 'name' the executes 'command'.  The command
1035 must *not* be enclosed in quotes.  Replaceable parameters are
1036 indicated by %1, %2, and so on, while %* is replaced by all the
1037 parameters.  If no command is given, the current alias for name
1038 is shown. If no name is given, all aliases are listed.
1039
1040 Aliases may be nested and can contain anything that can be
1041 legally typed at the pdb prompt.  Note!  You *can* override
1042 internal pdb commands with aliases!  Those internal commands
1043 are then hidden until the alias is removed.  Aliasing is recursively
1044 applied to the first word of the command line; all other words
1045 in the line are left alone.
1046
1047 Some useful aliases (especially when placed in the .pdbrc file) are:
1048
1049 #Print instance variables (usage "pi classInst")
1050 alias pi for k in %1.__dict__.keys(): print "%1.",k,"=",%1.__dict__[k]
1051
1052 #Print instance variables in self
1053 alias ps pi self
1054 """
1055
1056     def help_unalias(self):
1057         print >>self.stdout, """unalias name
1058 Deletes the specified alias."""
1059
1060     def help_commands(self):
1061         print >>self.stdout, """commands [bpnumber]
1062 (com) ...
1063 (com) end
1064 (Pdb)
1065
1066 Specify a list of commands for breakpoint number bpnumber.  The
1067 commands themselves appear on the following lines.  Type a line
1068 containing just 'end' to terminate the commands.
1069
1070 To remove all commands from a breakpoint, type commands and
1071 follow it immediately with  end; that is, give no commands.
1072
1073 With no bpnumber argument, commands refers to the last
1074 breakpoint set.
1075
1076 You can use breakpoint commands to start your program up again.
1077 Simply use the continue command, or step, or any other
1078 command that resumes execution.
1079
1080 Specifying any command resuming execution (currently continue,
1081 step, next, return, jump, quit and their abbreviations) terminates
1082 the command list (as if that command was immediately followed by end).
1083 This is because any time you resume execution
1084 (even with a simple next or step), you may encounter
1085 another breakpoint--which could have its own command list, leading to
1086 ambiguities about which list to execute.
1087
1088    If you use the 'silent' command in the command list, the
1089 usual message about stopping at a breakpoint is not printed.  This may
1090 be desirable for breakpoints that are to print a specific message and
1091 then continue.  If none of the other commands print anything, you
1092 see no sign that the breakpoint was reached.
1093 """
1094
1095     def help_pdb(self):
1096         help()
1097
1098     def lookupmodule(self, filename):
1099         """Helper function for break/clear parsing -- may be overridden.
1100
1101         lookupmodule() translates (possibly incomplete) file or module name
1102         into an absolute file name.
1103         """
1104         if os.path.isabs(filename) and  os.path.exists(filename):
1105             return filename
1106         f = os.path.join(sys.path[0], filename)
1107         if  os.path.exists(f) and self.canonic(f) == self.mainpyfile:
1108             return f
1109         root, ext = os.path.splitext(filename)
1110         if ext == '':
1111             filename = filename + '.py'
1112         if os.path.isabs(filename):
1113             return filename
1114         for dirname in sys.path:
1115             while os.path.islink(dirname):
1116                 dirname = os.readlink(dirname)
1117             fullname = os.path.join(dirname, filename)
1118             if os.path.exists(fullname):
1119                 return fullname
1120         return None
1121
1122     def _runscript(self, filename):
1123         # Start with fresh empty copy of globals and locals and tell the script
1124         # that it's being run as __main__ to avoid scripts being able to access
1125         # the pdb.py namespace.
1126         globals_ = {"__name__" : "__main__"}
1127         locals_ = globals_
1128
1129         # When bdb sets tracing, a number of call and line events happens
1130         # BEFORE debugger even reaches user's code (and the exact sequence of
1131         # events depends on python version). So we take special measures to
1132         # avoid stopping before we reach the main script (see user_line and
1133         # user_call for details).
1134         self._wait_for_mainpyfile = 1
1135         self.mainpyfile = self.canonic(filename)
1136         self._user_requested_quit = 0
1137         statement = 'execfile( "%s")' % filename
1138         self.run(statement, globals=globals_, locals=locals_)
1139
1140 # Simplified interface
1141
1142 def run(statement, globals=None, locals=None):
1143     Pdb().run(statement, globals, locals)
1144
1145 def runeval(expression, globals=None, locals=None):
1146     return Pdb().runeval(expression, globals, locals)
1147
1148 def runctx(statement, globals, locals):
1149     # B/W compatibility
1150     run(statement, globals, locals)
1151
1152 def runcall(*args, **kwds):
1153     return Pdb().runcall(*args, **kwds)
1154
1155 def set_trace():
1156     Pdb().set_trace(sys._getframe().f_back)
1157
1158 # Post-Mortem interface
1159
1160 def post_mortem(t):
1161     p = Pdb()
1162     p.reset()
1163     while t.tb_next is not None:
1164         t = t.tb_next
1165     p.interaction(t.tb_frame, t)
1166
1167 def pm():
1168     post_mortem(sys.last_traceback)
1169
1170
1171 # Main program for testing
1172
1173 TESTCMD = 'import x; x.main()'
1174
1175 def test():
1176     run(TESTCMD)
1177
1178 # print help
1179 def help():
1180     for dirname in sys.path:
1181         fullname = os.path.join(dirname, 'pdb.doc')
1182         if os.path.exists(fullname):
1183             sts = os.system('${PAGER-more} '+fullname)
1184             if sts: print '*** Pager exit status:', sts
1185             break
1186     else:
1187         print 'Sorry, can\'t find the help file "pdb.doc"',
1188         print 'along the Python search path'
1189
1190 def main():
1191     if not sys.argv[1:]:
1192         print "usage: pdb.py scriptfile [arg] ..."
1193         sys.exit(2)
1194
1195     mainpyfile =  sys.argv[1]     # Get script filename
1196     if not os.path.exists(mainpyfile):
1197         print 'Error:', mainpyfile, 'does not exist'
1198         sys.exit(1)
1199
1200     del sys.argv[0]         # Hide "pdb.py" from argument list
1201
1202     # Replace pdb's dir with script's dir in front of module search path.
1203     sys.path[0] = os.path.dirname(mainpyfile)
1204
1205     # Note on saving/restoring sys.argv: it's a good idea when sys.argv was
1206     # modified by the script being debugged. It's a bad idea when it was
1207     # changed by the user from the command line. The best approach would be to
1208     # have a "restart" command which would allow explicit specification of
1209     # command line arguments.
1210     pdb = Pdb()
1211     while 1:
1212         try:
1213             pdb._runscript(mainpyfile)
1214             if pdb._user_requested_quit:
1215                 break
1216             print "The program finished and will be restarted"
1217         except SystemExit:
1218             # In most cases SystemExit does not warrant a post-mortem session.
1219             print "The program exited via sys.exit(). Exit status: ",
1220             print sys.exc_info()[1]
1221         except:
1222             traceback.print_exc()
1223             print "Uncaught exception. Entering post mortem debugging"
1224             print "Running 'cont' or 'step' will restart the program"
1225             t = sys.exc_info()[2]
1226             while t.tb_next is not None:
1227                 t = t.tb_next
1228             pdb.interaction(t.tb_frame,t)
1229             print "Post mortem debugger finished. The "+mainpyfile+" will be restarted"
1230
1231
1232 # When invoked as main program, invoke the debugger on a script
1233 if __name__=='__main__':
1234     main()