[pypy-svn] r27846 - pypy/dist/pypy/module/stackless/test

stephan at codespeak.net stephan at codespeak.net
Mon May 29 15:09:01 CEST 2006


Author: stephan
Date: Mon May 29 15:08:59 2006
New Revision: 27846

Added:
   pypy/dist/pypy/module/stackless/test/stack4.py   (contents, props changed)
Modified:
   pypy/dist/pypy/module/stackless/test/stackless_.py
Log:
still not working python stackless impl. The 'stack4.py' shows a test that
concentrates on exactly one feature (in this case: channel.close()).
There should be more tests in this manner...


Added: pypy/dist/pypy/module/stackless/test/stack4.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/stackless/test/stack4.py	Mon May 29 15:08:59 2006
@@ -0,0 +1,40 @@
+"""
+this test shows what happens, when trying to use an already closed channel
+"""
+
+import sys
+import stackless
+if hasattr(stackless,'coroutine'):
+    import stackless_ as stackless
+
+def f(outchan):
+    v = 1
+    print 'f sending',v
+    outchan.send(v)
+    print 'f successfully sended',v
+    v = 2
+    print 'f sending',v
+    try:
+        outchan.send(v)
+        print 'f successfully sended',v
+    except StopIteration:
+        print 'f got StopIteration'
+
+
+def g(inchan):
+    print 'g before receiving'
+    v = inchan.receive()
+    print 'g received (just before closing)', v
+    inchan.close()
+    print 'g after closing channel'
+    try:
+        print 'g before receiving'
+        v = inchan.receive()
+    except StopIteration:
+        print 'g got StopIteration from receiving'
+
+
+chan = stackless.channel()
+t1 = stackless.tasklet(f)(chan)
+t2 = stackless.tasklet(g)(chan)
+stackless.run()

Modified: pypy/dist/pypy/module/stackless/test/stackless_.py
==============================================================================
--- pypy/dist/pypy/module/stackless/test/stackless_.py	(original)
+++ pypy/dist/pypy/module/stackless/test/stackless_.py	Mon May 29 15:08:59 2006
@@ -23,6 +23,10 @@
 
 last_thread_id = 0
 
+def restore_exception(etype, value, stack):
+    """until I find out how to restore an exception on python level"""
+    raise value
+
 class TaskletProxy(object):
     def __init__(self, coro):
         self.alive = False
@@ -71,6 +75,13 @@
     traceback = None
     type = None
     value = None
+    def __init__(self,etype=None, value=None, traceback=None):
+        self.type = etype
+        self.value = value
+        self.traceback = traceback
+
+    def _explode(self):
+        restore_exception(self.type, self.value, self.traceback)
 
 # channel: see below
 
@@ -154,6 +165,8 @@
 
 # end interface
 
+# implicit scheduler
+
 def _next():
     c = getcurrent()
     if c.next is c:
@@ -211,6 +224,8 @@
         print c,
     print ']'
 
+# end implicit scheduler
+
 main_tasklet = None
 main_coroutine = None
 
@@ -241,13 +256,6 @@
     """
     schedule()
 
-note = """
-I don't see why coro_reg is needed.
-tasklets should ideally inherit from coroutine.
-This will create unwanted attributes, but they will
-go away when we port this to interp-leve.
-"""
-
 def getcurrent():
     """
     getcurrent() -- return the currently executing tasklet.
@@ -280,6 +288,9 @@
     nt.switch()
     #print 'schedule: after switch',
     #_print_queue()
+    curr = getcurrent()
+    if type(curr.tempval) is bomb:
+        raise curr.tempval._explode()
     if retval is None:
         return getcurrent()
     else:
@@ -627,6 +638,8 @@
         the runnables list.
         The above policy can be changed by setting channel flags.
         """
+        if self.closing:
+            raise StopIteration
         if self.balance > 0: # Receiving 1
             wt = self.queue.popleft()
             retval = wt.tempval
@@ -653,6 +666,8 @@
         be activated immediately, and the sender is put at the end of
         the runnables list.
         """
+        if self.closing:
+            raise StopIteration
         ct = getcurrent()
         if ct.tempval is not None:
             print 'THERE IS STILL SOME CHANNEL SEND VALUE',ct.tempval
@@ -676,7 +691,8 @@
         channel. exc must be a subclass of Exception.
         Behavior is like channel.send, but that the receiver gets an exception.
         """
-        pass
+        b = bomb(exc, value)
+        self.send(bomb)
 
     ## needed
     def send_sequence(self, value):
@@ -687,7 +703,8 @@
         be activated immediately, and the sender is put at the end of
         the runnables list.
         """
-        pass
+        for item in value:
+            self.send(item)
 
 __init()
 



More information about the Pypy-commit mailing list