python-email-validator: Rejecting `example.com` addresses
Starting in v1.2.0, email-validator
is rejecting example.com
addresses. While this is consistent with its documented behavior,
Other Special Use Domain Names are always considered invalid and raise
EmailUndeliverableError
.
it would seem to violate IETF RFC 6761 section 6.5 which says :
Application software SHOULD NOT recognize example names as special and SHOULD use example names as they would other domain names.
Sadly, when our CI pulled in the new release, our testing broke, because we use example.com
in our test code.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 13
- Comments: 16 (7 by maintainers)
Commits related to this issue
- Remove example and example.com/net/org from the special use domains list By popular demand in #78. — committed to JoshData/python-email-validator by JoshData 2 years ago
- Remove example and example.com/net/org from the special use domains list By popular demand in #78. — committed to JoshData/python-email-validator by JoshData 2 years ago
- Raise EmailUndeliverableError for special use domain names and their subdomains, except @test when a new test_environment argument is passed Some of the domain names used in tests had to be revised b... — committed to JoshData/python-email-validator by JoshData 3 years ago
- Pin email-validator < 1.2.0 Version 1.2.0 introduced a breaking change: https://github.com/JoshData/python-email-validator/issues/78 Pin to version < 1.2.0 until it gets fixed. — committed to rclement/mailer by rclement 2 years ago
- Pin email-validator < 1.2.0 (#432) Version 1.2.0 introduced a breaking change: https://github.com/JoshData/python-email-validator/issues/78 Pin to version < 1.2.0 until it gets fixed. — committed to rclement/mailer by rclement 2 years ago
- Pin email-validator < 1.2.0 Version 1.2.0 introduced a breaking change: JoshData/python-email-validator#78 Pin to version < 1.2.0 until it gets fixed. — committed to rclement/business-card-generator by rclement 2 years ago
- Temporarily pin email-validator See JoshData/python-email-validator#78 — committed to bitcart/bitcart by MrNaif2018 2 years ago
I’m with @webbnh on this, but I’d go slightly further… I understand that this came with the best intentions, but you know how the saying goes 😃 I think this feature should be opt-in rather than opt-out in the first place, with a separate boolean flag controlling it ; this way, you give dependents time to implement their own wrappers around the new boolean flag (whether they want to support the extended “pick which domains are special” approach is probably up to them in the first place) - the reason I’m wording it that way is because (and I suppose this is common) I don’t actually directly use python-email-validator but flask-wtforms, which uses wtforms, which can optionally work with python-email-validator (notice the three layers deep, relatively obscure breakage from my POV, hehe).
I’ve pushed a commit that removes example and example.com/net/org from the special use domains list. I’ll make a release later in the week.
RFC 6761 says applications “SHOULD NOT” treat the “example” domains as special, which doesn’t mean it’s wrong to reject them (it’s not MUST NOT), but I get the problem. Since these domain names are reserved for IANA, I think it’s safe for this library to accept them. (Since they are reserved for documentation, it’s probably not appropriate to use these addresses generally in tests.)
In the latest release of this library, DNS-based deliverability checks will fail these domains anyway because example.com/net/org publish a NULL MX record (that’s new in this release) and the subdomains (e.g. mail.example) don’t resolve (that behavior is old). So beware that even with these domains removed from the special-use list, they may still fail. But with
check_deliverability=False
(which is probably a good idea in test environments anyway), they will now pass. (“example” alone, i.e. “josh@example”, doesn’t have a period which this library has always failed as a syntax error.)The RFC says the same thing about “test,” but because “test” is not reserved to IANA and the RFC warns that users should be aware that “test” may resolve differently in different environments, this domain does not seem to me to be safe to pass validation.
The latest release of this library has a new keyword argument
test_environment
. When it is true, DNS-based deliverabiltiy checks are disabled (same ascheck_deliverability=False
) and “test” is removed from the special-use domains list so that it can be used in tests (e.g. “me@test” or “me@mail.test” etc.). I think givingtest_environment=True
and using@test
email addresses is probably the right approach for creating tests, rather than using@example.com/net/org
addresses. But with the latest commit, using example domains would also work.How does this all sound?
Thank you so much for the quick fix Joshua. All tests are passing again!
I’ve pushed an updated package to pypi and GitHub releases. In 1.2.1:
@JoshData, that’s definitely a plausible approach.
However, to me, that feels like reaching inside what should be an opaque object and messing with its guts, but that’s probably my own problem – I come from a mindset where a package interface should be functional, and package data should be readonly, immutable, or hidden. Now, I know that that’s not really feasible in Python (and I note that
SPECIAL_USE_DOMAIN_NAMES
does not begin with an underscore…but I don’t consider that lack as positive permission to modify it in production code!)So, if you want to document
SPECIAL_USE_DOMAIN_NAMES
as a mutable and part of the package interface, that’s fine…but I personally would prefer an API function for getting and/or setting it. But, as I say, that’s just me… 😉Ah! Ok. I’ll look over the RFC and fix it (but I can’t do it immediately, I would recommend pinning to the prior version of the library for now).