diff --git a/test/sanity/import/importer.py b/test/sanity/import/importer.py index fbcd570c2ef..e594759d16e 100755 --- a/test/sanity/import/importer.py +++ b/test/sanity/import/importer.py @@ -4,12 +4,18 @@ from __future__ import absolute_import, print_function import contextlib -import imp import os import re import sys import traceback +try: + import importlib.util + imp = None +except ImportError: + importlib = None + import imp + try: from StringIO import StringIO except ImportError: @@ -76,10 +82,18 @@ def test_python_module(path, base_dir, messages, ansible_module): filter_dir = base_dir capture = Capture() + try: - with open(path, 'r') as module_fd: + if imp: + with open(path, 'r') as module_fd: + with capture_output(capture): + imp.load_module(name, module_fd, os.path.abspath(path), ('.py', 'r', imp.PY_SOURCE)) + else: + spec = importlib.util.spec_from_file_location(name, os.path.abspath(path)) + module = importlib.util.module_from_spec(spec) + with capture_output(capture): - imp.load_module(name, module_fd, os.path.abspath(path), ('.py', 'r', imp.PY_SOURCE)) + spec.loader.exec_module(module) capture_report(path, capture, messages) except ImporterAnsibleModuleException: @@ -95,29 +109,29 @@ def test_python_module(path, base_dir, messages, ansible_module): line = 0 offset = 0 - for result in results: - if result[0].startswith(filter_dir): - source = result[0][len(base_dir) + 1:].replace('test/sanity/import/', '') - line = result[1] or 0 - break - - if not source: - # If none of our source files are found in the traceback, report the file we were testing. - # I haven't been able to come up with a test case that encounters this issue yet. + if isinstance(ex, SyntaxError) and ex.filename.endswith(path): # pylint: disable=locally-disabled, no-member + # A SyntaxError in the source we're importing will have the correct path, line and offset. + # However, the traceback will report the path to this importer.py script instead. + # We'll use the details from the SyntaxError in this case, as it's more accurate. source = path - message += ' (in %s:%d)' % (results[-1][0], results[-1][1] or 0) - elif isinstance(ex, SyntaxError): - if ex.filename.endswith(path): # pylint: disable=locally-disabled, no-member - # A SyntaxError in the source we're importing will have the correct path, line and offset. - # However, the traceback will report the path to this importer.py script instead. - # We'll use the details from the SyntaxError in this case, as it's more accurate. + line = ex.lineno or 0 # pylint: disable=locally-disabled, no-member + offset = ex.offset or 0 # pylint: disable=locally-disabled, no-member + message = str(ex) + + # Hack to remove the filename and line number from the message, if present. + message = message.replace(' (%s, line %d)' % (os.path.basename(path), line), '') + else: + for result in results: + if result[0].startswith(filter_dir): + source = result[0][len(base_dir) + 1:].replace('test/sanity/import/', '') + line = result[1] or 0 + break + + if not source: + # If none of our source files are found in the traceback, report the file we were testing. + # I haven't been able to come up with a test case that encounters this issue yet. source = path - line = ex.lineno or 0 # pylint: disable=locally-disabled, no-member - offset = ex.offset or 0 # pylint: disable=locally-disabled, no-member - message = str(ex) - - # Hack to remove the filename and line number from the message, if present. - message = message.replace(' (%s, line %d)' % (os.path.basename(path), line), '') + message += ' (in %s:%d)' % (results[-1][0], results[-1][1] or 0) message = re.sub(r'\n *', ': ', message) error = '%s:%d:%d: %s: %s' % (source, line, offset, exc_type.__name__, message)