Skip to content

Commit 458c9c4

Browse files
0xdadeJoshData
andauthored
Use dnspython's resolve method when available (#46)
Closes #45 by defaulting to resolver.resolve and only falling back to resolver.query when resolver.resolve isn't present. Co-authored-by: Joshua Tauberer <jt@occams.info>
1 parent cc9b001 commit 458c9c4

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

email_validator/__init__.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -438,8 +438,20 @@ def validate_email_deliverability(domain, domain_i18n, timeout=DEFAULT_TIMEOUT):
438438
# Check that the domain resolves to an MX record. If there is no MX record,
439439
# try an A or AAAA record which is a deprecated fallback for deliverability.
440440

441-
# Add a trailing period to ensure the domain name is treated as fully qualified.
442-
domain += '.'
441+
def dns_resolver_resolve_shim(resolver, domain, record):
442+
try:
443+
# dns.resolver.Resolver.resolve is new to dnspython 2.x.
444+
# https://dnspython.readthedocs.io/en/latest/resolver-class.html#dns.resolver.Resolver.resolve
445+
return resolver.resolve(domain, record)
446+
except AttributeError:
447+
# dnspython 2.x is only available in Python 3.6 and later. For earlier versions
448+
# of Python, we maintain compatibility with dnspython 1.x which has a
449+
# dnspython.resolver.Resolver.query method instead. The only difference is that
450+
# query may treat the domain as relative and use the system's search domains,
451+
# which we prevent by adding a "." to the domain name to make it absolute.
452+
# dns.resolver.Resolver.query is deprecated in dnspython version 2.x.
453+
# https://dnspython.readthedocs.io/en/latest/resolver-class.html#dns.resolver.Resolver.query
454+
return resolver.query(domain + ".", record)
443455

444456
try:
445457
# We need a way to check how timeouts are handled in the tests. So we
@@ -455,21 +467,21 @@ def validate_email_deliverability(domain, domain_i18n, timeout=DEFAULT_TIMEOUT):
455467

456468
try:
457469
# Try resolving for MX records and get them in sorted priority order.
458-
response = dns.resolver.query(domain, "MX")
470+
response = dns_resolver_resolve_shim(resolver, domain, "MX")
459471
mtas = sorted([(r.preference, str(r.exchange).rstrip('.')) for r in response])
460472
mx_fallback = None
461473
except (dns.resolver.NoNameservers, dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
462474

463475
# If there was no MX record, fall back to an A record.
464476
try:
465-
response = dns.resolver.query(domain, "A")
477+
response = dns_resolver_resolve_shim(resolver, domain, "A")
466478
mtas = [(0, str(r)) for r in response]
467479
mx_fallback = "A"
468480
except (dns.resolver.NoNameservers, dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
469481

470482
# If there was no A record, fall back to an AAAA record.
471483
try:
472-
response = dns.resolver.query(domain, "AAAA")
484+
response = dns_resolver_resolve_shim(resolver, domain, "AAAA")
473485
mtas = [(0, str(r)) for r in response]
474486
mx_fallback = "AAAA"
475487
except (dns.resolver.NoNameservers, dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):

0 commit comments

Comments
 (0)