ansible-core 2.19.0b7__py3-none-any.whl → 2.19.0rc1__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.
Files changed (30) hide show
  1. ansible/_internal/_json/__init__.py +31 -20
  2. ansible/_internal/_json/_profiles/_legacy.py +1 -1
  3. ansible/_internal/_templating/_jinja_bits.py +31 -14
  4. ansible/_internal/_templating/_jinja_plugins.py +5 -2
  5. ansible/_internal/_templating/_utils.py +2 -1
  6. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +9 -0
  7. ansible/cli/_ssh_askpass.py +37 -30
  8. ansible/cli/console.py +1 -1
  9. ansible/executor/module_common.py +1 -1
  10. ansible/module_utils/_internal/_datatag/__init__.py +6 -1
  11. ansible/module_utils/ansible_release.py +1 -1
  12. ansible/modules/systemd.py +1 -1
  13. ansible/modules/systemd_service.py +1 -1
  14. ansible/playbook/playbook_include.py +0 -1
  15. ansible/playbook/role/__init__.py +2 -2
  16. ansible/plugins/connection/ssh.py +12 -5
  17. ansible/release.py +1 -1
  18. ansible/utils/vars.py +2 -1
  19. {ansible_core-2.19.0b7.dist-info → ansible_core-2.19.0rc1.dist-info}/METADATA +1 -1
  20. {ansible_core-2.19.0b7.dist-info → ansible_core-2.19.0rc1.dist-info}/RECORD +30 -30
  21. ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +2 -1
  22. {ansible_core-2.19.0b7.dist-info → ansible_core-2.19.0rc1.dist-info}/WHEEL +0 -0
  23. {ansible_core-2.19.0b7.dist-info → ansible_core-2.19.0rc1.dist-info}/entry_points.txt +0 -0
  24. {ansible_core-2.19.0b7.dist-info → ansible_core-2.19.0rc1.dist-info}/licenses/COPYING +0 -0
  25. {ansible_core-2.19.0b7.dist-info → ansible_core-2.19.0rc1.dist-info}/licenses/licenses/Apache-License.txt +0 -0
  26. {ansible_core-2.19.0b7.dist-info → ansible_core-2.19.0rc1.dist-info}/licenses/licenses/BSD-3-Clause.txt +0 -0
  27. {ansible_core-2.19.0b7.dist-info → ansible_core-2.19.0rc1.dist-info}/licenses/licenses/MIT-license.txt +0 -0
  28. {ansible_core-2.19.0b7.dist-info → ansible_core-2.19.0rc1.dist-info}/licenses/licenses/PSF-license.txt +0 -0
  29. {ansible_core-2.19.0b7.dist-info → ansible_core-2.19.0rc1.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
  30. {ansible_core-2.19.0b7.dist-info → ansible_core-2.19.0rc1.dist-info}/top_level.txt +0 -0
@@ -81,6 +81,7 @@ class AnsibleVariableVisitor:
81
81
  convert_custom_scalars: bool = False,
82
82
  convert_to_native_values: bool = False,
83
83
  apply_transforms: bool = False,
84
+ visit_keys: bool = False,
84
85
  encrypted_string_behavior: EncryptedStringBehavior = EncryptedStringBehavior.DECRYPT,
85
86
  ):
86
87
  super().__init__() # supports StateTrackingMixIn
@@ -92,6 +93,7 @@ class AnsibleVariableVisitor:
92
93
  self.convert_custom_scalars = convert_custom_scalars
93
94
  self.convert_to_native_values = convert_to_native_values
94
95
  self.apply_transforms = apply_transforms
96
+ self.visit_keys = visit_keys
95
97
  self.encrypted_string_behavior = encrypted_string_behavior
96
98
 
97
99
  if apply_transforms:
@@ -134,47 +136,55 @@ class AnsibleVariableVisitor:
134
136
 
135
137
  return result
136
138
 
139
+ def _visit_key(self, key: t.Any) -> t.Any:
140
+ """Internal implementation to recursively visit a key if visit_keys is enabled."""
141
+ if not self.visit_keys:
142
+ return key
143
+
144
+ return self._visit(None, key) # key=None prevents state tracking from seeing the key as value
145
+
137
146
  def _visit(self, key: t.Any, value: _T) -> _T:
138
147
  """Internal implementation to recursively visit a data structure's contents."""
139
148
  self._current = key # supports StateTrackingMixIn
140
149
 
141
- value_type = type(value)
150
+ value_type: type = type(value)
142
151
 
143
- if self.apply_transforms and value_type in _transform._type_transform_mapping:
152
+ # handle EncryptedString conversion before more generic transformation and native conversions
153
+ if value_type is EncryptedString: # pylint: disable=unidiomatic-typecheck
154
+ match self.encrypted_string_behavior:
155
+ case EncryptedStringBehavior.DECRYPT:
156
+ value = str(value) # type: ignore[assignment]
157
+ value_type = str
158
+ case EncryptedStringBehavior.REDACT:
159
+ value = "<redacted>" # type: ignore[assignment]
160
+ value_type = str
161
+ case EncryptedStringBehavior.FAIL:
162
+ raise AnsibleVariableTypeError.from_value(obj=value)
163
+ elif self.apply_transforms and value_type in _transform._type_transform_mapping:
144
164
  value = self._template_engine.transform(value)
145
165
  value_type = type(value)
146
166
 
147
- # DTFIX3: need to handle native copy for keys too
148
167
  if self.convert_to_native_values and isinstance(value, _datatag.AnsibleTaggedObject):
149
168
  value = value._native_copy()
150
169
  value_type = type(value)
151
170
 
152
171
  result: _T
153
172
 
154
- # DTFIX3: the visitor is ignoring dict/mapping keys except for debugging and schema-aware checking, it should be doing type checks on keys
155
- # keep in mind the allowed types for keys is a more restrictive set than for values (str and tagged str only, not EncryptedString)
156
- # DTFIX5: some type lists being consulted (the ones from datatag) are probably too permissive, and perhaps should not be dynamic
173
+ # DTFIX-FUTURE: Visitor generally ignores dict/mapping keys by default except for debugging and schema-aware checking.
174
+ # It could be checking keys destined for variable storage to apply more strict rules about key shape and type.
157
175
 
158
176
  if (result := self._early_visit(value, value_type)) is not _sentinel:
159
177
  pass
160
178
  # DTFIX7: de-duplicate and optimize; extract inline generator expressions and fallback function or mapping for native type calculation?
161
179
  elif value_type in _ANSIBLE_ALLOWED_MAPPING_VAR_TYPES: # check mappings first, because they're also collections
162
180
  with self: # supports StateTrackingMixIn
163
- result = AnsibleTagHelper.tag_copy(value, ((k, self._visit(k, v)) for k, v in value.items()), value_type=value_type)
181
+ result = AnsibleTagHelper.tag_copy(value, ((self._visit_key(k), self._visit(k, v)) for k, v in value.items()), value_type=value_type)
164
182
  elif value_type in _ANSIBLE_ALLOWED_NON_SCALAR_COLLECTION_VAR_TYPES:
165
183
  with self: # supports StateTrackingMixIn
166
184
  result = AnsibleTagHelper.tag_copy(value, (self._visit(k, v) for k, v in enumerate(t.cast(t.Iterable, value))), value_type=value_type)
167
- elif self.encrypted_string_behavior != EncryptedStringBehavior.FAIL and isinstance(value, EncryptedString):
168
- match self.encrypted_string_behavior:
169
- case EncryptedStringBehavior.REDACT:
170
- result = "<redacted>" # type: ignore[assignment]
171
- case EncryptedStringBehavior.PRESERVE:
172
- result = value # type: ignore[assignment]
173
- case EncryptedStringBehavior.DECRYPT:
174
- result = str(value) # type: ignore[assignment]
175
185
  elif self.convert_mapping_to_dict and _internal.is_intermediate_mapping(value):
176
186
  with self: # supports StateTrackingMixIn
177
- result = {k: self._visit(k, v) for k, v in value.items()} # type: ignore[assignment]
187
+ result = {self._visit_key(k): self._visit(k, v) for k, v in value.items()} # type: ignore[assignment]
178
188
  elif self.convert_sequence_to_list and _internal.is_intermediate_iterable(value):
179
189
  with self: # supports StateTrackingMixIn
180
190
  result = [self._visit(k, v) for k, v in enumerate(t.cast(t.Iterable, value))] # type: ignore[assignment]
@@ -184,12 +194,13 @@ class AnsibleVariableVisitor:
184
194
  result = float(value) # type: ignore[assignment]
185
195
  elif self.convert_custom_scalars and isinstance(value, int) and not isinstance(value, bool):
186
196
  result = int(value) # type: ignore[assignment]
187
- else:
188
- if value_type not in _ANSIBLE_ALLOWED_VAR_TYPES:
189
- raise AnsibleVariableTypeError.from_value(obj=value)
190
-
197
+ elif value_type in _ANSIBLE_ALLOWED_VAR_TYPES:
191
198
  # supported scalar type that requires no special handling, just return as-is
192
199
  result = value
200
+ elif self.encrypted_string_behavior is EncryptedStringBehavior.PRESERVE and isinstance(value, EncryptedString):
201
+ result = value # type: ignore[assignment]
202
+ else:
203
+ raise AnsibleVariableTypeError.from_value(obj=value)
193
204
 
194
205
  if self.origin and not Origin.is_tagged_on(result):
195
206
  # apply shared instance default origin tag
@@ -1,6 +1,6 @@
1
1
  """
2
2
  Backwards compatibility profile for serialization other than inventory (which should use inventory_legacy for backward-compatible trust behavior).
3
- Behavior is equivalent to pre 2.18 `AnsibleJSONEncoder` with vault_to_text=True.
3
+ Behavior is equivalent to pre 2.19 `AnsibleJSONEncoder` with vault_to_text=True.
4
4
  """
5
5
 
6
6
  from __future__ import annotations as _annotations
@@ -20,7 +20,7 @@ from jinja2.lexer import TOKEN_VARIABLE_BEGIN, TOKEN_VARIABLE_END, TOKEN_STRING,
20
20
  from jinja2.nativetypes import NativeCodeGenerator
21
21
  from jinja2.nodes import Const, EvalContext
22
22
  from jinja2.runtime import Context, Macro
23
- from jinja2.sandbox import ImmutableSandboxedEnvironment
23
+ from jinja2.sandbox import SandboxedEnvironment
24
24
  from jinja2.utils import missing, LRUCache
25
25
 
26
26
  from ansible.utils.display import Display
@@ -518,9 +518,6 @@ def create_template_error(ex: Exception, variable: t.Any, is_expression: bool) -
518
518
  return exception_to_raise
519
519
 
520
520
 
521
- # DTFIX3: implement CapturedExceptionMarker deferral support on call (and lookup), filter/test plugins, etc.
522
- # also update the protomatter integration test once this is done (the test was written differently since this wasn't done yet)
523
-
524
521
  _BUILTIN_FILTER_ALIASES: dict[str, str] = {}
525
522
  _BUILTIN_TEST_ALIASES: dict[str, str] = {
526
523
  '!=': 'ne',
@@ -535,7 +532,7 @@ _BUILTIN_FILTERS = filter_loader._wrap_funcs(defaults.DEFAULT_FILTERS, _BUILTIN_
535
532
  _BUILTIN_TESTS = test_loader._wrap_funcs(t.cast(dict[str, t.Callable], defaults.DEFAULT_TESTS), _BUILTIN_TEST_ALIASES)
536
533
 
537
534
 
538
- class AnsibleEnvironment(ImmutableSandboxedEnvironment):
535
+ class AnsibleEnvironment(SandboxedEnvironment):
539
536
  """
540
537
  Our custom environment, which simply allows us to override the class-level
541
538
  values for the Template and Context classes used by jinja2 internally.
@@ -546,6 +543,21 @@ class AnsibleEnvironment(ImmutableSandboxedEnvironment):
546
543
  code_generator_class = AnsibleCodeGenerator
547
544
  intercepted_binops = frozenset(('eq',))
548
545
 
546
+ _allowed_unsafe_attributes: dict[str, type | tuple[type, ...]] = dict(
547
+ # Allow bitwise operations on int until bitwise filters are available.
548
+ # see: https://github.com/ansible/ansible/issues/85204
549
+ __and__=int,
550
+ __lshift__=int,
551
+ __or__=int,
552
+ __rshift__=int,
553
+ __xor__=int,
554
+ )
555
+ """
556
+ Attributes which are considered unsafe by `is_safe_attribute`, which should be allowed when used on specific types.
557
+ The attributes allowed here are intended only for backward compatibility with existing use cases.
558
+ They should be exposed as filters in a future release and eventually deprecated.
559
+ """
560
+
549
561
  _lexer_cache = LRUCache(50)
550
562
 
551
563
  # DTFIX-FUTURE: bikeshed a name/mechanism to control template debugging
@@ -609,6 +621,9 @@ class AnsibleEnvironment(ImmutableSandboxedEnvironment):
609
621
  if _TemplateConfig.sandbox_mode == _SandboxMode.ALLOW_UNSAFE_ATTRIBUTES:
610
622
  return True
611
623
 
624
+ if (type_or_tuple := self._allowed_unsafe_attributes.get(attr)) and isinstance(obj, type_or_tuple):
625
+ return True
626
+
612
627
  return super().is_safe_attribute(obj, attr, value)
613
628
 
614
629
  @property
@@ -809,18 +824,18 @@ class AnsibleEnvironment(ImmutableSandboxedEnvironment):
809
824
  *args: t.Any,
810
825
  **kwargs: t.Any,
811
826
  ) -> t.Any:
812
- if _DirectCall.is_marked(__obj):
813
- # Both `_lookup` and `_query` handle arg proxying and `Marker` args internally.
814
- # Performing either before calling them will interfere with that processing.
815
- return super().call(__context, __obj, *args, **kwargs)
827
+ try:
828
+ if _DirectCall.is_marked(__obj):
829
+ # Both `_lookup` and `_query` handle arg proxying and `Marker` args internally.
830
+ # Performing either before calling them will interfere with that processing.
831
+ return super().call(__context, __obj, *args, **kwargs)
816
832
 
817
- # Jinja's generated macro code handles Markers, so preemptive raise on Marker args and lazy retrieval should be disabled for the macro invocation.
818
- is_macro = isinstance(__obj, Macro)
833
+ # Jinja's generated macro code handles Markers, so preemptive raise on Marker args and lazy retrieval should be disabled for the macro invocation.
834
+ is_macro = isinstance(__obj, Macro)
819
835
 
820
- if not is_macro and (first_marker := get_first_marker_arg(args, kwargs)) is not None:
821
- return first_marker
836
+ if not is_macro and (first_marker := get_first_marker_arg(args, kwargs)) is not None:
837
+ return first_marker
822
838
 
823
- try:
824
839
  with JinjaCallContext(accept_lazy_markers=is_macro):
825
840
  call_res = super().call(__context, __obj, *lazify_container_args(args), **lazify_container_kwargs(kwargs))
826
841
 
@@ -834,6 +849,8 @@ class AnsibleEnvironment(ImmutableSandboxedEnvironment):
834
849
 
835
850
  except MarkerError as ex:
836
851
  return ex.source
852
+ except Exception as ex:
853
+ return CapturedExceptionMarker(ex)
837
854
 
838
855
 
839
856
  AnsibleTemplate.environment_class = AnsibleEnvironment
@@ -23,7 +23,7 @@ from ansible.utils.display import Display
23
23
 
24
24
  from ._datatag import _JinjaConstTemplate
25
25
  from ._errors import AnsibleTemplatePluginRuntimeError, AnsibleTemplatePluginLoadError, AnsibleTemplatePluginNotFoundError
26
- from ._jinja_common import MarkerError, _TemplateConfig, get_first_marker_arg, Marker, JinjaCallContext
26
+ from ._jinja_common import MarkerError, _TemplateConfig, get_first_marker_arg, Marker, JinjaCallContext, CapturedExceptionMarker
27
27
  from ._lazy_containers import lazify_container_kwargs, lazify_container_args, lazify_container, _AnsibleLazyTemplateMixin
28
28
  from ._utils import LazyOptions, TemplateContext
29
29
 
@@ -119,7 +119,10 @@ class JinjaPluginIntercept(c.MutableMapping):
119
119
  except MarkerError as ex:
120
120
  return ex.source
121
121
  except Exception as ex:
122
- raise AnsibleTemplatePluginRuntimeError(instance.plugin_type, instance.ansible_name) from ex # DTFIX-FUTURE: which name to use? use plugin info?
122
+ try:
123
+ raise AnsibleTemplatePluginRuntimeError(instance.plugin_type, instance.ansible_name) from ex # DTFIX-FUTURE: which name to use? PluginInfo?
124
+ except AnsibleTemplatePluginRuntimeError as captured:
125
+ return CapturedExceptionMarker(captured)
123
126
 
124
127
  def _wrap_test(self, instance: AnsibleJinja2Plugin) -> t.Callable:
125
128
  """Intercept point for all test plugins to ensure that args are properly templated/lazified."""
@@ -99,9 +99,10 @@ Omit = object.__new__(_OmitType)
99
99
  _datatag._untaggable_types.add(_OmitType)
100
100
 
101
101
 
102
- # DTFIX5: review these type sets to ensure they're not overly permissive/dynamic
103
102
  IGNORE_SCALAR_VAR_TYPES = {value for value in _datatag._ANSIBLE_ALLOWED_SCALAR_VAR_TYPES if not issubclass(value, str)}
103
+ """Scalar variable types that short-circuit bypass templating."""
104
104
 
105
105
  PASS_THROUGH_SCALAR_VAR_TYPES = _datatag._ANSIBLE_ALLOWED_SCALAR_VAR_TYPES | {
106
106
  _OmitType, # allow pass through of omit for later handling after top-level finalize completes
107
107
  }
108
+ """Scalar variable types which are allowed to appear in finalized template results."""
@@ -3,12 +3,21 @@ from __future__ import annotations
3
3
  import dataclasses
4
4
  import typing as t
5
5
 
6
+ from ansible.template import accept_args_markers
7
+ from ansible._internal._templating._jinja_common import ExceptionMarker
6
8
 
9
+
10
+ @accept_args_markers
7
11
  def dump_object(value: t.Any) -> object:
8
12
  """Internal filter to convert objects not supported by JSON to types which are."""
9
13
  if dataclasses.is_dataclass(value):
10
14
  return dataclasses.asdict(value) # type: ignore[arg-type]
11
15
 
16
+ if isinstance(value, ExceptionMarker):
17
+ return dict(
18
+ exception=value._as_exception(),
19
+ )
20
+
12
21
  return value
13
22
 
14
23
 
@@ -3,45 +3,52 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import json
6
+ import multiprocessing.resource_tracker
6
7
  import os
7
8
  import re
8
9
  import sys
9
10
  import typing as t
10
- from multiprocessing.shared_memory import SharedMemory
11
11
 
12
- HOST_KEY_RE = re.compile(
13
- r'(The authenticity of host |differs from the key for the IP address)',
14
- )
12
+ from multiprocessing.shared_memory import SharedMemory
15
13
 
16
14
 
17
15
  def main() -> t.Never:
18
- try:
19
- if HOST_KEY_RE.search(sys.argv[1]):
20
- sys.stdout.buffer.write(b'no')
21
- sys.stdout.flush()
22
- sys.exit(0)
23
- except IndexError:
24
- pass
25
-
26
- kwargs: dict[str, bool] = {}
27
- if sys.version_info[:2] >= (3, 13):
28
- # deprecated: description='unneeded due to track argument for SharedMemory' python_version='3.12'
29
- kwargs['track'] = False
30
- try:
31
- shm = SharedMemory(name=os.environ['_ANSIBLE_SSH_ASKPASS_SHM'], **kwargs)
32
- except FileNotFoundError:
33
- # We must be running after the ansible fork is shutting down
34
- sys.exit(1)
16
+ if len(sys.argv) > 1:
17
+ exit_code = 0 if handle_prompt(sys.argv[1]) else 1
18
+ else:
19
+ exit_code = 1
20
+
21
+ sys.exit(exit_code)
22
+
23
+
24
+ def handle_prompt(prompt: str) -> bool:
25
+ if re.search(r'(The authenticity of host |differs from the key for the IP address)', prompt):
26
+ sys.stdout.write('no')
27
+ sys.stdout.flush()
28
+ return True
29
+
30
+ # deprecated: description='Python 3.13 and later support track' python_version='3.12'
31
+ can_track = sys.version_info[:2] >= (3, 13)
32
+ kwargs = dict(track=False) if can_track else {}
33
+
34
+ # This SharedMemory instance is intentionally not closed or unlinked.
35
+ # Closing will occur naturally in the SharedMemory finalizer.
36
+ # Unlinking is the responsibility of the process which created it.
37
+ shm = SharedMemory(name=os.environ['_ANSIBLE_SSH_ASKPASS_SHM'], **kwargs)
38
+
39
+ if not can_track:
40
+ # When track=False is not available, we must unregister explicitly, since it otherwise only occurs during unlink.
41
+ # This avoids resource tracker noise on stderr during process exit.
42
+ multiprocessing.resource_tracker.unregister(shm._name, 'shared_memory')
43
+
35
44
  cfg = json.loads(shm.buf.tobytes().rstrip(b'\x00'))
36
45
 
37
- try:
38
- if cfg['prompt'] not in sys.argv[1]:
39
- sys.exit(1)
40
- except IndexError:
41
- sys.exit(1)
46
+ if cfg['prompt'] not in prompt:
47
+ return False
42
48
 
43
- sys.stdout.buffer.write(cfg['password'].encode('utf-8'))
49
+ # Report the password provided by the SharedMemory instance.
50
+ # The contents are left untouched after consumption to allow subsequent attempts to succeed.
51
+ # This can occur when multiple password prompting methods are enabled, such as password and keyboard-interactive, which is the default on macOS.
52
+ sys.stdout.write(cfg['password'])
44
53
  sys.stdout.flush()
45
- shm.buf[:] = b'\x00' * shm.size
46
- shm.close()
47
- sys.exit(0)
54
+ return True
ansible/cli/console.py CHANGED
@@ -194,7 +194,7 @@ class ConsoleCLI(CLI, cmd.Cmd):
194
194
  result = None
195
195
  try:
196
196
  check_raw = module in C._ACTION_ALLOWS_RAW_ARGS
197
- task = dict(action=dict(module=module, args=parse_kv(module_args, check_raw=check_raw)), timeout=self.task_timeout)
197
+ task = dict(action=module, args=parse_kv(module_args, check_raw=check_raw), timeout=self.task_timeout)
198
198
  play_ds = dict(
199
199
  name="Ansible Shell",
200
200
  hosts=self.cwd,
@@ -954,7 +954,7 @@ class _BuiltModule:
954
954
  class _CachedModule:
955
955
  """Cached Python module created by AnsiballZ."""
956
956
 
957
- # DTFIX5: secure this (locked down pickle, don't use pickle, etc.)
957
+ # FIXME: switch this to use a locked down pickle config or don't use pickle- easy to mess up and reach objects that shouldn't be pickled
958
958
 
959
959
  zip_data: bytes
960
960
  metadata: ModuleMetadata
@@ -949,8 +949,13 @@ This set gets augmented with additional types when some controller-only types ar
949
949
 
950
950
  # noinspection PyProtectedMember
951
951
  _ANSIBLE_ALLOWED_VAR_TYPES = frozenset({type(None), bool}) | set(AnsibleTaggedObject._tagged_type_map) | set(AnsibleTaggedObject._tagged_type_map.values())
952
- """These are the only types supported by Ansible's variable storage. Subclasses are not permitted."""
952
+ """These are the exact types supported by Ansible's variable storage."""
953
953
 
954
954
  _ANSIBLE_ALLOWED_NON_SCALAR_COLLECTION_VAR_TYPES = frozenset(item for item in _ANSIBLE_ALLOWED_VAR_TYPES if is_non_scalar_collection_type(item))
955
+ """These are the exact non-scalar collection types supported by Ansible's variable storage."""
956
+
955
957
  _ANSIBLE_ALLOWED_MAPPING_VAR_TYPES = frozenset(item for item in _ANSIBLE_ALLOWED_VAR_TYPES if issubclass(item, c.Mapping))
958
+ """These are the exact mapping types supported by Ansible's variable storage."""
959
+
956
960
  _ANSIBLE_ALLOWED_SCALAR_VAR_TYPES = _ANSIBLE_ALLOWED_VAR_TYPES - _ANSIBLE_ALLOWED_NON_SCALAR_COLLECTION_VAR_TYPES
961
+ """These are the exact scalar types supported by Ansible's variable storage."""
@@ -17,6 +17,6 @@
17
17
 
18
18
  from __future__ import annotations
19
19
 
20
- __version__ = '2.19.0b7'
20
+ __version__ = '2.19.0rc1'
21
21
  __author__ = 'Ansible, Inc.'
22
22
  __codename__ = "What Is and What Should Never Be"
@@ -34,7 +34,7 @@ options:
34
34
  choices: [ reloaded, restarted, started, stopped ]
35
35
  enabled:
36
36
  description:
37
- - Whether the unit should start on boot. At least one of O(state) and O(enabled) are required.
37
+ - Whether the unit should start on boot. At least one of O(state) or O(enabled) are required.
38
38
  - If set, requires O(name).
39
39
  type: bool
40
40
  force:
@@ -34,7 +34,7 @@ options:
34
34
  choices: [ reloaded, restarted, started, stopped ]
35
35
  enabled:
36
36
  description:
37
- - Whether the unit should start on boot. At least one of O(state) and O(enabled) are required.
37
+ - Whether the unit should start on boot. At least one of O(state) or O(enabled) are required.
38
38
  - If set, requires O(name).
39
39
  type: bool
40
40
  force:
@@ -34,7 +34,6 @@ from ansible import constants as C
34
34
  class PlaybookInclude(Base, Conditional, Taggable):
35
35
 
36
36
  import_playbook = NonInheritableFieldAttribute(isa='string', required=True)
37
- vars_val = NonInheritableFieldAttribute(isa='dict', default=dict, alias='vars')
38
37
 
39
38
  _post_validate_object = True # manually post_validate to get free arg validation/coercion
40
39
 
@@ -374,8 +374,8 @@ class Role(Base, Conditional, Taggable, CollectionSearch, Delegatable):
374
374
  task_name = task_name + ' - ' + argument_spec['short_description']
375
375
 
376
376
  return {
377
- 'action': {
378
- 'module': 'ansible.builtin.validate_argument_spec',
377
+ 'action': 'ansible.builtin.validate_argument_spec',
378
+ 'args': {
379
379
  # Pass only the 'options' portion of the arg spec to the module.
380
380
  'argument_spec': argument_spec.get('options', {}),
381
381
  'provided_arguments': self._role_params,
@@ -640,11 +640,11 @@ def _clean_shm(func):
640
640
  self.shm.close()
641
641
  with contextlib.suppress(FileNotFoundError):
642
642
  self.shm.unlink()
643
- if not _HAS_RESOURCE_TRACK:
644
- # deprecated: description='unneeded due to track argument for SharedMemory' python_version='3.12'
645
- # There is a resource tracking issue where the resource is deleted, but tracking still has a record
646
- # This will effectively overwrite the record and remove it
647
- SharedMemory(name=self.shm.name, create=True, size=1).unlink()
643
+ if not _HAS_RESOURCE_TRACK:
644
+ # deprecated: description='unneeded due to track argument for SharedMemory' python_version='3.12'
645
+ # There is a resource tracking issue where the resource is deleted, but tracking still has a record
646
+ # This will effectively overwrite the record and remove it
647
+ SharedMemory(name=self.shm.name, create=True, size=1).unlink()
648
648
  return ret
649
649
  return inner
650
650
 
@@ -961,6 +961,13 @@ class Connection(ConnectionBase):
961
961
  b_args = (b"-o", b'ControlPath="%s"' % to_bytes(self.control_path % dict(directory=cpdir), errors='surrogate_or_strict'))
962
962
  self._add_args(b_command, b_args, u"found only ControlPersist; added ControlPath")
963
963
 
964
+ if password_mechanism == "ssh_askpass":
965
+ self._add_args(
966
+ b_command,
967
+ (b"-o", b"NumberOfPasswordPrompts=1"),
968
+ "Restrict number of password prompts in case incorrect password is provided.",
969
+ )
970
+
964
971
  # Finally, we add any caller-supplied extras.
965
972
  if other_args:
966
973
  b_command += [to_bytes(a) for a in other_args]
ansible/release.py CHANGED
@@ -17,6 +17,6 @@
17
17
 
18
18
  from __future__ import annotations
19
19
 
20
- __version__ = '2.19.0b7'
20
+ __version__ = '2.19.0rc1'
21
21
  __author__ = 'Ansible, Inc.'
22
22
  __codename__ = "What Is and What Should Never Be"
ansible/utils/vars.py CHANGED
@@ -293,7 +293,7 @@ def validate_variable_name(name: object) -> None:
293
293
  def transform_to_native_types(
294
294
  value: object,
295
295
  redact: bool = True,
296
- ) -> object:
296
+ ) -> t.Any:
297
297
  """
298
298
  Recursively transform the given value to Python native types.
299
299
  Potentially sensitive values such as individually vaulted variables will be redacted unless ``redact=False`` is passed.
@@ -306,6 +306,7 @@ def transform_to_native_types(
306
306
  convert_custom_scalars=True,
307
307
  convert_to_native_values=True,
308
308
  apply_transforms=True,
309
+ visit_keys=True, # ensure that keys are also converted
309
310
  encrypted_string_behavior=_json.EncryptedStringBehavior.REDACT if redact else _json.EncryptedStringBehavior.DECRYPT,
310
311
  )
311
312
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ansible-core
3
- Version: 2.19.0b7
3
+ Version: 2.19.0rc1
4
4
  Summary: Radically simple IT automation
5
5
  Author: Ansible Project
6
6
  Project-URL: Homepage, https://ansible.com/
@@ -3,7 +3,7 @@ ansible/__main__.py,sha256=24j-7-YT4lZ2fmV80JD-VRoYBnxR7YoP_VP-orJtDt0,796
3
3
  ansible/constants.py,sha256=qef45QpHi-yFFMvllvNKmqFpXdKKr304e5fEZnjgwZc,7989
4
4
  ansible/context.py,sha256=oKYyfjfWpy8vDeProtqfnqSmuij_t75_5e5t0U_hQ1g,1933
5
5
  ansible/keyword_desc.yml,sha256=5rGCsr-0B8w2D67qBD6q_2WFxfqj9ieb0V_2J-dZJ5E,7547
6
- ansible/release.py,sha256=dMGjO02KkKxgLMYgYx2uFdFxoeSiG06BB2GysRGLyHM,854
6
+ ansible/release.py,sha256=cmY3ehX6O1d-RO_lV9fseR-8fg1l2e8lO-bdrkkvrp4,855
7
7
  ansible/_internal/__init__.py,sha256=J3yCEAZoJLwxHMPEIWHwX6seRTCQ4Sr7cfHSw11ik9k,2208
8
8
  ansible/_internal/_collection_proxy.py,sha256=V3Zns3jdWR1hTP6q4mrNWoIKL67ayiQFPDOb6F7igsc,1228
9
9
  ansible/_internal/_event_formatting.py,sha256=cHMsuYi6v2W3fgEYdKLSe8O34kW5bZE26zyj7FOt268,4222
@@ -25,12 +25,12 @@ ansible/_internal/_errors/_error_factory.py,sha256=mu5V16XfB9KbrHyo6TfVWtXVkXNA8
25
25
  ansible/_internal/_errors/_error_utils.py,sha256=P8sWdmQxZ4UFJ1jfmRVgkdZ_xDYZ3nDNqIfZNK9yihY,9141
26
26
  ansible/_internal/_errors/_handler.py,sha256=4ZX27G_jrDsomR28OVC0A9WRponpte5V-QGq5ZcDzeE,3455
27
27
  ansible/_internal/_errors/_task_timeout.py,sha256=CN5J2eKa42cyahXC0IMrliwQAF7DMwNvdaJmzSqPBsk,923
28
- ansible/_internal/_json/__init__.py,sha256=X5QL0n8wbgR93jx3TPuQRd_MIfvzASO8ekzTmCRBqac,8796
28
+ ansible/_internal/_json/__init__.py,sha256=zt1caVsiZ8L08bz0dAdfbcY14c4y0-8As8AS9hW5wlo,9282
29
29
  ansible/_internal/_json/_legacy_encoder.py,sha256=clXiPnJ2aR5McuSbajugTPW2wav1wwklivxDKWZ1iFw,1646
30
30
  ansible/_internal/_json/_profiles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
31
  ansible/_internal/_json/_profiles/_cache_persistence.py,sha256=SVTQ59kZiO4YSVqewTz4qcfj-5iROcO5bJrE0DlHei0,1913
32
32
  ansible/_internal/_json/_profiles/_inventory_legacy.py,sha256=UGPOuvu_x3Z1lAvkca36ZRX0v0D1j_FCZd28y5BK_jM,1083
33
- ansible/_internal/_json/_profiles/_legacy.py,sha256=EepGJPeg-Q4o5pGuJkxGEod3Q_qd8zasNH1a1GRo35E,7555
33
+ ansible/_internal/_json/_profiles/_legacy.py,sha256=nDxOGCWLkcFZT3BGeGLtYCKVjmc3W8Gudh3bSVnKj3g,7555
34
34
  ansible/_internal/_plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
35
  ansible/_internal/_plugins/_cache.py,sha256=jwVeVm-ZJJaNqdyq7aS4Zt41C6VKyRO_DdwXaVBXWGc,1989
36
36
  ansible/_internal/_ssh/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -42,15 +42,15 @@ ansible/_internal/_templating/_chain_templar.py,sha256=VArYtkVpa0mZY2AhSL_Re2McP
42
42
  ansible/_internal/_templating/_datatag.py,sha256=HuOaYtpmXYZkTDVVVz5lO3E6trowAIp80P2BN-UTyHs,3903
43
43
  ansible/_internal/_templating/_engine.py,sha256=1-674lL9t4B0t93Ny0a9ZklU4bNkFefzNCAhNiFTOew,28155
44
44
  ansible/_internal/_templating/_errors.py,sha256=3dxLGu1NLft-9GDuNKNc1K4OIDaduAzFYkNOYBNAYCI,1302
45
- ansible/_internal/_templating/_jinja_bits.py,sha256=d87AxUcg7zqL32cFrblpMsGKc96fIWrol7CPN0afmEY,47937
45
+ ansible/_internal/_templating/_jinja_bits.py,sha256=LkG0g81V-7-hI53ylV_yPHGTezzvw-XOpL-B0VvL-kc,48568
46
46
  ansible/_internal/_templating/_jinja_common.py,sha256=qgiY2WbNfp6Xj55P-a-208UVFDsFALJMqh_2lMM_Q5k,11761
47
47
  ansible/_internal/_templating/_jinja_patches.py,sha256=O_1GHYLEYtu1f2g0iSb3GDBrQMk1Qbh43H4CUEP9wcE,1412
48
- ansible/_internal/_templating/_jinja_plugins.py,sha256=BJUipK95fR61IHIx3dqmq6JZdbBGifItMeT979ocKEs,16146
48
+ ansible/_internal/_templating/_jinja_plugins.py,sha256=bR_6EgqBeN2DXFygy-eEfLIFCNfKpsSaKIUqkHE3Cb8,16310
49
49
  ansible/_internal/_templating/_lazy_containers.py,sha256=dq7jPLtHJ42mNarYmROc2GES3IFQB2X-eIxp6HQtj5M,27159
50
50
  ansible/_internal/_templating/_marker_behaviors.py,sha256=EPQwotuBRagad5k9rGALlfCSV-CbNGXY6oA-DPp6dJ4,3439
51
51
  ansible/_internal/_templating/_template_vars.py,sha256=nQODzE_SeCYFuGpdUoEI6b3saJSddDVWCiOtY8n6ouY,2585
52
52
  ansible/_internal/_templating/_transform.py,sha256=07wo45Epm-ZvwgIEWjeFi4W3LHJUEXbDzXq4JWziq3s,2747
53
- ansible/_internal/_templating/_utils.py,sha256=7DYmkWZ4kInyeoLjLne9DR1LmOzDg_Dz0x3HkB6oxWE,3711
53
+ ansible/_internal/_templating/_utils.py,sha256=5raq0rENRluOjusegdsHDnnOKbeplNqGq600fzjKkxw,3783
54
54
  ansible/_internal/_yaml/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
55
  ansible/_internal/_yaml/_constructor.py,sha256=8T8MGiopbRJf8vUIBPFzQXqOlmvioeyFLFar0fV6GUE,9843
56
56
  ansible/_internal/_yaml/_dumper.py,sha256=FywWfP1DDYI7JoeNLUPpLUOMhzF50Mm4A8GEBaruRYE,2601
@@ -59,7 +59,7 @@ ansible/_internal/_yaml/_loader.py,sha256=h6pGkmFV8cYLrQKJExL0FkVcGHXN2uoCMmJX2S
59
59
  ansible/_internal/ansible_collections/ansible/_protomatter/README.md,sha256=IyejgfHj83nAH19YDcLC391EbcxRzGkVR-67-zkxnIA,612
60
60
  ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py,sha256=Hpdd8wDpE5N0UbqQbCZUVGFpyw01LDvmMG4R7uP27GQ,1469
61
61
  ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py,sha256=70XW_8Nt_5lR_EuuLG7iaKphwc9h_osz98x_S_KTOrY,537
62
- ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py,sha256=23uwaucJS4_xyYXjD3QBNO4Baz_RkQZSAaXZ9idWE70,466
62
+ ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py,sha256=ICUnrzOKm9L0Rx80U099g36wcSDdahAASh8xVSfZQXk,729
63
63
  ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py,sha256=D6jTmkPVQTpqS8OSWfsAe2XPWz7w4zDehaeEpHUrbus,472
64
64
  ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py,sha256=SXak4ieoaVHBL9g2yp2PTWjwKVfgPSrhWPEqjsYT320,429
65
65
  ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py,sha256=jumCgi2BVy80WgAyHMuVGTIqINN11pt1S5bkUJsF-y8,552
@@ -75,10 +75,10 @@ ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_w
75
75
  ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml,sha256=sRbc5UjNAelH023-mXpQ9z_-17i36-7L_0ynKIRb3EM,520
76
76
  ansible/_vendor/__init__.py,sha256=2QBeBwT7uG7M3Aw-pIdCpt6XPtHMCpbEKfACYKA7xIg,2033
77
77
  ansible/cli/__init__.py,sha256=uoA86dcx0QKjppjP3EC-yqIt1rfqtMAlWYO0-IrVX1A,27761
78
- ansible/cli/_ssh_askpass.py,sha256=hzDkbYV82KZHWTjbGCHvnDB3hWeYdwoXt-6kFkrkPHg,1365
78
+ ansible/cli/_ssh_askpass.py,sha256=fKYjoUkAxh1slpKm969wtJxX78zXe57bgLtQDhxMk_Y,2007
79
79
  ansible/cli/adhoc.py,sha256=nIMg7xxrJfnZ5IOyY4pWRb1A40O13mRcH2FII5YbNXY,8408
80
80
  ansible/cli/config.py,sha256=PJ9hQPhPaX4OsJ3Y6B5KOII0b09RieAJRg7-jD3jg3A,28607
81
- ansible/cli/console.py,sha256=NiSif9Fi8lIpI4C8c_eNqbgtY772bvEGXBDdv4wjAyg,22015
81
+ ansible/cli/console.py,sha256=F9jL6C3LTZBBD_0OIanGyM86PfxCSAe-gcvv7bqmt58,22002
82
82
  ansible/cli/doc.py,sha256=aBxvQgf28oMzSqr9CWgno5JkpZz_i8Kp4DO8_QMK9aY,73284
83
83
  ansible/cli/galaxy.py,sha256=ldWsmRxTCN-HXipw1TZvDRJjYLZDPwS_LYIKcEZabqE,95246
84
84
  ansible/cli/inventory.py,sha256=atRek-BmCrBIQqqqJ7SXxU5rZkmnQ4Rv9iKYuo2fdZE,16035
@@ -100,7 +100,7 @@ ansible/config/manager.py,sha256=CC-JhhK4KN07rvXAfiex4sxjFSVtxsLx6E_YnpEOE88,311
100
100
  ansible/errors/__init__.py,sha256=W1s19PaheqXMI2yKnZCuaKKjSAJRPgU1_xF2_J9B1NU,16353
101
101
  ansible/executor/__init__.py,sha256=mRvbCJPA-_veSG5ka3v04G5vsarLVDeB3EWFsu6geSI,749
102
102
  ansible/executor/interpreter_discovery.py,sha256=UWeAxnHknJCci2gG3zt6edx5Nj4WbHYfJVcmW_DzItY,3858
103
- ansible/executor/module_common.py,sha256=43ZXxIm_02oBUsUdHEERFMqn0fCxhPLmTSTuAmIi-K8,60380
103
+ ansible/executor/module_common.py,sha256=sXMOvKj_9ubeBaCPVBHh76uHaRYZm-8mOhsSG55aXQ8,60450
104
104
  ansible/executor/play_iterator.py,sha256=OY0W7x3F7VUQCjWIogkPqhvm7SFnxOXR5anlqJjHeHY,32282
105
105
  ansible/executor/playbook_executor.py,sha256=5wjvqw22RG4g_JlYDQnLFrUEa8aYQBWdgKhEpNonhKQ,14806
106
106
  ansible/executor/stats.py,sha256=Rw-Q73xYvXnYOt-LJFnHAR03NvVR3ESgbMkHnVGhIPI,3180
@@ -211,7 +211,7 @@ ansible/inventory/host.py,sha256=cZw906LeMYe6oF3ZxW6K2HWoW2Qc0jxHssg_C8cRumE,493
211
211
  ansible/inventory/manager.py,sha256=fxg2sq7s-VBJnn9TvJCgv-xvYIu0DLJTix_y3w0wLcc,31811
212
212
  ansible/module_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
213
213
  ansible/module_utils/_text.py,sha256=VkWgAnSNVCbTQqZgllUObBFsH3uM4EUW5srl1UR9t1g,544
214
- ansible/module_utils/ansible_release.py,sha256=dMGjO02KkKxgLMYgYx2uFdFxoeSiG06BB2GysRGLyHM,854
214
+ ansible/module_utils/ansible_release.py,sha256=cmY3ehX6O1d-RO_lV9fseR-8fg1l2e8lO-bdrkkvrp4,855
215
215
  ansible/module_utils/api.py,sha256=8BmCzQtp9rClsLGlDn4I9iJrUFLCdnoEIxYX59_IL9c,5756
216
216
  ansible/module_utils/basic.py,sha256=B3RnxUfoIswGK8-o23kubNqrqHv_9aibfD8LjR3LUYE,89793
217
217
  ansible/module_utils/connection.py,sha256=ZwtQEs-TtT-XecoEmFWiDevSkJLIj348YkiW6PP7G9E,7471
@@ -247,7 +247,7 @@ ansible/module_utils/_internal/_ansiballz/_extensions/_pydevd.py,sha256=Kd6XePQO
247
247
  ansible/module_utils/_internal/_concurrent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
248
248
  ansible/module_utils/_internal/_concurrent/_daemon_threading.py,sha256=okMP5QPoU9YhYMQF31tUJ6ChyiXJHF-6TD9t6nfjKWE,1085
249
249
  ansible/module_utils/_internal/_concurrent/_futures.py,sha256=Y0hpH1QXavZbKDude5Y8oYlxPvOhQarBhTQRc97odVs,936
250
- ansible/module_utils/_internal/_datatag/__init__.py,sha256=UoUnQUbIAMo20H5mZ2rH_nM9eaM4d0nCq2rVjcISJYE,37230
250
+ ansible/module_utils/_internal/_datatag/__init__.py,sha256=Km_sUa4LGwcSlWMOCXMRHvRa5t50WYCeBmMcU-lV2Rg,37459
251
251
  ansible/module_utils/_internal/_datatag/_tags.py,sha256=Rkze_LoP5-BUYsoAJjv5ojcplHsGp6MhwER95HQvRqY,468
252
252
  ansible/module_utils/_internal/_json/__init__.py,sha256=KscFIf_fl3-TTM2fe68MwETHZBCxf83nZrsbVhqkpEM,2181
253
253
  ansible/module_utils/_internal/_json/_legacy_encoder.py,sha256=Qz2WVbgFxprEpP174zrK7LIKEIk_cLwPsh2gbahavKo,1191
@@ -446,8 +446,8 @@ ansible/modules/shell.py,sha256=Wr_K2zrHqnT3Aw4I42FP_-7dBxNAU04OnKzEtxVyQT4,6830
446
446
  ansible/modules/slurp.py,sha256=XwO6kxFmejod2V-OGqk2lmhnK7OCkkFhLEmMcfGChJ0,3064
447
447
  ansible/modules/stat.py,sha256=sqIyBP-Iq4F8mPQUuunGzO6Q6GHrN1-mw7T3ApFF5Eg,18647
448
448
  ansible/modules/subversion.py,sha256=XEhsibJHb5rg_yioveP_c-THxbh0ZMm0d8qApk02MZg,13485
449
- ansible/modules/systemd.py,sha256=ZJ8uKx7xsvTQvmBTl5AyyP4KOBNZcjy5rr0CVH4lw2s,24990
450
- ansible/modules/systemd_service.py,sha256=ZJ8uKx7xsvTQvmBTl5AyyP4KOBNZcjy5rr0CVH4lw2s,24990
449
+ ansible/modules/systemd.py,sha256=x7HSnRWEnY80ROjZ1EHTXTILff-fix5IuEKwvqgd_t4,24989
450
+ ansible/modules/systemd_service.py,sha256=x7HSnRWEnY80ROjZ1EHTXTILff-fix5IuEKwvqgd_t4,24989
451
451
  ansible/modules/sysvinit.py,sha256=Nrs5gLyHKZsqtm_ymFO0e0wB2KSDXYfbDt-uNlgUiF0,13962
452
452
  ansible/modules/tempfile.py,sha256=3ZljXNOu06T5ObTAz5Ktm_WKFrJACHwLf-01F7isf5A,3570
453
453
  ansible/modules/template.py,sha256=y1zu-ZZ0P-Cpxjddzk5V5GVpQNNfQL8E5sVeAb2plR0,4537
@@ -489,12 +489,12 @@ ansible/playbook/loop_control.py,sha256=5rZz6aWXpvvwOD4CzrS_b_cnXIu4Gf56czkomX1N
489
489
  ansible/playbook/notifiable.py,sha256=MQz4VZuOga35VLcdUxVd9FQVzFg-djtQZhs09DS2juA,299
490
490
  ansible/playbook/play.py,sha256=RHxQgshU6c7t8qFCBdZOutdXjRjrWeqWItPJJSw2GJE,17357
491
491
  ansible/playbook/play_context.py,sha256=7tl_ObKgN8guKk6G9R1oSWoFmePDwhEiDHw2eEn78Hk,13673
492
- ansible/playbook/playbook_include.py,sha256=QOaTvcMEdH2INMWuwsVXUxcfIqXRYUcXNL3b2npr1Lo,5599
492
+ ansible/playbook/playbook_include.py,sha256=zTzEsS20DB9hSzRfU9DI4-BsteHwzWVshUF_SoIVVE0,5515
493
493
  ansible/playbook/role_include.py,sha256=DV7num4uVJvkIY4IHgB0uHmE8-gRmaNYbuoqP0-7dTY,7610
494
494
  ansible/playbook/taggable.py,sha256=5ZjDUpuna6UQcfYOr9UYqcfOwDQUVfFN5pLXFved708,3704
495
495
  ansible/playbook/task.py,sha256=LYMW_UEARc1ILIIUM9I_y5zbeyUGUfRddFWwlbW8pno,24567
496
496
  ansible/playbook/task_include.py,sha256=y7jSK7CqYEXmXShJOPUi3lCYuZI85197Gp4zLYsyUPw,5258
497
- ansible/playbook/role/__init__.py,sha256=_WlHeEAgq-MaUanFXnm2QI7SmKgOonoAubfNkeYMoZM,30674
497
+ ansible/playbook/role/__init__.py,sha256=k7EZxR8-FsY_SWOS4lAauBOfX21lMEsFbuNg_mTOPLg,30668
498
498
  ansible/playbook/role/definition.py,sha256=44IRVqojhemfrdC7bU7aIiYwcFm6kWr30Hn4x0B2Y8U,9477
499
499
  ansible/playbook/role/include.py,sha256=yGBXglTQDtCpZ2XO1mVxp2UtsdLpLTt30KVR2AbBe5U,2159
500
500
  ansible/playbook/role/metadata.py,sha256=h439HGUucs2gOMUJlp2M0OO0_wnWWlQmTs_sOe8h6Sc,5018
@@ -550,7 +550,7 @@ ansible/plugins/connection/__init__.py,sha256=5Dk6zdWL_uDwLk1Iy0WVyhqS55qytHMCr3
550
550
  ansible/plugins/connection/local.py,sha256=ooM9js5jPgJ70UpXIDNxtRkKKf6n9U_VrRBcrsdDdk8,12125
551
551
  ansible/plugins/connection/paramiko_ssh.py,sha256=F6sjILG7nnC4cka-7kQotBcT_1yzU4WeaOTMKa3-OUQ,27681
552
552
  ansible/plugins/connection/psrp.py,sha256=BZrcc6wu5kZrYs0S0vTnnoV2XXlt98-KcIoR70skSpA,30736
553
- ansible/plugins/connection/ssh.py,sha256=LoJf5URaWM6vQGuPQjdpOfsMW_94_LnWM6CFN0e8baM,71502
553
+ ansible/plugins/connection/ssh.py,sha256=AB2GvQnBXjoOM5HeLDZmIVBH5NQxPejz34vm_ow4fVc,71790
554
554
  ansible/plugins/connection/winrm.py,sha256=-E6MpnAnXhWe6XmUA5t_5rgYaWGsUhl9BVzbsj5YlTg,38488
555
555
  ansible/plugins/doc_fragments/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
556
556
  ansible/plugins/doc_fragments/action_common_attributes.py,sha256=Xj26JljzTDZD9aZw6nBSvdW-i5z8M7Fk6rzQqNsYKm8,2442
@@ -776,7 +776,7 @@ ansible/utils/singleton.py,sha256=6nYKQz0zmslyaOvbzCSG0Eud1eIgsQiSPZ1DyY7tXtc,10
776
776
  ansible/utils/ssh_functions.py,sha256=KZ9J3bpOCz-bvx1mqAbyWan_cg5L8C3OjPDl98y9Qm8,2293
777
777
  ansible/utils/unicode.py,sha256=__zbdElrMS9Rrqo9H7tF8zkjKFQCFU8kTtj5cVIITxM,1100
778
778
  ansible/utils/unsafe_proxy.py,sha256=KvL4YeKk3cjxVDTcK9-ijBUneJDOMRngqLOTITFABPE,2107
779
- ansible/utils/vars.py,sha256=qMj_uJH1b8ryuxv22559619p5sQa-44tr0s3gt8tl-I,11649
779
+ ansible/utils/vars.py,sha256=zBE8lhOBJBZVZRKF-xNAnGYAsa2_m7XYXu12JhEaHGI,11712
780
780
  ansible/utils/version.py,sha256=TKmSzm_MFZVJWpvmOnIEGZzRfeHLwWmeuHj16zGqb2c,7736
781
781
  ansible/utils/collection_loader/__init__.py,sha256=lwLu1LJhWz3cRzFLfNWuFdS-Rhods6aReqOaqoVaDaM,2564
782
782
  ansible/utils/collection_loader/_collection_config.py,sha256=6r5DY_4kKGQz4qk7u9vsrNq__UmGFlCjtAV-HwJsFaM,3000
@@ -788,12 +788,12 @@ ansible/vars/hostvars.py,sha256=cRK_4dssUwIN4aDxxYXEj7KzTazrykQ4PbJotne5oJc,4364
788
788
  ansible/vars/manager.py,sha256=1SNGcwMTT7m8aPC45DHdkOZRtnf7OEcuExBtocJusq4,28023
789
789
  ansible/vars/plugins.py,sha256=8svEABS2yBPzEdymdsrZ-0D70boUoCNvcgkWasvtVNo,4533
790
790
  ansible/vars/reserved.py,sha256=NgxlMBm_tloqDVb5TEX4eGhpYsz_AO6-Fmyi3kJpIFk,3107
791
- ansible_core-2.19.0b7.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
792
- ansible_core-2.19.0b7.dist-info/licenses/licenses/Apache-License.txt,sha256=y16Ofl9KOYjhBjwULGDcLfdWBfTEZRXnduOspt-XbhQ,11325
793
- ansible_core-2.19.0b7.dist-info/licenses/licenses/BSD-3-Clause.txt,sha256=la0N3fE3Se8vBiuvUcFKA8b-E41G7flTic6P8CkUroE,1548
794
- ansible_core-2.19.0b7.dist-info/licenses/licenses/MIT-license.txt,sha256=jLXp2XurnyZKbye40g9tfmLGtVlxh3pPD4n8xNqX8xc,1023
795
- ansible_core-2.19.0b7.dist-info/licenses/licenses/PSF-license.txt,sha256=g7BC_H1qyg8Q1o5F76Vrm8ChSWYI5-dyj-CdGlNKBUo,2484
796
- ansible_core-2.19.0b7.dist-info/licenses/licenses/simplified_bsd.txt,sha256=8R5R7R7sOa0h1Fi6RNgFgHowHBfun-OVOMzJ4rKAk2w,1237
791
+ ansible_core-2.19.0rc1.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
792
+ ansible_core-2.19.0rc1.dist-info/licenses/licenses/Apache-License.txt,sha256=y16Ofl9KOYjhBjwULGDcLfdWBfTEZRXnduOspt-XbhQ,11325
793
+ ansible_core-2.19.0rc1.dist-info/licenses/licenses/BSD-3-Clause.txt,sha256=la0N3fE3Se8vBiuvUcFKA8b-E41G7flTic6P8CkUroE,1548
794
+ ansible_core-2.19.0rc1.dist-info/licenses/licenses/MIT-license.txt,sha256=jLXp2XurnyZKbye40g9tfmLGtVlxh3pPD4n8xNqX8xc,1023
795
+ ansible_core-2.19.0rc1.dist-info/licenses/licenses/PSF-license.txt,sha256=g7BC_H1qyg8Q1o5F76Vrm8ChSWYI5-dyj-CdGlNKBUo,2484
796
+ ansible_core-2.19.0rc1.dist-info/licenses/licenses/simplified_bsd.txt,sha256=8R5R7R7sOa0h1Fi6RNgFgHowHBfun-OVOMzJ4rKAk2w,1237
797
797
  ansible_test/__init__.py,sha256=20VPOj11c6Ut1Av9RaurgwJvFhMqkWG3vAvcCbecNKw,66
798
798
  ansible_test/_data/ansible.cfg,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
799
799
  ansible_test/_data/coveragerc,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1039,7 +1039,7 @@ ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg,sha256=TfiS1
1039
1039
  ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg,sha256=jJ1K5-7XP-SLu6cJaZjDSNrJt7SRxwLDhSBWotw9g5Y,2062
1040
1040
  ansible_test/_util/controller/sanity/pylint/config/collection.cfg,sha256=MrPjqou7RMmSBmai8epIbSCLbYkZ0yyxFcadowXrPs8,4789
1041
1041
  ansible_test/_util/controller/sanity/pylint/config/default.cfg,sha256=PHGUd-3F3tkj-Ie8HPFlF2kg3R9F5z92Ric9icrLJs0,4363
1042
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py,sha256=Tu6mjKhbZiVhHJ-u1vixLxi3rtuSII6avT_NcZ_B6gw,21809
1042
+ ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py,sha256=3F7wU2Pz2AzGSLmHg-Io76UU3HAxHJIHXn7F7GFMawA,21823
1043
1043
  ansible_test/_util/controller/sanity/pylint/plugins/deprecated_comment.py,sha256=tmQf_-2VAT2GVfwa9X9ruBcaj0Sz6Ifx4cXmdzJ99SQ,5226
1044
1044
  ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py,sha256=s0AIoK03uqZSTwXSLvd4oXvf4WJ0Ckol5ingitHoMr4,836
1045
1045
  ansible_test/_util/controller/sanity/pylint/plugins/string_format.py,sha256=Mb1Mx8WS4RulsORFgyctlFRR0Sn-PYPy4mVu_GYCD18,2359
@@ -1090,8 +1090,8 @@ ansible_test/config/cloud-config-vultr.ini.template,sha256=XLKHk3lg_8ReQMdWfZzhh
1090
1090
  ansible_test/config/config.yml,sha256=1zdGucnIl6nIecZA7ISIANvqXiHWqq6Dthsk_6MUwNc,2642
1091
1091
  ansible_test/config/inventory.networking.template,sha256=bFNSk8zNQOaZ_twaflrY0XZ9mLwUbRLuNT0BdIFwvn4,1335
1092
1092
  ansible_test/config/inventory.winrm.template,sha256=1QU8W-GFLnYEw8yY9bVIvUAVvJYPM3hyoijf6-M7T00,1098
1093
- ansible_core-2.19.0b7.dist-info/METADATA,sha256=AwkLoXP0crj5iOvAW_RdP39kqChlpQWlPiFhxvu3qY0,7732
1094
- ansible_core-2.19.0b7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1095
- ansible_core-2.19.0b7.dist-info/entry_points.txt,sha256=S9yJij5Im6FgRQxzkqSCnPQokC7PcWrDW_NSygZczJU,451
1096
- ansible_core-2.19.0b7.dist-info/top_level.txt,sha256=IFbRLjAvih1DYzJWg3_F6t4sCzEMxRO7TOMNs6GkYHo,21
1097
- ansible_core-2.19.0b7.dist-info/RECORD,,
1093
+ ansible_core-2.19.0rc1.dist-info/METADATA,sha256=QnBK_jFoYoWx_2nkKML2MmP1NZ8LnR7yuw7zC7CwtIY,7733
1094
+ ansible_core-2.19.0rc1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1095
+ ansible_core-2.19.0rc1.dist-info/entry_points.txt,sha256=S9yJij5Im6FgRQxzkqSCnPQokC7PcWrDW_NSygZczJU,451
1096
+ ansible_core-2.19.0rc1.dist-info/top_level.txt,sha256=IFbRLjAvih1DYzJWg3_F6t4sCzEMxRO7TOMNs6GkYHo,21
1097
+ ansible_core-2.19.0rc1.dist-info/RECORD,,
@@ -9,6 +9,7 @@ import dataclasses
9
9
  import datetime
10
10
  import functools
11
11
  import pathlib
12
+ import re
12
13
 
13
14
  import astroid
14
15
  import astroid.context
@@ -156,7 +157,7 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
156
157
  ),
157
158
  )
158
159
 
159
- ANSIBLE_VERSION = StrictVersion('.'.join(ansible.release.__version__.split('.')[:3]))
160
+ ANSIBLE_VERSION = StrictVersion(re.match('[0-9.]*[0-9]', ansible.release.__version__)[0])
160
161
  """The current ansible-core X.Y.Z version."""
161
162
 
162
163
  DEPRECATION_MODULE_FUNCTIONS: dict[tuple[str, str], tuple[str, ...]] = {