IMAP4WithTimeout is broken on Python 3.14 with imapclient 3.1.0.
Traceback:
File "/home/jirka642/PycharmProjects/odoo_17/messaging/.venv/lib/python3.14/site-packages/imapclient/imapclient.py", line 288, in __init__
self._imap = self._create_IMAP4()
~~~~~~~~~~~~~~~~~~^^
File "/home/jirka642/PycharmProjects/odoo_17/messaging/.venv/lib/python3.14/site-packages/imapclient/imapclient.py", line 332, in _create_IMAP4
return imap4.IMAP4WithTimeout(self.host, self.port, connect_timeout)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/jirka642/PycharmProjects/odoo_17/messaging/.venv/lib/python3.14/site-packages/imapclient/imap4.py", line 13, in __init__
imaplib.IMAP4.__init__(self, address, port)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.14/imaplib.py", line 208, in __init__
self.open(host, port, timeout)
~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
File "/home/jirka642/PycharmProjects/odoo_17/messaging/.venv/lib/python3.14/site-packages/imapclient/imap4.py", line 22, in open
self.file = self.sock.makefile("rb")
^^^^^^^^^
AttributeError: property 'file' of 'IMAP4WithTimeout' object has no setter
I have been able to hotfix it like this, but that might not be the correct way to do it:
class FixedIMAP4WithTimeout(imaplib.IMAP4):
def __init__(self, host: str = "", port: int = 143, timeout: float | None = None) -> None:
self._timeout = timeout
super().__init__(host=host, port=port, timeout=timeout)
def _create_socket(self, timeout: float | None = None) -> socket.socket:
timeout = timeout if timeout is not None else self._timeout
return super()._create_socket(timeout=timeout)
class FixedIMAPClient(imapclient.IMAPClient):
def _create_IMAP4(self) -> imaplib.IMAP4:
if not self.stream and not self.ssl:
connect_timeout = getattr(self._timeout, "connect", None)
return FixedIMAP4WithTimeout(self.host, self.port, connect_timeout)
return super()._create_IMAP4()
IMAP4WithTimeoutis broken on Python 3.14 with imapclient 3.1.0.Traceback:
I have been able to hotfix it like this, but that might not be the correct way to do it: