Search code examples
pythonimaplib

Does Python's imaplib let you set a timeout?


I'm looking at the API for Python's imaplib.

From what I can tell, there is no way to setup a timeout like you can with smtplib.

Is that correct? How would you handle a host that's invalid if you don't want it to block?


Solution

  • The imaplib module doesn't provide a way to set timeout, but you can set a default timeout for new socket connections via the socket.setdefaulttimeout:

    import socket
    import imaplib
    socket.setdefaulttimeout(10)
    imap = imaplib.IMAP4('test.com', 666)
    

    Or you can also go about overriding the imaplib.IMAP4 class with some knowledge from imaplib source and docs, which provides better control:

    import imaplib
    import socket
    
    class IMAP(imaplib.IMAP4):
        def __init__(self, host='', port=imaplib.IMAP4_PORT, timeout=None):
            self.timeout = timeout
            # no super(), it's an old-style class
            imaplib.IMAP4.__init__(self, host, port)
    
        def open(self, host='', port=imaplib.IMAP4_PORT):
            self.host = host
            self.port = port
            self.sock = socket.create_connection((host, port), timeout=self.timeout)
            # clear timeout for socket.makefile, needs blocking mode
            self.sock.settimeout(None)
            self.file = self.sock.makefile('rb')
    

    Note that after creating the connection we should set the socket timeout back to None to get it to blocking mode for subsequent socket.makefile call, as stated in the method docs:

    ... The socket must be in blocking mode (it can not have a timeout). ...