exc_ops.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. """Exception-related primitive ops."""
  2. from __future__ import annotations
  3. from mypyc.ir.ops import ERR_ALWAYS, ERR_FALSE, ERR_NEVER
  4. from mypyc.ir.rtypes import bit_rprimitive, exc_rtuple, object_rprimitive, void_rtype
  5. from mypyc.primitives.registry import custom_op
  6. # If the argument is a class, raise an instance of the class. Otherwise, assume
  7. # that the argument is an exception object, and raise it.
  8. raise_exception_op = custom_op(
  9. arg_types=[object_rprimitive],
  10. return_type=void_rtype,
  11. c_function_name="CPy_Raise",
  12. error_kind=ERR_ALWAYS,
  13. )
  14. # Raise StopIteration exception with the specified value (which can be NULL).
  15. set_stop_iteration_value = custom_op(
  16. arg_types=[object_rprimitive],
  17. return_type=void_rtype,
  18. c_function_name="CPyGen_SetStopIterationValue",
  19. error_kind=ERR_ALWAYS,
  20. )
  21. # Raise exception with traceback.
  22. # Arguments are (exception type, exception value, traceback).
  23. raise_exception_with_tb_op = custom_op(
  24. arg_types=[object_rprimitive, object_rprimitive, object_rprimitive],
  25. return_type=void_rtype,
  26. c_function_name="CPyErr_SetObjectAndTraceback",
  27. error_kind=ERR_ALWAYS,
  28. )
  29. # Reraise the currently raised exception.
  30. reraise_exception_op = custom_op(
  31. arg_types=[], return_type=void_rtype, c_function_name="CPy_Reraise", error_kind=ERR_ALWAYS
  32. )
  33. # Propagate exception if the CPython error indicator is set (an exception was raised).
  34. no_err_occurred_op = custom_op(
  35. arg_types=[],
  36. return_type=bit_rprimitive,
  37. c_function_name="CPy_NoErrOccured",
  38. error_kind=ERR_FALSE,
  39. )
  40. err_occurred_op = custom_op(
  41. arg_types=[],
  42. return_type=object_rprimitive,
  43. c_function_name="PyErr_Occurred",
  44. error_kind=ERR_NEVER,
  45. is_borrowed=True,
  46. )
  47. # Keep propagating a raised exception by unconditionally giving an error value.
  48. # This doesn't actually raise an exception.
  49. keep_propagating_op = custom_op(
  50. arg_types=[],
  51. return_type=bit_rprimitive,
  52. c_function_name="CPy_KeepPropagating",
  53. error_kind=ERR_FALSE,
  54. )
  55. # Catches a propagating exception and makes it the "currently
  56. # handled exception" (by sticking it into sys.exc_info()). Returns the
  57. # exception that was previously being handled, which must be restored
  58. # later.
  59. error_catch_op = custom_op(
  60. arg_types=[], return_type=exc_rtuple, c_function_name="CPy_CatchError", error_kind=ERR_NEVER
  61. )
  62. # Restore an old "currently handled exception" returned from.
  63. # error_catch (by sticking it into sys.exc_info())
  64. restore_exc_info_op = custom_op(
  65. arg_types=[exc_rtuple],
  66. return_type=void_rtype,
  67. c_function_name="CPy_RestoreExcInfo",
  68. error_kind=ERR_NEVER,
  69. )
  70. # Checks whether the exception currently being handled matches a particular type.
  71. exc_matches_op = custom_op(
  72. arg_types=[object_rprimitive],
  73. return_type=bit_rprimitive,
  74. c_function_name="CPy_ExceptionMatches",
  75. error_kind=ERR_NEVER,
  76. )
  77. # Get the value of the exception currently being handled.
  78. get_exc_value_op = custom_op(
  79. arg_types=[],
  80. return_type=object_rprimitive,
  81. c_function_name="CPy_GetExcValue",
  82. error_kind=ERR_NEVER,
  83. )
  84. # Get exception info (exception type, exception instance, traceback object).
  85. get_exc_info_op = custom_op(
  86. arg_types=[], return_type=exc_rtuple, c_function_name="CPy_GetExcInfo", error_kind=ERR_NEVER
  87. )