Skip to content

Commit d4c9ec2

Browse files
committed
Some README and code comments changes
1 parent 3804cd7 commit d4c9ec2

File tree

2 files changed

+38
-52
lines changed

2 files changed

+38
-52
lines changed

README.md

Lines changed: 32 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,31 @@ email-validator: Validate Email Addresses
44
A robust email address syntax and deliverability validation library for
55
Python 3.7+ by [Joshua Tauberer](https://joshdata.me).
66

7-
This library validates that a string is of the form `name@example.com` and optionally checks that the domain name is set up to receive email. This is
8-
the sort of validation you would want for an email-based registration form on
9-
a website (but not necessarily for composing an email message).
7+
This library validates that a string is of the form `name@example.com`
8+
and optionally checks that the domain name is set up to receive email.
9+
This is the sort of validation you would want when you are identifying
10+
users by their email address like on a registration/login form (but not
11+
necessarily for composing an email message, see below).
1012

1113
Key features:
1214

1315
* Checks that an email address has the correct syntax --- good for
1416
registration/login forms or other uses related to identifying users.
15-
* Gives friendly error messages when validation fails (appropriate to show
16-
to end users).
17-
* (optionally) Checks deliverability: Does the domain name resolve? You can override the default DNS resolver.
18-
* Supports internationalized domain names and (optionally)
19-
internationalized local parts, but blocks unsafe characters.
20-
* Normalizes email addresses (super important for internationalized
17+
Rejects obsolete email address syntax that you'd find unexpected.
18+
* Gives friendly English error messages when validation fails that you
19+
can display to end-users.
20+
* Checks deliverability (optional): Does the domain name resolve?
21+
(You can override the default DNS resolver to add query caching.)
22+
* Supports internationalized domain names and internationalized local parts.
23+
Blocks unsafe characters for your safety.
24+
* Normalizes email addresses (important for internationalized
2125
addresses! see below).
2226

23-
The library is NOT for validation of the To: line in an email message
24-
(e.g. `My Name <my@address.com>`), which
25-
[flanker](https://github.com/mailgun/flanker) is more appropriate for.
26-
And this library does NOT permit obsolete forms of email addresses, so
27+
This library does NOT permit obsolete forms of email addresses, so
2728
if you need strict validation against the email specs exactly, use
28-
[pyIsEmail](https://github.com/michaelherold/pyIsEmail).
29+
[pyIsEmail](https://github.com/michaelherold/pyIsEmail) or try
30+
[flanker](https://github.com/mailgun/flanker) if you are parsing the
31+
To: line of an email.
2932

3033
[![Build Status](https://github.com/JoshData/python-email-validator/actions/workflows/test_and_build.yaml/badge.svg)](https://github.com/JoshData/python-email-validator/actions/workflows/test_and_build.yaml)
3134

@@ -42,7 +45,7 @@ This package [is on PyPI](https://pypi.org/project/email-validator/), so:
4245
pip install email-validator
4346
```
4447

45-
`pip3` also works.
48+
(You might need to use `pip3` depending on your local environment.)
4649

4750
Quick Start
4851
-----------
@@ -82,8 +85,7 @@ Usage
8285
### Overview
8386

8487
The module provides a function `validate_email(email_address)` which
85-
takes an email address (either a `str` or `bytes`, but only non-internationalized
86-
addresses are allowed when passing a `bytes`) and:
88+
takes an email address and:
8789

8890
- Raises a `EmailNotValidError` with a helpful, human-readable error
8991
message explaining why the email address is not valid, or
@@ -121,18 +123,19 @@ greylisting).
121123
The `validate_email` function also accepts the following keyword arguments
122124
(defaults are as shown below):
123125

126+
`check_deliverability=True`: If true, a DNS query is made to check that a non-null MX record is present for the domain-part of the email address (or if not, an A/AAAA record as an MX fallback can be present but in that case a reject-all SPF record must not be present). Set to `False` to skip this DNS-based check. DNS is slow and sometimes unavailable, so consider whether these checks are useful for your use case. It is recommended to pass `False` when performing validation for login pages (but not account creation pages) since re-validation of a previously validated domain in your database by querying DNS at every login is probably undesirable. You can also set `email_validator.CHECK_DELIVERABILITY` to `False` to turn this off for all calls by default.
127+
128+
`dns_resolver=None`: Pass an instance of [dns.resolver.Resolver](https://dnspython.readthedocs.io/en/latest/resolver-class.html) to control the DNS resolver including setting a timeout and [a cache](https://dnspython.readthedocs.io/en/latest/resolver-caching.html). The `caching_resolver` function shown above is a helper function to construct a dns.resolver.Resolver with a [LRUCache](https://dnspython.readthedocs.io/en/latest/resolver-caching.html#dns.resolver.LRUCache). Reuse the same resolver instance across calls to `validate_email` to make use of the cache.
129+
130+
`test_environment=False`: DNS-based deliverability checks are disabled and `test` and `subdomain.test` domain names are permitted (see below). You can also set `email_validator.TEST_ENVIRONMENT` to `True` to turn it on for all calls by default.
131+
124132
`allow_smtputf8=True`: Set to `False` to prohibit internationalized addresses that would
125133
require the
126134
[SMTPUTF8](https://tools.ietf.org/html/rfc6531) extension. You can also set `email_validator.ALLOW_SMTPUTF8` to `False` to turn it off for all calls by default.
127135

128-
`check_deliverability=True`: If true, a DNS query is made to check that a non-null MX record is present for the domain-part of the email address (or if not, an A/AAAA record as an MX fallback can be present but in that case a reject-all SPF record must not be present). Set to `False` to skip this DNS-based check. DNS is slow and sometimes unavailable, so consider whether these checks are useful for your use case. It is recommended to pass `False` when performing validation for login pages (but not account creation pages) since re-validation of a previously validated domain in your database by querying DNS at every login is probably undesirable. You can also set `email_validator.CHECK_DELIVERABILITY` to `False` to turn this off for all calls by default.
129-
130136
`allow_empty_local=False`: Set to `True` to allow an empty local part (i.e.
131137
`@example.com`), e.g. for validating Postfix aliases.
132138

133-
`dns_resolver=None`: Pass an instance of [dns.resolver.Resolver](https://dnspython.readthedocs.io/en/latest/resolver-class.html) to control the DNS resolver including setting a timeout and [a cache](https://dnspython.readthedocs.io/en/latest/resolver-caching.html). The `caching_resolver` function shown above is a helper function to construct a dns.resolver.Resolver with a [LRUCache](https://dnspython.readthedocs.io/en/latest/resolver-caching.html#dns.resolver.LRUCache). Reuse the same resolver instance across calls to `validate_email` to make use of the cache.
134-
135-
`test_environment=False`: DNS-based deliverability checks are disabled and `test` and `subdomain.test` domain names are permitted (see below). You can also set `email_validator.TEST_ENVIRONMENT` to `True` to turn it on for all calls by default.
136139

137140
### DNS timeout and cache
138141

@@ -180,13 +183,8 @@ domain names are converted into a special IDNA ASCII "[Punycode](https://www.rfc
180183
form starting with `xn--`. When an email address has non-ASCII
181184
characters in its domain part, the domain part is replaced with its IDNA
182185
ASCII equivalent form in the process of mail transmission. Your mail
183-
submission library probably does this for you transparently. Note that
184-
most web browsers are currently in transition between IDNA 2003 (RFC
185-
3490) and IDNA 2008 (RFC 5891) and [compliance around the web is not
186-
very
187-
good](http://archives.miloush.net/michkap/archive/2012/02/27/10273315.html)
188-
in any case, so be aware that edge cases are handled differently by
189-
different applications and libraries. This library conforms to IDNA 2008
186+
submission library probably does this for you transparently. ([Compliance
187+
around the web is not very good though](http://archives.miloush.net/michkap/archive/2012/02/27/10273315.html).) This library conforms to IDNA 2008
190188
using the [idna](https://github.com/kjd/idna) module by Kim Davies.
191189

192190
### Internationalized local parts
@@ -305,7 +303,7 @@ ValidatedEmail(
305303
smtputf8=False)
306304
```
307305

308-
For the fictitious address `example@ツ.life`, which has an
306+
For the fictitious but valid address `example@ツ.ⓁⒾⒻⒺ`, which has an
309307
internationalized domain but ASCII local part, the returned object is:
310308

311309
```python
@@ -320,13 +318,9 @@ ValidatedEmail(
320318

321319
```
322320

323-
Note that `smtputf8` is `False` even though the domain part is
324-
internationalized because
325-
[SMTPUTF8](https://tools.ietf.org/html/rfc6531) is only needed if the
326-
local part of the address is internationalized (the domain part can be
327-
converted to IDNA ASCII Punycode). Also note that the `email` and `domain`
328-
fields provide a normalized form of the email address and domain name
329-
(casefolding and Unicode normalization as required by IDNA 2008).
321+
Note that the `email` and `domain` fields provide a normalized form of the
322+
email address, domain name, and (in other cases) local part (see earlier
323+
discussion of normalization), which you should use in your database.
330324

331325
Calling `validate_email` with the ASCII form of the above email address,
332326
`example@xn--bdk.life`, returns the exact same information (i.e., the
@@ -390,21 +384,11 @@ or likely to cause trouble:
390384
The "quoted string" form of the local part of the email address (RFC
391385
5321 4.1.2) is not permitted.
392386
Quoted forms allow multiple @-signs, space characters, and other
393-
troublesome conditions. The unsual [(comment) syntax](https://github.com/JoshData/python-email-validator/issues/77)
387+
troublesome conditions. The unusual [(comment) syntax](https://github.com/JoshData/python-email-validator/issues/77)
394388
is also rejected. The "literal" form for the domain part of an email address (an
395389
IP address in brackets) is rejected. Other obsolete and deprecated syntaxes are
396390
rejected. No one uses these forms anymore.
397391

398-
Support for Python 2.x
399-
----------------------
400-
401-
The last version of this library supporting Python 2.x is version 1.2.1.
402-
403-
When using Python 2.x, it is required that Python be built with
404-
UCS-4 support (see
405-
[here](https://stackoverflow.com/questions/29109944/python-returns-length-of-2-for-single-unicode-character-string)).
406-
Without UCS-4 support, unicode characters outside of the BMP (Basic
407-
Multilingual Plane) will not validate correctly in internationalized addresses.
408392

409393
Testing
410394
-------

email_validator/__main__.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
#
33
# Usage:
44
#
5-
# python -m email_validator
5+
# python -m email_validator test@example.org
6+
# python -m email_validator < LIST_OF_ADDRESSES.TXT
67
#
78
# Provide email addresses to validate either as a command-line argument
8-
# or in STDIN separated by newlines. No output will be given for valid
9-
# email addresses. Validation errors will be printed for invalid email
10-
# addresses.
9+
# or in STDIN separated by newlines. Validation errors will be printed for
10+
# invalid email addresses. When passing an email address on the command
11+
# line, if the email address is valid, information about it will be printed.
12+
# When using STDIN, no output will be given for valid email addresses.
1113

1214
import json
1315
import sys

0 commit comments

Comments
 (0)