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

Recover from a 'foreign await' by throwing in the TypeError #1178

Merged
merged 5 commits into from
Aug 13, 2019

Conversation

oremanj
Copy link
Member

@oremanj oremanj commented Aug 7, 2019

This improves debuggability (since the traceback points to the location of the error, rather than just the nursery whose task was at fault) and fixes #552 by ensuring we don't abandon the child tasks of the errant one.

This improves debuggability (since the traceback points to the location of the error, rather than just the nursery whose task was at fault) and fixes python-trio#552 by ensuring we don't abandon the child tasks of the errant one.
@oremanj oremanj requested a review from njsmith August 7, 2019 15:00
@njsmith
Copy link
Member

njsmith commented Aug 7, 2019

Nice!

@codecov
Copy link

codecov bot commented Aug 7, 2019

Codecov Report

Merging #1178 into master will increase coverage by <.01%.
The diff coverage is 100%.

@@            Coverage Diff             @@
##           master    #1178      +/-   ##
==========================================
+ Coverage   99.56%   99.57%   +<.01%     
==========================================
  Files         106      106              
  Lines       12776    12800      +24     
  Branches      981      983       +2     
==========================================
+ Hits        12721    12745      +24     
  Misses         35       35              
  Partials       20       20
Impacted Files Coverage Δ
trio/_core/_run.py 99.72% <100%> (ø) ⬆️
trio/_core/tests/test_run.py 100% <100%> (ø) ⬆️
trio/tests/test_util.py 100% <0%> (ø) ⬆️
trio/_util.py 100% <0%> (ø) ⬆️

@oremanj
Copy link
Member Author

oremanj commented Aug 7, 2019

Added the requested test. I don't think having send() written in C is a fundamental invariant; what in your model would require that? A Python implementation will add an extraneous traceback frame at each task boundary, but that seems like a reasonable accounting of what really happened. I tried running Trio's testsuite with _next_send_fn set to a Python wrapper around the C send(), and only one test failed (test_traceback_frame_removal which directly makes assertions about which frame comes first in the traceback).

@oremanj
Copy link
Member Author

oremanj commented Aug 8, 2019

(Not sure what codecov is on about -- it looks green on the website.)

@njsmith
Copy link
Member

njsmith commented Aug 9, 2019

Codecov is complaining that this line is "partially" covered:

    assert any(entry.name == "child_xyzzy" for entry in excinfo.traceback)

I guess it's something to do with the embedded loop – maybe because it always exits early?

I don't think having send() written in C is a fundamental invariant; what in your model would require that? A Python implementation will add an extraneous traceback frame at each task boundary, but that seems like a reasonable accounting of what really happened. I tried running Trio's testsuite with _next_send_fn set to a Python wrapper around the C send(), and only one test failed (test_traceback_frame_removal which directly makes assertions about which frame comes first in the traceback).

I guess I had two things in mind:

  • We go to quite some trouble to only show user frames in user tracebacks, which is what that test is checking. I guess if for some reason we wanted to start supporting other methods besides CoroutineType.send and CoroutineType.throw, then we'd have to somehow update the traceback code?

  • The KeyboardInterrupt protection logic is super subtle, and this method is a delicate moment: it needs to atomically transition from "trio internal mode" to "user mode". I guess any way of resuming the task has to have some atomic moment when it both puts the user's frame on the stack and also resumes the user's try/except blocks, even if you wrapped send/throw inside some Python wrapper, so maybe it's not an issue? But only using C functions here definitely makes the analysis simpler :-)

This early exit is totally uninteresting, no reason for coverage to hassle us over it.
@njsmith njsmith merged commit cdd18e1 into python-trio:master Aug 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Our code for recovering after a "foreign await" needs to be reworked
2 participants