[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