Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit babe2bf

Browse files
committed
Initial revision
1 parent 68c172e commit babe2bf

14 files changed

Lines changed: 1776 additions & 0 deletions

File tree

Lib/bdb.py

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
# A generic Python debugger base class.
2+
# This class takes care of details of the trace facility;
3+
# a derived class should implement user interaction.
4+
# There are two debuggers based upon this:
5+
# 'pdb', a text-oriented debugger not unlike dbx or gdb;
6+
# and 'wdb', a window-oriented debugger.
7+
# And of course... you can roll your own!
8+
9+
import sys
10+
11+
BdbQuit = 'bdb.BdbQuit' # Exception to give up completely
12+
13+
14+
class Bdb: # Basic Debugger
15+
16+
def init(self):
17+
self.breaks = {}
18+
return self
19+
20+
def reset(self):
21+
self.botframe = None
22+
self.stopframe = None
23+
self.returnframe = None
24+
self.quitting = 0
25+
26+
def trace_dispatch(self, frame, event, arg):
27+
if self.quitting:
28+
return # None
29+
if event == 'line':
30+
return self.dispatch_line(frame)
31+
if event == 'call':
32+
return self.dispatch_call(frame, arg)
33+
if event == 'return':
34+
return self.dispatch_return(frame, arg)
35+
if event == 'exception':
36+
return self.dispatch_exception(frame, arg)
37+
print 'bdb.Bdb.dispatch: unknown debugging event:', `event`
38+
return self.trace_dispatch
39+
40+
def dispatch_line(self, frame):
41+
if self.stop_here(frame) or self.break_here(frame):
42+
self.user_line(frame)
43+
if self.quitting: raise BdbQuit
44+
return self.trace_dispatch
45+
46+
def dispatch_call(self, frame, arg):
47+
frame.f_locals['__args__'] = arg
48+
if self.botframe is None:
49+
# First call of dispatch since reset()
50+
self.botframe = frame
51+
return self.trace_dispatch
52+
if not (self.stop_here(frame) or self.break_anywhere(frame)):
53+
# No need to trace this function
54+
return # None
55+
self.user_call(frame, arg)
56+
if self.quitting: raise BdbQuit
57+
return self.trace_dispatch
58+
59+
def dispatch_return(self, frame, arg):
60+
if self.stop_here(frame) or frame == self.returnframe:
61+
self.user_return(frame, arg)
62+
if self.quitting: raise BdbQuit
63+
64+
def dispatch_exception(self, frame, arg):
65+
if self.stop_here(frame):
66+
self.user_exception(frame, arg)
67+
if self.quitting: raise BdbQuit
68+
return self.trace_dispatch
69+
70+
# Normally derived classes don't override the following
71+
# functions, but they may if they want to redefine the
72+
# definition of stopping and breakpoints.
73+
74+
def stop_here(self, frame):
75+
if self.stopframe is None:
76+
return 1
77+
if frame is self.stopframe:
78+
return 1
79+
while frame is not None and frame is not self.stopframe:
80+
if frame is self.botframe:
81+
return 1
82+
frame = frame.f_back
83+
return 0
84+
85+
def break_here(self, frame):
86+
if not self.breaks.has_key(frame.f_code.co_filename):
87+
return 0
88+
if not frame.f_lineno in \
89+
self.breaks[frame.f_code.co_filename]:
90+
return 0
91+
return 1
92+
93+
def break_anywhere(self, frame):
94+
return self.breaks.has_key(frame.f_code.co_filename)
95+
96+
# Derived classes should override the user_* functions
97+
# to gain control.
98+
99+
def user_call(self, frame, argument_list):
100+
# This function is called when there is the remote possibility
101+
# that we ever need to stop in this function
102+
pass
103+
104+
def user_line(self, frame):
105+
# This function is called when we stop or break at this line
106+
pass
107+
108+
def user_return(self, frame, return_value):
109+
# This function is called when a return trap is set here
110+
pass
111+
112+
def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
113+
# This function is called if an exception occurs,
114+
# but only if we are to stop at or just below this level
115+
pass
116+
117+
# Derived classes and clients can call the following functions
118+
# to affect the stepping state.
119+
120+
def set_step(self):
121+
# Stop after one line of code
122+
self.stopframe = None
123+
self.returnframe = None
124+
self.quitting = 0
125+
126+
def set_next(self, frame):
127+
# Stop on the next line in or below the given frame
128+
self.stopframe = frame
129+
self.returnframe = None
130+
self.quitting = 0
131+
132+
def set_return(self, frame):
133+
# Stop when returning from the given frame
134+
self.stopframe = frame.f_back
135+
self.returnframe = frame
136+
self.quitting = 0
137+
138+
def set_continue(self):
139+
# Don't stop except at breakpoints or when finished
140+
self.stopframe = self.botframe
141+
self.returnframe = None
142+
self.quitting = 0
143+
144+
def set_quit(self):
145+
self.stopframe = self.botframe
146+
self.returnframe = None
147+
self.quitting = 1
148+
sys.trace = None
149+
del sys.trace
150+
151+
# Derived classes and clients can call the following functions
152+
# to manipulate breakpoints. These functions return an
153+
# error message is something went wrong, None if all is well.
154+
# Call self.get_*break*() to see the breakpoints.
155+
156+
def set_break(self, filename, lineno):
157+
import linecache # Import as late as possible
158+
line = linecache.getline(filename, lineno)
159+
if not line:
160+
return 'That line does not exist!'
161+
if not self.breaks.has_key(filename):
162+
self.breaks[filename] = []
163+
list = self.breaks[filename]
164+
if lineno in list:
165+
return 'There is already a breakpoint there!'
166+
list.append(lineno)
167+
168+
def clear_break(self, filename, lineno):
169+
if not self.breaks.has_key(filename):
170+
return 'There are no breakpoints in that file!'
171+
if lineno not in self.breaks[filename]:
172+
return 'There is no breakpoint there!'
173+
self.breaks[filename].remove(lineno)
174+
if not self.breaks[filename]:
175+
del self.breaks[filename]
176+
177+
def clear_all_file_breaks(self, filename):
178+
if not self.breaks.has_key(filename):
179+
return 'There are no breakpoints in that file!'
180+
del self.breaks[filename]
181+
182+
def clear_all_breaks(self, filename, lineno):
183+
if not self.breaks:
184+
return 'There are no breakpoints!'
185+
self.breaks = {}
186+
187+
def get_break(self, filename, lineno):
188+
return self.breaks.has_key(filename) and \
189+
lineno in self.breaks[filename]
190+
191+
def get_file_breaks(self, filename):
192+
if self.breaks.has_key(filename):
193+
return self.breaks[filename]
194+
else:
195+
return []
196+
197+
def get_all_breaks(self):
198+
return self.breaks
199+
200+
# Derived classes and clients can call the following function
201+
# to get a data structure representing a stack trace.
202+
203+
def get_stack(self, f, t):
204+
stack = []
205+
if t and t.tb_frame is f:
206+
t = t.tb_next
207+
while f is not None:
208+
stack.append((f, f.f_lineno))
209+
if f is self.botframe:
210+
break
211+
f = f.f_back
212+
stack.reverse()
213+
i = max(0, len(stack) - 1)
214+
while t is not None:
215+
stack.append((t.tb_frame, t.tb_lineno))
216+
t = t.tb_next
217+
return stack, i
218+
219+
# The following two functions can be called by clients to use
220+
# a debugger to debug a statement, given as a string.
221+
222+
def run(self, cmd):
223+
import __main__
224+
dict = __main__.__dict__
225+
self.runctx(cmd, dict, dict)
226+
227+
def runctx(self, cmd, globals, locals):
228+
self.reset()
229+
sys.trace = self.trace_dispatch
230+
try:
231+
exec(cmd + '\n', globals, locals)
232+
except BdbQuit:
233+
pass
234+
finally:
235+
self.quitting = 1
236+
sys.trace = None
237+
del sys.trace
238+
# XXX What to do if the command finishes normally?
239+
240+
241+
# -------------------- testing --------------------
242+
243+
class Tdb(Bdb):
244+
def user_call(self, frame, args):
245+
import codehack
246+
name = codehack.getcodename(frame.f_code)
247+
if not name: name = '???'
248+
print '+++ call', name, args
249+
def user_line(self, frame):
250+
import linecache, string, codehack
251+
name = codehack.getcodename(frame.f_code)
252+
if not name: name = '???'
253+
fn = frame.f_code.co_filename
254+
line = linecache.getline(fn, frame.f_lineno)
255+
print '+++', fn, frame.f_lineno, name, ':', string.strip(line)
256+
def user_return(self, frame, retval):
257+
print '+++ return', retval
258+
def user_exception(self, frame, exc_stuff):
259+
print '+++ exception', exc_stuff
260+
self.set_continue()
261+
262+
def foo(n):
263+
print 'foo(', n, ')'
264+
x = bar(n*10)
265+
print 'bar returned', x
266+
267+
def bar(a):
268+
print 'bar(', a, ')'
269+
return a/2
270+
271+
def test():
272+
import linecache
273+
linecache.checkcache()
274+
t = Tdb().init()
275+
t.run('import bdb; bdb.foo(10)')

Lib/codehack.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# A subroutine for extracting a function name from a code object
2+
# (with cache)
3+
4+
import sys
5+
from stat import *
6+
import string
7+
import os
8+
import linecache
9+
10+
# Extract the function or class name from a code object.
11+
# This is a bit of a hack, since a code object doesn't contain
12+
# the name directly. So what do we do:
13+
# - get the filename (which *is* in the code object)
14+
# - look in the code string to find the first SET_LINENO instruction
15+
# (this must be the first instruction)
16+
# - get the line from the file
17+
# - if the line starts with 'class' or 'def' (after possible whitespace),
18+
# extract the following identifier
19+
#
20+
# This breaks apart when the function was read from <stdin>
21+
# or constructed by exec(), when the file is not accessible,
22+
# and also when the file has been modified or when a line is
23+
# continued with a backslash before the function or class name.
24+
#
25+
# Because this is a pretty expensive hack, a cache is kept.
26+
27+
SET_LINENO = 127 # The opcode (see "opcode.h" in the Python source)
28+
identchars = string.letters + string.digits + '_' # Identifier characters
29+
30+
_namecache = {} # The cache
31+
32+
def getcodename(co):
33+
key = `co` # arbitrary but uniquely identifying string
34+
if _namecache.has_key(key): return _namecache[key]
35+
filename = co.co_filename
36+
code = co.co_code
37+
name = ''
38+
if ord(code[0]) == SET_LINENO:
39+
lineno = ord(code[1]) | ord(code[2]) << 8
40+
line = linecache.getline(filename, lineno)
41+
words = string.split(line)
42+
if len(words) >= 2 and words[0] in ('def', 'class'):
43+
name = words[1]
44+
for i in range(len(name)):
45+
if name[i] not in identchars:
46+
name = name[:i]
47+
break
48+
_namecache[key] = name
49+
return name
50+
51+
# Use the above routine to find a function's name.
52+
53+
def getfuncname(func):
54+
return getcodename(func.func_code)

Lib/lib-old/codehack.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# A subroutine for extracting a function name from a code object
2+
# (with cache)
3+
4+
import sys
5+
from stat import *
6+
import string
7+
import os
8+
import linecache
9+
10+
# Extract the function or class name from a code object.
11+
# This is a bit of a hack, since a code object doesn't contain
12+
# the name directly. So what do we do:
13+
# - get the filename (which *is* in the code object)
14+
# - look in the code string to find the first SET_LINENO instruction
15+
# (this must be the first instruction)
16+
# - get the line from the file
17+
# - if the line starts with 'class' or 'def' (after possible whitespace),
18+
# extract the following identifier
19+
#
20+
# This breaks apart when the function was read from <stdin>
21+
# or constructed by exec(), when the file is not accessible,
22+
# and also when the file has been modified or when a line is
23+
# continued with a backslash before the function or class name.
24+
#
25+
# Because this is a pretty expensive hack, a cache is kept.
26+
27+
SET_LINENO = 127 # The opcode (see "opcode.h" in the Python source)
28+
identchars = string.letters + string.digits + '_' # Identifier characters
29+
30+
_namecache = {} # The cache
31+
32+
def getcodename(co):
33+
key = `co` # arbitrary but uniquely identifying string
34+
if _namecache.has_key(key): return _namecache[key]
35+
filename = co.co_filename
36+
code = co.co_code
37+
name = ''
38+
if ord(code[0]) == SET_LINENO:
39+
lineno = ord(code[1]) | ord(code[2]) << 8
40+
line = linecache.getline(filename, lineno)
41+
words = string.split(line)
42+
if len(words) >= 2 and words[0] in ('def', 'class'):
43+
name = words[1]
44+
for i in range(len(name)):
45+
if name[i] not in identchars:
46+
name = name[:i]
47+
break
48+
_namecache[key] = name
49+
return name
50+
51+
# Use the above routine to find a function's name.
52+
53+
def getfuncname(func):
54+
return getcodename(func.func_code)

0 commit comments

Comments
 (0)