An IMAP SSL connection can travel through SOCKS while keeping the mail server as its TLS peer. The useful integration point is where the client creates its transport, before the normal IMAP greeting and capability handling begin.

For CPython 3.14, the following illustrates a small adapter using PySocks. It overrides a private transport hook, so keep it tied to the imaplib version being maintained:

import imaplib
import ssl
import socks

class SocksIMAP4SSL(imaplib.IMAP4_SSL):
    def _create_socket(self, timeout):
        stream = socks.create_connection(
            (self.host, self.port),
            timeout=timeout,
            proxy_type=socks.SOCKS5,
            proxy_addr="proxy.example",
            proxy_port=1080,
            proxy_rdns=True,
        )
        try:
            return self.ssl_context.wrap_socket(
                stream, server_hostname=self.host)
        except Exception:
            stream.close()
            raise

context = ssl.create_default_context()
with SocksIMAP4SSL("imap.example", ssl_context=context,
                  timeout=15) as mailbox:
    mailbox.noop()

The names and port are placeholders for an already available proxy and IMAP service. For a public IMAP destination permitted to use public proxies, the SOCKS5 proxy list provides candidates; each must allow the required mail host and port. The PySocks dependency supplies SOCKS negotiation; imaplib still initializes the mail session. No global socket.socket replacement is involved.

Preserve the mail server’s identity

The TLS hostname remains imap.example. It is not the SOCKS hostname. Passing ssl.create_default_context() deliberately enables normal certificate and hostname checks; an encrypted socket alone is not enough to establish those checks.

proxy_rdns=True asks the SOCKS path to handle the destination hostname. If the proxy requires an account, its supported credential arguments belong to that transport configuration. They do not log in to the mailbox.

Leave session initialization with imaplib

The adapter returns the TLS stream to the normal constructor. Reimplementing open() from an old example can miss timeout parameters, buffering and other initialization expectations. In CPython 3.14, even the legacy file access is a compatibility property rather than a field to reconstruct freely.

On a library upgrade, review this private hook against the matching source. If maintaining a subclass is unsuitable, choose a mail client with a documented proxy transport interface. Either arrangement should preserve the same separation: proxy connection, destination TLS verification, then IMAP authentication.

Winndannde jowitiiɗe heen