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

add a new is_readable method to SocketType (fix #760) #1137

Merged
merged 2 commits into from
Jul 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/source/reference-io.rst
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,10 @@ Socket objects
left in an unknown state – possibly open, and possibly
closed. The only reasonable thing to do is to close it.

.. method:: is_readable

Check whether the socket is readable or not.

.. method:: sendfile

`Not implemented yet! <https://github.com/python-trio/trio/issues/45>`__
Expand Down
2 changes: 2 additions & 0 deletions newsfragments/760.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Trio sockets have a new method `~trio.socket.SocketType.is_readable` that allows
you to check whether a socket is readable. This is useful for HTTP/1.1 clients.
12 changes: 11 additions & 1 deletion trio/_socket.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os as _os
import sys as _sys
import select
import socket as _stdlib_socket
from functools import wraps as _wraps

Expand Down Expand Up @@ -289,7 +290,7 @@ def socket(

def _sniff_sockopts_for_fileno(family, type, proto, fileno):
"""Correct SOCKOPTS for given fileno, falling back to provided values.

"""
# Wrap the raw fileno into a Python socket object
# This object might have the wrong metadata, but it lets us easily call getsockopt
Expand Down Expand Up @@ -478,6 +479,15 @@ def shutdown(self, flag):
if flag in [_stdlib_socket.SHUT_WR, _stdlib_socket.SHUT_RDWR]:
self._did_shutdown_SHUT_WR = True

def is_readable(self):
# use select.select on Windows, and select.poll everywhere else
if _sys.platform == "win32":
rready, _, _ = select.select([self._sock], [], [], 0)
return bool(rready)
p = select.poll()
p.register(self._sock, select.POLLIN)
return bool(p.poll(0))

async def wait_writable(self):
await _core.wait_writable(self._sock)

Expand Down
11 changes: 11 additions & 0 deletions trio/tests/test_socket.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,17 @@ async def test_SocketType_simple_server(address, socket_type):
assert await client.recv(1) == b"x"


async def test_SocketType_is_readable():
a, b = tsocket.socketpair()
with a, b:
assert not a.is_readable()
await b.send(b"x")
await _core.wait_readable(a)
assert a.is_readable()
assert await a.recv(1) == b"x"
assert not a.is_readable()


# On some macOS systems, getaddrinfo likes to return V4-mapped addresses even
# when we *don't* pass AI_V4MAPPED.
# https://github.com/python-trio/trio/issues/580
Expand Down