Python: setup() vs __init__ ()for a socketserver's handler class
Question: I am trying to define a handler class for a `socketserver`. When the handler
class had no `__init__()` method defined, my server worked. The message sent
by the client was written to the output window. However, when I added an
`__init__()` method to declare a class member, my program threw an exception
because `RequestHandlerClass` required exactly one argument, and I was passing
four arguments to it. After pounding my head into a brick wall for a while, I
remembered that the `BaseRequestHandler` class has an override-able `setup()`
method. I declared an override for it and declared my class member inside it,
and it worked.

While I have a solution to my immediate problem, I'd like to understand this.
Should I never declare my own `__init__()` method in a request handler class?
Or if I should, how should it be declared?

Here's my code:

    
    
    import socketserver
    import logging
    import logging.config
    import json
    from TWMSMessageHandler import TWMSMessageHandler
    
    class SingleTCPHandler(socketserver.BaseRequestHandler):
        # def __init__(self):   ## causes an error 
        def setup(self):
            self.messageHandler = TWMSMessageHandler()
    
        # One instance per connection.  Override handle(self) to customize action.
        def handle(self):
            # self.request is the client connection
            data = self.request.recv(1024)  # clip input at 1Kb
    
            dataString = data.decode()
            print ("Received data: " + dataString)
            self.request.close()
    
    class MyTCPServer(socketserver.TCPServer):
    
        def __init__(self, serverAddress, handler):
            super().__init__(serverAddress, handler)
    
        def handle_timeout(self):
            print ("No message received in {0} seconds".format(self.timeout))
    
    if __name__ == "__main__":
        with open('TWMSHandler_log_config.json', 'rt') as f:
            config = json.load(f)
        logging.config.dictConfig(config)
    
        tcpServer = MyTCPServer(("127.0.0.1", 5006), SingleTCPHandler)
        tcpServer.timeout = 30
    
        loopCount = 0
        while loopCount < 5:
            try:
                print ("About to wait for request")
                tcpServer.handle_request()
                print ("Back from handle_request")
                loopCount = loopCount + 1
            except Exception as Value:
                print ("Oops!  " + str(Value))
                break
    


Answer: I'm assuming python 2.7 since you haven't specified otherwise, this should
apply to python 3.x too, however.

If you take a look at the source code
(<https://hg.python.org/cpython/file/2.7/Lib/SocketServer.py#l631>), the
BaseRequestHandler class which you are overriding takes 3 arguments besides
`self`: `request, client_address, server`. If you want to override `__init__`
you must be compatible with this signature, unless you also override the
callsite that calls `__init__` from within the TCPServer inheritance chain
(You don't want to do this).

Since all that function does is to save state you would otherwise have to save
yourself (Or call the base function through a `super` call), you may as well
just use `setup` as you are.

