ansible-core 2.18.4rc1__py3-none-any.whl → 2.19.0b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (709) hide show
  1. ansible/_internal/__init__.py +53 -0
  2. ansible/_internal/_ansiballz.py +265 -0
  3. ansible/_internal/_datatag/__init__.py +0 -0
  4. ansible/_internal/_datatag/_tags.py +130 -0
  5. ansible/_internal/_datatag/_utils.py +19 -0
  6. ansible/_internal/_datatag/_wrappers.py +33 -0
  7. ansible/_internal/_errors/__init__.py +0 -0
  8. ansible/_internal/_errors/_captured.py +128 -0
  9. ansible/_internal/_errors/_handler.py +91 -0
  10. ansible/_internal/_errors/_utils.py +310 -0
  11. ansible/_internal/_json/__init__.py +160 -0
  12. ansible/_internal/_json/_legacy_encoder.py +34 -0
  13. ansible/_internal/_json/_profiles/__init__.py +0 -0
  14. ansible/_internal/_json/_profiles/_cache_persistence.py +55 -0
  15. ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
  16. ansible/_internal/_json/_profiles/_legacy.py +198 -0
  17. ansible/_internal/_locking.py +21 -0
  18. ansible/_internal/_plugins/__init__.py +0 -0
  19. ansible/_internal/_plugins/_cache.py +57 -0
  20. ansible/_internal/_task.py +78 -0
  21. ansible/_internal/_templating/__init__.py +10 -0
  22. ansible/_internal/_templating/_access.py +86 -0
  23. ansible/_internal/_templating/_chain_templar.py +63 -0
  24. ansible/_internal/_templating/_datatag.py +95 -0
  25. ansible/_internal/_templating/_engine.py +588 -0
  26. ansible/_internal/_templating/_errors.py +28 -0
  27. ansible/_internal/_templating/_jinja_bits.py +1066 -0
  28. ansible/_internal/_templating/_jinja_common.py +332 -0
  29. ansible/_internal/_templating/_jinja_patches.py +44 -0
  30. ansible/_internal/_templating/_jinja_plugins.py +351 -0
  31. ansible/_internal/_templating/_lazy_containers.py +633 -0
  32. ansible/_internal/_templating/_marker_behaviors.py +103 -0
  33. ansible/_internal/_templating/_transform.py +63 -0
  34. ansible/_internal/_templating/_utils.py +107 -0
  35. ansible/_internal/_wrapt.py +1052 -0
  36. ansible/_internal/_yaml/__init__.py +0 -0
  37. ansible/_internal/_yaml/_constructor.py +240 -0
  38. ansible/_internal/_yaml/_dumper.py +62 -0
  39. ansible/_internal/_yaml/_errors.py +166 -0
  40. ansible/_internal/_yaml/_loader.py +66 -0
  41. ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
  42. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
  43. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
  44. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +18 -0
  45. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
  46. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
  47. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
  48. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
  49. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
  50. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
  51. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
  52. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
  53. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
  54. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
  55. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
  56. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
  57. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
  58. ansible/cli/__init__.py +153 -89
  59. ansible/cli/_ssh_askpass.py +47 -0
  60. ansible/cli/adhoc.py +14 -7
  61. ansible/cli/arguments/option_helpers.py +154 -7
  62. ansible/cli/config.py +43 -68
  63. ansible/cli/console.py +10 -8
  64. ansible/cli/doc.py +48 -46
  65. ansible/cli/galaxy.py +27 -20
  66. ansible/cli/inventory.py +28 -26
  67. ansible/cli/playbook.py +4 -12
  68. ansible/cli/pull.py +51 -11
  69. ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
  70. ansible/cli/vault.py +12 -11
  71. ansible/compat/__init__.py +2 -2
  72. ansible/config/base.yml +165 -108
  73. ansible/config/manager.py +52 -49
  74. ansible/constants.py +3 -4
  75. ansible/errors/__init__.py +277 -235
  76. ansible/executor/interpreter_discovery.py +28 -149
  77. ansible/executor/module_common.py +426 -493
  78. ansible/executor/play_iterator.py +22 -27
  79. ansible/executor/playbook_executor.py +11 -11
  80. ansible/executor/powershell/async_watchdog.ps1 +97 -102
  81. ansible/executor/powershell/async_wrapper.ps1 +202 -151
  82. ansible/executor/powershell/become_wrapper.ps1 +89 -144
  83. ansible/executor/powershell/bootstrap_wrapper.ps1 +24 -9
  84. ansible/executor/powershell/coverage_wrapper.ps1 +82 -135
  85. ansible/executor/powershell/exec_wrapper.ps1 +462 -196
  86. ansible/executor/powershell/module_manifest.py +417 -265
  87. ansible/executor/powershell/module_wrapper.ps1 +169 -186
  88. ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
  89. ansible/executor/powershell/psrp_put_file.ps1 +122 -0
  90. ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
  91. ansible/executor/powershell/winrm_put_file.ps1 +36 -0
  92. ansible/executor/process/worker.py +136 -76
  93. ansible/executor/stats.py +5 -5
  94. ansible/executor/task_executor.py +237 -236
  95. ansible/executor/task_queue_manager.py +62 -38
  96. ansible/executor/task_result.py +21 -12
  97. ansible/galaxy/__init__.py +2 -2
  98. ansible/galaxy/api.py +22 -18
  99. ansible/galaxy/collection/__init__.py +1 -1
  100. ansible/galaxy/collection/concrete_artifact_manager.py +8 -11
  101. ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
  102. ansible/galaxy/dependency_resolution/providers.py +1 -1
  103. ansible/galaxy/dependency_resolution/reporters.py +81 -0
  104. ansible/galaxy/role.py +4 -8
  105. ansible/galaxy/token.py +28 -21
  106. ansible/inventory/data.py +47 -57
  107. ansible/inventory/group.py +44 -72
  108. ansible/inventory/helpers.py +9 -0
  109. ansible/inventory/host.py +32 -54
  110. ansible/inventory/manager.py +77 -34
  111. ansible/keyword_desc.yml +1 -1
  112. ansible/module_utils/_internal/__init__.py +55 -0
  113. ansible/module_utils/_internal/_ambient_context.py +58 -0
  114. ansible/module_utils/_internal/_ansiballz.py +133 -0
  115. ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
  116. ansible/module_utils/_internal/_dataclass_annotation_patch.py +64 -0
  117. ansible/module_utils/_internal/_dataclass_validation.py +217 -0
  118. ansible/module_utils/_internal/_datatag/__init__.py +928 -0
  119. ansible/module_utils/_internal/_datatag/_tags.py +38 -0
  120. ansible/module_utils/_internal/_debugging.py +31 -0
  121. ansible/module_utils/_internal/_errors.py +30 -0
  122. ansible/module_utils/_internal/_json/__init__.py +63 -0
  123. ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
  124. ansible/module_utils/_internal/_json/_profiles/__init__.py +410 -0
  125. ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
  126. ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +31 -0
  127. ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +35 -0
  128. ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
  129. ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
  130. ansible/module_utils/_internal/_json/_profiles/_tagless.py +50 -0
  131. ansible/module_utils/_internal/_patches/__init__.py +66 -0
  132. ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +55 -0
  133. ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
  134. ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
  135. ansible/module_utils/_internal/_plugin_exec_context.py +49 -0
  136. ansible/module_utils/_internal/_testing.py +0 -0
  137. ansible/module_utils/_internal/_traceback.py +89 -0
  138. ansible/module_utils/ansible_release.py +2 -2
  139. ansible/module_utils/api.py +1 -2
  140. ansible/module_utils/basic.py +154 -120
  141. ansible/module_utils/common/_utils.py +24 -28
  142. ansible/module_utils/common/collections.py +1 -2
  143. ansible/module_utils/common/dict_transformations.py +2 -2
  144. ansible/module_utils/common/file.py +2 -2
  145. ansible/module_utils/common/json.py +90 -84
  146. ansible/module_utils/common/locale.py +2 -2
  147. ansible/module_utils/common/messages.py +108 -0
  148. ansible/module_utils/common/parameters.py +27 -24
  149. ansible/module_utils/common/process.py +2 -2
  150. ansible/module_utils/common/respawn.py +41 -19
  151. ansible/module_utils/common/sentinel.py +66 -0
  152. ansible/module_utils/common/sys_info.py +8 -8
  153. ansible/module_utils/common/text/converters.py +16 -37
  154. ansible/module_utils/common/validation.py +35 -24
  155. ansible/module_utils/common/warnings.py +86 -25
  156. ansible/module_utils/common/yaml.py +29 -3
  157. ansible/module_utils/compat/datetime.py +33 -21
  158. ansible/module_utils/compat/paramiko.py +21 -10
  159. ansible/module_utils/compat/typing.py +6 -5
  160. ansible/module_utils/connection.py +2 -2
  161. ansible/module_utils/csharp/Ansible.Basic.cs +14 -11
  162. ansible/module_utils/csharp/Ansible.Become.cs +1 -0
  163. ansible/module_utils/csharp/Ansible._Async.cs +517 -0
  164. ansible/module_utils/datatag.py +46 -0
  165. ansible/module_utils/distro/__init__.py +2 -2
  166. ansible/module_utils/facts/ansible_collector.py +4 -5
  167. ansible/module_utils/facts/collector.py +13 -14
  168. ansible/module_utils/facts/compat.py +4 -4
  169. ansible/module_utils/facts/default_collectors.py +1 -1
  170. ansible/module_utils/facts/hardware/aix.py +34 -0
  171. ansible/module_utils/facts/hardware/base.py +1 -1
  172. ansible/module_utils/facts/hardware/darwin.py +1 -3
  173. ansible/module_utils/facts/hardware/freebsd.py +2 -2
  174. ansible/module_utils/facts/hardware/linux.py +4 -4
  175. ansible/module_utils/facts/namespace.py +1 -1
  176. ansible/module_utils/facts/network/base.py +1 -1
  177. ansible/module_utils/facts/network/fc_wwn.py +1 -2
  178. ansible/module_utils/facts/network/iscsi.py +1 -2
  179. ansible/module_utils/facts/network/nvme.py +1 -2
  180. ansible/module_utils/facts/other/facter.py +1 -2
  181. ansible/module_utils/facts/other/ohai.py +2 -3
  182. ansible/module_utils/facts/system/apparmor.py +1 -2
  183. ansible/module_utils/facts/system/caps.py +1 -1
  184. ansible/module_utils/facts/system/chroot.py +1 -2
  185. ansible/module_utils/facts/system/cmdline.py +1 -2
  186. ansible/module_utils/facts/system/date_time.py +5 -3
  187. ansible/module_utils/facts/system/distribution.py +9 -8
  188. ansible/module_utils/facts/system/dns.py +1 -1
  189. ansible/module_utils/facts/system/env.py +1 -2
  190. ansible/module_utils/facts/system/fips.py +7 -20
  191. ansible/module_utils/facts/system/loadavg.py +1 -2
  192. ansible/module_utils/facts/system/local.py +1 -2
  193. ansible/module_utils/facts/system/lsb.py +1 -2
  194. ansible/module_utils/facts/system/pkg_mgr.py +1 -2
  195. ansible/module_utils/facts/system/platform.py +1 -2
  196. ansible/module_utils/facts/system/python.py +1 -2
  197. ansible/module_utils/facts/system/selinux.py +1 -1
  198. ansible/module_utils/facts/system/service_mgr.py +1 -2
  199. ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
  200. ansible/module_utils/facts/system/systemd.py +1 -1
  201. ansible/module_utils/facts/system/user.py +1 -2
  202. ansible/module_utils/facts/utils.py +3 -3
  203. ansible/module_utils/facts/virtual/base.py +1 -1
  204. ansible/module_utils/facts/virtual/sunos.py +3 -15
  205. ansible/module_utils/facts/virtual/sysctl.py +3 -16
  206. ansible/module_utils/json_utils.py +2 -2
  207. ansible/module_utils/parsing/convert_bool.py +1 -1
  208. ansible/module_utils/service.py +18 -21
  209. ansible/module_utils/splitter.py +7 -7
  210. ansible/module_utils/testing.py +31 -0
  211. ansible/module_utils/urls.py +60 -31
  212. ansible/modules/add_host.py +4 -4
  213. ansible/modules/apt.py +60 -46
  214. ansible/modules/apt_key.py +19 -12
  215. ansible/modules/apt_repository.py +19 -16
  216. ansible/modules/assemble.py +6 -6
  217. ansible/modules/assert.py +4 -4
  218. ansible/modules/async_status.py +10 -12
  219. ansible/modules/async_wrapper.py +8 -3
  220. ansible/modules/blockinfile.py +6 -7
  221. ansible/modules/command.py +10 -17
  222. ansible/modules/copy.py +57 -144
  223. ansible/modules/cron.py +20 -15
  224. ansible/modules/deb822_repository.py +8 -9
  225. ansible/modules/debconf.py +5 -5
  226. ansible/modules/debug.py +4 -4
  227. ansible/modules/dnf.py +8 -8
  228. ansible/modules/dnf5.py +52 -17
  229. ansible/modules/dpkg_selections.py +4 -4
  230. ansible/modules/expect.py +8 -10
  231. ansible/modules/fail.py +4 -4
  232. ansible/modules/fetch.py +4 -4
  233. ansible/modules/file.py +174 -133
  234. ansible/modules/find.py +20 -18
  235. ansible/modules/gather_facts.py +3 -3
  236. ansible/modules/get_url.py +59 -53
  237. ansible/modules/getent.py +7 -9
  238. ansible/modules/git.py +28 -25
  239. ansible/modules/group.py +6 -6
  240. ansible/modules/group_by.py +4 -4
  241. ansible/modules/hostname.py +13 -29
  242. ansible/modules/import_playbook.py +6 -6
  243. ansible/modules/import_role.py +7 -7
  244. ansible/modules/import_tasks.py +6 -6
  245. ansible/modules/include_role.py +6 -6
  246. ansible/modules/include_tasks.py +6 -6
  247. ansible/modules/include_vars.py +6 -6
  248. ansible/modules/iptables.py +86 -73
  249. ansible/modules/known_hosts.py +10 -10
  250. ansible/modules/lineinfile.py +5 -5
  251. ansible/modules/meta.py +4 -4
  252. ansible/modules/mount_facts.py +2 -2
  253. ansible/modules/package.py +4 -4
  254. ansible/modules/package_facts.py +22 -10
  255. ansible/modules/pause.py +6 -6
  256. ansible/modules/ping.py +6 -6
  257. ansible/modules/pip.py +10 -11
  258. ansible/modules/raw.py +4 -4
  259. ansible/modules/reboot.py +6 -6
  260. ansible/modules/replace.py +9 -13
  261. ansible/modules/rpm_key.py +7 -8
  262. ansible/modules/script.py +4 -4
  263. ansible/modules/service.py +7 -8
  264. ansible/modules/service_facts.py +87 -10
  265. ansible/modules/set_fact.py +5 -5
  266. ansible/modules/set_stats.py +4 -4
  267. ansible/modules/setup.py +2 -2
  268. ansible/modules/shell.py +6 -6
  269. ansible/modules/slurp.py +6 -6
  270. ansible/modules/stat.py +9 -23
  271. ansible/modules/subversion.py +15 -15
  272. ansible/modules/systemd.py +6 -6
  273. ansible/modules/systemd_service.py +6 -6
  274. ansible/modules/sysvinit.py +6 -6
  275. ansible/modules/tempfile.py +5 -6
  276. ansible/modules/template.py +6 -6
  277. ansible/modules/unarchive.py +32 -11
  278. ansible/modules/uri.py +35 -49
  279. ansible/modules/user.py +53 -34
  280. ansible/modules/validate_argument_spec.py +10 -7
  281. ansible/modules/wait_for.py +39 -32
  282. ansible/modules/wait_for_connection.py +6 -6
  283. ansible/modules/yum_repository.py +6 -6
  284. ansible/parsing/ajson.py +14 -32
  285. ansible/parsing/dataloader.py +99 -54
  286. ansible/parsing/mod_args.py +28 -44
  287. ansible/parsing/plugin_docs.py +21 -86
  288. ansible/parsing/quoting.py +1 -1
  289. ansible/parsing/splitter.py +27 -12
  290. ansible/parsing/utils/addresses.py +24 -24
  291. ansible/parsing/utils/yaml.py +32 -61
  292. ansible/parsing/vault/__init__.py +319 -87
  293. ansible/parsing/yaml/__init__.py +0 -18
  294. ansible/parsing/yaml/dumper.py +6 -120
  295. ansible/parsing/yaml/loader.py +6 -39
  296. ansible/parsing/yaml/objects.py +36 -339
  297. ansible/playbook/__init__.py +1 -1
  298. ansible/playbook/attribute.py +8 -3
  299. ansible/playbook/base.py +182 -132
  300. ansible/playbook/block.py +26 -24
  301. ansible/playbook/collectionsearch.py +1 -15
  302. ansible/playbook/conditional.py +3 -77
  303. ansible/playbook/handler.py +8 -2
  304. ansible/playbook/helpers.py +41 -53
  305. ansible/playbook/included_file.py +6 -15
  306. ansible/playbook/loop_control.py +2 -2
  307. ansible/playbook/play.py +85 -44
  308. ansible/playbook/play_context.py +12 -17
  309. ansible/playbook/playbook_include.py +14 -15
  310. ansible/playbook/role/__init__.py +24 -26
  311. ansible/playbook/role/definition.py +15 -17
  312. ansible/playbook/role/include.py +2 -4
  313. ansible/playbook/role/metadata.py +10 -11
  314. ansible/playbook/role_include.py +3 -3
  315. ansible/playbook/taggable.py +13 -8
  316. ansible/playbook/task.py +188 -118
  317. ansible/playbook/task_include.py +5 -5
  318. ansible/plugins/__init__.py +68 -21
  319. ansible/plugins/action/__init__.py +209 -176
  320. ansible/plugins/action/add_host.py +1 -1
  321. ansible/plugins/action/assemble.py +1 -1
  322. ansible/plugins/action/assert.py +54 -66
  323. ansible/plugins/action/copy.py +7 -11
  324. ansible/plugins/action/debug.py +37 -31
  325. ansible/plugins/action/dnf.py +3 -4
  326. ansible/plugins/action/fail.py +1 -1
  327. ansible/plugins/action/fetch.py +4 -5
  328. ansible/plugins/action/gather_facts.py +8 -7
  329. ansible/plugins/action/group_by.py +1 -1
  330. ansible/plugins/action/include_vars.py +10 -11
  331. ansible/plugins/action/package.py +3 -6
  332. ansible/plugins/action/pause.py +2 -2
  333. ansible/plugins/action/script.py +15 -8
  334. ansible/plugins/action/service.py +6 -11
  335. ansible/plugins/action/set_fact.py +3 -12
  336. ansible/plugins/action/set_stats.py +3 -8
  337. ansible/plugins/action/template.py +35 -59
  338. ansible/plugins/action/unarchive.py +1 -1
  339. ansible/plugins/action/validate_argument_spec.py +5 -5
  340. ansible/plugins/action/wait_for_connection.py +1 -1
  341. ansible/plugins/become/__init__.py +31 -8
  342. ansible/plugins/become/runas.py +71 -0
  343. ansible/plugins/become/su.py +13 -8
  344. ansible/plugins/become/sudo.py +19 -0
  345. ansible/plugins/cache/__init__.py +35 -44
  346. ansible/plugins/cache/base.py +8 -0
  347. ansible/plugins/cache/jsonfile.py +10 -16
  348. ansible/plugins/cache/memory.py +6 -12
  349. ansible/plugins/callback/__init__.py +141 -123
  350. ansible/plugins/callback/default.py +30 -23
  351. ansible/plugins/callback/junit.py +28 -24
  352. ansible/plugins/callback/minimal.py +17 -14
  353. ansible/plugins/callback/oneline.py +13 -7
  354. ansible/plugins/callback/tree.py +10 -6
  355. ansible/plugins/connection/__init__.py +47 -34
  356. ansible/plugins/connection/local.py +150 -54
  357. ansible/plugins/connection/paramiko_ssh.py +21 -18
  358. ansible/plugins/connection/psrp.py +76 -165
  359. ansible/plugins/connection/ssh.py +301 -78
  360. ansible/plugins/connection/winrm.py +58 -140
  361. ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
  362. ansible/plugins/doc_fragments/action_core.py +6 -6
  363. ansible/plugins/doc_fragments/backup.py +2 -2
  364. ansible/plugins/doc_fragments/checksum_common.py +27 -0
  365. ansible/plugins/doc_fragments/constructed.py +6 -2
  366. ansible/plugins/doc_fragments/decrypt.py +2 -2
  367. ansible/plugins/doc_fragments/default_callback.py +2 -2
  368. ansible/plugins/doc_fragments/files.py +2 -2
  369. ansible/plugins/doc_fragments/inventory_cache.py +2 -2
  370. ansible/plugins/doc_fragments/result_format_callback.py +2 -2
  371. ansible/plugins/doc_fragments/return_common.py +2 -2
  372. ansible/plugins/doc_fragments/template_common.py +4 -4
  373. ansible/plugins/doc_fragments/url.py +17 -1
  374. ansible/plugins/doc_fragments/url_windows.py +2 -2
  375. ansible/plugins/doc_fragments/validate.py +2 -2
  376. ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
  377. ansible/plugins/filter/__init__.py +6 -2
  378. ansible/plugins/filter/b64decode.yml +22 -0
  379. ansible/plugins/filter/b64encode.yml +22 -0
  380. ansible/plugins/filter/bool.yml +11 -4
  381. ansible/plugins/filter/core.py +218 -108
  382. ansible/plugins/filter/encryption.py +32 -32
  383. ansible/plugins/filter/flatten.yml +3 -2
  384. ansible/plugins/filter/human_to_bytes.yml +2 -2
  385. ansible/plugins/filter/mathstuff.py +30 -37
  386. ansible/plugins/filter/password_hash.yml +8 -0
  387. ansible/plugins/filter/regex_search.yml +1 -4
  388. ansible/plugins/filter/split.yml +1 -1
  389. ansible/plugins/filter/to_nice_yaml.yml +0 -4
  390. ansible/plugins/filter/to_yaml.yml +0 -4
  391. ansible/plugins/filter/unvault.yml +1 -1
  392. ansible/plugins/filter/urls.py +1 -1
  393. ansible/plugins/filter/urlsplit.py +8 -9
  394. ansible/plugins/filter/vault.yml +14 -9
  395. ansible/plugins/filter/win_basename.yml +6 -1
  396. ansible/plugins/filter/win_dirname.yml +5 -0
  397. ansible/plugins/inventory/__init__.py +97 -77
  398. ansible/plugins/inventory/advanced_host_list.py +7 -5
  399. ansible/plugins/inventory/auto.py +11 -4
  400. ansible/plugins/inventory/constructed.py +21 -24
  401. ansible/plugins/inventory/generator.py +16 -11
  402. ansible/plugins/inventory/host_list.py +7 -5
  403. ansible/plugins/inventory/ini.py +78 -44
  404. ansible/plugins/inventory/script.py +189 -119
  405. ansible/plugins/inventory/toml.py +16 -126
  406. ansible/plugins/inventory/yaml.py +10 -8
  407. ansible/plugins/list.py +3 -3
  408. ansible/plugins/loader.py +197 -82
  409. ansible/plugins/lookup/__init__.py +21 -4
  410. ansible/plugins/lookup/config.py +21 -35
  411. ansible/plugins/lookup/csvfile.py +3 -2
  412. ansible/plugins/lookup/dict.py +1 -6
  413. ansible/plugins/lookup/env.py +12 -9
  414. ansible/plugins/lookup/file.py +5 -8
  415. ansible/plugins/lookup/first_found.py +86 -55
  416. ansible/plugins/lookup/indexed_items.py +1 -10
  417. ansible/plugins/lookup/ini.py +14 -13
  418. ansible/plugins/lookup/items.py +1 -1
  419. ansible/plugins/lookup/lines.py +8 -1
  420. ansible/plugins/lookup/list.py +1 -1
  421. ansible/plugins/lookup/nested.py +2 -18
  422. ansible/plugins/lookup/password.py +5 -5
  423. ansible/plugins/lookup/pipe.py +5 -7
  424. ansible/plugins/lookup/sequence.py +18 -8
  425. ansible/plugins/lookup/subelements.py +1 -4
  426. ansible/plugins/lookup/template.py +42 -36
  427. ansible/plugins/lookup/together.py +0 -12
  428. ansible/plugins/lookup/unvault.py +1 -5
  429. ansible/plugins/lookup/url.py +2 -8
  430. ansible/plugins/lookup/vars.py +16 -24
  431. ansible/plugins/shell/__init__.py +2 -2
  432. ansible/plugins/shell/cmd.py +2 -2
  433. ansible/plugins/shell/powershell.py +39 -22
  434. ansible/plugins/shell/sh.py +3 -2
  435. ansible/plugins/strategy/__init__.py +94 -113
  436. ansible/plugins/strategy/debug.py +2 -2
  437. ansible/plugins/strategy/free.py +13 -28
  438. ansible/plugins/strategy/host_pinned.py +2 -2
  439. ansible/plugins/strategy/linear.py +31 -33
  440. ansible/plugins/terminal/__init__.py +4 -4
  441. ansible/plugins/test/__init__.py +7 -2
  442. ansible/plugins/test/core.py +54 -20
  443. ansible/plugins/test/files.py +1 -1
  444. ansible/plugins/test/mathstuff.py +3 -3
  445. ansible/plugins/test/uri.py +3 -3
  446. ansible/plugins/vars/host_group_vars.py +7 -14
  447. ansible/release.py +2 -2
  448. ansible/template/__init__.py +368 -944
  449. ansible/utils/__init__.py +0 -18
  450. ansible/utils/_ssh_agent.py +657 -0
  451. ansible/utils/collection_loader/__init__.py +52 -5
  452. ansible/utils/collection_loader/_collection_config.py +5 -6
  453. ansible/utils/collection_loader/_collection_finder.py +79 -93
  454. ansible/utils/collection_loader/_collection_meta.py +13 -8
  455. ansible/utils/display.py +428 -58
  456. ansible/utils/encrypt.py +27 -19
  457. ansible/utils/fqcn.py +2 -2
  458. ansible/utils/hashing.py +2 -2
  459. ansible/utils/helpers.py +2 -2
  460. ansible/utils/listify.py +8 -8
  461. ansible/utils/lock.py +2 -2
  462. ansible/utils/path.py +4 -4
  463. ansible/utils/plugin_docs.py +14 -13
  464. ansible/utils/sentinel.py +4 -62
  465. ansible/utils/singleton.py +2 -0
  466. ansible/utils/ssh_functions.py +1 -1
  467. ansible/utils/unsafe_proxy.py +23 -332
  468. ansible/utils/vars.py +28 -8
  469. ansible/utils/version.py +2 -2
  470. ansible/vars/clean.py +4 -4
  471. ansible/vars/hostvars.py +60 -90
  472. ansible/vars/manager.py +205 -264
  473. ansible/vars/reserved.py +8 -9
  474. ansible_core-2.19.0b1.dist-info/BSD-3-Clause.txt +28 -0
  475. {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/METADATA +5 -4
  476. ansible_core-2.19.0b1.dist-info/RECORD +1070 -0
  477. {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/WHEEL +1 -1
  478. ansible_test/_data/completion/docker.txt +7 -7
  479. ansible_test/_data/completion/remote.txt +6 -6
  480. ansible_test/_data/completion/windows.txt +1 -0
  481. ansible_test/_data/requirements/ansible.txt +2 -2
  482. ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
  483. ansible_test/_data/requirements/sanity.changelog.txt +1 -1
  484. ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
  485. ansible_test/_data/requirements/sanity.pylint.txt +4 -4
  486. ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
  487. ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
  488. ansible_test/_data/requirements/units.txt +1 -0
  489. ansible_test/_internal/__init__.py +1 -0
  490. ansible_test/_internal/ansible_util.py +2 -0
  491. ansible_test/_internal/become.py +1 -0
  492. ansible_test/_internal/bootstrap.py +1 -0
  493. ansible_test/_internal/cache.py +1 -0
  494. ansible_test/_internal/cgroup.py +1 -0
  495. ansible_test/_internal/ci/__init__.py +1 -0
  496. ansible_test/_internal/ci/azp.py +1 -0
  497. ansible_test/_internal/ci/local.py +1 -0
  498. ansible_test/_internal/classification/__init__.py +1 -0
  499. ansible_test/_internal/classification/common.py +1 -0
  500. ansible_test/_internal/classification/csharp.py +1 -0
  501. ansible_test/_internal/classification/powershell.py +1 -0
  502. ansible_test/_internal/classification/python.py +1 -0
  503. ansible_test/_internal/cli/__init__.py +1 -0
  504. ansible_test/_internal/cli/actions.py +1 -0
  505. ansible_test/_internal/cli/argparsing/__init__.py +1 -0
  506. ansible_test/_internal/cli/argparsing/actions.py +1 -0
  507. ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
  508. ansible_test/_internal/cli/argparsing/parsers.py +1 -0
  509. ansible_test/_internal/cli/commands/__init__.py +11 -0
  510. ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
  511. ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
  512. ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
  513. ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
  514. ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
  515. ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
  516. ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
  517. ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
  518. ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
  519. ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
  520. ansible_test/_internal/cli/commands/coverage/html.py +1 -0
  521. ansible_test/_internal/cli/commands/coverage/report.py +1 -0
  522. ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
  523. ansible_test/_internal/cli/commands/env.py +1 -0
  524. ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
  525. ansible_test/_internal/cli/commands/integration/network.py +1 -0
  526. ansible_test/_internal/cli/commands/integration/posix.py +1 -0
  527. ansible_test/_internal/cli/commands/integration/windows.py +1 -0
  528. ansible_test/_internal/cli/commands/sanity.py +9 -0
  529. ansible_test/_internal/cli/commands/shell.py +1 -0
  530. ansible_test/_internal/cli/commands/units.py +1 -0
  531. ansible_test/_internal/cli/compat.py +1 -0
  532. ansible_test/_internal/cli/completers.py +1 -0
  533. ansible_test/_internal/cli/converters.py +1 -0
  534. ansible_test/_internal/cli/environments.py +1 -0
  535. ansible_test/_internal/cli/epilog.py +1 -0
  536. ansible_test/_internal/cli/parsers/__init__.py +1 -0
  537. ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
  538. ansible_test/_internal/cli/parsers/helpers.py +1 -0
  539. ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
  540. ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
  541. ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
  542. ansible_test/_internal/commands/__init__.py +1 -0
  543. ansible_test/_internal/commands/coverage/__init__.py +2 -1
  544. ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
  545. ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
  546. ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
  547. ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
  548. ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
  549. ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
  550. ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
  551. ansible_test/_internal/commands/coverage/combine.py +2 -1
  552. ansible_test/_internal/commands/coverage/erase.py +1 -0
  553. ansible_test/_internal/commands/coverage/html.py +1 -0
  554. ansible_test/_internal/commands/coverage/report.py +1 -0
  555. ansible_test/_internal/commands/coverage/xml.py +1 -0
  556. ansible_test/_internal/commands/env/__init__.py +2 -0
  557. ansible_test/_internal/commands/integration/__init__.py +4 -0
  558. ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
  559. ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
  560. ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
  561. ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
  562. ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
  563. ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
  564. ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
  565. ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
  566. ansible_test/_internal/commands/integration/cloud/httptester.py +2 -1
  567. ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
  568. ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
  569. ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
  570. ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
  571. ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
  572. ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
  573. ansible_test/_internal/commands/integration/coverage.py +1 -0
  574. ansible_test/_internal/commands/integration/filters.py +1 -0
  575. ansible_test/_internal/commands/integration/network.py +1 -0
  576. ansible_test/_internal/commands/integration/posix.py +1 -0
  577. ansible_test/_internal/commands/integration/windows.py +1 -0
  578. ansible_test/_internal/commands/sanity/__init__.py +16 -1
  579. ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
  580. ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
  581. ansible_test/_internal/commands/sanity/compile.py +1 -0
  582. ansible_test/_internal/commands/sanity/ignores.py +1 -0
  583. ansible_test/_internal/commands/sanity/import.py +1 -0
  584. ansible_test/_internal/commands/sanity/integration_aliases.py +1 -0
  585. ansible_test/_internal/commands/sanity/pep8.py +1 -0
  586. ansible_test/_internal/commands/sanity/pslint.py +1 -0
  587. ansible_test/_internal/commands/sanity/pylint.py +24 -26
  588. ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
  589. ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
  590. ansible_test/_internal/commands/sanity/yamllint.py +1 -0
  591. ansible_test/_internal/commands/shell/__init__.py +1 -0
  592. ansible_test/_internal/commands/units/__init__.py +1 -0
  593. ansible_test/_internal/compat/__init__.py +1 -0
  594. ansible_test/_internal/compat/packaging.py +1 -0
  595. ansible_test/_internal/compat/yaml.py +1 -0
  596. ansible_test/_internal/completion.py +1 -0
  597. ansible_test/_internal/config.py +2 -0
  598. ansible_test/_internal/connections.py +1 -0
  599. ansible_test/_internal/constants.py +1 -0
  600. ansible_test/_internal/containers.py +1 -0
  601. ansible_test/_internal/content_config.py +1 -0
  602. ansible_test/_internal/core_ci.py +1 -0
  603. ansible_test/_internal/coverage_util.py +11 -10
  604. ansible_test/_internal/data.py +1 -0
  605. ansible_test/_internal/delegation.py +1 -0
  606. ansible_test/_internal/dev/__init__.py +1 -0
  607. ansible_test/_internal/dev/container_probe.py +1 -0
  608. ansible_test/_internal/diff.py +3 -2
  609. ansible_test/_internal/docker_util.py +2 -1
  610. ansible_test/_internal/encoding.py +1 -0
  611. ansible_test/_internal/executor.py +1 -0
  612. ansible_test/_internal/git.py +1 -0
  613. ansible_test/_internal/host_configs.py +1 -0
  614. ansible_test/_internal/host_profiles.py +1 -0
  615. ansible_test/_internal/http.py +1 -0
  616. ansible_test/_internal/init.py +1 -0
  617. ansible_test/_internal/inventory.py +35 -3
  618. ansible_test/_internal/io.py +1 -0
  619. ansible_test/_internal/metadata.py +1 -0
  620. ansible_test/_internal/payload.py +1 -0
  621. ansible_test/_internal/provider/__init__.py +1 -0
  622. ansible_test/_internal/provider/layout/__init__.py +1 -0
  623. ansible_test/_internal/provider/layout/ansible.py +1 -0
  624. ansible_test/_internal/provider/layout/collection.py +1 -0
  625. ansible_test/_internal/provider/layout/unsupported.py +1 -0
  626. ansible_test/_internal/provider/source/__init__.py +1 -0
  627. ansible_test/_internal/provider/source/git.py +1 -0
  628. ansible_test/_internal/provider/source/installed.py +1 -0
  629. ansible_test/_internal/provider/source/unsupported.py +1 -0
  630. ansible_test/_internal/provider/source/unversioned.py +1 -0
  631. ansible_test/_internal/provisioning.py +1 -0
  632. ansible_test/_internal/pypi_proxy.py +6 -5
  633. ansible_test/_internal/python_requirements.py +1 -0
  634. ansible_test/_internal/ssh.py +1 -0
  635. ansible_test/_internal/target.py +1 -0
  636. ansible_test/_internal/test.py +3 -2
  637. ansible_test/_internal/thread.py +1 -0
  638. ansible_test/_internal/timeout.py +1 -0
  639. ansible_test/_internal/util.py +1 -0
  640. ansible_test/_internal/util_common.py +5 -2
  641. ansible_test/_internal/venv.py +1 -0
  642. ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
  643. ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
  644. ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
  645. ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
  646. ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
  647. ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
  648. ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
  649. ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
  650. ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
  651. ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
  652. ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
  653. ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
  654. ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
  655. ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
  656. ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
  657. ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
  658. ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
  659. ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +7 -5
  660. ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +7 -5
  661. ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +7 -5
  662. ansible_test/_util/controller/sanity/pylint/config/collection.cfg +3 -5
  663. ansible_test/_util/controller/sanity/pylint/config/default.cfg +7 -7
  664. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -13
  665. ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
  666. ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
  667. ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
  668. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
  669. ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
  670. ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
  671. ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
  672. ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
  673. ansible_test/_util/controller/tools/collection_detail.py +1 -0
  674. ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
  675. ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
  676. ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
  677. ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
  678. ansible_test/_util/target/sanity/compile/compile.py +1 -0
  679. ansible_test/_util/target/sanity/import/importer.py +15 -16
  680. ansible_test/_util/target/setup/bootstrap.sh +9 -20
  681. ansible_test/_util/target/setup/probe_cgroups.py +1 -0
  682. ansible_test/_util/target/setup/quiet_pip.py +1 -0
  683. ansible_test/_util/target/setup/requirements.py +35 -27
  684. ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
  685. ansible_test/_util/target/tools/yamlcheck.py +2 -1
  686. ansible/compat/selectors.py +0 -32
  687. ansible/errors/yaml_strings.py +0 -138
  688. ansible/executor/action_write_locks.py +0 -44
  689. ansible/executor/discovery/python_target.py +0 -47
  690. ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
  691. ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
  692. ansible/module_utils/compat/importlib.py +0 -26
  693. ansible/module_utils/compat/selectors.py +0 -32
  694. ansible/module_utils/pycompat24.py +0 -73
  695. ansible/parsing/utils/jsonify.py +0 -36
  696. ansible/parsing/yaml/constructor.py +0 -178
  697. ansible/template/native_helpers.py +0 -251
  698. ansible/template/template.py +0 -43
  699. ansible/template/vars.py +0 -77
  700. ansible/utils/native_jinja.py +0 -11
  701. ansible/vars/fact_cache.py +0 -71
  702. ansible_core-2.18.4rc1.dist-info/RECORD +0 -992
  703. {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/Apache-License.txt +0 -0
  704. {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/COPYING +0 -0
  705. {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/MIT-license.txt +0 -0
  706. {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/PSF-license.txt +0 -0
  707. {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/entry_points.txt +0 -0
  708. {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/simplified_bsd.txt +0 -0
  709. {ansible_core-2.18.4rc1.dist-info → ansible_core-2.19.0b1.dist-info}/top_level.txt +0 -0
@@ -18,27 +18,28 @@
18
18
  from __future__ import annotations
19
19
 
20
20
  import difflib
21
+ import functools
21
22
  import json
22
23
  import re
23
24
  import sys
24
25
  import textwrap
26
+ import typing as t
27
+
25
28
  from typing import TYPE_CHECKING
26
29
 
27
- from collections import OrderedDict
28
30
  from collections.abc import MutableMapping
29
31
  from copy import deepcopy
30
32
 
31
33
  from ansible import constants as C
32
- from ansible.module_utils.common.text.converters import to_text
33
- from ansible.module_utils.six import text_type
34
- from ansible.parsing.ajson import AnsibleJSONEncoder
35
- from ansible.parsing.yaml.dumper import AnsibleDumper
36
- from ansible.parsing.yaml.objects import AnsibleUnicode
34
+ from ansible.module_utils._internal import _datatag
35
+ from ansible.module_utils.common.messages import ErrorSummary
36
+ from ansible._internal._yaml import _dumper
37
37
  from ansible.plugins import AnsiblePlugin
38
38
  from ansible.utils.color import stringc
39
39
  from ansible.utils.display import Display
40
- from ansible.utils.unsafe_proxy import AnsibleUnsafeText, NativeJinjaUnsafeText, _is_unsafe
41
40
  from ansible.vars.clean import strip_internal_keys, module_response_deepcopy
41
+ from ansible.module_utils._internal._json._profiles import _fallback_to_str
42
+ from ansible._internal._templating import _engine
42
43
 
43
44
  import yaml
44
45
 
@@ -52,23 +53,41 @@ __all__ = ["CallbackBase"]
52
53
 
53
54
 
54
55
  _DEBUG_ALLOWED_KEYS = frozenset(('msg', 'exception', 'warnings', 'deprecations'))
55
- _YAML_TEXT_TYPES = (text_type, AnsibleUnicode, AnsibleUnsafeText, NativeJinjaUnsafeText)
56
56
  # Characters that libyaml/pyyaml consider breaks
57
57
  _YAML_BREAK_CHARS = '\n\x85\u2028\u2029' # NL, NEL, LS, PS
58
58
  # regex representation of libyaml/pyyaml of a space followed by a break character
59
59
  _SPACE_BREAK_RE = re.compile(fr' +([{_YAML_BREAK_CHARS}])')
60
60
 
61
61
 
62
- class _AnsibleCallbackDumper(AnsibleDumper):
63
- def __init__(self, lossy=False):
62
+ class _AnsibleCallbackDumper(_dumper.AnsibleDumper):
63
+ def __init__(self, *args, lossy: bool = False, **kwargs):
64
+ super().__init__(*args, **kwargs)
65
+
64
66
  self._lossy = lossy
65
67
 
66
- def __call__(self, *args, **kwargs):
67
- # pyyaml expects that we are passing an object that can be instantiated, but to
68
- # smuggle the ``lossy`` configuration, we do that in ``__init__`` and then
69
- # define this ``__call__`` that will mimic the ability for pyyaml to instantiate class
70
- super().__init__(*args, **kwargs)
71
- return self
68
+ def _pretty_represent_str(self, data):
69
+ """Uses block style for multi-line strings"""
70
+ data = _datatag.AnsibleTagHelper.as_native_type(data)
71
+
72
+ if _should_use_block(data):
73
+ style = '|'
74
+ if self._lossy:
75
+ data = _munge_data_for_lossy_yaml(data)
76
+ else:
77
+ style = self.default_style
78
+
79
+ node = yaml.representer.ScalarNode('tag:yaml.org,2002:str', data, style=style)
80
+
81
+ if self.alias_key is not None:
82
+ self.represented_objects[self.alias_key] = node
83
+
84
+ return node
85
+
86
+ @classmethod
87
+ def _register_representers(cls) -> None:
88
+ super()._register_representers()
89
+
90
+ cls.add_multi_representer(str, cls._pretty_represent_str)
72
91
 
73
92
 
74
93
  def _should_use_block(scalar):
@@ -77,6 +96,7 @@ def _should_use_block(scalar):
77
96
  for ch in _YAML_BREAK_CHARS:
78
97
  if ch in scalar:
79
98
  return True
99
+
80
100
  return False
81
101
 
82
102
 
@@ -95,12 +115,12 @@ class _SpecialCharacterTranslator:
95
115
  return None
96
116
 
97
117
 
98
- def _filter_yaml_special(scalar):
118
+ def _filter_yaml_special(scalar: str) -> str:
99
119
  """Filter a string removing any character that libyaml/pyyaml declare as special"""
100
120
  return scalar.translate(_SpecialCharacterTranslator())
101
121
 
102
122
 
103
- def _munge_data_for_lossy_yaml(scalar):
123
+ def _munge_data_for_lossy_yaml(scalar: str) -> str:
104
124
  """Modify a string so that analyze_scalar in libyaml/pyyaml will allow block formatting"""
105
125
  # we care more about readability than accuracy, so...
106
126
  # ...libyaml/pyyaml does not permit trailing spaces for block scalars
@@ -113,38 +133,12 @@ def _munge_data_for_lossy_yaml(scalar):
113
133
  return _SPACE_BREAK_RE.sub(r'\1', scalar)
114
134
 
115
135
 
116
- def _pretty_represent_str(self, data):
117
- """Uses block style for multi-line strings"""
118
- if _is_unsafe(data):
119
- data = data._strip_unsafe()
120
- data = text_type(data)
121
- if _should_use_block(data):
122
- style = '|'
123
- if self._lossy:
124
- data = _munge_data_for_lossy_yaml(data)
125
- else:
126
- style = self.default_style
127
-
128
- node = yaml.representer.ScalarNode('tag:yaml.org,2002:str', data, style=style)
129
- if self.alias_key is not None:
130
- self.represented_objects[self.alias_key] = node
131
- return node
132
-
133
-
134
- for data_type in _YAML_TEXT_TYPES:
135
- _AnsibleCallbackDumper.add_representer(
136
- data_type,
137
- _pretty_represent_str
138
- )
139
-
140
-
141
136
  class CallbackBase(AnsiblePlugin):
142
-
143
- '''
137
+ """
144
138
  This is a base ansible callback class that does nothing. New callbacks should
145
139
  use this class as a base and override any callback methods they wish to execute
146
140
  custom actions.
147
- '''
141
+ """
148
142
 
149
143
  def __init__(self, display=None, options=None):
150
144
  if display:
@@ -165,7 +159,10 @@ class CallbackBase(AnsiblePlugin):
165
159
  if options is not None:
166
160
  self.set_options(options)
167
161
 
168
- self._hide_in_debug = ('changed', 'failed', 'skipped', 'invocation', 'skip_reason')
162
+ self._hide_in_debug = (
163
+ 'changed', 'failed', 'skipped', 'invocation', 'skip_reason',
164
+ 'ansible_loop_var', 'ansible_index_var', 'ansible_loop',
165
+ )
169
166
 
170
167
  # helper for callbacks, so they don't all have to include deepcopy
171
168
  _copy_result = deepcopy
@@ -173,13 +170,16 @@ class CallbackBase(AnsiblePlugin):
173
170
  def set_option(self, k, v):
174
171
  self._plugin_options[k] = C.config.get_config_value(k, plugin_type=self.plugin_type, plugin_name=self._load_name, direct={k: v})
175
172
 
176
- def get_option(self, k):
173
+ def get_option(self, k, hostvars=None):
177
174
  return self._plugin_options[k]
178
175
 
176
+ def has_option(self, option):
177
+ return (option in self._plugin_options)
178
+
179
179
  def set_options(self, task_keys=None, var_options=None, direct=None):
180
- ''' This is different than the normal plugin method as callbacks get called early and really don't accept keywords.
180
+ """ This is different than the normal plugin method as callbacks get called early and really don't accept keywords.
181
181
  Also _options was already taken for CLI args and callbacks use _plugin_options instead.
182
- '''
182
+ """
183
183
 
184
184
  # load from config
185
185
  self._plugin_options = C.config.get_plugin_options(self.plugin_type, self._load_name, keys=task_keys, variables=var_options, direct=direct)
@@ -240,9 +240,12 @@ class CallbackBase(AnsiblePlugin):
240
240
  if self._display.verbosity < 3 and 'diff' in result:
241
241
  del abridged_result['diff']
242
242
 
243
- # remove exception from screen output
244
- if 'exception' in abridged_result:
245
- del abridged_result['exception']
243
+ # remove error/warning values; the stdout callback should have already handled them
244
+ abridged_result.pop('exception', None)
245
+ abridged_result.pop('warnings', None)
246
+ abridged_result.pop('deprecations', None)
247
+
248
+ abridged_result = _engine.TemplateEngine().transform(abridged_result) # ensure the dumped view matches the transformed view a playbook sees
246
249
 
247
250
  if not serialize:
248
251
  # Just return ``abridged_result`` without going through serialization
@@ -251,17 +254,8 @@ class CallbackBase(AnsiblePlugin):
251
254
  return abridged_result
252
255
 
253
256
  if result_format == 'json':
254
- try:
255
- return json.dumps(abridged_result, cls=AnsibleJSONEncoder, indent=indent, ensure_ascii=False, sort_keys=sort_keys)
256
- except TypeError:
257
- # Python3 bug: throws an exception when keys are non-homogenous types:
258
- # https://bugs.python.org/issue25457
259
- # sort into an OrderedDict and then json.dumps() that instead
260
- if not OrderedDict:
261
- raise
262
- return json.dumps(OrderedDict(sorted(abridged_result.items(), key=to_text)),
263
- cls=AnsibleJSONEncoder, indent=indent,
264
- ensure_ascii=False, sort_keys=False)
257
+ return json.dumps(abridged_result, cls=_fallback_to_str.Encoder, indent=indent, ensure_ascii=False, sort_keys=sort_keys)
258
+
265
259
  elif result_format == 'yaml':
266
260
  # None is a sentinel in this case that indicates default behavior
267
261
  # default behavior for yaml is to prettify results
@@ -279,7 +273,7 @@ class CallbackBase(AnsiblePlugin):
279
273
  yaml.dump(
280
274
  abridged_result,
281
275
  allow_unicode=True,
282
- Dumper=_AnsibleCallbackDumper(lossy=lossy),
276
+ Dumper=functools.partial(_AnsibleCallbackDumper, lossy=lossy),
283
277
  default_flow_style=False,
284
278
  indent=indent,
285
279
  # sort_keys=sort_keys # This requires PyYAML>=5.1
@@ -287,32 +281,31 @@ class CallbackBase(AnsiblePlugin):
287
281
  ' ' * (indent or 4)
288
282
  )
289
283
 
290
- def _handle_warnings(self, res):
291
- ''' display warnings, if enabled and any exist in the result '''
292
- if C.ACTION_WARNINGS:
293
- if 'warnings' in res and res['warnings']:
294
- for warning in res['warnings']:
295
- self._display.warning(warning)
296
- del res['warnings']
297
- if 'deprecations' in res and res['deprecations']:
298
- for warning in res['deprecations']:
299
- self._display.deprecated(**warning)
300
- del res['deprecations']
301
-
302
- def _handle_exception(self, result, use_stderr=False):
303
-
304
- if 'exception' in result:
305
- msg = "An exception occurred during task execution. "
306
- exception_str = to_text(result['exception'])
307
- if self._display.verbosity < 3:
308
- # extract just the actual error message from the exception text
309
- error = exception_str.strip().split('\n')[-1]
310
- msg += "To see the full traceback, use -vvv. The error was: %s" % error
311
- else:
312
- msg = "The full traceback is:\n" + exception_str
313
- del result['exception']
284
+ def _handle_warnings(self, res: dict[str, t.Any]) -> None:
285
+ """Display warnings and deprecation warnings sourced by task execution."""
286
+ for warning in res.pop('warnings', []):
287
+ # DTFIX-RELEASE: what to do about propagating wrap_text from the original display.warning call?
288
+ self._display._warning(warning, wrap_text=False)
289
+
290
+ for warning in res.pop('deprecations', []):
291
+ self._display._deprecated(warning)
292
+
293
+ def _handle_exception(self, result: dict[str, t.Any], use_stderr: bool = False) -> None:
294
+ error_summary: ErrorSummary | None
314
295
 
315
- self._display.display(msg, color=C.COLOR_ERROR, stderr=use_stderr)
296
+ if error_summary := result.pop('exception', None):
297
+ self._display._error(error_summary, wrap_text=False, stderr=use_stderr)
298
+
299
+ def _handle_warnings_and_exception(self, result: TaskResult) -> None:
300
+ """Standardized handling of warnings/deprecations and exceptions from a task/item result."""
301
+ # DTFIX-RELEASE: make/doc/porting-guide a public version of this method?
302
+ try:
303
+ use_stderr = self.get_option('display_failed_stderr')
304
+ except KeyError:
305
+ use_stderr = False
306
+
307
+ self._handle_warnings(result._result)
308
+ self._handle_exception(result._result, use_stderr=use_stderr)
316
309
 
317
310
  def _serialize_diff(self, diff):
318
311
  try:
@@ -337,7 +330,7 @@ class CallbackBase(AnsiblePlugin):
337
330
  yaml.dump(
338
331
  diff,
339
332
  allow_unicode=True,
340
- Dumper=_AnsibleCallbackDumper(lossy=lossy),
333
+ Dumper=functools.partial(_AnsibleCallbackDumper, lossy=lossy),
341
334
  default_flow_style=False,
342
335
  indent=4,
343
336
  # sort_keys=sort_keys # This requires PyYAML>=5.1
@@ -406,7 +399,7 @@ class CallbackBase(AnsiblePlugin):
406
399
  return u''.join(ret)
407
400
 
408
401
  def _get_item_label(self, result):
409
- ''' retrieves the value to be displayed as a label for an item entry from a result object'''
402
+ """ retrieves the value to be displayed as a label for an item entry from a result object"""
410
403
  if result.get('_ansible_no_log', False):
411
404
  item = "(censored due to no_log)"
412
405
  else:
@@ -418,9 +411,10 @@ class CallbackBase(AnsiblePlugin):
418
411
  del result._result['results']
419
412
 
420
413
  def _clean_results(self, result, task_name):
421
- ''' removes data from results for display '''
414
+ """ removes data from results for display """
422
415
 
423
416
  # mostly controls that debug only outputs what it was meant to
417
+ # FIXME: this is a terrible heuristic to format debug's output- it masks exception detail
424
418
  if task_name in C._ACTION_DEBUG:
425
419
  if 'msg' in result:
426
420
  # msg should be alone
@@ -508,67 +502,91 @@ class CallbackBase(AnsiblePlugin):
508
502
  self.on_any(args, kwargs)
509
503
 
510
504
  def v2_runner_on_failed(self, result: TaskResult, ignore_errors: bool = False) -> None:
511
- """Get details about a failed task and whether or not Ansible should continue
512
- running tasks on the host where the failure occurred, then process the details
513
- as required by the callback (output, profiling, logging, notifications, etc.)
514
-
515
- Note: The 'ignore_errors' directive only works when the task can run and returns
516
- a value of 'failed'. It does not make Ansible ignore undefined variable errors,
517
- connection failures, execution issues (for example, missing packages), or syntax errors.
505
+ """Process results of a failed task.
518
506
 
519
- Customization note: For more information about the attributes and methods of the
520
- TaskResult class, see lib/ansible/executor/task_result.py.
507
+ Note: The value of 'ignore_errors' tells Ansible whether to
508
+ continue running tasks on the host where this task failed.
509
+ But the 'ignore_errors' directive only works when the task can
510
+ run and returns a value of 'failed'. It does not make Ansible
511
+ ignore undefined variable errors, connection failures, execution
512
+ issues (for example, missing packages), or syntax errors.
521
513
 
522
- :param TaskResult result: An object that contains details about the task
523
- :param bool ignore_errors: Whether or not Ansible should continue running tasks on the host
524
- where the failure occurred
514
+ :param result: The parameters of the task and its results.
515
+ :type result: TaskResult
516
+ :param ignore_errors: Whether Ansible should continue \
517
+ running tasks on the host where the task failed.
518
+ :type ignore_errors: bool
525
519
 
526
520
  :return: None
521
+ :rtype: None
527
522
  """
528
523
  host = result._host.get_name()
529
524
  self.runner_on_failed(host, result._result, ignore_errors)
530
525
 
531
526
  def v2_runner_on_ok(self, result: TaskResult) -> None:
532
- """Get details about a successful task and process them as required by the callback
533
- (output, profiling, logging, notifications, etc.)
534
-
535
- Customization note: For more information about the attributes and methods of the
536
- TaskResult class, see lib/ansible/executor/task_result.py.
527
+ """Process results of a successful task.
537
528
 
538
- :param TaskResult result: An object that contains details about the task
529
+ :param result: The parameters of the task and its results.
530
+ :type result: TaskResult
539
531
 
540
532
  :return: None
533
+ :rtype: None
541
534
  """
542
535
  host = result._host.get_name()
543
536
  self.runner_on_ok(host, result._result)
544
537
 
545
538
  def v2_runner_on_skipped(self, result: TaskResult) -> None:
546
- """Get details about a skipped task and process them as required by the callback
547
- (output, profiling, logging, notifications, etc.)
539
+ """Process results of a skipped task.
548
540
 
549
- Customization note: For more information about the attributes and methods of the
550
- TaskResult class, see lib/ansible/executor/task_result.py.
551
-
552
- :param TaskResult result: An object that contains details about the task
541
+ :param result: The parameters of the task and its results.
542
+ :type result: TaskResult
553
543
 
554
544
  :return: None
545
+ :rtype: None
555
546
  """
556
547
  if C.DISPLAY_SKIPPED_HOSTS:
557
548
  host = result._host.get_name()
558
549
  self.runner_on_skipped(host, self._get_item_label(getattr(result._result, 'results', {})))
559
550
 
560
- def v2_runner_on_unreachable(self, result):
551
+ def v2_runner_on_unreachable(self, result: TaskResult) -> None:
552
+ """Process results of a task if a target node is unreachable.
553
+
554
+ :param result: The parameters of the task and its results.
555
+ :type result: TaskResult
556
+
557
+ :return: None
558
+ :rtype: None
559
+ """
561
560
  host = result._host.get_name()
562
561
  self.runner_on_unreachable(host, result._result)
563
562
 
564
- def v2_runner_on_async_poll(self, result):
563
+ def v2_runner_on_async_poll(self, result: TaskResult) -> None:
564
+ """Get details about an unfinished task running in async mode.
565
+
566
+ Note: The value of the `poll` keyword in the task determines
567
+ the interval at which polling occurs and this method is run.
568
+
569
+ :param result: The parameters of the task and its status.
570
+ :type result: TaskResult
571
+
572
+ :rtype: None
573
+ :rtype: None
574
+ """
565
575
  host = result._host.get_name()
566
576
  jid = result._result.get('ansible_job_id')
567
577
  # FIXME, get real clock
568
578
  clock = 0
569
579
  self.runner_on_async_poll(host, result._result, jid, clock)
570
580
 
571
- def v2_runner_on_async_ok(self, result):
581
+ def v2_runner_on_async_ok(self, result: TaskResult) -> None:
582
+ """Process results of a successful task that ran in async mode.
583
+
584
+ :param result: The parameters of the task and its results.
585
+ :type result: TaskResult
586
+
587
+ :return: None
588
+ :rtype: None
589
+ """
572
590
  host = result._host.get_name()
573
591
  jid = result._result.get('ansible_job_id')
574
592
  self.runner_on_async_ok(host, result._result, jid)
@@ -631,13 +649,13 @@ class CallbackBase(AnsiblePlugin):
631
649
  def v2_playbook_on_include(self, included_file):
632
650
  pass # no v1 correspondence
633
651
 
634
- def v2_runner_item_on_ok(self, result):
652
+ def v2_runner_item_on_ok(self, result: TaskResult) -> None:
635
653
  pass
636
654
 
637
- def v2_runner_item_on_failed(self, result):
655
+ def v2_runner_item_on_failed(self, result: TaskResult) -> None:
638
656
  pass
639
657
 
640
- def v2_runner_item_on_skipped(self, result):
658
+ def v2_runner_item_on_skipped(self, result: TaskResult) -> None:
641
659
  pass
642
660
 
643
661
  def v2_runner_retry(self, result):
@@ -4,7 +4,7 @@
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
- DOCUMENTATION = '''
7
+ DOCUMENTATION = """
8
8
  name: default
9
9
  type: stdout
10
10
  short_description: default Ansible screen output
@@ -16,11 +16,12 @@ DOCUMENTATION = '''
16
16
  - result_format_callback
17
17
  requirements:
18
18
  - set as stdout in configuration
19
- '''
19
+ """
20
20
 
21
21
 
22
22
  from ansible import constants as C
23
23
  from ansible import context
24
+ from ansible.executor.task_result import TaskResult
24
25
  from ansible.playbook.task_include import TaskInclude
25
26
  from ansible.plugins.callback import CallbackBase
26
27
  from ansible.utils.color import colorize, hostcolor
@@ -29,10 +30,10 @@ from ansible.utils.fqcn import add_internal_fqcns
29
30
 
30
31
  class CallbackModule(CallbackBase):
31
32
 
32
- '''
33
+ """
33
34
  This is the default callback interface, which simply prints messages
34
35
  to stdout when new callback events are received.
35
- '''
36
+ """
36
37
 
37
38
  CALLBACK_VERSION = 2.0
38
39
  CALLBACK_TYPE = 'stdout'
@@ -46,20 +47,20 @@ class CallbackModule(CallbackBase):
46
47
  self._task_type_cache = {}
47
48
  super(CallbackModule, self).__init__()
48
49
 
49
- def v2_runner_on_failed(self, result, ignore_errors=False):
50
-
50
+ def v2_runner_on_failed(self, result: TaskResult, ignore_errors: bool = False) -> None:
51
51
  host_label = self.host_label(result)
52
- self._clean_results(result._result, result._task.action)
53
52
 
54
53
  if self._last_task_banner != result._task._uuid:
55
54
  self._print_task_banner(result._task)
56
55
 
57
- self._handle_exception(result._result, use_stderr=self.get_option('display_failed_stderr'))
58
- self._handle_warnings(result._result)
56
+ self._handle_warnings_and_exception(result)
57
+
58
+ # FIXME: this method should not exist, delegate "suggested keys to display" to the plugin or something... As-is, the placement of this
59
+ # call obliterates `results`, which causes a task summary to be printed on loop failures, which we don't do anywhere else.
60
+ self._clean_results(result._result, result._task.action)
59
61
 
60
62
  if result._task.loop and 'results' in result._result:
61
63
  self._process_items(result)
62
-
63
64
  else:
64
65
  if self._display.verbosity < 2 and self.get_option('show_task_path_on_failure'):
65
66
  self._print_task_path(result._task)
@@ -69,8 +70,7 @@ class CallbackModule(CallbackBase):
69
70
  if ignore_errors:
70
71
  self._display.display("...ignoring", color=C.COLOR_SKIP)
71
72
 
72
- def v2_runner_on_ok(self, result):
73
-
73
+ def v2_runner_on_ok(self, result: TaskResult) -> None:
74
74
  host_label = self.host_label(result)
75
75
 
76
76
  if isinstance(result._task, TaskInclude):
@@ -93,7 +93,7 @@ class CallbackModule(CallbackBase):
93
93
  msg = "ok: [%s]" % (host_label,)
94
94
  color = C.COLOR_OK
95
95
 
96
- self._handle_warnings(result._result)
96
+ self._handle_warnings_and_exception(result)
97
97
 
98
98
  if result._task.loop and 'results' in result._result:
99
99
  self._process_items(result)
@@ -104,8 +104,7 @@ class CallbackModule(CallbackBase):
104
104
  msg += " => %s" % (self._dump_results(result._result),)
105
105
  self._display.display(msg, color=color)
106
106
 
107
- def v2_runner_on_skipped(self, result):
108
-
107
+ def v2_runner_on_skipped(self, result: TaskResult) -> None:
109
108
  if self.get_option('display_skipped_hosts'):
110
109
 
111
110
  self._clean_results(result._result, result._task.action)
@@ -113,6 +112,8 @@ class CallbackModule(CallbackBase):
113
112
  if self._last_task_banner != result._task._uuid:
114
113
  self._print_task_banner(result._task)
115
114
 
115
+ self._handle_warnings_and_exception(result)
116
+
116
117
  if result._task.loop is not None and 'results' in result._result:
117
118
  self._process_items(result)
118
119
 
@@ -121,10 +122,12 @@ class CallbackModule(CallbackBase):
121
122
  msg += " => %s" % self._dump_results(result._result)
122
123
  self._display.display(msg, color=C.COLOR_SKIP)
123
124
 
124
- def v2_runner_on_unreachable(self, result):
125
+ def v2_runner_on_unreachable(self, result: TaskResult) -> None:
125
126
  if self._last_task_banner != result._task._uuid:
126
127
  self._print_task_banner(result._task)
127
128
 
129
+ self._handle_warnings_and_exception(result)
130
+
128
131
  host_label = self.host_label(result)
129
132
  msg = "fatal: [%s]: UNREACHABLE! => %s" % (host_label, self._dump_results(result._result))
130
133
  self._display.display(msg, color=C.COLOR_UNREACHABLE, stderr=self.get_option('display_failed_stderr'))
@@ -171,6 +174,7 @@ class CallbackModule(CallbackBase):
171
174
  # that they can secure this if they feel that their stdout is insecure
172
175
  # (shoulder surfing, logging stdout straight to a file, etc).
173
176
  args = ''
177
+ # FIXME: the no_log value is not templated at this point, so any template will be considered truthy
174
178
  if not task.no_log and C.DISPLAY_ARGS_TO_STDOUT:
175
179
  args = u', '.join(u'%s=%s' % a for a in task.args.items())
176
180
  args = u' %s' % args
@@ -234,8 +238,7 @@ class CallbackModule(CallbackBase):
234
238
  self._print_task_banner(result._task)
235
239
  self._display.display(diff)
236
240
 
237
- def v2_runner_item_on_ok(self, result):
238
-
241
+ def v2_runner_item_on_ok(self, result: TaskResult) -> None:
239
242
  host_label = self.host_label(result)
240
243
  if isinstance(result._task, TaskInclude):
241
244
  return
@@ -255,33 +258,37 @@ class CallbackModule(CallbackBase):
255
258
  msg = 'ok'
256
259
  color = C.COLOR_OK
257
260
 
261
+ self._handle_warnings_and_exception(result)
262
+
258
263
  msg = "%s: [%s] => (item=%s)" % (msg, host_label, self._get_item_label(result._result))
259
264
  self._clean_results(result._result, result._task.action)
260
265
  if self._run_is_verbose(result):
261
266
  msg += " => %s" % self._dump_results(result._result)
262
267
  self._display.display(msg, color=color)
263
268
 
264
- def v2_runner_item_on_failed(self, result):
269
+ def v2_runner_item_on_failed(self, result: TaskResult) -> None:
265
270
  if self._last_task_banner != result._task._uuid:
266
271
  self._print_task_banner(result._task)
267
272
 
273
+ self._handle_warnings_and_exception(result)
274
+
268
275
  host_label = self.host_label(result)
269
- self._clean_results(result._result, result._task.action)
270
- self._handle_exception(result._result, use_stderr=self.get_option('display_failed_stderr'))
271
276
 
272
277
  msg = "failed: [%s]" % (host_label,)
273
- self._handle_warnings(result._result)
278
+ self._clean_results(result._result, result._task.action)
274
279
  self._display.display(
275
280
  msg + " (item=%s) => %s" % (self._get_item_label(result._result), self._dump_results(result._result)),
276
281
  color=C.COLOR_ERROR,
277
282
  stderr=self.get_option('display_failed_stderr')
278
283
  )
279
284
 
280
- def v2_runner_item_on_skipped(self, result):
285
+ def v2_runner_item_on_skipped(self, result: TaskResult) -> None:
281
286
  if self.get_option('display_skipped_hosts'):
282
287
  if self._last_task_banner != result._task._uuid:
283
288
  self._print_task_banner(result._task)
284
289
 
290
+ self._handle_warnings_and_exception(result)
291
+
285
292
  self._clean_results(result._result, result._task.action)
286
293
  msg = "skipping: [%s] => (item=%s) " % (result._host.get_name(), self._get_item_label(result._result))
287
294
  if self._run_is_verbose(result):