From 338a532e07357c93fe9972dcca60e197f94ec20b Mon Sep 17 00:00:00 2001
From: "Adam J. Stewart" <ajstewart426@gmail.com>
Date: Thu, 31 Oct 2019 14:20:46 -0500
Subject: [PATCH] Travis CI: Test Python 3.8 (#13347)

* Travis CI: Test Python 3.8

* Fix use of deprecated cgi.escape method

* Fix version comparison

* Fix flake8 F811 change in Python 3.8

* Make flake8 happy

* Use Python 3.8 for all test categories
---
 .travis.yml                        | 26 +++++++++++++++-----------
 lib/spack/docs/getting_started.rst |  2 +-
 lib/spack/spack/cmd/flake8.py      | 12 ++++++++++++
 lib/spack/spack/cmd/list.py        | 10 +++++++---
 4 files changed, 35 insertions(+), 15 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index a79a5126b1..f8f0778cae 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 b7ba386bb2..7f3a34b62b 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 61f7dd567f..cc5b168c4b 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 570dcc7e27..fe6983ce74 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')
-- 
GitLab