Yury Selivanov added the comment: Nick, Guido,
Attached is a patch that fixes a refleak in 'async with' implementation. The problem is related to WITH_CLEANUP_START/WITH_CLEANUP_FINISH opcodes. For regular 'with' statements, these opcodes go one after another (essentially, it was one opcode before 'async with'). For 'async with' statements, we have a GET_AWAITABLE/YIELD_FROM pair between them. Now, if an error occurred during running a GET_AWAITABLE or a YIELD_FROM opcode, WITH_CLEANUP_FINISH was unreachable. All blocks were correctly unwound by the eval loop, but exception object got too many DECREFS. My solution is to continue using WITH_CLEANUP_START/WITH_CLEANUP_FINISH opcodes, but use SETUP_EXCEPT to guard them and nested YIELD_FROM and GET_AWAITABLE. In case of an exception, I propose to use another new opcode -- ASYNC_WITH_CLEANUP_EXCEPT. It unwinds the block set up by SETUP_EXCEPT, restores exception, NULLifies a copy of exception in the stack and does 'goto error', letting eval loop do the rest. "./python.exe -m test -R3:3 test_coroutines" with this patch reports no refleaks. I also updates test_coroutines with a lot of new 'async with' tests, I think that I got all usecases covered. Please take a look at the patch, I want to commit it as soon as possible. ---------- Added file: http://bugs.python.org/file39354/with.patch _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue24017> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com