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

BlockingIOError exceptions. Initial patch written by Xavier de Gaye.

Document also in asyncore documentation that recv() may raise BlockingIOError.
This commit is contained in:
Victor Stinner 2014-07-24 18:49:36 +02:00
parent 992019c006
commit 45cff66cf6
4 changed files with 26 additions and 0 deletions

View File

@ -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 empty bytes object implies that the channel has been closed from the
other end. 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) .. method:: listen(backlog)

View File

@ -115,6 +115,8 @@ class async_chat(asyncore.dispatcher):
try: try:
data = self.recv(self.ac_in_buffer_size) data = self.recv(self.ac_in_buffer_size)
except BlockingIOError:
return
except OSError as why: except OSError as why:
self.handle_error() self.handle_error()
return return

View File

@ -7,10 +7,12 @@ thread = support.import_module('_thread')
import asynchat import asynchat
import asyncore import asyncore
import errno
import socket import socket
import sys import sys
import time import time
import unittest import unittest
import unittest.mock
try: try:
import threading import threading
except ImportError: except ImportError:
@ -273,6 +275,21 @@ class TestAsynchat_WithPoll(TestAsynchat):
usepoll = True 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): class TestHelperFunctions(unittest.TestCase):
def test_find_prefix_at_end(self): def test_find_prefix_at_end(self):
self.assertEqual(asynchat.find_prefix_at_end("qwerty\r", "\r\n"), 1) self.assertEqual(asynchat.find_prefix_at_end("qwerty\r", "\r\n"), 1)

View File

@ -27,6 +27,9 @@ Core and Builtins
Library 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 - 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 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 sequence is used on some terminal (ex: TERM=xterm-256color") to enable