Hi, folks.
Anyone who has used python to check an email account is probably aware of imaplib, its useful-but-basic support for the protocol, and its unfortunate lack of certain features that are widely expected and implemented in IMAP servers today.
One such feature is the IDLE command (defined in rfc2177 and rfc9051), which would allow the server to push events to a client as they occur, avoiding the need to continually poll for mailbox changes. I think it’s fair to say this would make the module significantly more useful, as it comes up every so often in the python mailing lists and bug tracker.
As can be seen in issue 55454, several people have suggested solutions for this in the past, either by submitting small patches or by proposing the total replacement of imaplib. I recently found myself needing IMAP IDLE, so I spent some time looking over the patches in that bug report, and exploring the three alternative IMAP libraries that were proposed in this python-ideas thread.
IMHO, none of the those proposed solutions is appropriate for the standard library, since they all suffer from one or more of these problems:
- Leaving edge cases unhandled.
- Imposing new runtime complexities (notably multithreading) on programs and libraries that already use imaplib.
- Using standard library functions in ways that python’s documentation warns against.
- Presenting an error-prone or awkward API to the programmer.
Since I wasn’t satisfied with what was available, I wrote my own. Here are some notable differences from the other approaches I’ve seen:
- It’s an extension to imaplib, rather than a replacement.
- It doesn’t introduce additional threads.
- It doesn’t impose new requirements on the use of imaplib’s existing methods.
- It passes the unit tests in CPython’s test/test_imaplib.py module.
- It works on Windows, Linux, and other unix-like systems.
- It makes IDLE available on all of imaplib’s client variants (including IMAP4_stream).
- The interface is pythonic and easy to use.
To get an idea of its capabilities and how it looks to use it, please see the examples I wrote up in this comment on the issue tracker.
Two caveats:
- Due to a Windows limitation, the special case of IMAP4_stream running on Windows lacks a duraton/timeout feature. (This is the stdin/stdout pipe connection variant; timeouts work fine for socket-based connections, even on Windows.) I have documented it where appropriate.
- The file-like imaplib instance attributes are chagned from buffered to unbuffered mode. This could potentially break any client code that uses those objects directly without expecting partial reads/writes. However, these attributes are undocumented. As such, I think they are fair game for changes, and any code that uses them directly (circumventing the documented interface) has only itself to blame if it breaks. While this case could be supported through additional work, it would also add complexity to the library, which I feel is worth avoiding if possible.
I’m writing here to gauge interest in this work. I already use it daily, and I think it would be a helpful improvement to imaplib. If others agree, I could prepare a public repo so folks could experiment with it, and potentially submit it as a patch to the standard library.
If submitting it as a contribution, I would need some guidance from python maintainers, since I haven’t contributed code to Python before. (At least, not that I recall.)
Thanks for reading.