Skip to content

Commit e8df0ec

Browse files
authored
Modernize packaging
Switch to pyproject.toml packaging, using hatchling. - Replace all uses of setup.py with updated equivalent - BREAKING: Change extra name `amazon_ses` to `amazon-ses`, to comply with Python packaging name normalization - Use hatch custom build hook to freeze version number in readme (previously custom setup.py code) - Move separate requirements for dev, docs, tests into their own requirements.txt files - Fix AnymailImproperlyInstalled to correctly refer to package extra name - Update testing documentation - Update docs readme rendering to match PyPI (and avoid setup.py) - In tox tests, use isolated builds and update pip - Remove AUTHORS.txt (it just referred to GitHub)
1 parent 9fba582 commit e8df0ec

31 files changed

+417
-291
lines changed

.github/workflows/release.yml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,41 +24,43 @@ jobs:
2424
steps:
2525
- name: Get code
2626
uses: actions/checkout@v3
27+
2728
- name: Setup Python
2829
uses: actions/setup-python@v4
2930
with:
3031
python-version: "3.10"
3132

33+
- name: Install build requirements
34+
run: |
35+
python -m pip install --upgrade build hatch twine
36+
3237
- name: Get version
3338
# (This will end the workflow if git and source versions don't match.)
3439
id: version
3540
run: |
36-
VERSION="$(python setup.py --version)"
41+
VERSION="$(python -m hatch version)"
3742
TAG="v$VERSION"
3843
GIT_TAG="$(git tag -l --points-at "$GITHUB_REF" 'v*')"
39-
if [ "$GIT_TAG" != "$TAG" ]; then
44+
if [ "x$GIT_TAG" != "x$TAG" ]; then
4045
echo "::error ::package version '$TAG' does not match git tag '$GIT_TAG'"
4146
exit 1
4247
fi
4348
echo "version=$VERSION" >> $GITHUB_OUTPUT
4449
echo "tag=$TAG" >> $GITHUB_OUTPUT
4550
echo "anchor=${TAG//[^[:alnum:]]/-}" >> $GITHUB_OUTPUT
4651
47-
- name: Install build requirements
48-
run: |
49-
pip install twine wheel
5052
- name: Build
5153
run: |
5254
rm -rf build dist django_anymail.egg-info
53-
python setup.py sdist bdist_wheel
54-
twine check dist/*
55+
python -m build
56+
python -m twine check dist/*
5557
5658
- name: Publish to PyPI
5759
env:
5860
TWINE_USERNAME: __token__
5961
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
6062
run: |
61-
twine upload dist/*
63+
python -m twine upload dist/*
6264
6365
- name: Release to GitHub
6466
env:

ADDING_ESPS.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,20 @@ tests regularly. That requires the ESP have a free tier (testing is
3838
extremely low volume), a sandbox API, or that they offer developer
3939
accounts for open source projects like Anymail.
4040

41+
## Boilerplate
42+
43+
You should add entries for your ESP in:
44+
45+
- pyproject.toml:
46+
- in the `[project]` metadata section under `description` and `keywords`
47+
- in the `[project.optional-dependencies]` section
48+
- integration-test.yml in the test matrix
49+
- tox.ini in the `[testenv]` section under `setenv`
50+
- if your ESP requires any extra dependencies, also update the tox.ini
51+
`[testenv] extras` and the "partial installation" at the bottom of
52+
`[tox] envlist`
53+
- README.rst in the list of ESPs
54+
4155
## EmailBackend and payload
4256

4357
Anymail abstracts a lot of common functionality into its base classes;
@@ -99,9 +113,6 @@ Need to parse JSON in the API response? Use `self.deserialize_json_response()`
99113

100114
Good starting points: Test backend; SparkPost
101115

102-
Don't forget add an `'extras_require'` entry for your ESP in setup.py.
103-
Also update `'tests_require'`.
104-
105116
If the client lib supports the notion of a reusable API "connection"
106117
(or session), you should override `open()` and `close()` to provide
107118
API state caching. See the notes in the base implementation.

AUTHORS.txt

Lines changed: 0 additions & 5 deletions
This file was deleted.

CHANGELOG.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,25 @@ vNext
3333
Breaking changes
3434
~~~~~~~~~~~~~~~~
3535

36+
* **Amazon SES:** The "extra name" for installation must now be spelled with
37+
a hyphen rather than an underscore: ``django-anymail[amazon-ses]``.
38+
Be sure to update any dependencies specification (pip install, requirements.txt,
39+
etc.) that had been using ``[amazon_ses]``.
40+
3641
* Require Python 3.7 or later.
42+
3743
* Require urllib3 1.25 or later (released 2019-04-29).
3844

45+
Other
46+
~~~~~
47+
48+
* Modernize packaging. (Change from setup.py and setuptools
49+
to pyproject.toml and hatchling.) Other than the ``amazon-ses``
50+
naming normalization noted above, the new packaging should have
51+
no impact. If you have trouble installing django-anymail v10 where
52+
v9 worked, please report an issue including the exact install
53+
command and pip version you are using.
54+
3955

4056
v9.2
4157
-----

MANIFEST.in

Lines changed: 0 additions & 2 deletions
This file was deleted.

README.rst

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ Anymail: Django email integration for transactional ESPs
55
* Github: project page, exactly as it appears here
66
* Docs: shared-intro section gets included in docs/index.rst
77
quickstart section gets included in docs/quickstart.rst
8-
* PyPI: project page (via setup.py long_description),
9-
with several edits to freeze it to the specific PyPI release
10-
(see long_description_from_readme in setup.py)
8+
* PyPI: project page (via pyproject.toml readme; see also
9+
hatch_build.py which edits in the release version number)
1110
You can use docutils 1.0 markup, but *not* any Sphinx additions.
1211
GitHub rst supports code-block, but *no other* block directives.
1312

anymail/__init__.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
1-
# Expose package version at root of package
2-
from django import VERSION as DJANGO_VERSION
1+
from ._version import VERSION, __version__
32

4-
from ._version import VERSION, __version__ # NOQA: F401
3+
__all__ = [
4+
"VERSION",
5+
"__version__",
6+
]
57

6-
if DJANGO_VERSION < (3, 2, 0):
7-
default_app_config = "anymail.apps.AnymailBaseConfig"
8+
try:
9+
import django
10+
except ImportError:
11+
# (don't require django just to get package version)
12+
pass
13+
else:
14+
if django.VERSION < (3, 2, 0):
15+
# (No longer required -- and causes deprecation warning -- in Django 3.2+)
16+
default_app_config = "anymail.apps.AnymailBaseConfig"
17+
__all__.append("default_app_config")

anymail/_version.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
VERSION = (9, 2)
1+
# Don't import this file directly (unless you are a build system).
2+
# Instead, load version info from the package root.
23

34
#: major.minor.patch or major.minor.devN
4-
__version__ = ".".join([str(x) for x in VERSION])
5+
__version__ = "10.0.dev0"
56

6-
#: Sphinx's X.Y "version"
7-
__minor_version__ = ".".join([str(x) for x in VERSION[:2]])
7+
VERSION = __version__.split(",")

anymail/backends/amazon_ses.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from botocore.exceptions import BotoCoreError, ClientError, ConnectionError
1414
except ImportError as err:
1515
raise AnymailImproperlyInstalled(
16-
missing_package="boto3", backend="amazon_ses"
16+
missing_package="boto3", install_extra="amazon-ses"
1717
) from err
1818

1919

anymail/backends/amazon_sesv2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from botocore.exceptions import BotoCoreError, ClientError, ConnectionError
1515
except ImportError as err:
1616
raise AnymailImproperlyInstalled(
17-
missing_package="boto3", backend="amazon_sesv2"
17+
missing_package="boto3", install_extra="amazon-ses"
1818
) from err
1919

2020

0 commit comments

Comments
 (0)