pdb.py 24.3 KB
Newer Older
1
#! /usr/bin/env python
2

3
"""A Python debugger."""
4

5
# (See pdb.doc for documentation.)
Guido van Rossum's avatar
Guido van Rossum committed
6 7 8 9

import string
import sys
import linecache
10 11 12
import cmd
import bdb
import repr
13
import os
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
import re

def find_function(funcname, filename):
	cre = re.compile(r'def\s+%s\s*[(]' % funcname)
	try:
		fp = open(filename)
	except IOError:
		return None
	# consumer of this info expects the first line to be 1
	lineno = 1
	answer = None
	while 1:
		line = fp.readline()
		if line == '':
			break
		if cre.match(line):
			answer = funcname, filename, lineno
			break
		lineno = lineno + 1
	fp.close()
	return answer
Guido van Rossum's avatar
Guido van Rossum committed
35 36


37 38 39 40 41 42 43
# Interaction prompt line will separate file and call info from code
# text using value of line_prefix string.  A newline and arrow may
# be to your liking.  You can set it once pdb is imported using the
# command "pdb.line_prefix = '\n% '".
# line_prefix = ': '	# Use this to get the old situation back
line_prefix = '\n-> '	# Probably a better default

44
class Pdb(bdb.Bdb, cmd.Cmd):
Guido van Rossum's avatar
Guido van Rossum committed
45
	
46 47 48
	def __init__(self):
		bdb.Bdb.__init__(self)
		cmd.Cmd.__init__(self)
Guido van Rossum's avatar
Guido van Rossum committed
49
		self.prompt = '(Pdb) '
50
		self.aliases = {}
51 52 53 54 55
		# Try to load readline if it exists
		try:
			import readline
		except ImportError:
			pass
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76

		# Read $HOME/.pdbrc and ./.pdbrc
		self.rcLines = []
		if os.environ.has_key('HOME'):
			envHome = os.environ['HOME']
			try:
				rcFile = open (envHome + "/.pdbrc")
			except IOError:
				pass
			else:
				for line in rcFile.readlines():
					self.rcLines.append (line)
				rcFile.close()
		try:
			rcFile = open ("./.pdbrc")
		except IOError:
			pass
		else:
			for line in rcFile.readlines():
				self.rcLines.append (line)
			rcFile.close()
Guido van Rossum's avatar
Guido van Rossum committed
77 78
	
	def reset(self):
79
		bdb.Bdb.reset(self)
Guido van Rossum's avatar
Guido van Rossum committed
80 81 82 83
		self.forget()
	
	def forget(self):
		self.lineno = None
84
		self.stack = []
85 86
		self.curindex = 0
		self.curframe = None
87
	
88 89 90 91
	def setup(self, f, t):
		self.forget()
		self.stack, self.curindex = self.get_stack(f, t)
		self.curframe = self.stack[self.curindex][0]
92
		self.execRcLines()
93 94 95 96 97 98 99 100 101 102 103 104

	# Can be executed earlier than 'setup' if desired
	def execRcLines(self):
		if self.rcLines:
			# Make local copy because of recursion
			rcLines = self.rcLines
			# executed only once
			self.rcLines = []
			for line in rcLines:
				line = line[:-1]
				if len (line) > 0 and line[0] != '#':
					self.onecmd (line)
105
	
106
	# Override Bdb methods (except user_call, for now)
107
	
108
	def user_line(self, frame):
109
		"""This function is called when we stop or break at this line."""
110
		self.interaction(frame, None)
Guido van Rossum's avatar
Guido van Rossum committed
111
	
112
	def user_return(self, frame, return_value):
113
		"""This function is called when a return trap is set here."""
114 115 116
		frame.f_locals['__return__'] = return_value
		print '--Return--'
		self.interaction(frame, None)
117
	
118
	def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
119 120
		"""This function is called if an exception occurs,
		but only if we are to stop at or just below this level."""
121
		frame.f_locals['__exception__'] = exc_type, exc_value
122 123 124 125
		if type(exc_type) == type(''):
			exc_type_name = exc_type
		else: exc_type_name = exc_type.__name__
		print exc_type_name + ':', repr.repr(exc_value)
126
		self.interaction(frame, exc_traceback)
127
	
128
	# General interaction function
129
	
130
	def interaction(self, frame, traceback):
131
		self.setup(frame, traceback)
132
		self.print_stack_entry(self.stack[self.curindex])
133
		self.cmdloop()
134
		self.forget()
135

Guido van Rossum's avatar
Guido van Rossum committed
136
	def default(self, line):
137 138 139 140
		if line[:1] == '!': line = line[1:]
		locals = self.curframe.f_locals
		globals = self.curframe.f_globals
		try:
141
			code = compile(line + '\n', '<stdin>', 'single')
142
			exec code in globals, locals
143
		except:
144 145 146 147 148
			t, v = sys.exc_info()[:2]
			if type(t) == type(''):
				exc_type_name = t
			else: exc_type_name = t.__name__
			print '***', exc_type_name + ':', v
149

150
	def precmd(self, line):
151
		"""Handle alias expansion and ';;' separator."""
152 153 154 155 156 157 158 159 160 161
		if not line:
			return line
		args = string.split(line)
		while self.aliases.has_key(args[0]):
			line = self.aliases[args[0]]
			ii = 1
			for tmpArg in args[1:]:
				line = string.replace(line, "%" + str(ii),
						      tmpArg)
				ii = ii + 1
162 163
			line = string.replace(line, "%*",
					      string.join(args[1:], ' '))
164
			args = string.split(line)
165
		# split into ';;' separated commands
166 167
		# unless it's an alias command
		if args[0] != 'alias':
168 169 170 171
			marker = string.find(line, ';;')
			if marker >= 0:
				# queue up everything after marker
				next = string.lstrip(line[marker+2:])
172
				self.cmdqueue.append(next)
173
				line = string.rstrip(line[:marker])
174 175
		return line

176 177 178
	# Command definitions, called by cmdloop()
	# The argument is the remaining string on the command line
	# Return true to exit from the command loop 
Guido van Rossum's avatar
Guido van Rossum committed
179
	
180
	do_h = cmd.Cmd.do_help
181

182 183 184 185
	def do_EOF(self, arg):
		return 0	# Don't die on EOF

	def do_break(self, arg, temporary = 0):
186
		# break [ ([filename:]lineno | function) [, "condition"] ]
Guido van Rossum's avatar
Guido van Rossum committed
187
		if not arg:
188 189 190 191 192
			if self.breaks:  # There's at least one
				print "Num Type         Disp Enb   Where"
				for bp in bdb.Breakpoint.bpbynumber:
					if bp:
						bp.bpprint()
Guido van Rossum's avatar
Guido van Rossum committed
193
			return
194 195 196 197 198 199 200 201 202 203 204 205 206 207
		# parse arguments; comma has lowest precendence
		# and cannot occur in filename
		filename = None
		lineno = None
		cond = None
		comma = string.find(arg, ',')
		if comma > 0:
			# parse stuff after comma: "condition"
			cond = string.lstrip(arg[comma+1:])
			arg = string.rstrip(arg[:comma])
		# parse stuff before comma: [filename:]lineno | function
		colon = string.rfind(arg, ':')
		if colon >= 0:
			filename = string.rstrip(arg[:colon])
208 209 210 211 212 213 214
			f = self.lookupmodule(filename)
			if not f:
				print '*** ', `filename`,
				print 'not found from sys.path'
				return
			else:
				filename = f
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
			arg = string.lstrip(arg[colon+1:])
			try:
				lineno = int(arg)
			except ValueError, msg:
				print '*** Bad lineno:', arg
				return
		else:
			# no colon; can be lineno or function
			try:
				lineno = int(arg)
			except ValueError:
				try:
					func = eval(arg,
						    self.curframe.f_globals,
						    self.curframe.f_locals)
				except:
231
					func = arg
232 233 234 235
				try:
					if hasattr(func, 'im_func'):
						func = func.im_func
					code = func.func_code
236
					lineno = code.co_firstlineno
237
					filename = code.co_filename
238 239 240 241 242 243 244 245 246 247 248
				except:
					# last thing to try
					(ok, filename, ln) = self.lineinfo(arg)
					if not ok:
					    print '*** The specified object',
					    print `arg`,
					    print 'is not a function'
					    print ('or was not found '
						   'along sys.path.')
					    return
					lineno = int(ln)
249
		if not filename:
250 251 252 253 254 255 256
			filename = self.defaultFile()
		# Check for reasonable breakpoint
		line = self.checkline(filename, lineno)
		if line:
			# now set the break point
			err = self.set_break(filename, line, temporary, cond)
			if err: print '***', err
257 258 259 260 261
			else:
				bp = self.get_breaks(filename, line)[-1]
				print "Breakpoint %d at %s:%d" % (bp.number,
								  bp.file,
								  bp.line)
262 263 264

	# To be overridden in derived debuggers
	def defaultFile(self):
265
		"""Produce a reasonable default."""
266 267 268 269
		filename = self.curframe.f_code.co_filename
		if filename == '<string>' and mainpyfile:
			filename = mainpyfile
		return filename
270

Guido van Rossum's avatar
Guido van Rossum committed
271 272
	do_b = do_break
	
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
	def do_tbreak(self, arg):
		self.do_break(arg, 1)

	def lineinfo(self, identifier):
		failed = (None, None, None)
		# Input is identifier, may be in single quotes
		idstring = string.split(identifier, "'")
		if len(idstring) == 1:
			# not in single quotes
			id = string.strip(idstring[0])
		elif len(idstring) == 3:
			# quoted
			id = string.strip(idstring[1])
		else:
			return failed
		if id == '': return failed
		parts = string.split(id, '.')
		# Protection for derived debuggers
		if parts[0] == 'self':
			del parts[0]
			if len(parts) == 0:
				return failed
		# Best first guess at file to look at
		fname = self.defaultFile()
		if len(parts) == 1:
			item = parts[0]
		else:
			# More than one part.
			# First is module, second is method/class
			f = self.lookupmodule(parts[0])
			if f:
				fname = f
			item = parts[1]
306 307
		answer = find_function(item, fname)
		return answer or failed
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
		
	def checkline(self, filename, lineno):
		"""Return line number of first line at or after input
		argument such that if the input points to a 'def', the
		returned line number is the first
		non-blank/non-comment line to follow.  If the input
		points to a blank or comment line, return 0.  At end
		of file, also return 0."""

		line = linecache.getline(filename, lineno)
		if not line:
			print 'End of file'
			return 0
		line = string.strip(line)
		# Don't allow setting breakpoint at a blank line
		if ( not line or (line[0] == '#') or
		     (line[:3] == '"""') or line[:3] == "'''" ):
			print '*** Blank or comment'
			return 0
		# When a file is read in and a breakpoint is at
		# the 'def' statement, the system stops there at
		# code parse time.  We don't want that, so all breakpoints
		# set at 'def' statements are moved one line onward
		if line[:3] == 'def':
Guido van Rossum's avatar
Guido van Rossum committed
332 333
			instr = ''
			brackets = 0
334
			while 1:
Guido van Rossum's avatar
Guido van Rossum committed
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
				skipone = 0
				for c in line:
					if instr:
						if skipone:
							skipone = 0
						elif c == '\\':
							skipone = 1
						elif c == instr:
							instr = ''
					elif c == '#':
						break
					elif c in ('"',"'"):
						instr = c
					elif c in ('(','{','['):
						brackets = brackets + 1
					elif c in (')','}',']'):
						brackets = brackets - 1
352 353 354 355 356 357 358
				lineno = lineno+1
				line = linecache.getline(filename, lineno)
				if not line:
					print 'end of file'
					return 0
				line = string.strip(line)
				if not line: continue	# Blank line
Guido van Rossum's avatar
Guido van Rossum committed
359 360
				if brackets <= 0 and line[0] not in ('#','"',"'"):
					break
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
		return lineno

	def do_enable(self, arg):
		args = string.split(arg)
		for i in args:
			bp = bdb.Breakpoint.bpbynumber[int(i)]
			if bp:
				bp.enable()

	def do_disable(self, arg):
		args = string.split(arg)
		for i in args:
			bp = bdb.Breakpoint.bpbynumber[int(i)]
			if bp:
				bp.disable()

	def do_condition(self, arg):
		# arg is breakpoint number and condition
		args = string.split(arg, ' ', 1)
		bpnum = int(string.strip(args[0]))
		try:
			cond = args[1]
		except:
			cond = None
		bp = bdb.Breakpoint.bpbynumber[bpnum]
		if bp:
			bp.cond = cond
			if not cond:
				print 'Breakpoint', bpnum,
				print 'is now unconditional.'

	def do_ignore(self,arg):
393
		"""arg is bp number followed by ignore count."""
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413
		args = string.split(arg)
		bpnum = int(string.strip(args[0]))
		try:
			count = int(string.strip(args[1]))
		except:
			count = 0
		bp = bdb.Breakpoint.bpbynumber[bpnum]
		if bp:
			bp.ignore = count
			if (count > 0):
				reply = 'Will ignore next '
				if (count > 1):
					reply = reply + '%d crossings' % count
				else:
					reply = reply + '1 crossing'
				print reply + ' of breakpoint %d.' % bpnum
			else:
				print 'Will stop next time breakpoint',
				print bpnum, 'is reached.'

Guido van Rossum's avatar
Guido van Rossum committed
414
	def do_clear(self, arg):
415 416 417 418
		"""Three possibilities, tried in this order:
		clear -> clear all breaks, ask for confirmation
		clear file:lineno -> clear all breaks at file:lineno
		clear bpno bpno ... -> clear breakpoints by number"""
Guido van Rossum's avatar
Guido van Rossum committed
419
		if not arg:
420 421 422 423 424 425
			try:
				reply = raw_input('Clear all breaks? ')
			except EOFError:
				reply = 'no'
			reply = string.lower(string.strip(reply))
			if reply in ('y', 'yes'):
426
				self.clear_all_breaks()
Guido van Rossum's avatar
Guido van Rossum committed
427
			return
428 429 430 431 432 433 434 435 436 437 438 439 440
		if ':' in arg:
			# Make sure it works for "clear C:\foo\bar.py:12"
			i = string.rfind(arg, ':')
			filename = arg[:i]
			arg = arg[i+1:]
			try:
				lineno = int(arg)
			except:
				err = "Invalid line number (%s)" % arg
			else:
				err = self.clear_break(filename, lineno)
			if err: print '***', err
			return
441 442
		numberlist = string.split(arg)
		for i in numberlist:
443
			err = self.clear_bpbynumber(i)
444
			if err:
445
				print '***', err
446 447
			else:
				print 'Deleted breakpoint %s ' % (i,)
448
	do_cl = do_clear # 'c' is already an abbreviation for 'continue'
Guido van Rossum's avatar
Guido van Rossum committed
449 450
	
	def do_where(self, arg):
451
		self.print_stack_trace()
Guido van Rossum's avatar
Guido van Rossum committed
452 453 454
	do_w = do_where
	
	def do_up(self, arg):
455 456
		if self.curindex == 0:
			print '*** Oldest frame'
Guido van Rossum's avatar
Guido van Rossum committed
457
		else:
458 459
			self.curindex = self.curindex - 1
			self.curframe = self.stack[self.curindex][0]
460
			self.print_stack_entry(self.stack[self.curindex])
461
			self.lineno = None
Guido van Rossum's avatar
Guido van Rossum committed
462 463 464
	do_u = do_up
	
	def do_down(self, arg):
465 466
		if self.curindex + 1 == len(self.stack):
			print '*** Newest frame'
Guido van Rossum's avatar
Guido van Rossum committed
467
		else:
468 469
			self.curindex = self.curindex + 1
			self.curframe = self.stack[self.curindex][0]
470
			self.print_stack_entry(self.stack[self.curindex])
471
			self.lineno = None
Guido van Rossum's avatar
Guido van Rossum committed
472 473 474
	do_d = do_down
	
	def do_step(self, arg):
475
		self.set_step()
476
		return 1
Guido van Rossum's avatar
Guido van Rossum committed
477 478 479
	do_s = do_step
	
	def do_next(self, arg):
480
		self.set_next(self.curframe)
481
		return 1
Guido van Rossum's avatar
Guido van Rossum committed
482 483
	do_n = do_next
	
484
	def do_return(self, arg):
485
		self.set_return(self.curframe)
486 487 488
		return 1
	do_r = do_return
	
Guido van Rossum's avatar
Guido van Rossum committed
489
	def do_continue(self, arg):
490
		self.set_continue()
491
		return 1
Guido van Rossum's avatar
Guido van Rossum committed
492 493 494
	do_c = do_cont = do_continue
	
	def do_quit(self, arg):
495 496
		self.set_quit()
		return 1
Guido van Rossum's avatar
Guido van Rossum committed
497 498
	do_q = do_quit
	
499
	def do_args(self, arg):
500 501 502 503 504 505 506 507 508 509 510
		f = self.curframe
		co = f.f_code
		dict = f.f_locals
		n = co.co_argcount
		if co.co_flags & 4: n = n+1
		if co.co_flags & 8: n = n+1
		for i in range(n):
			name = co.co_varnames[i]
			print name, '=',
			if dict.has_key(name): print dict[name]
			else: print "*** undefined ***"
511 512 513 514 515 516 517 518 519 520 521
	do_a = do_args
	
	def do_retval(self, arg):
		if self.curframe.f_locals.has_key('__return__'):
			print self.curframe.f_locals['__return__']
		else:
			print '*** Not yet returned!'
	do_rv = do_retval
	
	def do_p(self, arg):
		try:
522
			value = eval(arg, self.curframe.f_globals,
523 524
					self.curframe.f_locals)
		except:
525 526 527 528 529
			t, v = sys.exc_info()[:2]
			if type(t) == type(''):
				exc_type_name = t
			else: exc_type_name = t.__name__
			print '***', exc_type_name + ':', `v`
530
			return
531

532 533
		print `value`

Guido van Rossum's avatar
Guido van Rossum committed
534
	def do_list(self, arg):
535
		self.lastcmd = 'list'
Guido van Rossum's avatar
Guido van Rossum committed
536 537 538 539 540 541 542 543 544 545 546 547
		last = None
		if arg:
			try:
				x = eval(arg, {}, {})
				if type(x) == type(()):
					first, last = x
					first = int(first)
					last = int(last)
					if last < first:
						# Assume it's a count
						last = first + last
				else:
548
					first = max(1, int(x) - 5)
Guido van Rossum's avatar
Guido van Rossum committed
549 550 551 552 553 554 555
			except:
				print '*** Error in argument:', `arg`
				return
		elif self.lineno is None:
			first = max(1, self.curframe.f_lineno - 5)
		else:
			first = self.lineno + 1
556
		if last == None:
Guido van Rossum's avatar
Guido van Rossum committed
557 558
			last = first + 10
		filename = self.curframe.f_code.co_filename
559
		breaklist = self.get_file_breaks(filename)
Guido van Rossum's avatar
Guido van Rossum committed
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
		try:
			for lineno in range(first, last+1):
				line = linecache.getline(filename, lineno)
				if not line:
					print '[EOF]'
					break
				else:
					s = string.rjust(`lineno`, 3)
					if len(s) < 4: s = s + ' '
					if lineno in breaklist: s = s + 'B'
					else: s = s + ' '
					if lineno == self.curframe.f_lineno:
						s = s + '->'
					print s + '\t' + line,
					self.lineno = lineno
		except KeyboardInterrupt:
			pass
	do_l = do_list
578 579 580

	def do_whatis(self, arg):
		try:
581
			value = eval(arg, self.curframe.f_globals,
582 583
					self.curframe.f_locals)
		except:
584 585 586 587 588
			t, v = sys.exc_info()[:2]
			if type(t) == type(''):
				exc_type_name = t
			else: exc_type_name = t.__name__
			print '***', exc_type_name + ':', `v`
589 590 591 592 593 594
			return
		code = None
		# Is it a function?
		try: code = value.func_code
		except: pass
		if code:
595
			print 'Function', code.co_name
596 597 598 599 600
			return
		# Is it an instance method?
		try: code = value.im_func.func_code
		except: pass
		if code:
601
			print 'Method', code.co_name
602 603 604
			return
		# None of the above...
		print type(value)
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624

	def do_alias(self, arg):
		args = string.split (arg)
		if len(args) == 0:
			keys = self.aliases.keys()
			keys.sort()
			for alias in keys:
				print "%s = %s" % (alias, self.aliases[alias])
			return
		if self.aliases.has_key(args[0]) and len (args) == 1:
			print "%s = %s" % (args[0], self.aliases[args[0]])
		else:
			self.aliases[args[0]] = string.join(args[1:], ' ')

	def do_unalias(self, arg):
		args = string.split (arg)
		if len(args) == 0: return
		if self.aliases.has_key(args[0]):
			del self.aliases[args[0]]

625
	# Print a traceback starting at the top stack frame.
626
	# The most recently entered frame is printed last;
627 628 629 630 631
	# this is different from dbx and gdb, but consistent with
	# the Python interpreter's stack trace.
	# It is also consistent with the up/down commands (which are
	# compatible with dbx and gdb: up moves towards 'main()'
	# and down moves towards the most recent stack frame).
Guido van Rossum's avatar
Guido van Rossum committed
632
	
633 634 635 636 637 638
	def print_stack_trace(self):
		try:
			for frame_lineno in self.stack:
				self.print_stack_entry(frame_lineno)
		except KeyboardInterrupt:
			pass
639
	
640
	def print_stack_entry(self, frame_lineno, prompt_prefix=line_prefix):
641 642 643 644 645
		frame, lineno = frame_lineno
		if frame is self.curframe:
			print '>',
		else:
			print ' ',
646
		print self.format_stack_entry(frame_lineno, prompt_prefix)
Guido van Rossum's avatar
Guido van Rossum committed
647 648


649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689
	# Help methods (derived from pdb.doc)

	def help_help(self):
		self.help_h()

	def help_h(self):
		print """h(elp)
	Without argument, print the list of available commands.
	With a command name as argument, print help about that command
	"help pdb" pipes the full documentation file to the $PAGER
	"help exec" gives help on the ! command"""

	def help_where(self):
		self.help_w()

	def help_w(self):
		print """w(here)
	Print a stack trace, with the most recent frame at the bottom.
	An arrow indicates the "current frame", which determines the
	context of most commands."""

	def help_down(self):
		self.help_d()

	def help_d(self):
		print """d(own)
	Move the current frame one level down in the stack trace
	(to an older frame)."""

	def help_up(self):
		self.help_u()

	def help_u(self):
		print """u(p)
	Move the current frame one level up in the stack trace
	(to a newer frame)."""

	def help_break(self):
		self.help_b()

	def help_b(self):
690
		print """b(reak) ([file:]lineno | function) [, condition]
691
	With a line number argument, set a break there in the current
692 693
	file.  With a function name, set a break at first executable line
	of that function.  Without argument, list all breaks.  If a second
694 695
	argument is present, it is a string specifying an expression
	which must evaluate to true before the breakpoint is honored.
696 697 698

	The line number may be prefixed with a filename and a colon,
	to specify a breakpoint in another file (probably one that
699
	hasn't been loaded yet).  The file is searched for on sys.path;
700
	the .py suffix may be omitted."""
701 702 703 704 705

	def help_clear(self):
		self.help_cl()

	def help_cl(self):
706
		print "cl(ear) filename:lineno"
707 708 709
		print """cl(ear) [bpnumber [bpnumber...]]
	With a space separated list of breakpoint numbers, clear
	those breakpoints.  Without argument, clear all breaks (but
710 711
	first ask confirmation).  With a filename:lineno argument,
	clear all breaks at that line in that file.
712 713 714

	Note that the argument is different from previous versions of
	the debugger (in python distributions 1.5.1 and before) where
715 716
	a linenumber was used instead of either filename:lineno or
	breakpoint numbers."""
717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745

	def help_tbreak(self):
		print """tbreak  same arguments as break, but breakpoint is
	removed when first hit."""

	def help_enable(self):
		print """enable bpnumber [bpnumber ...]
	Enables the breakpoints given as a space separated list of
	bp numbers."""

	def help_disable(self):
		print """disable bpnumber [bpnumber ...]
	Disables the breakpoints given as a space separated list of
	bp numbers."""

	def help_ignore(self):
		print """ignore bpnumber count
	Sets the ignore count for the given breakpoint number.  A breakpoint
	becomes active when the ignore count is zero.  When non-zero, the
	count is decremented each time the breakpoint is reached and the
	breakpoint is not disabled and any associated condition evaluates
	to true."""

	def help_condition(self):
		print """condition bpnumber str_condition
	str_condition is a string specifying an expression which
	must evaluate to true before the breakpoint is honored.
	If str_condition is absent, any existing condition is removed;
	i.e., the breakpoint is made unconditional."""
746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796

	def help_step(self):
		self.help_s()

	def help_s(self):
		print """s(tep)
	Execute the current line, stop at the first possible occasion
	(either in a function that is called or in the current function)."""

	def help_next(self):
		self.help_n()

	def help_n(self):
		print """n(ext)
	Continue execution until the next line in the current function
	is reached or it returns."""

	def help_return(self):
		self.help_r()

	def help_r(self):
		print """r(eturn)
	Continue execution until the current function returns."""

	def help_continue(self):
		self.help_c()

	def help_cont(self):
		self.help_c()

	def help_c(self):
		print """c(ont(inue))
	Continue execution, only stop when a breakpoint is encountered."""

	def help_list(self):
		self.help_l()

	def help_l(self):
		print """l(ist) [first [,last]]
	List source code for the current file.
	Without arguments, list 11 lines around the current line
	or continue the previous listing.
	With one argument, list 11 lines starting at that line.
	With two arguments, list the given range;
	if the second argument is less than the first, it is a count."""

	def help_args(self):
		self.help_a()

	def help_a(self):
		print """a(rgs)
797
	Print the arguments of the current function."""
798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820

	def help_p(self):
		print """p expression
	Print the value of the expression."""

	def help_exec(self):
		print """(!) statement
	Execute the (one-line) statement in the context of
	the current stack frame.
	The exclamation point can be omitted unless the first word
	of the statement resembles a debugger command.
	To assign to a global variable you must always prefix the
	command with a 'global' command, e.g.:
	(Pdb) global list_options; list_options = ['-l']
	(Pdb)"""

	def help_quit(self):
		self.help_q()

	def help_q(self):
		print """q(uit)	Quit from the debugger.
	The program being executed is aborted."""

821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856
	def help_whatis(self):
		print """whatis arg
	Prints the type of the argument."""

	def help_EOF(self):
		print """EOF
	Handles the receipt of EOF as a command."""

	def help_alias(self):
		print """alias [name [command [parameter parameter ...] ]]
	Creates an alias called 'name' the executes 'command'.  The command
	must *not* be enclosed in quotes.  Replaceable parameters are
	indicated by %1, %2, and so on, while %* is replaced by all the 
	parameters.  If no command is given, the current alias for name
	is shown. If no name is given, all aliases are listed.
	
	Aliases may be nested and can contain anything that can be
	legally typed at the pdb prompt.  Note!  You *can* override
	internal pdb commands with aliases!  Those internal commands
	are then hidden until the alias is removed.  Aliasing is recursively
	applied to the first word of the command line; all other words
	in the line are left alone.

	Some useful aliases (especially when placed in the .pdbrc file) are:

	#Print instance variables (usage "pi classInst")
	alias pi for k in %1.__dict__.keys(): print "%1.",k,"=",%1.__dict__[k]

	#Print instance variables in self
	alias ps pi self
	"""

	def help_unalias(self):
		print """unalias name
	Deletes the specified alias."""

857 858 859
	def help_pdb(self):
		help()

860
	def lookupmodule(self, filename):
861
		"""Helper function for break/clear parsing -- may be overridden."""
862 863 864 865 866
		root, ext = os.path.splitext(filename)
		if ext == '':
			filename = filename + '.py'
		if os.path.isabs(filename):
			return filename
867
		for dirname in sys.path:
868 869
			while os.path.islink(dirname):
				dirname = os.readlink(dirname)
870 871 872
			fullname = os.path.join(dirname, filename)
			if os.path.exists(fullname):
				return fullname
873
		return None
874

875 876
# Simplified interface

877 878 879 880 881
def run(statement, globals=None, locals=None):
	Pdb().run(statement, globals, locals)

def runeval(expression, globals=None, locals=None):
	return Pdb().runeval(expression, globals, locals)
882 883

def runctx(statement, globals, locals):
884 885
	# B/W compatibility
	run(statement, globals, locals)
886

887
def runcall(*args):
888
	return apply(Pdb().runcall, args)
889

890 891
def set_trace():
	Pdb().set_trace()
892 893 894 895

# Post-Mortem interface

def post_mortem(t):
896
	p = Pdb()
897 898 899 900 901 902 903 904 905 906
	p.reset()
	while t.tb_next <> None: t = t.tb_next
	p.interaction(t.tb_frame, t)

def pm():
	post_mortem(sys.last_traceback)


# Main program for testing

907
TESTCMD = 'import x; x.main()'
908

Guido van Rossum's avatar
Guido van Rossum committed
909
def test():
910
	run(TESTCMD)
911 912 913 914 915 916 917 918 919 920 921 922

# print help
def help():
	for dirname in sys.path:
		fullname = os.path.join(dirname, 'pdb.doc')
		if os.path.exists(fullname):
			sts = os.system('${PAGER-more} '+fullname)
			if sts: print '*** Pager exit status:', sts
			break
	else:
		print 'Sorry, can\'t find the help file "pdb.doc"',
		print 'along the Python search path'
923

924 925 926
mainmodule = ''
mainpyfile = ''

927 928 929 930 931 932
# When invoked as main program, invoke the debugger on a script
if __name__=='__main__':
	if not sys.argv[1:]:
		print "usage: pdb.py scriptfile [arg] ..."
		sys.exit(2)

933 934 935 936 937
	mainpyfile = filename = sys.argv[1]	# Get script filename
	if not os.path.exists(filename):
		print 'Error:', `filename`, 'does not exist'
		sys.exit(1)
	mainmodule = os.path.basename(filename)
938
	del sys.argv[0]		# Hide "pdb.py" from argument list
939

940 941
	# Insert script directory in front of module search path
	sys.path.insert(0, os.path.dirname(filename))
942

943
	run('execfile(' + `filename` + ')')