Skip to content
5 changes: 0 additions & 5 deletions Lib/email/_header_value_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1493,11 +1493,6 @@ def get_local_part(value):
local_part.defects.append(errors.ObsoleteHeaderDefect(
"local-part is not a dot-atom (contains CFWS)"))
local_part[0] = obs_local_part
try:
local_part.value.encode('ascii')
except UnicodeEncodeError:
local_part.defects.append(errors.NonASCIILocalPartDefect(
"local-part contains non-ASCII characters)"))
return local_part, value

def get_obs_local_part(value):
Expand Down
6 changes: 3 additions & 3 deletions Lib/email/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ class ObsoleteHeaderDefect(HeaderDefect):
"""Header uses syntax declared obsolete by RFC 5322"""

class NonASCIILocalPartDefect(HeaderDefect):
"""local_part contains non-ASCII characters"""
# This defect only occurs during unicode parsing, not when
# parsing messages decoded from binary.
"""Unused. Note: this error is deprecated and may be removed in the future."""
# RFC 6532 permits a non-ASCII local-part. _header_value_parser previously
# treated this as a parse-time defect (when parsing Unicode, but not bytes).

class InvalidDateDefect(HeaderDefect):
"""Header has unparsable or invalid date"""
11 changes: 0 additions & 11 deletions Lib/test/test_email/test__header_value_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1235,17 +1235,6 @@ def test_get_local_part_valid_and_invalid_qp_in_atom_list(self):
'@example.com')
self.assertEqual(local_part.local_part, r'\example\\ example')

def test_get_local_part_unicode_defect(self):
# Currently this only happens when parsing unicode, not when parsing
# stuff that was originally binary.
local_part = self._test_get_x(parser.get_local_part,
'exámple@example.com',
'exámple',
'exámple',
[errors.NonASCIILocalPartDefect],
'@example.com')
self.assertEqual(local_part.local_part, 'exámple')

# get_dtext

def test_get_dtext_only(self):
Expand Down
22 changes: 10 additions & 12 deletions Lib/test/test_email/test_headerregistry.py
Original file line number Diff line number Diff line change
Expand Up @@ -1497,17 +1497,19 @@ def test_quoting(self):
self.assertEqual(str(a), '"Sara J." <"bad name"@example.com>')

def test_il8n(self):
a = Address('Éric', 'wok', 'exàmple.com')
a = Address('Éric', 'wők', 'exàmple.com')
self.assertEqual(a.display_name, 'Éric')
self.assertEqual(a.username, 'wok')
self.assertEqual(a.username, 'wők')
self.assertEqual(a.domain, 'exàmple.com')
self.assertEqual(a.addr_spec, 'wok@exàmple.com')
self.assertEqual(str(a), 'Éric <wok@exàmple.com>')
self.assertEqual(a.addr_spec, 'wők@exàmple.com')
self.assertEqual(str(a), 'Éric <wők@exàmple.com>')

# XXX: there is an API design issue that needs to be solved here.
#def test_non_ascii_username_raises(self):
# with self.assertRaises(ValueError):
# Address('foo', 'wők', 'example.com')
def test_i18n_in_addr_spec(self):
a = Address(addr_spec='wők@exàmple.com')
self.assertEqual(a.username, 'wők')
self.assertEqual(a.domain, 'exàmple.com')
self.assertEqual(a.addr_spec, 'wők@exàmple.com')
self.assertEqual(str(a), 'wők@exàmple.com')

def test_crlf_in_constructor_args_raises(self):
cases = (
Expand All @@ -1528,10 +1530,6 @@ def test_crlf_in_constructor_args_raises(self):
with self.subTest(kwargs=kwargs), self.assertRaisesRegex(ValueError, "invalid arguments"):
Address(**kwargs)

def test_non_ascii_username_in_addr_spec_raises(self):
with self.assertRaises(ValueError):
Address('foo', addr_spec='wők@example.com')

def test_address_addr_spec_and_username_raises(self):
with self.assertRaises(TypeError):
Address('foo', username='bing', addr_spec='bar@baz')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
The :mod:`email` module no longer treats email addresses with non-ASCII
characters as defects when parsing a Unicode string or in the ``addr_spec``
parameter to :class:`email.headerregistry.Address`. :rfc:`5322` permits such
addresses, and they were already supported when parsing bytes and in the Address
``username`` parameter.

The (undocumented) :exc:`!email.errors.NonASCIILocalPartDefect` is no longer
used and should be considered deprecated.
Loading