tryexcept.py 2.6 KB

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