Skip to content

Commit

Permalink
Merge pull request #1137 from python-trio/gh-760
Browse files Browse the repository at this point in the history
add a new is_readable method to SocketType (fix #760)
  • Loading branch information
njsmith authored Jul 6, 2019
2 parents feca09e + 10cf005 commit 254ded3
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 1 deletion.
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

0 comments on commit 254ded3

Please sign in to comment.