[pypy-svn] r34943 - in pypy/dist/pypy/module/_stackless: . test

arigo at codespeak.net arigo at codespeak.net
Fri Nov 24 18:23:23 CET 2006


Author: arigo
Date: Fri Nov 24 18:23:21 2006
New Revision: 34943

Modified:
   pypy/dist/pypy/module/_stackless/clonable.py
   pypy/dist/pypy/module/_stackless/interp_clonable.py
   pypy/dist/pypy/module/_stackless/test/test_clonable.py
   pypy/dist/pypy/module/_stackless/test/test_interp_clonable.py
Log:
Change the parent of a freshly cloned coroutine, to be its original.
This allows much more natural code to be written, as seen in the new
test_fork().


Modified: pypy/dist/pypy/module/_stackless/clonable.py
==============================================================================
--- pypy/dist/pypy/module/_stackless/clonable.py	(original)
+++ pypy/dist/pypy/module/_stackless/clonable.py	Fri Nov 24 18:23:21 2006
@@ -83,6 +83,7 @@
         self.coroutine = None
         newcoro = AppClonableCoroutine(oldcoro.space, state=oldcoro.costate)
         newcoro.subctx = oldcoro.clone_into(newcoro, oldcoro.subctx)
+        newcoro.parent = oldcoro
         self.newcoroutine = newcoro
 
 def fork(space):

Modified: pypy/dist/pypy/module/_stackless/interp_clonable.py
==============================================================================
--- pypy/dist/pypy/module/_stackless/interp_clonable.py	(original)
+++ pypy/dist/pypy/module/_stackless/interp_clonable.py	Fri Nov 24 18:23:21 2006
@@ -64,7 +64,9 @@
     def call(self):
         oldcoro = self.coroutine
         self.coroutine = None
-        self.newcoroutine = oldcoro.clone()
+        newcoro = oldcoro.clone()
+        newcoro.parent = oldcoro
+        self.newcoroutine = newcoro
 
 def fork():
     """Fork, as in the Unix fork(): the call returns twice, and the return

Modified: pypy/dist/pypy/module/_stackless/test/test_clonable.py
==============================================================================
--- pypy/dist/pypy/module/_stackless/test/test_clonable.py	(original)
+++ pypy/dist/pypy/module/_stackless/test/test_clonable.py	Fri Nov 24 18:23:21 2006
@@ -110,3 +110,58 @@
         coro.switch()
         assert clonable.getcurrent() is main
         assert counter == [4]
+
+
+    def test_fork(self):
+        import _stackless
+
+        class Fail(Exception):
+            pass
+
+        class Success(Exception):
+            pass
+
+        def first_solution(func):
+            global next_answer
+            co = _stackless.clonable()
+            co.bind(func)
+            try:
+                co.switch()
+            except Success, e:
+                return e.args[0]
+
+        def zero_or_one():
+            sub = _stackless.fork()
+            if sub is not None:
+                # in the parent: run the child first
+                try:
+                    sub.switch()
+                except Fail:
+                    pass
+                # then proceed with answer '1'
+                return 1
+            else:
+                # in the child: answer '0'
+                return 0
+
+        # ____________________________________________________________
+
+        invalid_prefixes = {
+            (0, 0): True,
+            (0, 1, 0): True,
+            (0, 1, 1): True,
+            (1, 0): True,
+            (1, 1, 0, 0): True,
+            }
+
+        def example():
+            test = []
+            for n in range(5):
+                test.append(zero_or_one())
+                if tuple(test) in invalid_prefixes:
+                    raise Fail
+            raise Success(test)
+
+        res = first_solution(example)
+        assert res == [1, 1, 0, 1, 0]
+

Modified: pypy/dist/pypy/module/_stackless/test/test_interp_clonable.py
==============================================================================
--- pypy/dist/pypy/module/_stackless/test/test_interp_clonable.py	(original)
+++ pypy/dist/pypy/module/_stackless/test/test_interp_clonable.py	Fri Nov 24 18:23:21 2006
@@ -92,6 +92,7 @@
                     # in the parent
                     self.result.append(3)
                     newcoro.switch()
+                    self.result.append(5)
                 else:
                     # in the child
                     self.result.append(4)
@@ -103,8 +104,6 @@
             coro.bind(T(result))
             result.append(1)
             coro.switch()
-            result.append(5)
-            coro.switch()   # resume after newcoro.switch()
             result.append(6)
             n = 0
             for i in result:



More information about the Pypy-commit mailing list