python / cpython

The Python programming language
https://www.python.org
Other
63.66k stars 30.5k forks source link

socketserver.BaseRequestHandler inherited class #89976

Open 864f0117-0802-4783-a123-34c5202eaed1 opened 3 years ago

864f0117-0802-4783-a123-34c5202eaed1 commented 3 years ago
BPO 45818
Nosy @matsievskiysv

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields: ```python assignee = None closed_at = None created_at = labels = ['type-bug', 'library', '3.9'] title = 'socketserver.BaseRequestHandler inherited class' updated_at = user = 'https://github.com/matsievskiysv' ``` bugs.python.org fields: ```python activity = actor = 'matsievskiysv' assignee = 'none' closed = False closed_date = None closer = None components = ['Library (Lib)'] creation = creator = 'matsievskiysv' dependencies = [] files = [] hgrepos = [] issue_num = 45818 keywords = [] message_count = 1.0 messages = ['406413'] nosy_count = 1.0 nosy_names = ['matsievskiysv'] pr_nums = [] priority = 'normal' resolution = None stage = None status = 'open' superseder = None type = 'behavior' url = 'https://bugs.python.org/issue45818' versions = ['Python 3.9'] ```

864f0117-0802-4783-a123-34c5202eaed1 commented 3 years ago

Due to

try:
    self.handle()
finally:
    self.finish()

construct in socketserver.BaseRequestHandler.__init__() method inherited classes with overrided __init__() method may suffer from incomplete initialization. For example, in the following snippet

def __init__(self, request, client_address, server):
    super().__init__(request, client_address, server)
    self.foo = 1

in some cases all the code after super() call will not be executed.

This is a MWE of the server with partially initialized Handler class

from socketserver import UnixStreamServer, StreamRequestHandler, ForkingMixIn

class Handler(StreamRequestHandler):
    def __init__(self, request, client_address, server):
        super().__init__(request, client_address, server)
        self.foo = 1

    def handle(self):
        print(self.foo)

class ThreadedUnixStreamServer(ForkingMixIn, UnixStreamServer):
    pass

with ThreadedUnixStreamServer("/tmp/test.socket", Handler) as server:
    server.serve_forever()