From b94ee1cefd69bab87f13ec01e939a9a90285893b Mon Sep 17 00:00:00 2001 From: Matt Clay Date: Tue, 3 Oct 2023 14:52:38 -0700 Subject: [PATCH] Drop Python 2.7 and Python 3.6 support (#81866) * Drop Python 2.7 and Python 3.6 support * Remove obsolete _json_compat --- .azure-pipelines/azure-pipelines.yml | 16 ---- lib/ansible/config/base.yml | 2 - lib/ansible/module_utils/basic.py | 26 +++---- .../module_utils/common/_json_compat.py | 16 ---- lib/ansible/module_utils/common/validation.py | 2 +- .../ansible_test/_data/completion/docker.txt | 8 +- .../ansible_test/_data/completion/remote.txt | 2 - .../_internal/commands/sanity/__init__.py | 26 +------ .../_internal/python_requirements.py | 12 +-- .../code-smell/future-import-boilerplate.json | 7 -- .../code-smell/future-import-boilerplate.py | 46 ------------ .../code-smell/metaclass-boilerplate.json | 7 -- .../code-smell/metaclass-boilerplate.py | 44 ----------- .../_util/target/cli/ansible_test_cli_stub.py | 3 +- .../_util/target/common/constants.py | 5 +- .../_util/target/injector/python.py | 3 +- .../target/pytest/plugins/ansible_forked.py | 4 +- .../plugins/ansible_pytest_collections.py | 3 +- .../pytest/plugins/ansible_pytest_coverage.py | 3 +- .../_util/target/sanity/compile/compile.py | 3 +- .../_util/target/sanity/import/importer.py | 3 +- .../_util/target/setup/bootstrap.sh | 75 ------------------- .../_util/target/setup/probe_cgroups.py | 3 +- .../_util/target/setup/quiet_pip.py | 3 +- .../_util/target/setup/requirements.py | 3 +- .../_util/target/tools/virtualenvcheck.py | 3 +- .../_util/target/tools/yamlcheck.py | 3 +- .../ansible-test-future-boilerplate.py | 8 -- test/sanity/ignore.txt | 9 --- .../module_common/test_recursive_finder.py | 1 - test/units/module_utils/basic/test_imports.py | 14 ---- 31 files changed, 28 insertions(+), 335 deletions(-) delete mode 100644 lib/ansible/module_utils/common/_json_compat.py delete mode 100644 test/lib/ansible_test/_util/controller/sanity/code-smell/future-import-boilerplate.json delete mode 100644 test/lib/ansible_test/_util/controller/sanity/code-smell/future-import-boilerplate.py delete mode 100644 test/lib/ansible_test/_util/controller/sanity/code-smell/metaclass-boilerplate.json delete mode 100644 test/lib/ansible_test/_util/controller/sanity/code-smell/metaclass-boilerplate.py diff --git a/.azure-pipelines/azure-pipelines.yml b/.azure-pipelines/azure-pipelines.yml index e2d4f74c726..3390c34feb8 100644 --- a/.azure-pipelines/azure-pipelines.yml +++ b/.azure-pipelines/azure-pipelines.yml @@ -54,8 +54,6 @@ stages: nameFormat: Python {0} testFormat: units/{0} targets: - - test: 2.7 - - test: 3.6 - test: 3.7 - test: 3.8 - test: 3.9 @@ -81,12 +79,6 @@ stages: targets: - name: macOS 13.2 test: macos/13.2 - - name: RHEL 7.9 - test: rhel/7.9 - - name: RHEL 8.8 py36 - test: rhel/8.8@3.6 - - name: RHEL 8.8 py311 - test: rhel/8.8@3.11 - name: RHEL 9.2 py39 test: rhel/9.2@3.9 - name: RHEL 9.2 py311 @@ -101,8 +93,6 @@ stages: targets: - name: macOS 13.2 test: macos/13.2 - - name: RHEL 8.8 - test: rhel/8.8 - name: RHEL 9.2 test: rhel/9.2 - name: FreeBSD 13.2 @@ -118,8 +108,6 @@ stages: test: alpine/3.18 - name: Fedora 38 test: fedora/38 - - name: RHEL 8.8 - test: rhel/8.8 - name: RHEL 9.2 test: rhel/9.2 - name: Ubuntu 22.04 @@ -135,12 +123,8 @@ stages: targets: - name: Alpine 3 test: alpine3 - - name: CentOS 7 - test: centos7 - name: Fedora 38 test: fedora38 - - name: openSUSE 15 - test: opensuse15 - name: Ubuntu 20.04 test: ubuntu2004 - name: Ubuntu 22.04 diff --git a/lib/ansible/config/base.yml b/lib/ansible/config/base.yml index 255a1f861f2..057f66430cc 100644 --- a/lib/ansible/config/base.yml +++ b/lib/ansible/config/base.yml @@ -1563,10 +1563,8 @@ INTERPRETER_PYTHON_FALLBACK: - python3.9 - python3.8 - python3.7 - - python3.6 - /usr/bin/python3 - /usr/libexec/platform-python - - python2.7 - /usr/bin/python - python vars: diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py index 842d95f129f..d17704d31bd 100644 --- a/lib/ansible/module_utils/basic.py +++ b/lib/ansible/module_utils/basic.py @@ -2,22 +2,20 @@ # Copyright (c), Toshio Kuratomi 2016 # Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause) -from __future__ import absolute_import, division, print_function -__metaclass__ = type +from __future__ import annotations +import json import sys # Used for determining if the system is running a new enough python version # and should only restrict on our documented minimum versions -_PY3_MIN = sys.version_info >= (3, 6) -_PY2_MIN = (2, 7) <= sys.version_info < (3,) -_PY_MIN = _PY3_MIN or _PY2_MIN - -if not _PY_MIN: - print( - '\n{"failed": true, ' - '"msg": "ansible-core requires a minimum of Python2 version 2.7 or Python3 version 3.6. Current version: %s"}' % ''.join(sys.version.splitlines()) - ) +_PY_MIN = (3, 7) + +if sys.version_info < _PY_MIN: + print(json.dumps(dict( + failed=True, + msg=f"ansible-core requires a minimum of Python version {'.'.join(map(str, _PY_MIN))}. Current version: {''.join(sys.version.splitlines())}", + ))) sys.exit(1) # Ansible modules can be written in any language. @@ -128,12 +126,6 @@ def _get_available_hash_algorithms(): AVAILABLE_HASH_ALGORITHMS = _get_available_hash_algorithms() -try: - from ansible.module_utils.common._json_compat import json -except ImportError as e: - print('\n{{"msg": "Error: ansible requires the stdlib json: {0}", "failed": true}}'.format(to_native(e))) - sys.exit(1) - from ansible.module_utils.six.moves.collections_abc import ( KeysView, Mapping, MutableMapping, diff --git a/lib/ansible/module_utils/common/_json_compat.py b/lib/ansible/module_utils/common/_json_compat.py deleted file mode 100644 index 787af0ff1ab..00000000000 --- a/lib/ansible/module_utils/common/_json_compat.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2019 Ansible Project -# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause) - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - -import types -import json - -# Detect the python-json library which is incompatible -try: - if not isinstance(json.loads, types.FunctionType) or not isinstance(json.dumps, types.FunctionType): - raise ImportError('json.loads or json.dumps were not found in the imported json library.') -except AttributeError: - raise ImportError('python-json was detected, which is incompatible.') diff --git a/lib/ansible/module_utils/common/validation.py b/lib/ansible/module_utils/common/validation.py index cc5478999c7..2389c0463df 100644 --- a/lib/ansible/module_utils/common/validation.py +++ b/lib/ansible/module_utils/common/validation.py @@ -5,12 +5,12 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type +import json import os import re from ast import literal_eval from ansible.module_utils.common.text.converters import to_native -from ansible.module_utils.common._json_compat import json from ansible.module_utils.common.collections import is_iterable from ansible.module_utils.common.text.converters import jsonify from ansible.module_utils.common.text.formatters import human_to_bytes diff --git a/test/lib/ansible_test/_data/completion/docker.txt b/test/lib/ansible_test/_data/completion/docker.txt index 60e12fe1819..38dd5ed987f 100644 --- a/test/lib/ansible_test/_data/completion/docker.txt +++ b/test/lib/ansible_test/_data/completion/docker.txt @@ -1,9 +1,7 @@ -base image=quay.io/ansible/base-test-container:5.9.0 python=3.11,2.7,3.6,3.7,3.8,3.9,3.10,3.12 -default image=quay.io/ansible/default-test-container:9.2.0 python=3.11,2.7,3.6,3.7,3.8,3.9,3.10,3.12 context=collection -default image=quay.io/ansible/ansible-core-test-container:9.2.0 python=3.11,2.7,3.6,3.7,3.8,3.9,3.10,3.12 context=ansible-core +base image=quay.io/ansible/base-test-container:5.9.0 python=3.11,3.7,3.8,3.9,3.10,3.12 +default image=quay.io/ansible/default-test-container:9.2.0 python=3.11,3.7,3.8,3.9,3.10,3.12 context=collection +default image=quay.io/ansible/ansible-core-test-container:9.2.0 python=3.11,3.7,3.8,3.9,3.10,3.12 context=ansible-core alpine3 image=quay.io/ansible/alpine3-test-container:6.3.0 python=3.11 cgroup=none audit=none -centos7 image=quay.io/ansible/centos7-test-container:6.3.0 python=2.7 cgroup=v1-only fedora38 image=quay.io/ansible/fedora38-test-container:6.3.0 python=3.11 -opensuse15 image=quay.io/ansible/opensuse15-test-container:6.3.0 python=3.6 ubuntu2004 image=quay.io/ansible/ubuntu2004-test-container:6.3.0 python=3.8 ubuntu2204 image=quay.io/ansible/ubuntu2204-test-container:6.3.0 python=3.10 diff --git a/test/lib/ansible_test/_data/completion/remote.txt b/test/lib/ansible_test/_data/completion/remote.txt index 06d4b5ef365..d30f5ebb64e 100644 --- a/test/lib/ansible_test/_data/completion/remote.txt +++ b/test/lib/ansible_test/_data/completion/remote.txt @@ -6,8 +6,6 @@ freebsd/13.2 python=3.9,3.11 python_dir=/usr/local/bin become=su_sudo provider=a freebsd python_dir=/usr/local/bin become=su_sudo provider=aws arch=x86_64 macos/13.2 python=3.11 python_dir=/usr/local/bin become=sudo provider=parallels arch=x86_64 macos python_dir=/usr/local/bin become=sudo provider=parallels arch=x86_64 -rhel/7.9 python=2.7 become=sudo provider=aws arch=x86_64 -rhel/8.8 python=3.6,3.11 become=sudo provider=aws arch=x86_64 rhel/9.2 python=3.9,3.11 become=sudo provider=aws arch=x86_64 rhel become=sudo provider=aws arch=x86_64 ubuntu/22.04 python=3.10 become=sudo provider=aws arch=x86_64 diff --git a/test/lib/ansible_test/_internal/commands/sanity/__init__.py b/test/lib/ansible_test/_internal/commands/sanity/__init__.py index 9b675e4a61b..1959d99bde9 100644 --- a/test/lib/ansible_test/_internal/commands/sanity/__init__.py +++ b/test/lib/ansible_test/_internal/commands/sanity/__init__.py @@ -764,11 +764,6 @@ class SanityTest(metaclass=abc.ABCMeta): """True if the test targets should include symlinks.""" return False - @property - def py2_compat(self) -> bool: - """True if the test only applies to code that runs on Python 2.x.""" - return False - @property def supported_python_versions(self) -> t.Optional[tuple[str, ...]]: """A tuple of supported Python versions or None if the test does not depend on specific Python versions.""" @@ -786,23 +781,11 @@ class SanityTest(metaclass=abc.ABCMeta): def filter_targets_by_version(self, args: SanityConfig, targets: list[TestTarget], python_version: str) -> list[TestTarget]: """Return the given list of test targets, filtered to include only those relevant for the test, taking into account the Python version.""" + del args # args is not used here, but derived classes may make use of it del python_version # python_version is not used here, but derived classes may make use of it targets = self.filter_targets(targets) - if self.py2_compat: - # This sanity test is a Python 2.x compatibility test. - content_config = get_content_config(args) - - if content_config.py2_support: - # This collection supports Python 2.x. - # Filter targets to include only those that require support for remote-only Python versions. - targets = self.filter_remote_targets(targets) - else: - # This collection does not support Python 2.x. - # There are no targets to test. - targets = [] - return targets @staticmethod @@ -878,7 +861,6 @@ class SanityCodeSmellTest(SanitySingleVersion): self.__no_targets: bool = self.config.get('no_targets') self.__include_directories: bool = self.config.get('include_directories') self.__include_symlinks: bool = self.config.get('include_symlinks') - self.__py2_compat: bool = self.config.get('py2_compat', False) self.__error_code: str | None = self.config.get('error_code', None) else: self.output = None @@ -894,7 +876,6 @@ class SanityCodeSmellTest(SanitySingleVersion): self.__no_targets = True self.__include_directories = False self.__include_symlinks = False - self.__py2_compat = False self.__error_code = None if self.no_targets: @@ -939,11 +920,6 @@ class SanityCodeSmellTest(SanitySingleVersion): """True if the test targets should include symlinks.""" return self.__include_symlinks - @property - def py2_compat(self) -> bool: - """True if the test only applies to code that runs on Python 2.x.""" - return self.__py2_compat - @property def supported_python_versions(self) -> t.Optional[tuple[str, ...]]: """A tuple of supported Python versions or None if the test does not depend on specific Python versions.""" diff --git a/test/lib/ansible_test/_internal/python_requirements.py b/test/lib/ansible_test/_internal/python_requirements.py index 81006e419ae..01fe7d7447a 100644 --- a/test/lib/ansible_test/_internal/python_requirements.py +++ b/test/lib/ansible_test/_internal/python_requirements.py @@ -446,17 +446,7 @@ def get_venv_packages(python: PythonConfig) -> dict[str, str]: wheel='0.37.1', ) - override_packages = { - '2.7': dict( - pip='20.3.4', # 21.0 requires Python 3.6+ - setuptools='44.1.1', # 45.0.0 requires Python 3.5+ - wheel=None, - ), - '3.6': dict( - pip='21.3.1', # 22.0 requires Python 3.7+ - setuptools='59.6.0', # 59.7.0 requires Python 3.7+ - wheel=None, - ), + override_packages: dict[str, dict[str, str]] = { } packages = {name: version or default_packages[name] for name, version in override_packages.get(python.version, default_packages).items()} diff --git a/test/lib/ansible_test/_util/controller/sanity/code-smell/future-import-boilerplate.json b/test/lib/ansible_test/_util/controller/sanity/code-smell/future-import-boilerplate.json deleted file mode 100644 index 4ebce32c8ce..00000000000 --- a/test/lib/ansible_test/_util/controller/sanity/code-smell/future-import-boilerplate.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extensions": [ - ".py" - ], - "py2_compat": true, - "output": "path-message" -} diff --git a/test/lib/ansible_test/_util/controller/sanity/code-smell/future-import-boilerplate.py b/test/lib/ansible_test/_util/controller/sanity/code-smell/future-import-boilerplate.py deleted file mode 100644 index 7b39c370f90..00000000000 --- a/test/lib/ansible_test/_util/controller/sanity/code-smell/future-import-boilerplate.py +++ /dev/null @@ -1,46 +0,0 @@ -"""Enforce proper usage of __future__ imports.""" -from __future__ import annotations - -import ast -import sys - - -def main(): - """Main entry point.""" - for path in sys.argv[1:] or sys.stdin.read().splitlines(): - with open(path, 'rb') as path_fd: - lines = path_fd.read().splitlines() - - missing = True - if not lines: - # Files are allowed to be empty of everything including boilerplate - missing = False - - for text in lines: - if text in (b'from __future__ import (absolute_import, division, print_function)', - b'from __future__ import absolute_import, division, print_function'): - missing = False - break - - if missing: - with open(path, encoding='utf-8') as file: - contents = file.read() - - # noinspection PyBroadException - try: - node = ast.parse(contents) - - # files consisting of only assignments have no need for future import boilerplate - # the only exception would be division during assignment, but we'll overlook that for simplicity - # the most likely case is that of a documentation only python file - if all(isinstance(statement, ast.Assign) for statement in node.body): - missing = False - except Exception: # pylint: disable=broad-except - pass # the compile sanity test will report this error - - if missing: - print('%s: missing: from __future__ import (absolute_import, division, print_function)' % path) - - -if __name__ == '__main__': - main() diff --git a/test/lib/ansible_test/_util/controller/sanity/code-smell/metaclass-boilerplate.json b/test/lib/ansible_test/_util/controller/sanity/code-smell/metaclass-boilerplate.json deleted file mode 100644 index 4ebce32c8ce..00000000000 --- a/test/lib/ansible_test/_util/controller/sanity/code-smell/metaclass-boilerplate.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extensions": [ - ".py" - ], - "py2_compat": true, - "output": "path-message" -} diff --git a/test/lib/ansible_test/_util/controller/sanity/code-smell/metaclass-boilerplate.py b/test/lib/ansible_test/_util/controller/sanity/code-smell/metaclass-boilerplate.py deleted file mode 100644 index 8bdcfc9a94a..00000000000 --- a/test/lib/ansible_test/_util/controller/sanity/code-smell/metaclass-boilerplate.py +++ /dev/null @@ -1,44 +0,0 @@ -"""Require __metaclass__ boilerplate for code that supports Python 2.x.""" -from __future__ import annotations - -import ast -import sys - - -def main(): - """Main entry point.""" - for path in sys.argv[1:] or sys.stdin.read().splitlines(): - with open(path, 'rb') as path_fd: - lines = path_fd.read().splitlines() - - missing = True - if not lines: - # Files are allowed to be empty of everything including boilerplate - missing = False - - for text in lines: - if text == b'__metaclass__ = type': - missing = False - break - - if missing: - with open(path, encoding='utf-8') as file: - contents = file.read() - - # noinspection PyBroadException - try: - node = ast.parse(contents) - - # files consisting of only assignments have no need for metaclass boilerplate - # the most likely case is that of a documentation only python file - if all(isinstance(statement, ast.Assign) for statement in node.body): - missing = False - except Exception: # pylint: disable=broad-except - pass # the compile sanity test will report this error - - if missing: - print('%s: missing: __metaclass__ = type' % path) - - -if __name__ == '__main__': - main() diff --git a/test/lib/ansible_test/_util/target/cli/ansible_test_cli_stub.py b/test/lib/ansible_test/_util/target/cli/ansible_test_cli_stub.py index 930654fc1e7..9cb5d04ae0c 100755 --- a/test/lib/ansible_test/_util/target/cli/ansible_test_cli_stub.py +++ b/test/lib/ansible_test/_util/target/cli/ansible_test_cli_stub.py @@ -4,8 +4,7 @@ # NOTE: This file resides in the _util/target directory to ensure compatibility with all supported Python versions. -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import os import sys diff --git a/test/lib/ansible_test/_util/target/common/constants.py b/test/lib/ansible_test/_util/target/common/constants.py index 36a5a2c4342..fdad9f28a00 100644 --- a/test/lib/ansible_test/_util/target/common/constants.py +++ b/test/lib/ansible_test/_util/target/common/constants.py @@ -2,12 +2,9 @@ # NOTE: This file resides in the _util/target directory to ensure compatibility with all supported Python versions. -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations REMOTE_ONLY_PYTHON_VERSIONS = ( - '2.7', - '3.6', '3.7', '3.8', '3.9', diff --git a/test/lib/ansible_test/_util/target/injector/python.py b/test/lib/ansible_test/_util/target/injector/python.py index c1e88a9212c..eef61da514e 100644 --- a/test/lib/ansible_test/_util/target/injector/python.py +++ b/test/lib/ansible_test/_util/target/injector/python.py @@ -1,7 +1,6 @@ # auto-shebang """Provides an entry point for python scripts and python modules on the controller with the current python interpreter and optional code coverage collection.""" -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import os import sys diff --git a/test/lib/ansible_test/_util/target/pytest/plugins/ansible_forked.py b/test/lib/ansible_test/_util/target/pytest/plugins/ansible_forked.py index d00d9e93d1b..c9c5c96ad1a 100644 --- a/test/lib/ansible_test/_util/target/pytest/plugins/ansible_forked.py +++ b/test/lib/ansible_test/_util/target/pytest/plugins/ansible_forked.py @@ -4,9 +4,7 @@ # https://github.com/pytest-dev/pytest-forked # https://github.com/pytest-dev/py # TIP: Disable pytest-xdist when debugging internal errors in this plugin. -from __future__ import absolute_import, division, print_function - -__metaclass__ = type +from __future__ import annotations import os import pickle diff --git a/test/lib/ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py b/test/lib/ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py index 2f77c03bbbd..060a954b9b9 100644 --- a/test/lib/ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +++ b/test/lib/ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py @@ -1,6 +1,5 @@ """Enable unit testing of Ansible collections. PYTEST_DONT_REWRITE""" -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import os diff --git a/test/lib/ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py b/test/lib/ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py index b05298ab0b3..577a498e253 100644 --- a/test/lib/ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +++ b/test/lib/ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py @@ -1,6 +1,5 @@ """Monkey patch os._exit when running under coverage so we don't lose coverage data in forks, such as with `pytest --boxed`. PYTEST_DONT_REWRITE""" -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def pytest_configure(): diff --git a/test/lib/ansible_test/_util/target/sanity/compile/compile.py b/test/lib/ansible_test/_util/target/sanity/compile/compile.py index bd2446f6d8f..4e11f7cd7de 100644 --- a/test/lib/ansible_test/_util/target/sanity/compile/compile.py +++ b/test/lib/ansible_test/_util/target/sanity/compile/compile.py @@ -1,6 +1,5 @@ """Python syntax checker with lint friendly output.""" -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import sys diff --git a/test/lib/ansible_test/_util/target/sanity/import/importer.py b/test/lib/ansible_test/_util/target/sanity/import/importer.py index 7919fa0d7d1..4211bc4e604 100644 --- a/test/lib/ansible_test/_util/target/sanity/import/importer.py +++ b/test/lib/ansible_test/_util/target/sanity/import/importer.py @@ -1,6 +1,5 @@ """Import the given python module(s) and report error(s) encountered.""" -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations def main(): diff --git a/test/lib/ansible_test/_util/target/setup/bootstrap.sh b/test/lib/ansible_test/_util/target/setup/bootstrap.sh index ed9816dca23..f81c338369d 100644 --- a/test/lib/ansible_test/_util/target/setup/bootstrap.sh +++ b/test/lib/ansible_test/_util/target/setup/bootstrap.sh @@ -233,79 +233,6 @@ bootstrap_remote_macos() echo 'PATH="/usr/local/bin:$PATH"' > /etc/zshenv } -bootstrap_remote_rhel_7() -{ - packages=" - gcc - python-devel - python-virtualenv - " - - while true; do - # shellcheck disable=SC2086 - yum install -q -y ${packages} \ - && break - echo "Failed to install packages. Sleeping before trying again..." - sleep 10 - done - - install_pip - - bootstrap_remote_rhel_pinned_pip_packages -} - -bootstrap_remote_rhel_8() -{ - if [ "${python_version}" = "3.6" ]; then - py_pkg_prefix="python3" - else - py_pkg_prefix="python${python_version}" - fi - - packages=" - gcc - ${py_pkg_prefix}-devel - " - - # pip isn't included in the Python devel package under Python 3.11 - if [ "${python_version}" != "3.6" ]; then - packages=" - ${packages} - ${py_pkg_prefix}-pip - " - fi - - # Jinja2 is not installed with an OS package since the provided version is too old. - # Instead, ansible-test will install it using pip. - if [ "${controller}" ]; then - packages=" - ${packages} - ${py_pkg_prefix}-cryptography - " - fi - - # Python 3.11 isn't a module like the earlier versions - if [ "${python_version}" = "3.6" ]; then - while true; do - # shellcheck disable=SC2086 - yum module install -q -y "python${python_package_version}" \ - && break - echo "Failed to install packages. Sleeping before trying again..." - sleep 10 - done - fi - - while true; do - # shellcheck disable=SC2086 - yum install -q -y ${packages} \ - && break - echo "Failed to install packages. Sleeping before trying again..." - sleep 10 - done - - bootstrap_remote_rhel_pinned_pip_packages -} - bootstrap_remote_rhel_9() { if [ "${python_version}" = "3.9" ]; then @@ -351,8 +278,6 @@ bootstrap_remote_rhel_9() bootstrap_remote_rhel() { case "${platform_version}" in - 7.*) bootstrap_remote_rhel_7 ;; - 8.*) bootstrap_remote_rhel_8 ;; 9.*) bootstrap_remote_rhel_9 ;; esac } diff --git a/test/lib/ansible_test/_util/target/setup/probe_cgroups.py b/test/lib/ansible_test/_util/target/setup/probe_cgroups.py index 2ac7ecb0849..a09c0246eef 100644 --- a/test/lib/ansible_test/_util/target/setup/probe_cgroups.py +++ b/test/lib/ansible_test/_util/target/setup/probe_cgroups.py @@ -1,6 +1,5 @@ """A tool for probing cgroups to determine write access.""" -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json import os diff --git a/test/lib/ansible_test/_util/target/setup/quiet_pip.py b/test/lib/ansible_test/_util/target/setup/quiet_pip.py index 171ff8f3e24..42e5a19056e 100644 --- a/test/lib/ansible_test/_util/target/setup/quiet_pip.py +++ b/test/lib/ansible_test/_util/target/setup/quiet_pip.py @@ -1,6 +1,5 @@ """Custom entry-point for pip that filters out unwanted logging and warnings.""" -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import logging import os diff --git a/test/lib/ansible_test/_util/target/setup/requirements.py b/test/lib/ansible_test/_util/target/setup/requirements.py index b145fde5013..0bf52157d30 100644 --- a/test/lib/ansible_test/_util/target/setup/requirements.py +++ b/test/lib/ansible_test/_util/target/setup/requirements.py @@ -1,6 +1,5 @@ """A tool for installing test requirements on the controller and target host.""" -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations # pylint: disable=wrong-import-position diff --git a/test/lib/ansible_test/_util/target/tools/virtualenvcheck.py b/test/lib/ansible_test/_util/target/tools/virtualenvcheck.py index a38ad0747ec..49b308b5820 100644 --- a/test/lib/ansible_test/_util/target/tools/virtualenvcheck.py +++ b/test/lib/ansible_test/_util/target/tools/virtualenvcheck.py @@ -1,6 +1,5 @@ """Detect the real python interpreter when running in a virtual environment created by the 'virtualenv' module.""" -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/lib/ansible_test/_util/target/tools/yamlcheck.py b/test/lib/ansible_test/_util/target/tools/yamlcheck.py index dfd08e581ca..07dccca9edb 100644 --- a/test/lib/ansible_test/_util/target/tools/yamlcheck.py +++ b/test/lib/ansible_test/_util/target/tools/yamlcheck.py @@ -1,6 +1,5 @@ """Show availability of PyYAML and libyaml support.""" -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type +from __future__ import annotations import json diff --git a/test/sanity/code-smell/ansible-test-future-boilerplate.py b/test/sanity/code-smell/ansible-test-future-boilerplate.py index 9a6222519b1..74128ec7008 100644 --- a/test/sanity/code-smell/ansible-test-future-boilerplate.py +++ b/test/sanity/code-smell/ansible-test-future-boilerplate.py @@ -5,15 +5,7 @@ import sys def main(): - # The following directories contain code which must work under Python 2.x. - py2_compat = ( - 'test/lib/ansible_test/_util/target/', - ) - for path in sys.argv[1:] or sys.stdin.read().splitlines(): - if any(path.startswith(prefix) for prefix in py2_compat): - continue - with open(path, 'rb') as path_fd: lines = path_fd.read().splitlines() diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt index 079f1dfac7f..041962e0d3c 100644 --- a/test/sanity/ignore.txt +++ b/test/sanity/ignore.txt @@ -50,18 +50,12 @@ lib/ansible/modules/user.py validate-modules:doc-default-does-not-match-spec lib/ansible/modules/user.py validate-modules:use-run-command-not-popen lib/ansible/modules/yum.py validate-modules:parameter-invalid lib/ansible/module_utils/basic.py pylint:unused-import # deferring resolution to allow enabling the rule now -lib/ansible/module_utils/compat/_selectors2.py future-import-boilerplate # ignore bundled -lib/ansible/module_utils/compat/_selectors2.py metaclass-boilerplate # ignore bundled -lib/ansible/module_utils/compat/selinux.py import-2.7!skip # pass/fail depends on presence of libselinux.so -lib/ansible/module_utils/compat/selinux.py import-3.6!skip # pass/fail depends on presence of libselinux.so lib/ansible/module_utils/compat/selinux.py import-3.7!skip # pass/fail depends on presence of libselinux.so lib/ansible/module_utils/compat/selinux.py import-3.8!skip # pass/fail depends on presence of libselinux.so lib/ansible/module_utils/compat/selinux.py import-3.9!skip # pass/fail depends on presence of libselinux.so lib/ansible/module_utils/compat/selinux.py import-3.10!skip # pass/fail depends on presence of libselinux.so lib/ansible/module_utils/compat/selinux.py import-3.11!skip # pass/fail depends on presence of libselinux.so lib/ansible/module_utils/compat/selinux.py import-3.12!skip # pass/fail depends on presence of libselinux.so -lib/ansible/module_utils/distro/_distro.py future-import-boilerplate # ignore bundled -lib/ansible/module_utils/distro/_distro.py metaclass-boilerplate # ignore bundled lib/ansible/module_utils/distro/_distro.py no-assert lib/ansible/module_utils/distro/_distro.py pep8!skip # bundled code we don't want to modify lib/ansible/module_utils/distro/_distro.py pylint:undefined-variable # ignore bundled @@ -78,8 +72,6 @@ lib/ansible/module_utils/powershell/Ansible.ModuleUtils.Legacy.psm1 pslint:PSUse lib/ansible/module_utils/powershell/Ansible.ModuleUtils.LinkUtil.psm1 pslint:PSUseApprovedVerbs lib/ansible/module_utils/pycompat24.py no-get-exception lib/ansible/module_utils/six/__init__.py empty-init # breaks namespacing, bundled, do not override -lib/ansible/module_utils/six/__init__.py future-import-boilerplate # ignore bundled -lib/ansible/module_utils/six/__init__.py metaclass-boilerplate # ignore bundled lib/ansible/module_utils/six/__init__.py no-basestring lib/ansible/module_utils/six/__init__.py no-dict-iteritems lib/ansible/module_utils/six/__init__.py no-dict-iterkeys @@ -126,7 +118,6 @@ test/integration/targets/module_precedence/lib_with_extension/a.ini shebang test/integration/targets/module_precedence/lib_with_extension/ping.ini shebang test/integration/targets/module_precedence/roles_with_extension/foo/library/a.ini shebang test/integration/targets/module_precedence/roles_with_extension/foo/library/ping.ini shebang -test/integration/targets/module_utils/library/test.py future-import-boilerplate # allow testing of Python 2.x implicit relative imports test/integration/targets/old_style_modules_posix/library/helloworld.sh shebang test/integration/targets/template/files/encoding_1252_utf-8.expected no-smart-quotes test/integration/targets/template/files/encoding_1252_windows-1252.expected no-smart-quotes diff --git a/test/units/executor/module_common/test_recursive_finder.py b/test/units/executor/module_common/test_recursive_finder.py index 95b49d354dd..7939dc76ee9 100644 --- a/test/units/executor/module_common/test_recursive_finder.py +++ b/test/units/executor/module_common/test_recursive_finder.py @@ -42,7 +42,6 @@ MODULE_UTILS_BASIC_FILES = frozenset(('ansible/__init__.py', 'ansible/module_utils/basic.py', 'ansible/module_utils/six/__init__.py', 'ansible/module_utils/_text.py', - 'ansible/module_utils/common/_json_compat.py', 'ansible/module_utils/common/collections.py', 'ansible/module_utils/common/parameters.py', 'ansible/module_utils/common/warnings.py', diff --git a/test/units/module_utils/basic/test_imports.py b/test/units/module_utils/basic/test_imports.py index d1a5f3791e1..3c34de50745 100644 --- a/test/units/module_utils/basic/test_imports.py +++ b/test/units/module_utils/basic/test_imports.py @@ -61,20 +61,6 @@ class TestImports(ModuleTestCase): mod = builtins.__import__('ansible.module_utils.basic') self.assertFalse(mod.module_utils.basic.HAVE_SELINUX) - @patch.object(builtins, '__import__') - def test_module_utils_basic_import_json(self, mock_import): - def _mock_import(name, *args, **kwargs): - if name == 'ansible.module_utils.common._json_compat': - raise ImportError - return realimport(name, *args, **kwargs) - - self.clear_modules(['json', 'ansible.module_utils.basic']) - builtins.__import__('ansible.module_utils.basic') - self.clear_modules(['json', 'ansible.module_utils.basic']) - mock_import.side_effect = _mock_import - with self.assertRaises(SystemExit): - builtins.__import__('ansible.module_utils.basic') - # FIXME: doesn't work yet # @patch.object(builtins, 'bytes') # def test_module_utils_basic_bytes(self, mock_bytes):