-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Bad docs, or bad types for asyncio.WriteTransport? #5779
Comments
I am sorry for the late response. I am also unsure what to do here. Do you have any real world examples, where this causes problems? If that's the case, I suggest, we add |
(Please, no apology is necessary. Thank you for your open source contributions!) The real-world case it came up for is when I was trying to write a function to change the buffer limits -- itself something I was trying to do in order to coerce flush into guaranteeing that I had drained the entirety of the write buffer -- but, let's not worry about that. async def flush(writer: asyncio.StreamWriter) -> None:
transport = cast(asyncio.WriteTransport, writer.transport)
low, high = transport.get_write_buffer_limits() # <-- this line causes a problem
transport.set_write_buffer_limits(0, 0)
try:
await writer.drain()
finally:
transport.set_write_buffer_limits(high, low) I have to cast in the first place because writer.transport is known to mypy as Even with the cast, though, we still don't gain problem-free access to Maybe the right thing here really is a python bugfix to make the method abstract in the type that suggests it, then change typeshed to match. |
FWIW, I'd accept a PR to typeshed as outlined above. This method is part of the protocol, even if it's not "physically" present in the implementation. |
I fixed this in #7611, but the class Client:
def __init__(self, ..., writer: asyncio.StreamWriter) -> None:
...
self._writer = writer
...
...
def _send_bytes(self, b: bytes) -> None:
...
if self._writer.transport.get_write_buffer_size() > 4 * 1024: # type: ignore
... I agree we should just add |
Turns out I was confused. It's already fixed, but only if you target Python 3.9 or newer. The following program produces the same output consistently on Python 3.6 and all newer versions, when you connect to localhost port 12345 while it's running:
It only type-checks with typeshed/stdlib/asyncio/transports.pyi Lines 28 to 32 in 02310d9
|
I have to admit I am not fully certain of this one, there's a few layers of abstraction to sift through.
Typeshed declares this:
Which does seem true: CPython does indeed define get_write_buffer_limits() as part of that
_FlowControlMixin
class. Where I lose the plot, however, is the fact that https://docs.python.org/3/library/asyncio-protocol.html#write-only-transports seems to imply that allasyncio.WriteTransport
types will offer this method. In practice, I suppose that isn't strictly true, since the CPython implementation declares the class like this:And does not in fact guarantee the presence of this method. It turns out that the actual type of the transport beneath the StreamWriter that I have is ...
asyncio.selector_events._SelectorSocketTransport
, which inherits from_SelectorTransport
, which in turn inherits fromtransports._FlowControlMixin
andtransports.Transport
, the latter of which inherits from bothReadTransport
andWriteTransport
.Phew, OK.
I suppose this means the docs are "wrong" in the sense that
WriteTransport
does not necessarily guarantee the presence of this method, but "in practice" all implementations ofWriteTransport
use the_FlowControlMixin
that offers it.Does the WriteTransport class just need a
NotImplementedError
stub forget_write_buffer_limits()
...? or is it intentional that this method isn't required and the docs are wrong?The text was updated successfully, but these errors were encountered: