diff --git a/Lib/asynchat.py b/Lib/asynchat.py index ae82cfadcd0..65585129cea 100644 --- a/Lib/asynchat.py +++ b/Lib/asynchat.py @@ -77,7 +77,7 @@ class async_chat (asyncore.dispatcher): use_encoding = 0 encoding = 'latin1' - def __init__ (self, conn=None): + def __init__ (self, sock=None, map=None): # for string terminator matching self.ac_in_buffer = b'' @@ -92,7 +92,7 @@ class async_chat (asyncore.dispatcher): # we toss the use of the "simple producer" and replace it with # a pure deque, which the original fifo was a wrapping of self.producer_fifo = deque() - asyncore.dispatcher.__init__ (self, conn) + asyncore.dispatcher.__init__ (self, sock, map) def collect_incoming_data(self, data): raise NotImplementedError("must be implemented in subclass") diff --git a/Lib/asyncore.py b/Lib/asyncore.py index e82d24bf4ff..586358cff1a 100644 --- a/Lib/asyncore.py +++ b/Lib/asyncore.py @@ -98,8 +98,10 @@ def readwrite(obj, flags): obj.handle_read_event() if flags & select.POLLOUT: obj.handle_write_event() - if flags & (select.POLLERR | select.POLLHUP | select.POLLNVAL): + if flags & (select.POLLERR | select.POLLNVAL): obj.handle_expt_event() + if flags & select.POLLHUP: + obj.handle_close_event() except (ExitNow, KeyboardInterrupt, SystemExit): raise except: @@ -466,7 +468,7 @@ class dispatcher: ), 'error' ) - self.close() + self.handle_close() def handle_expt(self): self.log_info('unhandled exception', 'warning') diff --git a/Lib/test/test_asyncore.py b/Lib/test/test_asyncore.py index 716368b84f6..335bdede32c 100644 --- a/Lib/test/test_asyncore.py +++ b/Lib/test/test_asyncore.py @@ -39,6 +39,7 @@ class exitingdummy: raise asyncore.ExitNow() handle_write_event = handle_read_event + handle_close_event = handle_read_event handle_expt_event = handle_read_event class crashingdummy: @@ -49,6 +50,7 @@ class crashingdummy: raise Exception() handle_write_event = handle_read_event + handle_close_event = handle_read_event handle_expt_event = handle_read_event def handle_error(self): @@ -118,6 +120,7 @@ class HelperFunctionTests(unittest.TestCase): def __init__(self): self.read = False self.write = False + self.closed = False self.expt = False def handle_read_event(self): @@ -126,6 +129,9 @@ class HelperFunctionTests(unittest.TestCase): def handle_write_event(self): self.write = True + def handle_close_event(self): + self.closed = True + def handle_expt_event(self): self.expt = True @@ -168,9 +174,9 @@ class HelperFunctionTests(unittest.TestCase): for flag in (select.POLLERR, select.POLLHUP, select.POLLNVAL): tobj = testobj() - self.assertEqual(tobj.expt, False) + self.assertEqual((tobj.expt, tobj.closed)[flag == select.POLLHUP], False) asyncore.readwrite(tobj, flag) - self.assertEqual(tobj.expt, True) + self.assertEqual((tobj.expt, tobj.closed)[flag == select.POLLHUP], True) # check that ExitNow exceptions in the object handler method # bubbles all the way up through asyncore readwrite calls