diff --git a/CHANGELOG.md b/CHANGELOG.md index 76fa319..5b3afa7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ In Development * add support python3.15 * The IPv6 tag of a domain literal is now case-insensitive, as in the RFCs, so `me@[ipv6:::1]` is accepted (and normalized to `me@[IPv6:::1]`) when `allow_domain_literal=True`. * Internationalized domains with a right-to-left label are now rejected if any other label breaks the IDNA Bidi Rule (RFC 5893), such as a label starting with a digit. Such domains, like `1.xn--4dbc.com` and `xn--4dbc.1.com` (`1.אב.com` and `אב.1.com` in Unicode), could be displayed identically. +* Faster validation of domains without Punycode (xn--) labels. 2.3.0 (August 26, 2025) ----------------------- diff --git a/email_validator/syntax.py b/email_validator/syntax.py index 4e7a0be..0b116d2 100644 --- a/email_validator/syntax.py +++ b/email_validator/syntax.py @@ -651,6 +651,13 @@ def validate_email_domain_name(domain: str, test_environment: bool = False, glob if ascii_domain == d or ascii_domain.endswith("." + d): raise EmailSyntaxError("The part after the @-sign is a special-use or reserved name that cannot be used with email.") + # Domains without Punycode labels come back unchanged from the IDNA round trip below. + if "xn--" not in ascii_domain: + return { + "ascii_domain": ascii_domain, + "domain": ascii_domain, + } + # We may have been given an IDNA ASCII domain to begin with. Check # that the domain actually conforms to IDNA. It could look like IDNA # but not be actual IDNA. For ASCII-only domains, the conversion out