Author: Armin Rigo <ar...@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): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit