ansible-core 2.19.3rc1__py3-none-any.whl → 2.20.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.

Files changed (201) hide show
  1. ansible/_internal/__init__.py +1 -4
  2. ansible/_internal/_ansiballz/_builder.py +1 -3
  3. ansible/_internal/_collection_proxy.py +7 -9
  4. ansible/_internal/_json/__init__.py +3 -4
  5. ansible/_internal/_templating/_engine.py +1 -1
  6. ansible/_internal/_templating/_jinja_plugins.py +1 -2
  7. ansible/_internal/_wrapt.py +105 -301
  8. ansible/cli/__init__.py +11 -10
  9. ansible/cli/adhoc.py +1 -2
  10. ansible/cli/arguments/option_helpers.py +1 -1
  11. ansible/cli/config.py +5 -6
  12. ansible/cli/doc.py +70 -68
  13. ansible/cli/galaxy.py +15 -24
  14. ansible/cli/inventory.py +0 -1
  15. ansible/cli/playbook.py +0 -1
  16. ansible/cli/pull.py +0 -1
  17. ansible/cli/scripts/ansible_connection_cli_stub.py +1 -1
  18. ansible/collections/list.py +4 -2
  19. ansible/config/base.yml +1 -25
  20. ansible/config/manager.py +0 -2
  21. ansible/executor/play_iterator.py +42 -20
  22. ansible/executor/playbook_executor.py +0 -9
  23. ansible/executor/task_executor.py +26 -18
  24. ansible/executor/task_queue_manager.py +1 -3
  25. ansible/galaxy/api.py +33 -80
  26. ansible/galaxy/collection/__init__.py +4 -17
  27. ansible/galaxy/dependency_resolution/dataclasses.py +0 -10
  28. ansible/galaxy/dependency_resolution/providers.py +24 -118
  29. ansible/galaxy/role.py +1 -33
  30. ansible/inventory/manager.py +2 -3
  31. ansible/keyword_desc.yml +0 -3
  32. ansible/module_utils/_internal/_datatag/__init__.py +2 -10
  33. ansible/module_utils/_internal/_no_six.py +86 -0
  34. ansible/module_utils/_text.py +28 -8
  35. ansible/module_utils/ansible_release.py +2 -2
  36. ansible/module_utils/basic.py +26 -23
  37. ansible/module_utils/common/_collections_compat.py +11 -2
  38. ansible/module_utils/common/collections.py +8 -3
  39. ansible/module_utils/common/dict_transformations.py +1 -2
  40. ansible/module_utils/common/network.py +4 -2
  41. ansible/module_utils/common/parameters.py +32 -41
  42. ansible/module_utils/common/text/converters.py +109 -23
  43. ansible/module_utils/common/text/formatters.py +6 -2
  44. ansible/module_utils/common/validation.py +11 -9
  45. ansible/module_utils/connection.py +8 -3
  46. ansible/module_utils/facts/hardware/linux.py +23 -7
  47. ansible/module_utils/facts/hardware/netbsd.py +1 -1
  48. ansible/module_utils/facts/hardware/sunos.py +2 -1
  49. ansible/module_utils/facts/packages.py +6 -2
  50. ansible/module_utils/facts/system/distribution.py +2 -1
  51. ansible/module_utils/facts/system/env.py +6 -3
  52. ansible/module_utils/facts/system/local.py +3 -1
  53. ansible/module_utils/parsing/convert_bool.py +6 -2
  54. ansible/module_utils/service.py +2 -3
  55. ansible/module_utils/six/__init__.py +19 -6
  56. ansible/module_utils/yumdnf.py +0 -5
  57. ansible/modules/apt.py +18 -13
  58. ansible/modules/apt_repository.py +1 -1
  59. ansible/modules/assemble.py +5 -9
  60. ansible/modules/blockinfile.py +39 -23
  61. ansible/modules/cron.py +26 -35
  62. ansible/modules/deb822_repository.py +83 -12
  63. ansible/modules/dnf.py +3 -7
  64. ansible/modules/dnf5.py +4 -6
  65. ansible/modules/expect.py +0 -3
  66. ansible/modules/find.py +1 -2
  67. ansible/modules/get_url.py +1 -1
  68. ansible/modules/git.py +4 -5
  69. ansible/modules/include_vars.py +1 -1
  70. ansible/modules/known_hosts.py +7 -1
  71. ansible/modules/lineinfile.py +71 -63
  72. ansible/modules/package_facts.py +1 -1
  73. ansible/modules/pip.py +8 -2
  74. ansible/modules/replace.py +6 -6
  75. ansible/modules/service.py +3 -4
  76. ansible/modules/stat.py +20 -0
  77. ansible/modules/uri.py +9 -10
  78. ansible/modules/user.py +1 -2
  79. ansible/modules/wait_for.py +2 -2
  80. ansible/modules/wait_for_connection.py +2 -1
  81. ansible/modules/yum_repository.py +1 -16
  82. ansible/parsing/dataloader.py +24 -31
  83. ansible/parsing/mod_args.py +3 -0
  84. ansible/parsing/vault/__init__.py +1 -2
  85. ansible/playbook/base.py +8 -56
  86. ansible/playbook/block.py +1 -63
  87. ansible/playbook/collectionsearch.py +1 -2
  88. ansible/playbook/handler.py +1 -7
  89. ansible/playbook/helpers.py +15 -20
  90. ansible/playbook/included_file.py +1 -1
  91. ansible/playbook/play.py +105 -49
  92. ansible/playbook/play_context.py +4 -0
  93. ansible/playbook/role/__init__.py +10 -65
  94. ansible/playbook/role/definition.py +3 -4
  95. ansible/playbook/role/include.py +2 -3
  96. ansible/playbook/role/metadata.py +1 -12
  97. ansible/playbook/role/requirement.py +1 -2
  98. ansible/playbook/role_include.py +1 -2
  99. ansible/playbook/taggable.py +16 -5
  100. ansible/playbook/task.py +51 -55
  101. ansible/plugins/action/__init__.py +20 -19
  102. ansible/plugins/action/add_host.py +1 -2
  103. ansible/plugins/action/fetch.py +3 -5
  104. ansible/plugins/action/group_by.py +1 -2
  105. ansible/plugins/action/include_vars.py +20 -22
  106. ansible/plugins/action/script.py +1 -3
  107. ansible/plugins/action/template.py +1 -2
  108. ansible/plugins/action/uri.py +4 -2
  109. ansible/plugins/cache/__init__.py +1 -0
  110. ansible/plugins/callback/__init__.py +13 -6
  111. ansible/plugins/connection/__init__.py +3 -7
  112. ansible/plugins/connection/local.py +2 -3
  113. ansible/plugins/connection/psrp.py +0 -2
  114. ansible/plugins/connection/ssh.py +2 -7
  115. ansible/plugins/connection/winrm.py +0 -2
  116. ansible/plugins/doc_fragments/result_format_callback.py +15 -0
  117. ansible/plugins/filter/core.py +4 -5
  118. ansible/plugins/filter/encryption.py +3 -27
  119. ansible/plugins/filter/mathstuff.py +1 -2
  120. ansible/plugins/filter/to_nice_yaml.yml +31 -3
  121. ansible/plugins/filter/to_yaml.yml +29 -12
  122. ansible/plugins/inventory/__init__.py +1 -2
  123. ansible/plugins/inventory/toml.py +3 -6
  124. ansible/plugins/inventory/yaml.py +1 -2
  125. ansible/plugins/loader.py +3 -4
  126. ansible/plugins/lookup/password.py +1 -2
  127. ansible/plugins/lookup/subelements.py +2 -3
  128. ansible/plugins/lookup/url.py +1 -1
  129. ansible/plugins/lookup/varnames.py +1 -2
  130. ansible/plugins/shell/__init__.py +9 -4
  131. ansible/plugins/shell/powershell.py +8 -24
  132. ansible/plugins/strategy/__init__.py +6 -3
  133. ansible/plugins/test/core.py +4 -1
  134. ansible/plugins/test/falsy.yml +1 -1
  135. ansible/plugins/test/regex.yml +18 -6
  136. ansible/plugins/test/truthy.yml +1 -1
  137. ansible/release.py +2 -2
  138. ansible/template/__init__.py +3 -7
  139. ansible/utils/collection_loader/_collection_config.py +5 -0
  140. ansible/utils/collection_loader/_collection_finder.py +11 -14
  141. ansible/utils/context_objects.py +7 -4
  142. ansible/utils/display.py +7 -6
  143. ansible/utils/encrypt.py +0 -5
  144. ansible/utils/helpers.py +6 -2
  145. ansible/utils/jsonrpc.py +7 -3
  146. ansible/utils/plugin_docs.py +49 -38
  147. ansible/utils/ssh_functions.py +0 -19
  148. ansible/utils/unsafe_proxy.py +7 -7
  149. ansible/vars/clean.py +2 -3
  150. ansible/vars/manager.py +28 -22
  151. ansible/vars/plugins.py +1 -31
  152. {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/METADATA +3 -3
  153. {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/RECORD +199 -200
  154. ansible_test/_data/completion/docker.txt +7 -7
  155. ansible_test/_data/completion/network.txt +0 -1
  156. ansible_test/_data/completion/remote.txt +4 -4
  157. ansible_test/_data/requirements/ansible-test.txt +1 -1
  158. ansible_test/_data/requirements/sanity.changelog.txt +1 -1
  159. ansible_test/_data/requirements/sanity.pep8.txt +1 -1
  160. ansible_test/_data/requirements/sanity.pylint.txt +4 -4
  161. ansible_test/_internal/cache.py +2 -5
  162. ansible_test/_internal/cli/compat.py +1 -1
  163. ansible_test/_internal/commands/coverage/combine.py +1 -3
  164. ansible_test/_internal/commands/integration/__init__.py +3 -7
  165. ansible_test/_internal/commands/integration/cloud/httptester.py +1 -1
  166. ansible_test/_internal/commands/integration/coverage.py +1 -3
  167. ansible_test/_internal/commands/integration/filters.py +5 -10
  168. ansible_test/_internal/commands/sanity/validate_modules.py +1 -5
  169. ansible_test/_internal/commands/units/__init__.py +1 -13
  170. ansible_test/_internal/completion.py +2 -5
  171. ansible_test/_internal/config.py +2 -7
  172. ansible_test/_internal/coverage_util.py +1 -1
  173. ansible_test/_internal/delegation.py +2 -0
  174. ansible_test/_internal/docker_util.py +1 -1
  175. ansible_test/_internal/host_profiles.py +6 -11
  176. ansible_test/_internal/provider/__init__.py +2 -5
  177. ansible_test/_internal/provisioning.py +2 -5
  178. ansible_test/_internal/pypi_proxy.py +1 -1
  179. ansible_test/_internal/target.py +2 -6
  180. ansible_test/_internal/thread.py +1 -4
  181. ansible_test/_internal/util.py +9 -14
  182. ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +14 -19
  183. ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +40 -27
  184. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +31 -18
  185. ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +1 -2
  186. ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +59 -71
  187. ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -2
  188. ansible_test/_util/target/cli/ansible_test_cli_stub.py +4 -2
  189. ansible_test/_util/target/common/constants.py +2 -2
  190. ansible_test/_util/target/setup/bootstrap.sh +0 -6
  191. ansible/utils/py3compat.py +0 -27
  192. ansible_test/_data/pytest/config/legacy.ini +0 -4
  193. {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/WHEEL +0 -0
  194. {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/entry_points.txt +0 -0
  195. {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/licenses/COPYING +0 -0
  196. {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/licenses/licenses/Apache-License.txt +0 -0
  197. {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/licenses/licenses/BSD-3-Clause.txt +0 -0
  198. {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/licenses/licenses/MIT-license.txt +0 -0
  199. {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/licenses/licenses/PSF-license.txt +0 -0
  200. {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
  201. {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/top_level.txt +0 -0
@@ -5,6 +5,7 @@
5
5
 
6
6
  from __future__ import annotations
7
7
 
8
+ import collections.abc as _c
8
9
  import functools
9
10
  import typing as t
10
11
 
@@ -24,7 +25,6 @@ from ansible.galaxy.dependency_resolution.versioning import (
24
25
  is_pre_release,
25
26
  meets_requirements,
26
27
  )
27
- from ansible.module_utils.six import string_types
28
28
  from ansible.utils.version import SemanticVersion, LooseVersion
29
29
 
30
30
  try:
@@ -38,16 +38,16 @@ except ImportError:
38
38
 
39
39
 
40
40
  # TODO: add python requirements to ansible-test's ansible-core distribution info and remove the hardcoded lowerbound/upperbound fallback
41
- RESOLVELIB_LOWERBOUND = SemanticVersion("0.5.3")
41
+ RESOLVELIB_LOWERBOUND = SemanticVersion("0.8.0")
42
42
  RESOLVELIB_UPPERBOUND = SemanticVersion("2.0.0")
43
43
  RESOLVELIB_VERSION = SemanticVersion.from_loose_version(LooseVersion(resolvelib_version))
44
44
 
45
45
 
46
- class CollectionDependencyProviderBase(AbstractProvider):
46
+ class CollectionDependencyProvider(AbstractProvider):
47
47
  """Delegate providing a requirement interface for the resolver."""
48
48
 
49
49
  def __init__(
50
- self, # type: CollectionDependencyProviderBase
50
+ self,
51
51
  apis, # type: MultiGalaxyAPIProxy
52
52
  concrete_artifacts_manager=None, # type: ConcreteArtifactsManager
53
53
  preferred_candidates=None, # type: t.Iterable[Candidate]
@@ -103,8 +103,14 @@ class CollectionDependencyProviderBase(AbstractProvider):
103
103
  """
104
104
  return requirement_or_candidate.canonical_package_id
105
105
 
106
- def get_preference(self, *args, **kwargs):
107
- # type: (t.Any, t.Any) -> t.Union[float, int]
106
+ def get_preference(
107
+ self,
108
+ identifier: str,
109
+ resolutions: _c.Mapping[str, Candidate],
110
+ candidates: _c.Mapping[str, _c.Iterator[Candidate]],
111
+ information: _c.Iterator[t.NamedTuple],
112
+ backtrack_causes: _c.Sequence,
113
+ ) -> float | int:
108
114
  """Return sort key function return value for given requirement.
109
115
 
110
116
  This result should be based on preference that is defined as
@@ -112,38 +118,6 @@ class CollectionDependencyProviderBase(AbstractProvider):
112
118
  The lower the return value is, the more preferred this
113
119
  group of arguments is.
114
120
 
115
- resolvelib >=0.5.3, <0.7.0
116
-
117
- :param resolution: Currently pinned candidate, or ``None``.
118
-
119
- :param candidates: A list of possible candidates.
120
-
121
- :param information: A list of requirement information.
122
-
123
- Each ``information`` instance is a named tuple with two entries:
124
-
125
- * ``requirement`` specifies a requirement contributing to
126
- the current candidate list
127
-
128
- * ``parent`` specifies the candidate that provides
129
- (depended on) the requirement, or `None`
130
- to indicate a root requirement.
131
-
132
- resolvelib >=0.7.0, < 0.8.0
133
-
134
- :param identifier: The value returned by ``identify()``.
135
-
136
- :param resolutions: Mapping of identifier, candidate pairs.
137
-
138
- :param candidates: Possible candidates for the identifier.
139
- Mapping of identifier, list of candidate pairs.
140
-
141
- :param information: Requirement information of each package.
142
- Mapping of identifier, list of named tuple pairs.
143
- The named tuples have the entries ``requirement`` and ``parent``.
144
-
145
- resolvelib >=0.8.0, <= 1.0.1
146
-
147
121
  :param identifier: The value returned by ``identify()``.
148
122
 
149
123
  :param resolutions: Mapping of identifier, candidate pairs.
@@ -179,10 +153,6 @@ class CollectionDependencyProviderBase(AbstractProvider):
179
153
  the value is, the more preferred this requirement is (i.e. the
180
154
  sorting function is called with ``reverse=False``).
181
155
  """
182
- raise NotImplementedError
183
-
184
- def _get_preference(self, candidates):
185
- # type: (list[Candidate]) -> t.Union[float, int]
186
156
  if any(
187
157
  candidate in self._preferred_candidates
188
158
  for candidate in candidates
@@ -192,8 +162,12 @@ class CollectionDependencyProviderBase(AbstractProvider):
192
162
  return float('-inf')
193
163
  return len(candidates)
194
164
 
195
- def find_matches(self, *args, **kwargs):
196
- # type: (t.Any, t.Any) -> list[Candidate]
165
+ def find_matches(
166
+ self,
167
+ identifier: str,
168
+ requirements: _c.Mapping[str, _c.Iterator[Requirement]],
169
+ incompatibilities: _c.Mapping[str, _c.Iterator[Candidate]],
170
+ ) -> list[Candidate]:
197
171
  r"""Find all possible candidates satisfying given requirements.
198
172
 
199
173
  This tries to get candidates based on the requirements' types.
@@ -204,32 +178,13 @@ class CollectionDependencyProviderBase(AbstractProvider):
204
178
  For a "named" requirement, Galaxy-compatible APIs are consulted
205
179
  to find concrete candidates for this requirement. If there's a
206
180
  pre-installed candidate, it's prepended in front of others.
207
-
208
- resolvelib >=0.5.3, <0.6.0
209
-
210
- :param requirements: A collection of requirements which all of \
211
- the returned candidates must match. \
212
- All requirements are guaranteed to have \
213
- the same identifier. \
214
- The collection is never empty.
215
-
216
- resolvelib >=0.6.0
217
-
218
- :param identifier: The value returned by ``identify()``.
219
-
220
- :param requirements: The requirements all returned candidates must satisfy.
221
- Mapping of identifier, iterator of requirement pairs.
222
-
223
- :param incompatibilities: Incompatible versions that must be excluded
224
- from the returned list.
225
-
226
- :returns: An iterable that orders candidates by preference, \
227
- e.g. the most preferred candidate comes first.
228
181
  """
229
- raise NotImplementedError
182
+ return [
183
+ match for match in self._find_matches(list(requirements[identifier]))
184
+ if not any(match.ver == incompat.ver for incompat in incompatibilities[identifier])
185
+ ]
230
186
 
231
- def _find_matches(self, requirements):
232
- # type: (list[Requirement]) -> list[Candidate]
187
+ def _find_matches(self, requirements: list[Requirement]) -> list[Candidate]:
233
188
  # FIXME: The first requirement may be a Git repo followed by
234
189
  # FIXME: its cloned tmp dir. Using only the first one creates
235
190
  # FIXME: loops that prevent any further dependency exploration.
@@ -278,7 +233,7 @@ class CollectionDependencyProviderBase(AbstractProvider):
278
233
  # NOTE: Another known mistake is setting a minor part of the SemVer notation
279
234
  # NOTE: skipping the "patch" bit like "1.0" which is assumed non-compliant even
280
235
  # NOTE: after the conversion to string.
281
- if not isinstance(version, string_types):
236
+ if not isinstance(version, str):
282
237
  raise ValueError(version_err)
283
238
  elif version != '*':
284
239
  try:
@@ -457,52 +412,3 @@ class CollectionDependencyProviderBase(AbstractProvider):
457
412
  self._make_req_from_dict({'name': dep_name, 'version': dep_req})
458
413
  for dep_name, dep_req in req_map.items()
459
414
  ]
460
-
461
-
462
- # Classes to handle resolvelib API changes between minor versions for 0.X
463
- class CollectionDependencyProvider050(CollectionDependencyProviderBase):
464
- def find_matches(self, requirements): # type: ignore[override]
465
- # type: (list[Requirement]) -> list[Candidate]
466
- return self._find_matches(requirements)
467
-
468
- def get_preference(self, resolution, candidates, information): # type: ignore[override]
469
- # type: (t.Optional[Candidate], list[Candidate], list[t.NamedTuple]) -> t.Union[float, int]
470
- return self._get_preference(candidates)
471
-
472
-
473
- class CollectionDependencyProvider060(CollectionDependencyProviderBase):
474
- def find_matches(self, identifier, requirements, incompatibilities): # type: ignore[override]
475
- # type: (str, t.Mapping[str, t.Iterator[Requirement]], t.Mapping[str, t.Iterator[Requirement]]) -> list[Candidate]
476
- return [
477
- match for match in self._find_matches(list(requirements[identifier]))
478
- if not any(match.ver == incompat.ver for incompat in incompatibilities[identifier])
479
- ]
480
-
481
- def get_preference(self, resolution, candidates, information): # type: ignore[override]
482
- # type: (t.Optional[Candidate], list[Candidate], list[t.NamedTuple]) -> t.Union[float, int]
483
- return self._get_preference(candidates)
484
-
485
-
486
- class CollectionDependencyProvider070(CollectionDependencyProvider060):
487
- def get_preference(self, identifier, resolutions, candidates, information): # type: ignore[override]
488
- # type: (str, t.Mapping[str, Candidate], t.Mapping[str, t.Iterator[Candidate]], t.Iterator[t.NamedTuple]) -> t.Union[float, int]
489
- return self._get_preference(list(candidates[identifier]))
490
-
491
-
492
- class CollectionDependencyProvider080(CollectionDependencyProvider060):
493
- def get_preference(self, identifier, resolutions, candidates, information, backtrack_causes): # type: ignore[override]
494
- # type: (str, t.Mapping[str, Candidate], t.Mapping[str, t.Iterator[Candidate]], t.Iterator[t.NamedTuple], t.Sequence) -> t.Union[float, int]
495
- return self._get_preference(list(candidates[identifier]))
496
-
497
-
498
- def _get_provider(): # type () -> CollectionDependencyProviderBase
499
- if RESOLVELIB_VERSION >= SemanticVersion("0.8.0"):
500
- return CollectionDependencyProvider080
501
- if RESOLVELIB_VERSION >= SemanticVersion("0.7.0"):
502
- return CollectionDependencyProvider070
503
- if RESOLVELIB_VERSION >= SemanticVersion("0.6.0"):
504
- return CollectionDependencyProvider060
505
- return CollectionDependencyProvider050
506
-
507
-
508
- CollectionDependencyProvider = _get_provider()
ansible/galaxy/role.py CHANGED
@@ -23,7 +23,6 @@ from __future__ import annotations
23
23
 
24
24
  import errno
25
25
  import datetime
26
- import functools
27
26
  import os
28
27
  import tarfile
29
28
  import tempfile
@@ -46,32 +45,6 @@ from ansible.utils.path import is_subpath, unfrackpath
46
45
  display = Display()
47
46
 
48
47
 
49
- @functools.cache
50
- def _check_working_data_filter() -> bool:
51
- """
52
- Check if tarfile.data_filter implementation is working
53
- for the current Python version or not
54
- """
55
-
56
- # Implemented the following code to circumvent broken implementation of data_filter
57
- # in tarfile. See for more information - https://github.com/python/cpython/issues/107845
58
- # deprecated: description='probing broken data filter implementation' python_version='3.11'
59
- ret = False
60
- if hasattr(tarfile, 'data_filter'):
61
- # We explicitly check if tarfile.data_filter is broken or not
62
- ti = tarfile.TarInfo('docs/README.md')
63
- ti.type = tarfile.SYMTYPE
64
- ti.linkname = '../README.md'
65
-
66
- try:
67
- tarfile.data_filter(ti, '/foo')
68
- except tarfile.LinkOutsideDestinationError:
69
- pass
70
- else:
71
- ret = True
72
- return ret
73
-
74
-
75
48
  class GalaxyRole(object):
76
49
 
77
50
  SUPPORTED_SCMS = set(['git', 'hg'])
@@ -418,12 +391,7 @@ class GalaxyRole(object):
418
391
  relative_path = os.path.join(*full_path.replace(relative_path_dir, "", 1).split(os.sep))
419
392
  setattr(member, attr, relative_path)
420
393
 
421
- if _check_working_data_filter():
422
- # deprecated: description='extract fallback without filter' python_version='3.11'
423
- role_tar_file.extract(member, to_native(self.path), filter='data') # type: ignore[call-arg]
424
- else:
425
- # Remove along with manual path filter once Python 3.12 is minimum supported version
426
- role_tar_file.extract(member, to_native(self.path))
394
+ role_tar_file.extract(member, to_native(self.path), filter='data')
427
395
 
428
396
  # write out the install info file for later use
429
397
  self._write_galaxy_install_info()
@@ -33,7 +33,6 @@ from ansible._internal import _json, _wrapt
33
33
  from ansible._internal._json import EncryptedStringBehavior
34
34
  from ansible.errors import AnsibleError, AnsibleOptionsError
35
35
  from ansible.inventory.data import InventoryData
36
- from ansible.module_utils.six import string_types
37
36
  from ansible.module_utils.common.text.converters import to_bytes, to_text
38
37
  from ansible.parsing.utils.addresses import parse_address
39
38
  from ansible.plugins.loader import inventory_loader
@@ -112,7 +111,7 @@ def split_host_pattern(pattern):
112
111
  results = (split_host_pattern(p) for p in pattern)
113
112
  # flatten the results
114
113
  return list(itertools.chain.from_iterable(results))
115
- elif not isinstance(pattern, string_types):
114
+ elif not isinstance(pattern, str):
116
115
  pattern = to_text(pattern, errors='surrogate_or_strict')
117
116
 
118
117
  # If it's got commas in it, we'll treat it as a straightforward
@@ -162,7 +161,7 @@ class InventoryManager(object):
162
161
  # the inventory dirs, files, script paths or lists of hosts
163
162
  if sources is None:
164
163
  self._sources = []
165
- elif isinstance(sources, string_types):
164
+ elif isinstance(sources, str):
166
165
  self._sources = [sources]
167
166
  else:
168
167
  self._sources = sources
ansible/keyword_desc.yml CHANGED
@@ -1,6 +1,3 @@
1
- accelerate: "*DEPRECATED*, set to True to use accelerate connection plugin."
2
- accelerate_ipv6: "*DEPRECATED*, set to True to force accelerate plugin to use ipv6 for its connection."
3
- accelerate_port: "*DEPRECATED*, set to override default port use for accelerate connection."
4
1
  action: "The 'action' to execute for a task, it normally translates into a C(module) or action plugin."
5
2
  args: "A secondary way to add arguments into a task. Takes a dictionary in which keys map to options and values."
6
3
  always: List of tasks, in a block, that execute no matter if there is an error in the block or not.
@@ -500,17 +500,9 @@ class AnsibleDatatagBase(AnsibleSerializableDataclass, metaclass=abc.ABCMeta):
500
500
  _known_tag_type_map: t.Dict[str, t.Type[AnsibleDatatagBase]] = {}
501
501
  _known_tag_types: t.Set[t.Type[AnsibleDatatagBase]] = set()
502
502
 
503
- if sys.version_info >= (3, 9):
504
- # Include the key and value types in the type hints on Python 3.9 and later.
505
- # Earlier versions do not support subscriptable dict.
506
- # deprecated: description='always use subscriptable dict' python_version='3.8'
507
- class _AnsibleTagsMapping(dict[type[_TAnsibleDatatagBase], _TAnsibleDatatagBase]):
508
- __slots__ = _NO_INSTANCE_STORAGE
509
503
 
510
- else:
511
-
512
- class _AnsibleTagsMapping(dict):
513
- __slots__ = _NO_INSTANCE_STORAGE
504
+ class _AnsibleTagsMapping(dict[type[_TAnsibleDatatagBase], _TAnsibleDatatagBase]):
505
+ __slots__ = _NO_INSTANCE_STORAGE
514
506
 
515
507
 
516
508
  class _EmptyROInternalTagsMapping(dict):
@@ -0,0 +1,86 @@
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+ import types
5
+
6
+ from ansible.module_utils.common import warnings
7
+
8
+
9
+ # INLINED FROM THE SIX LIBRARY, see lib/ansible/module_utils/six/__init__.py
10
+ # Copyright (c) 2010-2024 Benjamin Peterson
11
+ def with_metaclass(meta, *bases):
12
+ """Create a base class with a metaclass."""
13
+
14
+ # This requires a bit of explanation: the basic idea is to make a dummy
15
+ # metaclass for one level of class instantiation that replaces itself with
16
+ # the actual metaclass.
17
+ class metaclass(type):
18
+
19
+ def __new__(cls, name, this_bases, d):
20
+ if sys.version_info[:2] >= (3, 7):
21
+ # This version introduced PEP 560 that requires a bit
22
+ # of extra care (we mimic what is done by __build_class__).
23
+ resolved_bases = types.resolve_bases(bases)
24
+ if resolved_bases is not bases:
25
+ d['__orig_bases__'] = bases
26
+ else:
27
+ resolved_bases = bases
28
+ return meta(name, resolved_bases, d)
29
+
30
+ @classmethod
31
+ def __prepare__(cls, name, this_bases):
32
+ return meta.__prepare__(name, bases)
33
+
34
+ return type.__new__(metaclass, 'temporary_class', (), {})
35
+
36
+
37
+ def add_metaclass(metaclass):
38
+ """Class decorator for creating a class with a metaclass."""
39
+
40
+ def wrapper(cls):
41
+ orig_vars = cls.__dict__.copy()
42
+ slots = orig_vars.get('__slots__')
43
+ if slots is not None:
44
+ if isinstance(slots, str):
45
+ slots = [slots]
46
+ for slots_var in slots:
47
+ orig_vars.pop(slots_var)
48
+ orig_vars.pop('__dict__', None)
49
+ orig_vars.pop('__weakref__', None)
50
+ if hasattr(cls, '__qualname__'):
51
+ orig_vars['__qualname__'] = cls.__qualname__
52
+ return metaclass(cls.__name__, cls.__bases__, orig_vars)
53
+
54
+ return wrapper
55
+
56
+
57
+ def iteritems(d, **kw):
58
+ return iter(d.items(**kw))
59
+
60
+
61
+ _mini_six = {
62
+ "PY2": False,
63
+ "PY3": True,
64
+ "text_type": str,
65
+ "binary_type": bytes,
66
+ "string_types": (str,),
67
+ "integer_types": (int,),
68
+ "iteritems": iteritems,
69
+ "add_metaclass": add_metaclass,
70
+ "with_metaclass": with_metaclass,
71
+ }
72
+ # INLINED SIX END
73
+
74
+
75
+ def deprecate(importable_name: str, module_name: str, *deprecated_args) -> object:
76
+ """Inject import-time deprecation warnings."""
77
+ if not (importable_name in deprecated_args and (importable := _mini_six.get(importable_name, ...) is not ...)):
78
+ raise AttributeError(f"module {module_name!r} has no attribute {importable_name!r}")
79
+
80
+ # TODO Inspect and remove all calls to this function in 2.24
81
+ warnings.deprecate(
82
+ msg=f"Importing {importable_name!r} from {module_name!r} is deprecated.",
83
+ version="2.24",
84
+ )
85
+
86
+ return importable
@@ -1,15 +1,35 @@
1
1
  # Copyright (c), Toshio Kuratomi <tkuratomi@ansible.com> 2016
2
2
  # Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
3
3
 
4
- """
5
- .. warn:: Use ansible.module_utils.common.text.converters instead.
6
- """
7
4
  from __future__ import annotations
8
5
 
9
- # Backwards compat for people still calling it from this package
10
- # pylint: disable=unused-import
11
- import codecs
6
+ from ansible.module_utils.common import warnings as _warnings
12
7
 
13
- from ansible.module_utils.six import PY3, text_type, binary_type
14
8
 
15
- from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
9
+ _mini_six = {
10
+ "binary_type": bytes,
11
+ "text_type": str,
12
+ "PY3": True,
13
+ }
14
+
15
+
16
+ def __getattr__(importable_name: str) -> object:
17
+ """Inject import-time deprecation warnings."""
18
+ help_text: str | None = None
19
+ importable: object
20
+ if importable_name == "codecs":
21
+ import codecs
22
+ importable = codecs
23
+ elif importable_name in {"to_bytes", "to_native", "to_text"}:
24
+ from ansible.module_utils.common.text import converters
25
+ importable = getattr(converters, importable_name)
26
+ help_text = "Use ansible.module_utils.common.text.converters instead."
27
+ elif (importable := _mini_six.get(importable_name, ...)) is ...:
28
+ raise AttributeError(f"module {__name__!r} has no attribute {importable_name!r}")
29
+
30
+ _warnings.deprecate(
31
+ msg=f"Importing {importable_name!r} from {__name__!r} is deprecated.",
32
+ version="2.24",
33
+ help_text=help_text,
34
+ )
35
+ return importable
@@ -17,6 +17,6 @@
17
17
 
18
18
  from __future__ import annotations
19
19
 
20
- __version__ = '2.19.3rc1'
20
+ __version__ = '2.20.0b2'
21
21
  __author__ = 'Ansible, Inc.'
22
- __codename__ = "What Is and What Should Never Be"
22
+ __codename__ = "Good Times Bad Times"
@@ -11,12 +11,13 @@ import typing as t
11
11
 
12
12
  # Used for determining if the system is running a new enough python version
13
13
  # and should only restrict on our documented minimum versions
14
- _PY_MIN = (3, 8)
14
+ _PY_MIN = (3, 9)
15
15
 
16
16
  if sys.version_info < _PY_MIN:
17
17
  print(json.dumps(dict(
18
18
  failed=True,
19
- msg=f"ansible-core requires a minimum of Python version {'.'.join(map(str, _PY_MIN))}. Current version: {''.join(sys.version.splitlines())}",
19
+ msg=f"Ansible requires Python {'.'.join(map(str, _PY_MIN))} or newer on the target. "
20
+ f"Current version: {''.join(sys.version.splitlines())}",
20
21
  )))
21
22
  sys.exit(1)
22
23
 
@@ -45,6 +46,15 @@ import tempfile
45
46
  import time
46
47
  import traceback
47
48
 
49
+ from collections.abc import (
50
+ KeysView,
51
+ Mapping,
52
+ MutableMapping,
53
+ Sequence,
54
+ MutableSequence,
55
+ Set,
56
+ MutableSet,
57
+ )
48
58
  from functools import reduce
49
59
 
50
60
  try:
@@ -122,13 +132,6 @@ def _get_available_hash_algorithms():
122
132
  AVAILABLE_HASH_ALGORITHMS = _get_available_hash_algorithms()
123
133
 
124
134
  from ansible.module_utils.common import json as _json
125
-
126
- from ansible.module_utils.six.moves.collections_abc import (
127
- KeysView,
128
- Mapping, MutableMapping,
129
- Sequence, MutableSequence,
130
- Set, MutableSet,
131
- )
132
135
  from ansible.module_utils.common.locale import get_best_parsable_locale
133
136
  from ansible.module_utils.common.process import get_bin_path
134
137
  from ansible.module_utils.common.file import (
@@ -2185,6 +2188,18 @@ def get_module_path():
2185
2188
  return os.path.dirname(os.path.realpath(__file__))
2186
2189
 
2187
2190
 
2191
+ _mini_six = {
2192
+ "b": lambda s: s.encode("latin-1"),
2193
+ "PY2": False,
2194
+ "PY3": True,
2195
+ "text_type": str,
2196
+ "binary_type": bytes,
2197
+ "string_types": (str,),
2198
+ "integer_types": (int,),
2199
+ "iteritems": lambda d, **kw: iter(d.items(**kw)),
2200
+ }
2201
+
2202
+
2188
2203
  def __getattr__(importable_name):
2189
2204
  """Inject import-time deprecation warnings."""
2190
2205
  if importable_name == 'datetime':
@@ -2202,24 +2217,12 @@ def __getattr__(importable_name):
2202
2217
  elif importable_name == 'repeat':
2203
2218
  from itertools import repeat
2204
2219
  importable = repeat
2205
- elif importable_name in {
2206
- 'PY2', 'PY3', 'b', 'binary_type', 'integer_types',
2207
- 'iteritems', 'string_types', 'text_type',
2208
- }:
2209
- import importlib
2210
- importable = getattr(
2211
- importlib.import_module('ansible.module_utils.six'),
2212
- importable_name
2213
- )
2214
2220
  elif importable_name == 'map':
2215
2221
  importable = map
2216
2222
  elif importable_name == 'shlex_quote':
2217
2223
  importable = shlex.quote
2218
- else:
2219
- raise AttributeError(
2220
- f'cannot import name {importable_name !r} '
2221
- f"from '{__name__}' ({__file__ !s})"
2222
- )
2224
+ elif (importable := _mini_six.get(importable_name, ...)) is ...:
2225
+ raise AttributeError(f"module {__name__!r} has no attribute {importable_name!r}")
2223
2226
 
2224
2227
  deprecate(
2225
2228
  msg=f"Importing '{importable_name}' from '{__name__}' is deprecated.",
@@ -2,7 +2,7 @@
2
2
  # Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
3
3
  """Collections ABC import shim.
4
4
 
5
- Use `ansible.module_utils.six.moves.collections_abc` instead, which has been available since ansible-core 2.11.
5
+ Use `collections.abc` instead.
6
6
  This module exists only for backwards compatibility.
7
7
  """
8
8
 
@@ -10,7 +10,7 @@ from __future__ import annotations
10
10
 
11
11
  # Although this was originally intended for internal use only, it has wide adoption in collections.
12
12
  # This is due in part to sanity tests previously recommending its use over `collections` imports.
13
- from ansible.module_utils.six.moves.collections_abc import ( # pylint: disable=unused-import
13
+ from collections.abc import ( # pylint: disable=unused-import
14
14
  MappingView,
15
15
  ItemsView,
16
16
  KeysView,
@@ -25,3 +25,12 @@ from ansible.module_utils.six.moves.collections_abc import ( # pylint: disable=
25
25
  Iterable,
26
26
  Iterator,
27
27
  )
28
+
29
+ from ansible.module_utils.common import warnings as _warnings
30
+
31
+
32
+ _warnings.deprecate(
33
+ msg="The `ansible.module_utils.common._collections_compat` module is deprecated.",
34
+ help_text="Use `collections.abc` from the Python standard library instead.",
35
+ version="2.24",
36
+ )
@@ -6,9 +6,10 @@
6
6
  from __future__ import annotations
7
7
 
8
8
 
9
+ from collections.abc import Hashable, Mapping, MutableMapping, Sequence # pylint: disable=unused-import
10
+
11
+ from ansible.module_utils._internal import _no_six
9
12
  from ansible.module_utils.common import warnings as _warnings
10
- from ansible.module_utils.six import binary_type, text_type
11
- from ansible.module_utils.six.moves.collections_abc import Hashable, Mapping, MutableMapping, Sequence # pylint: disable=unused-import
12
13
 
13
14
 
14
15
  class ImmutableDict(Hashable, Mapping):
@@ -67,7 +68,7 @@ class ImmutableDict(Hashable, Mapping):
67
68
 
68
69
  def is_string(seq):
69
70
  """Identify whether the input has a string-like type (including bytes)."""
70
- return isinstance(seq, (text_type, binary_type))
71
+ return isinstance(seq, (str, bytes))
71
72
 
72
73
 
73
74
  def is_iterable(seq, include_strings=False):
@@ -114,3 +115,7 @@ def count(seq):
114
115
  for elem in seq:
115
116
  counters[elem] = counters.get(elem, 0) + 1
116
117
  return counters
118
+
119
+
120
+ def __getattr__(importable_name):
121
+ return _no_six.deprecate(importable_name, __name__, "binary_type", "text_type")
@@ -7,10 +7,9 @@ from __future__ import annotations
7
7
 
8
8
 
9
9
  import re
10
+ from collections.abc import MutableMapping
10
11
  from copy import deepcopy
11
12
 
12
- from ansible.module_utils.six.moves.collections_abc import MutableMapping
13
-
14
13
 
15
14
  def camel_dict_to_snake_dict(camel_dict, reversible=False, ignore_list=()):
16
15
  """
@@ -6,11 +6,13 @@
6
6
  from __future__ import annotations
7
7
 
8
8
  import re
9
+
10
+ # backward compat
11
+ from builtins import zip # pylint: disable=unused-import
12
+
9
13
  from struct import pack
10
14
  from socket import inet_ntoa
11
15
 
12
- from ansible.module_utils.six.moves import zip
13
-
14
16
 
15
17
  VALID_MASKS = [2**8 - 2**i for i in range(0, 9)]
16
18