New submission from Nathaniel Smith <n...@pobox.com>:

There's a curious bit of code in genobject.c:_PyGen_Finalize:

        if (!error_value) {
            PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
                             "coroutine '%.50S' was never awaited",
                             gen->gi_qualname);
        }

Obviously this is the code that issues "coroutine ... was never awaited" 
warnings. That's not so curious. What's curious is the 'if' statement: what it 
does is suppress this warning if -- at the moment the coroutine object was GCed 
-- there is an active exception propagating.

This was added by bpo-27968, apparently as a way to hide some warnings in 
test_coroutine.py. This justification seems dubious to me, though, and there 
doesn't seem to have been much/any scrutiny of this at the time. We can 
certainly write those tests more carefully, so that they don't issue warnings 
-- e.g. by using 'with closing(corofn()) as coro: ...'. And this has a much 
broader effect than on just those tests. For example, say we accidentally write:

   def foo():
       len(corofn())  # should be len(await corofn())

we'll get an error that was caused by the coroutine not being awaited -- and we 
*won't* get the usual warning message explaining this, because the coroutine 
object is GCed while the exception propagates. Or, if an unawaited coroutine 
happens to get stuck in a reference cycle, then it's a matter of luck whether 
the message gets printed, depending on when exactly the cycle collector happens 
to trigger.

I guess in most cases where someone forgets an await and it causes errors, the 
coroutine happens to get stashed into a local variable, so it can't be GCed 
until after the exception is no longer active. And if another exception becomes 
active in the mean time, probably it will capture the first one as __context__, 
so that also keeps the coroutine alive past the time when the warning would be 
suppressed. So maybe this isn't a huge issue in practice? But this all feels 
very finicky and accidental, so I wanted to raise the issue for discussion.

----------
components: asyncio
messages: 310325
nosy: asvetlov, benjamin.peterson, giampaolo.rodola, njs, yselivanov
priority: normal
severity: normal
status: open
title: Should we really hide unawaited coroutine warnings when an exception is 
pending?
versions: Python 3.7, Python 3.8

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue32605>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to