changeset: 91832:aa150c7a5d24 parent: 91829:5d70ac83d104 parent: 91831:b7f144d14798 user: Victor Stinner date: Thu Jul 24 19:00:28 2014 +0200 files: Lib/asynchat.py Lib/test/test_asynchat.py Misc/NEWS description: (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. diff -r 5d70ac83d104 -r aa150c7a5d24 Doc/library/asyncore.rst --- a/Doc/library/asyncore.rst Thu Jul 24 12:44:07 2014 +0200 +++ b/Doc/library/asyncore.rst Thu Jul 24 19:00:28 2014 +0200 @@ -216,6 +216,10 @@ 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) diff -r 5d70ac83d104 -r aa150c7a5d24 Lib/asynchat.py --- a/Lib/asynchat.py Thu Jul 24 12:44:07 2014 +0200 +++ b/Lib/asynchat.py Thu Jul 24 19:00:28 2014 +0200 @@ -115,6 +115,8 @@ try: data = self.recv(self.ac_in_buffer_size) + except BlockingIOError: + return except OSError as why: self.handle_error() return diff -r 5d70ac83d104 -r aa150c7a5d24 Lib/test/test_asynchat.py --- a/Lib/test/test_asynchat.py Thu Jul 24 12:44:07 2014 +0200 +++ b/Lib/test/test_asynchat.py Thu Jul 24 19:00:28 2014 +0200 @@ -7,11 +7,13 @@ import asynchat import asyncore +import errno import socket import sys import time import unittest import warnings +import unittest.mock try: import threading except ImportError: @@ -274,6 +276,21 @@ 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) diff -r 5d70ac83d104 -r aa150c7a5d24 Misc/NEWS --- a/Misc/NEWS Thu Jul 24 12:44:07 2014 +0200 +++ b/Misc/NEWS Thu Jul 24 19:00:28 2014 +0200 @@ -108,6 +108,9 @@ 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