Skip to content
Open
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
4 changes: 3 additions & 1 deletion src/validators/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ def email(
+ r"!#-\[\]-\177]|\\[\011.]"
+ r')*")$',
username_part,
re.IGNORECASE,
# re.ASCII: Unicode case-insensitive matching would also admit characters
# outside these ranges, such as the Kelvin sign as a "k"
re.IGNORECASE | re.ASCII,
)
else False
)
26 changes: 26 additions & 0 deletions tests/test_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,29 @@ def test_rejects_newline_after_local_part(local_part: str):
def test_returns_failed_validation_on_idna_mapped_lookalike_domain(domain_part: str):
"""Test returns failed validation on email domains that only IDNA 2003 mapping makes valid."""
assert isinstance(email(f"user@{domain_part}"), ValidationError)


@pytest.mark.parametrize(
"local_part",
[
"\u212aelvin", # Kelvin sign, lowercase is k
"\u212belvin", # Angstrom sign, lowercase is U+00E5
"\u1e9eelvin", # capital sharp s, lowercase is U+00DF
"\u039celvin", # Greek capital mu, re equates it with U+00B5
"\u2c65elvin", # a with stroke, uppercase is U+023A
],
)
@pytest.mark.parametrize("quoted", [False, True])
def test_returns_failed_validation_on_case_folded_local_part(local_part: str, quoted: bool):
"""Test returns failed validation on characters allowed only through Unicode case folding."""
if quoted:
local_part = f'"{local_part}"'
assert isinstance(email(f"{local_part}@example.com"), ValidationError)


@pytest.mark.parametrize(
"local_part", ["KELVIN", "Kelvin", "\u0141\u00d3KA\u015a\u0106", "\u00ff\u0178", '"Kelvin"']
)
def test_returns_true_on_mixed_case_local_part(local_part: str):
"""Test returns true on upper and lower case letters inside the allowed ranges."""
assert email(f"{local_part}@example.com")
Loading