classification
Title: __str__ and __repr__ for asyncio.Task still omit arg values
Type: behavior Stage: resolved
Components: asyncio Versions: Python 3.9
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: asvetlov, kmaork, stuball123, xtreak, yselivanov
Priority: normal Keywords:

Created on 2020-02-13 08:19 by stuball123, last changed 2020-02-20 23:52 by yselivanov. This issue is now closed.

Messages (8)
msg361944 - (view) Author: Stuart Ball (stuball123) Date: 2020-02-13 08:19
This is not very helpful if your gather or wait contains multiple versions of foo with different argument values: 

`<Task pending coro=<foo() running at c.py:6>`

Should just be:

`<Task pending coro=<foo(42, "hello") running at c.py:6>`

Would probably take all of 5 minutes to implement and make a lot of people's lives easier.
msg361950 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2020-02-13 09:03
This could sometimes make the output verbose when the arguments themselves are tasks while including arguments in the signature in _format_coroutine.

$ cat /tmp/foo.py
import asyncio

async def foo(a, b): pass

async def main():
    task = asyncio.create_task(foo(1, b=1))
    task1 = asyncio.create_task(foo(1, b=task))
    print(repr(task))
    print(repr(task1))

asyncio.run(main())

$ python3.8 /tmp/foo.py
<Task pending name='Task-2' coro=<foo() running at /tmp/foo.py:3>>
<Task pending name='Task-3' coro=<foo() running at /tmp/foo.py:3>>

$ ./python.exe /tmp/foo.py
<Task pending name='Task-2' coro=<foo(a=1, b=1) running at /tmp/foo.py:3>>
<Task pending name='Task-3' coro=<foo(a=1, b=<Task pending name='Task-2' coro=<foo(a=1, b=1) running at /tmp/foo.py:3>>) running at /tmp/foo.py:3>>
msg362266 - (view) Author: Maor Kleinberger (kmaork) * Date: 2020-02-19 12:21
> This could sometimes make the output verbose

We could limit the length of the recursive __repr__ functions, and display partial reprs suffixed with ..., like in numpy for example.

We can define that the maximum wanted length of a task repr would be, say, 80 characters, get the reprs of all task arguments, and if the sum length is more than the maximum we can trim the longest ones and suffix with a '...'.

Maybe this restriction shouldn't be applied if python is built in debug mode.
msg362348 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2020-02-20 20:50
Not so easy to find a satisfactory generic approach.
An argument can also be 10 MiB length bytes array, a dictionary with 10,000 elements, HTML page, name it.
All these objects are printable but their representation is too verbose.
Task can have a dozen of arguments, only the latest may be meaningful for logically separating one task from others.

Task has a name exactly for the purpose of distinguishing similar but different tasks, please use it. Only the task creator knows how to name it better.
msg362363 - (view) Author: Maor Kleinberger (kmaork) * Date: 2020-02-20 22:55
> Not so easy to find a satisfactory generic approach.
I agree, but wouldn't you agree that some information is better than no information?

>Task has a name exactly for the purpose of distinguishing similar but different tasks
But in case the same task is run many times with different arguments, the task's name by itself doesn't provide very useful information...
msg362366 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2020-02-20 23:27
> I agree, but wouldn't you agree that some information is better than no information?

We do agree with that. Making it work in the way that does not disturb people when a 10mb bytes string is passed is challenging. We could just cut everything after 100 characters, but it's not an ideal solution either.

> But in case the same task is run many times with different arguments, the task's name by itself doesn't provide very useful information...

So make it useful. You can concatenate critical arguments reprs to task names or make them informative in other way.  If you're working with a third-party library that doesn't use task names consider making a PR.
msg362369 - (view) Author: Maor Kleinberger (kmaork) * Date: 2020-02-20 23:49
Oh I just learned that since python3.8 you can name individual tasks. Sorry for the confusion :)
It does seem like a good solution.
msg362371 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2020-02-20 23:52
> It does seem like a good solution.

Great. I'll close this issue then as the proposed solution is actually not as straightforward as it seems. Task names exist specifically to solve this case.
History
Date User Action Args
2020-02-20 23:52:20yselivanovsetstatus: open -> closed
resolution: rejected
messages: + msg362371

stage: resolved
2020-02-20 23:49:15kmaorksetmessages: + msg362369
2020-02-20 23:27:45yselivanovsetmessages: + msg362366
2020-02-20 22:55:12kmaorksetmessages: + msg362363
2020-02-20 20:50:19asvetlovsetmessages: + msg362348
2020-02-19 12:21:29kmaorksetnosy: + kmaork
messages: + msg362266
2020-02-13 09:03:47xtreaksettype: behavior
versions: + Python 3.9
2020-02-13 09:03:31xtreaksetmessages: + msg361950
2020-02-13 08:26:52xtreaksetnosy: + xtreak
2020-02-13 08:26:32xtreaksetnosy: + asvetlov, yselivanov
components: + asyncio
2020-02-13 08:19:35stuball123create