def _idle(self):
        """
        since imaplib doesn't support IMAP4r1 IDLE, we'll do it by hand
        """
        socket = None

        try:
            # build a new command tag (Xnnn) as bytes:
            self.command_tag = (self.command_tag + 1) % 1000
            command_tag = b"X" + bytes(str(self.command_tag).zfill(3), "ascii")

            # make sure we have selected anything before idling:
            directories = self.mailbox.split(",")
            self.connection.select(directories[0])

            socket = self.connection.socket()

            # send IDLE command and check response:
            socket.write(command_tag + b" IDLE\r\n")
            try:
                response = socket.read(4096).decode("ascii")
            except socket_error:
                raise imaplib.IMAP4.abort("Server didn't respond to 'IDLE' in time")
            # Dovecot will responde with "+ idling", courier will return "+ entering idle mode"
            # RFC 2177 (https://tools.ietf.org/html/rfc2177) only requires the "+" character.
            if not response.lower().startswith("+"):
                raise imaplib.IMAP4.abort(f"While initializing IDLE: {response}")

            # wait for changes (EXISTS, EXPUNGE, etc.):
            socket.settimeout(self.cache_timeout)
            while True:
                try:
                    response = socket.read(4096).decode("ascii")
                    if response.upper().startswith("* OK"):
                        continue  # ignore '* OK Still here'
                    else:
                        break
                except socket_error:  # IDLE timed out
                    break

        finally:  # terminate IDLE command gracefully
            if socket is None:
                return

            socket.settimeout(self.read_timeout)
            socket.write(b"DONE\r\n")  # important! Can't query IMAP again otherwise
            try:
                response = socket.read(4096).decode("ascii")
            except socket_error:
                raise imaplib.IMAP4.abort("Server didn't respond to 'DONE' in time")

            # sometimes, more messages come in between reading and DONEing; so read them again:
            if response.startswith("* "):
                try:
                    response = socket.read(4096).decode("ascii")
                except socket_error:
                    raise imaplib.IMAP4.abort("Server sent more continuations, but no 'DONE' ack")

            expected_response = (command_tag + b" OK").decode("ascii")
            if not response.lower().startswith(expected_response.lower()):
                raise imaplib.IMAP4.abort("While terminating IDLE: " + response)

        since imaplib doesn't support IMAP4r1 IDLE, we'll do it by hand
        
py3status/modules/imap.py