When trying to login on an imap server thant handles utf8 with an utf8 password, I get an UnicodeEncodeError: 'ascii' codec can't encode character error.
import imaplib
import getpass
host = input('Host: ')
with imaplib.IMAP4_SSL(host) as imap:
imap.login(input('User: '), getpass.getpass())
I can't enable UTF8 before login as I end up with imaplib.IMAP4.error: command ENABLE illegal in state NONAUTH, only allowed in states AUTH
However things are OK if I add the ENABLE command in NONAUTH state with imaplib.Commands['ENABLE'] = ('NONAUTH', 'AUTH', )
Your environment
CPython versions tested on: 3.10.4
Operating system and architecture: Linux 5.16.0-4-amd64 Debian testing 5.16.12-1
I noticed this now. This isn't a simple bug to fix, since comparing strings for equality isn't trivial in UTF-8. If two strings consist of the same bytes they're equal, but if they have some differences, they may still originate from equivalent key presses on two different keyboards, into two different user interfaces.
The good news is that SMTP has the same bug and I submitted #103611 to solve it, so once that's been merged this bug should become much simpler. I write this comment so the bug tracker will be aware of the relationship.
👋 @arnt
This is amazing ! I was expecting a simple documentation update for a not so reliable workaround and we might have a nice UTF-8 support. Thanks a lot and let me know if I can be of any help
See Issue #89869 about adding a method wrapping the AUTHENTICATE PLAIN command. I don’t think implementing SASL Prep is a requirement, especially at the client end. How usernames and passwords are mapped apparently depends on the application.
login() uses the LOGIN command, which can't carry non-ASCII credentials before UTF8=ACCEPT is enabled — a chicken-and-egg in the non-authenticated state. The new imaplib.IMAP4.login_plain() (GH-29398) authenticates with SASL PLAIN, carrying the user name and password as base64-encoded UTF-8, so non-ASCII credentials work. Use it over a TLS connection instead of login().
Activity
arnt commented on Jul 26, 2023
Hi,
I noticed this now. This isn't a simple bug to fix, since comparing strings for equality isn't trivial in UTF-8. If two strings consist of the same bytes they're equal, but if they have some differences, they may still originate from equivalent key presses on two different keyboards, into two different user interfaces.
The good news is that SMTP has the same bug and I submitted #103611 to solve it, so once that's been merged this bug should become much simpler. I write this comment so the bug tracker will be aware of the relationship.
JulienFS commented on Jul 26, 2023
👋 @arnt
This is amazing ! I was expecting a simple documentation update for a not so reliable workaround and we might have a nice UTF-8 support. Thanks a lot and let me know if I can be of any help
vadmium commented on Apr 21, 2024
See Issue #89869 about adding a method wrapping the AUTHENTICATE PLAIN command. I don’t think implementing SASL Prep is a requirement, especially at the client end. How usernames and passwords are mapped apparently depends on the application.
serhiy-storchaka commented on Jul 5, 2026
login() uses the LOGIN command, which can't carry non-ASCII credentials before UTF8=ACCEPT is enabled — a chicken-and-egg in the non-authenticated state. The new imaplib.IMAP4.login_plain() (GH-29398) authenticates with SASL PLAIN, carrying the user name and password as base64-encoded UTF-8, so non-ASCII credentials work. Use it over a TLS connection instead of login().