From 50d7b335634d4cece65c819551e5370ec7cc126d Mon Sep 17 00:00:00 2001
From: Massimiliano Culpo <massimiliano.culpo@googlemail.com>
Date: Thu, 20 Apr 2017 10:18:52 +0200
Subject: [PATCH] test/python_version.py: ported to pytest (#3438)

---
 lib/spack/spack/test/python_version.py | 164 +++++++++++++------------
 1 file changed, 85 insertions(+), 79 deletions(-)

diff --git a/lib/spack/spack/test/python_version.py b/lib/spack/spack/test/python_version.py
index ee0ff9d2c9..d58df1a0aa 100644
--- a/lib/spack/spack/test/python_version.py
+++ b/lib/spack/spack/test/python_version.py
@@ -36,7 +36,6 @@
 import os
 import sys
 import re
-import unittest
 
 import llnl.util.tty as tty
 import spack
@@ -65,83 +64,90 @@
         os.path.join(spack.lib_path, 'external', 'pyqver2.py')]
 
 
-class PythonVersionTest(unittest.TestCase):
-
-    def pyfiles(self, search_paths, exclude=()):
-        """List python search files in a set of search paths, excluding
-        any paths in the exclude list"""
-        # first file is the spack script.
-        yield spack.spack_file
-
-        # Iterate through the whole spack source tree.
-        for path in search_paths:
-            for root, dirnames, filenames in os.walk(path):
-                for filename in filenames:
-                    realpath = os.path.realpath(os.path.join(root, filename))
-                    if any(realpath.startswith(p) for p in exclude):
-                        continue
-
-                    if re.match(r'^[^.#].*\.py$', filename):
-                        yield os.path.join(root, filename)
-
-    def check_python_versions(self, files):
-        # This is a dict dict mapping:
-        #   version -> filename -> reasons
-        #
-        # Reasons are tuples of (lineno, string), where the string is the
-        # cause for a version incompatibility.
-        all_issues = {}
-
-        # Parse files and run pyqver on each file.
-        for path in files:
-            with open(path) as pyfile:
-                full_text = pyfile.read()
-            versions = pyqver.get_versions(full_text, path)
-
-            for ver, reasons in versions.items():
-                if ver <= spack_min_supported:
+def pyfiles(search_paths, exclude=()):
+    """Generator that yields all the python files in the search paths.
+
+    :param search_paths: list of paths to search for python files
+    :param exclude: file paths to exclude from search
+    :return: python files
+    """
+    # first file is the spack script.
+    yield spack.spack_file
+
+    # Iterate through the whole spack source tree.
+    for path in search_paths:
+        for root, dirnames, filenames in os.walk(path):
+            for filename in filenames:
+                realpath = os.path.realpath(os.path.join(root, filename))
+                if any(realpath.startswith(p) for p in exclude):
                     continue
 
-                # Record issues. Mark exceptions with '# nopyqver' comment
-                for lineno, cause in reasons:
-                    lines = full_text.split('\n')
-                    if not re.search(r'#\s*nopyqver\s*$', lines[lineno - 1]):
-                        all_issues.setdefault(ver, {})[path] = reasons
-
-        # Print a message if there are are issues
-        if all_issues:
-            tty.msg("Spack must remain compatible with Python version %d.%d"
-                    % spack_min_supported)
-
-        # Print out a table showing which files/linenos require which
-        # python version, and a string describing why.
-        for v in sorted(all_issues.keys(), reverse=True):
-            messages = []
-            for path in sorted(all_issues[v].keys()):
-                short_path = path
-                if path.startswith(spack.prefix):
-                    short_path = path[len(spack.prefix):]
-
-                reasons = [r for r in set(all_issues[v][path]) if r]
-                for lineno, cause in reasons:
-                    file_line = "%s:%s" % (short_path.lstrip('/'), lineno)
-                    messages.append((file_line, cause))
-
-            print()
-            tty.msg("These files require version %d.%d:" % v)
-            maxlen = max(len(f) for f, prob in messages)
-            fmt = "%%-%ds%%s" % (maxlen + 3)
-            print(fmt % ('File', 'Reason'))
-            print(fmt % ('-' * (maxlen), '-' * 20))
-            for msg in messages:
-                print(fmt % msg)
-
-        # Fail this test if there were issues.
-        self.assertTrue(len(all_issues) == 0)
-
-    def test_core_module_compatibility(self):
-        self.check_python_versions(
-            self.pyfiles([spack.lib_path], exclude=exclude_paths))
-
-    def test_package_module_compatibility(self):
-        self.check_python_versions(self.pyfiles([spack.packages_path]))
+                if re.match(r'^[^.#].*\.py$', filename):
+                    yield os.path.join(root, filename)
+
+
+def check_python_versions(files):
+    """Check that a set of Python files works with supported Ptyhon versions"""
+    # This is a dict dict mapping:
+    #   version -> filename -> reasons
+    #
+    # Reasons are tuples of (lineno, string), where the string is the
+    # cause for a version incompatibility.
+    all_issues = {}
+
+    # Parse files and run pyqver on each file.
+    for path in files:
+        with open(path) as pyfile:
+            full_text = pyfile.read()
+        versions = pyqver.get_versions(full_text, path)
+
+        for ver, reasons in versions.items():
+            if ver <= spack_min_supported:
+                continue
+
+            # Record issues. Mark exceptions with '# nopyqver' comment
+            for lineno, cause in reasons:
+                lines = full_text.split('\n')
+                if not re.search(r'#\s*nopyqver\s*$', lines[lineno - 1]):
+                    all_issues.setdefault(ver, {})[path] = reasons
+
+    # Print a message if there are are issues
+    if all_issues:
+        tty.msg("Spack must remain compatible with Python version %d.%d"
+                % spack_min_supported)
+
+    # Print out a table showing which files/linenos require which
+    # python version, and a string describing why.
+    for v in sorted(all_issues.keys(), reverse=True):
+        messages = []
+        for path in sorted(all_issues[v].keys()):
+            short_path = path
+            if path.startswith(spack.prefix):
+                short_path = path[len(spack.prefix):]
+
+            reasons = [r for r in set(all_issues[v][path]) if r]
+            for lineno, cause in reasons:
+                file_line = "%s:%s" % (short_path.lstrip('/'), lineno)
+                messages.append((file_line, cause))
+
+        print()
+        tty.msg("These files require version %d.%d:" % v)
+        maxlen = max(len(f) for f, prob in messages)
+        fmt = "%%-%ds%%s" % (maxlen + 3)
+        print(fmt % ('File', 'Reason'))
+        print(fmt % ('-' * (maxlen), '-' * 20))
+        for msg in messages:
+            print(fmt % msg)
+
+    # Fail this test if there were issues.
+    assert not all_issues
+
+
+def test_core_module_compatibility():
+    """Test that all core spack modules work with supported Python versions."""
+    check_python_versions(pyfiles([spack.lib_path], exclude=exclude_paths))
+
+
+def test_package_module_compatibility():
+    """Test that all spack packages work with supported Python versions."""
+    check_python_versions(pyfiles([spack.packages_path]))
-- 
GitLab