diff --git a/.travis.yml b/.travis.yml
index a79a5126b19412ef873c8973c2c648981be3e8b7..f8f0778caefaa1c51d359eed2d00a7e9d92f6afb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,12 +18,12 @@ jobs:
   fast_finish: true
   include:
     - stage: 'style checks'
-      python: '3.7'
+      python: '3.8'
       os: linux
       language: python
       env: TEST_SUITE=flake8
 # Shell integration with module files
-    - python: '3.7'
+    - python: '3.8'
       os: linux
       language: python
       env: [ TEST_SUITE=bootstrap ]
@@ -46,10 +46,14 @@ jobs:
       language: python
       env: TEST_SUITE=unit
     - python: '3.7'
+      os: linux
+      language: python
+      env: TEST_SUITE=unit
+    - python: '3.8'
       os: linux
       language: python
       env: [ TEST_SUITE=unit, COVERAGE=true ]
-    - python: '3.7'
+    - python: '3.8'
       os: linux
       language: python
       env: TEST_SUITE=doc
@@ -64,41 +68,41 @@ jobs:
       language: python
       env: [ TEST_SUITE=build, 'SPEC=mpich' ]
 # astyle (MakefilePackage)
-    - python: '3.7'
+    - python: '3.8'
       os: linux
       language: python
       env: [ TEST_SUITE=build, 'SPEC=astyle' ]
 # tut (WafPackage)
-    - python: '3.7'
+    - python: '3.8'
       os: linux
       language: python
       env: [ TEST_SUITE=build, 'SPEC=tut' ]
 # py-setuptools (PythonPackage)
-    - python: '3.7'
+    - python: '3.8'
       os: linux
       language: python
       env: [ TEST_SUITE=build, 'SPEC=py-setuptools' ]
 # perl-dbi (PerlPackage)
-#    - python: '2.7'
+#    - python: '3.8'
 #      os: linux
 #      language: python
 #      env: [ TEST_SUITE=build, 'SPEC=perl-dbi' ]
 # openjpeg (CMakePackage + external cmake)
-    - python: '3.7'
+    - python: '3.8'
       os: linux
       language: python
       env: [ TEST_SUITE=build, 'SPEC=openjpeg' ]
 # r-rcpp (RPackage + external R)
-    - python: '3.7'
+    - python: '3.8'
       os: linux
       language: python
       env: [ TEST_SUITE=build, 'SPEC=r-rcpp' ]
 # mpich (AutotoolsPackage)
-    - python: '3.7'
+    - python: '3.8'
       os: linux
       language: python
       env: [ TEST_SUITE=build, 'SPEC=mpich' ]
-    - python: '3.6'
+    - python: '3.8'
       stage: 'docker build'
       os: linux
       language: python
diff --git a/lib/spack/docs/getting_started.rst b/lib/spack/docs/getting_started.rst
index b7ba386bb29538fea4cf2d936f323a454c699573..7f3a34b62b21b18660fcf9d576d38e8a22bd3558 100644
--- a/lib/spack/docs/getting_started.rst
+++ b/lib/spack/docs/getting_started.rst
@@ -16,7 +16,7 @@ Prerequisites
 Spack has the following minimum requirements, which must be installed
 before Spack is run:
 
-#. Python 2 (2.6 or 2.7) or 3 (3.4 - 3.7) to run Spack
+#. Python 2 (2.6 or 2.7) or 3 (3.5 - 3.8) to run Spack
 #. A C/C++ compiler for building
 #. The ``make`` executable for building
 #. The ``git`` and ``curl`` commands for fetching
diff --git a/lib/spack/spack/cmd/flake8.py b/lib/spack/spack/cmd/flake8.py
index 61f7dd567f1abb4534bff31efaa15fcb32d0c525..cc5b168c4b433a05fa49fb23870d0a6c5d451a44 100644
--- a/lib/spack/spack/cmd/flake8.py
+++ b/lib/spack/spack/cmd/flake8.py
@@ -178,6 +178,12 @@ def add_pattern_exemptions(line, codes):
 
 def filter_file(source, dest, output=False):
     """Filter a single file through all the patterns in pattern_exemptions."""
+
+    # Prior to Python 3.8, `noqa: F811` needed to be placed on the `@when` line
+    # Starting with Python 3.8, it must be placed on the `def` line
+    # https://gitlab.com/pycqa/flake8/issues/583
+    ignore_f811_on_previous_line = False
+
     with open(source) as infile:
         parent = os.path.dirname(dest)
         mkdirp(parent)
@@ -197,6 +203,12 @@ def filter_file(source, dest, output=False):
                                 line_errors.append(code)
                                 break
 
+                if 'F811' in line_errors:
+                    ignore_f811_on_previous_line = True
+                elif ignore_f811_on_previous_line:
+                    line_errors.append('F811')
+                    ignore_f811_on_previous_line = False
+
                 if line_errors:
                     line = add_pattern_exemptions(line, line_errors)
 
diff --git a/lib/spack/spack/cmd/list.py b/lib/spack/spack/cmd/list.py
index 570dcc7e27ed79daf50a7c4e4645b739085ac2db..fe6983ce74e7639f9af514ed4ce7bcf5a6843eb0 100644
--- a/lib/spack/spack/cmd/list.py
+++ b/lib/spack/spack/cmd/list.py
@@ -7,7 +7,6 @@
 from __future__ import division
 
 import argparse
-import cgi
 import fnmatch
 import os
 import re
@@ -23,6 +22,11 @@
 import spack.cmd.common.arguments as arguments
 from spack.version import VersionList
 
+if sys.version_info > (3, 1):
+    from html import escape
+else:
+    from cgi import escape
+
 description = "list and search available packages"
 section = "basic"
 level = "short"
@@ -217,7 +221,7 @@ def head(n, span_id, title, anchor=None):
         out.write('<dd><ul class="first last simple">\n')
         out.write(('<li>'
                    '<a class="reference external" href="%s">%s</a>'
-                   '</li>\n') % (pkg.homepage, cgi.escape(pkg.homepage)))
+                   '</li>\n') % (pkg.homepage, escape(pkg.homepage, True)))
         out.write('</ul></dd>\n')
 
         out.write('<dt>Spack package:</dt>\n')
@@ -249,7 +253,7 @@ def head(n, span_id, title, anchor=None):
 
         out.write('<dt>Description:</dt>\n')
         out.write('<dd>\n')
-        out.write(cgi.escape(pkg.format_doc(indent=2)))
+        out.write(escape(pkg.format_doc(indent=2), True))
         out.write('\n')
         out.write('</dd>\n')
         out.write('</dl>\n')