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

unix_pipes.PipeSendStream: add send_some method #783

Closed
wants to merge 2 commits into from

Conversation

oremanj
Copy link
Member

@oremanj oremanj commented Nov 22, 2018

send_some does not block after its first write completes, and returns
an indication of how much data it sent, so it can be used in cases where
the amount of data sent before a cancellation must be known. This is
needed to implement stdlib-compatible subprocess.Popen.communicate().

`send_some` does not block after its first write completes, and returns
an indication of how much data it sent, so it can be used in cases where
the amount of data sent before a cancellation must be known. This is
needed to implement stdlib-compatible `subprocess.Popen.communicate()`.
@oremanj oremanj requested a review from njsmith November 22, 2018 00:11
@codecov
Copy link

codecov bot commented Nov 22, 2018

Codecov Report

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

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #783      +/-   ##
==========================================
+ Coverage   99.01%   99.01%   +<.01%     
==========================================
  Files          96       96              
  Lines       11673    11713      +40     
  Branches      832      836       +4     
==========================================
+ Hits        11558    11598      +40     
  Misses         94       94              
  Partials       21       21
Impacted Files Coverage Δ
trio/_subprocess/unix_pipes.py 100% <100%> (ø) ⬆️
trio/tests/subprocess/test_unix_pipes.py 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d692653...c2dabbe. Read the comment docs.

@njsmith
Copy link
Member

njsmith commented Nov 24, 2018

I think we decided in chat that we weren't going to try to implement the stdlib communicate method's more exotic semantics (for now), which means we don't need this either (for now)?

@njsmith
Copy link
Member

njsmith commented Nov 24, 2018

@oremanj
Copy link
Member Author

oremanj commented Nov 24, 2018

I just reviewed those chat logs again and I don’t think we actually decided anything - you pointed out that the stdlib behavior is unusual (which is true), I pointed out the usefulness of preserving at least the partial output across calls (which would require some funkiness even if it wouldn’t need send_some), and I thought maybe if we were going to do something weird it would be better to preserve the full stdlib functionality rather than just part of it.

@njsmith
Copy link
Member

njsmith commented Nov 27, 2018

Subprocesses are pretty complicated, and communicate is especially complicated. As a general principle this makes me nervous, because when you (I) try to implement lots of complicated things at once, you (I) usually end up not thinking things through properly and committing to bad choices. So my intuition is that if we're worried, we should leave out communicate entirely from the first pass, and then come back to it later when we're not distracted by the other aspects.

(Storing unbounded amounts of string data as state on the process object itself? Maybe it's a good idea, I dunno, but it's definitely super weird.)

@oremanj
Copy link
Member Author

oremanj commented Nov 27, 2018

Fair enough. Making communicate() restartable seems like it would be a backwards-compatible change; I'm happy to leave that capability out of the initial version, which obviates the need for this diff.

@oremanj oremanj closed this Nov 27, 2018
@njsmith
Copy link
Member

njsmith commented Nov 27, 2018

Like, is communicate even a useful abstraction in the first place? It seems to me like the two main ways to interact with a process are:

  • Interactively: spawn a process, send stuff, receive stuff, in a fine-grained way using Trio's regular I/O machinery
  • One-shot: the equivalent of subprocess.run, where you want to run a process + send the input + get the output as a single string. If this is cancelled, kill the process and throw away the results.

Neither of these involves communicate and its tricky cancellation semantics...

@oremanj
Copy link
Member Author

oremanj commented Nov 27, 2018

Hmm, that's a good point. I had been thinking "well of course run() is implemented in terms of communicate()" but there's no particular reason that needs to be the case. I think a non-restartable communicate() is not going to be too much of a burden to maintain and leaving it out would surprise people, but I'm open to other alternatives.

@njsmith
Copy link
Member

njsmith commented Nov 27, 2018

Maybe! Let's move ahead with the stuff that we already know how to handle, and then revisit communicate later once the core subprocess functionality exists :-)

oremanj added a commit to oremanj/trio that referenced this pull request Nov 28, 2018
Adds `trio.subprocess.Process` and `trio.subprocess.run`, async wrappers for the stdlib subprocess module. No communicate() yet due to discussion on python-trio#783.

Note that this did not wind up using the code in linux_waitpid, instead running waitid() [which supports not consuming the status of the process] in a thread, in order to interoperate better with subprocess.Popen code.

Still TODO:
[ ] Windows support (need pipe implementations and testing)
[ ] documentation writeup, newsfragment
[ ] consider whether this module layout is the one we want (other option would be to move _subprocess/unix_pipes.py to just _unix_pipes.py, _subprocess/highlevel.py to _subprocess.py, and get rid of _subprocess/linux_waitpid.py)
[ ] expose other subprocess functions such as call, check_call, output (simple wrappers around run())
[ ] expose a basic communicate()?
oremanj added a commit to oremanj/trio that referenced this pull request Nov 28, 2018
Adds `trio.subprocess.Process` and `trio.subprocess.run`, async wrappers for the stdlib subprocess module. No communicate() yet due to discussion on python-trio#783.

Note that this did not wind up using the code in linux_waitpid, instead running waitid() [which supports not consuming the status of the process] in a thread, in order to interoperate better with subprocess.Popen code.

Still TODO:
[ ] Windows support (need pipe implementations and testing)
[ ] documentation writeup, newsfragment
[ ] consider whether this module layout is the one we want (other option would be to move _subprocess/unix_pipes.py to just _unix_pipes.py, _subprocess/highlevel.py to _subprocess.py, and get rid of _subprocess/linux_waitpid.py)
[ ] expose other subprocess functions such as call, check_call, output (simple wrappers around run())
[ ] expose a basic communicate()?
@oremanj oremanj mentioned this pull request Nov 28, 2018
3 tasks
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.

2 participants