ansible-core 2.18.5rc1__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 +39 -13
  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 +19 -17
  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 +6 -6
  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 +33 -26
  279. ansible/modules/user.py +53 -34
  280. ansible/modules/validate_argument_spec.py +10 -7
  281. ansible/modules/wait_for.py +32 -27
  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 +7 -6
  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 +1 -1
  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.5rc1.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.5rc1.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.5rc1.dist-info/RECORD +0 -992
  703. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/Apache-License.txt +0 -0
  704. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/COPYING +0 -0
  705. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/MIT-license.txt +0 -0
  706. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/PSF-license.txt +0 -0
  707. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/entry_points.txt +0 -0
  708. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/simplified_bsd.txt +0 -0
  709. {ansible_core-2.18.5rc1.dist-info → ansible_core-2.19.0b1.dist-info}/top_level.txt +0 -0
@@ -4,8 +4,10 @@
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
+ import copy
7
8
  import json
8
9
  import sys
10
+ import typing as t
9
11
 
10
12
  # Used for determining if the system is running a new enough python version
11
13
  # and should only restrict on our documented minimum versions
@@ -24,6 +26,7 @@ if sys.version_info < _PY_MIN:
24
26
 
25
27
  import __main__
26
28
  import atexit
29
+ import dataclasses as _dataclasses
27
30
  import errno
28
31
  import grp
29
32
  import fcntl
@@ -50,6 +53,10 @@ try:
50
53
  except ImportError:
51
54
  HAS_SYSLOG = False
52
55
 
56
+ # deprecated: description='types.EllipsisType is available in Python 3.10+' python_version='3.9'
57
+ if t.TYPE_CHECKING:
58
+ from builtins import ellipsis
59
+
53
60
  try:
54
61
  from systemd import journal, daemon as systemd_daemon
55
62
  # Makes sure that systemd.journal has method sendv()
@@ -70,8 +77,12 @@ except ImportError:
70
77
  # Python2 & 3 way to get NoneType
71
78
  NoneType = type(None)
72
79
 
73
- from ._text import to_native, to_bytes, to_text
74
- from ansible.module_utils.common.text.converters import (
80
+ from ._internal import _traceback, _errors, _debugging
81
+
82
+ from .common.text.converters import (
83
+ to_native,
84
+ to_bytes,
85
+ to_text,
75
86
  jsonify,
76
87
  container_to_bytes as json_dict_unicode_to_bytes,
77
88
  container_to_text as json_dict_bytes_to_unicode,
@@ -86,6 +97,8 @@ from ansible.module_utils.common.text.formatters import (
86
97
  SIZE_RANGES,
87
98
  )
88
99
 
100
+ from ansible.module_utils.common import json as _common_json
101
+
89
102
  import hashlib
90
103
 
91
104
 
@@ -110,6 +123,8 @@ def _get_available_hash_algorithms():
110
123
 
111
124
  AVAILABLE_HASH_ALGORITHMS = _get_available_hash_algorithms()
112
125
 
126
+ from ansible.module_utils.common import json as _json
127
+
113
128
  from ansible.module_utils.six.moves.collections_abc import (
114
129
  KeysView,
115
130
  Mapping, MutableMapping,
@@ -148,11 +163,12 @@ from ansible.module_utils.common.validation import (
148
163
  safe_eval,
149
164
  )
150
165
  from ansible.module_utils.common._utils import get_all_subclasses as _get_all_subclasses
166
+ from ansible.module_utils.common import messages as _messages
151
167
  from ansible.module_utils.parsing.convert_bool import BOOLEANS, BOOLEANS_FALSE, BOOLEANS_TRUE, boolean
152
168
  from ansible.module_utils.common.warnings import (
153
169
  deprecate,
154
- get_deprecation_messages,
155
- get_warning_messages,
170
+ get_deprecations,
171
+ get_warnings,
156
172
  warn,
157
173
  )
158
174
 
@@ -168,7 +184,9 @@ imap = map
168
184
  # multiple AnsibleModules are created. Otherwise each AnsibleModule would
169
185
  # attempt to read from stdin. Other code should not use this directly as it
170
186
  # is an internal implementation detail
171
- _ANSIBLE_ARGS = None
187
+ _ANSIBLE_ARGS: bytes | None = None
188
+ _ANSIBLE_PROFILE: str | None = None
189
+ _PARSED_MODULE_ARGS: dict[str, t.Any] | None = None
172
190
 
173
191
 
174
192
  FILE_COMMON_ARGUMENTS = dict(
@@ -199,14 +217,14 @@ PERMS_RE = re.compile(r'^[rwxXstugo]*$')
199
217
  #
200
218
 
201
219
  def get_platform():
202
- '''
220
+ """
203
221
  **Deprecated** Use :py:func:`platform.system` directly.
204
222
 
205
223
  :returns: Name of the platform the module is running on in a native string
206
224
 
207
225
  Returns a native string that labels the platform ("Linux", "Solaris", etc). Currently, this is
208
226
  the result of calling :py:func:`platform.system`.
209
- '''
227
+ """
210
228
  return platform.system()
211
229
 
212
230
  # End deprecated functions
@@ -231,7 +249,7 @@ def get_all_subclasses(cls):
231
249
 
232
250
 
233
251
  def heuristic_log_sanitize(data, no_log_values=None):
234
- ''' Remove strings that look like passwords from log messages '''
252
+ """ Remove strings that look like passwords from log messages """
235
253
  # Currently filters:
236
254
  # user:pass@foo/whatever and http://username:pass@wherever/foo
237
255
  # This code has false positives and consumes parts of logs that are
@@ -296,7 +314,7 @@ def heuristic_log_sanitize(data, no_log_values=None):
296
314
 
297
315
 
298
316
  def _load_params():
299
- ''' read the modules parameters and store them globally.
317
+ """ read the modules parameters and store them globally.
300
318
 
301
319
  This function may be needed for certain very dynamic custom modules which
302
320
  want to process the parameters that are being handed the module. Since
@@ -305,42 +323,32 @@ def _load_params():
305
323
  will try not to break it gratuitously. It is certainly more future-proof
306
324
  to call this function and consume its outputs than to implement the logic
307
325
  inside it as a copy in your own code.
308
- '''
309
- global _ANSIBLE_ARGS
310
- if _ANSIBLE_ARGS is not None:
311
- buffer = _ANSIBLE_ARGS
312
- else:
313
- # debug overrides to read args from file or cmdline
326
+ """
327
+ global _ANSIBLE_ARGS, _ANSIBLE_PROFILE
314
328
 
315
- # Avoid tracebacks when locale is non-utf8
316
- # We control the args and we pass them as utf8
317
- if len(sys.argv) > 1:
318
- if os.path.isfile(sys.argv[1]):
319
- fd = open(sys.argv[1], 'rb')
320
- buffer = fd.read()
321
- fd.close()
322
- else:
323
- buffer = sys.argv[1].encode('utf-8', errors='surrogateescape')
324
- # default case, read from stdin
325
- else:
326
- buffer = sys.stdin.buffer.read()
327
- _ANSIBLE_ARGS = buffer
329
+ if _ANSIBLE_ARGS is None:
330
+ _ANSIBLE_ARGS, _ANSIBLE_PROFILE = _debugging.load_params()
328
331
 
329
- try:
330
- params = json.loads(buffer.decode('utf-8'))
331
- except ValueError:
332
- # This helper is used too early for fail_json to work.
333
- print('\n{"msg": "Error: Module unable to decode stdin/parameters as valid JSON. Unable to parse what parameters were passed", "failed": true}')
334
- sys.exit(1)
332
+ buffer = _ANSIBLE_ARGS
333
+ profile = _ANSIBLE_PROFILE
334
+
335
+ if not profile:
336
+ raise Exception("No serialization profile was specified.")
335
337
 
336
338
  try:
337
- return params['ANSIBLE_MODULE_ARGS']
338
- except KeyError:
339
- # This helper does not have access to fail_json so we have to print
340
- # json output on our own.
341
- print('\n{"msg": "Error: Module unable to locate ANSIBLE_MODULE_ARGS in JSON data from stdin. Unable to figure out what parameters were passed", '
342
- '"failed": true}')
343
- sys.exit(1)
339
+ decoder = _json.get_module_decoder(profile, _json.Direction.CONTROLLER_TO_MODULE)
340
+ params = json.loads(buffer.decode(), cls=decoder)
341
+ except Exception as ex:
342
+ raise Exception("Failed to decode JSON module parameters.") from ex
343
+
344
+ if (ansible_module_args := params.get('ANSIBLE_MODULE_ARGS', ...)) is ...:
345
+ raise Exception("ANSIBLE_MODULE_ARGS not provided.")
346
+
347
+ global _PARSED_MODULE_ARGS
348
+
349
+ _PARSED_MODULE_ARGS = copy.deepcopy(ansible_module_args) # AnsibleModule mutates the returned dict, so a copy is needed
350
+
351
+ return ansible_module_args
344
352
 
345
353
 
346
354
  def missing_required_lib(library, reason=None, url=None):
@@ -363,13 +371,13 @@ class AnsibleModule(object):
363
371
  required_one_of=None, add_file_common_args=False,
364
372
  supports_check_mode=False, required_if=None, required_by=None):
365
373
 
366
- '''
374
+ """
367
375
  Common code for quickly building an ansible module in Python
368
376
  (although you can write modules with anything that can return JSON).
369
377
 
370
378
  See :ref:`developing_modules_general` for a general introduction
371
379
  and :ref:`developing_program_flow_modules` for more detailed explanation.
372
- '''
380
+ """
373
381
 
374
382
  self._name = os.path.basename(__file__) # initialize name until we can parse from options
375
383
  self.argument_spec = argument_spec
@@ -394,7 +402,6 @@ class AnsibleModule(object):
394
402
  # run_command invocation
395
403
  self.run_command_environ_update = {}
396
404
  self._clean = {}
397
- self._string_conversion_action = ''
398
405
 
399
406
  self.aliases = {}
400
407
  self._legal_inputs = []
@@ -507,7 +514,7 @@ class AnsibleModule(object):
507
514
  def deprecate(self, msg, version=None, date=None, collection_name=None):
508
515
  if version is not None and date is not None:
509
516
  raise AssertionError("implementation error -- version and date must not both be set")
510
- deprecate(msg, version=version, date=date, collection_name=collection_name)
517
+ deprecate(msg, version=version, date=date)
511
518
  # For compatibility, we accept that neither version nor date is set,
512
519
  # and treat that the same as if version would not have been set
513
520
  if date is not None:
@@ -516,13 +523,13 @@ class AnsibleModule(object):
516
523
  self.log('[DEPRECATION WARNING] %s %s' % (msg, version))
517
524
 
518
525
  def load_file_common_arguments(self, params, path=None):
519
- '''
526
+ """
520
527
  many modules deal with files, this encapsulates common
521
528
  options that the file module accepts such that it is directly
522
529
  available to all modules and they can share code.
523
530
 
524
531
  Allows to overwrite the path/dest module argument by providing path.
525
- '''
532
+ """
526
533
 
527
534
  if path is None:
528
535
  path = params.get('path', params.get('dest', None))
@@ -635,12 +642,12 @@ class AnsibleModule(object):
635
642
  return (uid, gid)
636
643
 
637
644
  def find_mount_point(self, path):
638
- '''
645
+ """
639
646
  Takes a path and returns its mount point
640
647
 
641
648
  :param path: a string type with a filesystem path
642
649
  :returns: the path to the mount point as a text type
643
- '''
650
+ """
644
651
 
645
652
  b_path = os.path.realpath(to_bytes(os.path.expanduser(os.path.expandvars(path)), errors='surrogate_or_strict'))
646
653
  while not os.path.ismount(b_path):
@@ -654,9 +661,8 @@ class AnsibleModule(object):
654
661
  NFS or other 'special' fs mount point, otherwise the return will be (False, None).
655
662
  """
656
663
  try:
657
- f = open('/proc/mounts', 'r')
658
- mount_data = f.readlines()
659
- f.close()
664
+ with open('/proc/mounts', 'r') as f:
665
+ mount_data = f.readlines()
660
666
  except Exception:
661
667
  return (False, None)
662
668
 
@@ -880,8 +886,7 @@ class AnsibleModule(object):
880
886
  raise
881
887
  except Exception as e:
882
888
  path = to_text(b_path)
883
- self.fail_json(path=path, msg='chmod failed', details=to_native(e),
884
- exception=traceback.format_exc())
889
+ self.fail_json(path=path, msg='chmod failed', details=to_native(e))
885
890
 
886
891
  path_stat = os.lstat(b_path)
887
892
  new_mode = stat.S_IMODE(path_stat.st_mode)
@@ -929,8 +934,7 @@ class AnsibleModule(object):
929
934
  if rc != 0 or err:
930
935
  raise Exception("Error while setting attributes: %s" % (out + err))
931
936
  except Exception as e:
932
- self.fail_json(path=to_text(b_path), msg='chattr failed',
933
- details=to_native(e), exception=traceback.format_exc())
937
+ self.fail_json(path=to_text(b_path), msg='chattr failed', details=to_native(e))
934
938
  return changed
935
939
 
936
940
  def get_file_attributes(self, path, include_version=True):
@@ -1115,10 +1119,10 @@ class AnsibleModule(object):
1115
1119
  return self.set_fs_attributes_if_different(file_args, changed, diff, expand)
1116
1120
 
1117
1121
  def add_path_info(self, kwargs):
1118
- '''
1122
+ """
1119
1123
  for results that are files, supplement the info about the file
1120
1124
  in the return path with stats about the file path.
1121
- '''
1125
+ """
1122
1126
 
1123
1127
  path = kwargs.get('path', kwargs.get('dest', None))
1124
1128
  if path is None:
@@ -1155,10 +1159,10 @@ class AnsibleModule(object):
1155
1159
  return kwargs
1156
1160
 
1157
1161
  def _check_locale(self):
1158
- '''
1162
+ """
1159
1163
  Uses the locale module to test the currently set locale
1160
1164
  (per the LANG and LC_CTYPE environment settings)
1161
- '''
1165
+ """
1162
1166
  try:
1163
1167
  # setting the locale to '' uses the default locale
1164
1168
  # as it would be returned by locale.getdefaultlocale()
@@ -1175,8 +1179,7 @@ class AnsibleModule(object):
1175
1179
  os.environ['LC_ALL'] = best_locale
1176
1180
  os.environ['LC_MESSAGES'] = best_locale
1177
1181
  except Exception as e:
1178
- self.fail_json(msg="An unknown error was encountered while attempting to validate the locale: %s" %
1179
- to_native(e), exception=traceback.format_exc())
1182
+ self.fail_json(msg="An unknown error was encountered while attempting to validate the locale: %s" % to_native(e))
1180
1183
 
1181
1184
  def _set_internal_properties(self, argument_spec=None, module_parameters=None):
1182
1185
  if argument_spec is None:
@@ -1206,11 +1209,11 @@ class AnsibleModule(object):
1206
1209
  return safe_eval(value, locals, include_exceptions)
1207
1210
 
1208
1211
  def _load_params(self):
1209
- ''' read the input and set the params attribute.
1212
+ """ read the input and set the params attribute.
1210
1213
 
1211
1214
  This method is for backwards compatibility. The guts of the function
1212
1215
  were moved out in 2.1 so that custom modules could read the parameters.
1213
- '''
1216
+ """
1214
1217
  # debug overrides to read args from file or cmdline
1215
1218
  self.params = _load_params()
1216
1219
 
@@ -1226,7 +1229,6 @@ class AnsibleModule(object):
1226
1229
  msg='Failed to log to syslog (%s). To proceed anyway, '
1227
1230
  'disable syslog logging by setting no_target_syslog '
1228
1231
  'to True in your Ansible config.' % to_native(e),
1229
- exception=traceback.format_exc(),
1230
1232
  msg_to_log=msg,
1231
1233
  )
1232
1234
 
@@ -1297,7 +1299,7 @@ class AnsibleModule(object):
1297
1299
  self._log_to_syslog(journal_msg)
1298
1300
 
1299
1301
  def _log_invocation(self):
1300
- ''' log that ansible ran the module '''
1302
+ """ log that ansible ran the module """
1301
1303
  # TODO: generalize a separate log function and make log_invocation use it
1302
1304
  # Sanitize possible password argument when logging.
1303
1305
  log_args = dict()
@@ -1350,7 +1352,7 @@ class AnsibleModule(object):
1350
1352
  return None
1351
1353
 
1352
1354
  def get_bin_path(self, arg, required=False, opt_dirs=None):
1353
- '''
1355
+ """
1354
1356
  Find system executable in PATH.
1355
1357
 
1356
1358
  :param arg: The executable to find.
@@ -1358,7 +1360,7 @@ class AnsibleModule(object):
1358
1360
  :param opt_dirs: optional list of directories to search in addition to ``PATH``
1359
1361
  :returns: if found return full path; otherwise return original arg, unless 'warning' then return None
1360
1362
  :raises: Sysexit: if arg is not found and required=True (via fail_json)
1361
- '''
1363
+ """
1362
1364
 
1363
1365
  bin_path = None
1364
1366
  try:
@@ -1370,7 +1372,7 @@ class AnsibleModule(object):
1370
1372
  return bin_path
1371
1373
 
1372
1374
  def boolean(self, arg):
1373
- '''Convert the argument to a boolean'''
1375
+ """Convert the argument to a boolean"""
1374
1376
  if arg is None:
1375
1377
  return arg
1376
1378
 
@@ -1380,8 +1382,15 @@ class AnsibleModule(object):
1380
1382
  self.fail_json(msg=to_native(e))
1381
1383
 
1382
1384
  def jsonify(self, data):
1385
+ # deprecated: description='deprecate AnsibleModule.jsonify()' core_version='2.23'
1386
+ # deprecate(
1387
+ # msg="The `AnsibleModule.jsonify' method is deprecated.",
1388
+ # version="2.27",
1389
+ # # help_text="", # DTFIX-RELEASE: fill in this help text
1390
+ # )
1391
+
1383
1392
  try:
1384
- return jsonify(data)
1393
+ return json.dumps(data, cls=_common_json._get_legacy_encoder())
1385
1394
  except UnicodeError as e:
1386
1395
  self.fail_json(msg=to_text(e))
1387
1396
 
@@ -1410,7 +1419,7 @@ class AnsibleModule(object):
1410
1419
  else:
1411
1420
  self.warn(kwargs['warnings'])
1412
1421
 
1413
- warnings = get_warning_messages()
1422
+ warnings = get_warnings()
1414
1423
  if warnings:
1415
1424
  kwargs['warnings'] = warnings
1416
1425
 
@@ -1427,16 +1436,12 @@ class AnsibleModule(object):
1427
1436
  else:
1428
1437
  self.deprecate(kwargs['deprecations']) # pylint: disable=ansible-deprecated-no-version
1429
1438
 
1430
- deprecations = get_deprecation_messages()
1439
+ deprecations = get_deprecations()
1431
1440
  if deprecations:
1432
1441
  kwargs['deprecations'] = deprecations
1433
1442
 
1434
1443
  # preserve bools/none from no_log
1435
- # TODO: once python version on target high enough, dict comprehensions
1436
- preserved = {}
1437
- for k, v in kwargs.items():
1438
- if v is None or isinstance(v, bool):
1439
- preserved[k] = v
1444
+ preserved = {k: v for k, v in kwargs.items() if v is None or isinstance(v, bool)}
1440
1445
 
1441
1446
  # strip no_log collisions
1442
1447
  kwargs = remove_values(kwargs, self.no_log_values)
@@ -1444,28 +1449,66 @@ class AnsibleModule(object):
1444
1449
  # return preserved
1445
1450
  kwargs.update(preserved)
1446
1451
 
1447
- print('\n%s' % self.jsonify(kwargs))
1452
+ encoder = _json.get_module_encoder(_ANSIBLE_PROFILE, _json.Direction.MODULE_TO_CONTROLLER)
1453
+ print('\n%s' % json.dumps(kwargs, cls=encoder))
1448
1454
 
1449
- def exit_json(self, **kwargs):
1450
- ''' return from the module, without error '''
1455
+ def exit_json(self, **kwargs) -> t.NoReturn:
1456
+ """ return from the module, without error """
1451
1457
 
1452
1458
  self.do_cleanup_files()
1453
1459
  self._return_formatted(kwargs)
1454
1460
  sys.exit(0)
1455
1461
 
1456
- def fail_json(self, msg, **kwargs):
1457
- ''' return from the module, with an error message '''
1462
+ def fail_json(self, msg: str, *, exception: BaseException | str | ellipsis | None = ..., **kwargs) -> t.NoReturn:
1463
+ """
1464
+ Return from the module with an error message and optional exception/traceback detail.
1465
+ A traceback will only be included in the result if error traceback capturing has been enabled.
1466
+
1467
+ When `exception` is an exception object, its message chain will be automatically combined with `msg` to create the final error message.
1468
+ The message chain includes the exception's message as well as messages from any __cause__ exceptions.
1469
+ The traceback from `exception` will be used for the formatted traceback.
1470
+
1471
+ When `exception` is a string, it will be used as the formatted traceback.
1472
+
1473
+ When `exception` is set to `None`, the current call stack will be used for the formatted traceback.
1474
+
1475
+ When `exception` is not specified, a formatted traceback will be retrieved from the current exception.
1476
+ If no exception is pending, the current call stack will be used instead.
1477
+ """
1478
+ msg = str(msg) # coerce to str instead of raising an error due to an invalid type
1479
+
1480
+ kwargs.update(
1481
+ failed=True,
1482
+ msg=msg,
1483
+ )
1484
+
1485
+ if isinstance(exception, BaseException):
1486
+ # Include a `_messages.ErrorDetail` in the result.
1487
+ # The `msg` is included in the list of errors to ensure it is not lost when looking only at `exception` from the result.
1488
+
1489
+ error_summary = _errors.create_error_summary(exception)
1490
+ error_summary = _dataclasses.replace(error_summary, details=(_messages.Detail(msg=msg),) + error_summary.details)
1458
1491
 
1459
- kwargs['failed'] = True
1460
- kwargs['msg'] = msg
1492
+ kwargs.update(exception=error_summary)
1493
+ elif _traceback.is_traceback_enabled(_traceback.TracebackEvent.ERROR):
1494
+ # Include only a formatted traceback string in the result.
1495
+ # The controller will combine this with `msg` to create an `_messages.ErrorDetail`.
1496
+
1497
+ formatted_traceback: str | None
1498
+
1499
+ if isinstance(exception, str):
1500
+ formatted_traceback = exception
1501
+ elif exception is ... and (current_exception := t.cast(t.Optional[BaseException], sys.exc_info()[1])):
1502
+ formatted_traceback = _traceback.maybe_extract_traceback(current_exception, _traceback.TracebackEvent.ERROR)
1503
+ else:
1504
+ formatted_traceback = _traceback.maybe_capture_traceback(_traceback.TracebackEvent.ERROR)
1461
1505
 
1462
- # Add traceback if debug or high verbosity and it is missing
1463
- # NOTE: Badly named as exception, it really always has been a traceback
1464
- if 'exception' not in kwargs and sys.exc_info()[2] and (self._debug or self._verbosity >= 3):
1465
- kwargs['exception'] = ''.join(traceback.format_tb(sys.exc_info()[2]))
1506
+ if formatted_traceback:
1507
+ kwargs.update(exception=formatted_traceback)
1466
1508
 
1467
1509
  self.do_cleanup_files()
1468
1510
  self._return_formatted(kwargs)
1511
+
1469
1512
  sys.exit(1)
1470
1513
 
1471
1514
  def fail_on_missing_params(self, required_params=None):
@@ -1477,7 +1520,7 @@ class AnsibleModule(object):
1477
1520
  self.fail_json(msg=to_native(e))
1478
1521
 
1479
1522
  def digest_from_file(self, filename, algorithm):
1480
- ''' Return hex digest of local file for a digest_method specified by name, or None if file is not present. '''
1523
+ """ Return hex digest of local file for a digest_method specified by name, or None if file is not present. """
1481
1524
  b_filename = to_bytes(filename, errors='surrogate_or_strict')
1482
1525
 
1483
1526
  if not os.path.exists(b_filename):
@@ -1505,7 +1548,7 @@ class AnsibleModule(object):
1505
1548
  return digest_method.hexdigest()
1506
1549
 
1507
1550
  def md5(self, filename):
1508
- ''' Return MD5 hex digest of local file using digest_from_file().
1551
+ """ Return MD5 hex digest of local file using digest_from_file().
1509
1552
 
1510
1553
  Do not use this function unless you have no other choice for:
1511
1554
  1) Optional backwards compatibility
@@ -1514,21 +1557,21 @@ class AnsibleModule(object):
1514
1557
  This function will not work on systems complying with FIPS-140-2.
1515
1558
 
1516
1559
  Most uses of this function can use the module.sha1 function instead.
1517
- '''
1560
+ """
1518
1561
  if 'md5' not in AVAILABLE_HASH_ALGORITHMS:
1519
1562
  raise ValueError('MD5 not available. Possibly running in FIPS mode')
1520
1563
  return self.digest_from_file(filename, 'md5')
1521
1564
 
1522
1565
  def sha1(self, filename):
1523
- ''' Return SHA1 hex digest of local file using digest_from_file(). '''
1566
+ """ Return SHA1 hex digest of local file using digest_from_file(). """
1524
1567
  return self.digest_from_file(filename, 'sha1')
1525
1568
 
1526
1569
  def sha256(self, filename):
1527
- ''' Return SHA-256 hex digest of local file using digest_from_file(). '''
1570
+ """ Return SHA-256 hex digest of local file using digest_from_file(). """
1528
1571
  return self.digest_from_file(filename, 'sha256')
1529
1572
 
1530
1573
  def backup_local(self, fn):
1531
- '''make a date-marked backup of the specified file, return True or False on success or failure'''
1574
+ """make a date-marked backup of the specified file, return True or False on success or failure"""
1532
1575
 
1533
1576
  backupdest = ''
1534
1577
  if os.path.exists(fn):
@@ -1586,9 +1629,9 @@ class AnsibleModule(object):
1586
1629
  self.set_attributes_if_different(dest, current_attribs, True)
1587
1630
 
1588
1631
  def atomic_move(self, src, dest, unsafe_writes=False, keep_dest_attrs=True):
1589
- '''atomically move src to dest, copying attributes from dest, returns true on success
1632
+ """atomically move src to dest, copying attributes from dest, returns true on success
1590
1633
  it uses os.rename to ensure this as it is an atomic operation, rest of the function is
1591
- to work around limitations, corner cases and ensure selinux context is saved if possible'''
1634
+ to work around limitations, corner cases and ensure selinux context is saved if possible"""
1592
1635
  context = None
1593
1636
  dest_stat = None
1594
1637
  b_src = to_bytes(src, errors='surrogate_or_strict')
@@ -1617,7 +1660,7 @@ class AnsibleModule(object):
1617
1660
  if e.errno not in [errno.EPERM, errno.EXDEV, errno.EACCES, errno.ETXTBSY, errno.EBUSY]:
1618
1661
  # only try workarounds for errno 18 (cross device), 1 (not permitted), 13 (permission denied)
1619
1662
  # and 26 (text file busy) which happens on vagrant synced folders and other 'exotic' non posix file systems
1620
- self.fail_json(msg='Could not replace file: %s to %s: %s' % (src, dest, to_native(e)), exception=traceback.format_exc())
1663
+ self.fail_json(msg='Could not replace file: %s to %s: %s' % (src, dest, to_native(e)))
1621
1664
  else:
1622
1665
  # Use bytes here. In the shippable CI, this fails with
1623
1666
  # a UnicodeError with surrogateescape'd strings for an unknown
@@ -1630,12 +1673,11 @@ class AnsibleModule(object):
1630
1673
  tmp_dest_fd, tmp_dest_name = tempfile.mkstemp(prefix=b'.ansible_tmp', dir=b_dest_dir, suffix=b_suffix)
1631
1674
  except (OSError, IOError) as e:
1632
1675
  error_msg = 'The destination directory (%s) is not writable by the current user. Error was: %s' % (os.path.dirname(dest), to_native(e))
1633
- finally:
1634
- if error_msg:
1635
- if unsafe_writes:
1636
- self._unsafe_writes(b_src, b_dest)
1637
- else:
1638
- self.fail_json(msg=error_msg, exception=traceback.format_exc())
1676
+
1677
+ if unsafe_writes:
1678
+ self._unsafe_writes(b_src, b_dest)
1679
+ else:
1680
+ self.fail_json(msg=error_msg)
1639
1681
 
1640
1682
  if tmp_dest_name:
1641
1683
  b_tmp_dest_name = to_bytes(tmp_dest_name, errors='surrogate_or_strict')
@@ -1674,12 +1716,12 @@ class AnsibleModule(object):
1674
1716
  self._unsafe_writes(b_tmp_dest_name, b_dest)
1675
1717
  else:
1676
1718
  self.fail_json(msg='Unable to make %s into to %s, failed final rename from %s: %s' %
1677
- (src, dest, b_tmp_dest_name, to_native(e)), exception=traceback.format_exc())
1719
+ (src, dest, b_tmp_dest_name, to_native(e)))
1678
1720
  except (shutil.Error, OSError, IOError) as e:
1679
1721
  if unsafe_writes:
1680
1722
  self._unsafe_writes(b_src, b_dest)
1681
1723
  else:
1682
- self.fail_json(msg='Failed to replace file: %s to %s: %s' % (src, dest, to_native(e)), exception=traceback.format_exc())
1724
+ self.fail_json(msg='Failed to replace file: %s to %s: %s' % (src, dest, to_native(e)))
1683
1725
  finally:
1684
1726
  self.cleanup(b_tmp_dest_name)
1685
1727
 
@@ -1719,8 +1761,7 @@ class AnsibleModule(object):
1719
1761
  if in_src:
1720
1762
  in_src.close()
1721
1763
  except (shutil.Error, OSError, IOError) as e:
1722
- self.fail_json(msg='Could not write data to file (%s) from (%s): %s' % (dest, src, to_native(e)),
1723
- exception=traceback.format_exc())
1764
+ self.fail_json(msg='Could not write data to file (%s) from (%s): %s' % (dest, src, to_native(e)))
1724
1765
 
1725
1766
  def _clean_args(self, args):
1726
1767
 
@@ -1756,7 +1797,7 @@ class AnsibleModule(object):
1756
1797
  def run_command(self, args, check_rc=False, close_fds=True, executable=None, data=None, binary_data=False, path_prefix=None, cwd=None,
1757
1798
  use_unsafe_shell=False, prompt_regex=None, environ_update=None, umask=None, encoding='utf-8', errors='surrogate_or_strict',
1758
1799
  expand_user_and_vars=True, pass_fds=None, before_communicate_callback=None, ignore_invalid_cwd=True, handle_exceptions=True):
1759
- '''
1800
+ """
1760
1801
  Execute a command, returns rc, stdout, and stderr.
1761
1802
 
1762
1803
  The mechanism of this method for reading stdout and stderr differs from
@@ -1825,7 +1866,7 @@ class AnsibleModule(object):
1825
1866
  byte strings. On python3, stdout and stderr are text strings converted
1826
1867
  according to the encoding and errors parameters. If you want byte
1827
1868
  strings on python3, use encoding=None to turn decoding to text off.
1828
- '''
1869
+ """
1829
1870
  # used by clean args later on
1830
1871
  self._clean = None
1831
1872
 
@@ -2015,7 +2056,7 @@ class AnsibleModule(object):
2015
2056
  except Exception as e:
2016
2057
  self.log("Error Executing CMD:%s Exception:%s" % (self._clean_args(args), to_native(traceback.format_exc())))
2017
2058
  if handle_exceptions:
2018
- self.fail_json(rc=257, stdout=b'', stderr=b'', msg=to_native(e), exception=traceback.format_exc(), cmd=self._clean_args(args))
2059
+ self.fail_json(rc=257, stdout=b'', stderr=b'', msg=to_native(e), cmd=self._clean_args(args))
2019
2060
  else:
2020
2061
  raise e
2021
2062
 
@@ -2031,9 +2072,8 @@ class AnsibleModule(object):
2031
2072
 
2032
2073
  def append_to_file(self, filename, str):
2033
2074
  filename = os.path.expandvars(os.path.expanduser(filename))
2034
- fh = open(filename, 'a')
2035
- fh.write(str)
2036
- fh.close()
2075
+ with open(filename, 'a') as fh:
2076
+ fh.write(str)
2037
2077
 
2038
2078
  def bytes_to_human(self, size):
2039
2079
  return bytes_to_human(size)
@@ -2072,13 +2112,7 @@ def get_module_path():
2072
2112
 
2073
2113
  def __getattr__(importable_name):
2074
2114
  """Inject import-time deprecation warnings."""
2075
- if importable_name == 'get_exception':
2076
- from ansible.module_utils.pycompat24 import get_exception
2077
- importable = get_exception
2078
- elif importable_name in {'literal_eval', '_literal_eval'}:
2079
- from ast import literal_eval
2080
- importable = literal_eval
2081
- elif importable_name == 'datetime':
2115
+ if importable_name == 'datetime':
2082
2116
  import datetime
2083
2117
  importable = datetime
2084
2118
  elif importable_name == 'signal':