Kaydet (Commit) fe9ebe4f authored tarafından Victor Stinner's avatar Victor Stinner

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

socket.error() exceptions with blocking I/O errors: EAGAIN, EALREADY,
EINPROGRESS, or EWOULDBLOCK. Initial patch written by Xavier de Gaye.
üst 186f6654
......@@ -193,6 +193,11 @@ any that have been added to the map during asynchronous service) is closed.
Read at most *buffer_size* bytes from the socket's remote end-point. An
empty string implies that the channel has been closed from the other end.
Note that :meth:`recv` may raise :exc:`socket.error` with
:data:`~errno.EAGAIN` or :data:`~errno.EWOULDBLOCK`, even though
:func:`select.select` or :func:`select.poll` has reported the socket
ready for reading.
.. method:: listen(backlog)
......
......@@ -46,12 +46,17 @@ method) up to the terminator, and then control will be returned to
you - by calling your self.found_terminator() method.
"""
import socket
import asyncore
import errno
import socket
from collections import deque
from sys import py3kwarning
from warnings import filterwarnings, catch_warnings
_BLOCKING_IO_ERRORS = (errno.EAGAIN, errno.EALREADY, errno.EINPROGRESS,
errno.EWOULDBLOCK)
class async_chat (asyncore.dispatcher):
"""This is an abstract class. You must derive from this class, and add
the two methods collect_incoming_data() and found_terminator()"""
......@@ -109,6 +114,8 @@ class async_chat (asyncore.dispatcher):
try:
data = self.recv (self.ac_in_buffer_size)
except socket.error, why:
if why.args[0] in _BLOCKING_IO_ERRORS:
return
self.handle_error()
return
......
# test asynchat
import asyncore, asynchat, socket, time
import errno
import asyncore
import asynchat
import socket
import time
import unittest
import sys
from test import test_support
......@@ -235,6 +239,31 @@ class TestAsynchat(unittest.TestCase):
class TestAsynchat_WithPoll(TestAsynchat):
usepoll = True
class TestAsynchatMocked(unittest.TestCase):
def test_blockingioerror(self):
# Issue #16133: handle_read() must ignore blocking I/O errors like
# EAGAIN
class fake_socket:
def fileno(self):
return 0
def recv(self, size):
raise socket.error(errno.EAGAIN, "EAGAIN")
class MyChat(asynchat.async_chat):
def handle_error(self):
raise Exception("error")
sock = fake_socket()
dispatcher = MyChat()
dispatcher.set_socket(sock)
self.addCleanup(dispatcher.del_channel)
# must not call handle_error()
dispatcher.handle_read()
class TestHelperFunctions(unittest.TestCase):
def test_find_prefix_at_end(self):
self.assertEqual(asynchat.find_prefix_at_end("qwerty\r", "\r\n"), 1)
......@@ -267,6 +296,7 @@ class TestFifo(unittest.TestCase):
def test_main(verbose=None):
test_support.run_unittest(TestAsynchat, TestAsynchat_WithPoll,
TestAsynchatMocked,
TestHelperFunctions, TestFifo)
if __name__ == "__main__":
......
......@@ -13,6 +13,10 @@ Core and Builtins
Library
-------
- Issue #16133: The asynchat.async_chat.handle_read() method now ignores
socket.error() exceptions with blocking I/O errors: EAGAIN, EALREADY,
EINPROGRESS, or EWOULDBLOCK.
- Issue #1730136: Fix the comparison between a tkFont.Font and an object of
another kind.
......
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