I have an async application in which a lot of stuff happens so I cannot share the full code (runs on Python 3.10). However, I was a bit confused to see that “sometimes” exit_code = asyncio.run(main())
does not return the exit_code it’s supposed to return but instead returns None
. I added quite some logging to confirm that the exit code set by main()
is indeed not None
.
The application relies on some third-party async generators and grpc data streams and I’m pretty sure this error only happens when an abort event is triggered and the app shuts itself done in a controlled fashion. This shutdown also works as expected, except for the return code.
I had a look at the code for asyncio.run()
(https://github.com/python/cpython/blob/3.10/Lib/asyncio/runners.py#L44) and found the highlighted row interesting. Because to me it seems the the result of main is only returned when there is no unhandled exception, right? Otherwise it will continue to the finally
block, shuts down generators and executors before returning. Since there is no explicit return value, it returns None
.
Is my interpretation correct? And is this desired behaviour? Because for the part I’m interested in, I’m handling all exceptions. Up until my “main return” statement, everything works fine, but I cannot control the part between returning and whatever run_until_complete
may complain about. For know I circumvent the issue by storing the exit code in a global variable and then just reading that, but I am very curious to why this happens.