Skip to content

Commit 317b09a

Browse files
committed
add a new is_readable method to SocketType (fix #760)
1 parent 0b0feb2 commit 317b09a

File tree

4 files changed

+35
-1
lines changed

4 files changed

+35
-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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
We added a new ``is_readable`` method to the ``trio.socket.SocketType``
2+
object that allows you to check whether a socket is ready to be read
3+
or not.

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: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,23 @@ async def test_SocketType_simple_server(address, socket_type):
404404
assert await client.recv(1) == b"x"
405405

406406

407+
async def test_SocketTupe_is_readable():
408+
listener = tsocket.socket(tsocket.AF_INET)
409+
client = tsocket.socket(tsocket.AF_INET)
410+
with listener, client:
411+
await listener.bind(('127.0.0.1', 0))
412+
listener.listen(20)
413+
addr = listener.getsockname()[:2]
414+
async with _core.open_nursery() as nursery:
415+
nursery.start_soon(client.connect, addr)
416+
server, client_addr = await listener.accept()
417+
with server:
418+
assert not client.is_readable()
419+
await server.send(b"x")
420+
assert client.is_readable()
421+
assert await client.recv(1) == b"x"
422+
423+
407424
# On some macOS systems, getaddrinfo likes to return V4-mapped addresses even
408425
# when we *don't* pass AI_V4MAPPED.
409426
# https://github.com/python-trio/trio/issues/580

0 commit comments

Comments
 (0)