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