blob: b733598f258476b34721d8b99a133e7d28a65eb0 [file] [log] [blame]
Guido van Rossumaad67612000-05-08 17:31:04 +00001"""Extract, format and print information about Python stack traces."""
Guido van Rossum5c971671996-07-22 15:23:25 +00002
3import linecache
4import string
5import sys
6import types
7
8def _print(file, str='', terminator='\n'):
9 file.write(str+terminator)
Guido van Rossuma8763e51996-08-26 18:33:32 +000010
11
12def print_list(extracted_list, file=None):
Guido van Rossumaad67612000-05-08 17:31:04 +000013 """Print the list of tuples as returned by extract_tb() or
14 extract_stack() as a formatted stack trace to the given file."""
Guido van Rossuma8763e51996-08-26 18:33:32 +000015 if not file:
16 file = sys.stderr
17 for filename, lineno, name, line in extracted_list:
18 _print(file,
19 ' File "%s", line %d, in %s' % (filename,lineno,name))
20 if line:
21 _print(file, ' %s' % string.strip(line))
22
23def format_list(extracted_list):
Guido van Rossumaad67612000-05-08 17:31:04 +000024 """Given a list of tuples as returned by extract_tb() or
25 extract_stack(), return a list of strings ready for printing.
26 Each string in the resulting list corresponds to the item with
27 the same index in the argument list. Each string ends in a
28 newline; the strings may contain internal newlines as well, for
29 those items whose source text line is not None."""
Guido van Rossuma8763e51996-08-26 18:33:32 +000030 list = []
31 for filename, lineno, name, line in extracted_list:
32 item = ' File "%s", line %d, in %s\n' % (filename,lineno,name)
33 if line:
34 item = item + ' %s\n' % string.strip(line)
35 list.append(item)
36 return list
Guido van Rossum5c971671996-07-22 15:23:25 +000037
38
39def print_tb(tb, limit=None, file=None):
Guido van Rossumaad67612000-05-08 17:31:04 +000040 """Print up to 'limit' stack trace entries from the traceback 'tb'.
41 If 'limit' is omitted or None, all entries are printed. If 'file' is
42 omitted or None, the output goes to sys.stderr; otherwise 'file'
43 should be an open file or file-like object with a write() method."""
Guido van Rossum5c971671996-07-22 15:23:25 +000044 if not file:
45 file = sys.stderr
46 if limit is None:
47 if hasattr(sys, 'tracebacklimit'):
48 limit = sys.tracebacklimit
49 n = 0
50 while tb is not None and (limit is None or n < limit):
51 f = tb.tb_frame
Guido van Rossuma11cccc1997-10-06 20:19:59 +000052 lineno = tb_lineno(tb)
Guido van Rossum5c971671996-07-22 15:23:25 +000053 co = f.f_code
54 filename = co.co_filename
55 name = co.co_name
56 _print(file,
57 ' File "%s", line %d, in %s' % (filename,lineno,name))
58 line = linecache.getline(filename, lineno)
59 if line: _print(file, ' ' + string.strip(line))
60 tb = tb.tb_next
61 n = n+1
62
63def format_tb(tb, limit = None):
Guido van Rossumaad67612000-05-08 17:31:04 +000064 """A shorthand for 'format_list(extract_stack(f, limit))."""
Guido van Rossuma8763e51996-08-26 18:33:32 +000065 return format_list(extract_tb(tb, limit))
Guido van Rossum5c971671996-07-22 15:23:25 +000066
67def extract_tb(tb, limit = None):
Guido van Rossumaad67612000-05-08 17:31:04 +000068 """Return a list of up to 'limit' pre-processed stack trace entries
69 extracted from the traceback object 'traceback'. This is useful for
70 alternate formatting of stack traces. If 'limit' is omitted or None,
71 all entries are extracted. A pre-processed stack trace entry is a
72 quadruple (filename, line number, function name, text) representing
73 the information that is usually printed for a stack trace. The text
74 is a string with leading and trailing whitespace stripped; if the
75 source is not available it is None."""
Guido van Rossum5c971671996-07-22 15:23:25 +000076 if limit is None:
77 if hasattr(sys, 'tracebacklimit'):
78 limit = sys.tracebacklimit
79 list = []
80 n = 0
81 while tb is not None and (limit is None or n < limit):
82 f = tb.tb_frame
Guido van Rossuma11cccc1997-10-06 20:19:59 +000083 lineno = tb_lineno(tb)
Guido van Rossum5c971671996-07-22 15:23:25 +000084 co = f.f_code
85 filename = co.co_filename
86 name = co.co_name
87 line = linecache.getline(filename, lineno)
88 if line: line = string.strip(line)
89 else: line = None
Guido van Rossumb8cc6ae1996-10-08 14:13:43 +000090 list.append((filename, lineno, name, line))
Guido van Rossum5c971671996-07-22 15:23:25 +000091 tb = tb.tb_next
92 n = n+1
93 return list
94
95
96def print_exception(etype, value, tb, limit=None, file=None):
Guido van Rossumaad67612000-05-08 17:31:04 +000097 """Print exception information and up to 'limit' stack trace entries
98 from the traceback 'tb' to 'file'. This differs from print_tb() in
99 the following ways: (1) if traceback is not None, it prints a header
100 "Traceback (most recent call last):"; (2) it prints the exception type and
101 value after the stack trace; (3) if type is SyntaxError and value has
102 the appropriate format, it prints the line where the syntax error
103 occurred with a caret on the next line indicating the approximate
104 position of the error."""
Guido van Rossum5c971671996-07-22 15:23:25 +0000105 if not file:
106 file = sys.stderr
107 if tb:
Guido van Rossumaad67612000-05-08 17:31:04 +0000108 _print(file, 'Traceback (most recent call last):')
Guido van Rossum5c971671996-07-22 15:23:25 +0000109 print_tb(tb, limit, file)
110 lines = format_exception_only(etype, value)
111 for line in lines[:-1]:
112 _print(file, line, ' ')
113 _print(file, lines[-1], '')
114
115def format_exception(etype, value, tb, limit = None):
Guido van Rossumaad67612000-05-08 17:31:04 +0000116 """Format a stack trace and the exception information. The arguments
117 have the same meaning as the corresponding arguments to
118 print_exception(). The return value is a list of strings, each
119 ending in a newline and some containing internal newlines. When
Thomas Wouters7e474022000-07-16 12:04:32 +0000120 these lines are concatenated and printed, exactly the same text is
Guido van Rossumaad67612000-05-08 17:31:04 +0000121 printed as does print_exception()."""
Guido van Rossum5c971671996-07-22 15:23:25 +0000122 if tb:
Guido van Rossumaad67612000-05-08 17:31:04 +0000123 list = ['Traceback (most recent call last):\n']
Guido van Rossum5c971671996-07-22 15:23:25 +0000124 list = list + format_tb(tb, limit)
Guido van Rossum548703a1998-03-26 22:14:20 +0000125 else:
126 list = []
Guido van Rossum5c971671996-07-22 15:23:25 +0000127 list = list + format_exception_only(etype, value)
128 return list
129
130def format_exception_only(etype, value):
Guido van Rossumaad67612000-05-08 17:31:04 +0000131 """Format the exception part of a traceback. The arguments are the
132 exception type and value such as given by sys.last_type and
133 sys.last_value. The return value is a list of strings, each ending
134 in a newline. Normally, the list contains a single string;
135 however, for SyntaxError exceptions, it contains several lines that
136 (when printed) display detailed information about where the syntax
137 error occurred. The message indicating which exception occurred is
138 the always last string in the list."""
Guido van Rossum5c971671996-07-22 15:23:25 +0000139 list = []
140 if type(etype) == types.ClassType:
141 stype = etype.__name__
142 else:
143 stype = etype
144 if value is None:
145 list.append(str(stype) + '\n')
146 else:
147 if etype is SyntaxError:
148 try:
149 msg, (filename, lineno, offset, line) = value
150 except:
151 pass
152 else:
153 if not filename: filename = "<string>"
154 list.append(' File "%s", line %d\n' %
155 (filename, lineno))
156 i = 0
157 while i < len(line) and \
158 line[i] in string.whitespace:
159 i = i+1
160 list.append(' %s\n' % string.strip(line))
161 s = ' '
162 for c in line[i:offset-1]:
163 if c in string.whitespace:
164 s = s + c
165 else:
166 s = s + ' '
167 list.append('%s^\n' % s)
168 value = msg
Guido van Rossum8d691c82000-09-01 19:25:51 +0000169 list.append('%s: %s\n' % (str(stype), _some_str(value)))
Guido van Rossum5c971671996-07-22 15:23:25 +0000170 return list
171
Guido van Rossum8d691c82000-09-01 19:25:51 +0000172def _some_str(value):
173 try:
174 return str(value)
175 except:
176 return '<unprintable %s object>' % type(value).__name__
177
Guido van Rossum5c971671996-07-22 15:23:25 +0000178
179def print_exc(limit=None, file=None):
Guido van Rossumaad67612000-05-08 17:31:04 +0000180 """This is a shorthand for 'print_exception(sys.exc_type,
181 sys.exc_value, sys.exc_traceback, limit, file)'.
182 (In fact, it uses sys.exc_info() to retrieve the same information
183 in a thread-safe way.)"""
Guido van Rossum5c971671996-07-22 15:23:25 +0000184 if not file:
185 file = sys.stderr
Guido van Rossumff712aa1997-08-15 00:45:26 +0000186 try:
187 etype, value, tb = sys.exc_info()
188 print_exception(etype, value, tb, limit, file)
189 finally:
190 etype = value = tb = None
Guido van Rossum5c971671996-07-22 15:23:25 +0000191
192def print_last(limit=None, file=None):
Guido van Rossumaad67612000-05-08 17:31:04 +0000193 """This is a shorthand for 'print_exception(sys.last_type,
194 sys.last_value, sys.last_traceback, limit, file)'."""
Guido van Rossum5c971671996-07-22 15:23:25 +0000195 if not file:
196 file = sys.stderr
197 print_exception(sys.last_type, sys.last_value, sys.last_traceback,
198 limit, file)
Guido van Rossuma8763e51996-08-26 18:33:32 +0000199
200
201def print_stack(f=None, limit=None, file=None):
Guido van Rossumaad67612000-05-08 17:31:04 +0000202 """This function prints a stack trace from its invocation point.
203 The optional 'f' argument can be used to specify an alternate stack
204 frame at which to start. The optional 'limit' and 'file' arguments
205 have the same meaning as for print_exception()."""
Guido van Rossuma8763e51996-08-26 18:33:32 +0000206 if f is None:
207 try:
208 raise ZeroDivisionError
209 except ZeroDivisionError:
Guido van Rossumff712aa1997-08-15 00:45:26 +0000210 f = sys.exc_info()[2].tb_frame.f_back
Guido van Rossuma8763e51996-08-26 18:33:32 +0000211 print_list(extract_stack(f, limit), file)
212
213def format_stack(f=None, limit=None):
Guido van Rossumaad67612000-05-08 17:31:04 +0000214 """A shorthand for 'format_list(extract_stack(f, limit))'."""
Guido van Rossuma8763e51996-08-26 18:33:32 +0000215 if f is None:
216 try:
217 raise ZeroDivisionError
218 except ZeroDivisionError:
Guido van Rossumff712aa1997-08-15 00:45:26 +0000219 f = sys.exc_info()[2].tb_frame.f_back
220 return format_list(extract_stack(f, limit))
Guido van Rossuma8763e51996-08-26 18:33:32 +0000221
222def extract_stack(f=None, limit = None):
Guido van Rossumaad67612000-05-08 17:31:04 +0000223 """Extract the raw traceback from the current stack frame. The
224 return value has the same format as for extract_tb(). The optional
225 'f' and 'limit' arguments have the same meaning as for print_stack().
226 Each item in the list is a quadruple (filename, line number,
227 function name, text), and the entries are in order from oldest
228 to newest stack frame."""
Guido van Rossuma8763e51996-08-26 18:33:32 +0000229 if f is None:
230 try:
231 raise ZeroDivisionError
232 except ZeroDivisionError:
Guido van Rossumff712aa1997-08-15 00:45:26 +0000233 f = sys.exc_info()[2].tb_frame.f_back
Guido van Rossuma8763e51996-08-26 18:33:32 +0000234 if limit is None:
235 if hasattr(sys, 'tracebacklimit'):
236 limit = sys.tracebacklimit
237 list = []
238 n = 0
239 while f is not None and (limit is None or n < limit):
Guido van Rossuma11cccc1997-10-06 20:19:59 +0000240 lineno = f.f_lineno # XXX Too bad if -O is used
Guido van Rossuma8763e51996-08-26 18:33:32 +0000241 co = f.f_code
242 filename = co.co_filename
243 name = co.co_name
244 line = linecache.getline(filename, lineno)
245 if line: line = string.strip(line)
246 else: line = None
Guido van Rossumb8cc6ae1996-10-08 14:13:43 +0000247 list.append((filename, lineno, name, line))
Guido van Rossuma8763e51996-08-26 18:33:32 +0000248 f = f.f_back
249 n = n+1
250 list.reverse()
251 return list
Guido van Rossuma11cccc1997-10-06 20:19:59 +0000252
Guido van Rossuma11cccc1997-10-06 20:19:59 +0000253def tb_lineno(tb):
Guido van Rossumaad67612000-05-08 17:31:04 +0000254 """Calculate the correct line number of the traceback given in tb
255 (even with -O on)."""
256
257 # Coded by Marc-Andre Lemburg from the example of PyCode_Addr2Line()
258 # in compile.c.
259 # Revised version by Jim Hugunin to work with JPython too.
260
Guido van Rossuma11cccc1997-10-06 20:19:59 +0000261 c = tb.tb_frame.f_code
Guido van Rossum548703a1998-03-26 22:14:20 +0000262 if not hasattr(c, 'co_lnotab'):
263 return tb.tb_lineno
264
Guido van Rossuma11cccc1997-10-06 20:19:59 +0000265 tab = c.co_lnotab
266 line = c.co_firstlineno
267 stopat = tb.tb_lasti
268 addr = 0
269 for i in range(0, len(tab), 2):
270 addr = addr + ord(tab[i])
271 if addr > stopat:
272 break
273 line = line + ord(tab[i+1])
274 return line