Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-email-validator for 
openSUSE:Factory checked in at 2022-10-04 20:37:59
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-email-validator (Old)
 and      /work/SRC/openSUSE:Factory/.python-email-validator.new.2275 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-email-validator"

Tue Oct  4 20:37:59 2022 rev:3 rq:1007824 version:1.3.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-email-validator/python-email-validator.changes
    2022-09-08 14:24:09.194738042 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-email-validator.new.2275/python-email-validator.changes
  2022-10-04 20:38:03.960945314 +0200
@@ -1,0 +2,12 @@
+Tue Oct  4 08:06:34 UTC 2022 - Daniel Garcia <daniel.gar...@suse.com>
+
+- Update to 1.3.0:
+  * Deliverability checks now check for 'v=spf1 -all' SPF records as a way to 
reject more bad domains.
+  * Special use domain names now raise EmailSyntaxError instead of 
EmailUndeliverableError since they are performed even if check_deliverability 
is off.
+  * New module-level attributes are added to override the default values of 
the keyword arguments and the special-use domains list.
+  * The keyword arguments of the public methods are now marked as keyword-only.
+  * pyIsEmail's test cases are added to the tests.
+  * Recommend that check_deliverability be set to False for validation on 
login pages.
+  * Added an undocumented globally_deliverable option.
+
+-------------------------------------------------------------------

Old:
----
  email_validator-1.2.1.tar.gz

New:
----
  email_validator-1.3.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-email-validator.spec ++++++
--- /var/tmp/diff_new_pack.WZXxSv/_old  2022-10-04 20:38:04.500946082 +0200
+++ /var/tmp/diff_new_pack.WZXxSv/_new  2022-10-04 20:38:04.504946087 +0200
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-email-validator
-Version:        1.2.1
+Version:        1.3.0
 Release:        0
 Summary:        A robust email syntax and deliverability validation library 
for Python
 License:        CC0-1.0

++++++ email_validator-1.2.1.tar.gz -> email_validator-1.3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-email-validator-1.2.1/.travis.yml 
new/python-email-validator-1.3.0/.travis.yml
--- old/python-email-validator-1.2.1/.travis.yml        2022-05-02 
00:17:51.000000000 +0200
+++ new/python-email-validator-1.3.0/.travis.yml        2022-09-18 
21:30:31.000000000 +0200
@@ -1,14 +1,14 @@
 os: linux
-dist: xenial
+dist: bionic
 language: python
 cache: pip
 
 python:
-#- '2.7'
 - '3.6'
-- '3.7'
-- '3.8'
+#- '3.7'
+#- '3.8'
 - '3.9'
+- '3.10'
 
 install:
 - make install
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-email-validator-1.2.1/CHANGELOG.md 
new/python-email-validator-1.3.0/CHANGELOG.md
--- old/python-email-validator-1.2.1/CHANGELOG.md       1970-01-01 
01:00:00.000000000 +0100
+++ new/python-email-validator-1.3.0/CHANGELOG.md       2022-09-18 
21:30:31.000000000 +0200
@@ -0,0 +1,106 @@
+Version 1.3.0 (September 18, 2022)
+----------------------------------
+
+* Deliverability checks now check for 'v=spf1 -all' SPF records as a way to 
reject more bad domains.
+* Special use domain names now raise EmailSyntaxError instead of 
EmailUndeliverableError since they are performed even if check_deliverability 
is off.
+* New module-level attributes are added to override the default values of the 
keyword arguments and the special-use domains list.
+* The keyword arguments of the public methods are now marked as keyword-only.
+* [pyIsEmail](https://github.com/michaelherold/pyIsEmail)'s test cases are 
added to the tests.
+* Recommend that check_deliverability be set to False for validation on login 
pages.
+* Added an undocumented globally_deliverable option.
+
+Version 1.2.1 (May 1, 2022)
+---------------------------
+
+* example.com/net/org are removed from the special-use reserved domain names 
list so that they do not raise exceptions if check_deliverability is off.
+* Improved README.
+
+Verison 1.2.0 (April 24, 2022)
+------------------------------
+
+* Reject domains with NULL MX records (when deliverability checks
+  are turned on).
+* Reject unsafe unicode characters. (Some of these checks you should
+  be doing on all of your user inputs already!)
+* Reject most special-use reserved domain names with EmailUndeliverableError. 
A new `test_environment` option is added for using `@*.test` domains.
+* Improved safety of exception text by not repeating an unsafe input character 
in the message.
+* Minor fixes in tests.
+* Invoking the module as a standalone program now caches DNS queries.
+* Improved README.
+
+Version 1.1.3 (June 12, 2021)
+-----------------------------
+
+* Allow passing a custom dns_resolver so that a DNS cache and a custom timeout 
can be set.
+
+Version 1.1.2 (Nov 5, 2020)
+---------------------------
+
+* Fix invoking the module as a standalone program.
+* Fix deprecation warning in Python 3.8.
+* Code improvements.
+* Improved README.
+
+Version 1.1.1 (May 19, 2020)
+----------------------------
+
+* Fix exception when DNS queries time-out.
+* Improved README.
+
+Version 1.1.0 (Spril 30, 2020)
+------------------------------
+
+* The main function now returns an object with attributes rather than a dict 
with keys, but accessing the object in the old way is still supported.
+* Added overall email address length checks.
+* Minor tweak to regular expressions.
+* Improved error messages.
+* Added tests.
+* Linted source code files; changed README to Markdown.
+
+Version 1.0.5 (Oct 18, 2019)
+----------------------------
+
+* Prevent resolving domain names as if they were not fully qualified using a 
local search domain settings.
+
+Version 1.0.4 (May 2, 2019)
+---------------------------
+
+* Added a timeout argument for DNS queries.
+* The wheel distribution is now a universal wheel.
+* Improved README.
+
+Version 1.0.3 (Sept 12, 2017)
+-----------------------------
+
+* Added a wheel distribution for easier installation.
+
+Version 1.0.2 (Dec 30, 2016)
+----------------------------
+
+* Fix dnspython package name in Python 3.
+* Improved README.
+
+Version 1.0.1 (March 6, 2016)
+-----------------------------
+
+* Fixed minor errors.
+
+Version 1.0.0 (Sept 5, 2015)
+----------------------------
+
+* Fail domains with a leading period.
+* Improved error messages.
+* Added tests.
+
+Version 0.5.0 (June 15, 2015)
+-----------------------------
+
+* Use IDNA 2008 instead of IDNA 2003 and use the idna package's UTS46 
normalization instead of our own.
+* Fixes for Python 2.
+* Improved error messages.
+* Improved README.
+
+Version 0.1.0 (April 21, 2015)
+------------------------------
+
+Initial release!
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-email-validator-1.2.1/README.md 
new/python-email-validator-1.3.0/README.md
--- old/python-email-validator-1.2.1/README.md  2022-05-02 00:17:51.000000000 
+0200
+++ new/python-email-validator-1.3.0/README.md  2022-09-18 21:30:31.000000000 
+0200
@@ -31,18 +31,7 @@
 
 [![Build 
Status](https://app.travis-ci.com/JoshData/python-email-validator.svg?branch=main)](https://app.travis-ci.com/JoshData/python-email-validator)
 
----
-
-This library was first published in 2015. The current version is 1.2.1
-(posted May 1, 2022). The main changes in version 1.2 are:
-
-* Rejecting domains with NULL MX records (when deliverability checks
-  are turned on).
-* Rejecting unsafe unicode characters. (Some of these checks you should
-  be doing on all of your user inputs already!)
-* Rejecting most special-use reserved domain names. A new `test_environment`
-  option is added for using `@*.test` domains.
-* Some fixes in the tests.
+View the [CHANGELOG / Release Notes](CHANGELOG.md) for the version history of 
changes in the library. Occasionally this README is ahead of the latest 
published package --- see the CHANGELOG for details.
 
 ---
 
@@ -67,26 +56,27 @@
 from email_validator import validate_email, EmailNotValidError
 
 email = "my+addr...@mydomain.tld"
+is_new_account = True # False for login pages
 
 try:
-  # Validate & take the normalized form of the email
-  # address for all logic beyond this point (especially
+  # Check that the email address is valid.
+  validation = validate_email(email, check_deliverability=is_new_account)
+
+  # Take the normalized form of the email address
+  # for all logic beyond this point (especially
   # before going to a database query where equality
-  # does not take into account normalization).
-  email = validate_email(email).email
+  # may not take into account Unicode normalization).  
+  email = validation.email
 except EmailNotValidError as e:
-  # email is not valid, exception message is human-readable
+  # Email is not valid.
+  # The exception message is human-readable.
   print(str(e))
 ```
 
 This validates the address and gives you its normalized form. You should
 **put the normalized form in your database** and always normalize before
-checking if an address is in your database.
-
-The validator will accept internationalized email addresses, but not all
-mail systems can send email to an addresses with non-English characters in
-the *local* part of the address (before the @-sign). See the `allow_smtputf8`
-option below.
+checking if an address is in your database. When using this in a login form,
+set `check_deliverability` to `False` to avoid unnecessary DNS queries.
 
 Usage
 -----
@@ -104,7 +94,7 @@
 
 When an email address is not valid, `validate_email` raises either an
 `EmailSyntaxError` if the form of the address is invalid or an
-`EmailUndeliverableError` if the domain name fails the DNS check. Both
+`EmailUndeliverableError` if the domain name fails DNS checks. Both
 exception classes are subclasses of `EmailNotValidError`, which in turn
 is a subclass of `ValueError`.
 
@@ -118,14 +108,16 @@
 later in the document about that.)
 
 The validator checks that the domain name in the email address has a
-(non-null) MX DNS record indicating that it is configured for email.
+DNS MX record (except a NULL MX record) indicating that it can receive
+email and that it does not have a reject-all SPF record (`v=spf1 -all`)
+which would indicate that it cannot send email.
 There is nothing to be gained by trying to actually contact an SMTP
 server, so that's not done here. For privacy, security, and practicality
 reasons servers are good at not giving away whether an address is
 deliverable or not: email addresses that appear to accept mail at first
 can bounce mail after a delay, and bounced mail may indicate a temporary
 failure of a good email address (sometimes an intentional failure, like
-greylisting). (A/AAAA-record fallback is also checked.)
+greylisting).
 
 ### Options
 
@@ -136,7 +128,7 @@
     require the
     [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.
 
-`check_deliverability=True`: Set to `False` to skip the domain name MX DNS 
record check. You can also set `email_validator.CHECK_DELIVERABILITY` to 
`False` to turn it off for all calls by default.
+`check_deliverability=True`: If true, DNS queries check that a non-null MX (or 
A/AAAA record as an MX fallback) is present for the domain-part of the email 
address and that a reject-all SPF record is not present. Set to `False` to skip 
these DNS checks. 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 the domain 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.
 
 `allow_empty_local=False`: Set to `True` to allow an empty local part (i.e.
     `@example.com`), e.g. for validating Postfix aliases.
@@ -160,7 +152,7 @@
 
 ### Test addresses
 
-This library rejects email addresess that use the [Special Use Domain 
Names](https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml)
 `invalid`, `localhost`, `test`, and some others by raising 
`EmailUndeliverableError`. This is to protect your system from abuse: You 
probably don't want a user to be able to cause an email to be sent to 
`localhost`. However, in your non-production test environments you may want to 
use `@test` or `@myname.test` email addresses. There are three ways you can 
allow this:
+This library rejects email addresess that use the [Special Use Domain 
Names](https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml)
 `invalid`, `localhost`, `test`, and some others by raising `EmailSyntaxError`. 
This is to protect your system from abuse: You probably don't want a user to be 
able to cause an email to be sent to `localhost`. However, in your 
non-production test environments you may want to use `@test` or `@myname.test` 
email addresses. There are three ways you can allow this:
 
 1. Add `test_environment=True` to the call to `validate_email` (see above).
 2. Set `email_validator.TEST_ENVIRONMENT` to `True`.
@@ -322,9 +314,7 @@
   ascii_email='t...@joshdata.me',
   ascii_local_part='test',
   ascii_domain='joshdata.me',
-  smtputf8=False,
-  mx=[(10, 'box.occams.info')],
-  mx_fallback_type=None)
+  smtputf8=False)
 ```
 
 For the fictitious address `example@???.life`, which has an
@@ -391,6 +381,7 @@
 | `smtputf8` | A boolean indicating that the 
[SMTPUTF8](https://tools.ietf.org/html/rfc6531) feature of your mail relay will 
be required to transmit messages to this address because the local part of the 
address has non-ASCII characters (the local part cannot be IDNA-encoded). If 
`allow_smtputf8=False` is passed as an argument, this flag will always be false 
because an exception is raised if it would have been true. |
 | `mx` | A list of (priority, domain) tuples of MX records specified in the 
DNS for the domain (see [RFC 5321 section 
5](https://tools.ietf.org/html/rfc5321#section-5)). May be `None` if the 
deliverability check could not be completed because of a temporary issue like a 
timeout. |
 | `mx_fallback_type` | `None` if an `MX` record is found. If no MX records are 
actually specified in DNS and instead are inferred, through an obsolete 
mechanism, from A or AAAA records, the value is the type of DNS record used 
instead (`A` or `AAAA`). May be `None` if the deliverability check could not be 
completed because of a temporary issue like a timeout. |
+| `spf` | Any SPF record found while checking deliverability. |
 
 Assumptions
 -----------
@@ -400,18 +391,22 @@
 or likely to cause trouble:
 
 * The validator assumes the email address is intended to be
-  deliverable on the public Internet. The domain part
-  of the email address must be a resolvable domain name.
-  [Special Use Domain 
Names](https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml)
-  and their subdomains are always considered invalid (except see
-  the `test_environment` parameter above).
-* The "quoted string" form of the local part of the email address (RFC
-  5321 4.1.2) is not permitted --- no one uses this anymore anyway.
+  usable on the public Internet. The domain part
+  of the email address must be a resolvable domain name
+  (without NULL MX or SPF -all DNS records) if deliverability
+  checks are turned on.
+  Most [Special Use Domain 
Names](https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml)
+  and their subdomains and
+  domain names without a `.` are rejected as a syntax error
+  (except see the `test_environment` parameter above).
+* Obsolete email syntaxes are rejected:
+  The "quoted string" form of the local part of the email address (RFC
+  5321 4.1.2) is not permitted.
   Quoted forms allow multiple @-signs, space characters, and other
   troublesome conditions. The unsual [(comment) 
syntax](https://github.com/JoshData/python-email-validator/issues/77)
-  in email addresses is also rejected.
-* The "literal" form for the domain part of an email address (an
-  IP address) is not accepted --- no one uses this anymore anyway.
+  is also rejected. The "literal" form for the domain part of an email address 
(an
+  IP address in brackets) is rejected. Other obsolete and deprecated syntaxes 
are
+  rejected. No one uses these forms anymore.
 
 Testing
 -------
@@ -430,17 +425,15 @@
 
 To release:
 
-* Update the version number.
-* Follow the steps below to publish source and a universal wheel to pypi.
+* Update CHANGELOG.md.
+* Update the version number in setup.cfg.
+* Make a commit with the new version number.
+* Follow the steps below to publish source and a universal wheel to pypi and 
tag the release.
 * Make a release at 
https://github.com/JoshData/python-email-validator/releases/new.
 
 ```sh
-pip3 install twine
-rm -rf dist
-python3 setup.py sdist
-python3 setup.py bdist_wheel
-twine upload dist/*
-git tag v1.0.XXX # replace with version in setup.cfg
+./release_to_pypi.sh
+git tag v$(grep version setup.cfg | sed "s/.*= //")
 git push --tags
 ```
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-email-validator-1.2.1/email_validator/__init__.py 
new/python-email-validator-1.3.0/email_validator/__init__.py
--- old/python-email-validator-1.2.1/email_validator/__init__.py        
2022-05-02 00:17:51.000000000 +0200
+++ new/python-email-validator-1.3.0/email_validator/__init__.py        
2022-09-18 21:30:31.000000000 +0200
@@ -12,6 +12,7 @@
 ALLOW_SMTPUTF8 = True
 CHECK_DELIVERABILITY = True
 TEST_ENVIRONMENT = False
+GLOBALLY_DELIVERABLE = True
 DEFAULT_TIMEOUT = 15  # secs
 
 # Based on RFC 2822 section 3.2.4 / RFC 5322 section 3.2.3, these
@@ -251,7 +252,9 @@
     return reason.format(prefix, diff, suffix)
 
 
-def caching_resolver(timeout=DEFAULT_TIMEOUT, cache=None):
+def caching_resolver(*, timeout=None, cache=None):
+    if timeout is None:
+        timeout = DEFAULT_TIMEOUT
     resolver = dns.resolver.Resolver()
     resolver.cache = cache or dns.resolver.LRUCache()
     resolver.lifetime = timeout  # timeout, in seconds
@@ -260,11 +263,14 @@
 
 def validate_email(
     email,
-    allow_smtputf8=ALLOW_SMTPUTF8,
+    # /, # not supported in Python 3.6, 3.7
+    *,
+    allow_smtputf8=None,
     allow_empty_local=False,
-    check_deliverability=CHECK_DELIVERABILITY,
-    test_environment=TEST_ENVIRONMENT,
-    timeout=DEFAULT_TIMEOUT,
+    check_deliverability=None,
+    test_environment=None,
+    globally_deliverable=GLOBALLY_DELIVERABLE,
+    timeout=None,
     dns_resolver=None
 ):
     """
@@ -273,6 +279,16 @@
     but if bytes it must be ASCII-only.
     """
 
+    # Fill in default values of arguments.
+    if allow_smtputf8 is None:
+        allow_smtputf8 = ALLOW_SMTPUTF8
+    if check_deliverability is None:
+        check_deliverability = CHECK_DELIVERABILITY
+    if test_environment is None:
+        test_environment = TEST_ENVIRONMENT
+    if timeout is None:
+        timeout = DEFAULT_TIMEOUT
+
     # Allow email to be a str or bytes instance. If bytes,
     # it must be ASCII because that's how the bytes work
     # on the wire with SMTP.
@@ -300,7 +316,7 @@
     ret.smtputf8 = local_part_info["smtputf8"]
 
     # Validate the email address's domain part syntax and get a normalized 
form.
-    domain_part_info = validate_email_domain_part(parts[1], 
test_environment=test_environment)
+    domain_part_info = validate_email_domain_part(parts[1], 
test_environment=test_environment, globally_deliverable=globally_deliverable)
     ret.domain = domain_part_info["domain"]
     ret.ascii_domain = domain_part_info["ascii_domain"]
 
@@ -356,9 +372,8 @@
         deliverability_info = validate_email_deliverability(
             ret["domain"], ret["domain_i18n"], timeout, dns_resolver
         )
-        if "mx" in deliverability_info:
-            ret.mx = deliverability_info["mx"]
-            ret.mx_fallback_type = deliverability_info["mx-fallback"]
+        for key, value in deliverability_info.items():
+            setattr(ret, key, value)
 
     return ret
 
@@ -460,7 +475,7 @@
         }
 
 
-def validate_email_domain_part(domain, test_environment=False):
+def validate_email_domain_part(domain, test_environment=False, 
globally_deliverable=True):
     # Empty?
     if len(domain) == 0:
         raise EmailSyntaxError("There must be something after the @-sign.")
@@ -538,16 +553,22 @@
     if not m:
         raise EmailSyntaxError("The email address contains invalid characters 
after the @-sign.")
 
-    # All publicly deliverable addresses have domain named with at least
-    # one period, and we'll consider the lack of a period a syntax error
-    # since that will match people's sense of what an email address looks
-    # like. We'll skip this in test environments to allow '@test' email
-    # addresses.
-    if "." not in ascii_domain and not (ascii_domain == "test" and 
test_environment):
-        raise EmailSyntaxError("The domain name %s is not valid. It should 
have a period." % domain_i18n)
+    if globally_deliverable:
+        # All publicly deliverable addresses have domain named with at least
+        # one period, and we'll consider the lack of a period a syntax error
+        # since that will match people's sense of what an email address looks
+        # like. We'll skip this in test environments to allow '@test' email
+        # addresses.
+        if "." not in ascii_domain and not (ascii_domain == "test" and 
test_environment):
+            raise EmailSyntaxError("The domain name %s is not valid. It should 
have a period." % domain_i18n)
+
+        # We also know that all TLDs currently end with a letter.
+        if not re.search(r"[A-Za-z]\Z", ascii_domain):
+            raise EmailSyntaxError(
+                "The domain name %s is not valid. It is not within a valid 
top-level domain." % domain_i18n
+            )
 
-    # Check special-use and reserved domain names. Raise these as
-    # deliverability errors since they are syntactically valid.
+    # Check special-use and reserved domain names.
     # Some might fail DNS-based deliverability checks, but that
     # can be turned off, so we should fail them all sooner.
     for d in SPECIAL_USE_DOMAIN_NAMES:
@@ -556,14 +577,7 @@
             continue
 
         if ascii_domain == d or ascii_domain.endswith("." + d):
-            raise EmailUndeliverableError("The domain name %s is a special-use 
or reserved name that cannot be used with email." % domain_i18n)
-
-    # We also know that all TLDs currently end with a letter, and
-    # we'll consider that a non-DNS based deliverability check.
-    if not re.search(r"[A-Za-z]\Z", ascii_domain):
-        raise EmailUndeliverableError(
-            "The domain name %s is not valid. It is not within a valid 
top-level domain." % domain_i18n
-        )
+            raise EmailSyntaxError("The domain name %s is a special-use or 
reserved name that cannot be used with email." % domain_i18n)
 
     # Return the IDNA ASCII-encoded form of the domain, which is how it
     # would be transmitted on the wire (except when used with SMTPUTF8
@@ -580,6 +594,8 @@
 def validate_email_deliverability(domain, domain_i18n, 
timeout=DEFAULT_TIMEOUT, dns_resolver=None):
     # Check that the domain resolves to an MX record. If there is no MX record,
     # try an A or AAAA record which is a deprecated fallback for 
deliverability.
+    # (Note that changing the DEFAULT_TIMEOUT module-level attribute
+    #  will not change the default value of this method's timeout argument.)
 
     # If no dns.resolver.Resolver was given, get dnspython's default resolver.
     # Override the default resolver's timeout. This may affect other uses of
@@ -588,6 +604,8 @@
         dns_resolver = dns.resolver.get_default_resolver()
         dns_resolver.lifetime = timeout
 
+    deliverability_info = {}
+
     def dns_resolver_resolve_shim(domain, record):
         try:
             # dns.resolver.Resolver.resolve is new to dnspython 2.x.
@@ -611,39 +629,61 @@
             raise dns.exception.Timeout()
 
         try:
-            # Try resolving for MX records and get them in sorted priority 
order
-            # as (priority, qname) pairs.
+            # Try resolving for MX records.
             response = dns_resolver_resolve_shim(domain, "MX")
+
+            # For reporting, put them in priority order and remove the 
trailing dot in the qnames.
             mtas = sorted([(r.preference, str(r.exchange).rstrip('.')) for r 
in response])
-            mx_fallback = None
 
-            # Do not permit delivery if there is only a "null MX" record 
(whose value is
-            # (0, ".") but we've stripped trailing dots, so the 'exchange' is 
just "").
+            # Remove "null MX" records from the list (their value is (0, ".") 
but we've stripped
+            # trailing dots, so the 'exchange' is just ""). If there was only 
a null MX record,
+            # email is not deliverable.
             mtas = [(preference, exchange) for preference, exchange in mtas
                     if exchange != ""]
             if len(mtas) == 0:
                 raise EmailUndeliverableError("The domain name %s does not 
accept email." % domain_i18n)
 
+            deliverability_info["mx"] = mtas
+            deliverability_info["mx_fallback_type"] = None
+
         except (dns.resolver.NoNameservers, dns.resolver.NXDOMAIN, 
dns.resolver.NoAnswer):
 
             # If there was no MX record, fall back to an A record.
             try:
                 response = dns_resolver_resolve_shim(domain, "A")
-                mtas = [(0, str(r)) for r in response]
-                mx_fallback = "A"
+                deliverability_info["mx"] = [(0, str(r)) for r in response]
+                deliverability_info["mx_fallback_type"] = "A"
             except (dns.resolver.NoNameservers, dns.resolver.NXDOMAIN, 
dns.resolver.NoAnswer):
 
                 # If there was no A record, fall back to an AAAA record.
                 try:
                     response = dns_resolver_resolve_shim(domain, "AAAA")
-                    mtas = [(0, str(r)) for r in response]
-                    mx_fallback = "AAAA"
+                    deliverability_info["mx"] = [(0, str(r)) for r in response]
+                    deliverability_info["mx_fallback_type"] = "AAAA"
                 except (dns.resolver.NoNameservers, dns.resolver.NXDOMAIN, 
dns.resolver.NoAnswer):
 
                     # If there was no MX, A, or AAAA record, then mail to
                     # this domain is not deliverable.
                     raise EmailUndeliverableError("The domain name %s does not 
exist." % domain_i18n)
 
+        try:
+            # Check for a SPF reject all ("v=spf1 -all") record which indicates
+            # no emails are sent from this domain, which like a NULL MX record
+            # would indicate that the domain is not used for email.
+            response = dns_resolver_resolve_shim(domain, "TXT")
+            for rec in response:
+                value = b"".join(rec.strings)
+                if value.startswith(b"v=spf1 "):
+                    deliverability_info["spf"] = value.decode("ascii", 
errors='replace')
+                    if value == b"v=spf1 -all":
+                        raise EmailUndeliverableError("The domain name %s does 
not send email." % domain_i18n)
+        except dns.resolver.NoAnswer:
+            # No TXT records means there is no SPF policy, so we cannot take 
any action.
+            pass
+        except (dns.resolver.NoNameservers, dns.resolver.NXDOMAIN):
+            # Failure to resolve at this step will be ignored.
+            pass
+
     except dns.exception.Timeout:
         # A timeout could occur for various reasons, so don't treat it as a 
failure.
         return {
@@ -660,10 +700,7 @@
             "There was an error while checking if the domain name in the email 
address is deliverable: " + str(e)
         )
 
-    return {
-        "mx": mtas,
-        "mx-fallback": mx_fallback,
-    }
+    return deliverability_info
 
 
 def main():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-email-validator-1.2.1/release_to_pypi.sh 
new/python-email-validator-1.3.0/release_to_pypi.sh
--- old/python-email-validator-1.2.1/release_to_pypi.sh 1970-01-01 
01:00:00.000000000 +0100
+++ new/python-email-validator-1.3.0/release_to_pypi.sh 2022-09-18 
21:30:31.000000000 +0200
@@ -0,0 +1,6 @@
+#!/bin/sh
+pip3 install --upgrade twine
+rm -rf dist
+python3 setup.py sdist
+python3 setup.py bdist_wheel
+twine upload -u __token__ dist/* # username: __token__ password: pypi API token
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-email-validator-1.2.1/setup.cfg 
new/python-email-validator-1.3.0/setup.cfg
--- old/python-email-validator-1.2.1/setup.cfg  2022-05-02 00:17:51.000000000 
+0200
+++ new/python-email-validator-1.3.0/setup.cfg  2022-09-18 21:30:31.000000000 
+0200
@@ -1,7 +1,7 @@
 [metadata]
 name = email_validator
-version = 1.2.1
-description = A robust email syntax and deliverability validation library.
+version = 1.3.0
+description = A robust email address syntax and deliverability validation 
library.
 long_description = file: README.md
 long_description_content_type = text/markdown
 url = https://github.com/JoshData/python-email-validator
@@ -19,6 +19,7 @@
     Programming Language :: Python :: 3.7
     Programming Language :: Python :: 3.8
     Programming Language :: Python :: 3.9
+    Programming Language :: Python :: 3.10
     Topic :: Software Development :: Libraries :: Python Modules
 keywords = email address validator
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-email-validator-1.2.1/tests/test_main.py 
new/python-email-validator-1.3.0/tests/test_main.py
--- old/python-email-validator-1.2.1/tests/test_main.py 2022-05-02 
00:17:51.000000000 +0200
+++ new/python-email-validator-1.3.0/tests/test_main.py 2022-09-18 
21:30:31.000000000 +0200
@@ -271,7 +271,7 @@
 def test_email_invalid_reserved_domain(email_input):
     # Since these all fail deliverabiltiy from a static list,
     # DNS deliverability checks do not arise.
-    with pytest.raises(EmailUndeliverableError) as exc_info:
+    with pytest.raises(EmailSyntaxError) as exc_info:
         validate_email(email_input)
     # print(f'({email_input!r}, {str(exc_info.value)!r}),')
     assert "is a special-use or reserved name" in str(exc_info.value)
@@ -320,6 +320,205 @@
     validate_email("anyth...@mycompany.test", test_environment=True)
 
 
+# This is the pyIsEmail (https://github.com/michaelherold/pyIsEmail) test 
suite.
+#
+# The test data was extracted by:
+#
+# $ wget 
https://raw.githubusercontent.com/michaelherold/pyIsEmail/master/tests/data/tests.xml
+# $ xmllint --xpath '/tests/test/address/text()' tests.xml  > t1
+# $ xmllint --xpath "/tests/test[not(address='')]/diagnosis/text()" tests.xml 
> t2
+#
+# tests = []
+# def fixup_char(c):
+#  if ord(c) >= 0x2400 and ord(c) <= 0x2432:
+#   c = chr(ord(c)-0x2400)
+#  return c
+# for email, diagnosis in zip(open("t1"), open("t2")):
+#  email = email[:-1] # strip trailing \n but not more because trailing 
whitespace is significant
+#  email = "".join(fixup_char(c) for c in email).replace("&amp;", "&")
+#  tests.append([email, diagnosis.strip()])
+# print(repr(tests).replace("'], ['", "'],\n['"))
+@pytest.mark.parametrize(
+    ('email_input', 'status'),
+    [
+        ['test', 'ISEMAIL_ERR_NODOMAIN'],
+        ['@', 'ISEMAIL_ERR_NOLOCALPART'],
+        ['test@', 'ISEMAIL_ERR_NODOMAIN'],
+        # ['test@io', 'ISEMAIL_VALID'], # we reject domains without a dot, 
knowing they are not deliverable
+        ['@io', 'ISEMAIL_ERR_NOLOCALPART'],
+        ['@iana.org', 'ISEMAIL_ERR_NOLOCALPART'],
+        ['t...@iana.org', 'ISEMAIL_VALID'],
+        ['t...@nominet.org.uk', 'ISEMAIL_VALID'],
+        ['test@about.museum', 'ISEMAIL_VALID'],
+        ['a...@iana.org', 'ISEMAIL_VALID'],
+        ['test.t...@iana.org', 'ISEMAIL_VALID'],
+        ['.t...@iana.org', 'ISEMAIL_ERR_DOT_START'],
+        ['te...@iana.org', 'ISEMAIL_ERR_DOT_END'],
+        ['test..iana.org', 'ISEMAIL_ERR_CONSECUTIVEDOTS'],
+        ['test_exa-mple.com', 'ISEMAIL_ERR_NODOMAIN'],
+        ['!#$%&`*+/=?^`{|}~@iana.org', 'ISEMAIL_VALID'],
+        ['test\\@t...@iana.org', 'ISEMAIL_ERR_EXPECTING_ATEXT'],
+        ['1...@iana.org', 'ISEMAIL_VALID'],
+        ['t...@123.com', 'ISEMAIL_VALID'],
+        
['abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi...@iana.org', 
'ISEMAIL_VALID'],
+        
['abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghik...@iana.org', 
'ISEMAIL_RFC5322_LOCAL_TOOLONG'],
+        
['t...@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm.com', 
'ISEMAIL_RFC5322_LABEL_TOOLONG'],
+        ['t...@mason-dixon.com', 'ISEMAIL_VALID'],
+        ['t...@-iana.org', 'ISEMAIL_ERR_DOMAINHYPHENSTART'],
+        ['t...@iana-.com', 'ISEMAIL_ERR_DOMAINHYPHENEND'],
+        ['t...@g--a.com', 'ISEMAIL_VALID'],
+        ['t...@.iana.org', 'ISEMAIL_ERR_DOT_START'],
+        ['t...@iana.org.', 'ISEMAIL_ERR_DOT_END'],
+        ['t...@iana..com', 'ISEMAIL_ERR_CONSECUTIVEDOTS'],
+        
['abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij',
 'ISEMAIL_RFC5322_TOOLONG'],
+        
['a...@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.hij',
 'ISEMAIL_RFC5322_TOOLONG'],
+        
['a...@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.hijk',
 'ISEMAIL_RFC5322_DOMAIN_TOOLONG'],
+        ['"test"@iana.org', 'ISEMAIL_RFC5321_QUOTEDSTRING'],
+        ['""@iana.org', 'ISEMAIL_RFC5321_QUOTEDSTRING'],
+        ['"""@iana.org', 'ISEMAIL_ERR_EXPECTING_ATEXT'],
+        ['"\\a"@iana.org', 'ISEMAIL_RFC5321_QUOTEDSTRING'],
+        ['"\\""@iana.org', 'ISEMAIL_RFC5321_QUOTEDSTRING'],
+        ['"\\"@iana.org', 'ISEMAIL_ERR_UNCLOSEDQUOTEDSTR'],
+        ['"\\\\"@iana.org', 'ISEMAIL_RFC5321_QUOTEDSTRING'],
+        ['test"@iana.org', 'ISEMAIL_ERR_EXPECTING_ATEXT'],
+        ['"t...@iana.org', 'ISEMAIL_ERR_UNCLOSEDQUOTEDSTR'],
+        ['"test"t...@iana.org', 'ISEMAIL_ERR_ATEXT_AFTER_QS'],
+        ['test"text"@iana.org', 'ISEMAIL_ERR_EXPECTING_ATEXT'],
+        ['"test""test"@iana.org', 'ISEMAIL_ERR_EXPECTING_ATEXT'],
+        ['"test"."test"@iana.org', 'ISEMAIL_DEPREC_LOCALPART'],
+        ['"test\\ test"@iana.org', 'ISEMAIL_RFC5321_QUOTEDSTRING'],
+        ['"test".t...@iana.org', 'ISEMAIL_DEPREC_LOCALPART'],
+        ['"test\x00"@iana.org', 'ISEMAIL_ERR_EXPECTING_QTEXT'],
+        ['"test\\\x00"@iana.org', 'ISEMAIL_DEPREC_QP'],
+        ['"abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz 
abcdefghj"@iana.org', 'ISEMAIL_RFC5322_LOCAL_TOOLONG'],
+        ['"abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz 
abcdefg\\h"@iana.org', 'ISEMAIL_RFC5322_LOCAL_TOOLONG'],
+        ['test@[255.255.255.255]', 'ISEMAIL_RFC5321_ADDRESSLITERAL'],
+        ['test@a[255.255.255.255]', 'ISEMAIL_ERR_EXPECTING_ATEXT'],
+        ['test@[255.255.255]', 'ISEMAIL_RFC5322_DOMAINLITERAL'],
+        ['test@[255.255.255.255.255]', 'ISEMAIL_RFC5322_DOMAINLITERAL'],
+        ['test@[255.255.255.256]', 'ISEMAIL_RFC5322_DOMAINLITERAL'],
+        ['test@[1111:2222:3333:4444:5555:6666:7777:8888]', 
'ISEMAIL_RFC5322_DOMAINLITERAL'],
+        ['test@[IPv6:1111:2222:3333:4444:5555:6666:7777]', 
'ISEMAIL_RFC5322_IPV6_GRPCOUNT'],
+        ['test@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888]', 
'ISEMAIL_RFC5321_ADDRESSLITERAL'],
+        ['test@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888:9999]', 
'ISEMAIL_RFC5322_IPV6_GRPCOUNT'],
+        ['test@[IPv6:1111:2222:3333:4444:5555:6666:7777:888G]', 
'ISEMAIL_RFC5322_IPV6_BADCHAR'],
+        ['test@[IPv6:1111:2222:3333:4444:5555:6666::8888]', 
'ISEMAIL_RFC5321_IPV6DEPRECATED'],
+        ['test@[IPv6:1111:2222:3333:4444:5555::8888]', 
'ISEMAIL_RFC5321_ADDRESSLITERAL'],
+        ['test@[IPv6:1111:2222:3333:4444:5555:6666::7777:8888]', 
'ISEMAIL_RFC5322_IPV6_MAXGRPS'],
+        ['test@[IPv6::3333:4444:5555:6666:7777:8888]', 
'ISEMAIL_RFC5322_IPV6_COLONSTRT'],
+        ['test@[IPv6:::3333:4444:5555:6666:7777:8888]', 
'ISEMAIL_RFC5321_ADDRESSLITERAL'],
+        ['test@[IPv6:1111::4444:5555::8888]', 
'ISEMAIL_RFC5322_IPV6_2X2XCOLON'],
+        ['test@[IPv6:::]', 'ISEMAIL_RFC5321_ADDRESSLITERAL'],
+        ['test@[IPv6:1111:2222:3333:4444:5555:255.255.255.255]', 
'ISEMAIL_RFC5322_IPV6_GRPCOUNT'],
+        ['test@[IPv6:1111:2222:3333:4444:5555:6666:255.255.255.255]', 
'ISEMAIL_RFC5321_ADDRESSLITERAL'],
+        ['test@[IPv6:1111:2222:3333:4444:5555:6666:7777:255.255.255.255]', 
'ISEMAIL_RFC5322_IPV6_GRPCOUNT'],
+        ['test@[IPv6:1111:2222:3333:4444::255.255.255.255]', 
'ISEMAIL_RFC5321_ADDRESSLITERAL'],
+        ['test@[IPv6:1111:2222:3333:4444:5555:6666::255.255.255.255]', 
'ISEMAIL_RFC5322_IPV6_MAXGRPS'],
+        ['test@[IPv6:1111:2222:3333:4444:::255.255.255.255]', 
'ISEMAIL_RFC5322_IPV6_2X2XCOLON'],
+        ['test@[IPv6::255.255.255.255]', 'ISEMAIL_RFC5322_IPV6_COLONSTRT'],
+        [' test @iana.org', 'ISEMAIL_DEPREC_CFWS_NEAR_AT'],
+        ['test@ iana .com', 'ISEMAIL_DEPREC_CFWS_NEAR_AT'],
+        ['test . t...@iana.org', 'ISEMAIL_DEPREC_FWS'],
+        ['\r\n t...@iana.org', 'ISEMAIL_CFWS_FWS'],
+        ['\r\n \r\n t...@iana.org', 'ISEMAIL_DEPREC_FWS'],
+        ['(comment)t...@iana.org', 'ISEMAIL_CFWS_COMMENT'],
+        ['((comment)t...@iana.org', 'ISEMAIL_ERR_UNCLOSEDCOMMENT'],
+        ['(comment(comment))t...@iana.org', 'ISEMAIL_CFWS_COMMENT'],
+        ['test@(comment)iana.org', 'ISEMAIL_DEPREC_CFWS_NEAR_AT'],
+        ['test(comment)t...@iana.org', 'ISEMAIL_ERR_ATEXT_AFTER_CFWS'],
+        ['test@(comment)[255.255.255.255]', 'ISEMAIL_DEPREC_CFWS_NEAR_AT'],
+        
['(comment)abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi...@iana.org',
 'ISEMAIL_CFWS_COMMENT'],
+        
['test@(comment)abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghikl.com',
 'ISEMAIL_DEPREC_CFWS_NEAR_AT'],
+        
['(comment)test@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghik.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghik.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk.abcdefghijklmnopqrstuvwxyzabcdefghijk.abcdefghijklmnopqrstu',
 'ISEMAIL_CFWS_COMMENT'],
+        ['t...@iana.org\n', 'ISEMAIL_ERR_EXPECTING_ATEXT'],
+        ['t...@xn--hxajbheg2az3al.xn--jxalpdlp', 'ISEMAIL_VALID'],
+        ['xn--t...@iana.org', 'ISEMAIL_VALID'],
+        ['t...@iana.org-', 'ISEMAIL_ERR_DOMAINHYPHENEND'],
+        ['"t...@iana.org', 'ISEMAIL_ERR_UNCLOSEDQUOTEDSTR'],
+        ['(t...@iana.org', 'ISEMAIL_ERR_UNCLOSEDCOMMENT'],
+        ['test@(iana.org', 'ISEMAIL_ERR_UNCLOSEDCOMMENT'],
+        ['test@[1.2.3.4', 'ISEMAIL_ERR_UNCLOSEDDOMLIT'],
+        ['"test\\"@iana.org', 'ISEMAIL_ERR_UNCLOSEDQUOTEDSTR'],
+        ['(comment\\)t...@iana.org', 'ISEMAIL_ERR_UNCLOSEDCOMMENT'],
+        ['t...@iana.org(comment\\)', 'ISEMAIL_ERR_UNCLOSEDCOMMENT'],
+        ['t...@iana.org(comment\\', 'ISEMAIL_ERR_BACKSLASHEND'],
+        ['test@[RFC-5322-domain-literal]', 'ISEMAIL_RFC5322_DOMAINLITERAL'],
+        ['test@[RFC-5322]-domain-literal]', 'ISEMAIL_ERR_ATEXT_AFTER_DOMLIT'],
+        ['test@[RFC-5322-[domain-literal]', 'ISEMAIL_ERR_EXPECTING_DTEXT'],
+        ['test@[RFC-5322-\\\x07-domain-literal]', 
'ISEMAIL_RFC5322_DOMLIT_OBSDTEXT'],
+        ['test@[RFC-5322-\\\t-domain-literal]', 
'ISEMAIL_RFC5322_DOMLIT_OBSDTEXT'],
+        ['test@[RFC-5322-\\]-domain-literal]', 
'ISEMAIL_RFC5322_DOMLIT_OBSDTEXT'],
+        ['test@[RFC-5322-domain-literal\\]', 'ISEMAIL_ERR_UNCLOSEDDOMLIT'],
+        ['test@[RFC-5322-domain-literal\\', 'ISEMAIL_ERR_BACKSLASHEND'],
+        ['test@[RFC 5322 domain literal]', 'ISEMAIL_RFC5322_DOMAINLITERAL'],
+        ['test@[RFC-5322-domain-literal] (comment)', 
'ISEMAIL_RFC5322_DOMAINLITERAL'],
+        ['\x...@iana.org', 'ISEMAIL_ERR_EXPECTING_ATEXT'],
+        ['test@\x7f.org', 'ISEMAIL_ERR_EXPECTING_ATEXT'],
+        ['"\x7f"@iana.org', 'ISEMAIL_DEPREC_QTEXT'],
+        ['"\\\x7f"@iana.org', 'ISEMAIL_DEPREC_QP'],
+        ['(\x7f)t...@iana.org', 'ISEMAIL_DEPREC_CTEXT'],
+        ['t...@iana.org\r', 'ISEMAIL_ERR_CR_NO_LF'],
+        ['\rt...@iana.org', 'ISEMAIL_ERR_CR_NO_LF'],
+        ['"\rtest"@iana.org', 'ISEMAIL_ERR_CR_NO_LF'],
+        ['(\r)t...@iana.org', 'ISEMAIL_ERR_CR_NO_LF'],
+        ['t...@iana.org(\r)', 'ISEMAIL_ERR_CR_NO_LF'],
+        ['\nt...@iana.org', 'ISEMAIL_ERR_EXPECTING_ATEXT'],
+        ['"\n"@iana.org', 'ISEMAIL_ERR_EXPECTING_QTEXT'],
+        ['"\\\n"@iana.org', 'ISEMAIL_DEPREC_QP'],
+        ['(\n)t...@iana.org', 'ISEMAIL_ERR_EXPECTING_CTEXT'],
+        ['\x...@iana.org', 'ISEMAIL_ERR_EXPECTING_ATEXT'],
+        ['test@\x07.org', 'ISEMAIL_ERR_EXPECTING_ATEXT'],
+        ['"\x07"@iana.org', 'ISEMAIL_DEPREC_QTEXT'],
+        ['"\\\x07"@iana.org', 'ISEMAIL_DEPREC_QP'],
+        ['(\x07)t...@iana.org', 'ISEMAIL_DEPREC_CTEXT'],
+        ['\r\nt...@iana.org', 'ISEMAIL_ERR_FWS_CRLF_END'],
+        ['\r\n \r\nt...@iana.org', 'ISEMAIL_ERR_FWS_CRLF_END'],
+        [' \r\nt...@iana.org', 'ISEMAIL_ERR_FWS_CRLF_END'],
+        [' \r\n t...@iana.org', 'ISEMAIL_CFWS_FWS'],
+        [' \r\n \r\nt...@iana.org', 'ISEMAIL_ERR_FWS_CRLF_END'],
+        [' \r\n\r\nt...@iana.org', 'ISEMAIL_ERR_FWS_CRLF_X2'],
+        [' \r\n\r\n t...@iana.org', 'ISEMAIL_ERR_FWS_CRLF_X2'],
+        ['t...@iana.org\r\n ', 'ISEMAIL_CFWS_FWS'],
+        ['t...@iana.org\r\n \r\n ', 'ISEMAIL_DEPREC_FWS'],
+        ['t...@iana.org\r\n', 'ISEMAIL_ERR_FWS_CRLF_END'],
+        ['t...@iana.org\r\n \r\n', 'ISEMAIL_ERR_FWS_CRLF_END'],
+        ['t...@iana.org \r\n', 'ISEMAIL_ERR_FWS_CRLF_END'],
+        ['t...@iana.org \r\n ', 'ISEMAIL_CFWS_FWS'],
+        ['t...@iana.org \r\n \r\n', 'ISEMAIL_ERR_FWS_CRLF_END'],
+        ['t...@iana.org \r\n\r\n', 'ISEMAIL_ERR_FWS_CRLF_X2'],
+        ['t...@iana.org \r\n\r\n ', 'ISEMAIL_ERR_FWS_CRLF_X2'],
+        [' t...@iana.org', 'ISEMAIL_CFWS_FWS'],
+        ['t...@iana.org ', 'ISEMAIL_CFWS_FWS'],
+        ['test@[IPv6:1::2:]', 'ISEMAIL_RFC5322_IPV6_COLONEND'],
+        ['"test\\??"@iana.org', 'ISEMAIL_ERR_EXPECTING_QPAIR'],
+        ['test@iana/icann.org', 'ISEMAIL_RFC5322_DOMAIN'],
+        ['test.(comment)t...@iana.org', 'ISEMAIL_DEPREC_COMMENT']
+    ]
+)
+def test_pyisemail_tests(email_input, status):
+    if status == "ISEMAIL_VALID":
+        # All standard email address forms should not raise an exception.
+        validate_email(email_input, test_environment=True)
+    elif "_ERR_" in status or "_TOOLONG" in status \
+         or "_CFWS_FWS" in status or "_CFWS_COMMENT" in status \
+         or "_IPV6" in status or status == "ISEMAIL_RFC5322_DOMAIN":
+        # Invalid syntax, extranous whitespace, and "(comments)" should be 
rejected.
+        # The _IPV6_ diagnoses appear to represent syntactically invalid 
domain literals.
+        # The ISEMAIL_RFC5322_DOMAIN diagnosis appears to be a syntactically 
invalid domain.
+        with pytest.raises(EmailSyntaxError):
+            validate_email(email_input, test_environment=True)
+    elif "_DEPREC_" in status \
+         or "RFC5321_QUOTEDSTRING" in status \
+         or "DOMAINLITERAL" in status or "_DOMLIT_" in status or 
"_ADDRESSLITERAL" in status:
+        # Quoted strings in the local part, domain literals (IP addresses in 
brackets),
+        # and other deprecated syntax are valid email addresses and are 
accepted by pyIsEmail,
+        # but we reject them.
+        with pytest.raises(EmailSyntaxError):
+            validate_email(email_input, test_environment=True)
+    else:
+        raise ValueError("status {} is not recognized".format(status))
+
+
 def test_dict_accessor():
     input_email = "testa...@example.tld"
     valid_email = validate_email(input_email, check_deliverability=False)
@@ -329,8 +528,8 @@
 
 def test_deliverability_found():
     response = validate_email_deliverability('gmail.com', 'gmail.com')
-    assert response.keys() == {'mx', 'mx-fallback'}
-    assert response['mx-fallback'] is None
+    assert response.keys() == {'mx', 'mx_fallback_type', 'spf'}
+    assert response['mx_fallback_type'] is None
     assert len(response['mx']) > 1
     assert len(response['mx'][0]) == 2
     assert isinstance(response['mx'][0][0], int)

Reply via email to