From 5bcfcdd315b792dd74123df4b3efafba0c3f2a9c Mon Sep 17 00:00:00 2001
From: Matt Westcott <matt@west.co.tt>
Date: Mon, 2 Nov 2020 17:29:58 +0000
Subject: [PATCH] Formalise support for Python 3.9

---
 .travis.yml                       | 58 +++++++++++++------------------
 README.md                         |  2 +-
 docs/getting_started/tutorial.rst |  4 +--
 docs/releases/upgrading.rst       |  2 +-
 setup.py                          |  3 +-
 tox.ini                           |  3 +-
 6 files changed, 32 insertions(+), 40 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 03cda6a530..d0fb160cb7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,52 +9,42 @@ matrix:
   include:
    - env: TOXENV=py36-dj22-mysql-noelasticsearch
      python: 3.6
-   - env: TOXENV=py36-dj22-postgres-noelasticsearch
-     python: 3.6
-   - env: TOXENV=py37-dj22-sqlite-noelasticsearch
-     python: 3.7
    - env: TOXENV=py37-dj30-sqlite-noelasticsearch
      python: 3.7
-   - env: TOXENV=py37-dj30-mysql-noelasticsearch
-     python: 3.7
-   - env: TOXENV=py38-dj30-postgres-noelasticsearch
-     python: 3.8
    - env: TOXENV=py38-dj31-postgres-noelasticsearch
      python: 3.8
-   - env: TOXENV=py38-dj31-postgres-noelasticsearch-emailuser
-     python: 3.8
-   - env: TOXENV=py38-dj31-postgres-noelasticsearch-notz
-     python: 3.8
-   - env: TOXENV=py38-dj31stable-postgres-noelasticsearch
-     python: 3.8
-   - env: TOXENV=py38-djmaster-postgres-noelasticsearch
-     python: 3.8
+   - env: TOXENV=py39-dj31-mysql-noelasticsearch
+     python: 3.9
+   - env: TOXENV=py39-dj31-sqlite-noelasticsearch
+     python: 3.9
+   - env: TOXENV=py39-dj31-postgres-noelasticsearch-emailuser
+     python: 3.9
+   - env: TOXENV=py39-dj31-postgres-noelasticsearch-notz
+     python: 3.9
+   - env: TOXENV=py39-dj31stable-postgres-noelasticsearch
+     python: 3.9
+   - env: TOXENV=py39-djmaster-postgres-noelasticsearch
+     python: 3.9
    - env: TOXENV=py36-dj22-sqlite-elasticsearch2 INSTALL_ELASTICSEARCH2=yes
      python: 3.6
-   - env: TOXENV=py36-dj22-postgres-elasticsearch5 INSTALL_ELASTICSEARCH5=yes
-     python: 3.6
-   - env: TOXENV=py37-dj22-postgres-elasticsearch6 INSTALL_ELASTICSEARCH6=yes
+   - env: TOXENV=py37-dj30-postgres-elasticsearch5 INSTALL_ELASTICSEARCH5=yes
      python: 3.7
-   - env: TOXENV=py38-dj22-postgres-elasticsearch7 INSTALL_ELASTICSEARCH7=yes
-     python: 3.8
-   - env: TOXENV=py38-dj30-postgres-elasticsearch7 INSTALL_ELASTICSEARCH7=yes
-     python: 3.8
-   - env: TOXENV=py38-dj31-postgres-elasticsearch7 INSTALL_ELASTICSEARCH7=yes
-     python: 3.8
-   - env: TOXENV=py38-dj31-postgres-elasticsearch7-emailuser INSTALL_ELASTICSEARCH7=yes
+   - env: TOXENV=py38-dj31-postgres-elasticsearch6 INSTALL_ELASTICSEARCH6=yes
      python: 3.8
+   - env: TOXENV=py39-dj31-postgres-elasticsearch7 INSTALL_ELASTICSEARCH7=yes
+     python: 3.9
+   - env: TOXENV=py39-dj31-sqlite-elasticsearch7-emailuser INSTALL_ELASTICSEARCH7=yes
+     python: 3.9
   allow_failures:
     # Ignore failures on Elasticsearch tests because ES on Travis is intermittently flaky
     - env: TOXENV=py36-dj22-sqlite-elasticsearch2 INSTALL_ELASTICSEARCH2=yes
-    - env: TOXENV=py36-dj22-postgres-elasticsearch5 INSTALL_ELASTICSEARCH5=yes
-    - env: TOXENV=py37-dj22-postgres-elasticsearch6 INSTALL_ELASTICSEARCH6=yes
-    - env: TOXENV=py38-dj22-postgres-elasticsearch7 INSTALL_ELASTICSEARCH7=yes
-    - env: TOXENV=py38-dj30-postgres-elasticsearch7 INSTALL_ELASTICSEARCH7=yes
-    - env: TOXENV=py38-dj31-postgres-elasticsearch7 INSTALL_ELASTICSEARCH7=yes
-    - env: TOXENV=py38-dj31-postgres-elasticsearch7-emailuser INSTALL_ELASTICSEARCH7=yes
+    - env: TOXENV=py37-dj30-postgres-elasticsearch5 INSTALL_ELASTICSEARCH5=yes
+    - env: TOXENV=py38-dj31-postgres-elasticsearch6 INSTALL_ELASTICSEARCH6=yes
+    - env: TOXENV=py39-dj31-postgres-elasticsearch7 INSTALL_ELASTICSEARCH7=yes
+    - env: TOXENV=py39-dj31-sqlite-elasticsearch7-emailuser INSTALL_ELASTICSEARCH7=yes
     # allow failures against Django pre-releases on git
-    - env: TOXENV=py38-dj31stable-postgres-noelasticsearch
-    - env: TOXENV=py38-djmaster-postgres-noelasticsearch
+    - env: TOXENV=py39-dj31stable-postgres-noelasticsearch
+    - env: TOXENV=py39-djmaster-postgres-noelasticsearch
 
 # Services
 services:
diff --git a/README.md b/README.md
index 29f1a77854..69a9415c7a 100644
--- a/README.md
+++ b/README.md
@@ -57,7 +57,7 @@ _(If you are reading this on GitHub, the details here may not be indicative of t
 Wagtail supports:
 
 * Django 2.2.x, 3.0.x and 3.1.x
-* Python 3.6, 3.7 and 3.8
+* Python 3.6, 3.7, 3.8 and 3.9
 * PostgreSQL, MySQL and SQLite as database backends
 
 [Previous versions of Wagtail](https://docs.wagtail.io/en/stable/releases/upgrading.html#compatible-django-python-versions) additionally supported Python 2.7 and Django 1.x.
diff --git a/docs/getting_started/tutorial.rst b/docs/getting_started/tutorial.rst
index eba012adfd..d37e0a4c12 100644
--- a/docs/getting_started/tutorial.rst
+++ b/docs/getting_started/tutorial.rst
@@ -11,7 +11,7 @@ Install and run Wagtail
 Install dependencies
 ~~~~~~~~~~~~~~~~~~~~
 
-Wagtail supports Python 3.5, 3.6, 3.7 and 3.8.
+Wagtail supports Python 3.6, 3.7, 3.8 and 3.9.
 
 To check whether you have an appropriate version of Python 3:
 
@@ -19,7 +19,7 @@ To check whether you have an appropriate version of Python 3:
 
    $ python3 --version
 
-If this does not return a version number or returns a version lower than 3.5, you will need to `install Python 3 <https://www.python.org/downloads/>`_.
+If this does not return a version number or returns a version lower than 3.6, you will need to `install Python 3 <https://www.python.org/downloads/>`_.
 
 .. important::
    Before installing Wagtail, it is necessary to install the **libjpeg** and **zlib** libraries, which provide support for working with JPEG, PNG and GIF images (via the Python **Pillow** library).
diff --git a/docs/releases/upgrading.rst b/docs/releases/upgrading.rst
index 6c80c7378e..32fc2adc3d 100644
--- a/docs/releases/upgrading.rst
+++ b/docs/releases/upgrading.rst
@@ -139,5 +139,5 @@ The compatible versions of Django and Python for each Wagtail release are:
 +-------------------+------------------------------+-----------------------------+
 | 2.11              | 2.2, 3.0, 3.1                | 3.6, 3.7, 3.8               |
 +-------------------+------------------------------+-----------------------------+
-| 2.12              | 2.2, 3.0, 3.1                | 3.6, 3.7, 3.8               |
+| 2.12              | 2.2, 3.0, 3.1                | 3.6, 3.7, 3.8, 3.9          |
 +-------------------+------------------------------+-----------------------------+
diff --git a/setup.py b/setup.py
index 6ace006eb7..8b23d6ac0b 100755
--- a/setup.py
+++ b/setup.py
@@ -45,7 +45,7 @@ testing_extras = [
     'pytz>=2014.7',
     'elasticsearch>=1.0.0,<3.0',
     'Jinja2>=2.8,<3.0',
-    'boto3>=1.4,<1.5',
+    'boto3>=1.16,<1.17',
     'freezegun>=0.3.8',
     'openpyxl>=2.6.4',
     'Unidecode>=0.04.14,<2.0',
@@ -105,6 +105,7 @@ https://github.com/wagtail/wagtail/.",
         'Programming Language :: Python :: 3.6',
         'Programming Language :: Python :: 3.7',
         'Programming Language :: Python :: 3.8',
+        'Programming Language :: Python :: 3.9',
         'Framework :: Django',
         'Framework :: Django :: 2.2',
         'Framework :: Django :: 3.0',
diff --git a/tox.ini b/tox.ini
index 2316878cf9..b479825b6a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -2,7 +2,7 @@
 skipsdist = True
 usedevelop = True
 
-envlist = py{36,37,38}-dj{22,30,31,31stable,master}-{sqlite,postgres,mysql,mssql}-{elasticsearch7,elasticsearch6,elasticsearch5,elasticsearch2,noelasticsearch}-{customuser,emailuser}-{tz,notz},
+envlist = py{36,37,38,39}-dj{22,30,31,31stable,master}-{sqlite,postgres,mysql,mssql}-{elasticsearch7,elasticsearch6,elasticsearch5,elasticsearch2,noelasticsearch}-{customuser,emailuser}-{tz,notz},
 
 [testenv]
 install_command = pip install -e ".[testing]" -U {opts} {packages}
@@ -17,6 +17,7 @@ basepython =
     py36: python3.6
     py37: python3.7
     py38: python3.8
+    py39: python3.9
 
 deps =
     django-sendfile==0.3.6