gh-49555: Support international mailbox names in imaplib#153391
Conversation
Non-ASCII mailbox names are now encoded as modified UTF-7 (RFC 3501, section 5.1.3), so they can be passed as an ordinary str. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Documentation build overview
|
bitdancer
left a comment
There was a problem hiding this comment.
I was working on this review before the PR was merged. There are no code comments here, this is all about comments and documentation. So feel free to ignore it, but I'm going to submit it anyway in case it is useful.
|
|
||
| * Non-ASCII mailbox names are now automatically encoded as modified UTF-7 | ||
| (:rfc:`3501`, section 5.1.3), so international mailbox names can be passed | ||
| as ordinary :class:`str`. |
There was a problem hiding this comment.
Maybe add "even if UTF8=ACCEPT" has not been enabled? Or, if passing mailbox names as strings wasn't previously supported then this should be rephrased with that as the primary point and when utf-7 vs utf-8 is used explained after.
| # UTF-7 token -- one that needs no quoting, or an explicitly quoted | ||
| # string -- is passed through unchanged, so that a name obtained as raw | ||
| # bytes from LIST (and decoded as ASCII) round-trips without being | ||
| # encoded again. Pass bytes to bypass encoding entirely. |
There was a problem hiding this comment.
"Pass bytes to bypass encoding entirely" doesn't seem to apply to this function itself? I think that sentence applies to _mailbox, and more importantly to API functions that expect mailbox names. So that should be clarified somehow if I'm correct (maybe just moving the slightly modified comment to _mailbox). If a later programmer tried to pass bytes to _encode_mailbox it wouldn't do what that sentence of the comment says, unless I'm misunderstanding.
It also might be good to mention that _encoding can/should only ever be either ascii or utf-8, but that's optional ;)
| return raw | ||
| except UnicodeDecodeError: | ||
| pass | ||
| return arg.encode('utf-7-imap') |
There was a problem hiding this comment.
Is this a slight change in behavior? If I understand what this is doing correctly, if the string can be encoded to ascii it gets encoded to utf-7-imap in order to encode any & characters. But before this those would have just been passed through? Is this worth calling out in the changelog note, if I'm correct?
|
Thanks, this was useful -- not something to ignore. I've addressed all three points in #153485. The behavior changed only for invalid cases. For example, 'A&B' is not valid modified UTF-7 and could be rejected by the server, so it is now encoded correctly as 'A&-B' rather than sent as is. If it is valid modified UTF-7, like 'A&-B', it is sent as is. And all this affects only the default, non-UTF-8 mode. I clarified this in the changelog note. I rushed to merge this PR because it is relatively simple, and is a prerequisite of the stack of three large changes I am now working on (accepting structured arguments instead of preformatted strings, parsing results into structured data instead of returning raw bytes (optional), and supporting streaming). |
Mailbox names are now encoded as modified UTF-7 (RFC 3501, section 5.1.3), so an international mailbox name can be passed to any command as an ordinary
str.For backward compatibility, a
strthat is already valid modified UTF-7 — for example a name obtained from a rawLISTresponse and decoded as ASCII — is sent unchanged, and abytesargument is sent verbatim (bypassing encoding), so existing code keeps working. UnderUTF8=ACCEPT, mailbox names are sent as UTF-8 instead.This builds on the
utf-7-imapcodec added in gh-66788.