Re: [Async-sig] task.result() and exception traceback display

2017-12-25 Thread Nathaniel Smith
I haven't thought about this enough to have an opinion about whether
this is correct or how it could be improved, but I can explain why
you're seeing what you're seeing :-).

The traceback is really a trace of where the exception went after it
was raised, with new lines added to the top as it bubbles out. So the
bottom line is the 'raise' statement, because that's where it was
created, and then it bubbled onto the 'call 1' line and was caught.
Then it was raised again and bubbled onto the 'call 2' line. Etc. So
you should think of it not as a snapshot of your stack when it was
created, but as a travelogue.

-n

On Sun, Dec 24, 2017 at 9:55 PM, Chris Jerdonek
 wrote:
> Hi,
>
> I noticed that if a task in asyncio raises an exception, then the
> displayed traceback can be "polluted" by intermediate calls to
> task.result().  Also, the calls to task.result() can appear out of
> order relative to each other and to other lines.
>
> Here is an example:
>
> import asyncio
>
> async def raise_error():
> raise ValueError()
>
> async def main():
> task = asyncio.ensure_future(raise_error())
>
> try:
> await task  # call 1
> except Exception:
> pass
>
> try:
> task.result()  # call 2
> except Exception:
> pass
>
> task.result()  # call 3
>
> asyncio.get_event_loop().run_until_complete(main())
>
> The above outputs--
>
> Traceback (most recent call last):
>   File "test.py", line 24, in 
> asyncio.get_event_loop().run_until_complete(main())
>   File "/Users/.../3.6.4rc1/lib/python3.6/asyncio/base_events.py",
>   line 467, in run_until_complete
> return future.result()
>   File "test.py", line 21, in main
> task.result()  # call 3
>   File "test.py", line 17, in main
> task.result()  # call 2
>   File "test.py", line 12, in main
> await task  # call 1
>   File "test.py", line 5, in raise_error
> raise ValueError()
> ValueError
>
> Notice that the "call 2" line appears in the traceback, even though it
> doesn't come into play in the exception.  Also, the lines don't obey
> the "most recent call last" rule.  If this rule were followed, it
> should be something more like--
>
> Traceback (most recent call last):
>   File "test.py", line 24, in 
> asyncio.get_event_loop().run_until_complete(main())
>   File "/Users/.../3.6.4rc1/lib/python3.6/asyncio/base_events.py",
>   line 467, in run_until_complete
> return future.result()
>   File "test.py", line 12, in main
> await task  # call 1
>   File "test.py", line 5, in raise_error
> raise ValueError()
>   File "test.py", line 17, in main
> task.result()  # call 2
>   File "test.py", line 21, in main
> task.result()  # call 3
> ValueError
>
> If people agree there's an issue along these lines, I can file an
> issue in the tracker. I didn't seem to find one when searching for
> open issues with search terms like "asyncio traceback".
>
> Thanks,
> --Chris
> ___
> Async-sig mailing list
> Async-sig@python.org
> https://mail.python.org/mailman/listinfo/async-sig
> Code of Conduct: https://www.python.org/psf/codeofconduct/



-- 
Nathaniel J. Smith -- https://vorpus.org
___
Async-sig mailing list
Async-sig@python.org
https://mail.python.org/mailman/listinfo/async-sig
Code of Conduct: https://www.python.org/psf/codeofconduct/


[Async-sig] task.result() and exception traceback display

2017-12-24 Thread Chris Jerdonek
Hi,

I noticed that if a task in asyncio raises an exception, then the
displayed traceback can be "polluted" by intermediate calls to
task.result().  Also, the calls to task.result() can appear out of
order relative to each other and to other lines.

Here is an example:

import asyncio

async def raise_error():
raise ValueError()

async def main():
task = asyncio.ensure_future(raise_error())

try:
await task  # call 1
except Exception:
pass

try:
task.result()  # call 2
except Exception:
pass

task.result()  # call 3

asyncio.get_event_loop().run_until_complete(main())

The above outputs--

Traceback (most recent call last):
  File "test.py", line 24, in 
asyncio.get_event_loop().run_until_complete(main())
  File "/Users/.../3.6.4rc1/lib/python3.6/asyncio/base_events.py",
  line 467, in run_until_complete
return future.result()
  File "test.py", line 21, in main
task.result()  # call 3
  File "test.py", line 17, in main
task.result()  # call 2
  File "test.py", line 12, in main
await task  # call 1
  File "test.py", line 5, in raise_error
raise ValueError()
ValueError

Notice that the "call 2" line appears in the traceback, even though it
doesn't come into play in the exception.  Also, the lines don't obey
the "most recent call last" rule.  If this rule were followed, it
should be something more like--

Traceback (most recent call last):
  File "test.py", line 24, in 
asyncio.get_event_loop().run_until_complete(main())
  File "/Users/.../3.6.4rc1/lib/python3.6/asyncio/base_events.py",
  line 467, in run_until_complete
return future.result()
  File "test.py", line 12, in main
await task  # call 1
  File "test.py", line 5, in raise_error
raise ValueError()
  File "test.py", line 17, in main
task.result()  # call 2
  File "test.py", line 21, in main
task.result()  # call 3
ValueError

If people agree there's an issue along these lines, I can file an
issue in the tracker. I didn't seem to find one when searching for
open issues with search terms like "asyncio traceback".

Thanks,
--Chris
___
Async-sig mailing list
Async-sig@python.org
https://mail.python.org/mailman/listinfo/async-sig
Code of Conduct: https://www.python.org/psf/codeofconduct/