test_throw.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import sys
  2. from greenlet import greenlet
  3. from . import TestCase
  4. def switch(*args):
  5. return greenlet.getcurrent().parent.switch(*args)
  6. class ThrowTests(TestCase):
  7. def test_class(self):
  8. def f():
  9. try:
  10. switch("ok")
  11. except RuntimeError:
  12. switch("ok")
  13. return
  14. switch("fail")
  15. g = greenlet(f)
  16. res = g.switch()
  17. self.assertEqual(res, "ok")
  18. res = g.throw(RuntimeError)
  19. self.assertEqual(res, "ok")
  20. def test_val(self):
  21. def f():
  22. try:
  23. switch("ok")
  24. except RuntimeError:
  25. val = sys.exc_info()[1]
  26. if str(val) == "ciao":
  27. switch("ok")
  28. return
  29. switch("fail")
  30. g = greenlet(f)
  31. res = g.switch()
  32. self.assertEqual(res, "ok")
  33. res = g.throw(RuntimeError("ciao"))
  34. self.assertEqual(res, "ok")
  35. g = greenlet(f)
  36. res = g.switch()
  37. self.assertEqual(res, "ok")
  38. res = g.throw(RuntimeError, "ciao")
  39. self.assertEqual(res, "ok")
  40. def test_kill(self):
  41. def f():
  42. switch("ok")
  43. switch("fail")
  44. g = greenlet(f)
  45. res = g.switch()
  46. self.assertEqual(res, "ok")
  47. res = g.throw()
  48. self.assertTrue(isinstance(res, greenlet.GreenletExit))
  49. self.assertTrue(g.dead)
  50. res = g.throw() # immediately eaten by the already-dead greenlet
  51. self.assertTrue(isinstance(res, greenlet.GreenletExit))
  52. def test_throw_goes_to_original_parent(self):
  53. main = greenlet.getcurrent()
  54. def f1():
  55. try:
  56. main.switch("f1 ready to catch")
  57. except IndexError:
  58. return "caught"
  59. else:
  60. return "normal exit"
  61. def f2():
  62. main.switch("from f2")
  63. g1 = greenlet(f1)
  64. g2 = greenlet(f2, parent=g1)
  65. with self.assertRaises(IndexError):
  66. g2.throw(IndexError)
  67. self.assertTrue(g2.dead)
  68. self.assertTrue(g1.dead)
  69. g1 = greenlet(f1)
  70. g2 = greenlet(f2, parent=g1)
  71. res = g1.switch()
  72. self.assertEqual(res, "f1 ready to catch")
  73. res = g2.throw(IndexError)
  74. self.assertEqual(res, "caught")
  75. self.assertTrue(g2.dead)
  76. self.assertTrue(g1.dead)
  77. g1 = greenlet(f1)
  78. g2 = greenlet(f2, parent=g1)
  79. res = g1.switch()
  80. self.assertEqual(res, "f1 ready to catch")
  81. res = g2.switch()
  82. self.assertEqual(res, "from f2")
  83. res = g2.throw(IndexError)
  84. self.assertEqual(res, "caught")
  85. self.assertTrue(g2.dead)
  86. self.assertTrue(g1.dead)
  87. def test_non_traceback_param(self):
  88. with self.assertRaises(TypeError) as exc:
  89. greenlet.getcurrent().throw(
  90. Exception,
  91. Exception(),
  92. self
  93. )
  94. self.assertEqual(str(exc.exception),
  95. "throw() third argument must be a traceback object")
  96. def test_instance_of_wrong_type(self):
  97. with self.assertRaises(TypeError) as exc:
  98. greenlet.getcurrent().throw(
  99. Exception(),
  100. BaseException()
  101. )
  102. self.assertEqual(str(exc.exception),
  103. "instance exception may not have a separate value")
  104. def test_not_throwable(self):
  105. with self.assertRaises(TypeError) as exc:
  106. greenlet.getcurrent().throw(
  107. "abc"
  108. )
  109. self.assertEqual(str(exc.exception),
  110. "exceptions must be classes, or instances, not str")