mirror of
https://github.com/zebrajr/ansible.git
synced 2025-12-06 00:19:48 +01:00
ansible-test - Clean up old Python 2 compat code (#81962)
* Update generated code __future__ import * Remove Python 2.x compat from compile sanity test * Remove __metaclass__ from pylint good names list * Remove Python 2.x compat from ansible-test injector * Remove Python 2.x compat from ansible-test importer * Remove Python 2.x compat from ansible-test units * Remove Python 2.x compat from validate-modules * Remove Python 2.x compat from pylint plugins * Remove more Python 2.x compat from ansible-test * Remove Python 2.x openssl detection in ansible-test * Remove obsolete Python 2.x comment * Remove obsolete ansible-test Python 2.x support * Remove unused bootstrap script functions * Keep mypy happy * Remove unused imports * Keep pylint happy
This commit is contained in:
parent
3ae8541133
commit
f5c742cdfd
|
|
@ -1,2 +1 @@
|
||||||
# Empty __init__.py to allow importing of `ansible_test._util.target.common` under Python 2.x.
|
# Empty __init__.py to allow relative imports to work under mypy.
|
||||||
# This allows the ansible-test entry point to report supported Python versions before exiting.
|
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,6 @@ class ContentConfig:
|
||||||
|
|
||||||
modules: ModulesConfig
|
modules: ModulesConfig
|
||||||
python_versions: tuple[str, ...]
|
python_versions: tuple[str, ...]
|
||||||
py2_support: bool
|
|
||||||
|
|
||||||
|
|
||||||
class EnvironmentConfig(CommonConfig):
|
class EnvironmentConfig(CommonConfig):
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ from .io import (
|
||||||
from .util import (
|
from .util import (
|
||||||
ApplicationError,
|
ApplicationError,
|
||||||
display,
|
display,
|
||||||
str_to_version,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
from .data import (
|
from .data import (
|
||||||
|
|
@ -75,13 +74,9 @@ def parse_content_config(data: t.Any) -> ContentConfig:
|
||||||
python_versions = tuple(version for version in SUPPORTED_PYTHON_VERSIONS
|
python_versions = tuple(version for version in SUPPORTED_PYTHON_VERSIONS
|
||||||
if version in CONTROLLER_PYTHON_VERSIONS or version in modules.python_versions)
|
if version in CONTROLLER_PYTHON_VERSIONS or version in modules.python_versions)
|
||||||
|
|
||||||
# True if Python 2.x is supported.
|
|
||||||
py2_support = any(version for version in python_versions if str_to_version(version)[0] == 2)
|
|
||||||
|
|
||||||
return ContentConfig(
|
return ContentConfig(
|
||||||
modules=modules,
|
modules=modules,
|
||||||
python_versions=python_versions,
|
python_versions=python_versions,
|
||||||
py2_support=py2_support,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import base64
|
||||||
import dataclasses
|
import dataclasses
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
|
||||||
import typing as t
|
import typing as t
|
||||||
|
|
||||||
from .encoding import (
|
from .encoding import (
|
||||||
|
|
@ -24,9 +23,7 @@ from .util import (
|
||||||
ApplicationError,
|
ApplicationError,
|
||||||
SubprocessError,
|
SubprocessError,
|
||||||
display,
|
display,
|
||||||
find_executable,
|
|
||||||
raw_command,
|
raw_command,
|
||||||
str_to_version,
|
|
||||||
version_to_str,
|
version_to_str,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -536,34 +533,12 @@ def get_cryptography_requirements(python: PythonConfig) -> list[str]:
|
||||||
|
|
||||||
def get_openssl_version(python: PythonConfig) -> t.Optional[tuple[int, ...]]:
|
def get_openssl_version(python: PythonConfig) -> t.Optional[tuple[int, ...]]:
|
||||||
"""Return the openssl version."""
|
"""Return the openssl version."""
|
||||||
if not python.version.startswith('2.'):
|
version = json.loads(raw_command([python.path, os.path.join(ANSIBLE_TEST_TOOLS_ROOT, 'sslcheck.py')], capture=True)[0])['version']
|
||||||
# OpenSSL version checking only works on Python 3.x.
|
|
||||||
# This should be the most accurate, since it is the Python we will be using.
|
|
||||||
version = json.loads(raw_command([python.path, os.path.join(ANSIBLE_TEST_TOOLS_ROOT, 'sslcheck.py')], capture=True)[0])['version']
|
|
||||||
|
|
||||||
if version:
|
if version:
|
||||||
display.info(f'Detected OpenSSL version {version_to_str(version)} under Python {python.version}.', verbosity=1)
|
display.info(f'Detected OpenSSL version {version_to_str(version)} under Python {python.version}.', verbosity=1)
|
||||||
|
|
||||||
return tuple(version)
|
return tuple(version)
|
||||||
|
|
||||||
# Fall back to detecting the OpenSSL version from the CLI.
|
|
||||||
# This should provide an adequate solution on Python 2.x.
|
|
||||||
openssl_path = find_executable('openssl', required=False)
|
|
||||||
|
|
||||||
if openssl_path:
|
|
||||||
try:
|
|
||||||
result = raw_command([openssl_path, 'version'], capture=True)[0]
|
|
||||||
except SubprocessError:
|
|
||||||
result = ''
|
|
||||||
|
|
||||||
match = re.search(r'^OpenSSL (?P<version>[0-9]+\.[0-9]+\.[0-9]+)', result)
|
|
||||||
|
|
||||||
if match:
|
|
||||||
version = str_to_version(match.group('version'))
|
|
||||||
|
|
||||||
display.info(f'Detected OpenSSL version {version_to_str(version)} using the openssl CLI.', verbosity=1)
|
|
||||||
|
|
||||||
return version
|
|
||||||
|
|
||||||
display.info('Unable to detect OpenSSL version.', verbosity=1)
|
display.info('Unable to detect OpenSSL version.', verbosity=1)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -409,7 +409,7 @@ def create_interpreter_wrapper(interpreter: str, injected_interpreter: str) -> N
|
||||||
code = textwrap.dedent('''
|
code = textwrap.dedent('''
|
||||||
#!%s
|
#!%s
|
||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import annotations
|
||||||
|
|
||||||
from os import execv
|
from os import execv
|
||||||
from sys import argv
|
from sys import argv
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,7 @@ def run_venv(
|
||||||
pip: bool,
|
pip: bool,
|
||||||
path: str,
|
path: str,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Create a virtual environment using the 'venv' module. Not available on Python 2.x."""
|
"""Create a virtual environment using the 'venv' module."""
|
||||||
cmd = [run_python, '-m', 'venv']
|
cmd = [run_python, '-m', 'venv']
|
||||||
|
|
||||||
if system_site_packages:
|
if system_site_packages:
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1 @@
|
||||||
# Empty __init__.py to allow importing of `ansible_test._util.target.common` under Python 2.x.
|
# Empty __init__.py to keep pylint happy.
|
||||||
# This allows the ansible-test entry point to report supported Python versions before exiting.
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ bad-names=
|
||||||
tutu,
|
tutu,
|
||||||
|
|
||||||
good-names=
|
good-names=
|
||||||
__metaclass__,
|
|
||||||
C,
|
C,
|
||||||
ex,
|
ex,
|
||||||
i,
|
i,
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ bad-names=
|
||||||
tutu,
|
tutu,
|
||||||
|
|
||||||
good-names=
|
good-names=
|
||||||
__metaclass__,
|
|
||||||
C,
|
C,
|
||||||
ex,
|
ex,
|
||||||
i,
|
i,
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ bad-names=
|
||||||
tutu,
|
tutu,
|
||||||
|
|
||||||
good-names=
|
good-names=
|
||||||
__metaclass__,
|
|
||||||
C,
|
C,
|
||||||
ex,
|
ex,
|
||||||
i,
|
i,
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ except ImportError:
|
||||||
from pylint.checkers import BaseChecker, BaseTokenChecker
|
from pylint.checkers import BaseChecker, BaseTokenChecker
|
||||||
|
|
||||||
from ansible.module_utils.compat.version import LooseVersion
|
from ansible.module_utils.compat.version import LooseVersion
|
||||||
from ansible.module_utils.six import string_types
|
|
||||||
from ansible.release import __version__ as ansible_version_raw
|
from ansible.release import __version__ as ansible_version_raw
|
||||||
from ansible.utils.version import SemanticVersion
|
from ansible.utils.version import SemanticVersion
|
||||||
|
|
||||||
|
|
@ -137,7 +136,7 @@ def _get_func_name(node):
|
||||||
def parse_isodate(value):
|
def parse_isodate(value):
|
||||||
"""Parse an ISO 8601 date string."""
|
"""Parse an ISO 8601 date string."""
|
||||||
msg = 'Expected ISO 8601 date string (YYYY-MM-DD)'
|
msg = 'Expected ISO 8601 date string (YYYY-MM-DD)'
|
||||||
if not isinstance(value, string_types):
|
if not isinstance(value, str):
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
# From Python 3.7 in, there is datetime.date.fromisoformat(). For older versions,
|
# From Python 3.7 in, there is datetime.date.fromisoformat(). For older versions,
|
||||||
# we have to do things manually.
|
# we have to do things manually.
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,6 @@ from ansible.module_utils.common.collections import is_iterable
|
||||||
from ansible.module_utils.common.parameters import DEFAULT_TYPE_VALIDATORS
|
from ansible.module_utils.common.parameters import DEFAULT_TYPE_VALIDATORS
|
||||||
from ansible.module_utils.compat.version import StrictVersion, LooseVersion
|
from ansible.module_utils.compat.version import StrictVersion, LooseVersion
|
||||||
from ansible.module_utils.basic import to_bytes
|
from ansible.module_utils.basic import to_bytes
|
||||||
from ansible.module_utils.six import PY3, with_metaclass, string_types
|
|
||||||
from ansible.plugins.loader import fragment_loader
|
from ansible.plugins.loader import fragment_loader
|
||||||
from ansible.plugins.list import IGNORE as REJECTLIST
|
from ansible.plugins.list import IGNORE as REJECTLIST
|
||||||
from ansible.utils.plugin_docs import add_collection_to_versions_and_dates, add_fragments, get_docstring
|
from ansible.utils.plugin_docs import add_collection_to_versions_and_dates, add_fragments, get_docstring
|
||||||
|
|
@ -87,14 +86,11 @@ from .schema import (
|
||||||
from .utils import CaptureStd, NoArgsAnsibleModule, compare_unordered_lists, parse_yaml, parse_isodate
|
from .utils import CaptureStd, NoArgsAnsibleModule, compare_unordered_lists, parse_yaml, parse_isodate
|
||||||
|
|
||||||
|
|
||||||
if PY3:
|
# Because there is no ast.TryExcept in Python 3 ast module
|
||||||
# Because there is no ast.TryExcept in Python 3 ast module
|
TRY_EXCEPT = ast.Try
|
||||||
TRY_EXCEPT = ast.Try
|
# REPLACER_WINDOWS from ansible.executor.module_common is byte
|
||||||
# REPLACER_WINDOWS from ansible.executor.module_common is byte
|
# string but we need unicode for Python 3
|
||||||
# string but we need unicode for Python 3
|
REPLACER_WINDOWS = REPLACER_WINDOWS.decode('utf-8')
|
||||||
REPLACER_WINDOWS = REPLACER_WINDOWS.decode('utf-8')
|
|
||||||
else:
|
|
||||||
TRY_EXCEPT = ast.TryExcept
|
|
||||||
|
|
||||||
REJECTLIST_DIRS = frozenset(('.git', 'test', '.github', '.idea'))
|
REJECTLIST_DIRS = frozenset(('.git', 'test', '.github', '.idea'))
|
||||||
INDENT_REGEX = re.compile(r'([\t]*)')
|
INDENT_REGEX = re.compile(r'([\t]*)')
|
||||||
|
|
@ -269,7 +265,7 @@ class Reporter:
|
||||||
return 3 if sum(ret) else 0
|
return 3 if sum(ret) else 0
|
||||||
|
|
||||||
|
|
||||||
class Validator(with_metaclass(abc.ABCMeta, object)):
|
class Validator(metaclass=abc.ABCMeta):
|
||||||
"""Validator instances are intended to be run on a single object. if you
|
"""Validator instances are intended to be run on a single object. if you
|
||||||
are scanning multiple objects for problems, you'll want to have a separate
|
are scanning multiple objects for problems, you'll want to have a separate
|
||||||
Validator for each one."""
|
Validator for each one."""
|
||||||
|
|
@ -1193,7 +1189,7 @@ class ModuleValidator(Validator):
|
||||||
for entry in object:
|
for entry in object:
|
||||||
self._validate_semantic_markup(entry)
|
self._validate_semantic_markup(entry)
|
||||||
return
|
return
|
||||||
if not isinstance(object, string_types):
|
if not isinstance(object, str):
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.collection:
|
if self.collection:
|
||||||
|
|
@ -1374,7 +1370,7 @@ class ModuleValidator(Validator):
|
||||||
continue
|
continue
|
||||||
bad_term = False
|
bad_term = False
|
||||||
for term in check:
|
for term in check:
|
||||||
if not isinstance(term, string_types):
|
if not isinstance(term, str):
|
||||||
msg = name
|
msg = name
|
||||||
if context:
|
if context:
|
||||||
msg += " found in %s" % " -> ".join(context)
|
msg += " found in %s" % " -> ".join(context)
|
||||||
|
|
@ -1442,7 +1438,7 @@ class ModuleValidator(Validator):
|
||||||
continue
|
continue
|
||||||
bad_term = False
|
bad_term = False
|
||||||
for term in requirements:
|
for term in requirements:
|
||||||
if not isinstance(term, string_types):
|
if not isinstance(term, str):
|
||||||
msg = "required_if"
|
msg = "required_if"
|
||||||
if context:
|
if context:
|
||||||
msg += " found in %s" % " -> ".join(context)
|
msg += " found in %s" % " -> ".join(context)
|
||||||
|
|
@ -1525,13 +1521,13 @@ class ModuleValidator(Validator):
|
||||||
# This is already reported by schema checking
|
# This is already reported by schema checking
|
||||||
return
|
return
|
||||||
for key, value in terms.items():
|
for key, value in terms.items():
|
||||||
if isinstance(value, string_types):
|
if isinstance(value, str):
|
||||||
value = [value]
|
value = [value]
|
||||||
if not isinstance(value, (list, tuple)):
|
if not isinstance(value, (list, tuple)):
|
||||||
# This is already reported by schema checking
|
# This is already reported by schema checking
|
||||||
continue
|
continue
|
||||||
for term in value:
|
for term in value:
|
||||||
if not isinstance(term, string_types):
|
if not isinstance(term, str):
|
||||||
# This is already reported by schema checking
|
# This is already reported by schema checking
|
||||||
continue
|
continue
|
||||||
if len(set(value)) != len(value) or key in value:
|
if len(set(value)) != len(value) or key in value:
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1 @@
|
||||||
# Empty __init__.py to allow importing of `ansible_test._util.target.common` under Python 2.x.
|
# Empty __init__.py to keep pylint happy.
|
||||||
# This allows the ansible-test entry point to report supported Python versions before exiting.
|
|
||||||
|
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
# Empty __init__.py to allow importing of `ansible_test._util.target.common` under Python 2.x.
|
|
||||||
# This allows the ansible-test entry point to report supported Python versions before exiting.
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
"""Provides an entry point for python scripts and python modules on the controller with the current python interpreter and optional code coverage collection."""
|
"""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 annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import importlib.util
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
@ -18,22 +19,7 @@ def main():
|
||||||
if coverage_output:
|
if coverage_output:
|
||||||
args += ['-m', 'coverage.__main__', 'run', '--rcfile', coverage_config]
|
args += ['-m', 'coverage.__main__', 'run', '--rcfile', coverage_config]
|
||||||
else:
|
else:
|
||||||
if sys.version_info >= (3, 4):
|
found = bool(importlib.util.find_spec('coverage'))
|
||||||
# noinspection PyUnresolvedReferences
|
|
||||||
import importlib.util
|
|
||||||
|
|
||||||
# noinspection PyUnresolvedReferences
|
|
||||||
found = bool(importlib.util.find_spec('coverage'))
|
|
||||||
else:
|
|
||||||
# noinspection PyDeprecation
|
|
||||||
import imp
|
|
||||||
|
|
||||||
try:
|
|
||||||
# noinspection PyDeprecation
|
|
||||||
imp.find_module('coverage')
|
|
||||||
found = True
|
|
||||||
except ImportError:
|
|
||||||
found = False
|
|
||||||
|
|
||||||
if not found:
|
if not found:
|
||||||
sys.exit('ERROR: Could not find `coverage` module. '
|
sys.exit('ERROR: Could not find `coverage` module. '
|
||||||
|
|
@ -61,7 +47,7 @@ def find_program(name, executable): # type: (str, bool) -> str
|
||||||
Raises an exception if the program is not found.
|
Raises an exception if the program is not found.
|
||||||
"""
|
"""
|
||||||
path = os.environ.get('PATH', os.path.defpath)
|
path = os.environ.get('PATH', os.path.defpath)
|
||||||
seen = set([os.path.abspath(__file__)])
|
seen = {os.path.abspath(__file__)}
|
||||||
mode = os.F_OK | os.X_OK if executable else os.F_OK
|
mode = os.F_OK | os.X_OK if executable else os.F_OK
|
||||||
|
|
||||||
for base in path.split(os.path.pathsep):
|
for base in path.split(os.path.pathsep):
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,6 @@ def enable_assertion_rewriting_hook(): # type: () -> None
|
||||||
"""
|
"""
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
if sys.version_info[0] == 2:
|
|
||||||
return # Python 2.x is not supported
|
|
||||||
|
|
||||||
hook_name = '_pytest.assertion.rewrite.AssertionRewritingHook'
|
hook_name = '_pytest.assertion.rewrite.AssertionRewritingHook'
|
||||||
hooks = [hook for hook in sys.meta_path if hook.__class__.__module__ + '.' + hook.__class__.__qualname__ == hook_name]
|
hooks = [hook for hook in sys.meta_path if hook.__class__.__module__ + '.' + hook.__class__.__qualname__ == hook_name]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import sys
|
||||||
|
|
||||||
ENCODING = 'utf-8'
|
ENCODING = 'utf-8'
|
||||||
ERRORS = 'replace'
|
ERRORS = 'replace'
|
||||||
Text = type(u'')
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
@ -28,21 +27,14 @@ def compile_source(path):
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
# In some situations offset can be None. This can happen for syntax errors on Python 2.6
|
|
||||||
# (__future__ import following after a regular import).
|
|
||||||
offset = offset or 0
|
|
||||||
|
|
||||||
result = "%s:%d:%d: %s: %s" % (path, lineno, offset, extype.__name__, safe_message(message))
|
result = "%s:%d:%d: %s: %s" % (path, lineno, offset, extype.__name__, safe_message(message))
|
||||||
|
|
||||||
if sys.version_info <= (3,):
|
|
||||||
result = result.encode(ENCODING, ERRORS)
|
|
||||||
|
|
||||||
print(result)
|
print(result)
|
||||||
|
|
||||||
|
|
||||||
def safe_message(value):
|
def safe_message(value):
|
||||||
"""Given an input value as text or bytes, return the first non-empty line as text, ensuring it can be round-tripped as UTF-8."""
|
"""Given an input value as str or bytes, return the first non-empty line as str, ensuring it can be round-tripped as UTF-8."""
|
||||||
if isinstance(value, Text):
|
if isinstance(value, str):
|
||||||
value = value.encode(ENCODING, ERRORS)
|
value = value.encode(ENCODING, ERRORS)
|
||||||
|
|
||||||
value = value.decode(ENCODING, ERRORS)
|
value = value.decode(ENCODING, ERRORS)
|
||||||
|
|
|
||||||
|
|
@ -541,16 +541,6 @@ def main():
|
||||||
"ignore",
|
"ignore",
|
||||||
"AnsibleCollectionFinder has already been configured")
|
"AnsibleCollectionFinder has already been configured")
|
||||||
|
|
||||||
if sys.version_info[0] == 2:
|
|
||||||
warnings.filterwarnings(
|
|
||||||
"ignore",
|
|
||||||
"Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography,"
|
|
||||||
" and will be removed in a future release.")
|
|
||||||
warnings.filterwarnings(
|
|
||||||
"ignore",
|
|
||||||
"Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography,"
|
|
||||||
" and will be removed in the next release.")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
yield
|
yield
|
||||||
finally:
|
finally:
|
||||||
|
|
|
||||||
|
|
@ -65,18 +65,6 @@ install_pip() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
pip_install() {
|
|
||||||
pip_packages="$1"
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
"${python_interpreter}" -m pip install --disable-pip-version-check ${pip_packages} \
|
|
||||||
&& break
|
|
||||||
echo "Failed to install packages. Sleeping before trying again..."
|
|
||||||
sleep 10
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
bootstrap_remote_alpine()
|
bootstrap_remote_alpine()
|
||||||
{
|
{
|
||||||
py_pkg_prefix="py3"
|
py_pkg_prefix="py3"
|
||||||
|
|
@ -279,17 +267,6 @@ bootstrap_remote_rhel()
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
bootstrap_remote_rhel_pinned_pip_packages()
|
|
||||||
{
|
|
||||||
# pin packaging and pyparsing to match the downstream vendored versions
|
|
||||||
pip_packages="
|
|
||||||
packaging==20.4
|
|
||||||
pyparsing==2.4.7
|
|
||||||
"
|
|
||||||
|
|
||||||
pip_install "${pip_packages}"
|
|
||||||
}
|
|
||||||
|
|
||||||
bootstrap_remote_ubuntu()
|
bootstrap_remote_ubuntu()
|
||||||
{
|
{
|
||||||
py_pkg_prefix="python3"
|
py_pkg_prefix="python3"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user