greenlet_exceptions.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #ifndef GREENLET_EXCEPTIONS_HPP
  2. #define GREENLET_EXCEPTIONS_HPP
  3. #define PY_SSIZE_T_CLEAN
  4. #include <Python.h>
  5. #include <stdexcept>
  6. #include <string>
  7. #ifdef __clang__
  8. # pragma clang diagnostic push
  9. # pragma clang diagnostic ignored "-Wunused-function"
  10. #endif
  11. namespace greenlet {
  12. class PyErrOccurred : public std::runtime_error
  13. {
  14. public:
  15. PyErrOccurred() : std::runtime_error("")
  16. {
  17. assert(PyErr_Occurred());
  18. }
  19. PyErrOccurred(PyObject* exc_kind, const char* const msg)
  20. : std::runtime_error(msg)
  21. {
  22. PyErr_SetString(exc_kind, msg);
  23. }
  24. PyErrOccurred(PyObject* exc_kind, const std::string msg)
  25. : std::runtime_error(msg)
  26. {
  27. // This copies the c_str, so we don't have any lifetime
  28. // issues to worry about.
  29. PyErr_SetString(exc_kind, msg.c_str());
  30. }
  31. };
  32. class TypeError : public PyErrOccurred
  33. {
  34. public:
  35. TypeError(const char* const what)
  36. : PyErrOccurred(PyExc_TypeError, what)
  37. {
  38. }
  39. TypeError(const std::string what)
  40. : PyErrOccurred(PyExc_TypeError, what)
  41. {
  42. }
  43. };
  44. class ValueError : public PyErrOccurred
  45. {
  46. public:
  47. ValueError(const char* const what)
  48. : PyErrOccurred(PyExc_ValueError, what)
  49. {
  50. }
  51. };
  52. class AttributeError : public PyErrOccurred
  53. {
  54. public:
  55. AttributeError(const char* const what)
  56. : PyErrOccurred(PyExc_AttributeError, what)
  57. {
  58. }
  59. };
  60. /**
  61. * Calls `Py_FatalError` when constructed, so you can't actually
  62. * throw this. It just makes static analysis easier.
  63. */
  64. class PyFatalError : public std::runtime_error
  65. {
  66. public:
  67. PyFatalError(const char* const msg)
  68. : std::runtime_error(msg)
  69. {
  70. Py_FatalError(msg);
  71. }
  72. };
  73. static inline PyObject*
  74. Require(PyObject* p)
  75. {
  76. if (!p) {
  77. throw PyErrOccurred();
  78. }
  79. return p;
  80. };
  81. static inline void
  82. Require(const int retval)
  83. {
  84. if (retval < 0) {
  85. throw PyErrOccurred();
  86. }
  87. };
  88. };
  89. #ifdef __clang__
  90. # pragma clang diagnostic pop
  91. #endif
  92. #endif