From b9b3fdd93644310196c4158b3939480baf5b6df8 Mon Sep 17 00:00:00 2001 From: John Cusack Date: Thu, 29 Oct 2026 10:48:26 -0400 Subject: [PATCH] Skip the IDNA round trip for domains without Punycode labels --- CHANGELOG.md | 1 + email_validator/syntax.py | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 090cbfd..931227e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ In Development * Python 3.8 and 3.9 are no longer supported. * The `original` field of the returned validated email object incorrectly un-escaped the local part of the email address. Now it returns the original address, without any display name, as passed to validate_email. * add support python3.15 +* 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 9e00ce7..4c56771 100644 --- a/email_validator/syntax.py +++ b/email_validator/syntax.py @@ -644,6 +644,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