ansible-core 2.15.7rc1__py3-none-any.whl → 2.15.9__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/config.py CHANGED
@@ -314,7 +314,7 @@ class ConfigCLI(CLI):
314
314
 
315
315
  return data
316
316
 
317
- def _get_settings_ini(self, settings):
317
+ def _get_settings_ini(self, settings, seen):
318
318
 
319
319
  sections = {}
320
320
  for o in sorted(settings.keys()):
@@ -327,7 +327,7 @@ class ConfigCLI(CLI):
327
327
 
328
328
  if not opt.get('description'):
329
329
  # its a plugin
330
- new_sections = self._get_settings_ini(opt)
330
+ new_sections = self._get_settings_ini(opt, seen)
331
331
  for s in new_sections:
332
332
  if s in sections:
333
333
  sections[s].extend(new_sections[s])
@@ -343,37 +343,45 @@ class ConfigCLI(CLI):
343
343
 
344
344
  if 'ini' in opt and opt['ini']:
345
345
  entry = opt['ini'][-1]
346
+ if entry['section'] not in seen:
347
+ seen[entry['section']] = []
346
348
  if entry['section'] not in sections:
347
349
  sections[entry['section']] = []
348
350
 
349
- default = opt.get('default', '')
350
- if opt.get('type', '') == 'list' and not isinstance(default, string_types):
351
- # python lists are not valid ini ones
352
- default = ', '.join(default)
353
- elif default is None:
354
- default = ''
351
+ # avoid dupes
352
+ if entry['key'] not in seen[entry['section']]:
353
+ seen[entry['section']].append(entry['key'])
354
+
355
+ default = opt.get('default', '')
356
+ if opt.get('type', '') == 'list' and not isinstance(default, string_types):
357
+ # python lists are not valid ini ones
358
+ default = ', '.join(default)
359
+ elif default is None:
360
+ default = ''
361
+
362
+ if context.CLIARGS['commented']:
363
+ entry['key'] = ';%s' % entry['key']
355
364
 
356
- if context.CLIARGS['commented']:
357
- entry['key'] = ';%s' % entry['key']
365
+ key = desc + '\n%s=%s' % (entry['key'], default)
358
366
 
359
- key = desc + '\n%s=%s' % (entry['key'], default)
360
- sections[entry['section']].append(key)
367
+ sections[entry['section']].append(key)
361
368
 
362
369
  return sections
363
370
 
364
371
  def execute_init(self):
365
372
  """Create initial configuration"""
366
373
 
374
+ seen = {}
367
375
  data = []
368
376
  config_entries = self._list_entries_from_args()
369
377
  plugin_types = config_entries.pop('PLUGINS', None)
370
378
 
371
379
  if context.CLIARGS['format'] == 'ini':
372
- sections = self._get_settings_ini(config_entries)
380
+ sections = self._get_settings_ini(config_entries, seen)
373
381
 
374
382
  if plugin_types:
375
383
  for ptype in plugin_types:
376
- plugin_sections = self._get_settings_ini(plugin_types[ptype])
384
+ plugin_sections = self._get_settings_ini(plugin_types[ptype], seen)
377
385
  for s in plugin_sections:
378
386
  if s in sections:
379
387
  sections[s].extend(plugin_sections[s])
@@ -411,11 +411,7 @@ class TaskExecutor:
411
411
  """This method is responsible for effectively pre-validating Task.delegate_to and will
412
412
  happen before Task.post_validate is executed
413
413
  """
414
- delegated_vars, delegated_host_name = self._variable_manager.get_delegated_vars_and_hostname(
415
- templar,
416
- self._task,
417
- variables
418
- )
414
+ delegated_vars, delegated_host_name = self._variable_manager.get_delegated_vars_and_hostname(templar, self._task, variables)
419
415
  # At the point this is executed it is safe to mutate self._task,
420
416
  # since `self._task` is either a copy referred to by `tmp_task` in `_run_loop`
421
417
  # or just a singular non-looped task
ansible/galaxy/api.py CHANGED
@@ -483,8 +483,6 @@ class GalaxyAPI:
483
483
  }
484
484
  if role_name:
485
485
  args['alternate_role_name'] = role_name
486
- elif github_repo.startswith('ansible-role'):
487
- args['alternate_role_name'] = github_repo[len('ansible-role') + 1:]
488
486
  data = self._call_galaxy(url, args=urlencode(args), method="POST")
489
487
  if data.get('results', None):
490
488
  return data['results']
ansible/galaxy/role.py CHANGED
@@ -42,6 +42,7 @@ from ansible.module_utils.compat.version import LooseVersion
42
42
  from ansible.module_utils.urls import open_url
43
43
  from ansible.playbook.role.requirement import RoleRequirement
44
44
  from ansible.utils.display import Display
45
+ from ansible.utils.path import is_subpath, unfrackpath
45
46
 
46
47
  display = Display()
47
48
 
@@ -393,43 +394,41 @@ class GalaxyRole(object):
393
394
  # we only extract files, and remove any relative path
394
395
  # bits that might be in the file for security purposes
395
396
  # and drop any containing directory, as mentioned above
396
- if member.isreg() or member.issym():
397
- for attr in ('name', 'linkname'):
398
- attr_value = getattr(member, attr, None)
399
- if not attr_value:
400
- continue
401
- n_attr_value = to_native(attr_value)
402
- n_archive_parent_dir = to_native(archive_parent_dir)
403
- n_parts = n_attr_value.replace(n_archive_parent_dir, "", 1).split(os.sep)
404
- n_final_parts = []
405
- for n_part in n_parts:
406
- # TODO if the condition triggers it produces a broken installation.
407
- # It will create the parent directory as an empty file and will
408
- # explode if the directory contains valid files.
409
- # Leaving this as is since the whole module needs a rewrite.
410
- #
411
- # Check if we have any files with illegal names,
412
- # and display a warning if so. This could help users
413
- # to debug a broken installation.
414
- if not n_part:
415
- continue
416
- if n_part == '..':
417
- display.warning(f"Illegal filename '{n_part}': '..' is not allowed")
418
- continue
419
- if n_part.startswith('~'):
420
- display.warning(f"Illegal filename '{n_part}': names cannot start with '~'")
421
- continue
422
- if '$' in n_part:
423
- display.warning(f"Illegal filename '{n_part}': names cannot contain '$'")
424
- continue
425
- n_final_parts.append(n_part)
426
- setattr(member, attr, os.path.join(*n_final_parts))
427
-
428
- if _check_working_data_filter():
429
- # deprecated: description='extract fallback without filter' python_version='3.11'
430
- role_tar_file.extract(member, to_native(self.path), filter='data') # type: ignore[call-arg]
397
+ if not (member.isreg() or member.issym()):
398
+ continue
399
+
400
+ for attr in ('name', 'linkname'):
401
+ if not (attr_value := getattr(member, attr, None)):
402
+ continue
403
+
404
+ if attr_value.startswith(os.sep) and not is_subpath(attr_value, archive_parent_dir):
405
+ err = f"Invalid {attr} for tarfile member: path {attr_value} is not a subpath of the role {archive_parent_dir}"
406
+ raise AnsibleError(err)
407
+
408
+ if attr == 'linkname':
409
+ # Symlinks are relative to the link
410
+ relative_to_archive_dir = os.path.dirname(getattr(member, 'name', ''))
411
+ archive_dir_path = os.path.join(archive_parent_dir, relative_to_archive_dir, attr_value)
431
412
  else:
432
- role_tar_file.extract(member, to_native(self.path))
413
+ # Normalize paths that start with the archive dir
414
+ attr_value = attr_value.replace(archive_parent_dir, "", 1)
415
+ attr_value = os.path.join(*attr_value.split(os.sep)) # remove leading os.sep
416
+ archive_dir_path = os.path.join(archive_parent_dir, attr_value)
417
+
418
+ resolved_archive = unfrackpath(archive_parent_dir)
419
+ resolved_path = unfrackpath(archive_dir_path)
420
+ if not is_subpath(resolved_path, resolved_archive):
421
+ err = f"Invalid {attr} for tarfile member: path {resolved_path} is not a subpath of the role {resolved_archive}"
422
+ raise AnsibleError(err)
423
+
424
+ relative_path = os.path.join(*resolved_path.replace(resolved_archive, "", 1).split(os.sep)) or '.'
425
+ setattr(member, attr, relative_path)
426
+
427
+ if _check_working_data_filter():
428
+ # deprecated: description='extract fallback without filter' python_version='3.11'
429
+ role_tar_file.extract(member, to_native(self.path), filter='data') # type: ignore[call-arg]
430
+ else:
431
+ role_tar_file.extract(member, to_native(self.path))
433
432
 
434
433
  # write out the install info file for later use
435
434
  self._write_galaxy_install_info()
@@ -19,6 +19,6 @@
19
19
  from __future__ import (absolute_import, division, print_function)
20
20
  __metaclass__ = type
21
21
 
22
- __version__ = '2.15.7rc1'
22
+ __version__ = '2.15.9'
23
23
  __author__ = 'Ansible, Inc.'
24
24
  __codename__ = "Ten Years Gone"
@@ -41,7 +41,7 @@ seealso:
41
41
  - module: ansible.builtin.import_tasks
42
42
  - module: ansible.builtin.include_role
43
43
  - module: ansible.builtin.include_tasks
44
- - ref: playbooks_reuse_includes
44
+ - ref: playbooks_reuse
45
45
  description: More information related to including and importing playbooks, roles and tasks.
46
46
  '''
47
47
 
@@ -78,7 +78,7 @@ seealso:
78
78
  - module: ansible.builtin.import_tasks
79
79
  - module: ansible.builtin.include_role
80
80
  - module: ansible.builtin.include_tasks
81
- - ref: playbooks_reuse_includes
81
+ - ref: playbooks_reuse
82
82
  description: More information related to including and importing playbooks, roles and tasks.
83
83
  '''
84
84
 
@@ -45,7 +45,7 @@ seealso:
45
45
  - module: ansible.builtin.import_role
46
46
  - module: ansible.builtin.include_role
47
47
  - module: ansible.builtin.include_tasks
48
- - ref: playbooks_reuse_includes
48
+ - ref: playbooks_reuse
49
49
  description: More information related to including and importing playbooks, roles and tasks.
50
50
  '''
51
51
 
@@ -91,7 +91,7 @@ seealso:
91
91
  - module: ansible.builtin.import_role
92
92
  - module: ansible.builtin.import_tasks
93
93
  - module: ansible.builtin.include_tasks
94
- - ref: playbooks_reuse_includes
94
+ - ref: playbooks_reuse
95
95
  description: More information related to including and importing playbooks, roles and tasks.
96
96
  '''
97
97
 
@@ -49,7 +49,7 @@ seealso:
49
49
  - module: ansible.builtin.import_role
50
50
  - module: ansible.builtin.import_tasks
51
51
  - module: ansible.builtin.include_role
52
- - ref: playbooks_reuse_includes
52
+ - ref: playbooks_reuse
53
53
  description: More information related to including and importing playbooks, roles and tasks.
54
54
  '''
55
55
 
ansible/playbook/base.py CHANGED
@@ -731,7 +731,7 @@ class Base(FieldAttributeBase):
731
731
 
732
732
  # flags and misc. settings
733
733
  environment = FieldAttribute(isa='list', extend=True, prepend=True)
734
- no_log = FieldAttribute(isa='bool')
734
+ no_log = FieldAttribute(isa='bool', default=C.DEFAULT_NO_LOG)
735
735
  run_once = FieldAttribute(isa='bool')
736
736
  ignore_errors = FieldAttribute(isa='bool')
737
737
  ignore_unreachable = FieldAttribute(isa='bool')
@@ -318,10 +318,6 @@ class PlayContext(Base):
318
318
  display.warning('The "%s" connection plugin has an improperly configured remote target value, '
319
319
  'forcing "inventory_hostname" templated value instead of the string' % new_info.connection)
320
320
 
321
- # set no_log to default if it was not previously set
322
- if new_info.no_log is None:
323
- new_info.no_log = C.DEFAULT_NO_LOG
324
-
325
321
  if task.check_mode is not None:
326
322
  new_info.check_mode = task.check_mode
327
323
 
ansible/release.py CHANGED
@@ -19,6 +19,6 @@
19
19
  from __future__ import (absolute_import, division, print_function)
20
20
  __metaclass__ = type
21
21
 
22
- __version__ = '2.15.7rc1'
22
+ __version__ = '2.15.9'
23
23
  __author__ = 'Ansible, Inc.'
24
24
  __codename__ = "Ten Years Gone"
@@ -53,11 +53,14 @@
53
53
  from __future__ import (absolute_import, division, print_function)
54
54
  __metaclass__ = type
55
55
 
56
+ import sys
57
+ import types
58
+ import warnings
59
+ from sys import intern as _sys_intern
56
60
  from collections.abc import Mapping, Set
57
61
 
58
62
  from ansible.module_utils._text import to_bytes, to_text
59
63
  from ansible.module_utils.common.collections import is_sequence
60
- from ansible.module_utils.six import binary_type, text_type
61
64
  from ansible.utils.native_jinja import NativeJinjaText
62
65
 
63
66
 
@@ -68,12 +71,15 @@ class AnsibleUnsafe(object):
68
71
  __UNSAFE__ = True
69
72
 
70
73
 
71
- class AnsibleUnsafeBytes(binary_type, AnsibleUnsafe):
74
+ class AnsibleUnsafeBytes(bytes, AnsibleUnsafe):
72
75
  def _strip_unsafe(self):
73
76
  return super().__bytes__()
74
77
 
78
+ def __reduce__(self, /):
79
+ return (self.__class__, (self._strip_unsafe(),))
80
+
75
81
  def __str__(self, /): # pylint: disable=invalid-str-returned
76
- return self.encode()
82
+ return self.decode()
77
83
 
78
84
  def __bytes__(self, /): # pylint: disable=invalid-bytes-returned
79
85
  return self
@@ -82,15 +88,13 @@ class AnsibleUnsafeBytes(binary_type, AnsibleUnsafe):
82
88
  return AnsibleUnsafeText(super().__repr__())
83
89
 
84
90
  def __format__(self, format_spec, /): # pylint: disable=invalid-format-returned
85
- return self.__class__(super().__format__(format_spec))
91
+ return AnsibleUnsafeText(super().__format__(format_spec))
86
92
 
87
93
  def __getitem__(self, key, /):
94
+ if isinstance(key, int):
95
+ return super().__getitem__(key)
88
96
  return self.__class__(super().__getitem__(key))
89
97
 
90
- def __iter__(self, /):
91
- cls = self.__class__
92
- return (cls(c) for c in super().__iter__())
93
-
94
98
  def __reversed__(self, /):
95
99
  return self[::-1]
96
100
 
@@ -114,9 +118,6 @@ class AnsibleUnsafeBytes(binary_type, AnsibleUnsafe):
114
118
  def capitalize(self, /):
115
119
  return self.__class__(super().capitalize())
116
120
 
117
- def casefold(self, /):
118
- return self.__class__(super().casefold())
119
-
120
121
  def center(self, width, fillchar=b' ', /):
121
122
  return self.__class__(super().center(width, fillchar))
122
123
 
@@ -132,12 +133,6 @@ class AnsibleUnsafeBytes(binary_type, AnsibleUnsafe):
132
133
  def expandtabs(self, /, tabsize=8):
133
134
  return self.__class__(super().expandtabs(tabsize))
134
135
 
135
- def format(self, /, *args, **kwargs):
136
- return self.__class__(super().format(*args, **kwargs))
137
-
138
- def format_map(self, mapping, /):
139
- return self.__class__(super().format_map(mapping))
140
-
141
136
  def join(self, iterable_of_bytes, /):
142
137
  return self.__class__(super().join(iterable_of_bytes))
143
138
 
@@ -147,8 +142,8 @@ class AnsibleUnsafeBytes(binary_type, AnsibleUnsafe):
147
142
  def lower(self, /):
148
143
  return self.__class__(super().lower())
149
144
 
150
- def lstrip(self, bytes=None, /):
151
- return self.__class__(super().lstrip(bytes))
145
+ def lstrip(self, chars=None, /):
146
+ return self.__class__(super().lstrip(chars))
152
147
 
153
148
  def partition(self, sep, /):
154
149
  cls = self.__class__
@@ -164,8 +159,8 @@ class AnsibleUnsafeBytes(binary_type, AnsibleUnsafe):
164
159
  cls = self.__class__
165
160
  return tuple(cls(e) for e in super().rpartition(sep))
166
161
 
167
- def rstrip(self, bytes=None, /):
168
- return self.__class__(super().rstrip(bytes))
162
+ def rstrip(self, chars=None, /):
163
+ return self.__class__(super().rstrip(chars))
169
164
 
170
165
  def split(self, /, sep=None, maxsplit=-1):
171
166
  cls = self.__class__
@@ -179,8 +174,8 @@ class AnsibleUnsafeBytes(binary_type, AnsibleUnsafe):
179
174
  cls = self.__class__
180
175
  return [cls(e) for e in super().splitlines(keepends=keepends)]
181
176
 
182
- def strip(self, bytes=None, /):
183
- return self.__class__(super().strip(bytes))
177
+ def strip(self, chars=None, /):
178
+ return self.__class__(super().strip(chars))
184
179
 
185
180
  def swapcase(self, /):
186
181
  return self.__class__(super().swapcase())
@@ -198,14 +193,13 @@ class AnsibleUnsafeBytes(binary_type, AnsibleUnsafe):
198
193
  return self.__class__(super().zfill(width))
199
194
 
200
195
 
201
- class AnsibleUnsafeText(text_type, AnsibleUnsafe):
202
- # def __getattribute__(self, name):
203
- # print(f'attr: {name}')
204
- # return object.__getattribute__(self, name)
205
-
196
+ class AnsibleUnsafeText(str, AnsibleUnsafe):
206
197
  def _strip_unsafe(self, /):
207
198
  return super().__str__()
208
199
 
200
+ def __reduce__(self, /):
201
+ return (self.__class__, (self._strip_unsafe(),))
202
+
209
203
  def __str__(self, /): # pylint: disable=invalid-str-returned
210
204
  return self
211
205
 
@@ -361,9 +355,9 @@ def wrap_var(v):
361
355
  v = _wrap_sequence(v)
362
356
  elif isinstance(v, NativeJinjaText):
363
357
  v = NativeJinjaUnsafeText(v)
364
- elif isinstance(v, binary_type):
358
+ elif isinstance(v, bytes):
365
359
  v = AnsibleUnsafeBytes(v)
366
- elif isinstance(v, text_type):
360
+ elif isinstance(v, str):
367
361
  v = AnsibleUnsafeText(v)
368
362
 
369
363
  return v
@@ -379,3 +373,20 @@ def to_unsafe_text(*args, **kwargs):
379
373
 
380
374
  def _is_unsafe(obj):
381
375
  return getattr(obj, '__UNSAFE__', False) is True
376
+
377
+
378
+ def _intern(string):
379
+ """This is a monkey patch for ``sys.intern`` that will strip
380
+ the unsafe wrapper prior to interning the string.
381
+
382
+ This will not exist in future versions.
383
+ """
384
+ if isinstance(string, AnsibleUnsafeText):
385
+ string = string._strip_unsafe()
386
+ return _sys_intern(string)
387
+
388
+
389
+ if isinstance(sys.intern, types.BuiltinFunctionType):
390
+ sys.intern = _intern
391
+ else:
392
+ warnings.warn("skipped sys.intern patch; appears to have already been patched", RuntimeWarning)
ansible/vars/manager.py CHANGED
@@ -533,27 +533,35 @@ class VariableManager:
533
533
  delegated_host_name = None
534
534
  if task.delegate_to:
535
535
  delegated_host_name = templar.template(task.delegate_to, fail_on_undefined=False)
536
- delegated_host = self._inventory.get_host(delegated_host_name)
537
- if delegated_host is None:
538
- for h in self._inventory.get_hosts(ignore_limits=True, ignore_restrictions=True):
539
- # check if the address matches, or if both the delegated_to host
540
- # and the current host are in the list of localhost aliases
541
- if h.address == delegated_host_name:
542
- delegated_host = h
543
- break
544
- else:
545
- delegated_host = Host(name=delegated_host_name)
546
-
547
- delegated_vars['ansible_delegated_vars'] = {
548
- delegated_host_name: self.get_vars(
549
- play=task.get_play(),
550
- host=delegated_host,
551
- task=task,
552
- include_delegate_to=False,
553
- include_hostvars=True,
554
- )
555
- }
556
- delegated_vars['ansible_delegated_vars'][delegated_host_name]['inventory_hostname'] = variables.get('inventory_hostname')
536
+
537
+ # no need to do work if omitted
538
+ if delegated_host_name != self._omit_token:
539
+
540
+ if not delegated_host_name:
541
+ raise AnsibleError('Empty hostname produced from delegate_to: "%s"' % task.delegate_to)
542
+
543
+ delegated_host = self._inventory.get_host(delegated_host_name)
544
+ if delegated_host is None:
545
+ for h in self._inventory.get_hosts(ignore_limits=True, ignore_restrictions=True):
546
+ # check if the address matches, or if both the delegated_to host
547
+ # and the current host are in the list of localhost aliases
548
+ if h.address == delegated_host_name:
549
+ delegated_host = h
550
+ break
551
+ else:
552
+ delegated_host = Host(name=delegated_host_name)
553
+
554
+ delegated_vars['ansible_delegated_vars'] = {
555
+ delegated_host_name: self.get_vars(
556
+ play=task.get_play(),
557
+ host=delegated_host,
558
+ task=task,
559
+ include_delegate_to=False,
560
+ include_hostvars=True,
561
+ )
562
+ }
563
+ delegated_vars['ansible_delegated_vars'][delegated_host_name]['inventory_hostname'] = variables.get('inventory_hostname')
564
+
557
565
  return delegated_vars, delegated_host_name
558
566
 
559
567
  def _get_delegated_vars(self, play, task, existing_variables):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ansible-core
3
- Version: 2.15.7rc1
3
+ Version: 2.15.9
4
4
  Summary: Radically simple IT automation
5
5
  Home-page: https://ansible.com/
6
6
  Author: Ansible, Inc.
@@ -3,11 +3,11 @@ ansible/__main__.py,sha256=IvyRvY64pT0on94qCLibxgDJ0-7_2CRoaZ5kfGOl54Q,1395
3
3
  ansible/constants.py,sha256=JLIDnuSz3_PbtXWsL4vnvVBbxlh3lSrJREd7T73atEI,8293
4
4
  ansible/context.py,sha256=OzSlaA_GgGRyyf5I209sy19_eGOX6HXn441W9w_FcvU,2018
5
5
  ansible/keyword_desc.yml,sha256=vE9joFgSeHR4Djl7Bd-HHVCrGByRCrTUmWYZ8LKPZKk,7412
6
- ansible/release.py,sha256=eVdYKn_b940r-zcbKvF2C8-HSGucsRWOHGBfLzxVXME,921
6
+ ansible/release.py,sha256=-CbXCAtsQZrE1cxCjGfxhYrVqhAtni4yiMzsmL50v68,918
7
7
  ansible/_vendor/__init__.py,sha256=wJRKH7kI9OzYVY9hgSchOsTNTmTnugpPLGYj9Y5akX0,2086
8
8
  ansible/cli/__init__.py,sha256=ZK8bKuMmeRqeAcePriGtJ0tMuoDur3sN-ySBmOzAF3c,28687
9
9
  ansible/cli/adhoc.py,sha256=pGW6eysaireovp4sVsUuntg-l1o7DSujuhxVhVC2zsM,8230
10
- ansible/cli/config.py,sha256=aSt2sNV8iMkqXM8YcLpfXRlNZKvYdoOW625241xT_VI,22157
10
+ ansible/cli/config.py,sha256=tDqpTRDUh-mh1AEnaj0pGITH7TfCEzswbw2c8__dnak,22495
11
11
  ansible/cli/console.py,sha256=rc-6s-Exf9b8lead40RyfugZdU1-cMoN-kA1iI8Uhs8,21941
12
12
  ansible/cli/doc.py,sha256=x7LNU10RiJJejxHxbZg0xd6cdJarxTEK5LfWmQMc3y0,64153
13
13
  ansible/cli/galaxy.py,sha256=YFfYopOl1KL6Il6s4ilQ76RrxUpX2soh9eViK1GkSA8,92559
@@ -37,7 +37,7 @@ ansible/executor/module_common.py,sha256=6R58IqfOLzg0aDQWRWsi0cbohWMSf_Lvdhf_5hT
37
37
  ansible/executor/play_iterator.py,sha256=-ptFAZ7MBuV-aNRqPkpAPIpotPm4xag3yD3fUQqde_U,31026
38
38
  ansible/executor/playbook_executor.py,sha256=VQHEIvZbfOFzp388XFD0KjG0e8Ye8yuNPnnHAZmi898,15069
39
39
  ansible/executor/stats.py,sha256=757UK8wDzLCXq4ltI9PqpoMNAdtRsd9D9-GS-5Al_Hs,3264
40
- ansible/executor/task_executor.py,sha256=SspK6gfZG-YUjtKwyY10TVSf9CFftn2dGXMFrY5B49w,59955
40
+ ansible/executor/task_executor.py,sha256=h-bc0HS3y8b_8GncrUkV9tsEc5a-g4FX12boQPrXx50,59909
41
41
  ansible/executor/task_queue_manager.py,sha256=DxmfDMeWAClNvp85qvc1uATor-hilv8KsYno3Pl_Ztk,18758
42
42
  ansible/executor/task_result.py,sha256=DvshMci5i9-qCXs0m_vScSa6BJMbPwwNQBV7L2DTCzE,5748
43
43
  ansible/executor/discovery/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -56,8 +56,8 @@ ansible/executor/powershell/module_wrapper.ps1,sha256=JkCL_6aAZoXgQmFjU5hgEzTCMd
56
56
  ansible/executor/process/__init__.py,sha256=1lMXN1i2fFqslda4BmeI5tpYMFP95D5Wpr1AjDJi-SQ,833
57
57
  ansible/executor/process/worker.py,sha256=k5aTaoCUu_ZUmdnPgIGqGsD7013_o3srzwxNpAjD1SY,9415
58
58
  ansible/galaxy/__init__.py,sha256=_ccTedn8dUGGtkmHcQLIkeje_YD0TYSXlvCl1AOY5fE,2533
59
- ansible/galaxy/api.py,sha256=deSYsFinaJodT2Y9-XnOerWIwYY8V2AWQ_9kZI0pWCE,39872
60
- ansible/galaxy/role.py,sha256=6pK3to7HhD4z2KfRfxklIGVLIK3p5ld8zuIFFKRGfSo,21623
59
+ ansible/galaxy/api.py,sha256=E_c-WBgCj5QZSmOqLCGpiVbx5lQue1mHVwABFcVhmq0,39739
60
+ ansible/galaxy/role.py,sha256=g7vPiT4IWpsXHP3Z5g9L4Y0lxfRbrRXixewAIN-XgRk,21379
61
61
  ansible/galaxy/token.py,sha256=K0dAwD3Fjkn3Zs2N9sG98UesSWfAukie47QGyYpIf0M,6167
62
62
  ansible/galaxy/user_agent.py,sha256=x7cJzzpnTngHcwqSUd2hg0i28Dv0tbAyBdke5CSiNhM,813
63
63
  ansible/galaxy/collection/__init__.py,sha256=uD_Z41jelLRR9TkOfeydM2CYcWvFSXaU31e3l1ielNQ,77312
@@ -140,7 +140,7 @@ ansible/inventory/host.py,sha256=wXJp6kpSaZtDr4JNsgdAuhi5MzQ9LTQzaAH10zoVbIA,505
140
140
  ansible/inventory/manager.py,sha256=tGwhBR6poLuG_i4jZ5RGOG-rH4gu4DBfT0-4iLLZZMs,29490
141
141
  ansible/module_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
142
142
  ansible/module_utils/_text.py,sha256=F_YfeaxhwmTI16HICAzQS9ZmlKgBDdQ4mqR-Kh--okg,597
143
- ansible/module_utils/ansible_release.py,sha256=eVdYKn_b940r-zcbKvF2C8-HSGucsRWOHGBfLzxVXME,921
143
+ ansible/module_utils/ansible_release.py,sha256=-CbXCAtsQZrE1cxCjGfxhYrVqhAtni4yiMzsmL50v68,918
144
144
  ansible/module_utils/api.py,sha256=BTo7stVOANbtd-ngZslaqx70r9t5gfvo44cKyu5SFjU,5837
145
145
  ansible/module_utils/basic.py,sha256=wzb7sayWWJC6BzzUUI3-GJQppKrVWiuiUcv0pIDHsJA,88437
146
146
  ansible/module_utils/connection.py,sha256=XHxMlyAdwLiXDSo8jBMkV61-lz_0FDJUYH1B152UGJU,8430
@@ -306,11 +306,11 @@ ansible/modules/git.py,sha256=ZCOMhjdyvq9geb7iNyBlo5DHeC1Tj8nZGpGBNJQvQac,56555
306
306
  ansible/modules/group.py,sha256=VrfVk3qdDniNWb-sCgk5fjOQikDQMYfVBzZQI27GIGo,21259
307
307
  ansible/modules/group_by.py,sha256=RMC1jSnV1htlU_QLTZKYXWtUOdtDWXcHRFHBAqVsRMY,2467
308
308
  ansible/modules/hostname.py,sha256=BW47SL8_oTH9eZz8dX6-jA7sBMQr_n0D8LHCHSQD94I,28795
309
- ansible/modules/import_playbook.py,sha256=xDtdGpAdCah-0mfnDDoFxMMmR2oTx01P6ua6QFztkBQ,2116
310
- ansible/modules/import_role.py,sha256=JT9Vp1Tm5KgwyFXYF_g7Eae2LyNkMisQuVJ_wHBfP0o,3354
311
- ansible/modules/import_tasks.py,sha256=6HGZ_g9VWSTU01qhLC7F3Y0hZIIOJ5ZUBDOoXf_jv2M,2197
312
- ansible/modules/include_role.py,sha256=lSMVbXRlVBEPXr23cyAiJOXaMrxx_lqFPEIi0MV1knc,4260
313
- ansible/modules/include_tasks.py,sha256=H6hryVC1sYayj6UuXWluyVzEbd7O0qT8Vps4SKwz8n4,2712
309
+ ansible/modules/import_playbook.py,sha256=2Ekq8SsYeIOyrwIpt6822xv2ZHRBqe4QNToLOACRDYU,2107
310
+ ansible/modules/import_role.py,sha256=ybsJfXKKxW-Gncs_gIAE32JP2FfZxrbavqp6-lrGg-k,3345
311
+ ansible/modules/import_tasks.py,sha256=K28dgE-ENrPYCkfhwHX92nMFrGZ92RPv6zBKv4u16l8,2188
312
+ ansible/modules/include_role.py,sha256=FIe2GRhrChllGXMnDj3ffY7TFUH-YSrczjdC5MVGt5M,4251
313
+ ansible/modules/include_tasks.py,sha256=E6h6QHoBVVud_4-z5n_mOqs04988dccQWs4Isk8jkP8,2703
314
314
  ansible/modules/include_vars.py,sha256=RDofZtyKsmEtZUDKUg_7qtbqG0oyplE5VFURUtl4Jp0,6753
315
315
  ansible/modules/iptables.py,sha256=P3bYOOZ7VAtfVsa0AEVMtuhPusBuLGnPa56y--5Djzk,33759
316
316
  ansible/modules/known_hosts.py,sha256=i1SA88gqAIb_fSrMT0MB4W1tkk4rRVHt9ohXlYFCMKE,13819
@@ -367,7 +367,7 @@ ansible/parsing/yaml/loader.py,sha256=mYJ5c8WgwKlc5a8dv8mcPwMMifOY0cJrKiAqaRIWPu
367
367
  ansible/parsing/yaml/objects.py,sha256=HyFShve1aWC2Gynx11j37IM_EM0DxNKo-csBmyS2CUU,10523
368
368
  ansible/playbook/__init__.py,sha256=Q_R_9VslOm6SKFnj42CwaBPTtd4y2aQm2ExCKGHnQtE,4807
369
369
  ansible/playbook/attribute.py,sha256=ntK8od_S4MZs5JXWMzkFmr_qWL5eY2zRDVbs4cUk_V4,7733
370
- ansible/playbook/base.py,sha256=jC8dUQtOUT5Chmd4P_j2SsfV5CofOzbsISjiKoiDnzc,33895
370
+ ansible/playbook/base.py,sha256=wwbtFCugaKKz-5anHJFCMHvdMitaQik_uJU7ZKTZ3Lk,33921
371
371
  ansible/playbook/block.py,sha256=-vFVCz-1zXKu1GCAOc_TCH_VbPlaABzJtp5LXnArQUg,16729
372
372
  ansible/playbook/collectionsearch.py,sha256=dfTz79Af_3iurr0YZDcNWsAffaRlbrffXz_KZ3xZlpQ,2654
373
373
  ansible/playbook/conditional.py,sha256=qbJo7kXzZk8MXwNYMXAV2H0w3HxrRMttocNZjwFfRQs,8362
@@ -379,7 +379,7 @@ ansible/playbook/included_file.py,sha256=qIZLUTm0MUFer3-iZwbwRONYDRENb-2-OPQKCro
379
379
  ansible/playbook/loop_control.py,sha256=nd6BDDd1Sqfk-HYYg8VjF8B2v1ob6yExNKUlMZFmeiU,1773
380
380
  ansible/playbook/notifiable.py,sha256=V6cvqy4H1Ti_kmTEw1YOgZOAulI9WgAAnfHeLOGyB5I,264
381
381
  ansible/playbook/play.py,sha256=f9uTpi7o2bDoze8ZUFv5Iz3IAi06SISapW7e1YTko-U,16326
382
- ansible/playbook/play_context.py,sha256=j7v3B7frT874UOEWoW2uBSABstj5AyKuAf__U3fgN8A,14587
382
+ ansible/playbook/play_context.py,sha256=d5OKX160TTmB6ZpW_ji1iduHC4LQUQXHmdCBSpjPsR8,14442
383
383
  ansible/playbook/playbook_include.py,sha256=sJiA8eGfaxMtNv4j3Gcf7OTy_mR37-tijxJ7p8IkEpI,7555
384
384
  ansible/playbook/role_include.py,sha256=zdEtObpYpm303eS6iGabgSGE8heI3QbsNXIbP61vGDI,8067
385
385
  ansible/playbook/taggable.py,sha256=QpIS7BXQ9N48Vu1HW96OdSMyrQHckYtCgsVL9-mv-Ts,3249
@@ -668,7 +668,7 @@ ansible/utils/shlex.py,sha256=OMoMe9Kd5Ck3LLiiL87OixmYt4Qf3hpiphseg6rwX1Q,1279
668
668
  ansible/utils/singleton.py,sha256=fzXOd2ql_zrjCmnWR8Qx2WF_lmO5A8r46U81v7tePSo,949
669
669
  ansible/utils/ssh_functions.py,sha256=GpLSJC-vDj5YyTHN48QaSUpuwAsaDb1oS4tbyVTRKgU,2282
670
670
  ansible/utils/unicode.py,sha256=aJoGG4GCriSxk6mD8pHLgHrnmbU9C5aIyAVyucwWaFk,1167
671
- ansible/utils/unsafe_proxy.py,sha256=YvmpXIa_OiQC226K2fqcBgjnUBBrJFgniqb_aM3D0RU,12504
671
+ ansible/utils/unsafe_proxy.py,sha256=-3GKHvmPvW-EHF1Df212rHnp4HUD7rb4D_ysJhbuo30,12733
672
672
  ansible/utils/vars.py,sha256=r6EGRbxRR_6M6iSeSdXPSJq8i_IjowI9qbXBbOcwNyg,10563
673
673
  ansible/utils/version.py,sha256=LHBI8I_ifkG2Pp4Y_NALEOlumNpp1ruG3LPS9h8Ny5k,7789
674
674
  ansible/utils/collection_loader/__init__.py,sha256=l6gUbk5MzfUXlySWrj4xi4IF9UBIrOrEpRQ52-xfGsA,1118
@@ -679,16 +679,16 @@ ansible/vars/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
679
679
  ansible/vars/clean.py,sha256=TeNDx7skJFqR0K1ok_cQuvKDjzTrCc7u2qGWTNambQo,6083
680
680
  ansible/vars/fact_cache.py,sha256=4lxkYru1qucTDQ0aSmtc5UDWP-gm3edPmDSuTZ2GCmE,1956
681
681
  ansible/vars/hostvars.py,sha256=dg3jpVmNwSg8EJ4SIvYGT80uxMgRtrOW6vvtDfrQzDU,5152
682
- ansible/vars/manager.py,sha256=iCU2xx6xbr-ZVgTkdc419MdZcNfDCNtIL1JyfPNHKPU,38477
682
+ ansible/vars/manager.py,sha256=7krY5GH2T06FYCoCIigzo85kY7gIAm1aha-6fSPYXYA,38813
683
683
  ansible/vars/plugins.py,sha256=B7L3fXoSOoBZSXqJ2ulk0adx1g5SpAb8BxyLGPNA7d4,4695
684
684
  ansible/vars/reserved.py,sha256=FBD7n2dnA0CW4I0J1LtWwk2hQqvGW0KTRPcxaRtMKWo,2615
685
- ansible_core-2.15.7rc1.data/scripts/ansible-test,sha256=CYIYL99IxWdVTtDIj3avilIJXhGAmtjuKPPWNuLWuc8,1690
685
+ ansible_core-2.15.9.data/scripts/ansible-test,sha256=CYIYL99IxWdVTtDIj3avilIJXhGAmtjuKPPWNuLWuc8,1690
686
686
  ansible_test/__init__.py,sha256=6e721yAyyyocRKzbCKtQXloAfFP7Aqv0L3zG70uh-4A,190
687
687
  ansible_test/_data/ansible.cfg,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
688
688
  ansible_test/_data/coveragerc,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
689
689
  ansible_test/_data/completion/docker.txt,sha256=Bz-6tKH6BLsq25v03e7DBGnqgSLad-KQsOwkJMfix0U,822
690
690
  ansible_test/_data/completion/network.txt,sha256=_-mi013-JeufshKMUmykkOmZPw1cVbakIMaAuweHet8,198
691
- ansible_test/_data/completion/remote.txt,sha256=q5HD3KFI2oHaAo6oobkuBeMAewg1vFm9WlMScOzLb7I,1161
691
+ ansible_test/_data/completion/remote.txt,sha256=3x7DUcbePaWuKPYBxD82rwvLd1D88AFOEPfswiLS41s,1071
692
692
  ansible_test/_data/completion/windows.txt,sha256=7xcstRugKOY6lnvJd1nzLE7I5awR-uQfmPtRoyPAg7g,230
693
693
  ansible_test/_data/playbooks/posix_coverage_setup.yml,sha256=PgQNVzVTsNmfnu0sT2SAYiWtkMSOppfmh0oVmAsb7TQ,594
694
694
  ansible_test/_data/playbooks/posix_coverage_teardown.yml,sha256=xHci5QllwJymFtig-hsOXm-Wdrxz063JH14aIyRXhyc,212
@@ -927,7 +927,7 @@ ansible_test/_util/controller/sanity/code-smell/no-unicode-literals.py,sha256=-5
927
927
  ansible_test/_util/controller/sanity/code-smell/replace-urlopen.json,sha256=SsCZ1ULl6HPGBcMpXeCTH5-nNVU9jR-ZSeNy4fotpNY,111
928
928
  ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py,sha256=PSLEuYW5SBrcC7YIt8jdvJ3arxLL7SK7Mxbsvz1UfXc,624
929
929
  ansible_test/_util/controller/sanity/code-smell/runtime-metadata.json,sha256=H2E2-01YXLlSWjvLJT5Vtj3Gn4zB6xhPXsDJh4a7EH0,225
930
- ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py,sha256=f8qydXHd8HrxBj23cciII7z7z0jYIkFfcT-OHkhb-zI,11889
930
+ ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py,sha256=Hjf8KqEgEa-K2pZ8E0hKQ80BMTX1slCz0Hp2P1CZWn8,12183
931
931
  ansible_test/_util/controller/sanity/code-smell/shebang.json,sha256=3vtNzoowM53gi2KZi9peIKVIU79ulQY3FE0jYcSP77M,63
932
932
  ansible_test/_util/controller/sanity/code-smell/shebang.py,sha256=AKCti3RCgZy0GWB3bXgimr_OhqfVPOp_I7345UN_DV8,4672
933
933
  ansible_test/_util/controller/sanity/code-smell/symlinks.json,sha256=JkalgX52aKGUKqjKG5P-68F0tXmUMgldPrNAknMN2Fk,96
@@ -978,7 +978,7 @@ ansible_test/_util/target/injector/virtualenv.sh,sha256=OhiPVykh_qhPMlcE4vozBF5B
978
978
  ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py,sha256=HpAtq0mjSj-SqvEpNphpDiiISuwKcsffFnhBA99TFW0,5130
979
979
  ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py,sha256=Nr52YbVP7BwI4u6mZZptZIYGAfmqzzytdbC98lTr5Ks,1599
980
980
  ansible_test/_util/target/sanity/compile/compile.py,sha256=X1WHH2iLT4K8kyYJKlr-6AL6EAzKisL_hYrjvGrHCZ8,1637
981
- ansible_test/_util/target/sanity/import/importer.py,sha256=FNNKz2lSpxTNdfjLdvadzP3KryI4ut7gT03050gzDN8,25932
981
+ ansible_test/_util/target/sanity/import/importer.py,sha256=Q2cmqi-dFOfXYFzPybbWKgqMYUnjmXz7WFiYb9ysEO4,26208
982
982
  ansible_test/_util/target/setup/ConfigureRemotingForAnsible.ps1,sha256=pW9YaaSNvhc_0ijjMfSMdoQkrmZNJ-Rb4xCL8m8t7yU,16693
983
983
  ansible_test/_util/target/setup/bootstrap.sh,sha256=CPZvtpT8H7l2F2Th9kc85EseMm6evxsWPLCgfirBNSA,12994
984
984
  ansible_test/_util/target/setup/check_systemd_cgroup_v1.sh,sha256=Aq0T62x_KLtkGaWzYqWjvhchTqYFflrTbQET3h6xrT0,395
@@ -1001,9 +1001,9 @@ ansible_test/config/cloud-config-vultr.ini.template,sha256=XLKHk3lg_8ReQMdWfZzhh
1001
1001
  ansible_test/config/config.yml,sha256=wb3knoBmZewG3GWOMnRHoVPQWW4vPixKLPMNS6vJmTc,2620
1002
1002
  ansible_test/config/inventory.networking.template,sha256=bFNSk8zNQOaZ_twaflrY0XZ9mLwUbRLuNT0BdIFwvn4,1335
1003
1003
  ansible_test/config/inventory.winrm.template,sha256=1QU8W-GFLnYEw8yY9bVIvUAVvJYPM3hyoijf6-M7T00,1098
1004
- ansible_core-2.15.7rc1.dist-info/COPYING,sha256=CuBIWlvTemPmNgNZZBfk6w5lMzT6bH-TLKOg6F1K8ic,35148
1005
- ansible_core-2.15.7rc1.dist-info/METADATA,sha256=BN-cB-crEkutwnP18-SgIC2poE33Vu59JN2cwGlHTn0,6978
1006
- ansible_core-2.15.7rc1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
1007
- ansible_core-2.15.7rc1.dist-info/entry_points.txt,sha256=0mpmsrIhODChxKl3eS-NcVQCaMetBn8KdPLtVxQgR64,453
1008
- ansible_core-2.15.7rc1.dist-info/top_level.txt,sha256=IFbRLjAvih1DYzJWg3_F6t4sCzEMxRO7TOMNs6GkYHo,21
1009
- ansible_core-2.15.7rc1.dist-info/RECORD,,
1004
+ ansible_core-2.15.9.dist-info/COPYING,sha256=CuBIWlvTemPmNgNZZBfk6w5lMzT6bH-TLKOg6F1K8ic,35148
1005
+ ansible_core-2.15.9.dist-info/METADATA,sha256=TMxpqizUObDV8AC8aa0AyDK5jYgV551czxgnRHgtp9M,6975
1006
+ ansible_core-2.15.9.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
1007
+ ansible_core-2.15.9.dist-info/entry_points.txt,sha256=0mpmsrIhODChxKl3eS-NcVQCaMetBn8KdPLtVxQgR64,453
1008
+ ansible_core-2.15.9.dist-info/top_level.txt,sha256=IFbRLjAvih1DYzJWg3_F6t4sCzEMxRO7TOMNs6GkYHo,21
1009
+ ansible_core-2.15.9.dist-info/RECORD,,
@@ -3,8 +3,7 @@ alpine become=doas_sudo provider=aws arch=x86_64
3
3
  fedora/37 python=3.11 become=sudo provider=aws arch=x86_64 # untested in CI, known to occasionally hang during boot
4
4
  fedora/38 python=3.11 become=sudo provider=aws arch=x86_64
5
5
  fedora become=sudo provider=aws arch=x86_64
6
- freebsd/12.4 python=3.9 python_dir=/usr/local/bin become=su_sudo provider=aws arch=x86_64
7
- freebsd/13.1 python=3.8,3.7,3.9,3.10 python_dir=/usr/local/bin become=su_sudo provider=aws arch=x86_64
6
+ freebsd/13.2 python=3.8,3.7,3.9,3.10 python_dir=/usr/local/bin become=su_sudo provider=aws arch=x86_64
8
7
  freebsd python_dir=/usr/local/bin become=su_sudo provider=aws arch=x86_64
9
8
  macos/13.2 python=3.11 python_dir=/usr/local/bin become=sudo provider=parallels arch=x86_64
10
9
  macos python_dir=/usr/local/bin become=sudo provider=parallels arch=x86_64
@@ -197,21 +197,26 @@ def validate_metadata_file(path, is_ansible, check_deprecation_dates=False):
197
197
  avoid_additional_data
198
198
  )
199
199
 
200
- plugin_routing_schema = Any(
201
- Schema({
202
- ('deprecation'): Any(deprecation_schema),
203
- ('tombstone'): Any(tombstoning_schema),
204
- ('redirect'): fqcr,
205
- }, extra=PREVENT_EXTRA),
200
+ plugins_routing_common_schema = Schema({
201
+ ('deprecation'): Any(deprecation_schema),
202
+ ('tombstone'): Any(tombstoning_schema),
203
+ ('redirect'): fqcr,
204
+ }, extra=PREVENT_EXTRA)
205
+
206
+ plugin_routing_schema = Any(plugins_routing_common_schema)
207
+
208
+ # Adjusted schema for modules only
209
+ plugin_routing_schema_modules = Any(
210
+ plugins_routing_common_schema.extend({
211
+ ('action_plugin'): fqcr}
212
+ )
206
213
  )
207
214
 
208
215
  # Adjusted schema for module_utils
209
216
  plugin_routing_schema_mu = Any(
210
- Schema({
211
- ('deprecation'): Any(deprecation_schema),
212
- ('tombstone'): Any(tombstoning_schema),
213
- ('redirect'): Any(*string_types),
214
- }, extra=PREVENT_EXTRA),
217
+ plugins_routing_common_schema.extend({
218
+ ('redirect'): Any(*string_types)}
219
+ ),
215
220
  )
216
221
 
217
222
  list_dict_plugin_routing_schema = [{str_type: plugin_routing_schema}
@@ -220,6 +225,9 @@ def validate_metadata_file(path, is_ansible, check_deprecation_dates=False):
220
225
  list_dict_plugin_routing_schema_mu = [{str_type: plugin_routing_schema_mu}
221
226
  for str_type in string_types]
222
227
 
228
+ list_dict_plugin_routing_schema_modules = [{str_type: plugin_routing_schema_modules}
229
+ for str_type in string_types]
230
+
223
231
  plugin_schema = Schema({
224
232
  ('action'): Any(None, *list_dict_plugin_routing_schema),
225
233
  ('become'): Any(None, *list_dict_plugin_routing_schema),
@@ -233,7 +241,7 @@ def validate_metadata_file(path, is_ansible, check_deprecation_dates=False):
233
241
  ('inventory'): Any(None, *list_dict_plugin_routing_schema),
234
242
  ('lookup'): Any(None, *list_dict_plugin_routing_schema),
235
243
  ('module_utils'): Any(None, *list_dict_plugin_routing_schema_mu),
236
- ('modules'): Any(None, *list_dict_plugin_routing_schema),
244
+ ('modules'): Any(None, *list_dict_plugin_routing_schema_modules),
237
245
  ('netconf'): Any(None, *list_dict_plugin_routing_schema),
238
246
  ('shell'): Any(None, *list_dict_plugin_routing_schema),
239
247
  ('strategy'): Any(None, *list_dict_plugin_routing_schema),
@@ -560,6 +560,12 @@ def main():
560
560
  "ignore",
561
561
  "Python 3.5 support will be dropped in the next release of cryptography. Please upgrade your Python.")
562
562
 
563
+ # ansible.utils.unsafe_proxy attempts patching sys.intern generating a warning if it was already patched
564
+ warnings.filterwarnings(
565
+ "ignore",
566
+ "skipped sys.intern patch; appears to have already been patched"
567
+ )
568
+
563
569
  try:
564
570
  yield
565
571
  finally: