ansible-core 2.18.7rc1__py3-none-any.whl → 2.19.0__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 (757) hide show
  1. ansible/_internal/__init__.py +53 -0
  2. ansible/_internal/_ansiballz/__init__.py +0 -0
  3. ansible/_internal/_ansiballz/_builder.py +101 -0
  4. ansible/_internal/_ansiballz/_wrapper.py +262 -0
  5. ansible/_internal/_collection_proxy.py +47 -0
  6. ansible/_internal/_datatag/__init__.py +0 -0
  7. ansible/_internal/_datatag/_tags.py +130 -0
  8. ansible/_internal/_datatag/_utils.py +19 -0
  9. ansible/_internal/_datatag/_wrappers.py +33 -0
  10. ansible/_internal/_errors/__init__.py +0 -0
  11. ansible/_internal/_errors/_alarm_timeout.py +66 -0
  12. ansible/_internal/_errors/_captured.py +123 -0
  13. ansible/_internal/_errors/_error_factory.py +89 -0
  14. ansible/_internal/_errors/_error_utils.py +240 -0
  15. ansible/_internal/_errors/_handler.py +91 -0
  16. ansible/_internal/_errors/_task_timeout.py +28 -0
  17. ansible/_internal/_event_formatting.py +127 -0
  18. ansible/_internal/_json/__init__.py +214 -0
  19. ansible/_internal/_json/_legacy_encoder.py +34 -0
  20. ansible/_internal/_json/_profiles/__init__.py +0 -0
  21. ansible/_internal/_json/_profiles/_cache_persistence.py +57 -0
  22. ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
  23. ansible/_internal/_json/_profiles/_legacy.py +189 -0
  24. ansible/_internal/_locking.py +21 -0
  25. ansible/_internal/_plugins/__init__.py +0 -0
  26. ansible/_internal/_plugins/_cache.py +57 -0
  27. ansible/_internal/_ssh/__init__.py +0 -0
  28. ansible/_internal/_ssh/_agent_launch.py +91 -0
  29. ansible/_internal/_ssh/_ssh_agent.py +619 -0
  30. ansible/_internal/_task.py +78 -0
  31. ansible/_internal/_templating/__init__.py +12 -0
  32. ansible/_internal/_templating/_access.py +86 -0
  33. ansible/_internal/_templating/_chain_templar.py +63 -0
  34. ansible/_internal/_templating/_datatag.py +95 -0
  35. ansible/_internal/_templating/_engine.py +592 -0
  36. ansible/_internal/_templating/_errors.py +28 -0
  37. ansible/_internal/_templating/_jinja_bits.py +1106 -0
  38. ansible/_internal/_templating/_jinja_common.py +323 -0
  39. ansible/_internal/_templating/_jinja_patches.py +44 -0
  40. ansible/_internal/_templating/_jinja_plugins.py +375 -0
  41. ansible/_internal/_templating/_lazy_containers.py +633 -0
  42. ansible/_internal/_templating/_marker_behaviors.py +103 -0
  43. ansible/_internal/_templating/_template_vars.py +72 -0
  44. ansible/_internal/_templating/_transform.py +70 -0
  45. ansible/_internal/_templating/_utils.py +108 -0
  46. ansible/_internal/_testing.py +26 -0
  47. ansible/_internal/_wrapt.py +1052 -0
  48. ansible/_internal/_yaml/__init__.py +0 -0
  49. ansible/_internal/_yaml/_constructor.py +240 -0
  50. ansible/_internal/_yaml/_dumper.py +70 -0
  51. ansible/_internal/_yaml/_errors.py +166 -0
  52. ansible/_internal/_yaml/_loader.py +66 -0
  53. ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
  54. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
  55. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
  56. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +27 -0
  57. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
  58. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
  59. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
  60. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
  61. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
  62. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
  63. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
  64. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
  65. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
  66. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
  67. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
  68. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
  69. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
  70. ansible/cli/__init__.py +93 -104
  71. ansible/cli/_ssh_askpass.py +54 -0
  72. ansible/cli/adhoc.py +20 -10
  73. ansible/cli/arguments/option_helpers.py +163 -10
  74. ansible/cli/config.py +43 -68
  75. ansible/cli/console.py +13 -11
  76. ansible/cli/doc.py +134 -77
  77. ansible/cli/galaxy.py +27 -20
  78. ansible/cli/inventory.py +28 -28
  79. ansible/cli/playbook.py +4 -12
  80. ansible/cli/pull.py +6 -3
  81. ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
  82. ansible/cli/vault.py +12 -11
  83. ansible/compat/__init__.py +2 -2
  84. ansible/compat/importlib_resources.py +9 -12
  85. ansible/config/base.yml +218 -133
  86. ansible/config/manager.py +220 -159
  87. ansible/constants.py +2 -65
  88. ansible/errors/__init__.py +350 -256
  89. ansible/executor/interpreter_discovery.py +28 -149
  90. ansible/executor/module_common.py +480 -514
  91. ansible/executor/play_iterator.py +22 -27
  92. ansible/executor/playbook_executor.py +11 -11
  93. ansible/executor/powershell/async_watchdog.ps1 +97 -102
  94. ansible/executor/powershell/async_wrapper.ps1 +204 -153
  95. ansible/executor/powershell/become_wrapper.ps1 +107 -144
  96. ansible/executor/powershell/bootstrap_wrapper.ps1 +46 -9
  97. ansible/executor/powershell/coverage_wrapper.ps1 +91 -135
  98. ansible/executor/powershell/exec_wrapper.ps1 +675 -196
  99. ansible/executor/powershell/module_manifest.py +469 -265
  100. ansible/executor/powershell/module_wrapper.ps1 +195 -186
  101. ansible/executor/powershell/powershell_expand_user.ps1 +20 -0
  102. ansible/executor/powershell/powershell_mkdtemp.ps1 +17 -0
  103. ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
  104. ansible/executor/powershell/psrp_put_file.ps1 +122 -0
  105. ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
  106. ansible/executor/powershell/winrm_put_file.ps1 +36 -0
  107. ansible/executor/process/worker.py +139 -149
  108. ansible/executor/stats.py +5 -5
  109. ansible/executor/task_executor.py +270 -297
  110. ansible/executor/task_queue_manager.py +135 -137
  111. ansible/executor/task_result.py +182 -79
  112. ansible/galaxy/__init__.py +2 -2
  113. ansible/galaxy/api.py +26 -25
  114. ansible/galaxy/collection/__init__.py +6 -14
  115. ansible/galaxy/collection/concrete_artifact_manager.py +12 -21
  116. ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
  117. ansible/galaxy/dependency_resolution/providers.py +4 -4
  118. ansible/galaxy/dependency_resolution/reporters.py +81 -0
  119. ansible/galaxy/role.py +6 -10
  120. ansible/galaxy/token.py +28 -21
  121. ansible/inventory/data.py +47 -57
  122. ansible/inventory/group.py +50 -73
  123. ansible/inventory/helpers.py +9 -0
  124. ansible/inventory/host.py +37 -54
  125. ansible/inventory/manager.py +79 -34
  126. ansible/keyword_desc.yml +1 -1
  127. ansible/module_utils/_internal/__init__.py +55 -0
  128. ansible/module_utils/_internal/_ambient_context.py +58 -0
  129. ansible/module_utils/_internal/_ansiballz/__init__.py +0 -0
  130. ansible/module_utils/_internal/_ansiballz/_extensions/__init__.py +0 -0
  131. ansible/module_utils/_internal/_ansiballz/_extensions/_coverage.py +45 -0
  132. ansible/module_utils/_internal/_ansiballz/_extensions/_pydevd.py +62 -0
  133. ansible/module_utils/_internal/_ansiballz/_loader.py +81 -0
  134. ansible/module_utils/_internal/_ansiballz/_respawn.py +32 -0
  135. ansible/module_utils/_internal/_ansiballz/_respawn_wrapper.py +23 -0
  136. ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
  137. ansible/module_utils/_internal/_dataclass_validation.py +217 -0
  138. ansible/module_utils/_internal/_datatag/__init__.py +961 -0
  139. ansible/module_utils/_internal/_datatag/_tags.py +16 -0
  140. ansible/module_utils/_internal/_debugging.py +31 -0
  141. ansible/module_utils/_internal/_deprecator.py +157 -0
  142. ansible/module_utils/_internal/_errors.py +101 -0
  143. ansible/module_utils/_internal/_event_utils.py +61 -0
  144. ansible/module_utils/_internal/_json/__init__.py +63 -0
  145. ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
  146. ansible/module_utils/_internal/_json/_profiles/__init__.py +428 -0
  147. ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
  148. ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +33 -0
  149. ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +37 -0
  150. ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
  151. ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
  152. ansible/module_utils/_internal/_json/_profiles/_tagless.py +52 -0
  153. ansible/module_utils/_internal/_messages.py +130 -0
  154. ansible/module_utils/_internal/_patches/__init__.py +66 -0
  155. ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +53 -0
  156. ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
  157. ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
  158. ansible/module_utils/_internal/_plugin_info.py +38 -0
  159. ansible/module_utils/_internal/_stack.py +22 -0
  160. ansible/module_utils/_internal/_testing.py +0 -0
  161. ansible/module_utils/_internal/_text_utils.py +6 -0
  162. ansible/module_utils/_internal/_traceback.py +92 -0
  163. ansible/module_utils/_internal/_validation.py +14 -0
  164. ansible/module_utils/ansible_release.py +2 -2
  165. ansible/module_utils/api.py +1 -2
  166. ansible/module_utils/basic.py +303 -202
  167. ansible/module_utils/common/_utils.py +24 -28
  168. ansible/module_utils/common/arg_spec.py +8 -3
  169. ansible/module_utils/common/collections.py +7 -2
  170. ansible/module_utils/common/dict_transformations.py +2 -2
  171. ansible/module_utils/common/file.py +2 -2
  172. ansible/module_utils/common/json.py +90 -84
  173. ansible/module_utils/common/locale.py +2 -2
  174. ansible/module_utils/common/parameters.py +27 -24
  175. ansible/module_utils/common/process.py +2 -3
  176. ansible/module_utils/common/respawn.py +11 -33
  177. ansible/module_utils/common/sentinel.py +66 -0
  178. ansible/module_utils/common/sys_info.py +8 -8
  179. ansible/module_utils/common/text/converters.py +16 -37
  180. ansible/module_utils/common/validation.py +35 -24
  181. ansible/module_utils/common/warnings.py +143 -25
  182. ansible/module_utils/common/yaml.py +29 -3
  183. ansible/module_utils/compat/datetime.py +33 -21
  184. ansible/module_utils/compat/paramiko.py +21 -10
  185. ansible/module_utils/compat/typing.py +6 -5
  186. ansible/module_utils/connection.py +10 -13
  187. ansible/module_utils/csharp/Ansible.Basic.cs +15 -12
  188. ansible/module_utils/csharp/Ansible.Become.cs +1 -0
  189. ansible/module_utils/csharp/Ansible.Privilege.cs +2 -2
  190. ansible/module_utils/csharp/Ansible._Async.cs +517 -0
  191. ansible/module_utils/datatag.py +49 -0
  192. ansible/module_utils/distro/__init__.py +2 -2
  193. ansible/module_utils/facts/ansible_collector.py +4 -5
  194. ansible/module_utils/facts/collector.py +13 -14
  195. ansible/module_utils/facts/compat.py +4 -4
  196. ansible/module_utils/facts/default_collectors.py +1 -1
  197. ansible/module_utils/facts/hardware/aix.py +34 -0
  198. ansible/module_utils/facts/hardware/base.py +2 -2
  199. ansible/module_utils/facts/hardware/darwin.py +1 -3
  200. ansible/module_utils/facts/hardware/freebsd.py +2 -2
  201. ansible/module_utils/facts/hardware/linux.py +5 -5
  202. ansible/module_utils/facts/namespace.py +1 -1
  203. ansible/module_utils/facts/network/base.py +1 -1
  204. ansible/module_utils/facts/network/fc_wwn.py +1 -2
  205. ansible/module_utils/facts/network/iscsi.py +1 -2
  206. ansible/module_utils/facts/network/nvme.py +1 -2
  207. ansible/module_utils/facts/other/facter.py +2 -3
  208. ansible/module_utils/facts/other/ohai.py +2 -3
  209. ansible/module_utils/facts/sysctl.py +4 -6
  210. ansible/module_utils/facts/system/apparmor.py +1 -2
  211. ansible/module_utils/facts/system/caps.py +3 -3
  212. ansible/module_utils/facts/system/chroot.py +1 -2
  213. ansible/module_utils/facts/system/cmdline.py +1 -2
  214. ansible/module_utils/facts/system/date_time.py +5 -3
  215. ansible/module_utils/facts/system/distribution.py +27 -13
  216. ansible/module_utils/facts/system/dns.py +1 -1
  217. ansible/module_utils/facts/system/env.py +1 -2
  218. ansible/module_utils/facts/system/fips.py +7 -20
  219. ansible/module_utils/facts/system/loadavg.py +1 -2
  220. ansible/module_utils/facts/system/local.py +2 -3
  221. ansible/module_utils/facts/system/lsb.py +1 -2
  222. ansible/module_utils/facts/system/pkg_mgr.py +1 -2
  223. ansible/module_utils/facts/system/platform.py +1 -2
  224. ansible/module_utils/facts/system/python.py +1 -2
  225. ansible/module_utils/facts/system/selinux.py +1 -1
  226. ansible/module_utils/facts/system/service_mgr.py +1 -2
  227. ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
  228. ansible/module_utils/facts/system/systemd.py +1 -1
  229. ansible/module_utils/facts/system/user.py +1 -2
  230. ansible/module_utils/facts/utils.py +3 -3
  231. ansible/module_utils/facts/virtual/base.py +1 -1
  232. ansible/module_utils/facts/virtual/linux.py +3 -3
  233. ansible/module_utils/facts/virtual/sunos.py +3 -15
  234. ansible/module_utils/facts/virtual/sysctl.py +3 -16
  235. ansible/module_utils/json_utils.py +2 -2
  236. ansible/module_utils/parsing/convert_bool.py +7 -1
  237. ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 +1 -1
  238. ansible/module_utils/powershell/Ansible.ModuleUtils.CamelConversion.psm1 +1 -1
  239. ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 +1 -1
  240. ansible/module_utils/powershell/Ansible.ModuleUtils.WebRequest.psm1 +1 -1
  241. ansible/module_utils/service.py +21 -31
  242. ansible/module_utils/splitter.py +7 -7
  243. ansible/module_utils/testing.py +31 -0
  244. ansible/module_utils/urls.py +64 -35
  245. ansible/modules/add_host.py +4 -4
  246. ansible/modules/apt.py +69 -49
  247. ansible/modules/apt_key.py +19 -12
  248. ansible/modules/apt_repository.py +32 -51
  249. ansible/modules/assemble.py +16 -14
  250. ansible/modules/assert.py +4 -4
  251. ansible/modules/async_status.py +24 -24
  252. ansible/modules/async_wrapper.py +20 -25
  253. ansible/modules/blockinfile.py +6 -7
  254. ansible/modules/command.py +13 -20
  255. ansible/modules/copy.py +60 -147
  256. ansible/modules/cron.py +24 -21
  257. ansible/modules/deb822_repository.py +8 -9
  258. ansible/modules/debconf.py +5 -5
  259. ansible/modules/debug.py +4 -4
  260. ansible/modules/dnf.py +8 -8
  261. ansible/modules/dnf5.py +39 -13
  262. ansible/modules/dpkg_selections.py +4 -4
  263. ansible/modules/expect.py +13 -15
  264. ansible/modules/fail.py +4 -4
  265. ansible/modules/fetch.py +4 -4
  266. ansible/modules/file.py +184 -144
  267. ansible/modules/find.py +22 -20
  268. ansible/modules/gather_facts.py +3 -3
  269. ansible/modules/get_url.py +77 -54
  270. ansible/modules/getent.py +7 -9
  271. ansible/modules/git.py +38 -38
  272. ansible/modules/group.py +6 -6
  273. ansible/modules/group_by.py +4 -4
  274. ansible/modules/hostname.py +15 -32
  275. ansible/modules/import_playbook.py +6 -6
  276. ansible/modules/import_role.py +6 -6
  277. ansible/modules/import_tasks.py +6 -6
  278. ansible/modules/include_role.py +6 -6
  279. ansible/modules/include_tasks.py +6 -6
  280. ansible/modules/include_vars.py +6 -6
  281. ansible/modules/iptables.py +86 -73
  282. ansible/modules/known_hosts.py +22 -24
  283. ansible/modules/lineinfile.py +5 -5
  284. ansible/modules/meta.py +4 -4
  285. ansible/modules/mount_facts.py +2 -2
  286. ansible/modules/package.py +10 -4
  287. ansible/modules/package_facts.py +22 -10
  288. ansible/modules/pause.py +6 -6
  289. ansible/modules/ping.py +6 -6
  290. ansible/modules/pip.py +21 -26
  291. ansible/modules/raw.py +6 -6
  292. ansible/modules/reboot.py +6 -6
  293. ansible/modules/replace.py +10 -14
  294. ansible/modules/rpm_key.py +7 -8
  295. ansible/modules/script.py +4 -4
  296. ansible/modules/service.py +10 -17
  297. ansible/modules/service_facts.py +87 -10
  298. ansible/modules/set_fact.py +5 -5
  299. ansible/modules/set_stats.py +4 -4
  300. ansible/modules/setup.py +2 -2
  301. ansible/modules/shell.py +6 -6
  302. ansible/modules/slurp.py +16 -19
  303. ansible/modules/stat.py +15 -31
  304. ansible/modules/subversion.py +15 -15
  305. ansible/modules/systemd.py +7 -7
  306. ansible/modules/systemd_service.py +7 -7
  307. ansible/modules/sysvinit.py +9 -9
  308. ansible/modules/tempfile.py +5 -6
  309. ansible/modules/template.py +6 -6
  310. ansible/modules/unarchive.py +38 -17
  311. ansible/modules/uri.py +33 -26
  312. ansible/modules/user.py +45 -32
  313. ansible/modules/validate_argument_spec.py +10 -7
  314. ansible/modules/wait_for.py +70 -60
  315. ansible/modules/wait_for_connection.py +6 -6
  316. ansible/modules/yum_repository.py +10 -9
  317. ansible/parsing/ajson.py +17 -37
  318. ansible/parsing/dataloader.py +99 -54
  319. ansible/parsing/mod_args.py +62 -60
  320. ansible/parsing/plugin_docs.py +21 -86
  321. ansible/parsing/quoting.py +1 -1
  322. ansible/parsing/splitter.py +27 -12
  323. ansible/parsing/utils/addresses.py +24 -24
  324. ansible/parsing/utils/jsonify.py +5 -1
  325. ansible/parsing/utils/yaml.py +32 -61
  326. ansible/parsing/vault/__init__.py +327 -99
  327. ansible/parsing/yaml/__init__.py +0 -18
  328. ansible/parsing/yaml/dumper.py +6 -120
  329. ansible/parsing/yaml/loader.py +6 -39
  330. ansible/parsing/yaml/objects.py +43 -335
  331. ansible/playbook/__init__.py +1 -1
  332. ansible/playbook/attribute.py +8 -3
  333. ansible/playbook/base.py +187 -134
  334. ansible/playbook/block.py +26 -24
  335. ansible/playbook/collectionsearch.py +1 -15
  336. ansible/playbook/conditional.py +3 -77
  337. ansible/playbook/handler.py +8 -2
  338. ansible/playbook/helpers.py +41 -53
  339. ansible/playbook/included_file.py +32 -26
  340. ansible/playbook/loop_control.py +2 -2
  341. ansible/playbook/play.py +85 -44
  342. ansible/playbook/play_context.py +14 -17
  343. ansible/playbook/playbook_include.py +27 -62
  344. ansible/playbook/role/__init__.py +64 -49
  345. ansible/playbook/role/definition.py +15 -17
  346. ansible/playbook/role/include.py +2 -4
  347. ansible/playbook/role/metadata.py +10 -11
  348. ansible/playbook/role_include.py +3 -3
  349. ansible/playbook/taggable.py +28 -12
  350. ansible/playbook/task.py +192 -121
  351. ansible/playbook/task_include.py +5 -5
  352. ansible/plugins/__init__.py +58 -26
  353. ansible/plugins/action/__init__.py +188 -186
  354. ansible/plugins/action/add_host.py +2 -2
  355. ansible/plugins/action/assemble.py +11 -18
  356. ansible/plugins/action/assert.py +55 -67
  357. ansible/plugins/action/async_status.py +7 -2
  358. ansible/plugins/action/copy.py +14 -17
  359. ansible/plugins/action/debug.py +37 -31
  360. ansible/plugins/action/dnf.py +3 -4
  361. ansible/plugins/action/fail.py +1 -1
  362. ansible/plugins/action/fetch.py +7 -8
  363. ansible/plugins/action/gather_facts.py +13 -14
  364. ansible/plugins/action/group_by.py +1 -1
  365. ansible/plugins/action/include_vars.py +10 -11
  366. ansible/plugins/action/package.py +8 -14
  367. ansible/plugins/action/pause.py +2 -2
  368. ansible/plugins/action/script.py +27 -38
  369. ansible/plugins/action/service.py +9 -18
  370. ansible/plugins/action/set_fact.py +3 -12
  371. ansible/plugins/action/set_stats.py +3 -8
  372. ansible/plugins/action/template.py +47 -67
  373. ansible/plugins/action/unarchive.py +6 -16
  374. ansible/plugins/action/uri.py +9 -20
  375. ansible/plugins/action/validate_argument_spec.py +5 -5
  376. ansible/plugins/action/wait_for_connection.py +1 -1
  377. ansible/plugins/become/__init__.py +31 -8
  378. ansible/plugins/become/runas.py +71 -0
  379. ansible/plugins/become/su.py +13 -8
  380. ansible/plugins/become/sudo.py +19 -0
  381. ansible/plugins/cache/__init__.py +52 -63
  382. ansible/plugins/cache/base.py +8 -0
  383. ansible/plugins/cache/jsonfile.py +10 -16
  384. ansible/plugins/cache/memory.py +6 -12
  385. ansible/plugins/callback/__init__.py +294 -201
  386. ansible/plugins/callback/default.py +99 -95
  387. ansible/plugins/callback/junit.py +44 -43
  388. ansible/plugins/callback/minimal.py +28 -25
  389. ansible/plugins/callback/oneline.py +34 -21
  390. ansible/plugins/callback/tree.py +27 -16
  391. ansible/plugins/connection/__init__.py +47 -34
  392. ansible/plugins/connection/local.py +156 -60
  393. ansible/plugins/connection/paramiko_ssh.py +34 -24
  394. ansible/plugins/connection/psrp.py +76 -165
  395. ansible/plugins/connection/ssh.py +326 -86
  396. ansible/plugins/connection/winrm.py +62 -141
  397. ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
  398. ansible/plugins/doc_fragments/action_core.py +6 -6
  399. ansible/plugins/doc_fragments/backup.py +2 -2
  400. ansible/plugins/doc_fragments/checksum_common.py +27 -0
  401. ansible/plugins/doc_fragments/constructed.py +8 -4
  402. ansible/plugins/doc_fragments/decrypt.py +2 -2
  403. ansible/plugins/doc_fragments/default_callback.py +2 -2
  404. ansible/plugins/doc_fragments/files.py +2 -2
  405. ansible/plugins/doc_fragments/inventory_cache.py +2 -2
  406. ansible/plugins/doc_fragments/result_format_callback.py +2 -2
  407. ansible/plugins/doc_fragments/return_common.py +2 -2
  408. ansible/plugins/doc_fragments/template_common.py +4 -4
  409. ansible/plugins/doc_fragments/url.py +17 -1
  410. ansible/plugins/doc_fragments/url_windows.py +2 -2
  411. ansible/plugins/doc_fragments/validate.py +2 -2
  412. ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
  413. ansible/plugins/filter/__init__.py +6 -2
  414. ansible/plugins/filter/b64decode.yml +22 -0
  415. ansible/plugins/filter/b64encode.yml +22 -0
  416. ansible/plugins/filter/bool.yml +11 -4
  417. ansible/plugins/filter/core.py +245 -120
  418. ansible/plugins/filter/encryption.py +42 -34
  419. ansible/plugins/filter/flatten.yml +3 -2
  420. ansible/plugins/filter/human_to_bytes.yml +1 -1
  421. ansible/plugins/filter/mathstuff.py +30 -37
  422. ansible/plugins/filter/password_hash.yml +8 -0
  423. ansible/plugins/filter/pow.yml +1 -1
  424. ansible/plugins/filter/regex_search.yml +1 -4
  425. ansible/plugins/filter/root.yml +1 -1
  426. ansible/plugins/filter/split.yml +1 -1
  427. ansible/plugins/filter/strftime.yml +3 -3
  428. ansible/plugins/filter/to_nice_yaml.yml +0 -4
  429. ansible/plugins/filter/to_uuid.yml +1 -1
  430. ansible/plugins/filter/to_yaml.yml +0 -4
  431. ansible/plugins/filter/unvault.yml +1 -1
  432. ansible/plugins/filter/urls.py +1 -1
  433. ansible/plugins/filter/urlsplit.py +8 -9
  434. ansible/plugins/filter/vault.yml +14 -9
  435. ansible/plugins/filter/win_basename.yml +6 -1
  436. ansible/plugins/filter/win_dirname.yml +5 -0
  437. ansible/plugins/inventory/__init__.py +107 -86
  438. ansible/plugins/inventory/advanced_host_list.py +7 -5
  439. ansible/plugins/inventory/auto.py +11 -4
  440. ansible/plugins/inventory/constructed.py +21 -24
  441. ansible/plugins/inventory/generator.py +16 -11
  442. ansible/plugins/inventory/host_list.py +7 -5
  443. ansible/plugins/inventory/ini.py +78 -44
  444. ansible/plugins/inventory/script.py +190 -120
  445. ansible/plugins/inventory/toml.py +16 -126
  446. ansible/plugins/inventory/yaml.py +10 -8
  447. ansible/plugins/list.py +72 -19
  448. ansible/plugins/loader.py +383 -198
  449. ansible/plugins/lookup/__init__.py +21 -4
  450. ansible/plugins/lookup/config.py +21 -35
  451. ansible/plugins/lookup/csvfile.py +19 -73
  452. ansible/plugins/lookup/dict.py +1 -6
  453. ansible/plugins/lookup/env.py +12 -9
  454. ansible/plugins/lookup/file.py +5 -8
  455. ansible/plugins/lookup/first_found.py +87 -55
  456. ansible/plugins/lookup/indexed_items.py +1 -10
  457. ansible/plugins/lookup/ini.py +14 -13
  458. ansible/plugins/lookup/items.py +1 -1
  459. ansible/plugins/lookup/lines.py +8 -1
  460. ansible/plugins/lookup/list.py +1 -1
  461. ansible/plugins/lookup/nested.py +2 -18
  462. ansible/plugins/lookup/password.py +5 -5
  463. ansible/plugins/lookup/pipe.py +5 -7
  464. ansible/plugins/lookup/sequence.py +18 -8
  465. ansible/plugins/lookup/subelements.py +1 -4
  466. ansible/plugins/lookup/template.py +47 -36
  467. ansible/plugins/lookup/together.py +0 -12
  468. ansible/plugins/lookup/unvault.py +1 -5
  469. ansible/plugins/lookup/url.py +4 -10
  470. ansible/plugins/lookup/vars.py +16 -24
  471. ansible/plugins/shell/__init__.py +58 -4
  472. ansible/plugins/shell/cmd.py +2 -2
  473. ansible/plugins/shell/powershell.py +106 -31
  474. ansible/plugins/shell/sh.py +13 -7
  475. ansible/plugins/strategy/__init__.py +168 -193
  476. ansible/plugins/strategy/debug.py +2 -2
  477. ansible/plugins/strategy/free.py +16 -31
  478. ansible/plugins/strategy/host_pinned.py +2 -2
  479. ansible/plugins/strategy/linear.py +41 -41
  480. ansible/plugins/terminal/__init__.py +4 -4
  481. ansible/plugins/test/__init__.py +7 -2
  482. ansible/plugins/test/core.py +75 -35
  483. ansible/plugins/test/files.py +1 -1
  484. ansible/plugins/test/finished.yml +1 -1
  485. ansible/plugins/test/mathstuff.py +3 -3
  486. ansible/plugins/test/uri.py +5 -8
  487. ansible/plugins/vars/host_group_vars.py +7 -14
  488. ansible/release.py +2 -2
  489. ansible/template/__init__.py +353 -943
  490. ansible/utils/__init__.py +0 -18
  491. ansible/utils/collection_loader/__init__.py +54 -5
  492. ansible/utils/collection_loader/_collection_config.py +5 -6
  493. ansible/utils/collection_loader/_collection_finder.py +82 -96
  494. ansible/utils/collection_loader/_collection_meta.py +15 -8
  495. ansible/utils/display.py +485 -73
  496. ansible/utils/encrypt.py +27 -19
  497. ansible/utils/fqcn.py +2 -2
  498. ansible/utils/galaxy.py +2 -2
  499. ansible/utils/hashing.py +8 -10
  500. ansible/utils/helpers.py +2 -2
  501. ansible/utils/listify.py +10 -8
  502. ansible/utils/lock.py +2 -2
  503. ansible/utils/path.py +10 -12
  504. ansible/utils/plugin_docs.py +16 -14
  505. ansible/utils/py3compat.py +2 -7
  506. ansible/utils/sentinel.py +4 -62
  507. ansible/utils/singleton.py +2 -0
  508. ansible/utils/ssh_functions.py +6 -2
  509. ansible/utils/unsafe_proxy.py +23 -332
  510. ansible/utils/vars.py +55 -8
  511. ansible/utils/version.py +2 -2
  512. ansible/vars/clean.py +5 -5
  513. ansible/vars/hostvars.py +60 -90
  514. ansible/vars/manager.py +220 -285
  515. ansible/vars/plugins.py +4 -4
  516. ansible/vars/reserved.py +13 -12
  517. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/METADATA +4 -3
  518. ansible_core-2.19.0.dist-info/RECORD +1097 -0
  519. ansible_core-2.19.0.dist-info/licenses/licenses/BSD-3-Clause.txt +28 -0
  520. ansible_test/_data/completion/docker.txt +7 -7
  521. ansible_test/_data/completion/remote.txt +6 -6
  522. ansible_test/_data/completion/windows.txt +1 -0
  523. ansible_test/_data/requirements/ansible.txt +2 -2
  524. ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
  525. ansible_test/_data/requirements/sanity.changelog.txt +2 -2
  526. ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
  527. ansible_test/_data/requirements/sanity.pep8.txt +1 -1
  528. ansible_test/_data/requirements/sanity.pylint.txt +5 -5
  529. ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
  530. ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
  531. ansible_test/_data/requirements/units.txt +1 -0
  532. ansible_test/_internal/__init__.py +6 -0
  533. ansible_test/_internal/ansible_util.py +3 -1
  534. ansible_test/_internal/become.py +1 -0
  535. ansible_test/_internal/bootstrap.py +1 -0
  536. ansible_test/_internal/cache.py +1 -0
  537. ansible_test/_internal/cgroup.py +1 -0
  538. ansible_test/_internal/ci/__init__.py +1 -0
  539. ansible_test/_internal/ci/azp.py +1 -0
  540. ansible_test/_internal/ci/local.py +1 -0
  541. ansible_test/_internal/classification/__init__.py +1 -0
  542. ansible_test/_internal/classification/common.py +1 -0
  543. ansible_test/_internal/classification/csharp.py +1 -0
  544. ansible_test/_internal/classification/powershell.py +1 -0
  545. ansible_test/_internal/classification/python.py +1 -0
  546. ansible_test/_internal/cli/__init__.py +1 -0
  547. ansible_test/_internal/cli/actions.py +1 -0
  548. ansible_test/_internal/cli/argparsing/__init__.py +1 -0
  549. ansible_test/_internal/cli/argparsing/actions.py +1 -0
  550. ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
  551. ansible_test/_internal/cli/argparsing/parsers.py +1 -0
  552. ansible_test/_internal/cli/commands/__init__.py +11 -5
  553. ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
  554. ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
  555. ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
  556. ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
  557. ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
  558. ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
  559. ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
  560. ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
  561. ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
  562. ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
  563. ansible_test/_internal/cli/commands/coverage/html.py +1 -0
  564. ansible_test/_internal/cli/commands/coverage/report.py +1 -0
  565. ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
  566. ansible_test/_internal/cli/commands/env.py +1 -0
  567. ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
  568. ansible_test/_internal/cli/commands/integration/network.py +1 -0
  569. ansible_test/_internal/cli/commands/integration/posix.py +1 -0
  570. ansible_test/_internal/cli/commands/integration/windows.py +1 -0
  571. ansible_test/_internal/cli/commands/sanity.py +9 -0
  572. ansible_test/_internal/cli/commands/shell.py +1 -0
  573. ansible_test/_internal/cli/commands/units.py +1 -0
  574. ansible_test/_internal/cli/compat.py +1 -0
  575. ansible_test/_internal/cli/completers.py +1 -0
  576. ansible_test/_internal/cli/converters.py +1 -0
  577. ansible_test/_internal/cli/environments.py +52 -5
  578. ansible_test/_internal/cli/epilog.py +1 -0
  579. ansible_test/_internal/cli/parsers/__init__.py +1 -0
  580. ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
  581. ansible_test/_internal/cli/parsers/helpers.py +1 -0
  582. ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
  583. ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
  584. ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
  585. ansible_test/_internal/commands/__init__.py +1 -0
  586. ansible_test/_internal/commands/coverage/__init__.py +3 -2
  587. ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
  588. ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
  589. ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
  590. ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
  591. ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
  592. ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
  593. ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
  594. ansible_test/_internal/commands/coverage/combine.py +2 -1
  595. ansible_test/_internal/commands/coverage/erase.py +1 -0
  596. ansible_test/_internal/commands/coverage/html.py +1 -0
  597. ansible_test/_internal/commands/coverage/report.py +1 -0
  598. ansible_test/_internal/commands/coverage/xml.py +1 -0
  599. ansible_test/_internal/commands/env/__init__.py +2 -0
  600. ansible_test/_internal/commands/integration/__init__.py +22 -5
  601. ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
  602. ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
  603. ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
  604. ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
  605. ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
  606. ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
  607. ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
  608. ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
  609. ansible_test/_internal/commands/integration/cloud/httptester.py +3 -2
  610. ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
  611. ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
  612. ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
  613. ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
  614. ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
  615. ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
  616. ansible_test/_internal/commands/integration/coverage.py +8 -2
  617. ansible_test/_internal/commands/integration/filters.py +1 -0
  618. ansible_test/_internal/commands/integration/network.py +1 -0
  619. ansible_test/_internal/commands/integration/posix.py +1 -0
  620. ansible_test/_internal/commands/integration/windows.py +1 -0
  621. ansible_test/_internal/commands/sanity/__init__.py +19 -2
  622. ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
  623. ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
  624. ansible_test/_internal/commands/sanity/compile.py +1 -0
  625. ansible_test/_internal/commands/sanity/ignores.py +1 -0
  626. ansible_test/_internal/commands/sanity/import.py +1 -0
  627. ansible_test/_internal/commands/sanity/integration_aliases.py +12 -0
  628. ansible_test/_internal/commands/sanity/pep8.py +1 -0
  629. ansible_test/_internal/commands/sanity/pslint.py +1 -0
  630. ansible_test/_internal/commands/sanity/pylint.py +25 -26
  631. ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
  632. ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
  633. ansible_test/_internal/commands/sanity/yamllint.py +1 -0
  634. ansible_test/_internal/commands/shell/__init__.py +44 -4
  635. ansible_test/_internal/commands/units/__init__.py +5 -1
  636. ansible_test/_internal/compat/__init__.py +1 -0
  637. ansible_test/_internal/compat/packaging.py +1 -0
  638. ansible_test/_internal/compat/yaml.py +1 -0
  639. ansible_test/_internal/completion.py +1 -0
  640. ansible_test/_internal/config.py +23 -13
  641. ansible_test/_internal/connections.py +1 -0
  642. ansible_test/_internal/constants.py +1 -0
  643. ansible_test/_internal/containers.py +1 -0
  644. ansible_test/_internal/content_config.py +1 -0
  645. ansible_test/_internal/core_ci.py +1 -0
  646. ansible_test/_internal/coverage_util.py +11 -10
  647. ansible_test/_internal/data.py +1 -0
  648. ansible_test/_internal/debugging.py +166 -0
  649. ansible_test/_internal/delegation.py +22 -13
  650. ansible_test/_internal/dev/__init__.py +1 -0
  651. ansible_test/_internal/dev/container_probe.py +1 -0
  652. ansible_test/_internal/diff.py +3 -2
  653. ansible_test/_internal/docker_util.py +2 -1
  654. ansible_test/_internal/encoding.py +1 -0
  655. ansible_test/_internal/executor.py +1 -0
  656. ansible_test/_internal/git.py +1 -0
  657. ansible_test/_internal/host_configs.py +1 -0
  658. ansible_test/_internal/host_profiles.py +260 -16
  659. ansible_test/_internal/http.py +1 -0
  660. ansible_test/_internal/init.py +1 -0
  661. ansible_test/_internal/inventory.py +39 -3
  662. ansible_test/_internal/io.py +1 -0
  663. ansible_test/_internal/metadata.py +95 -4
  664. ansible_test/_internal/payload.py +1 -0
  665. ansible_test/_internal/processes.py +80 -0
  666. ansible_test/_internal/provider/__init__.py +1 -0
  667. ansible_test/_internal/provider/layout/__init__.py +1 -0
  668. ansible_test/_internal/provider/layout/ansible.py +1 -0
  669. ansible_test/_internal/provider/layout/collection.py +1 -0
  670. ansible_test/_internal/provider/layout/unsupported.py +1 -0
  671. ansible_test/_internal/provider/source/__init__.py +1 -0
  672. ansible_test/_internal/provider/source/git.py +1 -0
  673. ansible_test/_internal/provider/source/installed.py +1 -0
  674. ansible_test/_internal/provider/source/unsupported.py +1 -0
  675. ansible_test/_internal/provider/source/unversioned.py +1 -0
  676. ansible_test/_internal/provisioning.py +11 -4
  677. ansible_test/_internal/pypi_proxy.py +6 -5
  678. ansible_test/_internal/python_requirements.py +28 -0
  679. ansible_test/_internal/ssh.py +2 -5
  680. ansible_test/_internal/target.py +9 -0
  681. ansible_test/_internal/test.py +3 -2
  682. ansible_test/_internal/thread.py +3 -1
  683. ansible_test/_internal/timeout.py +2 -1
  684. ansible_test/_internal/util.py +41 -12
  685. ansible_test/_internal/util_common.py +18 -5
  686. ansible_test/_internal/venv.py +1 -0
  687. ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
  688. ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
  689. ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
  690. ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
  691. ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
  692. ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
  693. ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
  694. ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
  695. ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
  696. ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
  697. ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
  698. ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
  699. ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
  700. ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
  701. ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
  702. ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
  703. ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
  704. ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +8 -5
  705. ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +8 -5
  706. ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +8 -5
  707. ansible_test/_util/controller/sanity/pylint/config/collection.cfg +4 -5
  708. ansible_test/_util/controller/sanity/pylint/config/default.cfg +8 -7
  709. ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +541 -0
  710. ansible_test/_util/controller/sanity/pylint/plugins/deprecated_comment.py +137 -0
  711. ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
  712. ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
  713. ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
  714. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
  715. ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
  716. ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
  717. ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
  718. ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
  719. ansible_test/_util/controller/tools/collection_detail.py +1 -0
  720. ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
  721. ansible_test/_util/target/injector/python.py +8 -0
  722. ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
  723. ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
  724. ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
  725. ansible_test/_util/target/sanity/compile/compile.py +1 -0
  726. ansible_test/_util/target/sanity/import/importer.py +15 -16
  727. ansible_test/_util/target/setup/bootstrap.sh +9 -20
  728. ansible_test/_util/target/setup/probe_cgroups.py +1 -0
  729. ansible_test/_util/target/setup/quiet_pip.py +1 -0
  730. ansible_test/_util/target/setup/requirements.py +38 -36
  731. ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
  732. ansible_test/_util/target/tools/yamlcheck.py +2 -1
  733. ansible/compat/selectors.py +0 -32
  734. ansible/errors/yaml_strings.py +0 -138
  735. ansible/executor/action_write_locks.py +0 -44
  736. ansible/executor/discovery/python_target.py +0 -47
  737. ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
  738. ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
  739. ansible/module_utils/compat/importlib.py +0 -26
  740. ansible/module_utils/compat/selectors.py +0 -32
  741. ansible/module_utils/pycompat24.py +0 -73
  742. ansible/parsing/yaml/constructor.py +0 -178
  743. ansible/template/native_helpers.py +0 -251
  744. ansible/template/template.py +0 -43
  745. ansible/template/vars.py +0 -77
  746. ansible/utils/native_jinja.py +0 -11
  747. ansible/vars/fact_cache.py +0 -71
  748. ansible_core-2.18.7rc1.dist-info/RECORD +0 -992
  749. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +0 -411
  750. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/WHEEL +0 -0
  751. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/entry_points.txt +0 -0
  752. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/COPYING +0 -0
  753. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/Apache-License.txt +0 -0
  754. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/MIT-license.txt +0 -0
  755. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/PSF-license.txt +0 -0
  756. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
  757. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/top_level.txt +0 -0
@@ -23,14 +23,31 @@ from ansible.errors import AnsibleFileNotFound
23
23
  from ansible.plugins import AnsiblePlugin
24
24
  from ansible.utils.display import Display
25
25
 
26
+ import typing as t
27
+
28
+ if t.TYPE_CHECKING:
29
+ from ansible.parsing import dataloader as _dataloader
30
+ from ansible import template as _template
31
+
26
32
  display = Display()
27
33
 
28
34
  __all__ = ['LookupBase']
29
35
 
30
36
 
31
37
  class LookupBase(AnsiblePlugin):
38
+ accept_args_markers: t.ClassVar[bool] = False
39
+ """
40
+ When `False`, plugin invocation is skipped when a top-level argument is a `Marker`, with the first such value substituted as the plugin result.
41
+ This ensures that only plugins which understand `Marker` instances for top-level arguments will encounter them.
42
+ """
43
+
44
+ accept_lazy_markers: t.ClassVar[bool] = False
45
+ """
46
+ When `False`, plugins will trigger a `MarkerError` exception when attempting to retrieve a `Marker` from a lazy container.
47
+ This ensures that only plugins which understand lazy retrieval of `Marker` instances will encounter them.
48
+ """
32
49
 
33
- def __init__(self, loader=None, templar=None, **kwargs):
50
+ def __init__(self, loader: _dataloader.DataLoader | None = None, templar: _template.Templar | None = None, **kwargs) -> None:
34
51
 
35
52
  super(LookupBase, self).__init__()
36
53
 
@@ -72,7 +89,7 @@ class LookupBase(AnsiblePlugin):
72
89
  return ret
73
90
 
74
91
  @abstractmethod
75
- def run(self, terms, variables=None, **kwargs):
92
+ def run(self, terms, variables, **kwargs):
76
93
  """
77
94
  When the playbook specifies a lookup, this method is run. The
78
95
  arguments to the lookup become the arguments to this method. One
@@ -104,9 +121,9 @@ class LookupBase(AnsiblePlugin):
104
121
  pass
105
122
 
106
123
  def find_file_in_search_path(self, myvars, subdir, needle, ignore_missing=False):
107
- '''
124
+ """
108
125
  Return a file (needle) in the task's expected search path.
109
- '''
126
+ """
110
127
 
111
128
  if 'ansible_search_path' in myvars:
112
129
  paths = myvars['ansible_search_path']
@@ -83,32 +83,20 @@ _raw:
83
83
  import ansible.plugins.loader as plugin_loader
84
84
 
85
85
  from ansible import constants as C
86
- from ansible.errors import AnsibleError, AnsibleLookupError, AnsibleOptionsError
87
- from ansible.module_utils.common.text.converters import to_native
88
- from ansible.module_utils.six import string_types
86
+ from ansible.module_utils.common.sentinel import Sentinel
87
+ from ansible.errors import AnsibleError, AnsibleUndefinedConfigEntry
89
88
  from ansible.plugins.lookup import LookupBase
90
- from ansible.utils.sentinel import Sentinel
91
89
 
92
90
 
93
- class MissingSetting(AnsibleOptionsError):
94
- pass
91
+ def _get_plugin_config(pname, ptype, config, variables):
92
+ # plugin creates settings on load, this is cached so not too expensive to redo
93
+ loader = getattr(plugin_loader, '%s_loader' % ptype)
94
+ p = loader.get(pname, class_only=True)
95
95
 
96
+ if p is None:
97
+ raise AnsibleError(f"Unable to load {ptype} plugin {pname!r}.")
96
98
 
97
- def _get_plugin_config(pname, ptype, config, variables):
98
- try:
99
- # plugin creates settings on load, this is cached so not too expensive to redo
100
- loader = getattr(plugin_loader, '%s_loader' % ptype)
101
- p = loader.get(pname, class_only=True)
102
- if p is None:
103
- raise AnsibleLookupError('Unable to load %s plugin "%s"' % (ptype, pname))
104
- result, origin = C.config.get_config_value_and_origin(config, plugin_type=ptype, plugin_name=p._load_name, variables=variables)
105
- except AnsibleLookupError:
106
- raise
107
- except AnsibleError as e:
108
- msg = to_native(e)
109
- if 'was not defined' in msg:
110
- raise MissingSetting(msg, orig_exc=e)
111
- raise e
99
+ result, origin = C.config.get_config_value_and_origin(config, plugin_type=ptype, plugin_name=p._load_name, variables=variables)
112
100
 
113
101
  return result, origin
114
102
 
@@ -116,10 +104,11 @@ def _get_plugin_config(pname, ptype, config, variables):
116
104
  def _get_global_config(config):
117
105
  try:
118
106
  result = getattr(C, config)
119
- if callable(result):
120
- raise AnsibleLookupError('Invalid setting "%s" attempted' % config)
121
- except AttributeError as e:
122
- raise MissingSetting(to_native(e), orig_exc=e)
107
+ except AttributeError:
108
+ raise AnsibleUndefinedConfigEntry(f"Setting {config!r} does not exist.") from None
109
+
110
+ if callable(result):
111
+ raise ValueError(f"Invalid setting {config!r} attempted.")
123
112
 
124
113
  return result
125
114
 
@@ -136,16 +125,13 @@ class LookupModule(LookupBase):
136
125
  show_origin = self.get_option('show_origin')
137
126
 
138
127
  if (ptype or pname) and not (ptype and pname):
139
- raise AnsibleOptionsError('Both plugin_type and plugin_name are required, cannot use one without the other')
140
-
141
- if not isinstance(missing, string_types) or missing not in ['error', 'warn', 'skip']:
142
- raise AnsibleOptionsError('"on_missing" must be a string and one of "error", "warn" or "skip", not %s' % missing)
128
+ raise AnsibleError('Both plugin_type and plugin_name are required, cannot use one without the other.')
143
129
 
144
130
  ret = []
145
131
 
146
132
  for term in terms:
147
- if not isinstance(term, string_types):
148
- raise AnsibleOptionsError('Invalid setting identifier, "%s" is not a string, its a %s' % (term, type(term)))
133
+ if not isinstance(term, str):
134
+ raise AnsibleError(f'Invalid setting identifier, {term!r} is not a {str}, its a {type(term)}.')
149
135
 
150
136
  result = Sentinel
151
137
  origin = None
@@ -154,17 +140,17 @@ class LookupModule(LookupBase):
154
140
  result, origin = _get_plugin_config(pname, ptype, term, variables)
155
141
  else:
156
142
  result = _get_global_config(term)
157
- except MissingSetting as e:
143
+ except AnsibleUndefinedConfigEntry:
158
144
  if missing == 'error':
159
- raise AnsibleLookupError('Unable to find setting %s' % term, orig_exc=e)
145
+ raise
160
146
  elif missing == 'warn':
161
- self._display.warning('Skipping, did not find setting %s' % term)
147
+ self._display.warning(f"Skipping, did not find setting {term!r}.")
162
148
  elif missing == 'skip':
163
149
  pass # this is not needed, but added to have all 3 options stated
164
150
 
165
151
  if result is not Sentinel:
166
152
  if show_origin:
167
- ret.append((result, origin))
153
+ ret.append([result, origin])
168
154
  else:
169
155
  ret.append(result)
170
156
  return ret
@@ -16,7 +16,8 @@ DOCUMENTATION = r"""
16
16
  options:
17
17
  col:
18
18
  description: column to return (0 indexed).
19
- default: "1"
19
+ default: 1
20
+ type: int
20
21
  keycol:
21
22
  description: column to search in (0 indexed).
22
23
  default: 0
@@ -102,76 +103,26 @@ RETURN = """
102
103
  elements: str
103
104
  """
104
105
 
105
- import codecs
106
106
  import csv
107
107
 
108
108
  from collections.abc import MutableSequence
109
109
 
110
- from ansible.errors import AnsibleError, AnsibleAssertionError
110
+ from ansible.errors import AnsibleError
111
111
  from ansible.parsing.splitter import parse_kv
112
112
  from ansible.plugins.lookup import LookupBase
113
- from ansible.module_utils.six import PY2
114
- from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
115
-
116
-
117
- class CSVRecoder:
118
- """
119
- Iterator that reads an encoded stream and encodes the input to UTF-8
120
- """
121
- def __init__(self, f, encoding='utf-8'):
122
- self.reader = codecs.getreader(encoding)(f)
123
-
124
- def __iter__(self):
125
- return self
126
-
127
- def __next__(self):
128
- return next(self.reader).encode("utf-8")
129
-
130
- next = __next__ # For Python 2
131
-
132
-
133
- class CSVReader:
134
- """
135
- A CSV reader which will iterate over lines in the CSV file "f",
136
- which is encoded in the given encoding.
137
- """
138
-
139
- def __init__(self, f, dialect=csv.excel, encoding='utf-8', **kwds):
140
- if PY2:
141
- f = CSVRecoder(f, encoding)
142
- else:
143
- f = codecs.getreader(encoding)(f)
144
-
145
- self.reader = csv.reader(f, dialect=dialect, **kwds)
146
-
147
- def __next__(self):
148
- row = next(self.reader)
149
- return [to_text(s) for s in row]
150
-
151
- next = __next__ # For Python 2
152
-
153
- def __iter__(self):
154
- return self
155
113
 
156
114
 
157
115
  class LookupModule(LookupBase):
158
116
 
159
117
  def read_csv(self, filename, key, delimiter, encoding='utf-8', dflt=None, col=1, keycol=0):
160
-
161
- try:
162
- f = open(to_bytes(filename), 'rb')
163
- creader = CSVReader(f, delimiter=to_native(delimiter), encoding=encoding)
164
-
165
- for row in creader:
166
- if len(row) and row[keycol] == key:
167
- return row[int(col)]
168
- except Exception as e:
169
- raise AnsibleError("csvfile: %s" % to_native(e))
118
+ with open(filename, encoding=encoding) as f:
119
+ for row in csv.reader(f, dialect=csv.excel, delimiter=delimiter):
120
+ if row and row[keycol] == key:
121
+ return row[col]
170
122
 
171
123
  return dflt
172
124
 
173
125
  def run(self, terms, variables=None, **kwargs):
174
-
175
126
  ret = []
176
127
 
177
128
  self.set_options(var_options=variables, direct=kwargs)
@@ -191,23 +142,19 @@ class LookupModule(LookupBase):
191
142
  key = kv['_raw_params']
192
143
 
193
144
  # parameters override per term using k/v
194
- try:
195
- reset_params = False
196
- for name, value in kv.items():
197
- if name == '_raw_params':
198
- continue
199
- if name not in paramvals:
200
- raise AnsibleAssertionError('%s is not a valid option' % name)
201
-
202
- self._deprecate_inline_kv()
203
- self.set_option(name, value)
204
- reset_params = True
145
+ reset_params = False
146
+ for name, value in kv.items():
147
+ if name == '_raw_params':
148
+ continue
149
+ if name not in paramvals:
150
+ raise ValueError(f'{name!r} is not a valid option')
205
151
 
206
- if reset_params:
207
- paramvals = self.get_options()
152
+ self._deprecate_inline_kv()
153
+ self.set_option(name, value)
154
+ reset_params = True
208
155
 
209
- except (ValueError, AssertionError) as e:
210
- raise AnsibleError(e)
156
+ if reset_params:
157
+ paramvals = self.get_options()
211
158
 
212
159
  # default is just placeholder for real tab
213
160
  if paramvals['delimiter'] == 'TAB':
@@ -217,8 +164,7 @@ class LookupModule(LookupBase):
217
164
  var = self.read_csv(lookupfile, key, paramvals['delimiter'], paramvals['encoding'], paramvals['default'], paramvals['col'], paramvals['keycol'])
218
165
  if var is not None:
219
166
  if isinstance(var, MutableSequence):
220
- for v in var:
221
- ret.append(v)
167
+ ret.extend(var)
222
168
  else:
223
169
  ret.append(var)
224
170
 
@@ -61,16 +61,11 @@ from ansible.plugins.lookup import LookupBase
61
61
  class LookupModule(LookupBase):
62
62
 
63
63
  def run(self, terms, variables=None, **kwargs):
64
-
65
- # NOTE: can remove if with_ is removed
66
- if not isinstance(terms, list):
67
- terms = [terms]
68
-
69
64
  results = []
70
65
  for term in terms:
71
66
  # Expect any type of Mapping, notably hostvars
72
67
  if not isinstance(term, Mapping):
73
- raise AnsibleError("with_dict expects a dict")
68
+ raise AnsibleError(f"the 'dict' lookup plugin expects a dictionary, got '{term}' of type {type(term)})")
74
69
 
75
70
  results.extend(self._flatten_hash_to_list(term))
76
71
  return results
@@ -38,10 +38,6 @@ EXAMPLES = """
38
38
  ansible.builtin.debug:
39
39
  msg: "Hello {{ lookup('ansible.builtin.env', 'UNDEFINED_VARIABLE', default='World') }}"
40
40
 
41
- - name: Fail if the variable is not defined by setting default value to 'Undefined'
42
- ansible.builtin.debug:
43
- msg: "Hello {{ lookup('ansible.builtin.env', 'UNDEFINED_VARIABLE', default=Undefined) }}"
44
-
45
41
  - name: Fail if the variable is not defined by setting default value to 'undef()'
46
42
  ansible.builtin.debug:
47
43
  msg: "Hello {{ lookup('ansible.builtin.env', 'UNDEFINED_VARIABLE', default=undef()) }}"
@@ -56,23 +52,30 @@ RETURN = """
56
52
 
57
53
  import os
58
54
 
59
- from jinja2.runtime import Undefined
60
55
 
61
- from ansible.errors import AnsibleUndefinedVariable
62
56
  from ansible.plugins.lookup import LookupBase
57
+ from ansible._internal._templating._jinja_bits import _undef, _DEFAULT_UNDEF
58
+ from ansible._internal._datatag._tags import Origin
63
59
 
64
60
 
65
61
  class LookupModule(LookupBase):
66
- def run(self, terms, variables, **kwargs):
62
+ accept_args_markers = True # the `default` arg can accept undefined values
67
63
 
64
+ def run(self, terms, variables=None, **kwargs):
68
65
  self.set_options(var_options=variables, direct=kwargs)
69
66
 
70
67
  ret = []
71
68
  d = self.get_option('default')
69
+
72
70
  for term in terms:
73
71
  var = term.split()[0]
74
72
  val = os.environ.get(var, d)
75
- if isinstance(val, Undefined):
76
- raise AnsibleUndefinedVariable('The "env" lookup, found an undefined variable: %s' % var)
73
+
74
+ if val is _DEFAULT_UNDEF:
75
+ val = _undef(f'The environment variable {var!r} is not set.')
76
+ else:
77
+ val = Origin(description=f"<environment variable {var!r}>").try_tag(val)
78
+
77
79
  ret.append(val)
80
+
78
81
  return ret
@@ -25,7 +25,6 @@ DOCUMENTATION = """
25
25
  required: False
26
26
  default: False
27
27
  notes:
28
- - if read in variable context, the file can be interpreted as YAML if the content is valid to the parser.
29
28
  - this lookup does not understand 'globbing', use the fileglob lookup instead.
30
29
  seealso:
31
30
  - ref: playbook_task_paths
@@ -52,9 +51,8 @@ RETURN = """
52
51
  elements: str
53
52
  """
54
53
 
55
- from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleLookupError
54
+ from ansible.errors import AnsibleError
56
55
  from ansible.plugins.lookup import LookupBase
57
- from ansible.module_utils.common.text.converters import to_text
58
56
  from ansible.utils.display import Display
59
57
 
60
58
  display = Display()
@@ -74,8 +72,7 @@ class LookupModule(LookupBase):
74
72
  lookupfile = self.find_file_in_search_path(variables, 'files', term, ignore_missing=True)
75
73
  display.vvvv(u"File lookup using %s as file" % lookupfile)
76
74
  if lookupfile:
77
- b_contents, show_data = self._loader._get_file_contents(lookupfile)
78
- contents = to_text(b_contents, errors='surrogate_or_strict')
75
+ contents = self._loader.get_text_file_contents(lookupfile)
79
76
  if self.get_option('lstrip'):
80
77
  contents = contents.lstrip()
81
78
  if self.get_option('rstrip'):
@@ -83,8 +80,8 @@ class LookupModule(LookupBase):
83
80
  ret.append(contents)
84
81
  else:
85
82
  # TODO: only add search info if abs path?
86
- raise AnsibleOptionsError("file not found, use -vvvvv to see paths searched")
87
- except AnsibleError as e:
88
- raise AnsibleLookupError("The 'file' lookup had an issue accessing the file '%s'" % term, orig_exc=e)
83
+ raise AnsibleError("File not found. Use -vvvvv to see paths searched.")
84
+ except AnsibleError as ex:
85
+ raise AnsibleError(f"Unable to access the file {term!r}.") from ex
89
86
 
90
87
  return ret
@@ -40,15 +40,16 @@ DOCUMENTATION = """
40
40
  - When used as a template via C(lookup) or C(query), setting O(skip=True) will *not* cause the task to skip.
41
41
  Tasks must handle the empty list return from the template.
42
42
  - When V(False) and C(lookup) or C(query) specifies O(ignore:errors='ignore') all errors (including no file found,
43
- but potentially others) return an empty string or an empty list respectively.
43
+ but potentially others) return V(None) or an empty list respectively.
44
44
  - When V(True) and C(lookup) or C(query) specifies O(ignore:errors='ignore'), no file found will return an empty
45
- list and other potential errors return an empty string or empty list depending on the template call
45
+ list and other potential errors return V(None) or empty list depending on the template call
46
46
  (in other words return values of C(lookup) vs C(query)).
47
47
  seealso:
48
48
  - ref: playbook_task_paths
49
49
  description: Search paths used for relative paths/files.
50
50
  """
51
51
 
52
+
52
53
  EXAMPLES = """
53
54
  - name: Set _found_file to the first existing file, raising an error if a file is not found
54
55
  ansible.builtin.set_fact:
@@ -137,70 +138,77 @@ RETURN = """
137
138
  type: list
138
139
  elements: path
139
140
  """
140
- import os
141
-
142
- from collections.abc import Mapping, Sequence
143
141
 
144
- from jinja2.exceptions import UndefinedError
142
+ import collections.abc as c
143
+ import os
144
+ import re
145
+ import typing as t
145
146
 
146
- from ansible.errors import AnsibleLookupError, AnsibleUndefinedVariable
147
- from ansible.module_utils.six import string_types
147
+ from ansible._internal import _task
148
+ from ansible.errors import AnsibleError
148
149
  from ansible.plugins.lookup import LookupBase
150
+ from ansible._internal._templating import _jinja_common
151
+ from ansible._internal._templating import _jinja_plugins
152
+ from ansible import template as _template
149
153
  from ansible.utils.path import unfrackpath
154
+ from ansible.utils.display import Display
155
+ from ansible.module_utils.datatag import native_type_name
156
+
150
157
 
158
+ def _split_on(target: str, terms: str | list[str], splitters: str) -> list[str]:
159
+ termlist: list[str] = []
151
160
 
152
- def _splitter(value, chars):
153
- chars = set(chars)
154
- v = ''
155
- for c in value:
156
- if c in chars:
157
- yield v
158
- v = ''
159
- continue
160
- v += c
161
- yield v
161
+ if isinstance(terms, str):
162
+ split_terms = re.split(r'[%s]' % ''.join(map(re.escape, splitters)), terms)
162
163
 
164
+ if split_terms == [terms]:
165
+ termlist = [terms]
166
+ else:
167
+ Display().deprecated(
168
+ msg=f'Automatic splitting of {target} on {splitters!r} is deprecated.',
169
+ help_text=f'Provide a list of paths for {target} instead.',
170
+ version='2.23',
171
+ obj=terms,
172
+ )
163
173
 
164
- def _split_on(terms, spliters=','):
165
- termlist = []
166
- if isinstance(terms, string_types):
167
- termlist = list(_splitter(terms, spliters))
174
+ termlist = split_terms
168
175
  else:
169
176
  # added since options will already listify
170
- for t in terms:
171
- termlist.extend(_split_on(t, spliters))
177
+ for term in terms:
178
+ termlist.extend(_split_on(target, term, splitters))
179
+
172
180
  return termlist
173
181
 
174
182
 
175
183
  class LookupModule(LookupBase):
184
+ accept_args_markers = True # terms are allowed to be undefined
185
+ accept_lazy_markers = True # terms are allowed to be undefined
176
186
 
177
- def _process_terms(self, terms, variables, kwargs):
187
+ def _process_terms(self, terms: c.Sequence, variables: dict[str, t.Any]) -> list[str]:
178
188
 
179
189
  total_search = []
180
- skip = False
181
190
 
182
191
  # can use a dict instead of list item to pass inline config
183
192
  for term in terms:
184
- if isinstance(term, Mapping):
193
+ if isinstance(term, c.Mapping):
185
194
  self.set_options(var_options=variables, direct=term)
186
195
  files = self.get_option('files')
187
- elif isinstance(term, string_types):
196
+ files_description = "the 'files' option"
197
+ elif isinstance(term, str):
188
198
  files = [term]
189
- elif isinstance(term, Sequence):
190
- partial, skip = self._process_terms(term, variables, kwargs)
199
+ files_description = "files"
200
+ elif isinstance(term, c.Sequence):
201
+ partial = self._process_terms(term, variables)
191
202
  total_search.extend(partial)
192
203
  continue
193
204
  else:
194
- raise AnsibleLookupError("Invalid term supplied, can handle string, mapping or list of strings but got: %s for %s" % (type(term), term))
205
+ raise AnsibleError(f"Invalid term supplied. A string, dict or list is required, not {native_type_name(term)!r}).")
195
206
 
196
207
  paths = self.get_option('paths')
197
208
 
198
- # NOTE: this is used as 'global' but can be set many times?!?!?
199
- skip = self.get_option('skip')
200
-
201
209
  # magic extra splitting to create lists
202
- filelist = _split_on(files, ',;')
203
- pathlist = _split_on(paths, ',:;')
210
+ filelist = _split_on(files_description, files, ',;')
211
+ pathlist = _split_on('the "paths" option', paths, ',:;')
204
212
 
205
213
  # create search structure
206
214
  if pathlist:
@@ -208,40 +216,46 @@ class LookupModule(LookupBase):
208
216
  for fn in filelist:
209
217
  f = os.path.join(path, fn)
210
218
  total_search.append(f)
211
- elif filelist:
219
+ else:
212
220
  # NOTE: this is now 'extend', previously it would clobber all options, but we deemed that a bug
213
221
  total_search.extend(filelist)
214
- else:
215
- total_search.append(term)
216
222
 
217
- return total_search, skip
223
+ return total_search
224
+
225
+ def run(self, terms: list, variables=None, **kwargs):
226
+ if (first_marker := _template.get_first_marker_arg((), kwargs)) is not None:
227
+ first_marker.trip()
218
228
 
219
- def run(self, terms, variables, **kwargs):
229
+ if _jinja_plugins._LookupContext.current().invoked_as_with:
230
+ # we're being invoked by TaskExecutor.get_loop_items(), special backwards compatibility behavior
231
+ terms = _recurse_terms(terms, omit_undefined=True) # recursively drop undefined values from terms for backwards compatibility
232
+
233
+ # invoked_as_with shouldn't be possible outside a TaskContext
234
+ te_action = _task.TaskContext.current().task.action # FIXME: this value has not been templated, it should be (historical problem)...
235
+
236
+ # based on the presence of `var`/`template`/`file` in the enclosing task action name, choose a subdir to search
237
+ for subdir in ['template', 'var', 'file']:
238
+ if subdir in te_action:
239
+ break
240
+
241
+ subdir += "s" # convert to the matching directory name
242
+ else:
243
+ terms = _recurse_terms(terms, omit_undefined=False) # undefined values are only omitted when invoked using `with`
244
+
245
+ subdir = None
220
246
 
221
247
  self.set_options(var_options=variables, direct=kwargs)
222
248
 
223
249
  if not terms:
224
250
  terms = self.get_option('files')
225
251
 
226
- total_search, skip = self._process_terms(terms, variables, kwargs)
252
+ total_search = self._process_terms(terms, variables)
227
253
 
228
254
  # NOTE: during refactor noticed that the 'using a dict' as term
229
255
  # is designed to only work with 'one' otherwise inconsistencies will appear.
230
256
  # see other notes below.
231
257
 
232
- # actually search
233
- subdir = getattr(self, '_subdir', 'files')
234
-
235
- path = None
236
258
  for fn in total_search:
237
-
238
- try:
239
- fn = self._templar.template(fn)
240
- except (AnsibleUndefinedVariable, UndefinedError):
241
- # NOTE: backwards compat ff behaviour is to ignore errors when vars are undefined.
242
- # moved here from task_executor.
243
- continue
244
-
245
259
  # get subdir if set by task executor, default to files otherwise
246
260
  path = self.find_file_in_search_path(variables, subdir, fn, ignore_missing=True)
247
261
 
@@ -249,8 +263,26 @@ class LookupModule(LookupBase):
249
263
  if path is not None:
250
264
  return [unfrackpath(path, follow=False)]
251
265
 
266
+ skip = self.get_option('skip')
267
+
252
268
  # if we get here, no file was found
253
269
  if skip:
254
270
  # NOTE: global skip won't matter, only last 'skip' value in dict term
255
271
  return []
256
- raise AnsibleLookupError("No file was found when using first_found.")
272
+
273
+ raise AnsibleError("No file was found when using first_found.")
274
+
275
+
276
+ def _recurse_terms(o: t.Any, omit_undefined: bool) -> t.Any:
277
+ """Recurse through supported container types, optionally omitting undefined markers and tripping all remaining markers, returning the result."""
278
+ match o:
279
+ case dict():
280
+ return {k: _recurse_terms(v, omit_undefined) for k, v in o.items() if not (omit_undefined and isinstance(v, _jinja_common.UndefinedMarker))}
281
+ case list():
282
+ return [_recurse_terms(v, omit_undefined) for v in o if not (omit_undefined and isinstance(v, _jinja_common.UndefinedMarker))]
283
+ case tuple():
284
+ return tuple(_recurse_terms(v, omit_undefined) for v in o if not (omit_undefined and isinstance(v, _jinja_common.UndefinedMarker)))
285
+ case _jinja_common.Marker():
286
+ o.trip()
287
+ case _:
288
+ return o
@@ -33,19 +33,10 @@ RETURN = """
33
33
  elements: list
34
34
  """
35
35
 
36
- from ansible.errors import AnsibleError
37
36
  from ansible.plugins.lookup import LookupBase
38
37
 
39
38
 
40
39
  class LookupModule(LookupBase):
41
-
42
- def __init__(self, basedir=None, **kwargs):
43
- self.basedir = basedir
44
-
45
- def run(self, terms, variables, **kwargs):
46
-
47
- if not isinstance(terms, list):
48
- raise AnsibleError("with_indexed_items expects a list")
49
-
40
+ def run(self, terms, variables=None, **kwargs):
50
41
  items = self._flatten(terms)
51
42
  return list(zip(range(len(items)), items))