[pypy-commit] pypy py3.6: (vxgmichel, arigo)
arigo
pypy.commits at gmail.com
Sun Jul 16 07:15:26 EDT 2017
Author: Armin Rigo <arigo at tunes.org>
Branch: py3.6
Changeset: r91886:bc59a0b5e616
Date: 2017-07-16 13:14 +0200
http://bitbucket.org/pypy/pypy/changeset/bc59a0b5e616/
Log: (vxgmichel, arigo)
asend/send on async_generator objects
diff --git a/pypy/conftest.py b/pypy/conftest.py
--- a/pypy/conftest.py
+++ b/pypy/conftest.py
@@ -5,7 +5,7 @@
# some tests fail otherwise
sys.setrecursionlimit(2000)
-LOOK_FOR_PYTHON3 = 'python3.5'
+LOOK_FOR_PYTHON3 = 'python3.6'
PYTHON3 = os.getenv('PYTHON3') or py.path.local.sysfind(LOOK_FOR_PYTHON3)
if PYTHON3 is not None:
PYTHON3 = str(PYTHON3)
diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -593,16 +593,18 @@
return self
def descr__anext__(self):
- return AsyncGenASend(self)
+ return AsyncGenASend(self, self.space.w_None)
def descr_asend(self, w_arg):
- XXX
- return AsyncGenASend(w_arg)
+ return AsyncGenASend(self, w_arg)
def descr_athrow(self, w_type, w_val=None, w_tb=None):
XXX
return AsyncGenAThrow(w_type, w_val, w_tb)
+ def descr_aclose(self):
+ XXX
+
class AsyncGenValueWrapper(W_Root):
def __init__(self, w_value):
@@ -610,9 +612,11 @@
class AsyncGenASend(W_Root):
+ state = 0
- def __init__(self, async_gen):
+ def __init__(self, async_gen, w_value_to_send):
self.async_gen = async_gen
+ self.w_value_to_send = w_value_to_send
def descr__iter__(self):
return self
@@ -632,8 +636,29 @@
def send_ex(self, w_arg_or_err):
space = self.async_gen.space
- w_value = self.async_gen.send_ex(w_arg_or_err)
- if isinstance(w_value, AsyncGenValueWrapper):
- raise OperationError(space.w_StopIteration, w_value.w_value)
- else:
- return w_value
+ if self.state == 2:
+ raise OperationError(space.w_StopIteration, space.w_None)
+
+ # We think that the code should look like this:
+ #if self.w_value_to_send is not None:
+ # if not space.is_w(w_arg_or_err, space.w_None):
+ # raise ...
+ # w_arg_or_err = self.w_value_to_send
+ # self.w_value_to_send = None
+
+ # But instead, CPython's logic is this, which we think is
+ # giving nonsense results for 'g.asend(42).send(43)':
+ if self.state == 0:
+ if space.is_w(w_arg_or_err, space.w_None):
+ w_arg_or_err = self.w_value_to_send
+ self.state = 1
+
+ try:
+ w_value = self.async_gen.send_ex(w_arg_or_err)
+ if isinstance(w_value, AsyncGenValueWrapper):
+ raise OperationError(space.w_StopIteration, w_value.w_value)
+ else:
+ return w_value
+ except OperationError as e:
+ self.state = 2
+ raise
diff --git a/pypy/interpreter/test/test_coroutine.py b/pypy/interpreter/test/test_coroutine.py
--- a/pypy/interpreter/test/test_coroutine.py
+++ b/pypy/interpreter/test/test_coroutine.py
@@ -276,3 +276,42 @@
raises(Done, co.send, 93)
assert result == [5, 6]
"""
+
+ def test_async_yield_with_explicit_send(self): """
+ class X:
+ def __await__(self):
+ i1 = yield 40
+ assert i1 == 82
+ i2 = yield 41
+ assert i2 == 93
+
+ async def mygen():
+ x = yield 5
+ assert x == 2189
+ await X()
+ y = yield 6
+ assert y == 319
+
+ result = []
+ async def foo():
+ gen = mygen()
+ result.append(await gen.asend(None))
+ result.append(await gen.asend(2189))
+ try:
+ await gen.asend(319)
+ except StopAsyncIteration:
+ return 42
+ else:
+ raise AssertionError
+
+ co = foo()
+ x = co.send(None)
+ assert x == 40
+ assert result == [5]
+ x = co.send(82)
+ assert x == 41
+ assert result == [5]
+ e = raises(StopIteration, co.send, 93)
+ assert e.value.args == (42,)
+ assert result == [5, 6]
+ """
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -857,11 +857,11 @@
__repr__ = interp2app(AsyncGenerator.descr__repr__),
#__reduce__ = interp2app(Coroutine.descr__reduce__),
#__setstate__ = interp2app(Coroutine.descr__setstate__),
- asend = interp2app(AsyncGenerator.descr_send,
+ asend = interp2app(AsyncGenerator.descr_asend,
descrmismatch='asend'),
- athrow = interp2app(AsyncGenerator.descr_throw,
+ athrow = interp2app(AsyncGenerator.descr_athrow,
descrmismatch='athrow'),
- aclose = interp2app(AsyncGenerator.descr_close,
+ aclose = interp2app(AsyncGenerator.descr_aclose,
descrmismatch='aclose'),
__aiter__ = interp2app(AsyncGenerator.descr__aiter__,
descrmismatch='__aiter__'),
More information about the pypy-commit
mailing list