Skip to content

gh-49555: Support international mailbox names in imaplib#153391

Merged
serhiy-storchaka merged 1 commit into
python:mainfrom
serhiy-storchaka:imaplib-mutf7-mailbox
Jul 9, 2026
Merged

gh-49555: Support international mailbox names in imaplib#153391
serhiy-storchaka merged 1 commit into
python:mainfrom
serhiy-storchaka:imaplib-mutf7-mailbox

Conversation

@serhiy-storchaka

@serhiy-storchaka serhiy-storchaka commented Jul 9, 2026

Copy link
Copy Markdown
Member

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 str that is already valid modified UTF-7 — for example a name obtained from a raw LIST response and decoded as ASCII — is sent unchanged, and a bytes argument is sent verbatim (bypassing encoding), so existing code keeps working. Under UTF8=ACCEPT, mailbox names are sent as UTF-8 instead.

This builds on the utf-7-imap codec added in gh-66788.

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>
@read-the-docs-community

Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #33508763 | 📁 Comparing f6d7a81 against main (d6855c8)

  🔍 Preview build  

3 files changed
± library/imaplib.html
± whatsnew/3.16.html
± whatsnew/changelog.html

@serhiy-storchaka serhiy-storchaka merged commit 25bd6eb into python:main Jul 9, 2026
53 checks passed
@serhiy-storchaka serhiy-storchaka deleted the imaplib-mutf7-mailbox branch July 9, 2026 16:03

@bitdancer bitdancer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread Doc/whatsnew/3.16.rst

* 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`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread Lib/imaplib.py
# 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"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 ;)

Comment thread Lib/imaplib.py
return raw
except UnicodeDecodeError:
pass
return arg.encode('utf-7-imap')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

@serhiy-storchaka

Copy link
Copy Markdown
Member Author

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants