Please see attached test. Returning True from __exit__ when type is None can break expected program flow. So far, I've found that each of break/continue/return inside a with block is affected. Both with and without '--jit off'
PyPy2 is unaffected. Thanks! -Nate
import unittest # Platform # Ubuntu Xenial # PyPy 3 # url: https://bitbucket.org/pypy/pypy/downloads/pypy3-v6.0.0-linux64.tar.bz2 # md5: 86db0d6e4c332043dd79d0ab5aac4c2b # sha1: 500637664748891bf0f82bcbc0a66f8866f56f1a class ContrivedContext(object): def __enter__(self): return self def __exit__(self, type, value, traceback): # CPython 2.7, 3.4, 3.7 behave as expected # PyPy 2 is fine as well # For PyPy 3.5, however (with and without '--jit off'): # returning True for non-error causes a break/continue/return not to work correctly if type is None: # tests pass if False is always returned when type is None return True class Test_PyPy35_Context_Badness(unittest.TestCase): def test_break(self): while True: with ContrivedContext(): break # should never reach this self.assertTrue(False) # or this # but in PyPy 3.5, the above 'break' failed to kick us out of the loop, # due to the context __exit__ returning True self.assertTrue(False) # should reach this self.assertTrue(True) def test_continue(self): go = True while go: go = False with ContrivedContext(): continue # should never reach this self.assertTrue(False) # or this # but in PyPy 3.5, the above 'continue' failed to jump to the beginning of the loop, # due to the context __exit__ returning True self.assertTrue(False) # should reach this self.assertTrue(True) def test_return(self): with ContrivedContext(): return # should never reach this self.assertTrue(False) # or this # but in PyPy 3.5, the above 'return' failed and did not exit the function, # due to the context __exit__ returning True self.assertTrue(False) if __name__ == '__main__': unittest.main()
_______________________________________________ pypy-dev mailing list pypy-dev@python.org https://mail.python.org/mailman/listinfo/pypy-dev