8000 bpo-36889: Document Stream class and add docstrings by tirkarthi · Pull Request #14488 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-36889: Document Stream class and add docstrings #14488 8000

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

Merged
merged 9 commits into from
Sep 13, 2019

Conversation

tirkarthi
Copy link
Member
@tirkarthi tirkarthi commented Jun 30, 2019
  • This just copies the docs from StreamWriter and StreamReader.
  • Add docstring for asyncio functions.

https://bugs.python.org/issue36889

Automerge-Triggered-By: @asvetlov

.. coroutinemethod:: start_tls(sslcontext, *, server_hostname=None, \
ssl_handshake_timeout=None)

Calls :meth:`Stream.drain()` and rest of the arguments are passed directly to
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd actually elaborate a bit on this method - why we have it, ideally, with an example.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a sentence over upgrading the TLS. I have also added similar sentence around sendfile above. I couldn't come up with a useful example than calling connect and then calling start_tls to upgrade SSL in next statement. If there is a more practical one please add in.

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

the high watermark, *drain()* blocks until the size of the
buffer is drained down to the low watermark and writing can
be resumed. When there is nothing to wait for, the :meth:`drain`
returns immediately.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit more subtle. drain() is only needed when you do a few stream.write() calls. When you have only one stream.write() you can just say await stream.write() and not bother with drain(). @asvetlov am I right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my perspective, people always should use await stream.write() form and never drain() explicitly. There is no reason for late buffer overrun detection (and draining) if it can be done earlier.

The only reason why the method exists is backward compatibility for subprocess stdin/stdout/stderr pipes usage.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should reflect it in docs but sorry, I cannot propose exact wording.

.. coroutinemethod:: start_tls(sslcontext, *, server_hostname=None, \
ssl_handshake_timeout=None)

Calls :meth:`Stream.drain()` to write to the connection and uses :meth:`loop.start_tls`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same as for sendfile: the method upgrades a connection to TLS encrypted one.

@tirkarthi
Copy link
Member Author

I have pushed the changes to make sure await stream.write(data) as recommended with stream.write(data); await stream.drain() also documented with a method. I think the only detail pending now is over how multiple stream.write can be buffered to use stream.drain later as below that should be noted in the stream.drain docs.

#14488 (comment)

This is a bit more subtle. drain() is only needed when you do a few stream.write() calls. When you have only one stream.write() you can just say await stream.write() and not bother with drain(). @asvetlov am I right?

@asvetlov
Copy link
Contributor
asvetlov commented Sep 11, 2019

I think the only detail pending now is over how multiple stream.write can be buffered to use stream.drain later as below that should be noted in the stream.drain docs.

The interesting part is that multiple sync writes and single drain after doesn't help with buffering. Instead, it may consume more memory then expected.

asyncio streams already have low and high watermarks for write buffer size control. If kernel write buffer is full the data is collected in asyncio internal write buffer. If the internal buffer size is greater than high watermark the writing is paused until the size of the buffer doesn't fall to less than the low watermark. After that write is resumed and keeps resumed until the high watermark is reached again.

So, data is effectively buffered even if await stream.write() notation is always used, drain() after multiple sync write() calls doesn't make any value.

I doubt if we need to document it here, in a method reference. Maybe a separate asyncio section about buffering makes sense?
The section is not related to streams itself, low-level protocol.pause_writing() / protocol.resume_writing() supports the same logic.

@1st1
Copy link
Member
1st1 commented Sep 11, 2019

Andrew, reading all of this makes me think about soft-deprecating non-await write() and drain() in the documentation (it will probably take us many releases before we can actually deprecate them, if ever). This will actually encourage people to just write await stream.write() and not touch drain() etc.

@asvetlov
Copy link
Contributor

Andrew, reading all of this makes me think about soft-deprecating non-await write() and drain() in the documentation (it will probably take us many releases before we can actually deprecate them, if ever). This will actually encourage people to just write await stream.write() and not touch drain() etc.

@1st1 I told you at US PyCon that non-awaitable methods are useless and should be deprecated eventually. You had doubts, so we decided to support both.

I totally agree with the deprecation strategy.

Does soft-deprecation means ..deprecated: section or completely removal these API from docs?
The second is more aggressive, sure. But it simplifies documentation writing and (much more important) reading a lot.

@1st1 what do you prefer?

@1st1
Copy link
Member
1st1 commented Sep 11, 2019

Does soft-deprecation means ..deprecated: section or completely removal these API from docs?
The second is more aggressive, sure. But it simplifies documentation writing and (much more important) reading a lot.

I'd do it in a very soft way in 3.8/3.9; basically we just warn users that they are deprecated in the docs and that's it.

@asvetlov
Copy link
Contributor
asvetlov commented Sep 11, 2019

Ok, I agree with any decision.
@tirkarthi please add .. deprecated:: sections.

Sorry for the endless list of notes. Writing a new stream API took me weeks, documenting it takes a long as well.

@tirkarthi
Copy link
Member Author

Added deprecated notes to Stream.drain and method Stream.write to recommending usage of await Stream.write as a coroutine to be awaited. There is also StreamWriter.write and StreamWriter.writelines but they are already recommended to use stream.write and contain examples on using it in 3.7 where await is not supported so I have not added deprecations there.

No problem, I got to know better about the API while documentation and also closed some old and outdated issues related to Streams on the tracker with the PR. Appreciate your help on word formation and care to perfect user facing documentation.

Copy link
Contributor
@asvetlov asvetlov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the current text, looks good.
The last nitpick: please provide an order to Stream methods.
I think alphabetical sorting is better than the current grouping.

@tirkarthi
Copy link
Member Author

Good, done. The current order is alphabetic sort as below with attribute mode at first

mode

abort
at_eof
can_write_eof
close
drain
get_extra_info
is_closing
read
readexactly
readline
readuntil
sendfile
start_tls
wait_closed
write coroutine
write method
writelines
write_eof

``

Copy link
Contributor
@asvetlov asvetlov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done!
Thank you very much!

@asvetlov
Copy link
Contributor

@1st1 please review again. The PR is ready for merging from my perspective

@miss-islington
Copy link
Contributor

@tirkarthi: Status check is done, and it's a success ✅ .

@miss-islington miss-islington merged commit d31b315 into python:master Sep 13, 2019
@miss-islington
Copy link
Contributor

Thanks @tirkarthi for the PR 🌮🎉.. I'm working now to backport this PR to: 3.8.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

I'm having trouble backporting to 3.8. Reason: 'Error 110 while writing to socket. Connection timed out.'. Please retry by removing and re-adding the needs backport to 3.8 label.

@tirkarthi
Copy link
Member Author

Thank you very much Andrew and Yury. I can create a separate PR if there are additional improvements.

@asvetlov
Copy link
Contributor

Oops. Sorry, @1st1
I've added automerge label with the hope that the merge will be blocked until your approval.
@miss-islington has own logic for this situation.

Anyway, please feel free to express your objection if any, @tirkarthi and I can fix them in the following PR quickly.

@miss-islington
Copy link
Contributor

Thanks @tirkarthi for the PR 🌮🎉.. I'm working now to backport this PR to: 3.8.
🐍🍒⛏🤖

@bedevere-bot
Copy link

GH-16087 is a backport of this pull request to the 3.8 branch.

miss-islington added a commit that referenced this pull request Sep 13, 2019
* This just copies the docs from `StreamWriter` and `StreamReader`.
* Add docstring for asyncio functions.

https://bugs.python.org/issue36889

Automerge-Triggered-By: @asvetlov
(cherry picked from commit d31b315)

Co-authored-by: Xtreak <tir.karthi@gmail.com>
aeros added a commit to aeros/cpython that referenced this pull request Sep 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants
0