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