codekingpro/portable-devtools
114k
1"""
2Testing initialstub throwing an already started exception.
3"""
4
5import greenlet
6
7a = None
8b = None
9c = None
10main = greenlet.getcurrent()
11
12# If we switch into a dead greenlet,
13# we go looking for its parents.
14# if a parent is not yet started, we start it.
15
16results = []
17
18def a_run(*args):
19 #results.append('A')
20 results.append(('Begin A', args))
21
22
23def c_run():
24 results.append('Begin C')
25 b.switch('From C')
26 results.append('C done')
27
28class A(greenlet.greenlet): pass
29
30class B(greenlet.greenlet):
31 doing_it = False
32 def __getattribute__(self, name):
33 if name == 'run' and not self.doing_it:
34 assert greenlet.getcurrent() is c
35 self.doing_it = True
36 results.append('Switch to b from B.__getattribute__ in '
37 + type(greenlet.getcurrent()).__name__)
38 b.switch()
39 results.append('B.__getattribute__ back from main in '
40 + type(greenlet.getcurrent()).__name__)
41 if name == 'run':
42 name = '_B_run'
43 return object.__getattribute__(self, name)
44
45 def _B_run(self, *arg):
46 results.append(('Begin B', arg))
47 results.append('_B_run switching to main')
48 main.switch('From B')
49
50class C(greenlet.greenlet):
51 pass
52a = A(a_run)
53b = B(parent=a)
54c = C(c_run, b)
55
56# Start a child; while running, it will start B,
57# but starting B will ALSO start B.
58result = c.switch()
59results.append(('main from c', result))
60
61# Switch back to C, which was in the middle of switching
62# already. This will throw the ``GreenletStartedWhileInPython``
63# exception, which results in parent A getting started (B is finished)
64c.switch()
65
66results.append(('A dead?', a.dead, 'B dead?', b.dead, 'C dead?', c.dead))
67
68# A and B should both be dead now.
69assert a.dead
70assert b.dead
71assert not c.dead
72
73result = c.switch()
74results.append(('main from c.2', result))
75# Now C is dead
76assert c.dead
77
78print("RESULTS:", results)
79 