Skip to content

Commit

Permalink
Issue python#16133: The asynchat.async_chat.handle_read() method now …
Browse files Browse the repository at this point in the history
…ignores

BlockingIOError exceptions. Initial patch written by Xavier de Gaye.

Document also in asyncore documentation that recv() may raise BlockingIOError.
  • Loading branch information
vstinner committed Jul 24, 2014
1 parent 992019c commit 45cff66
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Doc/library/asyncore.rst
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ any that have been added to the map during asynchronous service) is closed.
empty bytes object implies that the channel has been closed from the
other end.

Note that :meth:`recv` may raise :exc:`BlockingIOError` , even though
:func:`select.select` or :func:`select.poll` has reported the socket
ready for reading.


.. method:: listen(backlog)

Expand Down
2 changes: 2 additions & 0 deletions Lib/asynchat.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ def handle_read(self):

try:
data = self.recv(self.ac_in_buffer_size)
except BlockingIOError:
return
except OSError as why:
self.handle_error()
return
Expand Down
17 changes: 17 additions & 0 deletions Lib/test/test_asynchat.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@

import asynchat
import asyncore
import errno
import socket
import sys
import time
import unittest
import unittest.mock
try:
import threading
except ImportError:
Expand Down Expand Up @@ -273,6 +275,21 @@ class TestAsynchat_WithPoll(TestAsynchat):
usepoll = True


class TestAsynchatMocked(unittest.TestCase):
def test_blockingioerror(self):
# Issue #16133: handle_read() must ignore BlockingIOError
sock = unittest.mock.Mock()
sock.recv.side_effect = BlockingIOError(errno.EAGAIN)

dispatcher = asynchat.async_chat()
dispatcher.set_socket(sock)
self.addCleanup(dispatcher.del_channel)

with unittest.mock.patch.object(dispatcher, 'handle_error') as error:
dispatcher.handle_read()
self.assertFalse(error.called)


class TestHelperFunctions(unittest.TestCase):
def test_find_prefix_at_end(self):
self.assertEqual(asynchat.find_prefix_at_end("qwerty\r", "\r\n"), 1)
Expand Down
3 changes: 3 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ Core and Builtins
Library
-------

- Issue #16133: The asynchat.async_chat.handle_read() method now ignores
BlockingIOError exceptions.

- Issue #19884: readline: Disable the meta modifier key if stdout is not
a terminal to not write the ANSI sequence "\033[1034h" into stdout. This
sequence is used on some terminal (ex: TERM=xterm-256color") to enable
Expand Down

0 comments on commit 45cff66

Please sign in to comment.