1"""Extract, format and print information about Python stack traces."""
2
3import linecache
4import sys
5import types
6
7__all__ = ['extract_stack', 'extract_tb', 'format_exception',
8           'format_exception_only', 'format_list', 'format_stack',
9           'format_tb', 'print_exc', 'format_exc', 'print_exception',
10           'print_last', 'print_stack', 'print_tb', 'tb_lineno']
11
12def _print(file, str='', terminator='\n'):
13    file.write(str+terminator)
14
15
16def print_list(extracted_list, file=None):
17    """Print the list of tuples as returned by extract_tb() or
18    extract_stack() as a formatted stack trace to the given file."""
19    if file is None:
20        file = sys.stderr
21    for filename, lineno, name, line in extracted_list:
22        _print(file,
23               '  File "%s", line %d, in %s' % (filename,lineno,name))
24        if line:
25            _print(file, '    %s' % line.strip())
26
27def format_list(extracted_list):
28    """Format a list of traceback entry tuples for printing.
29
30    Given a list of tuples as returned by extract_tb() or
31    extract_stack(), return a list of strings ready for printing.
32    Each string in the resulting list corresponds to the item with the
33    same index in the argument list.  Each string ends in a newline;
34    the strings may contain internal newlines as well, for those items
35    whose source text line is not None.
36    """
37    list = []
38    for filename, lineno, name, line in extracted_list:
39        item = '  File "%s", line %d, in %s\n' % (filename,lineno,name)
40        if line:
41            item = item + '    %s\n' % line.strip()
42        list.append(item)
43    return list
44
45
46def print_tb(tb, limit=None, file=None):
47    """Print up to 'limit' stack trace entries from the traceback 'tb'.
48
49    If 'limit' is omitted or None, all entries are printed.  If 'file'
50    is omitted or None, the output goes to sys.stderr; otherwise
51    'file' should be an open file or file-like object with a write()
52    method.
53    """
54    if file is None:
55        file = sys.stderr
56    if limit is None:
57        if hasattr(sys, 'tracebacklimit'):
58            limit = sys.tracebacklimit
59    n = 0
60    while tb is not None and (limit is None or n < limit):
61        f = tb.tb_frame
62        lineno = tb.tb_lineno
63        co = f.f_code
64        filename = co.co_filename
65        name = co.co_name
66        _print(file,
67               '  File "%s", line %d, in %s' % (filename, lineno, name))
68        linecache.checkcache(filename)
69        line = linecache.getline(filename, lineno, f.f_globals)
70        if line: _print(file, '    ' + line.strip())
71        tb = tb.tb_next
72        n = n+1
73
74def format_tb(tb, limit = None):
75    """A shorthand for 'format_list(extract_stack(f, limit))."""
76    return format_list(extract_tb(tb, limit))
77
78def extract_tb(tb, limit = None):
79    """Return list of up to limit pre-processed entries from traceback.
80
81    This is useful for alternate formatting of stack traces.  If
82    'limit' is omitted or None, all entries are extracted.  A
83    pre-processed stack trace entry is a quadruple (filename, line
84    number, function name, text) representing the information that is
85    usually printed for a stack trace.  The text is a string with
86    leading and trailing whitespace stripped; if the source is not
87    available it is None.
88    """
89    if limit is None:
90        if hasattr(sys, 'tracebacklimit'):
91            limit = sys.tracebacklimit
92    list = []
93    n = 0
94    while tb is not None and (limit is None or n < limit):
95        f = tb.tb_frame
96        lineno = tb.tb_lineno
97        co = f.f_code
98        filename = co.co_filename
99        name = co.co_name
100        linecache.checkcache(filename)
101        line = linecache.getline(filename, lineno, f.f_globals)
102        if line: line = line.strip()
103        else: line = None
104        list.append((filename, lineno, name, line))
105        tb = tb.tb_next
106        n = n+1
107    return list
108
109
110def print_exception(etype, value, tb, limit=None, file=None):
111    """Print exception up to 'limit' stack trace entries from 'tb' to 'file'.
112
113    This differs from print_tb() in the following ways: (1) if
114    traceback is not None, it prints a header "Traceback (most recent
115    call last):"; (2) it prints the exception type and value after the
116    stack trace; (3) if type is SyntaxError and value has the
117    appropriate format, it prints the line where the syntax error
118    occurred with a caret on the next line indicating the approximate
119    position of the error.
120    """
121    if file is None:
122        file = sys.stderr
123    if tb:
124        _print(file, 'Traceback (most recent call last):')
125        print_tb(tb, limit, file)
126    lines = format_exception_only(etype, value)
127    for line in lines:
128        _print(file, line, '')
129
130def format_exception(etype, value, tb, limit = None):
131    """Format a stack trace and the exception information.
132
133    The arguments have the same meaning as the corresponding arguments
134    to print_exception().  The return value is a list of strings, each
135    ending in a newline and some containing internal newlines.  When
136    these lines are concatenated and printed, exactly the same text is
137    printed as does print_exception().
138    """
139    if tb:
140        list = ['Traceback (most recent call last):\n']
141        list = list + format_tb(tb, limit)
142    else:
143        list = []
144    list = list + format_exception_only(etype, value)
145    return list
146
147def format_exception_only(etype, value):
148    """Format the exception part of a traceback.
149
150    The arguments are the exception type and value such as given by
151    sys.last_type and sys.last_value. The return value is a list of
152    strings, each ending in a newline.
153
154    Normally, the list contains a single string; however, for
155    SyntaxError exceptions, it contains several lines that (when
156    printed) display detailed information about where the syntax
157    error occurred.
158
159    The message indicating which exception occurred is always the last
160    string in the list.
161
162    """
163
164    # An instance should not have a meaningful value parameter, but
165    # sometimes does, particularly for string exceptions, such as
166    # >>> raise string1, string2  # deprecated
167    #
168    # Clear these out first because issubtype(string1, SyntaxError)
169    # would raise another exception and mask the original problem.
170    if (isinstance(etype, BaseException) or
171        isinstance(etype, types.InstanceType) or
172        etype is None or type(etype) is str):
173        return [_format_final_exc_line(etype, value)]
174
175    stype = etype.__name__
176
177    if not issubclass(etype, SyntaxError):
178        return [_format_final_exc_line(stype, value)]
179
180    # It was a syntax error; show exactly where the problem was found.
181    lines = []
182    try:
183        msg, (filename, lineno, offset, badline) = value.args
184    except Exception:
185        pass
186    else:
187        filename = filename or "<string>"
188        lines.append('  File "%s", line %d\n' % (filename, lineno))
189        if badline is not None:
190            lines.append('    %s\n' % badline.strip())
191            if offset is not None:
192                caretspace = badline.rstrip('\n')[:offset].lstrip()
193                # non-space whitespace (likes tabs) must be kept for alignment
194                caretspace = ((c.isspace() and c or ' ') for c in caretspace)
195                # only three spaces to account for offset1 == pos 0
196                lines.append('   %s^\n' % ''.join(caretspace))
197        value = msg
198
199    lines.append(_format_final_exc_line(stype, value))
200    return lines
201
202def _format_final_exc_line(etype, value):
203    """Return a list of a single line -- normal case for format_exception_only"""
204    valuestr = _some_str(value)
205    if value is None or not valuestr:
206        line = "%s\n" % etype
207    else:
208        line = "%s: %s\n" % (etype, valuestr)
209    return line
210
211def _some_str(value):
212    try:
213        return str(value)
214    except Exception:
215        pass
216    try:
217        value = unicode(value)
218        return value.encode("ascii", "backslashreplace")
219    except Exception:
220        pass
221    return '<unprintable %s object>' % type(value).__name__
222
223
224def print_exc(limit=None, file=None):
225    """Shorthand for 'print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback, limit, file)'.
226    (In fact, it uses sys.exc_info() to retrieve the same information
227    in a thread-safe way.)"""
228    if file is None:
229        file = sys.stderr
230    try:
231        etype, value, tb = sys.exc_info()
232        print_exception(etype, value, tb, limit, file)
233    finally:
234        etype = value = tb = None
235
236
237def format_exc(limit=None):
238    """Like print_exc() but return a string."""
239    try:
240        etype, value, tb = sys.exc_info()
241        return ''.join(format_exception(etype, value, tb, limit))
242    finally:
243        etype = value = tb = None
244
245
246def print_last(limit=None, file=None):
247    """This is a shorthand for 'print_exception(sys.last_type,
248    sys.last_value, sys.last_traceback, limit, file)'."""
249    if not hasattr(sys, "last_type"):
250        raise ValueError("no last exception")
251    if file is None:
252        file = sys.stderr
253    print_exception(sys.last_type, sys.last_value, sys.last_traceback,
254                    limit, file)
255
256
257def print_stack(f=None, limit=None, file=None):
258    """Print a stack trace from its invocation point.
259
260    The optional 'f' argument can be used to specify an alternate
261    stack frame at which to start. The optional 'limit' and 'file'
262    arguments have the same meaning as for print_exception().
263    """
264    if f is None:
265        try:
266            raise ZeroDivisionError
267        except ZeroDivisionError:
268            f = sys.exc_info()[2].tb_frame.f_back
269    print_list(extract_stack(f, limit), file)
270
271def format_stack(f=None, limit=None):
272    """Shorthand for 'format_list(extract_stack(f, limit))'."""
273    if f is None:
274        try:
275            raise ZeroDivisionError
276        except ZeroDivisionError:
277            f = sys.exc_info()[2].tb_frame.f_back
278    return format_list(extract_stack(f, limit))
279
280def extract_stack(f=None, limit = None):
281    """Extract the raw traceback from the current stack frame.
282
283    The return value has the same format as for extract_tb().  The
284    optional 'f' and 'limit' arguments have the same meaning as for
285    print_stack().  Each item in the list is a quadruple (filename,
286    line number, function name, text), and the entries are in order
287    from oldest to newest stack frame.
288    """
289    if f is None:
290        try:
291            raise ZeroDivisionError
292        except ZeroDivisionError:
293            f = sys.exc_info()[2].tb_frame.f_back
294    if limit is None:
295        if hasattr(sys, 'tracebacklimit'):
296            limit = sys.tracebacklimit
297    list = []
298    n = 0
299    while f is not None and (limit is None or n < limit):
300        lineno = f.f_lineno
301        co = f.f_code
302        filename = co.co_filename
303        name = co.co_name
304        linecache.checkcache(filename)
305        line = linecache.getline(filename, lineno, f.f_globals)
306        if line: line = line.strip()
307        else: line = None
308        list.append((filename, lineno, name, line))
309        f = f.f_back
310        n = n+1
311    list.reverse()
312    return list
313
314def tb_lineno(tb):
315    """Calculate correct line number of traceback given in tb.
316
317    Obsolete in 2.3.
318    """
319    return tb.tb_lineno
320