ansible-core 2.15.4rc1__py3-none-any.whl → 2.16.0b2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ansible-core might be problematic. Click here for more details.
- ansible/cli/__init__.py +3 -3
- ansible/cli/adhoc.py +1 -1
- ansible/cli/arguments/option_helpers.py +15 -5
- ansible/cli/config.py +2 -2
- ansible/cli/console.py +21 -17
- ansible/cli/doc.py +8 -9
- ansible/cli/galaxy.py +60 -27
- ansible/cli/inventory.py +1 -1
- ansible/cli/playbook.py +1 -1
- ansible/cli/pull.py +2 -2
- ansible/cli/scripts/ansible_connection_cli_stub.py +1 -1
- ansible/cli/vault.py +11 -6
- ansible/collections/__init__.py +0 -29
- ansible/collections/list.py +23 -44
- ansible/config/ansible_builtin_runtime.yml +8 -4
- ansible/config/base.yml +34 -22
- ansible/config/manager.py +1 -1
- ansible/constants.py +3 -5
- ansible/errors/__init__.py +1 -1
- ansible/executor/interpreter_discovery.py +1 -1
- ansible/executor/module_common.py +39 -32
- ansible/executor/play_iterator.py +0 -15
- ansible/executor/playbook_executor.py +3 -3
- ansible/executor/powershell/module_manifest.py +1 -1
- ansible/executor/powershell/module_wrapper.ps1 +4 -1
- ansible/executor/process/worker.py +22 -7
- ansible/executor/task_executor.py +39 -40
- ansible/executor/task_queue_manager.py +8 -11
- ansible/galaxy/__init__.py +1 -1
- ansible/galaxy/api.py +8 -11
- ansible/galaxy/collection/__init__.py +17 -4
- ansible/galaxy/collection/concrete_artifact_manager.py +7 -2
- ansible/galaxy/collection/galaxy_api_proxy.py +1 -1
- ansible/galaxy/data/container/README.md +3 -5
- ansible/galaxy/dependency_resolution/__init__.py +1 -6
- ansible/galaxy/dependency_resolution/dataclasses.py +22 -1
- ansible/galaxy/dependency_resolution/providers.py +61 -69
- ansible/galaxy/role.py +31 -13
- ansible/galaxy/token.py +2 -2
- ansible/inventory/group.py +1 -1
- ansible/inventory/manager.py +1 -1
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/basic.py +11 -41
- ansible/module_utils/common/file.py +0 -100
- ansible/module_utils/common/json.py +1 -1
- ansible/module_utils/common/locale.py +1 -1
- ansible/module_utils/common/text/converters.py +2 -2
- ansible/module_utils/common/validation.py +1 -1
- ansible/module_utils/compat/_selectors2.py +4 -4
- ansible/module_utils/compat/datetime.py +40 -0
- ansible/module_utils/compat/selinux.py +1 -1
- ansible/module_utils/compat/typing.py +1 -1
- ansible/module_utils/connection.py +1 -1
- ansible/module_utils/facts/hardware/linux.py +2 -2
- ansible/module_utils/facts/hardware/openbsd.py +1 -1
- ansible/module_utils/facts/network/linux.py +3 -3
- ansible/module_utils/facts/other/facter.py +8 -15
- ansible/module_utils/facts/sysctl.py +1 -1
- ansible/module_utils/facts/system/date_time.py +2 -2
- ansible/module_utils/facts/system/distribution.py +1 -1
- ansible/module_utils/facts/system/local.py +6 -2
- ansible/module_utils/facts/system/pkg_mgr.py +6 -1
- ansible/module_utils/facts/system/service_mgr.py +4 -2
- ansible/module_utils/parsing/convert_bool.py +1 -1
- ansible/module_utils/service.py +9 -6
- ansible/module_utils/urls.py +40 -22
- ansible/modules/add_host.py +2 -2
- ansible/modules/apt.py +48 -31
- ansible/modules/apt_key.py +4 -4
- ansible/modules/apt_repository.py +5 -5
- ansible/modules/assemble.py +7 -7
- ansible/modules/assert.py +1 -1
- ansible/modules/async_status.py +11 -7
- ansible/modules/async_wrapper.py +1 -1
- ansible/modules/blockinfile.py +60 -17
- ansible/modules/command.py +37 -15
- ansible/modules/copy.py +35 -30
- ansible/modules/cron.py +14 -14
- ansible/modules/deb822_repository.py +4 -3
- ansible/modules/debconf.py +35 -14
- ansible/modules/debug.py +1 -1
- ansible/modules/dnf.py +29 -27
- ansible/modules/dnf5.py +22 -22
- ansible/modules/dpkg_selections.py +9 -2
- ansible/modules/expect.py +4 -4
- ansible/modules/fetch.py +7 -7
- ansible/modules/file.py +30 -30
- ansible/modules/find.py +82 -22
- ansible/modules/gather_facts.py +6 -2
- ansible/modules/get_url.py +29 -29
- ansible/modules/getent.py +4 -4
- ansible/modules/git.py +27 -27
- ansible/modules/group.py +5 -12
- ansible/modules/hostname.py +21 -2
- ansible/modules/include_role.py +5 -5
- ansible/modules/include_tasks.py +2 -2
- ansible/modules/include_vars.py +5 -5
- ansible/modules/iptables.py +70 -65
- ansible/modules/known_hosts.py +7 -7
- ansible/modules/lineinfile.py +33 -33
- ansible/modules/meta.py +13 -13
- ansible/modules/package.py +8 -8
- ansible/modules/package_facts.py +3 -3
- ansible/modules/pause.py +2 -2
- ansible/modules/ping.py +5 -5
- ansible/modules/pip.py +80 -46
- ansible/modules/reboot.py +8 -4
- ansible/modules/replace.py +20 -15
- ansible/modules/rpm_key.py +2 -2
- ansible/modules/script.py +16 -10
- ansible/modules/service.py +26 -98
- ansible/modules/service_facts.py +36 -12
- ansible/modules/set_fact.py +2 -2
- ansible/modules/set_stats.py +2 -2
- ansible/modules/setup.py +18 -18
- ansible/modules/shell.py +3 -3
- ansible/modules/stat.py +9 -30
- ansible/modules/subversion.py +9 -9
- ansible/modules/systemd.py +20 -19
- ansible/modules/systemd_service.py +20 -19
- ansible/modules/sysvinit.py +26 -21
- ansible/modules/tempfile.py +5 -4
- ansible/modules/template.py +60 -6
- ansible/modules/unarchive.py +21 -18
- ansible/modules/uri.py +39 -39
- ansible/modules/user.py +81 -53
- ansible/modules/wait_for.py +22 -21
- ansible/modules/wait_for_connection.py +4 -4
- ansible/modules/yum.py +38 -38
- ansible/modules/yum_repository.py +58 -80
- ansible/parsing/dataloader.py +27 -27
- ansible/parsing/mod_args.py +1 -1
- ansible/parsing/plugin_docs.py +3 -3
- ansible/parsing/splitter.py +14 -16
- ansible/parsing/utils/yaml.py +1 -1
- ansible/parsing/vault/__init__.py +8 -6
- ansible/parsing/yaml/constructor.py +1 -1
- ansible/parsing/yaml/objects.py +1 -1
- ansible/playbook/__init__.py +1 -1
- ansible/playbook/base.py +2 -2
- ansible/playbook/block.py +0 -1
- ansible/playbook/conditional.py +40 -114
- ansible/playbook/helpers.py +5 -28
- ansible/playbook/included_file.py +8 -7
- ansible/playbook/play.py +1 -1
- ansible/playbook/play_context.py +2 -2
- ansible/playbook/playbook_include.py +2 -2
- ansible/playbook/role/__init__.py +1 -1
- ansible/playbook/role/include.py +1 -1
- ansible/playbook/role/metadata.py +1 -1
- ansible/playbook/role_include.py +1 -1
- ansible/playbook/task.py +2 -2
- ansible/playbook/task_include.py +1 -24
- ansible/plugins/__init__.py +13 -5
- ansible/plugins/action/__init__.py +17 -43
- ansible/plugins/action/add_host.py +2 -3
- ansible/plugins/action/assemble.py +1 -1
- ansible/plugins/action/assert.py +2 -1
- ansible/plugins/action/copy.py +2 -2
- ansible/plugins/action/debug.py +2 -1
- ansible/plugins/action/fail.py +1 -0
- ansible/plugins/action/fetch.py +3 -1
- ansible/plugins/action/gather_facts.py +37 -13
- ansible/plugins/action/group_by.py +1 -0
- ansible/plugins/action/include_vars.py +3 -2
- ansible/plugins/action/normal.py +3 -3
- ansible/plugins/action/pause.py +1 -1
- ansible/plugins/action/reboot.py +21 -16
- ansible/plugins/action/script.py +23 -8
- ansible/plugins/action/set_fact.py +1 -0
- ansible/plugins/action/set_stats.py +1 -0
- ansible/plugins/action/shell.py +6 -0
- ansible/plugins/action/template.py +1 -1
- ansible/plugins/action/unarchive.py +1 -1
- ansible/plugins/action/uri.py +1 -1
- ansible/plugins/action/validate_argument_spec.py +1 -0
- ansible/plugins/action/wait_for_connection.py +4 -4
- ansible/plugins/become/__init__.py +1 -1
- ansible/plugins/become/su.py +1 -1
- ansible/plugins/cache/__init__.py +1 -1
- ansible/plugins/callback/junit.py +1 -1
- ansible/plugins/callback/oneline.py +1 -1
- ansible/plugins/callback/tree.py +1 -1
- ansible/plugins/cliconf/__init__.py +2 -2
- ansible/plugins/connection/__init__.py +65 -37
- ansible/plugins/connection/local.py +9 -8
- ansible/plugins/connection/paramiko_ssh.py +34 -28
- ansible/plugins/connection/psrp.py +56 -43
- ansible/plugins/connection/ssh.py +67 -43
- ansible/plugins/connection/winrm.py +77 -30
- ansible/plugins/doc_fragments/constructed.py +4 -4
- ansible/plugins/doc_fragments/files.py +12 -12
- ansible/plugins/doc_fragments/inventory_cache.py +0 -6
- ansible/plugins/doc_fragments/result_format_callback.py +5 -5
- ansible/plugins/doc_fragments/shell_common.py +2 -2
- ansible/plugins/doc_fragments/shell_windows.py +1 -1
- ansible/plugins/doc_fragments/template_common.py +6 -6
- ansible/plugins/doc_fragments/url.py +10 -10
- ansible/plugins/doc_fragments/url_windows.py +15 -15
- ansible/plugins/doc_fragments/vars_plugin_staging.py +4 -4
- ansible/plugins/filter/b64decode.yml +1 -1
- ansible/plugins/filter/b64encode.yml +2 -2
- ansible/plugins/filter/bool.yml +5 -5
- ansible/plugins/filter/combine.yml +1 -1
- ansible/plugins/filter/commonpath.yml +2 -1
- ansible/plugins/filter/core.py +6 -8
- ansible/plugins/filter/dict2items.yml +11 -1
- ansible/plugins/filter/difference.yml +1 -0
- ansible/plugins/filter/encryption.py +1 -1
- ansible/plugins/filter/extract.yml +1 -1
- ansible/plugins/filter/flatten.yml +1 -1
- ansible/plugins/filter/from_yaml.yml +1 -1
- ansible/plugins/filter/from_yaml_all.yml +2 -2
- ansible/plugins/filter/hash.yml +1 -1
- ansible/plugins/filter/human_readable.yml +1 -1
- ansible/plugins/filter/human_to_bytes.yml +2 -2
- ansible/plugins/filter/intersect.yml +1 -0
- ansible/plugins/filter/mandatory.yml +7 -0
- ansible/plugins/filter/mathstuff.py +15 -17
- ansible/plugins/filter/normpath.yml +1 -1
- ansible/plugins/filter/path_join.yml +8 -1
- ansible/plugins/filter/realpath.yml +3 -2
- ansible/plugins/filter/regex_findall.yml +8 -2
- ansible/plugins/filter/regex_replace.yml +9 -3
- ansible/plugins/filter/regex_search.yml +8 -2
- ansible/plugins/filter/relpath.yml +2 -2
- ansible/plugins/filter/root.yml +1 -1
- ansible/plugins/filter/splitext.yml +1 -1
- ansible/plugins/filter/subelements.yml +2 -2
- ansible/plugins/filter/symmetric_difference.yml +1 -0
- ansible/plugins/filter/ternary.yml +5 -5
- ansible/plugins/filter/to_json.yml +7 -7
- ansible/plugins/filter/to_nice_json.yml +5 -5
- ansible/plugins/filter/to_yaml.yml +2 -2
- ansible/plugins/filter/type_debug.yml +1 -1
- ansible/plugins/filter/union.yml +1 -0
- ansible/plugins/filter/unvault.yml +2 -2
- ansible/plugins/filter/urldecode.yml +13 -32
- ansible/plugins/filter/urlsplit.py +1 -1
- ansible/plugins/filter/vault.yml +1 -1
- ansible/plugins/filter/zip.yml +1 -1
- ansible/plugins/filter/zip_longest.yml +1 -1
- ansible/plugins/inventory/__init__.py +1 -1
- ansible/plugins/inventory/advanced_host_list.py +1 -1
- ansible/plugins/inventory/constructed.py +2 -2
- ansible/plugins/inventory/host_list.py +1 -1
- ansible/plugins/inventory/ini.py +6 -3
- ansible/plugins/inventory/script.py +8 -2
- ansible/plugins/inventory/toml.py +1 -1
- ansible/plugins/inventory/yaml.py +1 -1
- ansible/plugins/list.py +21 -17
- ansible/plugins/loader.py +66 -88
- ansible/plugins/lookup/__init__.py +1 -1
- ansible/plugins/lookup/config.py +16 -6
- ansible/plugins/lookup/csvfile.py +7 -4
- ansible/plugins/lookup/env.py +1 -1
- ansible/plugins/lookup/file.py +5 -2
- ansible/plugins/lookup/fileglob.py +5 -2
- ansible/plugins/lookup/first_found.py +20 -14
- ansible/plugins/lookup/ini.py +6 -3
- ansible/plugins/lookup/lines.py +2 -1
- ansible/plugins/lookup/password.py +7 -7
- ansible/plugins/lookup/pipe.py +1 -0
- ansible/plugins/lookup/random_choice.py +2 -2
- ansible/plugins/lookup/sequence.py +1 -1
- ansible/plugins/lookup/subelements.py +2 -2
- ansible/plugins/lookup/template.py +4 -1
- ansible/plugins/lookup/unvault.py +4 -1
- ansible/plugins/lookup/url.py +6 -6
- ansible/plugins/lookup/varnames.py +1 -1
- ansible/plugins/netconf/__init__.py +3 -3
- ansible/plugins/shell/__init__.py +1 -1
- ansible/plugins/shell/cmd.py +7 -7
- ansible/plugins/shell/powershell.py +1 -1
- ansible/plugins/strategy/__init__.py +8 -10
- ansible/plugins/strategy/free.py +1 -1
- ansible/plugins/strategy/linear.py +3 -3
- ansible/plugins/terminal/__init__.py +2 -2
- ansible/plugins/test/abs.yml +1 -1
- ansible/plugins/test/all.yml +1 -1
- ansible/plugins/test/any.yml +1 -1
- ansible/plugins/test/change.yml +2 -2
- ansible/plugins/test/changed.yml +2 -2
- ansible/plugins/test/contains.yml +1 -1
- ansible/plugins/test/core.py +1 -1
- ansible/plugins/test/directory.yml +1 -1
- ansible/plugins/test/exists.yml +3 -2
- ansible/plugins/test/failed.yml +2 -2
- ansible/plugins/test/failure.yml +2 -2
- ansible/plugins/test/falsy.yml +2 -2
- ansible/plugins/test/file.yml +1 -1
- ansible/plugins/test/finished.yml +2 -2
- ansible/plugins/test/is_abs.yml +1 -1
- ansible/plugins/test/is_dir.yml +1 -1
- ansible/plugins/test/is_file.yml +1 -1
- ansible/plugins/test/is_link.yml +1 -1
- ansible/plugins/test/is_mount.yml +1 -1
- ansible/plugins/test/is_same_file.yml +1 -1
- ansible/plugins/test/isnan.yml +1 -1
- ansible/plugins/test/issubset.yml +1 -2
- ansible/plugins/test/issuperset.yml +1 -2
- ansible/plugins/test/link.yml +1 -1
- ansible/plugins/test/link_exists.yml +1 -1
- ansible/plugins/test/match.yml +2 -2
- ansible/plugins/test/mount.yml +1 -1
- ansible/plugins/test/nan.yml +1 -1
- ansible/plugins/test/reachable.yml +2 -2
- ansible/plugins/test/regex.yml +1 -1
- ansible/plugins/test/same_file.yml +1 -1
- ansible/plugins/test/search.yml +2 -2
- ansible/plugins/test/skip.yml +3 -3
- ansible/plugins/test/skipped.yml +3 -3
- ansible/plugins/test/started.yml +2 -2
- ansible/plugins/test/subset.yml +1 -2
- ansible/plugins/test/succeeded.yml +2 -2
- ansible/plugins/test/success.yml +2 -2
- ansible/plugins/test/successful.yml +2 -2
- ansible/plugins/test/superset.yml +1 -2
- ansible/plugins/test/truthy.yml +3 -3
- ansible/plugins/test/unreachable.yml +2 -2
- ansible/plugins/test/uri.yml +1 -1
- ansible/plugins/test/url.yml +1 -1
- ansible/plugins/test/urn.yml +1 -1
- ansible/plugins/test/vault_encrypted.yml +1 -1
- ansible/plugins/test/version.yml +7 -7
- ansible/plugins/test/version_compare.yml +7 -7
- ansible/plugins/vars/host_group_vars.py +1 -1
- ansible/release.py +2 -2
- ansible/template/__init__.py +24 -26
- ansible/template/native_helpers.py +1 -1
- ansible/template/vars.py +1 -1
- ansible/utils/_junit_xml.py +1 -1
- ansible/utils/cmd_functions.py +1 -1
- ansible/utils/collection_loader/_collection_finder.py +12 -1
- ansible/utils/display.py +113 -62
- ansible/utils/encrypt.py +11 -14
- ansible/utils/hashing.py +1 -1
- ansible/utils/jsonrpc.py +1 -1
- ansible/utils/path.py +1 -1
- ansible/utils/plugin_docs.py +1 -1
- ansible/utils/py3compat.py +1 -1
- ansible/utils/shlex.py +2 -10
- ansible/utils/ssh_functions.py +5 -4
- ansible/utils/unicode.py +1 -1
- ansible/utils/unsafe_proxy.py +1 -1
- ansible/utils/vars.py +4 -29
- ansible/vars/hostvars.py +1 -2
- ansible/vars/manager.py +13 -9
- ansible/vars/plugins.py +2 -2
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/COPYING +4 -5
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/METADATA +2 -4
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/RECORD +424 -425
- ansible_test/_data/completion/docker.txt +9 -9
- ansible_test/_data/completion/remote.txt +4 -7
- ansible_test/_data/completion/windows.txt +0 -2
- ansible_test/_data/requirements/ansible-test.txt +2 -1
- ansible_test/_data/requirements/ansible.txt +0 -3
- ansible_test/_data/requirements/constraints.txt +0 -2
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -5
- ansible_test/_data/requirements/sanity.changelog.in +1 -2
- ansible_test/_data/requirements/sanity.changelog.txt +4 -6
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -4
- ansible_test/_data/requirements/sanity.import.txt +1 -3
- ansible_test/_data/requirements/sanity.integration-aliases.txt +1 -3
- ansible_test/_data/requirements/sanity.mypy.txt +12 -12
- ansible_test/_data/requirements/sanity.pep8.txt +1 -1
- ansible_test/_data/requirements/sanity.pylint.txt +6 -12
- ansible_test/_data/requirements/sanity.runtime-metadata.txt +1 -3
- ansible_test/_data/requirements/sanity.validate-modules.in +1 -1
- ansible_test/_data/requirements/sanity.validate-modules.txt +3 -5
- ansible_test/_data/requirements/sanity.yamllint.txt +3 -5
- ansible_test/_data/requirements/units.txt +0 -1
- ansible_test/_internal/ci/azp.py +4 -4
- ansible_test/_internal/cli/environments.py +0 -13
- ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +4 -4
- ansible_test/_internal/commands/coverage/combine.py +1 -1
- ansible_test/_internal/commands/integration/cloud/acme.py +6 -8
- ansible_test/_internal/commands/integration/cloud/cs.py +4 -9
- ansible_test/_internal/commands/integration/cloud/galaxy.py +103 -96
- ansible_test/_internal/commands/integration/cloud/httptester.py +0 -3
- ansible_test/_internal/commands/integration/cloud/nios.py +7 -9
- ansible_test/_internal/commands/integration/cloud/openshift.py +2 -7
- ansible_test/_internal/commands/integration/cloud/vcenter.py +11 -95
- ansible_test/_internal/commands/sanity/__init__.py +10 -0
- ansible_test/_internal/commands/sanity/import.py +8 -2
- ansible_test/_internal/commands/sanity/pylint.py +27 -1
- ansible_test/_internal/commands/units/__init__.py +2 -1
- ansible_test/_internal/config.py +0 -7
- ansible_test/_internal/containers.py +11 -56
- ansible_test/_internal/core_ci.py +0 -7
- ansible_test/_internal/coverage_util.py +8 -3
- ansible_test/_internal/delegation.py +0 -1
- ansible_test/_internal/diff.py +1 -1
- ansible_test/_internal/docker_util.py +9 -2
- ansible_test/_internal/host_profiles.py +6 -6
- ansible_test/_internal/http.py +1 -1
- ansible_test/_internal/junit_xml.py +1 -1
- ansible_test/_internal/pypi_proxy.py +1 -1
- ansible_test/_internal/python_requirements.py +3 -8
- ansible_test/_internal/util.py +1 -6
- ansible_test/_util/controller/sanity/code-smell/no-get-exception.json +4 -0
- ansible_test/_util/controller/sanity/code-smell/replace-urlopen.json +4 -0
- ansible_test/_util/controller/sanity/code-smell/use-compat-six.json +4 -0
- ansible_test/_util/controller/sanity/mypy/ansible-core.ini +3 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +2 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +0 -1
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +1 -0
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +172 -10
- ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +13 -2
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +7 -1
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +6 -6
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +1 -1
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -1
- ansible_test/_util/controller/sanity/yamllint/yamllinter.py +3 -3
- ansible_test/_util/controller/tools/collection_detail.py +2 -2
- ansible_test/_util/target/common/constants.py +2 -2
- ansible_test/_util/target/pytest/plugins/ansible_forked.py +103 -0
- ansible_test/_util/target/sanity/import/importer.py +0 -8
- ansible_test/_util/target/setup/bootstrap.sh +36 -16
- ansible_test/_util/target/setup/quiet_pip.py +0 -4
- ansible/modules/_include.py +0 -80
- ansible_test/_internal/commands/integration/cloud/foreman.py +0 -102
- ansible_test/_util/target/setup/ConfigureRemotingForAnsible.ps1 +0 -435
- {ansible_core-2.15.4rc1.data → ansible_core-2.16.0b2.data}/scripts/ansible-test +0 -0
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/WHEEL +0 -0
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/top_level.txt +0 -0
|
@@ -5,14 +5,31 @@
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
7
|
import datetime
|
|
8
|
+
import functools
|
|
9
|
+
import json
|
|
8
10
|
import re
|
|
11
|
+
import shlex
|
|
9
12
|
import typing as t
|
|
13
|
+
from tokenize import COMMENT, TokenInfo
|
|
10
14
|
|
|
11
15
|
import astroid
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
from pylint.
|
|
17
|
+
# support pylint 2.x and 3.x -- remove when supporting only 3.x
|
|
18
|
+
try:
|
|
19
|
+
from pylint.interfaces import IAstroidChecker, ITokenChecker
|
|
20
|
+
except ImportError:
|
|
21
|
+
class IAstroidChecker:
|
|
22
|
+
"""Backwards compatibility for 2.x / 3.x support."""
|
|
23
|
+
|
|
24
|
+
class ITokenChecker:
|
|
25
|
+
"""Backwards compatibility for 2.x / 3.x support."""
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
from pylint.checkers.utils import check_messages
|
|
29
|
+
except ImportError:
|
|
30
|
+
from pylint.checkers.utils import only_required_for_messages as check_messages
|
|
31
|
+
|
|
32
|
+
from pylint.checkers import BaseChecker, BaseTokenChecker
|
|
16
33
|
|
|
17
34
|
from ansible.module_utils.compat.version import LooseVersion
|
|
18
35
|
from ansible.module_utils.six import string_types
|
|
@@ -95,7 +112,7 @@ ANSIBLE_VERSION = LooseVersion('.'.join(ansible_version_raw.split('.')[:3]))
|
|
|
95
112
|
|
|
96
113
|
|
|
97
114
|
def _get_expr_name(node):
|
|
98
|
-
"""
|
|
115
|
+
"""Function to get either ``attrname`` or ``name`` from ``node.func.expr``
|
|
99
116
|
|
|
100
117
|
Created specifically for the case of ``display.deprecated`` or ``self._display.deprecated``
|
|
101
118
|
"""
|
|
@@ -106,6 +123,17 @@ def _get_expr_name(node):
|
|
|
106
123
|
return node.func.expr.name
|
|
107
124
|
|
|
108
125
|
|
|
126
|
+
def _get_func_name(node):
|
|
127
|
+
"""Function to get either ``attrname`` or ``name`` from ``node.func``
|
|
128
|
+
|
|
129
|
+
Created specifically for the case of ``from ansible.module_utils.common.warnings import deprecate``
|
|
130
|
+
"""
|
|
131
|
+
try:
|
|
132
|
+
return node.func.attrname
|
|
133
|
+
except AttributeError:
|
|
134
|
+
return node.func.name
|
|
135
|
+
|
|
136
|
+
|
|
109
137
|
def parse_isodate(value):
|
|
110
138
|
"""Parse an ISO 8601 date string."""
|
|
111
139
|
msg = 'Expected ISO 8601 date string (YYYY-MM-DD)'
|
|
@@ -118,7 +146,7 @@ def parse_isodate(value):
|
|
|
118
146
|
try:
|
|
119
147
|
return datetime.datetime.strptime(value, '%Y-%m-%d').date()
|
|
120
148
|
except ValueError:
|
|
121
|
-
raise ValueError(msg)
|
|
149
|
+
raise ValueError(msg) from None
|
|
122
150
|
|
|
123
151
|
|
|
124
152
|
class AnsibleDeprecatedChecker(BaseChecker):
|
|
@@ -160,6 +188,8 @@ class AnsibleDeprecatedChecker(BaseChecker):
|
|
|
160
188
|
self.add_message('ansible-deprecated-date', node=node, args=(date,))
|
|
161
189
|
|
|
162
190
|
def _check_version(self, node, version, collection_name):
|
|
191
|
+
if collection_name is None:
|
|
192
|
+
collection_name = 'ansible.builtin'
|
|
163
193
|
if not isinstance(version, (str, float)):
|
|
164
194
|
if collection_name == 'ansible.builtin':
|
|
165
195
|
symbol = 'ansible-invalid-deprecated-version'
|
|
@@ -197,14 +227,14 @@ class AnsibleDeprecatedChecker(BaseChecker):
|
|
|
197
227
|
@property
|
|
198
228
|
def collection_name(self) -> t.Optional[str]:
|
|
199
229
|
"""Return the collection name, or None if ansible-core is being tested."""
|
|
200
|
-
return self.config.collection_name
|
|
230
|
+
return self.linter.config.collection_name
|
|
201
231
|
|
|
202
232
|
@property
|
|
203
233
|
def collection_version(self) -> t.Optional[SemanticVersion]:
|
|
204
234
|
"""Return the collection version, or None if ansible-core is being tested."""
|
|
205
|
-
if self.config.collection_version is None:
|
|
235
|
+
if self.linter.config.collection_version is None:
|
|
206
236
|
return None
|
|
207
|
-
sem_ver = SemanticVersion(self.config.collection_version)
|
|
237
|
+
sem_ver = SemanticVersion(self.linter.config.collection_version)
|
|
208
238
|
# Ignore pre-release for version comparison to catch issues before the final release is cut.
|
|
209
239
|
sem_ver.prerelease = ()
|
|
210
240
|
return sem_ver
|
|
@@ -216,8 +246,9 @@ class AnsibleDeprecatedChecker(BaseChecker):
|
|
|
216
246
|
date = None
|
|
217
247
|
collection_name = None
|
|
218
248
|
try:
|
|
219
|
-
|
|
220
|
-
|
|
249
|
+
funcname = _get_func_name(node)
|
|
250
|
+
if (funcname == 'deprecated' and 'display' in _get_expr_name(node) or
|
|
251
|
+
funcname == 'deprecate'):
|
|
221
252
|
if node.keywords:
|
|
222
253
|
for keyword in node.keywords:
|
|
223
254
|
if len(node.keywords) == 1 and keyword.arg is None:
|
|
@@ -263,6 +294,137 @@ class AnsibleDeprecatedChecker(BaseChecker):
|
|
|
263
294
|
pass
|
|
264
295
|
|
|
265
296
|
|
|
297
|
+
class AnsibleDeprecatedCommentChecker(BaseTokenChecker):
|
|
298
|
+
"""Checks for ``# deprecated:`` comments to ensure that the ``version``
|
|
299
|
+
has not passed or met the time for removal
|
|
300
|
+
"""
|
|
301
|
+
|
|
302
|
+
__implements__ = (ITokenChecker,)
|
|
303
|
+
|
|
304
|
+
name = 'deprecated-comment'
|
|
305
|
+
msgs = {
|
|
306
|
+
'E9601': ("Deprecated core version (%r) found: %s",
|
|
307
|
+
"ansible-deprecated-version-comment",
|
|
308
|
+
"Used when a '# deprecated:' comment specifies a version "
|
|
309
|
+
"less than or equal to the current version of Ansible",
|
|
310
|
+
{'minversion': (2, 6)}),
|
|
311
|
+
'E9602': ("Deprecated comment contains invalid keys %r",
|
|
312
|
+
"ansible-deprecated-version-comment-invalid-key",
|
|
313
|
+
"Used when a '#deprecated:' comment specifies invalid data",
|
|
314
|
+
{'minversion': (2, 6)}),
|
|
315
|
+
'E9603': ("Deprecated comment missing version",
|
|
316
|
+
"ansible-deprecated-version-comment-missing-version",
|
|
317
|
+
"Used when a '#deprecated:' comment specifies invalid data",
|
|
318
|
+
{'minversion': (2, 6)}),
|
|
319
|
+
'E9604': ("Deprecated python version (%r) found: %s",
|
|
320
|
+
"ansible-deprecated-python-version-comment",
|
|
321
|
+
"Used when a '#deprecated:' comment specifies a python version "
|
|
322
|
+
"less than or equal to the minimum python version",
|
|
323
|
+
{'minversion': (2, 6)}),
|
|
324
|
+
'E9605': ("Deprecated comment contains invalid version %r: %s",
|
|
325
|
+
"ansible-deprecated-version-comment-invalid-version",
|
|
326
|
+
"Used when a '#deprecated:' comment specifies an invalid version",
|
|
327
|
+
{'minversion': (2, 6)}),
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
options = (
|
|
331
|
+
('min-python-version-db', {
|
|
332
|
+
'default': None,
|
|
333
|
+
'type': 'string',
|
|
334
|
+
'metavar': '<path>',
|
|
335
|
+
'help': 'The path to the DB mapping paths to minimum Python versions.',
|
|
336
|
+
}),
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
def process_tokens(self, tokens: list[TokenInfo]) -> None:
|
|
340
|
+
for token in tokens:
|
|
341
|
+
if token.type == COMMENT:
|
|
342
|
+
self._process_comment(token)
|
|
343
|
+
|
|
344
|
+
def _deprecated_string_to_dict(self, token: TokenInfo, string: str) -> dict[str, str]:
|
|
345
|
+
valid_keys = {'description', 'core_version', 'python_version'}
|
|
346
|
+
data = dict.fromkeys(valid_keys)
|
|
347
|
+
for opt in shlex.split(string):
|
|
348
|
+
if '=' not in opt:
|
|
349
|
+
data[opt] = None
|
|
350
|
+
continue
|
|
351
|
+
key, _sep, value = opt.partition('=')
|
|
352
|
+
data[key] = value
|
|
353
|
+
if not any((data['core_version'], data['python_version'])):
|
|
354
|
+
self.add_message(
|
|
355
|
+
'ansible-deprecated-version-comment-missing-version',
|
|
356
|
+
line=token.start[0],
|
|
357
|
+
col_offset=token.start[1],
|
|
358
|
+
)
|
|
359
|
+
bad = set(data).difference(valid_keys)
|
|
360
|
+
if bad:
|
|
361
|
+
self.add_message(
|
|
362
|
+
'ansible-deprecated-version-comment-invalid-key',
|
|
363
|
+
line=token.start[0],
|
|
364
|
+
col_offset=token.start[1],
|
|
365
|
+
args=(','.join(bad),)
|
|
366
|
+
)
|
|
367
|
+
return data
|
|
368
|
+
|
|
369
|
+
@functools.cached_property
|
|
370
|
+
def _min_python_version_db(self) -> dict[str, str]:
|
|
371
|
+
"""A dictionary of absolute file paths and their minimum required Python version."""
|
|
372
|
+
with open(self.linter.config.min_python_version_db) as db_file:
|
|
373
|
+
return json.load(db_file)
|
|
374
|
+
|
|
375
|
+
def _process_python_version(self, token: TokenInfo, data: dict[str, str]) -> None:
|
|
376
|
+
current_file = self.linter.current_file
|
|
377
|
+
check_version = self._min_python_version_db[current_file]
|
|
378
|
+
|
|
379
|
+
try:
|
|
380
|
+
if LooseVersion(data['python_version']) < LooseVersion(check_version):
|
|
381
|
+
self.add_message(
|
|
382
|
+
'ansible-deprecated-python-version-comment',
|
|
383
|
+
line=token.start[0],
|
|
384
|
+
col_offset=token.start[1],
|
|
385
|
+
args=(
|
|
386
|
+
data['python_version'],
|
|
387
|
+
data['description'] or 'description not provided',
|
|
388
|
+
),
|
|
389
|
+
)
|
|
390
|
+
except (ValueError, TypeError) as exc:
|
|
391
|
+
self.add_message(
|
|
392
|
+
'ansible-deprecated-version-comment-invalid-version',
|
|
393
|
+
line=token.start[0],
|
|
394
|
+
col_offset=token.start[1],
|
|
395
|
+
args=(data['python_version'], exc)
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
def _process_core_version(self, token: TokenInfo, data: dict[str, str]) -> None:
|
|
399
|
+
try:
|
|
400
|
+
if ANSIBLE_VERSION >= LooseVersion(data['core_version']):
|
|
401
|
+
self.add_message(
|
|
402
|
+
'ansible-deprecated-version-comment',
|
|
403
|
+
line=token.start[0],
|
|
404
|
+
col_offset=token.start[1],
|
|
405
|
+
args=(
|
|
406
|
+
data['core_version'],
|
|
407
|
+
data['description'] or 'description not provided',
|
|
408
|
+
)
|
|
409
|
+
)
|
|
410
|
+
except (ValueError, TypeError) as exc:
|
|
411
|
+
self.add_message(
|
|
412
|
+
'ansible-deprecated-version-comment-invalid-version',
|
|
413
|
+
line=token.start[0],
|
|
414
|
+
col_offset=token.start[1],
|
|
415
|
+
args=(data['core_version'], exc)
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
def _process_comment(self, token: TokenInfo) -> None:
|
|
419
|
+
if token.string.startswith('# deprecated:'):
|
|
420
|
+
data = self._deprecated_string_to_dict(token, token.string[13:].strip())
|
|
421
|
+
if data['core_version']:
|
|
422
|
+
self._process_core_version(token, data)
|
|
423
|
+
if data['python_version']:
|
|
424
|
+
self._process_python_version(token, data)
|
|
425
|
+
|
|
426
|
+
|
|
266
427
|
def register(linter):
|
|
267
428
|
"""required method to auto register this checker """
|
|
268
429
|
linter.register_checker(AnsibleDeprecatedChecker(linter))
|
|
430
|
+
linter.register_checker(AnsibleDeprecatedCommentChecker(linter))
|
|
@@ -5,10 +5,21 @@
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
7
|
import astroid
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
# support pylint 2.x and 3.x -- remove when supporting only 3.x
|
|
10
|
+
try:
|
|
11
|
+
from pylint.interfaces import IAstroidChecker
|
|
12
|
+
except ImportError:
|
|
13
|
+
class IAstroidChecker:
|
|
14
|
+
"""Backwards compatibility for 2.x / 3.x support."""
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
from pylint.checkers.utils import check_messages
|
|
18
|
+
except ImportError:
|
|
19
|
+
from pylint.checkers.utils import only_required_for_messages as check_messages
|
|
20
|
+
|
|
9
21
|
from pylint.checkers import BaseChecker
|
|
10
22
|
from pylint.checkers import utils
|
|
11
|
-
from pylint.checkers.utils import check_messages
|
|
12
23
|
|
|
13
24
|
MSGS = {
|
|
14
25
|
'E9305': ("disabled", # kept for backwards compatibility with inline ignores, remove after 2.14 is EOL
|
|
@@ -6,8 +6,14 @@ import typing as t
|
|
|
6
6
|
|
|
7
7
|
import astroid
|
|
8
8
|
|
|
9
|
+
# support pylint 2.x and 3.x -- remove when supporting only 3.x
|
|
10
|
+
try:
|
|
11
|
+
from pylint.interfaces import IAstroidChecker
|
|
12
|
+
except ImportError:
|
|
13
|
+
class IAstroidChecker:
|
|
14
|
+
"""Backwards compatibility for 2.x / 3.x support."""
|
|
15
|
+
|
|
9
16
|
from pylint.checkers import BaseChecker
|
|
10
|
-
from pylint.interfaces import IAstroidChecker
|
|
11
17
|
|
|
12
18
|
ANSIBLE_TEST_MODULES_PATH = os.environ['ANSIBLE_TEST_MODULES_PATH']
|
|
13
19
|
ANSIBLE_TEST_MODULE_UTILS_PATH = os.environ['ANSIBLE_TEST_MODULE_UTILS_PATH']
|
|
@@ -808,22 +808,22 @@ class ModuleValidator(Validator):
|
|
|
808
808
|
continue
|
|
809
809
|
|
|
810
810
|
if grandchild.id == 'DOCUMENTATION':
|
|
811
|
-
docs['DOCUMENTATION']['value'] = child.value.
|
|
811
|
+
docs['DOCUMENTATION']['value'] = child.value.value
|
|
812
812
|
docs['DOCUMENTATION']['lineno'] = child.lineno
|
|
813
813
|
docs['DOCUMENTATION']['end_lineno'] = (
|
|
814
|
-
child.lineno + len(child.value.
|
|
814
|
+
child.lineno + len(child.value.value.splitlines())
|
|
815
815
|
)
|
|
816
816
|
elif grandchild.id == 'EXAMPLES':
|
|
817
|
-
docs['EXAMPLES']['value'] = child.value.
|
|
817
|
+
docs['EXAMPLES']['value'] = child.value.value
|
|
818
818
|
docs['EXAMPLES']['lineno'] = child.lineno
|
|
819
819
|
docs['EXAMPLES']['end_lineno'] = (
|
|
820
|
-
child.lineno + len(child.value.
|
|
820
|
+
child.lineno + len(child.value.value.splitlines())
|
|
821
821
|
)
|
|
822
822
|
elif grandchild.id == 'RETURN':
|
|
823
|
-
docs['RETURN']['value'] = child.value.
|
|
823
|
+
docs['RETURN']['value'] = child.value.value
|
|
824
824
|
docs['RETURN']['lineno'] = child.lineno
|
|
825
825
|
docs['RETURN']['end_lineno'] = (
|
|
826
|
-
child.lineno + len(child.value.
|
|
826
|
+
child.lineno + len(child.value.value.splitlines())
|
|
827
827
|
)
|
|
828
828
|
|
|
829
829
|
return docs
|
|
@@ -29,7 +29,7 @@ from contextlib import contextmanager
|
|
|
29
29
|
from ansible.executor.powershell.module_manifest import PSModuleDepFinder
|
|
30
30
|
from ansible.module_utils.basic import FILE_COMMON_ARGUMENTS, AnsibleModule
|
|
31
31
|
from ansible.module_utils.six import reraise
|
|
32
|
-
from ansible.module_utils.
|
|
32
|
+
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
|
33
33
|
|
|
34
34
|
from .utils import CaptureStd, find_executable, get_module_name_from_filename
|
|
35
35
|
|
|
@@ -28,7 +28,7 @@ from io import BytesIO, TextIOWrapper
|
|
|
28
28
|
import yaml
|
|
29
29
|
import yaml.reader
|
|
30
30
|
|
|
31
|
-
from ansible.module_utils.
|
|
31
|
+
from ansible.module_utils.common.text.converters import to_text
|
|
32
32
|
from ansible.module_utils.basic import AnsibleModule
|
|
33
33
|
from ansible.module_utils.common.yaml import SafeLoader
|
|
34
34
|
from ansible.module_utils.six import string_types
|
|
@@ -181,15 +181,15 @@ class YamlChecker:
|
|
|
181
181
|
if doc_types and target.id not in doc_types:
|
|
182
182
|
continue
|
|
183
183
|
|
|
184
|
-
fmt_match = fmt_re.match(statement.value.
|
|
184
|
+
fmt_match = fmt_re.match(statement.value.value.lstrip())
|
|
185
185
|
fmt = 'yaml'
|
|
186
186
|
if fmt_match:
|
|
187
187
|
fmt = fmt_match.group(1)
|
|
188
188
|
|
|
189
189
|
docs[target.id] = dict(
|
|
190
|
-
yaml=statement.value.
|
|
190
|
+
yaml=statement.value.value,
|
|
191
191
|
lineno=statement.lineno,
|
|
192
|
-
end_lineno=statement.lineno + len(statement.value.
|
|
192
|
+
end_lineno=statement.lineno + len(statement.value.value.splitlines()),
|
|
193
193
|
fmt=fmt.lower(),
|
|
194
194
|
)
|
|
195
195
|
|
|
@@ -50,7 +50,7 @@ def read_manifest_json(collection_path):
|
|
|
50
50
|
)
|
|
51
51
|
validate_version(result['version'])
|
|
52
52
|
except Exception as ex: # pylint: disable=broad-except
|
|
53
|
-
raise Exception('{0}: {1}'.format(os.path.basename(manifest_path), ex))
|
|
53
|
+
raise Exception('{0}: {1}'.format(os.path.basename(manifest_path), ex)) from None
|
|
54
54
|
|
|
55
55
|
return result
|
|
56
56
|
|
|
@@ -71,7 +71,7 @@ def read_galaxy_yml(collection_path):
|
|
|
71
71
|
)
|
|
72
72
|
validate_version(result['version'])
|
|
73
73
|
except Exception as ex: # pylint: disable=broad-except
|
|
74
|
-
raise Exception('{0}: {1}'.format(os.path.basename(galaxy_path), ex))
|
|
74
|
+
raise Exception('{0}: {1}'.format(os.path.basename(galaxy_path), ex)) from None
|
|
75
75
|
|
|
76
76
|
return result
|
|
77
77
|
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""Run each test in its own fork. PYTEST_DONT_REWRITE"""
|
|
2
|
+
# MIT License (see licenses/MIT-license.txt or https://opensource.org/licenses/MIT)
|
|
3
|
+
# Based on code originally from:
|
|
4
|
+
# https://github.com/pytest-dev/pytest-forked
|
|
5
|
+
# https://github.com/pytest-dev/py
|
|
6
|
+
# TIP: Disable pytest-xdist when debugging internal errors in this plugin.
|
|
7
|
+
from __future__ import absolute_import, division, print_function
|
|
8
|
+
|
|
9
|
+
__metaclass__ = type
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import pickle
|
|
13
|
+
import tempfile
|
|
14
|
+
import warnings
|
|
15
|
+
|
|
16
|
+
from pytest import Item, hookimpl
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
from pytest import TestReport
|
|
20
|
+
except ImportError:
|
|
21
|
+
from _pytest.runner import TestReport # Backwards compatibility with pytest < 7. Remove once Python 2.7 is not supported.
|
|
22
|
+
|
|
23
|
+
from _pytest.runner import runtestprotocol
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@hookimpl(tryfirst=True)
|
|
27
|
+
def pytest_runtest_protocol(item, nextitem): # type: (Item, Item | None) -> object | None
|
|
28
|
+
"""Entry point for enabling this plugin."""
|
|
29
|
+
# This is needed because pytest-xdist creates an OS thread (using execnet).
|
|
30
|
+
# See: https://github.com/pytest-dev/execnet/blob/d6aa1a56773c2e887515d63e50b1d08338cb78a7/execnet/gateway_base.py#L51
|
|
31
|
+
warnings.filterwarnings("ignore", "^This process .* is multi-threaded, use of .* may lead to deadlocks in the child.$", DeprecationWarning)
|
|
32
|
+
|
|
33
|
+
item_hook = item.ihook
|
|
34
|
+
item_hook.pytest_runtest_logstart(nodeid=item.nodeid, location=item.location)
|
|
35
|
+
|
|
36
|
+
reports = run_item(item, nextitem)
|
|
37
|
+
|
|
38
|
+
for report in reports:
|
|
39
|
+
item_hook.pytest_runtest_logreport(report=report)
|
|
40
|
+
|
|
41
|
+
item_hook.pytest_runtest_logfinish(nodeid=item.nodeid, location=item.location)
|
|
42
|
+
|
|
43
|
+
return True
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def run_item(item, nextitem): # type: (Item, Item | None) -> list[TestReport]
|
|
47
|
+
"""Run the item in a child process and return a list of reports."""
|
|
48
|
+
with tempfile.NamedTemporaryFile() as temp_file:
|
|
49
|
+
pid = os.fork()
|
|
50
|
+
|
|
51
|
+
if not pid:
|
|
52
|
+
temp_file.delete = False
|
|
53
|
+
run_child(item, nextitem, temp_file.name)
|
|
54
|
+
|
|
55
|
+
return run_parent(item, pid, temp_file.name)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def run_child(item, nextitem, result_path): # type: (Item, Item | None, str) -> None
|
|
59
|
+
"""Run the item, record the result and exit. Called in the child process."""
|
|
60
|
+
with warnings.catch_warnings(record=True) as captured_warnings:
|
|
61
|
+
reports = runtestprotocol(item, nextitem=nextitem, log=False)
|
|
62
|
+
|
|
63
|
+
with open(result_path, "wb") as result_file:
|
|
64
|
+
pickle.dump((reports, captured_warnings), result_file)
|
|
65
|
+
|
|
66
|
+
os._exit(0) # noqa
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def run_parent(item, pid, result_path): # type: (Item, int, str) -> list[TestReport]
|
|
70
|
+
"""Wait for the child process to exit and return the test reports. Called in the parent process."""
|
|
71
|
+
exit_code = waitstatus_to_exitcode(os.waitpid(pid, 0)[1])
|
|
72
|
+
|
|
73
|
+
if exit_code:
|
|
74
|
+
reason = "Test CRASHED with exit code {}.".format(exit_code)
|
|
75
|
+
report = TestReport(item.nodeid, item.location, {x: 1 for x in item.keywords}, "failed", reason, "call", user_properties=item.user_properties)
|
|
76
|
+
|
|
77
|
+
if item.get_closest_marker("xfail"):
|
|
78
|
+
report.outcome = "skipped"
|
|
79
|
+
report.wasxfail = reason
|
|
80
|
+
|
|
81
|
+
reports = [report]
|
|
82
|
+
else:
|
|
83
|
+
with open(result_path, "rb") as result_file:
|
|
84
|
+
reports, captured_warnings = pickle.load(result_file) # type: list[TestReport], list[warnings.WarningMessage]
|
|
85
|
+
|
|
86
|
+
for warning in captured_warnings:
|
|
87
|
+
warnings.warn_explicit(warning.message, warning.category, warning.filename, warning.lineno)
|
|
88
|
+
|
|
89
|
+
return reports
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def waitstatus_to_exitcode(status): # type: (int) -> int
|
|
93
|
+
"""Convert a wait status to an exit code."""
|
|
94
|
+
# This function was added in Python 3.9.
|
|
95
|
+
# See: https://docs.python.org/3/library/os.html#os.waitstatus_to_exitcode
|
|
96
|
+
|
|
97
|
+
if os.WIFEXITED(status):
|
|
98
|
+
return os.WEXITSTATUS(status)
|
|
99
|
+
|
|
100
|
+
if os.WIFSIGNALED(status):
|
|
101
|
+
return -os.WTERMSIG(status)
|
|
102
|
+
|
|
103
|
+
raise ValueError(status)
|
|
@@ -552,14 +552,6 @@ def main():
|
|
|
552
552
|
"Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography,"
|
|
553
553
|
" and will be removed in the next release.")
|
|
554
554
|
|
|
555
|
-
if sys.version_info[:2] == (3, 5):
|
|
556
|
-
warnings.filterwarnings(
|
|
557
|
-
"ignore",
|
|
558
|
-
"Python 3.5 support will be dropped in the next release ofcryptography. Please upgrade your Python.")
|
|
559
|
-
warnings.filterwarnings(
|
|
560
|
-
"ignore",
|
|
561
|
-
"Python 3.5 support will be dropped in the next release of cryptography. Please upgrade your Python.")
|
|
562
|
-
|
|
563
555
|
try:
|
|
564
556
|
yield
|
|
565
557
|
finally:
|
|
@@ -53,7 +53,7 @@ install_pip() {
|
|
|
53
53
|
pip_bootstrap_url="https://ci-files.testing.ansible.com/ansible-test/get-pip-20.3.4.py"
|
|
54
54
|
;;
|
|
55
55
|
*)
|
|
56
|
-
pip_bootstrap_url="https://ci-files.testing.ansible.com/ansible-test/get-pip-
|
|
56
|
+
pip_bootstrap_url="https://ci-files.testing.ansible.com/ansible-test/get-pip-23.1.2.py"
|
|
57
57
|
;;
|
|
58
58
|
esac
|
|
59
59
|
|
|
@@ -163,8 +163,6 @@ bootstrap_remote_freebsd()
|
|
|
163
163
|
# Declare platform/python version combinations which do not have supporting OS packages available.
|
|
164
164
|
# For these combinations ansible-test will use pip to install the requirements instead.
|
|
165
165
|
case "${platform_version}/${python_version}" in
|
|
166
|
-
"12.4/3.9")
|
|
167
|
-
;;
|
|
168
166
|
*)
|
|
169
167
|
jinja2_pkg="" # not available
|
|
170
168
|
cryptography_pkg="" # not available
|
|
@@ -261,7 +259,7 @@ bootstrap_remote_rhel_8()
|
|
|
261
259
|
if [ "${python_version}" = "3.6" ]; then
|
|
262
260
|
py_pkg_prefix="python3"
|
|
263
261
|
else
|
|
264
|
-
py_pkg_prefix="python${
|
|
262
|
+
py_pkg_prefix="python${python_version}"
|
|
265
263
|
fi
|
|
266
264
|
|
|
267
265
|
packages="
|
|
@@ -269,6 +267,14 @@ bootstrap_remote_rhel_8()
|
|
|
269
267
|
${py_pkg_prefix}-devel
|
|
270
268
|
"
|
|
271
269
|
|
|
270
|
+
# pip isn't included in the Python devel package under Python 3.11
|
|
271
|
+
if [ "${python_version}" != "3.6" ]; then
|
|
272
|
+
packages="
|
|
273
|
+
${packages}
|
|
274
|
+
${py_pkg_prefix}-pip
|
|
275
|
+
"
|
|
276
|
+
fi
|
|
277
|
+
|
|
272
278
|
# Jinja2 is not installed with an OS package since the provided version is too old.
|
|
273
279
|
# Instead, ansible-test will install it using pip.
|
|
274
280
|
if [ "${controller}" ]; then
|
|
@@ -278,9 +284,19 @@ bootstrap_remote_rhel_8()
|
|
|
278
284
|
"
|
|
279
285
|
fi
|
|
280
286
|
|
|
287
|
+
# Python 3.11 isn't a module like the earlier versions
|
|
288
|
+
if [ "${python_version}" = "3.6" ]; then
|
|
289
|
+
while true; do
|
|
290
|
+
# shellcheck disable=SC2086
|
|
291
|
+
yum module install -q -y "python${python_package_version}" \
|
|
292
|
+
&& break
|
|
293
|
+
echo "Failed to install packages. Sleeping before trying again..."
|
|
294
|
+
sleep 10
|
|
295
|
+
done
|
|
296
|
+
fi
|
|
297
|
+
|
|
281
298
|
while true; do
|
|
282
299
|
# shellcheck disable=SC2086
|
|
283
|
-
yum module install -q -y "python${python_package_version}" && \
|
|
284
300
|
yum install -q -y ${packages} \
|
|
285
301
|
&& break
|
|
286
302
|
echo "Failed to install packages. Sleeping before trying again..."
|
|
@@ -292,22 +308,34 @@ bootstrap_remote_rhel_8()
|
|
|
292
308
|
|
|
293
309
|
bootstrap_remote_rhel_9()
|
|
294
310
|
{
|
|
295
|
-
|
|
311
|
+
if [ "${python_version}" = "3.9" ]; then
|
|
312
|
+
py_pkg_prefix="python3"
|
|
313
|
+
else
|
|
314
|
+
py_pkg_prefix="python${python_version}"
|
|
315
|
+
fi
|
|
296
316
|
|
|
297
317
|
packages="
|
|
298
318
|
gcc
|
|
299
319
|
${py_pkg_prefix}-devel
|
|
300
320
|
"
|
|
301
321
|
|
|
322
|
+
# pip is not included in the Python devel package under Python 3.11
|
|
323
|
+
if [ "${python_version}" != "3.9" ]; then
|
|
324
|
+
packages="
|
|
325
|
+
${packages}
|
|
326
|
+
${py_pkg_prefix}-pip
|
|
327
|
+
"
|
|
328
|
+
fi
|
|
329
|
+
|
|
302
330
|
# Jinja2 is not installed with an OS package since the provided version is too old.
|
|
303
331
|
# Instead, ansible-test will install it using pip.
|
|
332
|
+
# packaging and resolvelib are missing for Python 3.11 (and possible later) so we just
|
|
333
|
+
# skip them and let ansible-test install them from PyPI.
|
|
304
334
|
if [ "${controller}" ]; then
|
|
305
335
|
packages="
|
|
306
336
|
${packages}
|
|
307
337
|
${py_pkg_prefix}-cryptography
|
|
308
|
-
${py_pkg_prefix}-packaging
|
|
309
338
|
${py_pkg_prefix}-pyyaml
|
|
310
|
-
${py_pkg_prefix}-resolvelib
|
|
311
339
|
"
|
|
312
340
|
fi
|
|
313
341
|
|
|
@@ -387,14 +415,6 @@ bootstrap_remote_ubuntu()
|
|
|
387
415
|
echo "Failed to install packages. Sleeping before trying again..."
|
|
388
416
|
sleep 10
|
|
389
417
|
done
|
|
390
|
-
|
|
391
|
-
if [ "${controller}" ]; then
|
|
392
|
-
if [ "${platform_version}/${python_version}" = "20.04/3.9" ]; then
|
|
393
|
-
# Install pyyaml using pip so libyaml support is available on Python 3.9.
|
|
394
|
-
# The OS package install (which is installed by default) only has a .so file for Python 3.8.
|
|
395
|
-
pip_install "--upgrade pyyaml"
|
|
396
|
-
fi
|
|
397
|
-
fi
|
|
398
418
|
}
|
|
399
419
|
|
|
400
420
|
bootstrap_docker()
|
|
@@ -27,10 +27,6 @@ WARNING_MESSAGE_FILTERS = (
|
|
|
27
27
|
# pip 21.0 will drop support for Python 2.7 in January 2021.
|
|
28
28
|
# More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
|
|
29
29
|
'DEPRECATION: Python 2.7 reached the end of its life ',
|
|
30
|
-
|
|
31
|
-
# DEPRECATION: Python 3.5 reached the end of its life on September 13th, 2020. Please upgrade your Python as Python 3.5 is no longer maintained.
|
|
32
|
-
# pip 21.0 will drop support for Python 3.5 in January 2021. pip 21.0 will remove support for this functionality.
|
|
33
|
-
'DEPRECATION: Python 3.5 reached the end of its life ',
|
|
34
30
|
)
|
|
35
31
|
|
|
36
32
|
|