ansible-core 2.18.1__py3-none-any.whl → 2.18.2__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 (29) hide show
  1. ansible/cli/vault.py +3 -2
  2. ansible/executor/action_write_locks.py +3 -3
  3. ansible/executor/task_executor.py +2 -13
  4. ansible/executor/task_queue_manager.py +0 -2
  5. ansible/module_utils/ansible_release.py +1 -1
  6. ansible/module_utils/csharp/Ansible.Basic.cs +1 -1
  7. ansible/module_utils/facts/ansible_collector.py +6 -0
  8. ansible/playbook/play.py +3 -1
  9. ansible/plugins/action/copy.py +6 -1
  10. ansible/plugins/action/gather_facts.py +30 -5
  11. ansible/plugins/connection/__init__.py +21 -0
  12. ansible/plugins/connection/ssh.py +3 -3
  13. ansible/plugins/filter/regex_search.yml +4 -1
  14. ansible/plugins/shell/powershell.py +75 -3
  15. ansible/plugins/strategy/__init__.py +5 -3
  16. ansible/release.py +1 -1
  17. ansible/vars/manager.py +10 -2
  18. ansible/vars/reserved.py +12 -6
  19. {ansible_core-2.18.1.dist-info → ansible_core-2.18.2.dist-info}/METADATA +2 -2
  20. {ansible_core-2.18.1.dist-info → ansible_core-2.18.2.dist-info}/RECORD +29 -29
  21. {ansible_core-2.18.1.dist-info → ansible_core-2.18.2.dist-info}/WHEEL +1 -1
  22. ansible_test/_internal/commands/coverage/__init__.py +5 -5
  23. {ansible_core-2.18.1.dist-info → ansible_core-2.18.2.dist-info}/Apache-License.txt +0 -0
  24. {ansible_core-2.18.1.dist-info → ansible_core-2.18.2.dist-info}/COPYING +0 -0
  25. {ansible_core-2.18.1.dist-info → ansible_core-2.18.2.dist-info}/MIT-license.txt +0 -0
  26. {ansible_core-2.18.1.dist-info → ansible_core-2.18.2.dist-info}/PSF-license.txt +0 -0
  27. {ansible_core-2.18.1.dist-info → ansible_core-2.18.2.dist-info}/entry_points.txt +0 -0
  28. {ansible_core-2.18.1.dist-info → ansible_core-2.18.2.dist-info}/simplified_bsd.txt +0 -0
  29. {ansible_core-2.18.1.dist-info → ansible_core-2.18.2.dist-info}/top_level.txt +0 -0
ansible/cli/vault.py CHANGED
@@ -138,11 +138,12 @@ class VaultCLI(CLI):
138
138
  raise AnsibleOptionsError("At most one input file may be used with the --output option")
139
139
 
140
140
  if options.action == 'encrypt_string':
141
- if '-' in options.args or not options.args or options.encrypt_string_stdin_name:
141
+ if '-' in options.args or options.encrypt_string_stdin_name or (not options.args and not options.encrypt_string_prompt):
142
+ # prompting from stdin and reading from stdin are mutually exclusive, if stdin is still provided, it is ignored
142
143
  self.encrypt_string_read_stdin = True
143
144
 
144
- # TODO: prompting from stdin and reading from stdin seem mutually exclusive, but verify that.
145
145
  if options.encrypt_string_prompt and self.encrypt_string_read_stdin:
146
+ # should only trigger if prompt + either - or encrypt string stdin name were provided
146
147
  raise AnsibleOptionsError('The --prompt option is not supported if also reading input from stdin')
147
148
 
148
149
  return options
@@ -19,7 +19,7 @@ from __future__ import annotations
19
19
 
20
20
  import multiprocessing.synchronize
21
21
 
22
- from multiprocessing import Lock
22
+ from ansible.utils.multiprocessing import context as multiprocessing_context
23
23
 
24
24
  from ansible.module_utils.facts.system.pkg_mgr import PKG_MGRS
25
25
 
@@ -32,7 +32,7 @@ if 'action_write_locks' not in globals():
32
32
  # Below is a Lock for use when we weren't expecting a named module. It gets used when an action
33
33
  # plugin invokes a module whose name does not match with the action's name. Slightly less
34
34
  # efficient as all processes with unexpected module names will wait on this lock
35
- action_write_locks[None] = Lock()
35
+ action_write_locks[None] = multiprocessing_context.Lock()
36
36
 
37
37
  # These plugins are known to be called directly by action plugins with names differing from the
38
38
  # action plugin name. We precreate them here as an optimization.
@@ -41,4 +41,4 @@ if 'action_write_locks' not in globals():
41
41
 
42
42
  mods.update(('copy', 'file', 'setup', 'slurp', 'stat'))
43
43
  for mod_name in mods:
44
- action_write_locks[mod_name] = Lock()
44
+ action_write_locks[mod_name] = multiprocessing_context.Lock()
@@ -1073,18 +1073,6 @@ class TaskExecutor:
1073
1073
  option_vars = C.config.get_plugin_vars('connection', self._connection._load_name)
1074
1074
  varnames.extend(option_vars)
1075
1075
 
1076
- # create dict of 'templated vars'
1077
- options = {'_extras': {}}
1078
- for k in option_vars:
1079
- if k in variables:
1080
- options[k] = templar.template(variables[k])
1081
-
1082
- # add extras if plugin supports them
1083
- if getattr(self._connection, 'allow_extras', False):
1084
- for k in variables:
1085
- if k.startswith('ansible_%s_' % self._connection.extras_prefix) and k not in options:
1086
- options['_extras'][k] = templar.template(variables[k])
1087
-
1088
1076
  task_keys = self._task.dump_attrs()
1089
1077
 
1090
1078
  # The task_keys 'timeout' attr is the task's timeout, not the connection timeout.
@@ -1102,7 +1090,8 @@ class TaskExecutor:
1102
1090
  del task_keys['retries']
1103
1091
 
1104
1092
  # set options with 'templated vars' specific to this plugin and dependent ones
1105
- self._connection.set_options(task_keys=task_keys, var_options=options)
1093
+ var_options = self._connection._resolve_option_variables(variables, templar)
1094
+ self._connection.set_options(task_keys=task_keys, var_options=var_options)
1106
1095
  varnames.extend(self._set_plugin_options('shell', variables, templar, task_keys))
1107
1096
 
1108
1097
  if self._connection.become is not None:
@@ -39,7 +39,6 @@ from ansible.plugins.loader import callback_loader, strategy_loader, module_load
39
39
  from ansible.plugins.callback import CallbackBase
40
40
  from ansible.template import Templar
41
41
  from ansible.vars.hostvars import HostVars
42
- from ansible.vars.reserved import warn_if_reserved
43
42
  from ansible.utils.display import Display
44
43
  from ansible.utils.lock import lock_decorator
45
44
  from ansible.utils.multiprocessing import context as multiprocessing_context
@@ -282,7 +281,6 @@ class TaskQueueManager:
282
281
 
283
282
  all_vars = self._variable_manager.get_vars(play=play)
284
283
  templar = Templar(loader=self._loader, variables=all_vars)
285
- warn_if_reserved(all_vars, templar.environment.globals.keys())
286
284
 
287
285
  new_play = play.copy()
288
286
  new_play.post_validate(templar)
@@ -17,6 +17,6 @@
17
17
 
18
18
  from __future__ import annotations
19
19
 
20
- __version__ = '2.18.1'
20
+ __version__ = '2.18.2'
21
21
  __author__ = 'Ansible, Inc.'
22
22
  __codename__ = "Fool in the Rain"
@@ -1210,7 +1210,7 @@ namespace Ansible.Basic
1210
1210
  object val = requiredCheck[1];
1211
1211
  IList requirements = (IList)requiredCheck[2];
1212
1212
 
1213
- if (ParseStr(param[key]) != ParseStr(val))
1213
+ if (param[key] == null || ParseStr(param[key]) != ParseStr(val))
1214
1214
  continue;
1215
1215
 
1216
1216
  string term = "all";
@@ -113,7 +113,13 @@ class CollectorMetaDataCollector(collector.BaseFactCollector):
113
113
  self.module_setup = module_setup
114
114
 
115
115
  def collect(self, module=None, collected_facts=None):
116
+ # NOTE: deprecate/remove once DT lands
117
+ # we can return this data, but should not be top level key
116
118
  meta_facts = {'gather_subset': self.gather_subset}
119
+
120
+ # NOTE: this is just a boolean indicator that 'facts were gathered'
121
+ # and should be moved to the 'gather_facts' action plugin
122
+ # probably revised to handle modules/subsets combos
117
123
  if self.module_setup:
118
124
  meta_facts['module_setup'] = self.module_setup
119
125
  return meta_facts
ansible/playbook/play.py CHANGED
@@ -31,7 +31,6 @@ from ansible.playbook.helpers import load_list_of_blocks, load_list_of_roles
31
31
  from ansible.playbook.role import Role
32
32
  from ansible.playbook.task import Task
33
33
  from ansible.playbook.taggable import Taggable
34
- from ansible.vars.manager import preprocess_vars
35
34
  from ansible.utils.display import Display
36
35
 
37
36
  display = Display()
@@ -227,6 +226,9 @@ class Play(Base, Taggable, CollectionSearch):
227
226
  return self.roles
228
227
 
229
228
  def _load_vars_prompt(self, attr, ds):
229
+ # avoid circular dep
230
+ from ansible.vars.manager import preprocess_vars
231
+
230
232
  new_ds = preprocess_vars(ds)
231
233
  vars_prompts = []
232
234
  if new_ds is not None:
@@ -26,7 +26,7 @@ import tempfile
26
26
  import traceback
27
27
 
28
28
  from ansible import constants as C
29
- from ansible.errors import AnsibleError, AnsibleFileNotFound
29
+ from ansible.errors import AnsibleError, AnsibleActionFail, AnsibleFileNotFound
30
30
  from ansible.module_utils.basic import FILE_COMMON_ARGUMENTS
31
31
  from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
32
32
  from ansible.module_utils.parsing.convert_bool import boolean
@@ -414,6 +414,11 @@ class ActionModule(ActionBase):
414
414
  result = super(ActionModule, self).run(tmp, task_vars)
415
415
  del tmp # tmp no longer has any effect
416
416
 
417
+ # ensure user is not setting internal parameters
418
+ for internal in ('_original_basename', '_diff_peek'):
419
+ if self._task.args.get(internal, None) is not None:
420
+ raise AnsibleActionFail(f'Invalid parameter specified: "{internal}"')
421
+
417
422
  source = self._task.args.get('src', None)
418
423
  content = self._task.args.get('content', None)
419
424
  dest = self._task.args.get('dest', None)
@@ -8,6 +8,7 @@ import time
8
8
  import typing as t
9
9
 
10
10
  from ansible import constants as C
11
+ from ansible.errors import AnsibleActionFail
11
12
  from ansible.executor.module_common import get_action_args_with_defaults
12
13
  from ansible.module_utils.parsing.convert_bool import boolean
13
14
  from ansible.plugins.action import ActionBase
@@ -61,6 +62,7 @@ class ActionModule(ActionBase):
61
62
  return mod_args
62
63
 
63
64
  def _combine_task_result(self, result: dict[str, t.Any], task_result: dict[str, t.Any]) -> dict[str, t.Any]:
65
+ """ builds the final result to return """
64
66
  filtered_res = {
65
67
  'ansible_facts': task_result.get('ansible_facts', {}),
66
68
  'warnings': task_result.get('warnings', []),
@@ -70,6 +72,33 @@ class ActionModule(ActionBase):
70
72
  # on conflict the last plugin processed wins, but try to do deep merge and append to lists.
71
73
  return merge_hash(result, filtered_res, list_merge='append_rp')
72
74
 
75
+ def _handle_smart(self, modules: list, task_vars: dict[str, t.Any]):
76
+ """ Updates the module list when 'smart' is used, lookup network os mappings or use setup, warn when things seem inconsistent """
77
+
78
+ if 'smart' not in modules:
79
+ return
80
+
81
+ modules.pop(modules.index('smart')) # remove as this will cause 'module not found' errors
82
+ network_os = self._task.args.get('network_os', task_vars.get('ansible_network_os', task_vars.get('ansible_facts', {}).get('network_os')))
83
+
84
+ if network_os:
85
+
86
+ connection_map = C.config.get_config_value('CONNECTION_FACTS_MODULES', variables=task_vars)
87
+ if network_os in connection_map:
88
+ modules.append(connection_map[network_os])
89
+ elif not modules:
90
+ raise AnsibleActionFail(f"No fact modules available and we could not find a fact module for your network OS ({network_os}), "
91
+ "try setting one via the `FACTS_MODULES` configuration.")
92
+
93
+ if set(modules).intersection(set(C._ACTION_SETUP)):
94
+ # most don't realize how setup works with networking connection plugins (forced_local)
95
+ self._display.warning("Detected 'setup' module and a network OS is set, the output when running it will reflect 'localhost'"
96
+ " and not the target when a netwoking connection plugin is used.")
97
+
98
+ elif not set(modules).difference(set(C._ACTION_SETUP)):
99
+ # no network OS and setup not in list, add setup by default since 'smart'
100
+ modules.append('ansible.legacy.setup')
101
+
73
102
  def run(self, tmp: t.Optional[str] = None, task_vars: t.Optional[dict[str, t.Any]] = None) -> dict[str, t.Any]:
74
103
 
75
104
  result = super(ActionModule, self).run(tmp, task_vars)
@@ -77,13 +106,9 @@ class ActionModule(ActionBase):
77
106
 
78
107
  # copy the value with list() so we don't mutate the config
79
108
  modules = list(C.config.get_config_value('FACTS_MODULES', variables=task_vars))
109
+ self._handle_smart(modules, task_vars)
80
110
 
81
111
  parallel = task_vars.pop('ansible_facts_parallel', self._task.args.pop('parallel', None))
82
- if 'smart' in modules:
83
- connection_map = C.config.get_config_value('CONNECTION_FACTS_MODULES', variables=task_vars)
84
- network_os = self._task.args.get('network_os', task_vars.get('ansible_network_os', task_vars.get('ansible_facts', {}).get('network_os')))
85
- modules.extend([connection_map.get(network_os or self._connection.ansible_name, 'ansible.legacy.setup')])
86
- modules.pop(modules.index('smart'))
87
112
 
88
113
  failed = {}
89
114
  skipped = {}
@@ -285,6 +285,27 @@ class ConnectionBase(AnsiblePlugin):
285
285
  display.debug('Set connection var {0} to {1}'.format(varname, value))
286
286
  variables[varname] = value
287
287
 
288
+ def _resolve_option_variables(self, variables, templar):
289
+ """
290
+ Return a dict of variable -> templated value, for any variables that
291
+ that match options registered by this plugin.
292
+ """
293
+ # create dict of 'templated vars'
294
+ var_options = {
295
+ '_extras': {},
296
+ }
297
+ for var_name in C.config.get_plugin_vars('connection', self._load_name):
298
+ if var_name in variables:
299
+ var_options[var_name] = templar.template(variables[var_name])
300
+
301
+ # add extras if plugin supports them
302
+ if getattr(self, 'allow_extras', False):
303
+ for var_name in variables:
304
+ if var_name.startswith(f'ansible_{self.extras_prefix}_') and var_name not in var_options:
305
+ var_options['_extras'][var_name] = templar.template(variables[var_name])
306
+
307
+ return var_options
308
+
288
309
 
289
310
  class NetworkConnectionBase(ConnectionBase):
290
311
  """
@@ -389,7 +389,7 @@ from ansible.errors import (
389
389
  from ansible.module_utils.six import PY3, text_type, binary_type
390
390
  from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
391
391
  from ansible.plugins.connection import ConnectionBase, BUFSIZE
392
- from ansible.plugins.shell.powershell import _parse_clixml
392
+ from ansible.plugins.shell.powershell import _replace_stderr_clixml
393
393
  from ansible.utils.display import Display
394
394
  from ansible.utils.path import unfrackpath, makedirs_safe
395
395
 
@@ -1327,8 +1327,8 @@ class Connection(ConnectionBase):
1327
1327
  (returncode, stdout, stderr) = self._run(cmd, in_data, sudoable=sudoable)
1328
1328
 
1329
1329
  # When running on Windows, stderr may contain CLIXML encoded output
1330
- if getattr(self._shell, "_IS_WINDOWS", False) and stderr.startswith(b"#< CLIXML"):
1331
- stderr = _parse_clixml(stderr)
1330
+ if getattr(self._shell, "_IS_WINDOWS", False):
1331
+ stderr = _replace_stderr_clixml(stderr)
1332
1332
 
1333
1333
  return (returncode, stdout, stderr)
1334
1334
 
@@ -8,6 +8,9 @@ DOCUMENTATION:
8
8
  - Maps to Python's C(re.search).
9
9
  - 'The substring matched by the group is accessible via the symbolic group name or
10
10
  the ``\{number}`` special sequence. See examples section.'
11
+ - The return for no match will be C(None) in most cases, depending on whether it is used with other filters/tests or not.
12
+ It also depends on the Jinja version used and whether native is enabled.
13
+ - "For a more complete explanation see U(https://docs.ansible.com/ansible-core/devel/reference_appendices/faq.html#why-does-the-regex-search-filter-return-none-instead-of-an-empty-string)."
11
14
  positional: _input, _regex
12
15
  options:
13
16
  _input:
@@ -52,5 +55,5 @@ EXAMPLES: |
52
55
 
53
56
  RETURN:
54
57
  _value:
55
- description: Matched string or empty string if no match.
58
+ description: Matched string or if no match a C(None) or an empty string (see notes)
56
59
  type: str
@@ -26,13 +26,85 @@ from ansible.module_utils.common.text.converters import to_bytes, to_text
26
26
  from ansible.plugins.shell import ShellBase
27
27
 
28
28
  # This is weird, we are matching on byte sequences that match the utf-16-be
29
- # matches for '_x(a-fA-F0-9){4}_'. The \x00 and {8} will match the hex sequence
30
- # when it is encoded as utf-16-be.
31
- _STRING_DESERIAL_FIND = re.compile(rb"\x00_\x00x([\x00(a-fA-F0-9)]{8})\x00_")
29
+ # matches for '_x(a-fA-F0-9){4}_'. The \x00 and {4} will match the hex sequence
30
+ # when it is encoded as utf-16-be byte sequence.
31
+ _STRING_DESERIAL_FIND = re.compile(rb"\x00_\x00x((?:\x00[a-fA-F0-9]){4})\x00_")
32
32
 
33
33
  _common_args = ['PowerShell', '-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Unrestricted']
34
34
 
35
35
 
36
+ def _replace_stderr_clixml(stderr: bytes) -> bytes:
37
+ """Replace CLIXML with stderr data.
38
+
39
+ Tries to replace an embedded CLIXML string with the actual stderr data. If
40
+ it fails to parse the CLIXML data, it will return the original data. This
41
+ will replace any line inside the stderr string that contains a valid CLIXML
42
+ sequence.
43
+
44
+ :param bytes stderr: The stderr to try and decode.
45
+
46
+ :returns: The stderr with the decoded CLIXML data or the original data.
47
+ """
48
+ clixml_header = b"#< CLIXML\r\n"
49
+
50
+ if stderr.find(clixml_header) == -1:
51
+ return stderr
52
+
53
+ lines: list[bytes] = []
54
+ is_clixml = False
55
+ for line in stderr.splitlines(True):
56
+ if is_clixml:
57
+ is_clixml = False
58
+
59
+ # If the line does not contain the closing CLIXML tag, we just
60
+ # add the found header line and this line without trying to parse.
61
+ end_idx = line.find(b"</Objs>")
62
+ if end_idx == -1:
63
+ lines.append(clixml_header)
64
+ lines.append(line)
65
+ continue
66
+
67
+ clixml = line[: end_idx + 7]
68
+ remaining = line[end_idx + 7 :]
69
+
70
+ # While we expect the stderr to be UTF-8 encoded, we fallback to
71
+ # the most common "ANSI" codepage used by Windows cp437 if it is
72
+ # not valid UTF-8.
73
+ try:
74
+ clixml.decode("utf-8")
75
+ except UnicodeDecodeError:
76
+ # cp427 can decode any sequence and once we have the string, we
77
+ # can encode any cp427 chars to UTF-8.
78
+ clixml_text = clixml.decode("cp437")
79
+ clixml = clixml_text.encode("utf-8")
80
+
81
+ try:
82
+ decoded_clixml = _parse_clixml(clixml)
83
+ lines.append(decoded_clixml)
84
+ if remaining:
85
+ lines.append(remaining)
86
+
87
+ except Exception:
88
+ # Any errors and we just add the original CLIXML header and
89
+ # line back in.
90
+ lines.append(clixml_header)
91
+ lines.append(line)
92
+
93
+ elif line == clixml_header:
94
+ # The next line should contain the full CLIXML data.
95
+ is_clixml = True
96
+
97
+ else:
98
+ lines.append(line)
99
+
100
+ # This should never happen but if there was a CLIXML header without a newline
101
+ # following it, we need to add it back.
102
+ if is_clixml:
103
+ lines.append(clixml_header)
104
+
105
+ return b"".join(lines)
106
+
107
+
36
108
  def _parse_clixml(data: bytes, stream: str = "Error") -> bytes:
37
109
  """
38
110
  Takes a byte string like '#< CLIXML\r\n<Objs...' and extracts the stream
@@ -28,7 +28,7 @@ import time
28
28
  import typing as t
29
29
 
30
30
  from collections import deque
31
- from multiprocessing import Lock
31
+
32
32
 
33
33
  from jinja2.exceptions import UndefinedError
34
34
 
@@ -55,6 +55,7 @@ from ansible.utils.fqcn import add_internal_fqcns
55
55
  from ansible.utils.unsafe_proxy import wrap_var
56
56
  from ansible.utils.sentinel import Sentinel
57
57
  from ansible.utils.vars import combine_vars
58
+ from ansible.utils.multiprocessing import context as multiprocessing_context
58
59
  from ansible.vars.clean import strip_internal_keys, module_response_deepcopy
59
60
 
60
61
  display = Display()
@@ -365,7 +366,7 @@ class StrategyBase:
365
366
 
366
367
  if task.action not in action_write_locks.action_write_locks:
367
368
  display.debug('Creating lock for %s' % task.action)
368
- action_write_locks.action_write_locks[task.action] = Lock()
369
+ action_write_locks.action_write_locks[task.action] = multiprocessing_context.Lock()
369
370
 
370
371
  # create a templar and template things we need later for the queuing process
371
372
  templar = Templar(loader=self._loader, variables=task_vars)
@@ -1068,7 +1069,8 @@ class StrategyBase:
1068
1069
  del self._active_connections[target_host]
1069
1070
  else:
1070
1071
  connection = plugin_loader.connection_loader.get(play_context.connection, play_context, os.devnull)
1071
- connection.set_options(task_keys=task.dump_attrs(), var_options=all_vars)
1072
+ var_options = connection._resolve_option_variables(all_vars, templar)
1073
+ connection.set_options(task_keys=task.dump_attrs(), var_options=var_options)
1072
1074
  play_context.set_attributes_from_plugin(connection)
1073
1075
 
1074
1076
  if connection:
ansible/release.py CHANGED
@@ -17,6 +17,6 @@
17
17
 
18
18
  from __future__ import annotations
19
19
 
20
- __version__ = '2.18.1'
20
+ __version__ = '2.18.2'
21
21
  __author__ = 'Ansible, Inc.'
22
22
  __codename__ = "Fool in the Rain"
ansible/vars/manager.py CHANGED
@@ -39,6 +39,7 @@ from ansible.utils.vars import combine_vars, load_extra_vars, load_options_vars
39
39
  from ansible.utils.unsafe_proxy import wrap_var
40
40
  from ansible.vars.clean import namespace_facts, clean_facts
41
41
  from ansible.vars.plugins import get_vars_from_inventory_sources, get_vars_from_path
42
+ from ansible.vars.reserved import warn_if_reserved
42
43
 
43
44
  display = Display()
44
45
 
@@ -415,6 +416,9 @@ class VariableManager:
415
416
  # extra vars
416
417
  all_vars = _combine_and_track(all_vars, self._extra_vars, "extra vars")
417
418
 
419
+ # before we add 'reserved vars', check we didn't add any reserved vars
420
+ warn_if_reserved(all_vars.keys())
421
+
418
422
  # magic variables
419
423
  all_vars = _combine_and_track(all_vars, magic_variables, "magic vars")
420
424
 
@@ -560,6 +564,7 @@ class VariableManager:
560
564
  if not isinstance(facts, Mapping):
561
565
  raise AnsibleAssertionError("the type of 'facts' to set for host_facts should be a Mapping but is a %s" % type(facts))
562
566
 
567
+ warn_if_reserved(facts.keys())
563
568
  try:
564
569
  host_cache = self._fact_cache[host]
565
570
  except KeyError:
@@ -583,15 +588,18 @@ class VariableManager:
583
588
  if not isinstance(facts, Mapping):
584
589
  raise AnsibleAssertionError("the type of 'facts' to set for nonpersistent_facts should be a Mapping but is a %s" % type(facts))
585
590
 
591
+ warn_if_reserved(facts.keys())
586
592
  try:
587
593
  self._nonpersistent_fact_cache[host] |= facts
588
594
  except KeyError:
589
595
  self._nonpersistent_fact_cache[host] = facts
590
596
 
591
597
  def set_host_variable(self, host, varname, value):
592
- '''
598
+ """
593
599
  Sets a value in the vars_cache for a host.
594
- '''
600
+ """
601
+
602
+ warn_if_reserved(varname)
595
603
  if host not in self._vars_cache:
596
604
  self._vars_cache[host] = dict()
597
605
  if varname in self._vars_cache[host] and isinstance(self._vars_cache[host][varname], MutableMapping) and isinstance(value, MutableMapping):
ansible/vars/reserved.py CHANGED
@@ -21,15 +21,17 @@ from ansible.playbook import Play
21
21
  from ansible.playbook.block import Block
22
22
  from ansible.playbook.role import Role
23
23
  from ansible.playbook.task import Task
24
+ from ansible.template import Templar
24
25
  from ansible.utils.display import Display
25
26
 
26
27
  display = Display()
27
28
 
28
29
 
29
- def get_reserved_names(include_private=True):
30
- ''' this function returns the list of reserved names associated with play objects'''
30
+ def get_reserved_names(include_private: bool = True) -> set[str]:
31
+ """ this function returns the list of reserved names associated with play objects"""
31
32
 
32
- public = set()
33
+ templar = Templar(loader=None)
34
+ public = set(templar.environment.globals.keys())
33
35
  private = set()
34
36
  result = set()
35
37
 
@@ -58,11 +60,15 @@ def get_reserved_names(include_private=True):
58
60
  else:
59
61
  result = public
60
62
 
63
+ # due to Collectors always adding, need to ignore this
64
+ # eventually should remove after we deprecate it in setup.py
65
+ result.remove('gather_subset')
66
+
61
67
  return result
62
68
 
63
69
 
64
- def warn_if_reserved(myvars, additional=None):
65
- ''' this function warns if any variable passed conflicts with internally reserved names '''
70
+ def warn_if_reserved(myvars: list[str], additional: list[str] | None = None) -> None:
71
+ """ this function warns if any variable passed conflicts with internally reserved names """
66
72
 
67
73
  if additional is None:
68
74
  reserved = _RESERVED_NAMES
@@ -75,7 +81,7 @@ def warn_if_reserved(myvars, additional=None):
75
81
  display.warning('Found variable using reserved name: %s' % varname)
76
82
 
77
83
 
78
- def is_reserved_name(name):
84
+ def is_reserved_name(name: str) -> bool:
79
85
  return name in _RESERVED_NAMES
80
86
 
81
87
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: ansible-core
3
- Version: 2.18.1
3
+ Version: 2.18.2
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=dSgbrzNsmhYc4GQOWZvRm4XKgf--_MUWcMa_9_7l5Pc,9757
4
4
  ansible/context.py,sha256=oKYyfjfWpy8vDeProtqfnqSmuij_t75_5e5t0U_hQ1g,1933
5
5
  ansible/keyword_desc.yml,sha256=xD-MRMB8mSRaj2ADwRnjIEbOwJKbc6BYadouGPfS0mI,7462
6
- ansible/release.py,sha256=nwl33uI0Znd--VXfd2FGtervHk-ITobNGw-XJN9qeOA,836
6
+ ansible/release.py,sha256=U-5xX-4Rd1AukTzNrukHD-Qk_UrpbV4_Z-oIFaTMD0A,836
7
7
  ansible/_vendor/__init__.py,sha256=2QBeBwT7uG7M3Aw-pIdCpt6XPtHMCpbEKfACYKA7xIg,2033
8
8
  ansible/cli/__init__.py,sha256=e0KjeLfG1Ketbwl-uOmQ-zXoq3_El80LnHTGu80d1gs,28111
9
9
  ansible/cli/adhoc.py,sha256=quJ9WzRzf3dz_dtDGmahNMffqyNVy1jzQCMo21YL5Qg,8194
@@ -14,7 +14,7 @@ ansible/cli/galaxy.py,sha256=KXTPM-hXtamDZUZXHRPGs2BPpIaf3HztlgyH9wOys7Q,95000
14
14
  ansible/cli/inventory.py,sha256=TTVyNM1G2IkTthmISmTGqlr4KjZKGrRVOh9gIJfjGtk,16765
15
15
  ansible/cli/playbook.py,sha256=d0x_X0BXjxYjPJ-qc6JcyGxR6IzxdvnSjoT4tUtaGKQ,10865
16
16
  ansible/cli/pull.py,sha256=g3PsUQ2UTj2L9IRKhHXRNzJ7X-uzwmk4plpRHxZrWtM,17287
17
- ansible/cli/vault.py,sha256=pwrXBRpVjcz7T_0UdzG63lQuwhMHdGtSOVj4ZEDYBaw,22954
17
+ ansible/cli/vault.py,sha256=dICxhXQMRMTguu7gJW8qhGohiNdGn1Xxubt1kf2fRBc,23118
18
18
  ansible/cli/arguments/__init__.py,sha256=_4taT82hZKKTzhdXKmIgqxWwuG21XZxF874V2k1e3us,168
19
19
  ansible/cli/arguments/option_helpers.py,sha256=YiiGDtsXIwFg8mZPeQnYHsEUgsjUfeLCRrpks8hUc_Q,18488
20
20
  ansible/cli/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -31,14 +31,14 @@ ansible/config/manager.py,sha256=27_GXGb3SxX0Shqf5YtHvDSoycinzsDAjaPqwPsbY5o,291
31
31
  ansible/errors/__init__.py,sha256=Dd-jh7JVwfweicHg6irB9ugrK66vHATv9eiRbEep4dM,14943
32
32
  ansible/errors/yaml_strings.py,sha256=fKfgD3rC017dyMackTpu-LkvbsdnsfBAKCxMH-fDtIg,3858
33
33
  ansible/executor/__init__.py,sha256=mRvbCJPA-_veSG5ka3v04G5vsarLVDeB3EWFsu6geSI,749
34
- ansible/executor/action_write_locks.py,sha256=Up2n3cwFCr4T4IvttHpe3QOxRBF_9NgWJ1tFm9CHpfM,1915
34
+ ansible/executor/action_write_locks.py,sha256=DcjCvRELlz5dyUDxCjCZCVjy4-j4u0y-YNgY90dvbG0,2007
35
35
  ansible/executor/interpreter_discovery.py,sha256=z0ekwq9rND1wAZChHOYNfav7ycTvnkgVFPEek8aXj-I,9975
36
36
  ansible/executor/module_common.py,sha256=4pVfjMgCle9ttAZTeuwSx3Kdi0rljagyHC11i4VnCl4,65755
37
37
  ansible/executor/play_iterator.py,sha256=Oazd9aWy4zB67uy27sYg4BveFx_Uf_tIsbhD76hMc28,32496
38
38
  ansible/executor/playbook_executor.py,sha256=qurZBiWjAWWRYcHb3ti4sBI8_WotOYvTRDar4JC3leE,14764
39
39
  ansible/executor/stats.py,sha256=gcBhJQrZTgE95737d6lArJ3FpTlbAfVt6GMhEqs5ZPU,3180
40
- ansible/executor/task_executor.py,sha256=99oxT0B787aRpw7B8OssXWuzltcfiraGISnIpHTo7U4,61338
41
- ansible/executor/task_queue_manager.py,sha256=fC404XkveICb7hRwIVu4PvRNgFkFLCNihsGsUDHVFzg,18640
40
+ ansible/executor/task_executor.py,sha256=bGD5I1sKTY2zKMhGarTBEvOg3nscPo8ZJTFwWN_Fy-g,60913
41
+ ansible/executor/task_queue_manager.py,sha256=hBnT_wAeS9GNclT8IXJmXm6lMVQKkhyj2ShCi66W_VA,18518
42
42
  ansible/executor/task_result.py,sha256=48zZWpxCiM0Z_MVG9zGQGCxHLNzs1horT68Qmfa-v_8,5696
43
43
  ansible/executor/discovery/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
44
  ansible/executor/discovery/python_target.py,sha256=GW0tFmxr75vyFxKAIznJDEfjfSz1HaGbqRpUUif1LT4,1181
@@ -141,7 +141,7 @@ ansible/inventory/host.py,sha256=PDb5OTplhfpUIvdHiP2BckUOB1gUl302N-3sW0_sTyg,503
141
141
  ansible/inventory/manager.py,sha256=45mHgZTAkQ3IjAtrgsNzJXvynC-HIEor-JJE-V3xXN4,29454
142
142
  ansible/module_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
143
143
  ansible/module_utils/_text.py,sha256=VkWgAnSNVCbTQqZgllUObBFsH3uM4EUW5srl1UR9t1g,544
144
- ansible/module_utils/ansible_release.py,sha256=nwl33uI0Znd--VXfd2FGtervHk-ITobNGw-XJN9qeOA,836
144
+ ansible/module_utils/ansible_release.py,sha256=U-5xX-4Rd1AukTzNrukHD-Qk_UrpbV4_Z-oIFaTMD0A,836
145
145
  ansible/module_utils/api.py,sha256=r4wd6XZGhUnxMF416Ry6ebgq8BIhjCPSPOvO2ZtrYxE,5785
146
146
  ansible/module_utils/basic.py,sha256=fogfpo_l7JtS34WvgwwOebmPfMhFjQaJN5CwjKgUJVE,86291
147
147
  ansible/module_utils/connection.py,sha256=8TviwCucQ7d_JILwaUHE4tCuNfR3U1WFkmxLMxWa8Rw,7671
@@ -185,7 +185,7 @@ ansible/module_utils/compat/selinux.py,sha256=9bq2UMTE_PILEHdvUsXPk_84oWfKiMppyr
185
185
  ansible/module_utils/compat/typing.py,sha256=J_K9Ru1-f0KSKO_WhWGRCh0WBNWl6jUmQK1_0yYYZOs,736
186
186
  ansible/module_utils/compat/version.py,sha256=ifck3MH9LhxMENpZXOrntEqX6b7X8shknt3Fweg6AzQ,12734
187
187
  ansible/module_utils/csharp/Ansible.AccessToken.cs,sha256=TIOpRx4lv9FlhMyWfHS30CIMRtM3uqR8-u6Rv0X1HWE,16390
188
- ansible/module_utils/csharp/Ansible.Basic.cs,sha256=xp1pMZNhib3vhR3Wdc5JlDv1SORo4dIGjc17LmnLr1g,78845
188
+ ansible/module_utils/csharp/Ansible.Basic.cs,sha256=fzeoQXu21SAPWE5MSw33T_6-iZDoTDkH2qdEV1Xf2ww,78867
189
189
  ansible/module_utils/csharp/Ansible.Become.cs,sha256=g0FyAMO3kl186IGhgACQhNAMP8o2UHNzXVUv0Enau2w,32793
190
190
  ansible/module_utils/csharp/Ansible.Privilege.cs,sha256=7e46na6k6ygdRwN53bzfIS8O-IwfM1TF_q5DeFH2Z80,19398
191
191
  ansible/module_utils/csharp/Ansible.Process.cs,sha256=bON6hExhSB-SR2p2ryFZj6kU3a5TxonFv498wg2Je98,19452
@@ -193,7 +193,7 @@ ansible/module_utils/csharp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
193
193
  ansible/module_utils/distro/__init__.py,sha256=m0TmpmCD9JjwUo-kjnGQbW-qMBzZ2zir-QaQRQcc2Vs,1943
194
194
  ansible/module_utils/distro/_distro.py,sha256=AuS5qgpCjnm1SMJjQ8eUkZBR_P57NRYrsz1xXhbXD8s,49584
195
195
  ansible/module_utils/facts/__init__.py,sha256=Vyndmo-7rUjG-SX3hQHGoviksC_DeKSijZ2tFDESIAQ,1890
196
- ansible/module_utils/facts/ansible_collector.py,sha256=TGc3uEaOx0u-ucNM5_pt0HQTG-mN8zlQJLYPZXoeEFw,6566
196
+ ansible/module_utils/facts/ansible_collector.py,sha256=CdvWuu2_JV1zkXP-Das8P6qMM_Ch56idq2OTaaTut-4,6883
197
197
  ansible/module_utils/facts/collector.py,sha256=gU4L-zklNx3pS-G1ROx8nkbvrAKT3LPX-nQSLoeSOeQ,14716
198
198
  ansible/module_utils/facts/compat.py,sha256=jX8FsMTpZcdrFxIYsxaVrHYn69Pu7hWqehU97ncaC2A,4062
199
199
  ansible/module_utils/facts/default_collectors.py,sha256=iKefVeINbQuhXok28HxuT-MNhDHMHDQdNGvgD2SqmoQ,8376
@@ -382,7 +382,7 @@ ansible/playbook/helpers.py,sha256=jFUM97igAQastlBo8x0-SmwsTVGO1f0SPY5896aMgPg,1
382
382
  ansible/playbook/included_file.py,sha256=-Pd20gvOv2FZW6ReaoicjjIlZiJ1Sc607rFnwtrqycY,11735
383
383
  ansible/playbook/loop_control.py,sha256=F9ch4fIcYkhbvuMKZVqGqzxzujDUcciXoDoX7RK44To,2022
384
384
  ansible/playbook/notifiable.py,sha256=MQz4VZuOga35VLcdUxVd9FQVzFg-djtQZhs09DS2juA,299
385
- ansible/playbook/play.py,sha256=KJ5m0bpIWFz-rSy0WjSH4DhtsYAu4oMlIRvD0REKGik,15525
385
+ ansible/playbook/play.py,sha256=FjDa5dZiYM031gTW_4LSbgdZXMSZxfUjA4z4A5zbW_k,15563
386
386
  ansible/playbook/play_context.py,sha256=BEOXI3xfqFw5AD_reKbJulpxJGgwYG-jLvs8RY4SQbg,13846
387
387
  ansible/playbook/playbook_include.py,sha256=IqdVFE5F7eEnCtl7839c_rh9yuc4A4Oz5iIyG1DtptU,7492
388
388
  ansible/playbook/role_include.py,sha256=NCgDHtXlOltJ0XXSgGTTxDVrLC6IBe_d9SgNGXtsI20,7575
@@ -403,12 +403,12 @@ ansible/plugins/action/assemble.py,sha256=feMs3r2BAgQGQnpPmzJIGI7BSfOUl0eiyTVwln
403
403
  ansible/plugins/action/assert.py,sha256=mAPHyQ03Qb6nxIFuFiUHWGR56bTw0tA61fYX22_2OTI,5103
404
404
  ansible/plugins/action/async_status.py,sha256=Cv6dLt94Z6YIPZpPIDhS_yC7yqKtT13HyDdaIONMUCU,1726
405
405
  ansible/plugins/action/command.py,sha256=N09Vf2QypBMZ6NSptQGbf6EAN-kfqLCROGPkOSgV3SY,1069
406
- ansible/plugins/action/copy.py,sha256=5gEcEtSkZ3FXljZY9lldsS_g6e1DgAyEXTgHjNnlvn0,27446
406
+ ansible/plugins/action/copy.py,sha256=VKn_OMPz-_B8KaKl4htlJedn95RMrpmGO_tWOFIg6ys,27735
407
407
  ansible/plugins/action/debug.py,sha256=vPmHIfMAbuqpHb2aq0QS7M_g7Fu5pFTwMoYjCKCAa2E,3472
408
408
  ansible/plugins/action/dnf.py,sha256=N10UXOlFgqzwQgoQfzlqpXIAgHB69OZvfwoC-m2-geM,3667
409
409
  ansible/plugins/action/fail.py,sha256=_1JuS0Z8Y8EB4FKG1u7KdP6xMuLobRHJsmtzmvN2CkU,1457
410
410
  ansible/plugins/action/fetch.py,sha256=cQAmUWEGMDjfVfHGviNtsT4i06rnoubL3EgrOlUZbLw,10188
411
- ansible/plugins/action/gather_facts.py,sha256=JFkrn3_78A7eUw0I3DsfUoe3Pu3wVLkhLUiOJ7Oyk0A,7863
411
+ ansible/plugins/action/gather_facts.py,sha256=yNUrBPdzdJoA6euqy6k-gWpS_6yS0m-iBNq438PsbKk,9186
412
412
  ansible/plugins/action/group_by.py,sha256=97d4TF9o7vS5y0s1HfGgvh70l2gkQ2uUGxy0knlok5Y,1894
413
413
  ansible/plugins/action/include_vars.py,sha256=_xPrP_BeGqbhvpJYQFDUkREL9UzZ6Y4q_AnCshvsn1A,11573
414
414
  ansible/plugins/action/normal.py,sha256=cCHrZ3z2kB_wnnSNkmJHJWcJNRgdoxnLUNeHex-P8DE,1854
@@ -441,11 +441,11 @@ ansible/plugins/callback/minimal.py,sha256=51pTYXwnCAm4Z4TYbWTu-wq8gKpYCeq1AuSD8
441
441
  ansible/plugins/callback/oneline.py,sha256=FkE0lEoH_sZoxSgjeAvc0eH6Rt4k0Qi6fV9Pte8WYxQ,3450
442
442
  ansible/plugins/callback/tree.py,sha256=LRR7Aq0xYGZ0fQGCaenEoslEd5669yK259UQs7ai4tI,3014
443
443
  ansible/plugins/cliconf/__init__.py,sha256=gmcmxY7ssnbeMSRNO8d3qag_QmqM9vkcdBT42AKMy1E,22719
444
- ansible/plugins/connection/__init__.py,sha256=7B9UmhcM4divUhg-RsurhOOGQiCVeLGGh0Zp_zCvK4w,17947
444
+ ansible/plugins/connection/__init__.py,sha256=z3FcfUSemloUoUQokC8GBe6uTUvfBed6vIFAzbpIDyw,18825
445
445
  ansible/plugins/connection/local.py,sha256=A-XQy_wIky16xrgkm2KW2jyZLpzmcUPjNOPtoQQnDJg,8339
446
446
  ansible/plugins/connection/paramiko_ssh.py,sha256=w86LCVdqICCLqFtTPxUUMqXCzQEW_06rLCAFYHxCHlU,27195
447
447
  ansible/plugins/connection/psrp.py,sha256=VgDVeSVFANMrm4SN5m_JEsRanPJ-V08aoxXVs5RAixc,33543
448
- ansible/plugins/connection/ssh.py,sha256=QRfQjIg4omxqOyhamxRyDPsxdFGM7HG6071SODdgMf4,62224
448
+ ansible/plugins/connection/ssh.py,sha256=gyAJNb0sjkdZLoAQ1heEm_SjZR9ohz4bLsVgv2aKE6Y,62206
449
449
  ansible/plugins/connection/winrm.py,sha256=XLeUlCxhePUsDKXUrq_yqN1Ydu4Re8RsbZWTxdy8Muc,42188
450
450
  ansible/plugins/doc_fragments/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
451
451
  ansible/plugins/doc_fragments/action_common_attributes.py,sha256=OaP2is2r9wm_f8gbLZhDDDwccg1joXMvJM72vbgcbIo,2442
@@ -510,7 +510,7 @@ ansible/plugins/filter/realpath.yml,sha256=9r5FyANyU3sAEgEiKui69Kphy-aeos6FukqAV
510
510
  ansible/plugins/filter/regex_escape.yml,sha256=L1c6OrzqOYpkRmdWJ_ZTalY07lojcYItzdciAaBmBoI,688
511
511
  ansible/plugins/filter/regex_findall.yml,sha256=KyKpce7oAF0ok3044sQS2w15UbF4o7u3QwbqFtP56ao,1425
512
512
  ansible/plugins/filter/regex_replace.yml,sha256=gopa5TURn49Xg-W1VcJ9GNTMWhB_wqN6vqHqNoB-2Cg,2421
513
- ansible/plugins/filter/regex_search.yml,sha256=ue74lf9chJW_y72XuTpxneyE5BSk9NTtO6Le_WSJOcU,2019
513
+ ansible/plugins/filter/regex_search.yml,sha256=-2eBaW3ifvoFW1c2CI2xSPqYZCfnpmli475GIzg4E6U,2445
514
514
  ansible/plugins/filter/rekey_on_member.yml,sha256=IIVoLQemrn9BZMLygkGA6CPP4eLPHmRblOT2-TnWh70,921
515
515
  ansible/plugins/filter/relpath.yml,sha256=8-Kg_vFBeL6rwMQyyQMZaehB8LUa5h5cJEEr7_8qyi4,758
516
516
  ansible/plugins/filter/root.yml,sha256=sT1tsUZ5NBX7LjrPc-08Omg__szm9kOlamivlflJJ88,617
@@ -581,9 +581,9 @@ ansible/plugins/lookup/vars.py,sha256=W9at2j3xBk6z4IXfSutTEHqdzbiTI1B1tuYOLdd1BM
581
581
  ansible/plugins/netconf/__init__.py,sha256=50w1g2rhUo6L-xtiMT20jbR8WyOnhwNSRd2IRNSjNX4,17094
582
582
  ansible/plugins/shell/__init__.py,sha256=8pc3ab91OGbnvzk3oQ-sU8uXMXNoNbjtdCbdXmZYTWY,8985
583
583
  ansible/plugins/shell/cmd.py,sha256=kPCSKrJJFH5XTkmteEI3P1Da6WfPSXxDnV39VFpgD-A,2170
584
- ansible/plugins/shell/powershell.py,sha256=-AR5n5Yr2HPM-V5ogAwvLeLehfc1XrrhqmX85ZtXHFU,13134
584
+ ansible/plugins/shell/powershell.py,sha256=cgAg1HFhiP_caInzUm0VBSaKzoBNfwEWOh0Y1ADjPII,15619
585
585
  ansible/plugins/shell/sh.py,sha256=wblaY2EGdA2O00gNuTVZVgVV08RH0e_g4V_AkE50Iws,3884
586
- ansible/plugins/strategy/__init__.py,sha256=v-aMyfOUmBSULxmtqxwMCb8Uu_VKdM6XcpAtepAkKG4,57493
586
+ ansible/plugins/strategy/__init__.py,sha256=rkfyXtvBqvQIXgL8T4XChQTRMaiLnliTZj5cL_PY4yY,57651
587
587
  ansible/plugins/strategy/debug.py,sha256=yMmfT-lQHfR2y9bQcqrSPzqHuWZMo7V9y4ZWOXoboRE,1205
588
588
  ansible/plugins/strategy/free.py,sha256=WNrpfg2B8fVcYC5qvBhn4uEH0Cc1-UmFzBH6Hhs3u_I,16728
589
589
  ansible/plugins/strategy/host_pinned.py,sha256=GrDDQCtohmmJn3t9VOPb0lUZK_nUWy0s__z5Tq_rHfI,1875
@@ -684,9 +684,9 @@ ansible/vars/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
684
684
  ansible/vars/clean.py,sha256=X2WMksJMWITQ9FsM-Fb_YxT_hAGDqJ3urSTJzYBEdAk,5999
685
685
  ansible/vars/fact_cache.py,sha256=M57vMhkQ2DrzvNaZkfaCmKQJUqP1Rn_A31_X-5YBfzQ,1903
686
686
  ansible/vars/hostvars.py,sha256=o11xrzDVYn23renGbb3lx3R-nH9qOjLFju5IYJanDxg,5324
687
- ansible/vars/manager.py,sha256=nFJcvbhanUQO7loAUiFHEnGCuRpxsmYXCj8e9XVJTYc,30972
687
+ ansible/vars/manager.py,sha256=yksGRuDjOQnbTV1B0ot3gLSMtjCazIEmNjY5H_z1iw8,31258
688
688
  ansible/vars/plugins.py,sha256=PocWZPMqFl1LoNgWlGFNxwg9nZnUzhQmlXO4g7bcP2A,4503
689
- ansible/vars/reserved.py,sha256=kZiQMPvaFin35006gLwDpX16w-9xlu6EaL4LSTKP40U,2531
689
+ ansible/vars/reserved.py,sha256=Tsc4m2UwVce3dOvSWrjT2wB3lpNJtUyNZn45zNhsW0I,2869
690
690
  ansible_test/__init__.py,sha256=20VPOj11c6Ut1Av9RaurgwJvFhMqkWG3vAvcCbecNKw,66
691
691
  ansible_test/_data/ansible.cfg,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
692
692
  ansible_test/_data/coveragerc,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -824,7 +824,7 @@ ansible_test/_internal/cli/parsers/host_config_parsers.py,sha256=CYkTBciLYR1DWaE
824
824
  ansible_test/_internal/cli/parsers/key_value_parsers.py,sha256=GBpyOMBkPuycyWYjK5ePwZTDgzdSlfSHhYpLJWPrmkE,9570
825
825
  ansible_test/_internal/cli/parsers/value_parsers.py,sha256=ALoTjbmDr8IGWYbEEPUy082nFIb6kbekDJD5JFQp4Bc,6060
826
826
  ansible_test/_internal/commands/__init__.py,sha256=oRNkU8riDVtUFvIOyQlxiWinOWDUUKb-uEaC_GaE-PQ,88
827
- ansible_test/_internal/commands/coverage/__init__.py,sha256=XJDpIfim37RtN-Jluqw4fG6yhTfOcywtDoKlbSImgpo,14408
827
+ ansible_test/_internal/commands/coverage/__init__.py,sha256=kuIFvKUJpXLB0YB7afO4pP-1TGpnUUuK-Bf4cX73lio,14408
828
828
  ansible_test/_internal/commands/coverage/combine.py,sha256=eQslZpo2AUl4HOKYLaKqauKSES7XsWTxjexX8AVnzGI,11950
829
829
  ansible_test/_internal/commands/coverage/erase.py,sha256=CJL1BDKOM-OUBINwLJoDlWHwzkH3FB51StM2P0MZ56Q,915
830
830
  ansible_test/_internal/commands/coverage/html.py,sha256=66H-4TYmqpUe51XJEQ7URfDeHDUDD52Alta_Ug7tifw,1319
@@ -980,13 +980,13 @@ ansible_test/config/cloud-config-vultr.ini.template,sha256=XLKHk3lg_8ReQMdWfZzhh
980
980
  ansible_test/config/config.yml,sha256=1zdGucnIl6nIecZA7ISIANvqXiHWqq6Dthsk_6MUwNc,2642
981
981
  ansible_test/config/inventory.networking.template,sha256=bFNSk8zNQOaZ_twaflrY0XZ9mLwUbRLuNT0BdIFwvn4,1335
982
982
  ansible_test/config/inventory.winrm.template,sha256=1QU8W-GFLnYEw8yY9bVIvUAVvJYPM3hyoijf6-M7T00,1098
983
- ansible_core-2.18.1.dist-info/Apache-License.txt,sha256=y16Ofl9KOYjhBjwULGDcLfdWBfTEZRXnduOspt-XbhQ,11325
984
- ansible_core-2.18.1.dist-info/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
985
- ansible_core-2.18.1.dist-info/METADATA,sha256=oS9XGMUIfXsHqopT6dBy7mN8ZBpcNEb9BmGQrT-Es-M,7668
986
- ansible_core-2.18.1.dist-info/MIT-license.txt,sha256=jLXp2XurnyZKbye40g9tfmLGtVlxh3pPD4n8xNqX8xc,1023
987
- ansible_core-2.18.1.dist-info/PSF-license.txt,sha256=g7BC_H1qyg8Q1o5F76Vrm8ChSWYI5-dyj-CdGlNKBUo,2484
988
- ansible_core-2.18.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
989
- ansible_core-2.18.1.dist-info/entry_points.txt,sha256=S9yJij5Im6FgRQxzkqSCnPQokC7PcWrDW_NSygZczJU,451
990
- ansible_core-2.18.1.dist-info/simplified_bsd.txt,sha256=8R5R7R7sOa0h1Fi6RNgFgHowHBfun-OVOMzJ4rKAk2w,1237
991
- ansible_core-2.18.1.dist-info/top_level.txt,sha256=IFbRLjAvih1DYzJWg3_F6t4sCzEMxRO7TOMNs6GkYHo,21
992
- ansible_core-2.18.1.dist-info/RECORD,,
983
+ ansible_core-2.18.2.dist-info/Apache-License.txt,sha256=y16Ofl9KOYjhBjwULGDcLfdWBfTEZRXnduOspt-XbhQ,11325
984
+ ansible_core-2.18.2.dist-info/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
985
+ ansible_core-2.18.2.dist-info/METADATA,sha256=Cg9WFxRolEkSO_EFlMIPEHI68issQS76-gOeSyoVxIo,7668
986
+ ansible_core-2.18.2.dist-info/MIT-license.txt,sha256=jLXp2XurnyZKbye40g9tfmLGtVlxh3pPD4n8xNqX8xc,1023
987
+ ansible_core-2.18.2.dist-info/PSF-license.txt,sha256=g7BC_H1qyg8Q1o5F76Vrm8ChSWYI5-dyj-CdGlNKBUo,2484
988
+ ansible_core-2.18.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
989
+ ansible_core-2.18.2.dist-info/entry_points.txt,sha256=S9yJij5Im6FgRQxzkqSCnPQokC7PcWrDW_NSygZczJU,451
990
+ ansible_core-2.18.2.dist-info/simplified_bsd.txt,sha256=8R5R7R7sOa0h1Fi6RNgFgHowHBfun-OVOMzJ4rKAk2w,1237
991
+ ansible_core-2.18.2.dist-info/top_level.txt,sha256=IFbRLjAvih1DYzJWg3_F6t4sCzEMxRO7TOMNs6GkYHo,21
992
+ ansible_core-2.18.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: setuptools (75.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -293,6 +293,11 @@ def sanitize_filename(
293
293
  new_name = re.sub('^.*/ansible_modlib.zip/ansible/', ansible_path, filename)
294
294
  display.info('%s -> %s' % (filename, new_name), verbosity=3)
295
295
  filename = new_name
296
+ elif integration_temp_path in filename:
297
+ # Rewrite the path of code running from an integration test temporary directory.
298
+ new_name = re.sub(r'^.*' + re.escape(integration_temp_path) + '[^/]+/', root_path, filename)
299
+ display.info('%s -> %s' % (filename, new_name), verbosity=3)
300
+ filename = new_name
296
301
  elif collection_search_re and collection_search_re.search(filename):
297
302
  new_name = os.path.abspath(collection_sub_re.sub('', filename))
298
303
  display.info('%s -> %s' % (filename, new_name), verbosity=3)
@@ -328,11 +333,6 @@ def sanitize_filename(
328
333
  new_name = re.sub('^(/.*?)?/root/ansible/', root_path, filename)
329
334
  display.info('%s -> %s' % (filename, new_name), verbosity=3)
330
335
  filename = new_name
331
- elif integration_temp_path in filename:
332
- # Rewrite the path of code running from an integration test temporary directory.
333
- new_name = re.sub(r'^.*' + re.escape(integration_temp_path) + '[^/]+/', root_path, filename)
334
- display.info('%s -> %s' % (filename, new_name), verbosity=3)
335
- filename = new_name
336
336
 
337
337
  filename = os.path.abspath(filename) # make sure path is absolute (will be relative if previously exported)
338
338