print_exception.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import sys
  2. try:
  3. try:
  4. import uio as io
  5. except ImportError:
  6. import io
  7. except ImportError:
  8. print("SKIP")
  9. raise SystemExit
  10. if hasattr(sys, 'print_exception'):
  11. print_exception = sys.print_exception
  12. else:
  13. import traceback
  14. print_exception = lambda e, f: traceback.print_exception(None, e, sys.exc_info()[2], file=f)
  15. def print_exc(e):
  16. buf = io.StringIO()
  17. print_exception(e, buf)
  18. s = buf.getvalue()
  19. for l in s.split("\n"):
  20. # uPy on pyboard prints <stdin> as file, so remove filename.
  21. if l.startswith(" File "):
  22. l = l.split('"')
  23. print(l[0], l[2])
  24. # uPy and CPy tracebacks differ in that CPy prints a source line for
  25. # each traceback entry. In this case, we know that offending line
  26. # has 4-space indent, so filter it out.
  27. elif not l.startswith(" "):
  28. print(l)
  29. # basic exception message
  30. try:
  31. 1/0
  32. except Exception as e:
  33. print('caught')
  34. print_exc(e)
  35. # exception message with more than 1 source-code line
  36. def f():
  37. g()
  38. def g():
  39. 2/0
  40. try:
  41. f()
  42. except Exception as e:
  43. print('caught')
  44. print_exc(e)
  45. # Here we have a function with lots of bytecode generated for a single source-line, and
  46. # there is an error right at the end of the bytecode. It should report the correct line.
  47. def f():
  48. f([1, 2], [1, 2], [1, 2], {1:1, 1:1, 1:1, 1:1, 1:1, 1:1, 1:X})
  49. return 1
  50. try:
  51. f()
  52. except Exception as e:
  53. print_exc(e)
  54. # Test non-stream object passed as output object, only valid for uPy
  55. if hasattr(sys, 'print_exception'):
  56. try:
  57. sys.print_exception(Exception, 1)
  58. had_exception = False
  59. except OSError:
  60. had_exception = True
  61. assert had_exception