tryexcept.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. # Copyright (c) 2020 Rocky Bernstein
  2. def tryexcept(self, lhs, n, rule, ast, tokens, first, last):
  3. come_from_except = ast[-1]
  4. if rule in (
  5. (
  6. "try_except",
  7. (
  8. "SETUP_EXCEPT",
  9. "suite_stmts_opt",
  10. "POP_BLOCK",
  11. "except_handler",
  12. "opt_come_from_except",
  13. ),
  14. ),
  15. (
  16. "c_try_except",
  17. (
  18. "SETUP_EXCEPT",
  19. "c_suite_stmts",
  20. "POP_BLOCK",
  21. "c_except_handler",
  22. "opt_come_from_except",
  23. ),
  24. ),
  25. ):
  26. if come_from_except[0] == "COME_FROM":
  27. # There should be at least two COME_FROMs, one from an
  28. # exception handler and one from the try. Otherwise
  29. # we have a try/else.
  30. return True
  31. pass
  32. elif rule == (
  33. "try_except",
  34. (
  35. "SETUP_EXCEPT",
  36. "suite_stmts_opt",
  37. "POP_BLOCK",
  38. "except_handler",
  39. "\\e_opt_come_from_except",
  40. ),
  41. ):
  42. # Find END_FINALLY.
  43. for i in range(last, first, -1):
  44. if tokens[i] == "END_FINALLY":
  45. jump_before_finally = tokens[i - 1]
  46. if jump_before_finally.kind.startswith("JUMP"):
  47. if jump_before_finally == "JUMP_FORWARD":
  48. # If there is a JUMP_FORWARD before
  49. # the END_FINALLY to some jumps place
  50. # beyond tokens[last].off2int() then
  51. # this is a try/else rather than an
  52. # try (no else).
  53. return tokens[i - 1].attr > tokens[last].off2int(
  54. prefer_last=True
  55. )
  56. elif jump_before_finally == "JUMP_LOOP":
  57. # If there is a JUMP_LOOP before the
  58. # END_FINALLY then this is a looping
  59. # jump, but then jumps in the except
  60. # handlers have to also be a looping
  61. # jump or this is a try/else rather
  62. # than an try (no else).
  63. except_handler = ast[3]
  64. if (
  65. except_handler == "except_handler"
  66. and except_handler[0] == "JUMP_FORWARD"
  67. ):
  68. return True
  69. return False
  70. pass
  71. pass
  72. pass
  73. return False