12
12
ALLOW_SMTPUTF8 = True
13
13
CHECK_DELIVERABILITY = True
14
14
TEST_ENVIRONMENT = False
15
+ GLOBALLY_DELIVERABLE = True
15
16
DEFAULT_TIMEOUT = 15 # secs
16
17
17
18
# Based on RFC 2822 section 3.2.4 / RFC 5322 section 3.2.3, these
@@ -268,6 +269,7 @@ def validate_email(
268
269
allow_empty_local = False ,
269
270
check_deliverability = None ,
270
271
test_environment = None ,
272
+ globally_deliverable = GLOBALLY_DELIVERABLE ,
271
273
timeout = None ,
272
274
dns_resolver = None
273
275
):
@@ -314,7 +316,7 @@ def validate_email(
314
316
ret .smtputf8 = local_part_info ["smtputf8" ]
315
317
316
318
# Validate the email address's domain part syntax and get a normalized form.
317
- domain_part_info = validate_email_domain_part (parts [1 ], test_environment = test_environment )
319
+ domain_part_info = validate_email_domain_part (parts [1 ], test_environment = test_environment , globally_deliverable = globally_deliverable )
318
320
ret .domain = domain_part_info ["domain" ]
319
321
ret .ascii_domain = domain_part_info ["ascii_domain" ]
320
322
@@ -473,7 +475,7 @@ def validate_email_local_part(local, allow_smtputf8=True, allow_empty_local=Fals
473
475
}
474
476
475
477
476
- def validate_email_domain_part (domain , test_environment = False ):
478
+ def validate_email_domain_part (domain , test_environment = False , globally_deliverable = True ):
477
479
# Empty?
478
480
if len (domain ) == 0 :
479
481
raise EmailSyntaxError ("There must be something after the @-sign." )
@@ -551,13 +553,20 @@ def validate_email_domain_part(domain, test_environment=False):
551
553
if not m :
552
554
raise EmailSyntaxError ("The email address contains invalid characters after the @-sign." )
553
555
554
- # All publicly deliverable addresses have domain named with at least
555
- # one period, and we'll consider the lack of a period a syntax error
556
- # since that will match people's sense of what an email address looks
557
- # like. We'll skip this in test environments to allow '@test' email
558
- # addresses.
559
- if "." not in ascii_domain and not (ascii_domain == "test" and test_environment ):
560
- raise EmailSyntaxError ("The domain name %s is not valid. It should have a period." % domain_i18n )
556
+ if globally_deliverable :
557
+ # All publicly deliverable addresses have domain named with at least
558
+ # one period, and we'll consider the lack of a period a syntax error
559
+ # since that will match people's sense of what an email address looks
560
+ # like. We'll skip this in test environments to allow '@test' email
561
+ # addresses.
562
+ if "." not in ascii_domain and not (ascii_domain == "test" and test_environment ):
563
+ raise EmailSyntaxError ("The domain name %s is not valid. It should have a period." % domain_i18n )
564
+
565
+ # We also know that all TLDs currently end with a letter.
566
+ if not re .search (r"[A-Za-z]\Z" , ascii_domain ):
567
+ raise EmailSyntaxError (
568
+ "The domain name %s is not valid. It is not within a valid top-level domain." % domain_i18n
569
+ )
561
570
562
571
# Check special-use and reserved domain names.
563
572
# Some might fail DNS-based deliverability checks, but that
@@ -570,12 +579,6 @@ def validate_email_domain_part(domain, test_environment=False):
570
579
if ascii_domain == d or ascii_domain .endswith ("." + d ):
571
580
raise EmailSyntaxError ("The domain name %s is a special-use or reserved name that cannot be used with email." % domain_i18n )
572
581
573
- # We also know that all TLDs currently end with a letter.
574
- if not re .search (r"[A-Za-z]\Z" , ascii_domain ):
575
- raise EmailSyntaxError (
576
- "The domain name %s is not valid. It is not within a valid top-level domain." % domain_i18n
577
- )
578
-
579
582
# Return the IDNA ASCII-encoded form of the domain, which is how it
580
583
# would be transmitted on the wire (except when used with SMTPUTF8
581
584
# possibly), as well as the canonical Unicode form of the domain,
0 commit comments