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
@@ -14,14 +14,14 @@
14
14
  # along with Ansible. If not, see <http://www.gnu.org/licenses/>.
15
15
  from __future__ import annotations
16
16
 
17
- DOCUMENTATION = '''
17
+ DOCUMENTATION = """
18
18
  name: debug
19
19
  short_description: Executes tasks in interactive debug session.
20
20
  description:
21
21
  - Task execution is 'linear' but controlled by an interactive debug session.
22
22
  version_added: "2.1"
23
23
  author: Kishin Yagami (!UNKNOWN)
24
- '''
24
+ """
25
25
 
26
26
  from ansible.plugins.strategy.linear import StrategyModule as LinearStrategyModule
27
27
 
@@ -16,7 +16,7 @@
16
16
  # along with Ansible. If not, see <http://www.gnu.org/licenses/>.
17
17
  from __future__ import annotations
18
18
 
19
- DOCUMENTATION = '''
19
+ DOCUMENTATION = """
20
20
  name: free
21
21
  short_description: Executes tasks without waiting for all hosts
22
22
  description:
@@ -27,7 +27,7 @@ DOCUMENTATION = '''
27
27
  won't hold up the rest of the hosts and tasks.
28
28
  version_added: "2.0"
29
29
  author: Ansible Core Team
30
- '''
30
+ """
31
31
 
32
32
  import time
33
33
 
@@ -37,8 +37,7 @@ from ansible.playbook.handler import Handler
37
37
  from ansible.playbook.included_file import IncludedFile
38
38
  from ansible.plugins.loader import action_loader
39
39
  from ansible.plugins.strategy import StrategyBase
40
- from ansible.template import Templar
41
- from ansible.module_utils.common.text.converters import to_text
40
+ from ansible._internal._templating._engine import TemplateEngine
42
41
  from ansible.utils.display import Display
43
42
 
44
43
  display = Display()
@@ -54,7 +53,7 @@ class StrategyModule(StrategyBase):
54
53
  self._host_pinned = False
55
54
 
56
55
  def run(self, iterator, play_context):
57
- '''
56
+ """
58
57
  The "free" strategy is a bit more complex, in that it allows tasks to
59
58
  be sent to hosts as quickly as they can be processed. This means that
60
59
  some hosts may finish very quickly if run tasks result in little or no
@@ -65,7 +64,7 @@ class StrategyModule(StrategyBase):
65
64
  and starting the search from there as opposed to the top of the hosts
66
65
  list again, which would end up favoring hosts near the beginning of the
67
66
  list.
68
- '''
67
+ """
69
68
 
70
69
  # the last host to be given a task
71
70
  last_host = 0
@@ -124,13 +123,13 @@ class StrategyModule(StrategyBase):
124
123
  _hosts=self._hosts_cache,
125
124
  _hosts_all=self._hosts_cache_all)
126
125
  self.add_tqm_variables(task_vars, play=iterator._play)
127
- templar = Templar(loader=self._loader, variables=task_vars)
126
+ templar = TemplateEngine(loader=self._loader, variables=task_vars)
128
127
  display.debug("done getting variables", host=host_name)
129
128
 
130
129
  try:
131
130
  throttle = int(templar.template(task.throttle))
132
- except Exception as e:
133
- raise AnsibleError("Failed to convert the throttle value to an integer.", obj=task._ds, orig_exc=e)
131
+ except Exception as ex:
132
+ raise AnsibleError("Failed to convert the throttle value to an integer.", obj=task.throttle) from ex
134
133
 
135
134
  if throttle > 0:
136
135
  same_tasks = 0
@@ -155,13 +154,7 @@ class StrategyModule(StrategyBase):
155
154
  # corresponding action plugin
156
155
  action = None
157
156
 
158
- try:
159
- task.name = to_text(templar.template(task.name, fail_on_undefined=False), nonstring='empty')
160
- display.debug("done templating", host=host_name)
161
- except Exception:
162
- # just ignore any errors during task name templating,
163
- # we don't care if it just shows the raw name
164
- display.debug("templating failed for some reason", host=host_name)
157
+ task.post_validate_attribute("name", templar=templar)
165
158
 
166
159
  run_once = templar.template(task.run_once) or action and getattr(action, 'BYPASS_HOST_LOOP', False)
167
160
  if run_once:
@@ -172,15 +165,6 @@ class StrategyModule(StrategyBase):
172
165
  display.warning("Using run_once with the free strategy is not currently supported. This task will still be "
173
166
  "executed for every host in the inventory list.")
174
167
 
175
- # check to see if this task should be skipped, due to it being a member of a
176
- # role which has already run (and whether that role allows duplicate execution)
177
- if not isinstance(task, Handler) and task._role:
178
- role_obj = self._get_cached_role(task, iterator._play)
179
- if role_obj.has_run(host) and task._role._metadata.allow_duplicates is False:
180
- display.debug("'%s' skipped because role has already run" % task, host=host_name)
181
- del self._blocked_hosts[host_name]
182
- continue
183
-
184
168
  if task.action in C._ACTION_META:
185
169
  if self._host_pinned:
186
170
  meta_task_dummy_results_count += 1
@@ -264,14 +248,15 @@ class StrategyModule(StrategyBase):
264
248
  iterator.handlers = [h for b in iterator._play.handlers for h in b.block]
265
249
  except AnsibleParserError:
266
250
  raise
267
- except AnsibleError as e:
268
- display.error(to_text(e), wrap_text=False)
251
+ except AnsibleError as ex:
252
+ # FIXME: send the error to the callback; don't directly write to display here
253
+ display.error(ex)
269
254
  for r in included_file._results:
270
- r._result['failed'] = True
271
- r._result['reason'] = str(e)
272
- self._tqm._stats.increment('failures', r._host.name)
255
+ r._return_data['failed'] = True
256
+ r._return_data['reason'] = str(ex)
257
+ self._tqm._stats.increment('failures', r.host.name)
273
258
  self._tqm.send_callback('v2_runner_on_failed', r)
274
- failed_includes_hosts.add(r._host)
259
+ failed_includes_hosts.add(r.host)
275
260
  continue
276
261
  else:
277
262
  # since we skip incrementing the stats when the task result is
@@ -16,7 +16,7 @@
16
16
  # along with Ansible. If not, see <http://www.gnu.org/licenses/>.
17
17
  from __future__ import annotations
18
18
 
19
- DOCUMENTATION = '''
19
+ DOCUMENTATION = """
20
20
  name: host_pinned
21
21
  short_description: Executes tasks on each host without interruption
22
22
  description:
@@ -28,7 +28,7 @@ DOCUMENTATION = '''
28
28
  Other than that, it behaves just like the "free" strategy.
29
29
  version_added: "2.7"
30
30
  author: Ansible Core Team
31
- '''
31
+ """
32
32
 
33
33
  from ansible.plugins.strategy.free import StrategyModule as FreeStrategyModule
34
34
  from ansible.utils.display import Display
@@ -16,7 +16,7 @@
16
16
  # along with Ansible. If not, see <http://www.gnu.org/licenses/>.
17
17
  from __future__ import annotations
18
18
 
19
- DOCUMENTATION = '''
19
+ DOCUMENTATION = """
20
20
  name: linear
21
21
  short_description: Executes tasks in a linear fashion
22
22
  description:
@@ -27,29 +27,34 @@ DOCUMENTATION = '''
27
27
  notes:
28
28
  - This was the default Ansible behaviour before 'strategy plugins' were introduced in 2.0.
29
29
  author: Ansible Core Team
30
- '''
30
+ """
31
31
 
32
32
  from ansible import constants as C
33
- from ansible.errors import AnsibleError, AnsibleAssertionError, AnsibleParserError
34
- from ansible.module_utils.common.text.converters import to_text
33
+ from ansible.errors import AnsibleError, AnsibleAssertionError, AnsibleParserError, AnsibleValueOmittedError
35
34
  from ansible.playbook.handler import Handler
36
35
  from ansible.playbook.included_file import IncludedFile
37
36
  from ansible.plugins.loader import action_loader
38
37
  from ansible.plugins.strategy import StrategyBase
39
- from ansible.template import Templar
38
+ from ansible._internal._templating._engine import TemplateEngine
40
39
  from ansible.utils.display import Display
40
+ from ansible.inventory.host import Host
41
+ from ansible.playbook.task import Task
42
+ from ansible.executor.play_iterator import PlayIterator
43
+ from ansible.playbook.play_context import PlayContext
44
+ from ansible.executor import task_result as _task_result
41
45
 
42
46
  display = Display()
43
47
 
44
48
 
45
49
  class StrategyModule(StrategyBase):
46
50
 
47
- def _get_next_task_lockstep(self, hosts, iterator):
48
- '''
51
+ def _get_next_task_lockstep(self, hosts: list[Host], iterator: PlayIterator) -> list[tuple[Host, Task]]:
52
+ """
49
53
  Returns a list of (host, task) tuples, where the task may
50
54
  be a noop task to keep the iterator in lock step across
51
55
  all hosts.
52
- '''
56
+ """
57
+
53
58
  state_task_per_host = {}
54
59
  for host in hosts:
55
60
  state, task = iterator.get_next_task_for_host(host, peek=True)
@@ -84,20 +89,20 @@ class StrategyModule(StrategyBase):
84
89
  iterator.set_state_for_host(host.name, state)
85
90
  host_tasks.append((host, task))
86
91
 
87
- if cur_task.action in C._ACTION_META and cur_task.args.get('_raw_params') == 'flush_handlers':
92
+ if cur_task._get_meta() == 'flush_handlers':
88
93
  iterator.all_tasks[iterator.cur_task:iterator.cur_task] = [h for b in iterator._play.handlers for h in b.block]
89
94
 
90
95
  return host_tasks
91
96
 
92
- def run(self, iterator, play_context):
93
- '''
97
+ def run(self, iterator, play_context: PlayContext): # type: ignore[override]
98
+ """
94
99
  The linear strategy is simple - get the next task and queue
95
100
  it for all hosts, then wait for the queue to drain before
96
101
  moving on to the next task
97
- '''
102
+ """
98
103
 
99
104
  # iterate over each task, while there is one left to run
100
- result = self._tqm.RUN_OK
105
+ result = int(self._tqm.RUN_OK)
101
106
  work_to_do = True
102
107
 
103
108
  self._set_hosts_cache(iterator._play)
@@ -122,7 +127,7 @@ class StrategyModule(StrategyBase):
122
127
  # flag set if task is set to any_errors_fatal
123
128
  any_errors_fatal = False
124
129
 
125
- results = []
130
+ results: list[_task_result._RawTaskResult] = []
126
131
  for (host, task) in host_tasks:
127
132
  if self._tqm._terminated:
128
133
  break
@@ -130,26 +135,23 @@ class StrategyModule(StrategyBase):
130
135
  run_once = False
131
136
  work_to_do = True
132
137
 
133
- # check to see if this task should be skipped, due to it being a member of a
134
- # role which has already run (and whether that role allows duplicate execution)
135
- if not isinstance(task, Handler) and task._role:
136
- role_obj = self._get_cached_role(task, iterator._play)
137
- if role_obj.has_run(host) and task._role._metadata.allow_duplicates is False:
138
- display.debug("'%s' skipped because role has already run" % task)
139
- continue
138
+ host_name = host.get_name()
140
139
 
141
140
  display.debug("getting variables")
142
141
  task_vars = self._variable_manager.get_vars(play=iterator._play, host=host, task=task,
143
142
  _hosts=self._hosts_cache, _hosts_all=self._hosts_cache_all)
144
143
  self.add_tqm_variables(task_vars, play=iterator._play)
145
- templar = Templar(loader=self._loader, variables=task_vars)
144
+ templar = TemplateEngine(loader=self._loader, variables=task_vars)
146
145
  display.debug("done getting variables")
147
146
 
148
147
  # test to see if the task across all hosts points to an action plugin which
149
148
  # sets BYPASS_HOST_LOOP to true, or if it has run_once enabled. If so, we
150
149
  # will only send this task to the first host in the list.
151
150
 
152
- task_action = templar.template(task.action)
151
+ try:
152
+ task_action = templar.template(task.action)
153
+ except AnsibleValueOmittedError:
154
+ raise AnsibleParserError("Omit is not valid for the `action` keyword.", obj=task.action) from None
153
155
 
154
156
  try:
155
157
  action = action_loader.get(task_action, class_only=True, collection_list=task.collections)
@@ -162,7 +164,7 @@ class StrategyModule(StrategyBase):
162
164
  # for the linear strategy, we run meta tasks just once and for
163
165
  # all hosts currently being iterated over rather than one host
164
166
  results.extend(self._execute_meta(task, play_context, iterator, host))
165
- if task.args.get('_raw_params', None) not in ('noop', 'reset_connection', 'end_host', 'role_complete', 'flush_handlers', 'end_role'):
167
+ if task._get_meta() not in ('noop', 'reset_connection', 'end_host', 'role_complete', 'flush_handlers', 'end_role'):
166
168
  run_once = True
167
169
  if (task.any_errors_fatal or run_once) and not task.ignore_errors:
168
170
  any_errors_fatal = True
@@ -176,22 +178,20 @@ class StrategyModule(StrategyBase):
176
178
  break
177
179
 
178
180
  run_once = action and getattr(action, 'BYPASS_HOST_LOOP', False) or templar.template(task.run_once)
179
- try:
180
- task.name = to_text(templar.template(task.name, fail_on_undefined=False), nonstring='empty')
181
- except Exception as e:
182
- display.debug(f"Failed to templalte task name ({task.name}), ignoring error and continuing: {e}")
183
181
 
184
182
  if (task.any_errors_fatal or run_once) and not task.ignore_errors:
185
183
  any_errors_fatal = True
186
184
 
187
185
  if not callback_sent:
186
+ task.post_validate_attribute("name", templar=templar)
187
+
188
188
  if isinstance(task, Handler):
189
189
  self._tqm.send_callback('v2_playbook_on_handler_task_start', task)
190
190
  else:
191
191
  self._tqm.send_callback('v2_playbook_on_task_start', task, is_conditional=False)
192
192
  callback_sent = True
193
193
 
194
- self._blocked_hosts[host.get_name()] = True
194
+ self._blocked_hosts[host_name] = True
195
195
  self._queue_task(host, task, task_vars, play_context)
196
196
  del task_vars
197
197
 
@@ -283,14 +283,15 @@ class StrategyModule(StrategyBase):
283
283
  display.debug("done iterating over new_blocks loaded from include file")
284
284
  except AnsibleParserError:
285
285
  raise
286
- except AnsibleError as e:
287
- display.error(to_text(e), wrap_text=False)
286
+ except AnsibleError as ex:
287
+ # FIXME: send the error to the callback; don't directly write to display here
288
+ display.error(ex)
288
289
  for r in included_file._results:
289
- r._result['failed'] = True
290
- r._result['reason'] = str(e)
291
- self._tqm._stats.increment('failures', r._host.name)
290
+ r._return_data['failed'] = True
291
+ r._return_data['reason'] = str(ex)
292
+ self._tqm._stats.increment('failures', r.host.name)
292
293
  self._tqm.send_callback('v2_runner_on_failed', r)
293
- failed_includes_hosts.add(r._host)
294
+ failed_includes_hosts.add(r.host)
294
295
  else:
295
296
  # since we skip incrementing the stats when the task result is
296
297
  # first processed, we do so now for each host in the list
@@ -321,9 +322,9 @@ class StrategyModule(StrategyBase):
321
322
  unreachable_hosts = []
322
323
  for res in results:
323
324
  if res.is_failed():
324
- failed_hosts.append(res._host.name)
325
+ failed_hosts.append(res.host.name)
325
326
  elif res.is_unreachable():
326
- unreachable_hosts.append(res._host.name)
327
+ unreachable_hosts.append(res.host.name)
327
328
 
328
329
  if any_errors_fatal and (failed_hosts or unreachable_hosts):
329
330
  for host in hosts_left:
@@ -355,10 +356,9 @@ class StrategyModule(StrategyBase):
355
356
  return result
356
357
  display.debug("done checking to see if all hosts have failed")
357
358
 
358
- except (IOError, EOFError) as e:
359
- display.debug("got IOError/EOFError in task loop: %s" % e)
360
- # most likely an abort, return failed
361
- return self._tqm.RUN_UNKNOWN_ERROR
359
+ finally:
360
+ # removed unnecessary exception handler, don't want to mis-attribute the entire code block by changing indentation
361
+ pass
362
362
 
363
363
  # run the base class run() method, which executes the cleanup function
364
364
  # and runs any outstanding handlers which have been triggered
@@ -26,7 +26,7 @@ from ansible.errors import AnsibleConnectionFailure
26
26
 
27
27
 
28
28
  class TerminalBase(ABC):
29
- '''
29
+ """
30
30
  A base class for implementing cli connections
31
31
 
32
32
  .. note:: Unlike most of Ansible, nearly all strings in
@@ -36,7 +36,7 @@ class TerminalBase(ABC):
36
36
  :func:`~ansible.module_utils.common.text.converters.to_bytes` and
37
37
  :func:`~ansible.module_utils.common.text.converters.to_text` to avoid unexpected
38
38
  problems.
39
- '''
39
+ """
40
40
 
41
41
  #: compiled bytes regular expressions as stdout
42
42
  terminal_stdout_re = [] # type: list[re.Pattern]
@@ -64,11 +64,11 @@ class TerminalBase(ABC):
64
64
  self._connection = connection
65
65
 
66
66
  def _exec_cli_command(self, cmd, check_rc=True):
67
- '''
67
+ """
68
68
  Executes the CLI command on the remote device and returns the output
69
69
 
70
70
  :arg cmd: Byte string command to be executed
71
- '''
71
+ """
72
72
  return self._connection.exec_command(cmd)
73
73
 
74
74
  def _get_prompt(self):
@@ -3,10 +3,15 @@
3
3
 
4
4
  from __future__ import annotations
5
5
 
6
+ import typing as t
7
+
6
8
  from ansible.plugins import AnsibleJinja2Plugin
7
9
 
8
10
 
9
11
  class AnsibleJinja2Test(AnsibleJinja2Plugin):
12
+ @property
13
+ def plugin_type(self) -> str:
14
+ return "test"
10
15
 
11
- def _no_options(self, *args, **kwargs):
12
- raise NotImplementedError("Jinaj2 test plugins do not support option functions, they use direct arguments instead.")
16
+ def _no_options(self, *args, **kwargs) -> t.NoReturn:
17
+ raise NotImplementedError("Jinja2 test plugins do not support option functions, they use direct arguments instead.")
@@ -17,17 +17,22 @@
17
17
 
18
18
  from __future__ import annotations
19
19
 
20
+ import functools
20
21
  import re
21
22
  import operator as py_operator
22
23
 
23
24
  from collections.abc import MutableMapping, MutableSequence
24
25
 
26
+ from jinja2.tests import test_defined, test_undefined
27
+
25
28
  from ansible.module_utils.compat.version import LooseVersion, StrictVersion
26
29
 
27
30
  from ansible import errors
28
31
  from ansible.module_utils.common.text.converters import to_native, to_text, to_bytes
32
+ from ansible._internal._templating._jinja_common import Marker, UndefinedMarker
29
33
  from ansible.module_utils.parsing.convert_bool import boolean
30
- from ansible.parsing.vault import is_encrypted_file
34
+ from ansible.template import accept_args_markers
35
+ from ansible.parsing.vault import is_encrypted_file, VaultHelper, VaultLib
31
36
  from ansible.utils.display import Display
32
37
  from ansible.utils.version import SemanticVersion
33
38
 
@@ -41,40 +46,44 @@ display = Display()
41
46
 
42
47
 
43
48
  def timedout(result):
44
- ''' Test if task result yields a time out'''
49
+ """ Test if task result yields a time out"""
45
50
  if not isinstance(result, MutableMapping):
46
51
  raise errors.AnsibleFilterError("The 'timedout' test expects a dictionary")
47
- return result.get('timedout', False) and result['timedout'].get('period', False)
52
+
53
+ return bool(result.get('timedout') and bool(result['timedout'].get('period')))
48
54
 
49
55
 
50
56
  def failed(result):
51
- ''' Test if task result yields failed '''
57
+ """ Test if task result yields failed """
52
58
  if not isinstance(result, MutableMapping):
53
59
  raise errors.AnsibleFilterError("The 'failed' test expects a dictionary")
54
- return result.get('failed', False)
60
+
61
+ return bool(result.get('failed'))
55
62
 
56
63
 
57
64
  def success(result):
58
- ''' Test if task result yields success '''
59
- return not failed(result)
65
+ """ Test if task result yields success """
66
+ return not bool(failed(result))
60
67
 
61
68
 
62
69
  def unreachable(result):
63
- ''' Test if task result yields unreachable '''
70
+ """ Test if task result yields unreachable """
64
71
  if not isinstance(result, MutableMapping):
65
72
  raise errors.AnsibleFilterError("The 'unreachable' test expects a dictionary")
66
- return result.get('unreachable', False)
73
+
74
+ return bool(result.get('unreachable'))
67
75
 
68
76
 
69
77
  def reachable(result):
70
- ''' Test if task result yields reachable '''
71
- return not unreachable(result)
78
+ """ Test if task result yields reachable """
79
+ return bool(not unreachable(result))
72
80
 
73
81
 
74
82
  def changed(result):
75
- ''' Test if task result yields changed '''
83
+ """ Test if task result yields changed """
76
84
  if not isinstance(result, MutableMapping):
77
85
  raise errors.AnsibleFilterError("The 'changed' test expects a dictionary")
86
+
78
87
  if 'changed' not in result:
79
88
  changed = False
80
89
  if (
@@ -83,29 +92,31 @@ def changed(result):
83
92
  isinstance(result['results'][0], MutableMapping)
84
93
  ):
85
94
  for res in result['results']:
86
- if res.get('changed', False):
95
+ if res.get('changed'):
87
96
  changed = True
88
97
  break
89
98
  else:
90
- changed = result.get('changed', False)
91
- return changed
99
+ changed = result.get('changed')
100
+
101
+ return bool(changed)
92
102
 
93
103
 
94
104
  def skipped(result):
95
- ''' Test if task result yields skipped '''
105
+ """ Test if task result yields skipped """
96
106
  if not isinstance(result, MutableMapping):
97
107
  raise errors.AnsibleFilterError("The 'skipped' test expects a dictionary")
98
- return result.get('skipped', False)
108
+
109
+ return bool(result.get('skipped'))
99
110
 
100
111
 
101
112
  def started(result):
102
- ''' Test if async task has started '''
113
+ """ Test if async task has started """
103
114
  if not isinstance(result, MutableMapping):
104
115
  raise errors.AnsibleFilterError("The 'started' test expects a dictionary")
116
+
105
117
  if 'started' in result:
106
118
  # For async tasks, return status
107
- # NOTE: The value of started is 0 or 1, not False or True :-/
108
- return result.get('started', 0) == 1
119
+ return bool(result.get('started'))
109
120
  else:
110
121
  # For non-async tasks, warn user, but return as if started
111
122
  display.warning("The 'started' test expects an async task, but a non-async task was tested")
@@ -113,13 +124,13 @@ def started(result):
113
124
 
114
125
 
115
126
  def finished(result):
116
- ''' Test if async task has finished '''
127
+ """ Test if async task has finished """
117
128
  if not isinstance(result, MutableMapping):
118
129
  raise errors.AnsibleFilterError("The 'finished' test expects a dictionary")
130
+
119
131
  if 'finished' in result:
120
132
  # For async tasks, return status
121
- # NOTE: The value of finished is 0 or 1, not False or True :-/
122
- return result.get('finished', 0) == 1
133
+ return bool(result.get('finished'))
123
134
  else:
124
135
  # For non-async tasks, warn user, but return as if finished
125
136
  display.warning("The 'finished' test expects an async task, but a non-async task was tested")
@@ -127,12 +138,10 @@ def finished(result):
127
138
 
128
139
 
129
140
  def regex(value='', pattern='', ignorecase=False, multiline=False, match_type='search'):
130
- ''' Expose `re` as a boolean filter using the `search` method by default.
141
+ """ Expose `re` as a boolean filter using the `search` method by default.
131
142
  This is likely only useful for `search` and `match` which already
132
143
  have their own filters.
133
- '''
134
- # In addition to ensuring the correct type, to_text here will ensure
135
- # _fail_with_undefined_error happens if the value is Undefined
144
+ """
136
145
  value = to_text(value, errors='surrogate_or_strict')
137
146
  flags = 0
138
147
  if ignorecase:
@@ -143,12 +152,19 @@ def regex(value='', pattern='', ignorecase=False, multiline=False, match_type='s
143
152
  return bool(getattr(_re, match_type, 'search')(value))
144
153
 
145
154
 
146
- def vault_encrypted(value):
155
+ @accept_args_markers
156
+ def vault_encrypted(value: object) -> bool:
147
157
  """Evaluate whether a variable is a single vault encrypted value
148
158
 
149
159
  .. versionadded:: 2.10
150
160
  """
151
- return getattr(value, '__ENCRYPTED__', False) and value.is_encrypted()
161
+ if ciphertext := VaultHelper.get_ciphertext(value, with_tags=False):
162
+ return VaultLib.is_encrypted(ciphertext)
163
+
164
+ if isinstance(value, Marker):
165
+ value.trip()
166
+
167
+ return False
152
168
 
153
169
 
154
170
  def vaulted_file(value):
@@ -159,22 +175,22 @@ def vaulted_file(value):
159
175
  try:
160
176
  with open(to_bytes(value), 'rb') as f:
161
177
  return is_encrypted_file(f)
162
- except (OSError, IOError) as e:
163
- raise errors.AnsibleFilterError(f"Cannot test if the file {value} is a vault", orig_exc=e)
178
+ except OSError as ex:
179
+ raise errors.AnsibleFilterError(f"Cannot test if the file {value!r} is a vault.") from ex
164
180
 
165
181
 
166
182
  def match(value, pattern='', ignorecase=False, multiline=False):
167
- ''' Perform a `re.match` returning a boolean '''
183
+ """ Perform a `re.match` returning a boolean """
168
184
  return regex(value, pattern, ignorecase, multiline, 'match')
169
185
 
170
186
 
171
187
  def search(value, pattern='', ignorecase=False, multiline=False):
172
- ''' Perform a `re.search` returning a boolean '''
188
+ """ Perform a `re.search` returning a boolean """
173
189
  return regex(value, pattern, ignorecase, multiline, 'search')
174
190
 
175
191
 
176
192
  def version_compare(value, version, operator='eq', strict=None, version_type=None):
177
- ''' Perform a version comparison on a value '''
193
+ """ Perform a version comparison on a value """
178
194
  op_map = {
179
195
  '==': 'eq', '=': 'eq', 'eq': 'eq',
180
196
  '<': 'lt', 'lt': 'lt',
@@ -257,8 +273,28 @@ def falsy(value, convert_bool=False):
257
273
  return not truthy(value, convert_bool=convert_bool)
258
274
 
259
275
 
276
+ @accept_args_markers
277
+ @functools.wraps(test_defined)
278
+ def wrapped_test_defined(value: object) -> Marker | bool:
279
+ """Wrapper around Jinja's `defined` test to avoid mutating the externally-owned function with our marker attribute."""
280
+ if isinstance(value, Marker) and not isinstance(value, UndefinedMarker):
281
+ return value
282
+
283
+ return test_defined(value)
284
+
285
+
286
+ @accept_args_markers
287
+ @functools.wraps(test_undefined)
288
+ def wrapped_test_undefined(value: object) -> Marker | bool:
289
+ """Wrapper around Jinja's `undefined` test to avoid mutating the externally-owned function with our marker attribute."""
290
+ if isinstance(value, Marker) and not isinstance(value, UndefinedMarker):
291
+ return value
292
+
293
+ return test_undefined(value)
294
+
295
+
260
296
  class TestModule(object):
261
- ''' Ansible core jinja2 tests '''
297
+ """ Ansible core jinja2 tests """
262
298
 
263
299
  def tests(self):
264
300
  return {
@@ -304,4 +340,8 @@ class TestModule(object):
304
340
  # vault
305
341
  'vault_encrypted': vault_encrypted,
306
342
  'vaulted_file': vaulted_file,
343
+
344
+ # overrides that require special arg handling
345
+ 'defined': wrapped_test_defined,
346
+ 'undefined': wrapped_test_undefined,
307
347
  }
@@ -21,7 +21,7 @@ from os.path import isdir, isfile, isabs, exists, lexists, islink, samefile, ism
21
21
 
22
22
 
23
23
  class TestModule(object):
24
- ''' Ansible file jinja2 tests '''
24
+ """ Ansible file jinja2 tests """
25
25
 
26
26
  def tests(self):
27
27
  return {
@@ -5,7 +5,7 @@ DOCUMENTATION:
5
5
  short_description: Did async task finish
6
6
  description:
7
7
  - Used to test if an async task has finished, it will also work with normal tasks but will issue a warning.
8
- - This test checks for the existence of a C(finished) key in the input dictionary and that it is V(1) if present
8
+ - This test checks for the existence of a C(finished) key in the input dictionary and that it is V(True) if present
9
9
  options:
10
10
  _input:
11
11
  description: registered result from an Ansible task