_compat.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. from __future__ import absolute_import, division, print_function
  2. import types
  3. def format_exception_only(etype, value):
  4. """Format the exception part of a traceback.
  5. The arguments are the exception type and value such as given by
  6. sys.last_type and sys.last_value. The return value is a list of
  7. strings, each ending in a newline.
  8. Normally, the list contains a single string; however, for
  9. SyntaxError exceptions, it contains several lines that (when
  10. printed) display detailed information about where the syntax
  11. error occurred.
  12. The message indicating which exception occurred is always the last
  13. string in the list.
  14. """
  15. # An instance should not have a meaningful value parameter, but
  16. # sometimes does, particularly for string exceptions, such as
  17. # >>> raise string1, string2 # deprecated
  18. #
  19. # Clear these out first because issubtype(string1, SyntaxError)
  20. # would throw another exception and mask the original problem.
  21. if (isinstance(etype, BaseException) or
  22. isinstance(etype, types.InstanceType) or
  23. etype is None or type(etype) is str): # noqa: E129
  24. return [_format_final_exc_line(etype, value)]
  25. stype = etype.__name__
  26. if not issubclass(etype, SyntaxError):
  27. return [_format_final_exc_line(stype, value)]
  28. # It was a syntax error; show exactly where the problem was found.
  29. lines = []
  30. try:
  31. msg, (filename, lineno, offset, badline) = value.args
  32. except Exception:
  33. pass
  34. else:
  35. filename = filename or "<string>"
  36. lines.append(' File "%s", line %d\n' % (filename, lineno))
  37. if badline is not None:
  38. lines.append(' %s\n' % badline.strip())
  39. if offset is not None:
  40. caretspace = badline.rstrip('\n')[:offset].lstrip()
  41. # non-space whitespace (likes tabs) must be kept for alignment
  42. caretspace = ((c.isspace() and c or ' ') for c in caretspace)
  43. # only three spaces to account for offset1 == pos 0
  44. lines.append(' %s^\n' % ''.join(caretspace))
  45. value = msg
  46. lines.append(_format_final_exc_line(stype, value))
  47. return lines
  48. def _format_final_exc_line(etype, value):
  49. """Return a list of a single line -- normal case for format_exception_only"""
  50. valuestr = _some_str(value)
  51. if value is None or not valuestr:
  52. line = "%s\n" % etype
  53. else:
  54. line = "%s: %s\n" % (etype, valuestr)
  55. return line
  56. def _some_str(value):
  57. try:
  58. return str(value)
  59. except UnicodeError:
  60. try:
  61. value = unicode(value) # noqa: F821
  62. return value.encode('utf-8', 'replace')
  63. except Exception:
  64. pass
  65. return '<unprintable %s object>' % type(value).__name__