Commit 316b16de authored by Victor Stinner's avatar Victor Stinner

(Merge 3.4) 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.
parents e1d24f7e 45cff66c
...@@ -216,6 +216,10 @@ any that have been added to the map during asynchronous service) is closed. ...@@ -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)
......
...@@ -115,6 +115,8 @@ class async_chat(asyncore.dispatcher): ...@@ -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
......
...@@ -7,11 +7,13 @@ thread = support.import_module('_thread') ...@@ -7,11 +7,13 @@ 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 warnings import warnings
import unittest.mock
try: try:
import threading import threading
except ImportError: except ImportError:
...@@ -274,6 +276,21 @@ class TestAsynchat_WithPoll(TestAsynchat): ...@@ -274,6 +276,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)
......
...@@ -108,6 +108,9 @@ Core and Builtins ...@@ -108,6 +108,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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment