#36664: Python 3.15 compatibility.
-------------------------------------+-------------------------------------
Reporter: Mariusz Felisiak | Owner: Mariusz
| Felisiak
Type: New feature | Status: assigned
Component: Core (Other) | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Someday/Maybe
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):
* cc: Mike Edmunds (added)
Comment:
Hi Mike,
Thanks to you, the future referenced in `EmailBackend.prep_address()` has
arrived:
{{{#!py
if not force_ascii:
# Non-ASCII local-part is valid with SMTPUTF8. Remove once
# https://github.com/python/cpython/issues/81074 is fixed.
defects.discard("local-part contains non-ASCII characters)")
}}}
We have on the 3.15 builds:
{{{#!py
======================================================================
ERROR: test_rejects_non_ascii_local_part
(mail.test_backends.SMTPBackendTests.test_rejects_non_ascii_local_part)
The SMTP EmailBackend does not currently support non-ASCII local-parts.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/jwalls/django/tests/mail/test_backends.py", line 832, in
test_rejects_non_ascii_local_part
backend.send_messages([email])
~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
File "/Users/jwalls/django/django/core/mail/backends/smtp.py", line 138,
in send_messages
sent = self._send(message)
File "/Users/jwalls/django/django/core/mail/backends/smtp.py", line 155,
in _send
self.connection.sendmail(from_email, recipients, message.as_bytes())
^^^^^^^^^^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/unittest/mock.py",
line 697, in __getattr__
raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'sendmail'
}}}
It fails more informatively when I remove `spec=object()`:
{{{#!py
======================================================================
ERROR: test_rejects_non_ascii_local_part
(mail.test_backends.SMTPBackendTests.test_rejects_non_ascii_local_part)
The SMTP EmailBackend does not currently support non-ASCII local-parts.
----------------------------------------------------------------------
Traceback (most recent call last):
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/_header_value_parser.py",
line 2843, in _refold_without_ew
tstr.encode(encoding)
~~~~~~~~~~~^^^^^^^^^^
UnicodeEncodeError: 'ascii' codec can't encode character '\xf8' in
position 1: ordinal not in range(128)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/jwalls/django/tests/mail/test_backends.py", line 832, in
test_rejects_non_ascii_local_part
backend.send_messages([email])
~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
File "/Users/jwalls/django/django/core/mail/backends/smtp.py", line 138,
in send_messages
sent = self._send(message)
File "/Users/jwalls/django/django/core/mail/backends/smtp.py", line 155,
in _send
self.connection.sendmail(from_email, recipients, message.as_bytes())
~~~~~~~~~~~~~~~~^^
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/message.py",
line 214, in as_bytes
g.flatten(self, unixfrom=unixfrom)
~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/generator.py",
line 118, in flatten
self._write(msg)
~~~~~~~~~~~^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/generator.py",
line 201, in _write
self._write_headers(msg)
~~~~~~~~~~~~~~~~~~~^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/generator.py",
line 433, in _write_headers
folded = self.policy.fold_binary(h, v)
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/policy.py",
line 207, in fold_binary
folded = self._fold(name, value, refold_binary=self.cte_type=='7bit')
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/policy.py",
line 213, in _fold
return value.fold(policy=self)
~~~~~~~~~~^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/headerregistry.py",
line 251, in fold
return header.fold(policy=policy)
~~~~~~~~~~~^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/_header_value_parser.py",
line 170, in fold
return _refold_parse_tree(self, policy=policy)
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/_header_value_parser.py",
line 2832, in _refold_parse_tree
_refold_with_ew(parse_tree, lines, maxlen, encoding, policy=policy)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/_header_value_parser.py",
line 2936, in _refold_with_ew
encoded_part = part.fold(policy=policy)[:-len(policy.linesep)]
~~~~~~~~~^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/_header_value_parser.py",
line 170, in fold
return _refold_parse_tree(self, policy=policy)
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/_header_value_parser.py",
line 2832, in _refold_parse_tree
_refold_with_ew(parse_tree, lines, maxlen, encoding, policy=policy)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/_header_value_parser.py",
line 2936, in _refold_with_ew
encoded_part = part.fold(policy=policy)[:-len(policy.linesep)]
~~~~~~~~~^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/_header_value_parser.py",
line 170, in fold
return _refold_parse_tree(self, policy=policy)
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/_header_value_parser.py",
line 2834, in _refold_parse_tree
_refold_without_ew(parse_tree, lines, maxlen, encoding, policy=policy)
~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.15/lib/python3.15/email/_header_value_parser.py",
line 2854, in _refold_without_ew
raise errors.HeaderWriteError(
...<2 lines>...
)
email.errors.HeaderWriteError: Non-ASCII local-part 'nø' is invalid under
current policy setting (utf8=False)
----------------------------------------------------------------------
}}}
Should we be catching `email.errors.HeaderWriteError` and re-raising in
the code, or should we be adjusting the test for 3.15? And should we do
anything about the `if not force_ascii:` branch for now? Appreciate your
advice.
--
Ticket URL: <https://code.djangoproject.com/ticket/36664#comment:5>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/django-updates/0107019e1dbdd513-a83396f7-a45f-4be6-b83a-109da18ec340-000000%40eu-central-1.amazonses.com.