Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions django/core/mail/backends/smtp.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,10 @@ def prep_address(self, address, force_ascii=True):
# Django allows local mailboxes like "From: webmaster" (#15042).
defects.discard("addr-spec local part with no domain")
if not force_ascii:
# Non-ASCII local-part is valid with SMTPUTF8. Remove once
# https://github.com/python/cpython/issues/81074 is fixed.
# PY315: Non-ASCII local-part is valid with SMTPUTF8. This check
# can be removed once the minimum supported Python version is 3.15
# (so the fix for https://github.com/python/cpython/issues/81074
# is in all supported versions).
defects.discard("local-part contains non-ASCII characters)")
if defects:
raise ValueError(f"Invalid address {address!r}: {'; '.join(defects)}")
Expand Down
29 changes: 20 additions & 9 deletions tests/mail/test_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import ssl
import sys
import tempfile
from email.errors import HeaderWriteError
from email.message import EmailMessage as PyEmailMessage
from io import StringIO
from pathlib import Path
from smtplib import SMTPException
Expand Down Expand Up @@ -1093,17 +1095,26 @@ def test_does_not_reencode_idna(self):
)

def test_rejects_non_ascii_local_part(self):
"""
The SMTP EmailBackend does not currently support non-ASCII local-parts.
(That would require using the RFC 6532 SMTPUTF8 extension.) #35713.
"""
# The SMTP EmailBackend must work around invalid email encoding caused
# by https://github.com/python/cpython/issues/122476 (#35713).
try:
# Detect fix for CPython issue gh-122476.
message = PyEmailMessage()
message["To"] = "nø@example.dk"
message.as_bytes()
except HeaderWriteError:
# PY315: Error from Python email generator.
msg = "Non-ASCII local-part 'nø' is invalid"
else:
# Python <=3.14: Error from smtp.EmailBackend.prep_address().
msg = (
"Invalid address 'nø@example.dk': local-part contains "
"non-ASCII characters"
)

backend = self.create_backend()
backend.connection = mock.Mock(spec=object())
email = EmailMessage(to=["nø@example.dk"])
with self.assertRaisesMessage(
ValueError,
"Invalid address 'nø@example.dk': local-part contains non-ASCII characters",
):
with self.assertRaisesMessage((ValueError, HeaderWriteError), msg):
backend.send_messages([email])

def test_prep_address_without_force_ascii(self):
Expand Down
Loading