Browse code

Fixes for ansible-test sanity import test. (#45249)

* Fix import test on Python 3.7.
* Fix path processing in import sanity test.

(cherry picked from commit 6fb333faff457591349cbbf3736339967493b991)

Matt Clay authored on 2018/09/06 05:54:50
Showing 1 changed files
... ...
@@ -4,13 +4,19 @@
4 4
 from __future__ import absolute_import, print_function
5 5
 
6 6
 import contextlib
7
-import imp
8 7
 import os
9 8
 import re
10 9
 import sys
11 10
 import traceback
12 11
 
13 12
 try:
13
+    import importlib.util
14
+    imp = None
15
+except ImportError:
16
+    importlib = None
17
+    import imp
18
+
19
+try:
14 20
     from StringIO import StringIO
15 21
 except ImportError:
16 22
     from io import StringIO
... ...
@@ -76,10 +82,18 @@ def test_python_module(path, base_dir, messages, ansible_module):
76 76
         filter_dir = base_dir
77 77
 
78 78
     capture = Capture()
79
+
79 80
     try:
80
-        with open(path, 'r') as module_fd:
81
+        if imp:
82
+            with open(path, 'r') as module_fd:
83
+                with capture_output(capture):
84
+                    imp.load_module(name, module_fd, os.path.abspath(path), ('.py', 'r', imp.PY_SOURCE))
85
+        else:
86
+            spec = importlib.util.spec_from_file_location(name, os.path.abspath(path))
87
+            module = importlib.util.module_from_spec(spec)
88
+
81 89
             with capture_output(capture):
82
-                imp.load_module(name, module_fd, os.path.abspath(path), ('.py', 'r', imp.PY_SOURCE))
90
+                spec.loader.exec_module(module)
83 91
 
84 92
         capture_report(path, capture, messages)
85 93
     except ImporterAnsibleModuleException:
... ...
@@ -95,29 +109,29 @@ def test_python_module(path, base_dir, messages, ansible_module):
95 95
         line = 0
96 96
         offset = 0
97 97
 
98
-        for result in results:
99
-            if result[0].startswith(filter_dir):
100
-                source = result[0][len(base_dir) + 1:].replace('test/sanity/import/', '')
101
-                line = result[1] or 0
102
-                break
103
-
104
-        if not source:
105
-            # If none of our source files are found in the traceback, report the file we were testing.
106
-            # I haven't been able to come up with a test case that encounters this issue yet.
98
+        if isinstance(ex, SyntaxError) and ex.filename.endswith(path):  # pylint: disable=locally-disabled, no-member
99
+            # A SyntaxError in the source we're importing will have the correct path, line and offset.
100
+            # However, the traceback will report the path to this importer.py script instead.
101
+            # We'll use the details from the SyntaxError in this case, as it's more accurate.
107 102
             source = path
108
-            message += ' (in %s:%d)' % (results[-1][0], results[-1][1] or 0)
109
-        elif isinstance(ex, SyntaxError):
110
-            if ex.filename.endswith(path):  # pylint: disable=locally-disabled, no-member
111
-                # A SyntaxError in the source we're importing will have the correct path, line and offset.
112
-                # However, the traceback will report the path to this importer.py script instead.
113
-                # We'll use the details from the SyntaxError in this case, as it's more accurate.
103
+            line = ex.lineno or 0  # pylint: disable=locally-disabled, no-member
104
+            offset = ex.offset or 0  # pylint: disable=locally-disabled, no-member
105
+            message = str(ex)
106
+
107
+            # Hack to remove the filename and line number from the message, if present.
108
+            message = message.replace(' (%s, line %d)' % (os.path.basename(path), line), '')
109
+        else:
110
+            for result in results:
111
+                if result[0].startswith(filter_dir):
112
+                    source = result[0][len(base_dir) + 1:].replace('test/sanity/import/', '')
113
+                    line = result[1] or 0
114
+                    break
115
+
116
+            if not source:
117
+                # If none of our source files are found in the traceback, report the file we were testing.
118
+                # I haven't been able to come up with a test case that encounters this issue yet.
114 119
                 source = path
115
-                line = ex.lineno or 0  # pylint: disable=locally-disabled, no-member
116
-                offset = ex.offset or 0  # pylint: disable=locally-disabled, no-member
117
-                message = str(ex)
118
-
119
-                # Hack to remove the filename and line number from the message, if present.
120
-                message = message.replace(' (%s, line %d)' % (os.path.basename(path), line), '')
120
+                message += ' (in %s:%d)' % (results[-1][0], results[-1][1] or 0)
121 121
 
122 122
         message = re.sub(r'\n *', ': ', message)
123 123
         error = '%s:%d:%d: %s: %s' % (source, line, offset, exc_type.__name__, message)