[pypy-svn] r35922 - in pypy/dist/pypy: lib lib/app_test lib/test2 module/_stackless/test

stephan at codespeak.net stephan at codespeak.net
Wed Dec 20 19:18:40 CET 2006


Author: stephan
Date: Wed Dec 20 19:18:39 2006
New Revision: 35922

Added:
   pypy/dist/pypy/lib/app_test/test_stackless_pickling.py
      - copied, changed from r35891, pypy/dist/pypy/module/_stackless/test/test_stackless_pickling.py
Removed:
   pypy/dist/pypy/lib/test2/test_stackless.py
   pypy/dist/pypy/module/_stackless/test/test_stackless.py
   pypy/dist/pypy/module/_stackless/test/test_stackless_pickling.py
Modified:
   pypy/dist/pypy/lib/app_test/test_stackless.py
   pypy/dist/pypy/lib/stackless_new.py
Log:
fixed the stackless_new implementation such that it doesn't need to be
reinitialized after every test.
Included the test2/test_stackless.py tests in app_test/test_stackless 
(and skip them, because they are not yet working with stackless_new).
Moved the module/_stackless/test/test_stackless_pickling.py tests over 
to app_test and modified to be pure application test suite (they pass 
with CStackless and pypy-c, not sure though, how to disable for py.py 
and CPython) 


Modified: pypy/dist/pypy/lib/app_test/test_stackless.py
==============================================================================
--- pypy/dist/pypy/lib/app_test/test_stackless.py	(original)
+++ pypy/dist/pypy/lib/app_test/test_stackless.py	Wed Dec 20 19:18:39 2006
@@ -11,15 +11,12 @@
     if 'coroutine' in dir(stackless):
         stackless_c = False
         raise ImportError("We are running pypy-c")
-    withinit = False
 except ImportError:
     stackless_c = False
     try:
         from pypy.lib import stackless_new as stackless
     except ImportError, e:
         skip('cannot import stackless: %s' % (e,))
-    #from pypy.lib import stackless
-    withinit = True
 
 def pypy_skip(txt):
     "don't skip, if we are running with CStackless"
@@ -28,13 +25,6 @@
 
 class Test_Stackless:
 
-    def setup_method(self, method):
-        # there is still a bug in stackless_new
-        # that requires to reinitialize the module
-        # for every test
-        if withinit:
-            stackless._init()
-
     def test_simple(self):
         rlist = []
 
@@ -79,6 +69,7 @@
         stackless.run()
 
         assert len(rlist) == 20
+        print rlist
         for i in range(10):
             (s,r), rlist = rlist[:2], rlist[2:]
             assert s == 's%s' % i
@@ -458,6 +449,79 @@
         r = stackless.schedule('test')
         assert r == 'test'
 
+    def test_simple_pipe(self):
+        pypy_skip('should not fail, but does')
+        def pipe(X_in, X_out):
+            foo = X_in.receive()
+            X_out.send(foo)
+
+        X, Y = stackless.channel(), stackless.channel()
+        stackless.tasklet(pipe)(X, Y)
+        stackless.run()
+        X.send(42)
+        assert Y.receive() == 42
+
+    def test_nested_pipe(self):
+        pypy_skip('should not fail, but does')
+        from stackless import run, tasklet, channel
+
+        def pipe(X, Y):
+            foo = X.receive()
+            Y.send(foo)
+
+        def nest(X, Y):
+            X2, Y2 = stackless.channel(), stackless.channel()
+            stackless.tasklet(pipe)(X2, Y2)
+            X2.send(X.receive())
+            Y.send(Y2.receive())
+
+        X, Y = stackless.channel(), stackless.channel()
+        stackless.tasklet(nest)(X, Y)
+        X.send(42)
+        assert Y.receive() == 42
+
+    def test_wait_two(self):
+        """
+        A tasklets/channels adaptation of the test_wait_two from the
+        logic object space
+        """
+        pypy_skip('should not fail, but does')
+        
+        def sleep(X, Barrier):
+            Barrier.send((X, X.receive()))
+
+        def wait_two(X, Y, Ret_chan):
+            Barrier = stackless.channel()
+            stackless.tasklet(sleep)(X, Barrier)
+            stackless.tasklet(sleep)(Y, Barrier)
+            ret = Barrier.receive()
+            if ret[0] == X:
+                Ret_chan.send((1, ret[1]))
+            return Ret_chan.send((2, ret[1]))
+
+        X, Y, Ret_chan = stackless.channel(), stackless.channel(), stackless.channel()
+        stackless.tasklet(wait_two)(X, Y, Ret_chan)
+        Y.send(42)
+        X.send(42)
+        assert Ret_chan.receive() == (2, 42)
+        
+    def test_noop(self):
+        """
+        this test is from pypy/lib/test2.
+        Left it in for documentation purposes.
+        "switch" is not officially in the tasklet interface. It it just
+        an implementation detail, that tasklets are descendents from
+        coroutines, which do have a 'switch' method
+        """
+        skip("this test does not make sense at the moment")
+        main = stackless.getcurrent()
+
+        def switch_to_main():
+            main.switch()
+        
+        t = stackless.tasklet(switch_to_main)()
+        stackless.run()
+
 
 
 

Modified: pypy/dist/pypy/lib/stackless_new.py
==============================================================================
--- pypy/dist/pypy/lib/stackless_new.py	(original)
+++ pypy/dist/pypy/lib/stackless_new.py	Wed Dec 20 19:18:39 2006
@@ -18,6 +18,11 @@
 
 from collections import deque
 
+import operator
+def deque_remove(dq, value):
+    "deque.remove is only in python2.5"
+    del dq[operator.indexOf(dq, value)]
+
 __all__ = 'run getcurrent getmain schedule tasklet channel coroutine \
                 TaskletExit greenlet'.split()
 
@@ -81,11 +86,13 @@
             #receiver.tempval = sender.tempval
             receiver.tempval = sender.tempval
             squeue.append(sender)
+            #schedule()
         else: # nobody is waiting
             self.balance -= 1
-            squeue.pop()
+            #squeue.pop()
+            #deque_remove(receiver)
             self.queue.append(receiver)
-        schedule()
+            schedule_remove()
         msg = receiver.tempval
         return msg
 
@@ -218,6 +225,8 @@
     Please note that the 'timeout' feature is not yet implemented
     """
     schedule_remove()
+    while squeue:
+        schedule()
     
 scall = 0
 
@@ -228,14 +237,9 @@
     tasklet as default.
     schedule_remove(retval=stackless.current) -- ditto, and remove self.
     """
-    global first_run
-    if first_run:
-        squeue.rotate(-1)
-        first_run = False
-    t = squeue.pop()
-    if t is not getcurrent():
-        squeue.appendleft(t)
-
+    try:
+        deque_remove(squeue, getcurrent())
+    except:pass
     schedule()
 
 def schedule(retval=None):
@@ -247,16 +251,12 @@
     """
 
     mtask = getmain()
-    global first_run
-    if first_run:
-        squeue.rotate(-1)
-        first_run = False
-
     if squeue:
         task = squeue[0]
         squeue.rotate(-1)
-        if task is not getcurrent() and task.is_alive:
-            task.switch()
+        curr = getcurrent()
+        if task is not curr and task.is_alive:
+            r = task.switch()
             curr = getcurrent()
             if not task.is_alive:
                 if squeue:
@@ -269,13 +269,20 @@
                     if curr is not mtask:
                         mtask.switch()
                 schedule()
+        elif task is curr:
+            if len(squeue) > 1:
+                schedule()
+        elif not task.is_alive:
+            try:
+                deque_remove(squeue, task)
+            except:pass
+            if not squeue:
+                squeue.append(mtask)
 
 def _init():
     global main_tasklet
     global global_task_id
-    global first_run
     global squeue
-    first_run = True
     global_task_id = 0
     main_tasklet = coroutine.getcurrent()
     try:



More information about the Pypy-commit mailing list