Skip to content

Commit 254ded3

Browse files
authored
Merge pull request #1137 from python-trio/gh-760
add a new is_readable method to SocketType (fix #760)
2 parents feca09e + 10cf005 commit 254ded3

File tree

4 files changed

+28
-1
lines changed

4 files changed

+28
-1
lines changed

docs/source/reference-io.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,10 @@ Socket objects
403403
left in an unknown state – possibly open, and possibly
404404
closed. The only reasonable thing to do is to close it.
405405

406+
.. method:: is_readable
407+
408+
Check whether the socket is readable or not.
409+
406410
.. method:: sendfile
407411

408412
`Not implemented yet! <https://github.com/python-trio/trio/issues/45>`__

newsfragments/760.feature.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Trio sockets have a new method `~trio.socket.SocketType.is_readable` that allows
2+
you to check whether a socket is readable. This is useful for HTTP/1.1 clients.

trio/_socket.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os as _os
22
import sys as _sys
3+
import select
34
import socket as _stdlib_socket
45
from functools import wraps as _wraps
56

@@ -289,7 +290,7 @@ def socket(
289290

290291
def _sniff_sockopts_for_fileno(family, type, proto, fileno):
291292
"""Correct SOCKOPTS for given fileno, falling back to provided values.
292-
293+
293294
"""
294295
# Wrap the raw fileno into a Python socket object
295296
# This object might have the wrong metadata, but it lets us easily call getsockopt
@@ -478,6 +479,15 @@ def shutdown(self, flag):
478479
if flag in [_stdlib_socket.SHUT_WR, _stdlib_socket.SHUT_RDWR]:
479480
self._did_shutdown_SHUT_WR = True
480481

482+
def is_readable(self):
483+
# use select.select on Windows, and select.poll everywhere else
484+
if _sys.platform == "win32":
485+
rready, _, _ = select.select([self._sock], [], [], 0)
486+
return bool(rready)
487+
p = select.poll()
488+
p.register(self._sock, select.POLLIN)
489+
return bool(p.poll(0))
490+
481491
async def wait_writable(self):
482492
await _core.wait_writable(self._sock)
483493

trio/tests/test_socket.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,17 @@ async def test_SocketType_simple_server(address, socket_type):
404404
assert await client.recv(1) == b"x"
405405

406406

407+
async def test_SocketType_is_readable():
408+
a, b = tsocket.socketpair()
409+
with a, b:
410+
assert not a.is_readable()
411+
await b.send(b"x")
412+
await _core.wait_readable(a)
413+
assert a.is_readable()
414+
assert await a.recv(1) == b"x"
415+
assert not a.is_readable()
416+
417+
407418
# On some macOS systems, getaddrinfo likes to return V4-mapped addresses even
408419
# when we *don't* pass AI_V4MAPPED.
409420
# https://github.com/python-trio/trio/issues/580

0 commit comments

Comments
 (0)