Related changes:
* remove Travis-CI config; stop running tests on Travis
* rename live integration test environment variables
to all start with `ANYMAIL_TEST_` (simplifies tox config)
Minimum supported versions are now Django 2.0, Python 3.5.
This touches a lot of code, to:
* Remove obsolete portability code and workarounds
(six, backports of email parsers, test utils, etc.)
* Use Python 3 syntax (class defs, raise ... from, etc.)
* Correct inheritance for mixin classes
* Fix outdated docs content and links
* Suppress Python 3 "unclosed SSLSocket" ResourceWarnings
that are beyond our control (in integration tests due to boto3,
python-sparkpost)
In the live integration tests, work around Mailgun's recent change
to how inline attachments are reported in "accepted" events data.
(But keep it working either way, since it seems likely this change was
unintentional—other event types still exclude inline attachments from
`event.message.attachments`.)
Fixes#172
Mailgun has two different template mechanisms and two different ways
of providing substitution variables to them. Update Anymail's
normalized merge_data handling to work with either (while preserving
existing batch send and metadata capabilities that also use Mailgun's
custom data and recipient variables parameters).
Completes work started by @anstosa in #156.
Closes#155.
Tox:
* Add Tox factor for extras (all, none, individual ESP).
For now, only break out ESPs that have specific extra
dependencies (amazon_ses, sparkpost).
* Install most package dependencies (including extras)
through the package itself.
* Use new runtests.py environment vars to limit test tags
when Tox isn't installing all extras.
Travis:
* Rework matrix to request specific TOXENVs directly;
drop tox-travis.
Test runner (runtests.py):
* Centralize RUN_LIVE_TESTS logic in runtests.py
* Add ANYMAIL_ONLY_TEST and ANYMAIL_SKIP_TESTS env vars
(comma-separated lists of tags)
Test implementations:
* Tag all ESP-specific tests with ESP
* Tag live tests with "live"
* Don't import ESP-specific packages at test module level.
(Test discovery imports test modules before tag-based filtering.)
Closes#104
Workaround requests/requests#4652 (urllib3/urllib3#303), where
uploaded files in multipart/form-data are improperly given RFC 2231
encoded filenames. That format is not accepted by Mailgun's API (and is
prohibited by RFC 7578), resulting in the attachments being silently
dropped.
Fix is to patch up the multipart/form-data before posting to remove
the RFC 2231 encoding.
Fixes#125
Using undeliverable @example.com recipient addresses leads some ESPs
to flag the Anymail test accounts. Switch all live integration tests
to mailinator.com recipients (unless they were already using the ESP's
own "test sink" addresses).
[RFC-5322 allows](https://tools.ietf.org/html/rfc5322#section-3.6.2)
multiple addresses in the From header.
Django's SMTP backend supports this, as a single comma-separated
string (*not* a list of strings like the recipient params):
from_email='one@example.com, two@example.com'
to=['one@example.com', 'two@example.com']
Both Mailgun and SparkPost support multiple From addresses
(and Postmark accepts them, though truncates to the first one
on their end). For compatibility with Django -- and because
Anymail attempts to support all ESP features -- Anymail now
allows multiple From addresses, too, for ESPs that support it.
Note: as a practical matter, deliverability with multiple
From addresses is pretty bad. (Google outright rejects them.)
This change also reworks Anymail's internal ParsedEmail object,
and approach to parsing addresses, for better consistency with
Django's SMTP backend and improved error messaging.
In particular, Django (and now Anymail) allows multiple email
addresses in a single recipient string:
to=['one@example.com', 'two@example.com, three@example.com']
len(to) == 2 # but there will be three recipients
Fixes#60
Track change to Mailgun's events API, which
no longer includes message recipients.
(Only affected check for successful send
in the integration tests; Anymail doesn't
use the events API outside test code.)
Fixes#58
* **Future breaking change:**
Rename all Anymail backends to just `EmailBackend`,
matching Django's naming convention.
(E.g., switch to "anymail.backends.mailgun.EmailBackend"
rather than "anymail.backends.mailgun.MailgunBackend".)
The old names still work, but will issue a DeprecationWarning
and will be removed in some future release.
(Apologies for this change; the old naming convention was
a holdover from Djrill, and I wanted consistency with
other Django EmailBackends before hitting 1.0.)
Fixes#49.
Drop `from __future__ import unicode_literals`;
it was there for Python 3.2 compatibility (which
Anymail doesn't support). Ensures tests use normal
strs in Python 2.x.
Allow custom MAILGUN_SENDER_DOMAIN in Anymail
settings. (Replaces need to use global esp_extra.)
Improve docs to cover cases where this is needed.
(esp_extra sender_domain is still supported for
overriding individual messages.)
Fixes#26.
To conserve our ESP test accounts' send quotas, don't run
the live API integration tests 13 times in every Travis run.
Instead, just run them twice, on a representative set
of Python/Django combinations:
* Once on Python 2.7 (currently with Django 1.8)
* Once on Python 3.x (currently 3.5 with Django 1.9)
(Prep for running weekly tests on Travis cron.)
The *non*-integration tests still run on all combos.
* Introduce RUN_LIVE_TESTS environment var to control
whether live API integration test cases should run.
Default True, except in Travis-CI runs default False.
* Enable RUN_LIVE_TESTS in .travis.yml matrix for the
Python/Django combos listed above.
Treat Mailgun metadata like all other ESPs: simple
key-value dict, where values are strings. If you want
to store JSON in metadata, you should serialize and
deserialize it yourself.