pythonpython-3.xasyncore

asyncore.dispatcher_with_send.send() returns None


I have the following code:

class Handler(asyncore.dispatcher_with_send):
    def __init__(self, class_, sock):
        super().__init__(sock)
        # ...

    # ...

    def writable(self):
        return self.generator or self._out_buffer
    def handle_write(self):
        # ...

        sent = self.send(self._out_buffer)
        import sys
        print(self._out_buffer)
        sys.stdout.flush()
        assert sent is not None
        # ...
        self._out_buffer = self._out_buffer[sent:]
        if not self._out_buffer:
            print('Closing connection.')
            self.close()

    def handle_close(self):
        print('connection closed.')
        super().handle_close()

Whose output is:

Incoming connection from ('127.0.0.1', 39045)
b'400 Bad Request\r\n\r\n'
error: uncaptured python exception, closing channel <ppp_libmodule.async_http.Handler connected 127.0.0.1:39045 at 0x7f27c9ab6d30> (<class 'AssertionError'>: [/usr/lib/python3.4/asyncore.py|write|91] [/usr/lib/python3.4/asyncore.py|handle_write_event|461] [/home/progval/.local/lib/python3.4/site-packages/ppp_libmodule-0.7.2-py3.4.egg/ppp_libmodule/async_http.py|handle_write|71])
connection closed.

As you can see, the assertion sent is not None fails.

However, according to the example given for handle_write, self.send() should only return an integer. And the socket has not been closed, since handle_close is called after the assertion fails.

And the client receives the data in the buffer.

Any idea of what I am doing wrong / did not understand?


Solution

  • class Handler(asyncore.dispatcher_with_send):
        ...
        sent = self.send(self._out_buffer)
        assert sent is not None
    

    asyncore.dispatcher_with_send:

    class dispatcher_with_send(dispatcher):
        ...    
        def send(self, data):
            if self.debug:
                self.log_info('sending %s' % repr(data))
            self.out_buffer = self.out_buffer + data
            self.initiate_send()
    

    dispatcher_with_send.send returns nothing, so your assert fails.

    The example uses asyncore.dispatcher, whose send method returns number of bytes sent.