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