+++ /dev/null
-"""Extract, format and print information about Python stack traces."""\r
-\r
-import linecache\r
-import sys\r
-import types\r
-\r
-__all__ = ['extract_stack', 'extract_tb', 'format_exception',\r
- 'format_exception_only', 'format_list', 'format_stack',\r
- 'format_tb', 'print_exc', 'format_exc', 'print_exception',\r
- 'print_last', 'print_stack', 'print_tb', 'tb_lineno']\r
-\r
-def _print(file, str='', terminator='\n'):\r
- file.write(str+terminator)\r
-\r
-\r
-def print_list(extracted_list, file=None):\r
- """Print the list of tuples as returned by extract_tb() or\r
- extract_stack() as a formatted stack trace to the given file."""\r
- if file is None:\r
- file = sys.stderr\r
- for filename, lineno, name, line in extracted_list:\r
- _print(file,\r
- ' File "%s", line %d, in %s' % (filename,lineno,name))\r
- if line:\r
- _print(file, ' %s' % line.strip())\r
-\r
-def format_list(extracted_list):\r
- """Format a list of traceback entry tuples for printing.\r
-\r
- Given a list of tuples as returned by extract_tb() or\r
- extract_stack(), return a list of strings ready for printing.\r
- Each string in the resulting list corresponds to the item with the\r
- same index in the argument list. Each string ends in a newline;\r
- the strings may contain internal newlines as well, for those items\r
- whose source text line is not None.\r
- """\r
- list = []\r
- for filename, lineno, name, line in extracted_list:\r
- item = ' File "%s", line %d, in %s\n' % (filename,lineno,name)\r
- if line:\r
- item = item + ' %s\n' % line.strip()\r
- list.append(item)\r
- return list\r
-\r
-\r
-def print_tb(tb, limit=None, file=None):\r
- """Print up to 'limit' stack trace entries from the traceback 'tb'.\r
-\r
- If 'limit' is omitted or None, all entries are printed. If 'file'\r
- is omitted or None, the output goes to sys.stderr; otherwise\r
- 'file' should be an open file or file-like object with a write()\r
- method.\r
- """\r
- if file is None:\r
- file = sys.stderr\r
- if limit is None:\r
- if hasattr(sys, 'tracebacklimit'):\r
- limit = sys.tracebacklimit\r
- n = 0\r
- while tb is not None and (limit is None or n < limit):\r
- f = tb.tb_frame\r
- lineno = tb.tb_lineno\r
- co = f.f_code\r
- filename = co.co_filename\r
- name = co.co_name\r
- _print(file,\r
- ' File "%s", line %d, in %s' % (filename, lineno, name))\r
- linecache.checkcache(filename)\r
- line = linecache.getline(filename, lineno, f.f_globals)\r
- if line: _print(file, ' ' + line.strip())\r
- tb = tb.tb_next\r
- n = n+1\r
-\r
-def format_tb(tb, limit = None):\r
- """A shorthand for 'format_list(extract_tb(tb, limit))'."""\r
- return format_list(extract_tb(tb, limit))\r
-\r
-def extract_tb(tb, limit = None):\r
- """Return list of up to limit pre-processed entries from traceback.\r
-\r
- This is useful for alternate formatting of stack traces. If\r
- 'limit' is omitted or None, all entries are extracted. A\r
- pre-processed stack trace entry is a quadruple (filename, line\r
- number, function name, text) representing the information that is\r
- usually printed for a stack trace. The text is a string with\r
- leading and trailing whitespace stripped; if the source is not\r
- available it is None.\r
- """\r
- if limit is None:\r
- if hasattr(sys, 'tracebacklimit'):\r
- limit = sys.tracebacklimit\r
- list = []\r
- n = 0\r
- while tb is not None and (limit is None or n < limit):\r
- f = tb.tb_frame\r
- lineno = tb.tb_lineno\r
- co = f.f_code\r
- filename = co.co_filename\r
- name = co.co_name\r
- linecache.checkcache(filename)\r
- line = linecache.getline(filename, lineno, f.f_globals)\r
- if line: line = line.strip()\r
- else: line = None\r
- list.append((filename, lineno, name, line))\r
- tb = tb.tb_next\r
- n = n+1\r
- return list\r
-\r
-\r
-def print_exception(etype, value, tb, limit=None, file=None):\r
- """Print exception up to 'limit' stack trace entries from 'tb' to 'file'.\r
-\r
- This differs from print_tb() in the following ways: (1) if\r
- traceback is not None, it prints a header "Traceback (most recent\r
- call last):"; (2) it prints the exception type and value after the\r
- stack trace; (3) if type is SyntaxError and value has the\r
- appropriate format, it prints the line where the syntax error\r
- occurred with a caret on the next line indicating the approximate\r
- position of the error.\r
- """\r
- if file is None:\r
- file = sys.stderr\r
- if tb:\r
- _print(file, 'Traceback (most recent call last):')\r
- print_tb(tb, limit, file)\r
- lines = format_exception_only(etype, value)\r
- for line in lines:\r
- _print(file, line, '')\r
-\r
-def format_exception(etype, value, tb, limit = None):\r
- """Format a stack trace and the exception information.\r
-\r
- The arguments have the same meaning as the corresponding arguments\r
- to print_exception(). The return value is a list of strings, each\r
- ending in a newline and some containing internal newlines. When\r
- these lines are concatenated and printed, exactly the same text is\r
- printed as does print_exception().\r
- """\r
- if tb:\r
- list = ['Traceback (most recent call last):\n']\r
- list = list + format_tb(tb, limit)\r
- else:\r
- list = []\r
- list = list + format_exception_only(etype, value)\r
- return list\r
-\r
-def format_exception_only(etype, value):\r
- """Format the exception part of a traceback.\r
-\r
- The arguments are the exception type and value such as given by\r
- sys.last_type and sys.last_value. The return value is a list of\r
- strings, each ending in a newline.\r
-\r
- Normally, the list contains a single string; however, for\r
- SyntaxError exceptions, it contains several lines that (when\r
- printed) display detailed information about where the syntax\r
- error occurred.\r
-\r
- The message indicating which exception occurred is always the last\r
- string in the list.\r
-\r
- """\r
-\r
- # An instance should not have a meaningful value parameter, but\r
- # sometimes does, particularly for string exceptions, such as\r
- # >>> raise string1, string2 # deprecated\r
- #\r
- # Clear these out first because issubtype(string1, SyntaxError)\r
- # would raise another exception and mask the original problem.\r
- if (isinstance(etype, BaseException) or\r
- isinstance(etype, types.InstanceType) or\r
- etype is None or type(etype) is str):\r
- return [_format_final_exc_line(etype, value)]\r
-\r
- stype = etype.__name__\r
-\r
- if not issubclass(etype, SyntaxError):\r
- return [_format_final_exc_line(stype, value)]\r
-\r
- # It was a syntax error; show exactly where the problem was found.\r
- lines = []\r
- try:\r
- msg, (filename, lineno, offset, badline) = value.args\r
- except Exception:\r
- pass\r
- else:\r
- filename = filename or "<string>"\r
- lines.append(' File "%s", line %d\n' % (filename, lineno))\r
- if badline is not None:\r
- lines.append(' %s\n' % badline.strip())\r
- if offset is not None:\r
- caretspace = badline.rstrip('\n')\r
- offset = min(len(caretspace), offset) - 1\r
- caretspace = caretspace[:offset].lstrip()\r
- # non-space whitespace (likes tabs) must be kept for alignment\r
- caretspace = ((c.isspace() and c or ' ') for c in caretspace)\r
- lines.append(' %s^\n' % ''.join(caretspace))\r
- value = msg\r
-\r
- lines.append(_format_final_exc_line(stype, value))\r
- return lines\r
-\r
-def _format_final_exc_line(etype, value):\r
- """Return a list of a single line -- normal case for format_exception_only"""\r
- valuestr = _some_str(value)\r
- if value is None or not valuestr:\r
- line = "%s\n" % etype\r
- else:\r
- line = "%s: %s\n" % (etype, valuestr)\r
- return line\r
-\r
-def _some_str(value):\r
- try:\r
- return str(value)\r
- except Exception:\r
- pass\r
- try:\r
- value = unicode(value)\r
- return value.encode("ascii", "backslashreplace")\r
- except Exception:\r
- pass\r
- return '<unprintable %s object>' % type(value).__name__\r
-\r
-\r
-def print_exc(limit=None, file=None):\r
- """Shorthand for 'print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback, limit, file)'.\r
- (In fact, it uses sys.exc_info() to retrieve the same information\r
- in a thread-safe way.)"""\r
- if file is None:\r
- file = sys.stderr\r
- try:\r
- etype, value, tb = sys.exc_info()\r
- print_exception(etype, value, tb, limit, file)\r
- finally:\r
- etype = value = tb = None\r
-\r
-\r
-def format_exc(limit=None):\r
- """Like print_exc() but return a string."""\r
- try:\r
- etype, value, tb = sys.exc_info()\r
- return ''.join(format_exception(etype, value, tb, limit))\r
- finally:\r
- etype = value = tb = None\r
-\r
-\r
-def print_last(limit=None, file=None):\r
- """This is a shorthand for 'print_exception(sys.last_type,\r
- sys.last_value, sys.last_traceback, limit, file)'."""\r
- if not hasattr(sys, "last_type"):\r
- raise ValueError("no last exception")\r
- if file is None:\r
- file = sys.stderr\r
- print_exception(sys.last_type, sys.last_value, sys.last_traceback,\r
- limit, file)\r
-\r
-\r
-def print_stack(f=None, limit=None, file=None):\r
- """Print a stack trace from its invocation point.\r
-\r
- The optional 'f' argument can be used to specify an alternate\r
- stack frame at which to start. The optional 'limit' and 'file'\r
- arguments have the same meaning as for print_exception().\r
- """\r
- if f is None:\r
- try:\r
- raise ZeroDivisionError\r
- except ZeroDivisionError:\r
- f = sys.exc_info()[2].tb_frame.f_back\r
- print_list(extract_stack(f, limit), file)\r
-\r
-def format_stack(f=None, limit=None):\r
- """Shorthand for 'format_list(extract_stack(f, limit))'."""\r
- if f is None:\r
- try:\r
- raise ZeroDivisionError\r
- except ZeroDivisionError:\r
- f = sys.exc_info()[2].tb_frame.f_back\r
- return format_list(extract_stack(f, limit))\r
-\r
-def extract_stack(f=None, limit = None):\r
- """Extract the raw traceback from the current stack frame.\r
-\r
- The return value has the same format as for extract_tb(). The\r
- optional 'f' and 'limit' arguments have the same meaning as for\r
- print_stack(). Each item in the list is a quadruple (filename,\r
- line number, function name, text), and the entries are in order\r
- from oldest to newest stack frame.\r
- """\r
- if f is None:\r
- try:\r
- raise ZeroDivisionError\r
- except ZeroDivisionError:\r
- f = sys.exc_info()[2].tb_frame.f_back\r
- if limit is None:\r
- if hasattr(sys, 'tracebacklimit'):\r
- limit = sys.tracebacklimit\r
- list = []\r
- n = 0\r
- while f is not None and (limit is None or n < limit):\r
- lineno = f.f_lineno\r
- co = f.f_code\r
- filename = co.co_filename\r
- name = co.co_name\r
- linecache.checkcache(filename)\r
- line = linecache.getline(filename, lineno, f.f_globals)\r
- if line: line = line.strip()\r
- else: line = None\r
- list.append((filename, lineno, name, line))\r
- f = f.f_back\r
- n = n+1\r
- list.reverse()\r
- return list\r
-\r
-def tb_lineno(tb):\r
- """Calculate correct line number of traceback given in tb.\r
-\r
- Obsolete in 2.3.\r
- """\r
- return tb.tb_lineno\r