Skip to content
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

Should we really hide unawaited coroutine warnings when an exception is pending? #76786

Closed
njsmith opened this issue Jan 20, 2018 · 3 comments
Closed
Labels
3.7 (EOL) end of life 3.8 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs)

Comments

@njsmith
Copy link
Contributor

njsmith commented Jan 20, 2018

BPO 32605
Nosy @giampaolo, @benjaminp, @njsmith, @asvetlov, @1st1

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:

assignee = None
closed_at = <Date 2018-01-29.19:32:43.508>
created_at = <Date 2018-01-20.05:30:49.949>
labels = ['interpreter-core', '3.7', '3.8']
title = 'Should we really hide unawaited coroutine warnings when an exception is pending?'
updated_at = <Date 2018-01-29.19:32:53.470>
user = 'https://github.com/njsmith'

bugs.python.org fields:

activity = <Date 2018-01-29.19:32:53.470>
actor = 'yselivanov'
assignee = 'none'
closed = True
closed_date = <Date 2018-01-29.19:32:43.508>
closer = 'yselivanov'
components = ['Interpreter Core']
creation = <Date 2018-01-20.05:30:49.949>
creator = 'njs'
dependencies = []
files = []
hgrepos = []
issue_num = 32605
keywords = []
message_count = 3.0
messages = ['310325', '311068', '311159']
nosy_count = 5.0
nosy_names = ['giampaolo.rodola', 'benjamin.peterson', 'njs', 'asvetlov', 'yselivanov']
pr_nums = []
priority = 'normal'
resolution = 'fixed'
stage = 'resolved'
status = 'closed'
superseder = None
type = None
url = 'https://bugs.python.org/issue32605'
versions = ['Python 3.7', 'Python 3.8']

@njsmith
Copy link
Contributor Author

njsmith commented Jan 20, 2018

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.

@njsmith njsmith added topic-asyncio 3.7 (EOL) end of life 3.8 only security fixes labels Jan 20, 2018
@1st1
Copy link
Member

1st1 commented Jan 29, 2018

So in bpo-32703 we consider removing the check. I'll try to figure out what to do with "coroutine ... was never awaited" warnings in test_coroutines -- probably just silence them.

@1st1
Copy link
Member

1st1 commented Jan 29, 2018

With PR #5410 being merged I believe this issue can be now closed.

@1st1 1st1 closed this as completed Jan 29, 2018
@1st1 1st1 added interpreter-core (Objects, Python, Grammar, and Parser dirs) and removed topic-asyncio labels Jan 29, 2018
@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.7 (EOL) end of life 3.8 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs)
Projects
None yet
Development

No branches or pull requests

2 participants