Skip to content

RuntimeWarning "coroutine was never awaited" prints first line of file called sys #117535

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

Closed
hroncok opened this issue Apr 4, 2024 · 8 comments
Closed
Labels
type-bug An unexpected behavior, bug, or error

Comments

@hroncok
Copy link
Contributor

hroncok commented Apr 4, 2024

Bug report

Bug description:

async def coroutine():
    pass

coroutine().nope
$ echo 'Why would you print me?' > sys

$ python3.12 nowait.py 
Traceback (most recent call last):
  File ".../nowait.py", line 4, in <module>
    coroutine().nope
AttributeError: 'coroutine' object has no attribute 'nope'
sys:1: RuntimeWarning: coroutine 'coroutine' was never awaited
  Why would you print me?

Note the last line of the error. It is from the sys file.

This does not go away when Python is invoked with -P, -E, or -I.

CPython versions tested on:

3.12, 3.13

Operating systems tested on:

Linux

Linked PRs

@hroncok hroncok added the type-bug An unexpected behavior, bug, or error label Apr 4, 2024
@gaogaotiantian
Copy link
Member

I did not quite get the issue, do you mean why sys:1: RuntimeWarning: coroutine 'coroutine' was never awaited is printed for your code? Because you created a coroutine coroutine() and never awaited it. Or it's something else?

@hroncok
Copy link
Contributor Author

hroncok commented Apr 4, 2024

The string Why would you print me? is part of the output.

@hroncok
Copy link
Contributor Author

hroncok commented Apr 4, 2024

Hypothesis: The thing that shows the warning wants to actually show the first line of the sys module.

Whether or not it makes sense to show the first line of the sys module I don't know. But it wrongly shows the first line of the sys file in $PWD next to the script.

@hroncok
Copy link
Contributor Author

hroncok commented Apr 4, 2024

Perhaps the weirdest thing is that I can git bisect this to the first ever 3.12 commit, which only changes the version :/

e851177

I have no idea how that's relevant, unless the behavior depends on the value of the Python version.

@gaogaotiantian
Copy link
Member

Ahh, interesting. I believe I know what's going on. The warning module sent sys as a fake file name but linecache actually read it. I'll see if there's anything I can do.

@serhiy-storchaka
Copy link
Member

The output is supposed to include the source file name, the line number, the warning category name, and the warning message.

$ echo 'open("/dev/null")' >example.py; ./python example.py
/home/serhiy/py/cpython3.12/example.py:1: ResourceWarning: unclosed file <_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'>
  open("/dev/null")
ResourceWarning: Enable tracemalloc to get the object allocation traceback

If the source is not a file, some special values like <stdin> or <string> are used:

$ echo 'open("/dev/null")' | ./python
<stdin>:1: ResourceWarning: unclosed file <_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'>
ResourceWarning: Enable tracemalloc to get the object allocation traceback
$ ./python -c 'open("/dev/null")'
<string>:1: ResourceWarning: unclosed file <_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'>
ResourceWarning: Enable tracemalloc to get the object allocation traceback

But if the warning is generated when no Python function frame exists, you get the "sys:1:" prefix:

$ echo 'f = open("/dev/null")' >example.py; ./python example.py
sys:1: ResourceWarning: unclosed file <_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'>
$ echo 'f = open("/dev/null")' | ./python
sys:1: ResourceWarning: unclosed file <_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'>
$ ./python -c 'f = open("/dev/null")'
sys:1: ResourceWarning: unclosed file <_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'>

sys is not a real file name (and if it matches the real file, it causes a confusion as in this issue), and it does not look special enough. I believe it was a mistake -- the original author confused the file name and the module name. We should use some other special value.

I considered several variants:

  • None. It will require more changes in the C code which currently asserts that the filename is a string, but it is easily recognized special value. The "None:1:" prefix does not look nice, so it can just be omitted.
  • An empty string. It never matches the real file name, and special enough.
  • <sys>, <system>, <python>, <interpreter>, <core>, etc. It looks like one of existing special values, and will likely be handled by the code which already handles them.

Omitting the prefix can produce less confusing for casual users output, but it is less informative. <sys> looks like the most obvious variant. I suggest to use it if nobody suggests a better name.

While we are here, I suggest also to change the line number from 1 to 0. It does not make any sense, since there are no source lines, but 0 looks more special than 1.

@gaogaotiantian
Copy link
Member

This is fixed in both 3.12 and 3.13. Closing for complete.

@hroncok
Copy link
Contributor Author

hroncok commented Apr 19, 2024

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

3 participants