-
-
Notifications
You must be signed in to change notification settings - Fork 31.8k
traceback.clear_frames manages to deadlock a background task #79932
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
My use case: Issue: I believe this issue is a duplicate to https://bugs.python.org/issue29211, but wanted to provide another actual use case where it can pop up. Also even if the generator raises a GeneratorExit, why did the background thread freeze is still a mystery to me. Script to reproduce in my case is attached. |
So yes, the The reproduce example can be lowered to something like:: import asyncio
async def background(error_future):
try:
raise ValueError
except Exception as exc:
error_future.set_exception(exc)
await asyncio.sleep(1)
async def main():
loop = asyncio.get_event_loop()
error_future = loop.create_future()
task = asyncio.create_task(background(error_future))
await asyncio.wait([error_future])
exc = error_future.exception()
import traceback
traceback.clear_frames(exc.__traceback__)
# Will block forever, as task will never be waken up
await task
if __name__ == "__main__":
asyncio.run(main()) |
Very interesting. Thanks for reporting this issue. I'll definitely take a look at this before 3.8 is released. For 3.7 you'll likely have to find a workaround. |
For now, it seems like |
|
@iritkatriel ^^ |
I think this is the fix:
But when I apply it we get two failures from tests that seem to imply that the current behaviour is a feature:
|
I had already tried this and hence I wrote |
I think we should consider changing it. |
Note the confusion in the comments in test_clear_executing_generator:
The second one was added later - the bpo issue justifies with just "the variable f wasn't used, let's use it for something". Was there ever a conscious decision that clearing a suspended frame should be allowed, and that it closes the generator?
|
That closing a frame closes the generator, yes. Something to do with PEP 442. That clearing a suspended frame should be allowed, I don't know. Why not change |
I think we could either change generator.frame() to disallow it or traceback.clear_frames() to skip those frames. assertRaises is too high level to care about this. Currently traceback.clear_frames() swallows exceptions from clear(), and the exception comes from clearing a running (but not a suspended) frame. So either we change frame.clear() to also raise on a suspended frame, or we change the code in traceback.clear_frame() to check for suspended/running instead of relying on the exception. |
I've created a PR to raise an exception when the frame is suspended |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
Linked PRs
The text was updated successfully, but these errors were encountered: