Python - How can I fetch emails via POP or IMAP through a proxy?

You don't need to dirtily hack imaplib. You could try using the SocksiPy package, which supports socks4, socks5 and http proxy (connect):

Something like this, obviously you'd want to handle the setproxy options better, via extra arguments to a custom __init__ method, etc.

from imaplib import IMAP4, IMAP4_SSL, IMAP4_PORT, IMAP4_SSL_PORT
from socks import sockssocket, PROXY_TYPE_SOCKS4, PROXY_TYPE_SOCKS5, PROXY_TYPE_HTTP

class SocksIMAP4(IMAP4):
    def open(self,host,port=IMAP4_PORT):
        self.host = host
        self.port = port
        self.sock = sockssocket()
        self.sock.setproxy(PROXY_TYPE_SOCKS5,'socks.example.com')
        self.sock.connect((host,port))
        self.file = self.sock.makefile('rb')

You could do similar with IMAP4_SSL. Just take care to wrap it into an ssl socket

import ssl

class SocksIMAP4SSL(IMAP4_SSL):
    def open(self, host, port=IMAP4_SSL_PORT):
        self.host = host
        self.port = port
        #actual privoxy default setting, but as said, you may want to parameterize it
        self.sock = create_connection((host, port), PROXY_TYPE_HTTP, "127.0.0.1", 8118)
        self.sslobj = ssl.wrap_socket(self.sock, self.keyfile, self.certfile)
        self.file = self.sslobj.makefile('rb')

Answer to my own question... There's a quick and dirty way to force trafic from a python script to go through a proxy without hassle using Socksipy (thanks MattH for pointing me that way)

import socks
import socket
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS4,proxy_ip,port,True)
socket.socket = socks.socksocket

That global socket override is obviously a bit brutal, but works as a quick fix till I find the time to properly subclass IMAP4 and IMAP4_SSL.