[pypy-commit] pypy py3.5: Add another test for 'async with', and fix for 'with' or 'async with':
arigo
pypy.commits at gmail.com
Sun Jul 1 16:51:21 EDT 2018
Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r94795:0a4016e8a6bc
Date: 2018-07-01 22:50 +0200
http://bitbucket.org/pypy/pypy/changeset/0a4016e8a6bc/
Log: Add another test for 'async with', and fix for 'with' or 'async
with': if they call '__exit__' or '__aexit__' and this returns True,
we must ignore that if we're processing a return/break/continue
instead of a real exception.
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -1260,9 +1260,11 @@
def WITH_CLEANUP_FINISH(self, oparg, next_instr):
w_suppress = self.popvalue()
- if self.space.is_true(w_suppress):
- # __exit__() returned True -> Swallow the exception.
- self.settopvalue(self.space.w_None)
+ w_unroller = self.peekvalue()
+ if isinstance(w_unroller, SApplicationException):
+ if self.space.is_true(w_suppress):
+ # __exit__() returned True -> Swallow the exception.
+ self.settopvalue(self.space.w_None)
# this is always followed by END_FINALLY
# in the stack now: [w_unroller-or-w_None..]
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
@@ -112,6 +112,27 @@
assert seen == ['aenter', 'aexit']
"""
+ def test_async_with_exit_True(self): """
+ seen = []
+ class X:
+ async def __aenter__(self):
+ seen.append('aenter')
+ async def __aexit__(self, *args):
+ seen.append('aexit')
+ return True
+ async def f(x):
+ async with x:
+ return 42
+ c = f(X())
+ try:
+ c.send(None)
+ except StopIteration as e:
+ assert e.value == 42
+ else:
+ assert False, "should have raised"
+ assert seen == ['aenter', 'aexit']
+ """
+
def test_await(self): """
class X:
def __await__(self):
More information about the pypy-commit
mailing list