def testTempval(self): def Worker(items): items.append(stackless.schedule()) items.append(stackless.schedule(None)) items.append(stackless.schedule('foo')) items.append(stackless.schedule(42)) items = [] tasklet_obj = stackless.tasklet(Worker)(items) self.assertEqual(None, tasklet_obj.tempval) self.assertEqual([], items) stackless.current.tempval = 5 self.assertEqual(stackless.getcurrent(), stackless.schedule()) self.assertEqual(None, stackless.current.tempval) self.assertEqual(tasklet_obj, tasklet_obj.tempval) self.assertEqual([], items) stackless.schedule() self.assertEqual(None, tasklet_obj.tempval) self.assertEqual([tasklet_obj], items) stackless.schedule() self.assertEqual('foo', tasklet_obj.tempval) self.assertEqual([tasklet_obj, None], items) tasklet_obj.tempval = False stackless.schedule() self.assertEqual([tasklet_obj, None, False], items) self.assertEqual(42, tasklet_obj.tempval) stackless.schedule() self.assertEqual([tasklet_obj, None, False, 42], items) # Upon TaskletExit. self.assertEqual(None, tasklet_obj.tempval) self.assertEqual(1, stackless.getruncount()) self.assertEqual(stackless.getcurrent(), stackless.schedule()) self.assertEqual(None, stackless.current.tempval) self.assertEqual(43, stackless.schedule(43)) # This seems to be a strange Stackless quirk, this should be 43. self.assertEqual(None, stackless.getcurrent().tempval) self.assertEqual(54, stackless.schedule_remove(54)) self.assertEqual(None, stackless.current.tempval) def Worker2(items, main_tasklet): items.append(stackless.getcurrent().tempval) items.append(stackless.schedule(44)) items.append(stackless.current.tempval) main_tasklet.insert() del items[:] stackless.tasklet(Worker2)(items, stackless.getcurrent()) self.assertEqual(55, stackless.schedule_remove(55)) self.assertEqual(None, stackless.current.tempval) self.assertEqual([None, 44, None], items) self.assertRaisesStr(AssertionError, '', stackless.schedule, stackless.bomb(AssertionError)) self.assertRaisesStr(AssertionError, 'foo', stackless.schedule, stackless.bomb(AssertionError, 'foo'))
def _doRemoteError(self, fault): try: ntype, value = fault.type, fault.value if isinstance(value, ntype): b = bomb(ntype, value) else: b = bomb(ntype, ntype(value)) b.raise_() except Exception, e: self._status = FutureResult.STATUS_ERROR self._exception = e ftlog.error()
def SendException(tasklet, exc_info): """Send exception to tasklet, even if it's blocked on a channel. To get the tasklet is activated (to handle the exception) after SendException, call tasklet.run() after calling SendException. tasklet.insert() is called automatically to ensure that it eventually gets scheduled. """ if not isinstance(exc_info, list) and not isinstance(exc_info, tuple): raise TypeError if tasklet == stackless.current: if len(exc_info) < 3: exc_info = list(exc_info) + [None, None] raise exc_info[0], exc_info[1], exc_info[2] bomb = stackless.bomb(*exc_info) if tasklet.blocked: c = tasklet._channel old_preference = c.preference c.preference = 1 # Prefer the sender. for i in xrange(-c.balance): c.send(bomb) c.preference = old_preference else: tasklet.tempval = bomb tasklet.insert()
def send_exception_nowait(self, ntype, value): if self.balance == 0: self.exc = (ntype, value) else: if isinstance(value, ntype): self.send(bomb(ntype, value)) else: self.send_exception(ntype, value)
def send_exception_nowait(self, exp_type, exp_value): if self.balance == 0: self.exc = (exp_type, exp_value) else: if isinstance(exp_value, exp_type): self.send(stackless.bomb(exp_type, exp_value)) else: self.send_exception(exp_type, exp_value)
def test_bomb(self): try: 1/0 except: import sys b = stackless.bomb(*sys.exc_info()) assert b.type is ZeroDivisionError assert str(b.value).startswith('integer division') assert b.traceback is not None
def test_bomb(self): try: 1 / 0 except: import sys b = stackless.bomb(*sys.exc_info()) assert b.type is ZeroDivisionError assert str(b.value).startswith('integer division') assert b.traceback is not None
def send_exception_noblock(self, ntype, value): ''' send exception in non-block style :param ntype: subclass of BaseException :param value: class instance or parameters :return: void ''' if self.balance == 0: self.nbQueue.append((1, ntype, value)) else: assert issubclass(ntype,BaseException) if isinstance(value, ntype): self.send(stackless.bomb(ntype, value)) else: self.send_exception(ntype, value)
def throw(self, typ=None, val=None, tb=None): global current if not typ: typ = GreenletExit target = self del self # Save memory and drop reference. while True: # This logic is tested in GreenletTest.testThrow. if not target.dead: if target._tasklet: break target.dead = True target.__dict__.pop('run', None) # Keep methods of subclasses. if issubclass(typ, GreenletExit): # This is tested by GreenletUsingStacklesstest.testParentOnKill. apply_args = [(target.parent.switch, (typ(val),))] del target, typ, val, tb # Save memory and drop reference. return apply(*apply_args.pop()) target = target.parent if target is current: raise typ, val, tb target._tasklet.tempval = stackless.bomb(typ, val, tb) del typ, val, tb # Save memory and drop reference. # Don't call target.switch, it might be overridden in a subclass. # The following code is duplicated between .switch() and .throw(), but # it would be too slow to refactor to a function because of the extra # references to `target'. current = target target = [target._tasklet.remove().run] try: retval = target.pop()() except TaskletExit: return _handle_tasklet_exit_in_switch(*sys.exc_info()) except: stackless.current.next.remove() assert current._tasklet is stackless.current raise stackless.current.next.remove() assert current._tasklet is stackless.current return retval
def throw(self, typ=None, val=None, tb=None): global current if not typ: typ = GreenletExit target = self del self # Save memory and drop reference. while True: # This logic is tested in GreenletTest.testThrow. if not target.dead: if target._tasklet: break target.dead = True target.__dict__.pop('run', None) # Keep methods of subclasses. if issubclass(typ, GreenletExit): # This is tested by GreenletUsingStacklesstest.testParentOnKill. apply_args = [(target.parent.switch, (typ(val), ))] del target, typ, val, tb # Save memory and drop reference. return apply(*apply_args.pop()) target = target.parent if target is current: raise typ, val, tb target._tasklet.tempval = stackless.bomb(typ, val, tb) del typ, val, tb # Save memory and drop reference. # Don't call target.switch, it might be overridden in a subclass. # The following code is duplicated between .switch() and .throw(), but # it would be too slow to refactor to a function because of the extra # references to `target'. current = target target = [target._tasklet.remove().run] try: retval = target.pop()() except TaskletExit: return _handle_tasklet_exit_in_switch(*sys.exc_info()) except: stackless.current.next.remove() assert current._tasklet is stackless.current raise stackless.current.next.remove() assert current._tasklet is stackless.current return retval
def Bomber(tasklet_obj, msg): tasklet_obj.tempval = stackless.bomb(AssertionError, msg)
def SendBomb(): assert c.send(stackless.bomb(typ, val, tb1)) is None
target._tasklet.tempval = e except TaskletExit, e: # This doesn't happen with gevent in a worker greenlet, because the # exception handler in the hub (gevent.core.__event_handler) stops the # TaskletExit from propagating. # Still true (but del'ed above): assert greenlet_obj is current target = current.parent while target.dead: target = target.parent if target._tasklet is None: _first_switch(target, e) else: target._tasklet.tempval = e except: # Still true (but del'ed above): assert greenlet_obj is current bomb_obj = stackless.bomb(*sys.exc_info()) target = current.parent while True: # This logic is tested in GreenletTest.testThrow. if not target.dead: if target._tasklet: break # This is tested in greenlet5 of GreenletTest.testSwitchToParent. target.dead = True target.__dict__.pop('run', None) # Keep methods of subclasses. target = target.parent target._tasklet.tempval = bomb_obj del bomb_obj # Save memory. if getattr(current, '_is_revived', False): current.dead = True # Not inserting the placeholder, because the parent wouldn't remove it. _insert_after_current_tasklet(target._tasklet)
def testStackless(self): events = [] def Divide(a, b): return a / b def Worker(name, c): while True: events.append(name + '.wait') events.append('%s/%s' % (name, c.receive())) def Single(name): events.append(name + '.single') def Cooperative(name): while True: events.append(name + '.coop') stackless.schedule() def CooperativeRemove(name): while True: events.append(name + '.corm') stackless.schedule_remove() def Run(): while True: events.append('schedule') i = len(events) stackless.schedule() if i == len(events): break events.append('done') c = stackless.channel() self.assertTrue(stackless.current is stackless.getmain()) self.assertTrue(stackless.getcurrent() is stackless.main) self.assertEqual(1, stackless.getruncount()) self.assertTrue(stackless.current is stackless.getcurrent().next) self.assertTrue(stackless.current is stackless.getcurrent().prev) ta = stackless.tasklet(Worker)('A', c) tb = stackless.tasklet(Worker)('B', c) tc = stackless.tasklet(Worker)('C', c) td = stackless.tasklet().bind(Worker)('D', c) self.assertEqual(5, stackless.getruncount()) self.assertTrue(td is stackless.current.prev) self.assertTrue(ta is stackless.getcurrent().next) self.assertTrue(td.next is stackless.current) self.assertTrue(td.prev is tc) self.assertEqual(c.preference, -1) self.assertEqual(c.balance, 0) del events[:] events.append('send') self.assertEqual(5, stackless.getruncount()) self.assertEqual(None, c.send('msg')) self.assertEqual(1, stackless.getruncount()) Run() self.assertEqual( ' '.join(events), 'send A.wait A/msg A.wait B.wait C.wait D.wait schedule done') self.assertEqual(c.preference, -1) self.assertEqual(c.balance, -4) del events[:] events.append('send') c.preference = 0 # same as c.preference = 1 self.assertEqual(1, stackless.getruncount()) self.assertEqual(None, c.send('msg')) self.assertEqual(2, stackless.getruncount()) Run() #print ' '.join(events) self.assertEqual(' '.join(events), 'send schedule A/msg A.wait schedule done') self.assertEqual(c.preference, 0) self.assertEqual(c.balance, -4) del events[:] c.preference = 1 events.append('send') self.assertEqual(1, stackless.getruncount()) self.assertEqual(None, c.send('msg')) self.assertEqual(2, stackless.getruncount()) Run() self.assertEqual(' '.join(events), 'send schedule B/msg B.wait schedule done') self.assertEqual(c.preference, 1) del events[:] c.preference = 2 # same as c.preference = 1 events.append('send') self.assertEqual(1, stackless.getruncount()) self.assertEqual(None, c.send('msg')) self.assertEqual(None, c.send('msg')) self.assertEqual(3, stackless.getruncount()) Run() self.assertEqual( ' '.join(events), 'send schedule C/msg C.wait D/msg D.wait schedule done') # Now the doubly-linked list is (d, main, a, b, c). Why? self.assertEqual(c.balance, -4) del events[:] c.preference = 5 events.append('send') self.assertEqual(c.balance, -4) self.assertEqual(1, stackless.getruncount()) t = stackless.tasklet(Single) self.assertEqual(1, stackless.getruncount()) self.assertTrue(t is t('T')) self.assertEqual(2, stackless.getruncount()) t.remove() self.assertEqual(1, stackless.getruncount()) self.assertEqual(t, t.insert()) self.assertEqual(2, stackless.getruncount()) self.assertEqual(None, c.send('msg1')) self.assertEqual(c.balance, -3) self.assertEqual(None, c.send('msg2')) self.assertEqual(None, c.send('msg3')) self.assertEqual(None, c.send('msg4')) self.assertEqual(6, stackless.getruncount()) events.append('a4') self.assertEqual(c.balance, 0) self.assertEqual(None, c.send('msg5')) self.assertEqual(5, stackless.getruncount()) events.append('a5') self.assertEqual(None, c.send('msg6')) self.assertEqual(5, stackless.getruncount()) Run() self.assertEqual( ' '.join(events), 'send a4 T.single A/msg1 A.wait a5 B/msg2 B.wait schedule C/msg3 C.wait D/msg4 D.wait A/msg5 A.wait B/msg6 B.wait schedule done' ) self.assertTrue(stackless.getcurrent() is stackless.current.next) self.assertTrue(stackless.getcurrent() is stackless.current.prev) del events[:] self.assertEqual(c.balance, -4) c.preference = 42 self.assertEqual(None, c.send('msg1')) self.assertEqual(c.balance, -3) self.assertTrue(tc is stackless.getcurrent().next) self.assertTrue(tc is stackless.current.prev) self.assertTrue(tc.prev is stackless.getcurrent()) self.assertTrue(tc.next is stackless.current) self.assertEqual(None, c.send('msg2')) self.assertEqual(c.balance, -2) self.assertTrue(tc is stackless.getcurrent().next) self.assertTrue(td is stackless.current.prev) self.assertTrue(td.next is stackless.getcurrent()) self.assertTrue(td.prev is tc) self.assertEqual(None, c.send('msg3')) self.assertEqual(c.balance, -1) self.assertTrue(tc is stackless.current.next) self.assertTrue(ta is stackless.getcurrent().prev) self.assertTrue(ta.next is stackless.current) self.assertTrue(ta.prev is td) self.assertEqual(' '.join(events), '') self.assertEqual(4, stackless.getruncount()) t = stackless.tasklet(Single)('T') self.assertTrue(t is stackless.getcurrent().prev) self.assertTrue(ta is t.prev) self.assertTrue(t.alive) self.assertEqual(5, stackless.getruncount()) t.remove() #self.assertTrue(t.next is None # NotImplementedError in greenstackless) self.assertTrue(ta is stackless.current.prev) self.assertTrue(t.alive) self.assertEqual(4, stackless.getruncount()) t.run() self.assertEqual(4, stackless.getruncount()) self.assertTrue(not t.alive) self.assertEqual(' '.join(events), 'T.single') del events[:] td.run() self.assertEqual(' '.join(events), 'D/msg2 D.wait A/msg3 A.wait') del events[:] self.assertEqual(c.balance, -3) self.assertTrue(tc is stackless.getcurrent().next) self.assertTrue(tc is stackless.current.prev) self.assertTrue(tc.prev is stackless.getcurrent()) self.assertTrue(tc.next is stackless.current) tc.run() self.assertEqual(' '.join(events), 'C/msg1 C.wait') del events[:] self.assertEqual(c.balance, -4) self.assertTrue(stackless.getcurrent() is stackless.current.next) self.assertTrue(stackless.getcurrent() is stackless.current.prev) t = stackless.tasklet(Cooperative)('T') r = stackless.tasklet(CooperativeRemove)('R') u = stackless.tasklet(Cooperative)('U') self.assertEqual(4, stackless.getruncount()) del events[:] stackless.schedule() self.assertEqual(' '.join(events), 'T.coop R.corm U.coop') self.assertEqual(3, stackless.getruncount()) del events[:] stackless.schedule() self.assertEqual(' '.join(events), 'T.coop U.coop') self.assertEqual(3, stackless.getruncount()) del events[:] t.kill() # This involves t.run(), so u gets run as well. self.assertEqual(' '.join(events), 'U.coop') self.assertEqual(2, stackless.getruncount()) r.kill() self.assertEqual(2, stackless.getruncount()) r.kill() self.assertEqual(2, stackless.getruncount()) u.kill() self.assertEqual(1, stackless.getruncount()) typ, val, tb1 = None, None, None try: Divide(42, 0) except ZeroDivisionError: typ, val, tb1 = sys.exc_info() self.assertTrue(typ is ZeroDivisionError) tb2 = None try: if hasattr(stackless.getcurrent(), 'throw'): # greenstackless stackless.current.throw(typ, val, tb1) else: # Stackless stackless.getcurrent().tempval = stackless.bomb(typ, val, tb1) stackless.current.run() except: self.assertTrue(sys.exc_info()[0] is typ) self.assertTrue(sys.exc_info()[1] is val) tb2 = sys.exc_info()[2] tb3 = tb2 and tb2.tb_next tb4 = tb3 and tb3.tb_next # greenstackless adds 2 frames. self.assertTrue(tb1 in (tb2, tb3, tb4)) self.assertTrue(tb2) self.assertEqual(-4, c.balance) ta.kill() self.assertEqual(-3, c.balance) td.kill() self.assertEqual(-2, c.balance) tc.kill() self.assertEqual(-1, c.balance) tb.kill() self.assertEqual(0, c.balance) tb2 = None self.assertEqual(0, c.balance) c.preference = 1 def SendBomb(): assert c.send(stackless.bomb(typ, val, tb1)) is None stackless.tasklet(SendBomb)() try: c.receive() except: self.assertTrue(sys.exc_info()[0] is typ) self.assertTrue(sys.exc_info()[1] is val) tb2 = sys.exc_info()[2] tb3 = tb2 and tb2.tb_next tb4 = tb3 and tb3.tb_next tb5 = tb4 and tb4.tb_next # greenstackless adds 3 frames (including c.receive() etc.) self.assertTrue(tb1 in (tb2, tb3, tb4, tb5)) self.assertTrue(tb2) tb2 = None self.assertEqual(0, c.balance) c.preference = 1 def SendBomb(): assert c.send(stackless.bomb(typ, val, tb1)) is None stackless.tasklet(SendBomb)() try: c.receive() except: self.assertTrue(sys.exc_info()[0] is typ) self.assertTrue(sys.exc_info()[1] is val) tb2 = sys.exc_info()[2] tb3 = tb2 and tb2.tb_next tb4 = tb3 and tb3.tb_next tb5 = tb4 and tb4.tb_next # greenstackless adds 3 frames (including c.receive() etc.) self.assertTrue(tb1 in (tb2, tb3, tb4, tb5)) self.assertTrue(tb2) tb2 = None def RaiseException(task): task.raise_exception(ValueError, 42) stackless.tasklet(RaiseException)(stackless.getcurrent()) try: stackless.schedule() except: self.assertTrue(sys.exc_info()[0] is ValueError) self.assertEqual(str(sys.exc_info()[1]), '42') tb2 = sys.exc_info()[2] # Don't check the traceback (tb2), should be in stackless.schedule(). self.assertTrue(tb2) tb2 = None self.assertEqual(0, c.balance) c.preference = 1 def SendException(task): assert c.send_exception(ValueError, 43) is None stackless.tasklet(SendException)(stackless.current) try: c.receive() except: self.assertTrue(sys.exc_info()[0] is ValueError) self.assertEqual(str(sys.exc_info()[1]), '43') tb2 = sys.exc_info()[2] # Don't check the traceback (tb2), should be in stackless.schedule(). self.assertTrue(tb2)
def testStackless(self): events = [] def Divide(a, b): return a / b def Worker(name, c): while True: events.append(name + '.wait') events.append('%s/%s' % (name, c.receive())) def Single(name): events.append(name + '.single') def Cooperative(name): while True: events.append(name + '.coop') stackless.schedule() def CooperativeRemove(name): while True: events.append(name + '.corm') stackless.schedule_remove() def Run(): while True: events.append('schedule') i = len(events) stackless.schedule() if i == len(events): break events.append('done') c = stackless.channel() self.assertTrue(stackless.current is stackless.getmain()) self.assertTrue(stackless.getcurrent() is stackless.main) self.assertEqual(1, stackless.getruncount()) self.assertTrue(stackless.current is stackless.getcurrent().next) self.assertTrue(stackless.current is stackless.getcurrent().prev) ta = stackless.tasklet(Worker)('A', c) tb = stackless.tasklet(Worker)('B', c) tc = stackless.tasklet(Worker)('C', c) td = stackless.tasklet().bind(Worker)('D', c) self.assertEqual(5, stackless.getruncount()) self.assertTrue(td is stackless.current.prev) self.assertTrue(ta is stackless.getcurrent().next) self.assertTrue(td.next is stackless.current) self.assertTrue(td.prev is tc) self.assertEqual(c.preference, -1) self.assertEqual(c.balance, 0) del events[:] events.append('send') self.assertEqual(5, stackless.getruncount()) self.assertEqual(None, c.send('msg')) self.assertEqual(1, stackless.getruncount()) Run() self.assertEqual(' '.join(events), 'send A.wait A/msg A.wait B.wait C.wait D.wait schedule done') self.assertEqual(c.preference, -1) self.assertEqual(c.balance, -4) del events[:] events.append('send') c.preference = 0 # same as c.preference = 1 self.assertEqual(1, stackless.getruncount()) self.assertEqual(None, c.send('msg')) self.assertEqual(2, stackless.getruncount()) Run() #print ' '.join(events) self.assertEqual(' '.join(events), 'send schedule A/msg A.wait schedule done') self.assertEqual(c.preference, 0) self.assertEqual(c.balance, -4) del events[:] c.preference = 1 events.append('send') self.assertEqual(1, stackless.getruncount()) self.assertEqual(None, c.send('msg')) self.assertEqual(2, stackless.getruncount()) Run() self.assertEqual(' '.join(events), 'send schedule B/msg B.wait schedule done') self.assertEqual(c.preference, 1) del events[:] c.preference = 2 # same as c.preference = 1 events.append('send') self.assertEqual(1, stackless.getruncount()) self.assertEqual(None, c.send('msg')) self.assertEqual(None, c.send('msg')) self.assertEqual(3, stackless.getruncount()) Run() self.assertEqual(' '.join(events), 'send schedule C/msg C.wait D/msg D.wait schedule done') # Now the doubly-linked list is (d, main, a, b, c). Why? self.assertEqual(c.balance, -4) del events[:] c.preference = 5 events.append('send') self.assertEqual(c.balance, -4) self.assertEqual(1, stackless.getruncount()) t = stackless.tasklet(Single) self.assertEqual(1, stackless.getruncount()) self.assertTrue(t is t('T')) self.assertEqual(2, stackless.getruncount()) t.remove() self.assertEqual(1, stackless.getruncount()) self.assertEqual(t, t.insert()) self.assertEqual(2, stackless.getruncount()) self.assertEqual(None, c.send('msg1')) self.assertEqual(c.balance, -3) self.assertEqual(None, c.send('msg2')) self.assertEqual(None, c.send('msg3')) self.assertEqual(None, c.send('msg4')) self.assertEqual(6, stackless.getruncount()) events.append('a4') self.assertEqual(c.balance, 0) self.assertEqual(None, c.send('msg5')) self.assertEqual(5, stackless.getruncount()) events.append('a5') self.assertEqual(None, c.send('msg6')) self.assertEqual(5, stackless.getruncount()) Run() self.assertEqual(' '.join(events), 'send a4 T.single A/msg1 A.wait a5 B/msg2 B.wait schedule C/msg3 C.wait D/msg4 D.wait A/msg5 A.wait B/msg6 B.wait schedule done') self.assertTrue(stackless.getcurrent() is stackless.current.next) self.assertTrue(stackless.getcurrent() is stackless.current.prev) del events[:] self.assertEqual(c.balance, -4) c.preference = 42 self.assertEqual(None, c.send('msg1')) self.assertEqual(c.balance, -3) self.assertTrue(tc is stackless.getcurrent().next) self.assertTrue(tc is stackless.current.prev) self.assertTrue(tc.prev is stackless.getcurrent()) self.assertTrue(tc.next is stackless.current) self.assertEqual(None, c.send('msg2')) self.assertEqual(c.balance, -2) self.assertTrue(tc is stackless.getcurrent().next) self.assertTrue(td is stackless.current.prev) self.assertTrue(td.next is stackless.getcurrent()) self.assertTrue(td.prev is tc) self.assertEqual(None, c.send('msg3')) self.assertEqual(c.balance, -1) self.assertTrue(tc is stackless.current.next) self.assertTrue(ta is stackless.getcurrent().prev) self.assertTrue(ta.next is stackless.current) self.assertTrue(ta.prev is td) self.assertEqual(' '.join(events), '') self.assertEqual(4, stackless.getruncount()) t = stackless.tasklet(Single)('T') self.assertTrue(t is stackless.getcurrent().prev) self.assertTrue(ta is t.prev) self.assertTrue(t.alive) self.assertEqual(5, stackless.getruncount()) t.remove() #self.assertTrue(t.next is None # NotImplementedError in greenstackless) self.assertTrue(ta is stackless.current.prev) self.assertTrue(t.alive) self.assertEqual(4, stackless.getruncount()) t.run() self.assertEqual(4, stackless.getruncount()) self.assertTrue(not t.alive) self.assertEqual(' '.join(events), 'T.single') del events[:] td.run() self.assertEqual(' '.join(events), 'D/msg2 D.wait A/msg3 A.wait') del events[:] self.assertEqual(c.balance, -3) self.assertTrue(tc is stackless.getcurrent().next) self.assertTrue(tc is stackless.current.prev) self.assertTrue(tc.prev is stackless.getcurrent()) self.assertTrue(tc.next is stackless.current) tc.run() self.assertEqual(' '.join(events), 'C/msg1 C.wait') del events[:] self.assertEqual(c.balance, -4) self.assertTrue(stackless.getcurrent() is stackless.current.next) self.assertTrue(stackless.getcurrent() is stackless.current.prev) t = stackless.tasklet(Cooperative)('T') r = stackless.tasklet(CooperativeRemove)('R') u = stackless.tasklet(Cooperative)('U') self.assertEqual(4, stackless.getruncount()) del events[:] stackless.schedule() self.assertEqual(' '.join(events), 'T.coop R.corm U.coop') self.assertEqual(3, stackless.getruncount()) del events[:] stackless.schedule() self.assertEqual(' '.join(events), 'T.coop U.coop') self.assertEqual(3, stackless.getruncount()) del events[:] t.kill() # This involves t.run(), so u gets run as well. self.assertEqual(' '.join(events), 'U.coop') self.assertEqual(2, stackless.getruncount()) r.kill() self.assertEqual(2, stackless.getruncount()) r.kill() self.assertEqual(2, stackless.getruncount()) u.kill() self.assertEqual(1, stackless.getruncount()) typ, val, tb1 = None, None, None try: Divide(42, 0) except ZeroDivisionError: typ, val, tb1 = sys.exc_info() self.assertTrue(typ is ZeroDivisionError) tb2 = None try: if hasattr(stackless.getcurrent(), 'throw'): # greenstackless stackless.current.throw(typ, val, tb1) else: # Stackless stackless.getcurrent().tempval = stackless.bomb(typ, val, tb1) stackless.current.run() except: self.assertTrue(sys.exc_info()[0] is typ) self.assertTrue(sys.exc_info()[1] is val) tb2 = sys.exc_info()[2] tb3 = tb2 and tb2.tb_next tb4 = tb3 and tb3.tb_next # greenstackless adds 2 frames. self.assertTrue(tb1 in (tb2, tb3, tb4) ) self.assertTrue(tb2) self.assertEqual(-4, c.balance) ta.kill() self.assertEqual(-3, c.balance) td.kill() self.assertEqual(-2, c.balance) tc.kill() self.assertEqual(-1, c.balance) tb.kill() self.assertEqual(0, c.balance) tb2 = None self.assertEqual(0, c.balance) c.preference = 1 def SendBomb(): assert c.send(stackless.bomb(typ, val, tb1)) is None stackless.tasklet(SendBomb)() try: c.receive() except: self.assertTrue(sys.exc_info()[0] is typ) self.assertTrue(sys.exc_info()[1] is val) tb2 = sys.exc_info()[2] tb3 = tb2 and tb2.tb_next tb4 = tb3 and tb3.tb_next tb5 = tb4 and tb4.tb_next # greenstackless adds 3 frames (including c.receive() etc.) self.assertTrue(tb1 in (tb2, tb3, tb4, tb5)) self.assertTrue(tb2) tb2 = None self.assertEqual(0, c.balance) c.preference = 1 def SendBomb(): assert c.send(stackless.bomb(typ, val, tb1)) is None stackless.tasklet(SendBomb)() try: c.receive() except: self.assertTrue(sys.exc_info()[0] is typ) self.assertTrue(sys.exc_info()[1] is val) tb2 = sys.exc_info()[2] tb3 = tb2 and tb2.tb_next tb4 = tb3 and tb3.tb_next tb5 = tb4 and tb4.tb_next # greenstackless adds 3 frames (including c.receive() etc.) self.assertTrue(tb1 in (tb2, tb3, tb4, tb5)) self.assertTrue(tb2) tb2 = None def RaiseException(task): task.raise_exception(ValueError, 42) stackless.tasklet(RaiseException)(stackless.getcurrent()) try: stackless.schedule() except: self.assertTrue(sys.exc_info()[0] is ValueError) self.assertEqual(str(sys.exc_info()[1]), '42') tb2 = sys.exc_info()[2] # Don't check the traceback (tb2), should be in stackless.schedule(). self.assertTrue(tb2) tb2 = None self.assertEqual(0, c.balance) c.preference = 1 def SendException(task): assert c.send_exception(ValueError, 43) is None stackless.tasklet(SendException)(stackless.current) try: c.receive() except: self.assertTrue(sys.exc_info()[0] is ValueError) self.assertEqual(str(sys.exc_info()[1]), '43') tb2 = sys.exc_info()[2] # Don't check the traceback (tb2), should be in stackless.schedule(). self.assertTrue(tb2)