ansible-core 2.18.7rc1__py3-none-any.whl → 2.19.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ansible-core might be problematic. Click here for more details.

Files changed (757) hide show
  1. ansible/_internal/__init__.py +53 -0
  2. ansible/_internal/_ansiballz/__init__.py +0 -0
  3. ansible/_internal/_ansiballz/_builder.py +101 -0
  4. ansible/_internal/_ansiballz/_wrapper.py +262 -0
  5. ansible/_internal/_collection_proxy.py +47 -0
  6. ansible/_internal/_datatag/__init__.py +0 -0
  7. ansible/_internal/_datatag/_tags.py +130 -0
  8. ansible/_internal/_datatag/_utils.py +19 -0
  9. ansible/_internal/_datatag/_wrappers.py +33 -0
  10. ansible/_internal/_errors/__init__.py +0 -0
  11. ansible/_internal/_errors/_alarm_timeout.py +66 -0
  12. ansible/_internal/_errors/_captured.py +123 -0
  13. ansible/_internal/_errors/_error_factory.py +89 -0
  14. ansible/_internal/_errors/_error_utils.py +240 -0
  15. ansible/_internal/_errors/_handler.py +91 -0
  16. ansible/_internal/_errors/_task_timeout.py +28 -0
  17. ansible/_internal/_event_formatting.py +127 -0
  18. ansible/_internal/_json/__init__.py +214 -0
  19. ansible/_internal/_json/_legacy_encoder.py +34 -0
  20. ansible/_internal/_json/_profiles/__init__.py +0 -0
  21. ansible/_internal/_json/_profiles/_cache_persistence.py +57 -0
  22. ansible/_internal/_json/_profiles/_inventory_legacy.py +40 -0
  23. ansible/_internal/_json/_profiles/_legacy.py +189 -0
  24. ansible/_internal/_locking.py +21 -0
  25. ansible/_internal/_plugins/__init__.py +0 -0
  26. ansible/_internal/_plugins/_cache.py +57 -0
  27. ansible/_internal/_ssh/__init__.py +0 -0
  28. ansible/_internal/_ssh/_agent_launch.py +91 -0
  29. ansible/_internal/_ssh/_ssh_agent.py +619 -0
  30. ansible/_internal/_task.py +78 -0
  31. ansible/_internal/_templating/__init__.py +12 -0
  32. ansible/_internal/_templating/_access.py +86 -0
  33. ansible/_internal/_templating/_chain_templar.py +63 -0
  34. ansible/_internal/_templating/_datatag.py +95 -0
  35. ansible/_internal/_templating/_engine.py +592 -0
  36. ansible/_internal/_templating/_errors.py +28 -0
  37. ansible/_internal/_templating/_jinja_bits.py +1106 -0
  38. ansible/_internal/_templating/_jinja_common.py +323 -0
  39. ansible/_internal/_templating/_jinja_patches.py +44 -0
  40. ansible/_internal/_templating/_jinja_plugins.py +375 -0
  41. ansible/_internal/_templating/_lazy_containers.py +633 -0
  42. ansible/_internal/_templating/_marker_behaviors.py +103 -0
  43. ansible/_internal/_templating/_template_vars.py +72 -0
  44. ansible/_internal/_templating/_transform.py +70 -0
  45. ansible/_internal/_templating/_utils.py +108 -0
  46. ansible/_internal/_testing.py +26 -0
  47. ansible/_internal/_wrapt.py +1052 -0
  48. ansible/_internal/_yaml/__init__.py +0 -0
  49. ansible/_internal/_yaml/_constructor.py +240 -0
  50. ansible/_internal/_yaml/_dumper.py +70 -0
  51. ansible/_internal/_yaml/_errors.py +166 -0
  52. ansible/_internal/_yaml/_loader.py +66 -0
  53. ansible/_internal/ansible_collections/ansible/_protomatter/README.md +11 -0
  54. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py +36 -0
  55. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py +19 -0
  56. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py +27 -0
  57. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py +16 -0
  58. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py +18 -0
  59. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py +24 -0
  60. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml +33 -0
  61. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py +16 -0
  62. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py +17 -0
  63. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py +49 -0
  64. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py +21 -0
  65. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml +2 -0
  66. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py +15 -0
  67. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml +19 -0
  68. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py +18 -0
  69. ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml +19 -0
  70. ansible/cli/__init__.py +93 -104
  71. ansible/cli/_ssh_askpass.py +54 -0
  72. ansible/cli/adhoc.py +20 -10
  73. ansible/cli/arguments/option_helpers.py +163 -10
  74. ansible/cli/config.py +43 -68
  75. ansible/cli/console.py +13 -11
  76. ansible/cli/doc.py +134 -77
  77. ansible/cli/galaxy.py +27 -20
  78. ansible/cli/inventory.py +28 -28
  79. ansible/cli/playbook.py +4 -12
  80. ansible/cli/pull.py +6 -3
  81. ansible/cli/scripts/ansible_connection_cli_stub.py +7 -7
  82. ansible/cli/vault.py +12 -11
  83. ansible/compat/__init__.py +2 -2
  84. ansible/compat/importlib_resources.py +9 -12
  85. ansible/config/base.yml +218 -133
  86. ansible/config/manager.py +220 -159
  87. ansible/constants.py +2 -65
  88. ansible/errors/__init__.py +350 -256
  89. ansible/executor/interpreter_discovery.py +28 -149
  90. ansible/executor/module_common.py +480 -514
  91. ansible/executor/play_iterator.py +22 -27
  92. ansible/executor/playbook_executor.py +11 -11
  93. ansible/executor/powershell/async_watchdog.ps1 +97 -102
  94. ansible/executor/powershell/async_wrapper.ps1 +204 -153
  95. ansible/executor/powershell/become_wrapper.ps1 +107 -144
  96. ansible/executor/powershell/bootstrap_wrapper.ps1 +46 -9
  97. ansible/executor/powershell/coverage_wrapper.ps1 +91 -135
  98. ansible/executor/powershell/exec_wrapper.ps1 +675 -196
  99. ansible/executor/powershell/module_manifest.py +469 -265
  100. ansible/executor/powershell/module_wrapper.ps1 +195 -186
  101. ansible/executor/powershell/powershell_expand_user.ps1 +20 -0
  102. ansible/executor/powershell/powershell_mkdtemp.ps1 +17 -0
  103. ansible/executor/powershell/psrp_fetch_file.ps1 +41 -0
  104. ansible/executor/powershell/psrp_put_file.ps1 +122 -0
  105. ansible/executor/powershell/winrm_fetch_file.ps1 +46 -0
  106. ansible/executor/powershell/winrm_put_file.ps1 +36 -0
  107. ansible/executor/process/worker.py +139 -149
  108. ansible/executor/stats.py +5 -5
  109. ansible/executor/task_executor.py +270 -297
  110. ansible/executor/task_queue_manager.py +135 -137
  111. ansible/executor/task_result.py +182 -79
  112. ansible/galaxy/__init__.py +2 -2
  113. ansible/galaxy/api.py +26 -25
  114. ansible/galaxy/collection/__init__.py +6 -14
  115. ansible/galaxy/collection/concrete_artifact_manager.py +12 -21
  116. ansible/galaxy/dependency_resolution/dataclasses.py +14 -4
  117. ansible/galaxy/dependency_resolution/providers.py +4 -4
  118. ansible/galaxy/dependency_resolution/reporters.py +81 -0
  119. ansible/galaxy/role.py +6 -10
  120. ansible/galaxy/token.py +28 -21
  121. ansible/inventory/data.py +47 -57
  122. ansible/inventory/group.py +50 -73
  123. ansible/inventory/helpers.py +9 -0
  124. ansible/inventory/host.py +37 -54
  125. ansible/inventory/manager.py +79 -34
  126. ansible/keyword_desc.yml +1 -1
  127. ansible/module_utils/_internal/__init__.py +55 -0
  128. ansible/module_utils/_internal/_ambient_context.py +58 -0
  129. ansible/module_utils/_internal/_ansiballz/__init__.py +0 -0
  130. ansible/module_utils/_internal/_ansiballz/_extensions/__init__.py +0 -0
  131. ansible/module_utils/_internal/_ansiballz/_extensions/_coverage.py +45 -0
  132. ansible/module_utils/_internal/_ansiballz/_extensions/_pydevd.py +62 -0
  133. ansible/module_utils/_internal/_ansiballz/_loader.py +81 -0
  134. ansible/module_utils/_internal/_ansiballz/_respawn.py +32 -0
  135. ansible/module_utils/_internal/_ansiballz/_respawn_wrapper.py +23 -0
  136. ansible/module_utils/_internal/_concurrent/_daemon_threading.py +1 -0
  137. ansible/module_utils/_internal/_dataclass_validation.py +217 -0
  138. ansible/module_utils/_internal/_datatag/__init__.py +961 -0
  139. ansible/module_utils/_internal/_datatag/_tags.py +16 -0
  140. ansible/module_utils/_internal/_debugging.py +31 -0
  141. ansible/module_utils/_internal/_deprecator.py +157 -0
  142. ansible/module_utils/_internal/_errors.py +101 -0
  143. ansible/module_utils/_internal/_event_utils.py +61 -0
  144. ansible/module_utils/_internal/_json/__init__.py +63 -0
  145. ansible/module_utils/_internal/_json/_legacy_encoder.py +26 -0
  146. ansible/module_utils/_internal/_json/_profiles/__init__.py +428 -0
  147. ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py +73 -0
  148. ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py +33 -0
  149. ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py +37 -0
  150. ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py +35 -0
  151. ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py +33 -0
  152. ansible/module_utils/_internal/_json/_profiles/_tagless.py +52 -0
  153. ansible/module_utils/_internal/_messages.py +130 -0
  154. ansible/module_utils/_internal/_patches/__init__.py +66 -0
  155. ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py +53 -0
  156. ansible/module_utils/_internal/_patches/_socket_patch.py +34 -0
  157. ansible/module_utils/_internal/_patches/_sys_intern_patch.py +34 -0
  158. ansible/module_utils/_internal/_plugin_info.py +38 -0
  159. ansible/module_utils/_internal/_stack.py +22 -0
  160. ansible/module_utils/_internal/_testing.py +0 -0
  161. ansible/module_utils/_internal/_text_utils.py +6 -0
  162. ansible/module_utils/_internal/_traceback.py +92 -0
  163. ansible/module_utils/_internal/_validation.py +14 -0
  164. ansible/module_utils/ansible_release.py +2 -2
  165. ansible/module_utils/api.py +1 -2
  166. ansible/module_utils/basic.py +303 -202
  167. ansible/module_utils/common/_utils.py +24 -28
  168. ansible/module_utils/common/arg_spec.py +8 -3
  169. ansible/module_utils/common/collections.py +7 -2
  170. ansible/module_utils/common/dict_transformations.py +2 -2
  171. ansible/module_utils/common/file.py +2 -2
  172. ansible/module_utils/common/json.py +90 -84
  173. ansible/module_utils/common/locale.py +2 -2
  174. ansible/module_utils/common/parameters.py +27 -24
  175. ansible/module_utils/common/process.py +2 -3
  176. ansible/module_utils/common/respawn.py +11 -33
  177. ansible/module_utils/common/sentinel.py +66 -0
  178. ansible/module_utils/common/sys_info.py +8 -8
  179. ansible/module_utils/common/text/converters.py +16 -37
  180. ansible/module_utils/common/validation.py +35 -24
  181. ansible/module_utils/common/warnings.py +143 -25
  182. ansible/module_utils/common/yaml.py +29 -3
  183. ansible/module_utils/compat/datetime.py +33 -21
  184. ansible/module_utils/compat/paramiko.py +21 -10
  185. ansible/module_utils/compat/typing.py +6 -5
  186. ansible/module_utils/connection.py +10 -13
  187. ansible/module_utils/csharp/Ansible.Basic.cs +15 -12
  188. ansible/module_utils/csharp/Ansible.Become.cs +1 -0
  189. ansible/module_utils/csharp/Ansible.Privilege.cs +2 -2
  190. ansible/module_utils/csharp/Ansible._Async.cs +517 -0
  191. ansible/module_utils/datatag.py +49 -0
  192. ansible/module_utils/distro/__init__.py +2 -2
  193. ansible/module_utils/facts/ansible_collector.py +4 -5
  194. ansible/module_utils/facts/collector.py +13 -14
  195. ansible/module_utils/facts/compat.py +4 -4
  196. ansible/module_utils/facts/default_collectors.py +1 -1
  197. ansible/module_utils/facts/hardware/aix.py +34 -0
  198. ansible/module_utils/facts/hardware/base.py +2 -2
  199. ansible/module_utils/facts/hardware/darwin.py +1 -3
  200. ansible/module_utils/facts/hardware/freebsd.py +2 -2
  201. ansible/module_utils/facts/hardware/linux.py +5 -5
  202. ansible/module_utils/facts/namespace.py +1 -1
  203. ansible/module_utils/facts/network/base.py +1 -1
  204. ansible/module_utils/facts/network/fc_wwn.py +1 -2
  205. ansible/module_utils/facts/network/iscsi.py +1 -2
  206. ansible/module_utils/facts/network/nvme.py +1 -2
  207. ansible/module_utils/facts/other/facter.py +2 -3
  208. ansible/module_utils/facts/other/ohai.py +2 -3
  209. ansible/module_utils/facts/sysctl.py +4 -6
  210. ansible/module_utils/facts/system/apparmor.py +1 -2
  211. ansible/module_utils/facts/system/caps.py +3 -3
  212. ansible/module_utils/facts/system/chroot.py +1 -2
  213. ansible/module_utils/facts/system/cmdline.py +1 -2
  214. ansible/module_utils/facts/system/date_time.py +5 -3
  215. ansible/module_utils/facts/system/distribution.py +27 -13
  216. ansible/module_utils/facts/system/dns.py +1 -1
  217. ansible/module_utils/facts/system/env.py +1 -2
  218. ansible/module_utils/facts/system/fips.py +7 -20
  219. ansible/module_utils/facts/system/loadavg.py +1 -2
  220. ansible/module_utils/facts/system/local.py +2 -3
  221. ansible/module_utils/facts/system/lsb.py +1 -2
  222. ansible/module_utils/facts/system/pkg_mgr.py +1 -2
  223. ansible/module_utils/facts/system/platform.py +1 -2
  224. ansible/module_utils/facts/system/python.py +1 -2
  225. ansible/module_utils/facts/system/selinux.py +1 -1
  226. ansible/module_utils/facts/system/service_mgr.py +1 -2
  227. ansible/module_utils/facts/system/ssh_pub_keys.py +1 -1
  228. ansible/module_utils/facts/system/systemd.py +1 -1
  229. ansible/module_utils/facts/system/user.py +1 -2
  230. ansible/module_utils/facts/utils.py +3 -3
  231. ansible/module_utils/facts/virtual/base.py +1 -1
  232. ansible/module_utils/facts/virtual/linux.py +3 -3
  233. ansible/module_utils/facts/virtual/sunos.py +3 -15
  234. ansible/module_utils/facts/virtual/sysctl.py +3 -16
  235. ansible/module_utils/json_utils.py +2 -2
  236. ansible/module_utils/parsing/convert_bool.py +7 -1
  237. ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 +1 -1
  238. ansible/module_utils/powershell/Ansible.ModuleUtils.CamelConversion.psm1 +1 -1
  239. ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 +1 -1
  240. ansible/module_utils/powershell/Ansible.ModuleUtils.WebRequest.psm1 +1 -1
  241. ansible/module_utils/service.py +21 -31
  242. ansible/module_utils/splitter.py +7 -7
  243. ansible/module_utils/testing.py +31 -0
  244. ansible/module_utils/urls.py +64 -35
  245. ansible/modules/add_host.py +4 -4
  246. ansible/modules/apt.py +69 -49
  247. ansible/modules/apt_key.py +19 -12
  248. ansible/modules/apt_repository.py +32 -51
  249. ansible/modules/assemble.py +16 -14
  250. ansible/modules/assert.py +4 -4
  251. ansible/modules/async_status.py +24 -24
  252. ansible/modules/async_wrapper.py +20 -25
  253. ansible/modules/blockinfile.py +6 -7
  254. ansible/modules/command.py +13 -20
  255. ansible/modules/copy.py +60 -147
  256. ansible/modules/cron.py +24 -21
  257. ansible/modules/deb822_repository.py +8 -9
  258. ansible/modules/debconf.py +5 -5
  259. ansible/modules/debug.py +4 -4
  260. ansible/modules/dnf.py +8 -8
  261. ansible/modules/dnf5.py +39 -13
  262. ansible/modules/dpkg_selections.py +4 -4
  263. ansible/modules/expect.py +13 -15
  264. ansible/modules/fail.py +4 -4
  265. ansible/modules/fetch.py +4 -4
  266. ansible/modules/file.py +184 -144
  267. ansible/modules/find.py +22 -20
  268. ansible/modules/gather_facts.py +3 -3
  269. ansible/modules/get_url.py +77 -54
  270. ansible/modules/getent.py +7 -9
  271. ansible/modules/git.py +38 -38
  272. ansible/modules/group.py +6 -6
  273. ansible/modules/group_by.py +4 -4
  274. ansible/modules/hostname.py +15 -32
  275. ansible/modules/import_playbook.py +6 -6
  276. ansible/modules/import_role.py +6 -6
  277. ansible/modules/import_tasks.py +6 -6
  278. ansible/modules/include_role.py +6 -6
  279. ansible/modules/include_tasks.py +6 -6
  280. ansible/modules/include_vars.py +6 -6
  281. ansible/modules/iptables.py +86 -73
  282. ansible/modules/known_hosts.py +22 -24
  283. ansible/modules/lineinfile.py +5 -5
  284. ansible/modules/meta.py +4 -4
  285. ansible/modules/mount_facts.py +2 -2
  286. ansible/modules/package.py +10 -4
  287. ansible/modules/package_facts.py +22 -10
  288. ansible/modules/pause.py +6 -6
  289. ansible/modules/ping.py +6 -6
  290. ansible/modules/pip.py +21 -26
  291. ansible/modules/raw.py +6 -6
  292. ansible/modules/reboot.py +6 -6
  293. ansible/modules/replace.py +10 -14
  294. ansible/modules/rpm_key.py +7 -8
  295. ansible/modules/script.py +4 -4
  296. ansible/modules/service.py +10 -17
  297. ansible/modules/service_facts.py +87 -10
  298. ansible/modules/set_fact.py +5 -5
  299. ansible/modules/set_stats.py +4 -4
  300. ansible/modules/setup.py +2 -2
  301. ansible/modules/shell.py +6 -6
  302. ansible/modules/slurp.py +16 -19
  303. ansible/modules/stat.py +15 -31
  304. ansible/modules/subversion.py +15 -15
  305. ansible/modules/systemd.py +7 -7
  306. ansible/modules/systemd_service.py +7 -7
  307. ansible/modules/sysvinit.py +9 -9
  308. ansible/modules/tempfile.py +5 -6
  309. ansible/modules/template.py +6 -6
  310. ansible/modules/unarchive.py +38 -17
  311. ansible/modules/uri.py +33 -26
  312. ansible/modules/user.py +45 -32
  313. ansible/modules/validate_argument_spec.py +10 -7
  314. ansible/modules/wait_for.py +70 -60
  315. ansible/modules/wait_for_connection.py +6 -6
  316. ansible/modules/yum_repository.py +10 -9
  317. ansible/parsing/ajson.py +17 -37
  318. ansible/parsing/dataloader.py +99 -54
  319. ansible/parsing/mod_args.py +62 -60
  320. ansible/parsing/plugin_docs.py +21 -86
  321. ansible/parsing/quoting.py +1 -1
  322. ansible/parsing/splitter.py +27 -12
  323. ansible/parsing/utils/addresses.py +24 -24
  324. ansible/parsing/utils/jsonify.py +5 -1
  325. ansible/parsing/utils/yaml.py +32 -61
  326. ansible/parsing/vault/__init__.py +327 -99
  327. ansible/parsing/yaml/__init__.py +0 -18
  328. ansible/parsing/yaml/dumper.py +6 -120
  329. ansible/parsing/yaml/loader.py +6 -39
  330. ansible/parsing/yaml/objects.py +43 -335
  331. ansible/playbook/__init__.py +1 -1
  332. ansible/playbook/attribute.py +8 -3
  333. ansible/playbook/base.py +187 -134
  334. ansible/playbook/block.py +26 -24
  335. ansible/playbook/collectionsearch.py +1 -15
  336. ansible/playbook/conditional.py +3 -77
  337. ansible/playbook/handler.py +8 -2
  338. ansible/playbook/helpers.py +41 -53
  339. ansible/playbook/included_file.py +32 -26
  340. ansible/playbook/loop_control.py +2 -2
  341. ansible/playbook/play.py +85 -44
  342. ansible/playbook/play_context.py +14 -17
  343. ansible/playbook/playbook_include.py +27 -62
  344. ansible/playbook/role/__init__.py +64 -49
  345. ansible/playbook/role/definition.py +15 -17
  346. ansible/playbook/role/include.py +2 -4
  347. ansible/playbook/role/metadata.py +10 -11
  348. ansible/playbook/role_include.py +3 -3
  349. ansible/playbook/taggable.py +28 -12
  350. ansible/playbook/task.py +192 -121
  351. ansible/playbook/task_include.py +5 -5
  352. ansible/plugins/__init__.py +58 -26
  353. ansible/plugins/action/__init__.py +188 -186
  354. ansible/plugins/action/add_host.py +2 -2
  355. ansible/plugins/action/assemble.py +11 -18
  356. ansible/plugins/action/assert.py +55 -67
  357. ansible/plugins/action/async_status.py +7 -2
  358. ansible/plugins/action/copy.py +14 -17
  359. ansible/plugins/action/debug.py +37 -31
  360. ansible/plugins/action/dnf.py +3 -4
  361. ansible/plugins/action/fail.py +1 -1
  362. ansible/plugins/action/fetch.py +7 -8
  363. ansible/plugins/action/gather_facts.py +13 -14
  364. ansible/plugins/action/group_by.py +1 -1
  365. ansible/plugins/action/include_vars.py +10 -11
  366. ansible/plugins/action/package.py +8 -14
  367. ansible/plugins/action/pause.py +2 -2
  368. ansible/plugins/action/script.py +27 -38
  369. ansible/plugins/action/service.py +9 -18
  370. ansible/plugins/action/set_fact.py +3 -12
  371. ansible/plugins/action/set_stats.py +3 -8
  372. ansible/plugins/action/template.py +47 -67
  373. ansible/plugins/action/unarchive.py +6 -16
  374. ansible/plugins/action/uri.py +9 -20
  375. ansible/plugins/action/validate_argument_spec.py +5 -5
  376. ansible/plugins/action/wait_for_connection.py +1 -1
  377. ansible/plugins/become/__init__.py +31 -8
  378. ansible/plugins/become/runas.py +71 -0
  379. ansible/plugins/become/su.py +13 -8
  380. ansible/plugins/become/sudo.py +19 -0
  381. ansible/plugins/cache/__init__.py +52 -63
  382. ansible/plugins/cache/base.py +8 -0
  383. ansible/plugins/cache/jsonfile.py +10 -16
  384. ansible/plugins/cache/memory.py +6 -12
  385. ansible/plugins/callback/__init__.py +294 -201
  386. ansible/plugins/callback/default.py +99 -95
  387. ansible/plugins/callback/junit.py +44 -43
  388. ansible/plugins/callback/minimal.py +28 -25
  389. ansible/plugins/callback/oneline.py +34 -21
  390. ansible/plugins/callback/tree.py +27 -16
  391. ansible/plugins/connection/__init__.py +47 -34
  392. ansible/plugins/connection/local.py +156 -60
  393. ansible/plugins/connection/paramiko_ssh.py +34 -24
  394. ansible/plugins/connection/psrp.py +76 -165
  395. ansible/plugins/connection/ssh.py +326 -86
  396. ansible/plugins/connection/winrm.py +62 -141
  397. ansible/plugins/doc_fragments/action_common_attributes.py +14 -14
  398. ansible/plugins/doc_fragments/action_core.py +6 -6
  399. ansible/plugins/doc_fragments/backup.py +2 -2
  400. ansible/plugins/doc_fragments/checksum_common.py +27 -0
  401. ansible/plugins/doc_fragments/constructed.py +8 -4
  402. ansible/plugins/doc_fragments/decrypt.py +2 -2
  403. ansible/plugins/doc_fragments/default_callback.py +2 -2
  404. ansible/plugins/doc_fragments/files.py +2 -2
  405. ansible/plugins/doc_fragments/inventory_cache.py +2 -2
  406. ansible/plugins/doc_fragments/result_format_callback.py +2 -2
  407. ansible/plugins/doc_fragments/return_common.py +2 -2
  408. ansible/plugins/doc_fragments/template_common.py +4 -4
  409. ansible/plugins/doc_fragments/url.py +17 -1
  410. ansible/plugins/doc_fragments/url_windows.py +2 -2
  411. ansible/plugins/doc_fragments/validate.py +2 -2
  412. ansible/plugins/doc_fragments/vars_plugin_staging.py +2 -2
  413. ansible/plugins/filter/__init__.py +6 -2
  414. ansible/plugins/filter/b64decode.yml +22 -0
  415. ansible/plugins/filter/b64encode.yml +22 -0
  416. ansible/plugins/filter/bool.yml +11 -4
  417. ansible/plugins/filter/core.py +245 -120
  418. ansible/plugins/filter/encryption.py +42 -34
  419. ansible/plugins/filter/flatten.yml +3 -2
  420. ansible/plugins/filter/human_to_bytes.yml +1 -1
  421. ansible/plugins/filter/mathstuff.py +30 -37
  422. ansible/plugins/filter/password_hash.yml +8 -0
  423. ansible/plugins/filter/pow.yml +1 -1
  424. ansible/plugins/filter/regex_search.yml +1 -4
  425. ansible/plugins/filter/root.yml +1 -1
  426. ansible/plugins/filter/split.yml +1 -1
  427. ansible/plugins/filter/strftime.yml +3 -3
  428. ansible/plugins/filter/to_nice_yaml.yml +0 -4
  429. ansible/plugins/filter/to_uuid.yml +1 -1
  430. ansible/plugins/filter/to_yaml.yml +0 -4
  431. ansible/plugins/filter/unvault.yml +1 -1
  432. ansible/plugins/filter/urls.py +1 -1
  433. ansible/plugins/filter/urlsplit.py +8 -9
  434. ansible/plugins/filter/vault.yml +14 -9
  435. ansible/plugins/filter/win_basename.yml +6 -1
  436. ansible/plugins/filter/win_dirname.yml +5 -0
  437. ansible/plugins/inventory/__init__.py +107 -86
  438. ansible/plugins/inventory/advanced_host_list.py +7 -5
  439. ansible/plugins/inventory/auto.py +11 -4
  440. ansible/plugins/inventory/constructed.py +21 -24
  441. ansible/plugins/inventory/generator.py +16 -11
  442. ansible/plugins/inventory/host_list.py +7 -5
  443. ansible/plugins/inventory/ini.py +78 -44
  444. ansible/plugins/inventory/script.py +190 -120
  445. ansible/plugins/inventory/toml.py +16 -126
  446. ansible/plugins/inventory/yaml.py +10 -8
  447. ansible/plugins/list.py +72 -19
  448. ansible/plugins/loader.py +383 -198
  449. ansible/plugins/lookup/__init__.py +21 -4
  450. ansible/plugins/lookup/config.py +21 -35
  451. ansible/plugins/lookup/csvfile.py +19 -73
  452. ansible/plugins/lookup/dict.py +1 -6
  453. ansible/plugins/lookup/env.py +12 -9
  454. ansible/plugins/lookup/file.py +5 -8
  455. ansible/plugins/lookup/first_found.py +87 -55
  456. ansible/plugins/lookup/indexed_items.py +1 -10
  457. ansible/plugins/lookup/ini.py +14 -13
  458. ansible/plugins/lookup/items.py +1 -1
  459. ansible/plugins/lookup/lines.py +8 -1
  460. ansible/plugins/lookup/list.py +1 -1
  461. ansible/plugins/lookup/nested.py +2 -18
  462. ansible/plugins/lookup/password.py +5 -5
  463. ansible/plugins/lookup/pipe.py +5 -7
  464. ansible/plugins/lookup/sequence.py +18 -8
  465. ansible/plugins/lookup/subelements.py +1 -4
  466. ansible/plugins/lookup/template.py +47 -36
  467. ansible/plugins/lookup/together.py +0 -12
  468. ansible/plugins/lookup/unvault.py +1 -5
  469. ansible/plugins/lookup/url.py +4 -10
  470. ansible/plugins/lookup/vars.py +16 -24
  471. ansible/plugins/shell/__init__.py +58 -4
  472. ansible/plugins/shell/cmd.py +2 -2
  473. ansible/plugins/shell/powershell.py +106 -31
  474. ansible/plugins/shell/sh.py +13 -7
  475. ansible/plugins/strategy/__init__.py +168 -193
  476. ansible/plugins/strategy/debug.py +2 -2
  477. ansible/plugins/strategy/free.py +16 -31
  478. ansible/plugins/strategy/host_pinned.py +2 -2
  479. ansible/plugins/strategy/linear.py +41 -41
  480. ansible/plugins/terminal/__init__.py +4 -4
  481. ansible/plugins/test/__init__.py +7 -2
  482. ansible/plugins/test/core.py +75 -35
  483. ansible/plugins/test/files.py +1 -1
  484. ansible/plugins/test/finished.yml +1 -1
  485. ansible/plugins/test/mathstuff.py +3 -3
  486. ansible/plugins/test/uri.py +5 -8
  487. ansible/plugins/vars/host_group_vars.py +7 -14
  488. ansible/release.py +2 -2
  489. ansible/template/__init__.py +353 -943
  490. ansible/utils/__init__.py +0 -18
  491. ansible/utils/collection_loader/__init__.py +54 -5
  492. ansible/utils/collection_loader/_collection_config.py +5 -6
  493. ansible/utils/collection_loader/_collection_finder.py +82 -96
  494. ansible/utils/collection_loader/_collection_meta.py +15 -8
  495. ansible/utils/display.py +485 -73
  496. ansible/utils/encrypt.py +27 -19
  497. ansible/utils/fqcn.py +2 -2
  498. ansible/utils/galaxy.py +2 -2
  499. ansible/utils/hashing.py +8 -10
  500. ansible/utils/helpers.py +2 -2
  501. ansible/utils/listify.py +10 -8
  502. ansible/utils/lock.py +2 -2
  503. ansible/utils/path.py +10 -12
  504. ansible/utils/plugin_docs.py +16 -14
  505. ansible/utils/py3compat.py +2 -7
  506. ansible/utils/sentinel.py +4 -62
  507. ansible/utils/singleton.py +2 -0
  508. ansible/utils/ssh_functions.py +6 -2
  509. ansible/utils/unsafe_proxy.py +23 -332
  510. ansible/utils/vars.py +55 -8
  511. ansible/utils/version.py +2 -2
  512. ansible/vars/clean.py +5 -5
  513. ansible/vars/hostvars.py +60 -90
  514. ansible/vars/manager.py +220 -285
  515. ansible/vars/plugins.py +4 -4
  516. ansible/vars/reserved.py +13 -12
  517. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/METADATA +4 -3
  518. ansible_core-2.19.0.dist-info/RECORD +1097 -0
  519. ansible_core-2.19.0.dist-info/licenses/licenses/BSD-3-Clause.txt +28 -0
  520. ansible_test/_data/completion/docker.txt +7 -7
  521. ansible_test/_data/completion/remote.txt +6 -6
  522. ansible_test/_data/completion/windows.txt +1 -0
  523. ansible_test/_data/requirements/ansible.txt +2 -2
  524. ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
  525. ansible_test/_data/requirements/sanity.changelog.txt +2 -2
  526. ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
  527. ansible_test/_data/requirements/sanity.pep8.txt +1 -1
  528. ansible_test/_data/requirements/sanity.pylint.txt +5 -5
  529. ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
  530. ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
  531. ansible_test/_data/requirements/units.txt +1 -0
  532. ansible_test/_internal/__init__.py +6 -0
  533. ansible_test/_internal/ansible_util.py +3 -1
  534. ansible_test/_internal/become.py +1 -0
  535. ansible_test/_internal/bootstrap.py +1 -0
  536. ansible_test/_internal/cache.py +1 -0
  537. ansible_test/_internal/cgroup.py +1 -0
  538. ansible_test/_internal/ci/__init__.py +1 -0
  539. ansible_test/_internal/ci/azp.py +1 -0
  540. ansible_test/_internal/ci/local.py +1 -0
  541. ansible_test/_internal/classification/__init__.py +1 -0
  542. ansible_test/_internal/classification/common.py +1 -0
  543. ansible_test/_internal/classification/csharp.py +1 -0
  544. ansible_test/_internal/classification/powershell.py +1 -0
  545. ansible_test/_internal/classification/python.py +1 -0
  546. ansible_test/_internal/cli/__init__.py +1 -0
  547. ansible_test/_internal/cli/actions.py +1 -0
  548. ansible_test/_internal/cli/argparsing/__init__.py +1 -0
  549. ansible_test/_internal/cli/argparsing/actions.py +1 -0
  550. ansible_test/_internal/cli/argparsing/argcompletion.py +1 -0
  551. ansible_test/_internal/cli/argparsing/parsers.py +1 -0
  552. ansible_test/_internal/cli/commands/__init__.py +11 -5
  553. ansible_test/_internal/cli/commands/coverage/__init__.py +1 -0
  554. ansible_test/_internal/cli/commands/coverage/analyze/__init__.py +1 -0
  555. ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py +1 -0
  556. ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py +1 -0
  557. ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py +1 -0
  558. ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py +1 -0
  559. ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py +1 -0
  560. ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py +1 -0
  561. ansible_test/_internal/cli/commands/coverage/combine.py +1 -0
  562. ansible_test/_internal/cli/commands/coverage/erase.py +1 -0
  563. ansible_test/_internal/cli/commands/coverage/html.py +1 -0
  564. ansible_test/_internal/cli/commands/coverage/report.py +1 -0
  565. ansible_test/_internal/cli/commands/coverage/xml.py +1 -0
  566. ansible_test/_internal/cli/commands/env.py +1 -0
  567. ansible_test/_internal/cli/commands/integration/__init__.py +1 -0
  568. ansible_test/_internal/cli/commands/integration/network.py +1 -0
  569. ansible_test/_internal/cli/commands/integration/posix.py +1 -0
  570. ansible_test/_internal/cli/commands/integration/windows.py +1 -0
  571. ansible_test/_internal/cli/commands/sanity.py +9 -0
  572. ansible_test/_internal/cli/commands/shell.py +1 -0
  573. ansible_test/_internal/cli/commands/units.py +1 -0
  574. ansible_test/_internal/cli/compat.py +1 -0
  575. ansible_test/_internal/cli/completers.py +1 -0
  576. ansible_test/_internal/cli/converters.py +1 -0
  577. ansible_test/_internal/cli/environments.py +52 -5
  578. ansible_test/_internal/cli/epilog.py +1 -0
  579. ansible_test/_internal/cli/parsers/__init__.py +1 -0
  580. ansible_test/_internal/cli/parsers/base_argument_parsers.py +1 -0
  581. ansible_test/_internal/cli/parsers/helpers.py +1 -0
  582. ansible_test/_internal/cli/parsers/host_config_parsers.py +1 -0
  583. ansible_test/_internal/cli/parsers/key_value_parsers.py +1 -0
  584. ansible_test/_internal/cli/parsers/value_parsers.py +1 -0
  585. ansible_test/_internal/commands/__init__.py +1 -0
  586. ansible_test/_internal/commands/coverage/__init__.py +3 -2
  587. ansible_test/_internal/commands/coverage/analyze/__init__.py +1 -0
  588. ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +1 -0
  589. ansible_test/_internal/commands/coverage/analyze/targets/combine.py +1 -0
  590. ansible_test/_internal/commands/coverage/analyze/targets/expand.py +1 -0
  591. ansible_test/_internal/commands/coverage/analyze/targets/filter.py +1 -0
  592. ansible_test/_internal/commands/coverage/analyze/targets/generate.py +1 -0
  593. ansible_test/_internal/commands/coverage/analyze/targets/missing.py +1 -0
  594. ansible_test/_internal/commands/coverage/combine.py +2 -1
  595. ansible_test/_internal/commands/coverage/erase.py +1 -0
  596. ansible_test/_internal/commands/coverage/html.py +1 -0
  597. ansible_test/_internal/commands/coverage/report.py +1 -0
  598. ansible_test/_internal/commands/coverage/xml.py +1 -0
  599. ansible_test/_internal/commands/env/__init__.py +2 -0
  600. ansible_test/_internal/commands/integration/__init__.py +22 -5
  601. ansible_test/_internal/commands/integration/cloud/__init__.py +1 -0
  602. ansible_test/_internal/commands/integration/cloud/acme.py +2 -1
  603. ansible_test/_internal/commands/integration/cloud/aws.py +1 -0
  604. ansible_test/_internal/commands/integration/cloud/azure.py +1 -0
  605. ansible_test/_internal/commands/integration/cloud/cs.py +1 -0
  606. ansible_test/_internal/commands/integration/cloud/digitalocean.py +1 -0
  607. ansible_test/_internal/commands/integration/cloud/galaxy.py +3 -2
  608. ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -0
  609. ansible_test/_internal/commands/integration/cloud/httptester.py +3 -2
  610. ansible_test/_internal/commands/integration/cloud/nios.py +2 -1
  611. ansible_test/_internal/commands/integration/cloud/opennebula.py +1 -0
  612. ansible_test/_internal/commands/integration/cloud/openshift.py +1 -0
  613. ansible_test/_internal/commands/integration/cloud/scaleway.py +1 -0
  614. ansible_test/_internal/commands/integration/cloud/vcenter.py +1 -0
  615. ansible_test/_internal/commands/integration/cloud/vultr.py +1 -0
  616. ansible_test/_internal/commands/integration/coverage.py +8 -2
  617. ansible_test/_internal/commands/integration/filters.py +1 -0
  618. ansible_test/_internal/commands/integration/network.py +1 -0
  619. ansible_test/_internal/commands/integration/posix.py +1 -0
  620. ansible_test/_internal/commands/integration/windows.py +1 -0
  621. ansible_test/_internal/commands/sanity/__init__.py +19 -2
  622. ansible_test/_internal/commands/sanity/ansible_doc.py +1 -0
  623. ansible_test/_internal/commands/sanity/bin_symlinks.py +1 -0
  624. ansible_test/_internal/commands/sanity/compile.py +1 -0
  625. ansible_test/_internal/commands/sanity/ignores.py +1 -0
  626. ansible_test/_internal/commands/sanity/import.py +1 -0
  627. ansible_test/_internal/commands/sanity/integration_aliases.py +12 -0
  628. ansible_test/_internal/commands/sanity/pep8.py +1 -0
  629. ansible_test/_internal/commands/sanity/pslint.py +1 -0
  630. ansible_test/_internal/commands/sanity/pylint.py +25 -26
  631. ansible_test/_internal/commands/sanity/shellcheck.py +1 -0
  632. ansible_test/_internal/commands/sanity/validate_modules.py +1 -0
  633. ansible_test/_internal/commands/sanity/yamllint.py +1 -0
  634. ansible_test/_internal/commands/shell/__init__.py +44 -4
  635. ansible_test/_internal/commands/units/__init__.py +5 -1
  636. ansible_test/_internal/compat/__init__.py +1 -0
  637. ansible_test/_internal/compat/packaging.py +1 -0
  638. ansible_test/_internal/compat/yaml.py +1 -0
  639. ansible_test/_internal/completion.py +1 -0
  640. ansible_test/_internal/config.py +23 -13
  641. ansible_test/_internal/connections.py +1 -0
  642. ansible_test/_internal/constants.py +1 -0
  643. ansible_test/_internal/containers.py +1 -0
  644. ansible_test/_internal/content_config.py +1 -0
  645. ansible_test/_internal/core_ci.py +1 -0
  646. ansible_test/_internal/coverage_util.py +11 -10
  647. ansible_test/_internal/data.py +1 -0
  648. ansible_test/_internal/debugging.py +166 -0
  649. ansible_test/_internal/delegation.py +22 -13
  650. ansible_test/_internal/dev/__init__.py +1 -0
  651. ansible_test/_internal/dev/container_probe.py +1 -0
  652. ansible_test/_internal/diff.py +3 -2
  653. ansible_test/_internal/docker_util.py +2 -1
  654. ansible_test/_internal/encoding.py +1 -0
  655. ansible_test/_internal/executor.py +1 -0
  656. ansible_test/_internal/git.py +1 -0
  657. ansible_test/_internal/host_configs.py +1 -0
  658. ansible_test/_internal/host_profiles.py +260 -16
  659. ansible_test/_internal/http.py +1 -0
  660. ansible_test/_internal/init.py +1 -0
  661. ansible_test/_internal/inventory.py +39 -3
  662. ansible_test/_internal/io.py +1 -0
  663. ansible_test/_internal/metadata.py +95 -4
  664. ansible_test/_internal/payload.py +1 -0
  665. ansible_test/_internal/processes.py +80 -0
  666. ansible_test/_internal/provider/__init__.py +1 -0
  667. ansible_test/_internal/provider/layout/__init__.py +1 -0
  668. ansible_test/_internal/provider/layout/ansible.py +1 -0
  669. ansible_test/_internal/provider/layout/collection.py +1 -0
  670. ansible_test/_internal/provider/layout/unsupported.py +1 -0
  671. ansible_test/_internal/provider/source/__init__.py +1 -0
  672. ansible_test/_internal/provider/source/git.py +1 -0
  673. ansible_test/_internal/provider/source/installed.py +1 -0
  674. ansible_test/_internal/provider/source/unsupported.py +1 -0
  675. ansible_test/_internal/provider/source/unversioned.py +1 -0
  676. ansible_test/_internal/provisioning.py +11 -4
  677. ansible_test/_internal/pypi_proxy.py +6 -5
  678. ansible_test/_internal/python_requirements.py +28 -0
  679. ansible_test/_internal/ssh.py +2 -5
  680. ansible_test/_internal/target.py +9 -0
  681. ansible_test/_internal/test.py +3 -2
  682. ansible_test/_internal/thread.py +3 -1
  683. ansible_test/_internal/timeout.py +2 -1
  684. ansible_test/_internal/util.py +41 -12
  685. ansible_test/_internal/util_common.py +18 -5
  686. ansible_test/_internal/venv.py +1 -0
  687. ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +1 -0
  688. ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py +1 -0
  689. ansible_test/_util/controller/sanity/code-smell/changelog.py +1 -0
  690. ansible_test/_util/controller/sanity/code-smell/empty-init.py +1 -0
  691. ansible_test/_util/controller/sanity/code-smell/line-endings.py +1 -0
  692. ansible_test/_util/controller/sanity/code-smell/no-assert.py +1 -0
  693. ansible_test/_util/controller/sanity/code-smell/no-get-exception.py +1 -0
  694. ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py +1 -0
  695. ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py +1 -0
  696. ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py +1 -0
  697. ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +28 -1
  698. ansible_test/_util/controller/sanity/code-smell/shebang.py +1 -0
  699. ansible_test/_util/controller/sanity/code-smell/symlinks.py +1 -0
  700. ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py +1 -0
  701. ansible_test/_util/controller/sanity/code-smell/use-compat-six.py +1 -0
  702. ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py +2 -1
  703. ansible_test/_util/controller/sanity/pep8/current-ignore.txt +4 -0
  704. ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +8 -5
  705. ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +8 -5
  706. ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +8 -5
  707. ansible_test/_util/controller/sanity/pylint/config/collection.cfg +4 -5
  708. ansible_test/_util/controller/sanity/pylint/config/default.cfg +8 -7
  709. ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +541 -0
  710. ansible_test/_util/controller/sanity/pylint/plugins/deprecated_comment.py +137 -0
  711. ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py +1 -0
  712. ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +1 -8
  713. ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +1 -8
  714. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +55 -28
  715. ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +12 -5
  716. ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +13 -2
  717. ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -0
  718. ansible_test/_util/controller/sanity/yamllint/yamllinter.py +35 -17
  719. ansible_test/_util/controller/tools/collection_detail.py +1 -0
  720. ansible_test/_util/controller/tools/yaml_to_json.py +2 -1
  721. ansible_test/_util/target/injector/python.py +8 -0
  722. ansible_test/_util/target/pytest/plugins/ansible_forked.py +6 -1
  723. ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py +2 -1
  724. ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +1 -0
  725. ansible_test/_util/target/sanity/compile/compile.py +1 -0
  726. ansible_test/_util/target/sanity/import/importer.py +15 -16
  727. ansible_test/_util/target/setup/bootstrap.sh +9 -20
  728. ansible_test/_util/target/setup/probe_cgroups.py +1 -0
  729. ansible_test/_util/target/setup/quiet_pip.py +1 -0
  730. ansible_test/_util/target/setup/requirements.py +38 -36
  731. ansible_test/_util/target/tools/virtualenvcheck.py +2 -1
  732. ansible_test/_util/target/tools/yamlcheck.py +2 -1
  733. ansible/compat/selectors.py +0 -32
  734. ansible/errors/yaml_strings.py +0 -138
  735. ansible/executor/action_write_locks.py +0 -44
  736. ansible/executor/discovery/python_target.py +0 -47
  737. ansible/executor/powershell/module_powershell_wrapper.ps1 +0 -86
  738. ansible/executor/powershell/module_script_wrapper.ps1 +0 -22
  739. ansible/module_utils/compat/importlib.py +0 -26
  740. ansible/module_utils/compat/selectors.py +0 -32
  741. ansible/module_utils/pycompat24.py +0 -73
  742. ansible/parsing/yaml/constructor.py +0 -178
  743. ansible/template/native_helpers.py +0 -251
  744. ansible/template/template.py +0 -43
  745. ansible/template/vars.py +0 -77
  746. ansible/utils/native_jinja.py +0 -11
  747. ansible/vars/fact_cache.py +0 -71
  748. ansible_core-2.18.7rc1.dist-info/RECORD +0 -992
  749. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +0 -411
  750. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/WHEEL +0 -0
  751. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/entry_points.txt +0 -0
  752. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/COPYING +0 -0
  753. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/Apache-License.txt +0 -0
  754. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/MIT-license.txt +0 -0
  755. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/PSF-license.txt +0 -0
  756. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
  757. {ansible_core-2.18.7rc1.dist-info → ansible_core-2.19.0.dist-info}/top_level.txt +0 -0
@@ -4,6 +4,7 @@
4
4
  from __future__ import annotations
5
5
 
6
6
  import base64
7
+ import functools
7
8
  import glob
8
9
  import hashlib
9
10
  import json
@@ -11,31 +12,34 @@ import ntpath
11
12
  import os.path
12
13
  import re
13
14
  import shlex
14
- import sys
15
15
  import time
16
16
  import uuid
17
17
  import yaml
18
18
  import datetime
19
+ import typing as t
19
20
 
20
21
  from collections.abc import Mapping
21
22
  from functools import partial
22
23
  from random import Random, SystemRandom, shuffle
23
24
 
24
- from jinja2.filters import pass_environment
25
+ from jinja2.filters import do_map, do_select, do_selectattr, do_reject, do_rejectattr, pass_environment, sync_do_groupby
26
+ from jinja2.environment import Environment
25
27
 
26
- from ansible.errors import AnsibleError, AnsibleFilterError, AnsibleFilterTypeError
27
- from ansible.module_utils.six import string_types, integer_types, reraise, text_type
28
+ from ansible._internal._templating import _lazy_containers
29
+ from ansible.errors import AnsibleFilterError, AnsibleTypeError, AnsibleTemplatePluginError
30
+ from ansible.module_utils.datatag import native_type_name
31
+ from ansible.module_utils.common.json import get_encoder, get_decoder
32
+ from ansible.module_utils.six import string_types, integer_types, text_type
28
33
  from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
29
34
  from ansible.module_utils.common.collections import is_sequence
30
- from ansible.module_utils.common.yaml import yaml_load, yaml_load_all
31
- from ansible.parsing.ajson import AnsibleJSONEncoder
32
35
  from ansible.parsing.yaml.dumper import AnsibleDumper
33
- from ansible.template import recursive_check_defined
36
+ from ansible.template import accept_args_markers, accept_lazy_markers
37
+ from ansible._internal._templating._jinja_common import MarkerError, UndefinedMarker, validate_arg_type
38
+ from ansible._internal._yaml import _loader as _yaml_loader
34
39
  from ansible.utils.display import Display
35
40
  from ansible.utils.encrypt import do_encrypt, PASSLIB_AVAILABLE
36
41
  from ansible.utils.hashing import md5s, checksum_s
37
42
  from ansible.utils.unicode import unicode_wrap
38
- from ansible.utils.unsafe_proxy import _is_unsafe
39
43
  from ansible.utils.vars import merge_hash
40
44
 
41
45
  display = Display()
@@ -43,53 +47,84 @@ display = Display()
43
47
  UUID_NAMESPACE_ANSIBLE = uuid.UUID('361E6D51-FAEC-444A-9079-341386DA8E2E')
44
48
 
45
49
 
46
- def to_yaml(a, *args, **kw):
47
- '''Make verbose, human-readable yaml'''
48
- default_flow_style = kw.pop('default_flow_style', None)
49
- try:
50
- transformed = yaml.dump(a, Dumper=AnsibleDumper, allow_unicode=True, default_flow_style=default_flow_style, **kw)
51
- except Exception as e:
52
- raise AnsibleFilterError("to_yaml - %s" % to_native(e), orig_exc=e)
53
- return to_text(transformed)
50
+ @accept_lazy_markers
51
+ def to_yaml(a, *_args, default_flow_style: bool | None = None, **kwargs) -> str:
52
+ """Serialize input as terse flow-style YAML."""
53
+ return yaml.dump(a, Dumper=AnsibleDumper, allow_unicode=True, default_flow_style=default_flow_style, **kwargs)
54
54
 
55
55
 
56
- def to_nice_yaml(a, indent=4, *args, **kw):
57
- '''Make verbose, human-readable yaml'''
58
- try:
59
- transformed = yaml.dump(a, Dumper=AnsibleDumper, indent=indent, allow_unicode=True, default_flow_style=False, **kw)
60
- except Exception as e:
61
- raise AnsibleFilterError("to_nice_yaml - %s" % to_native(e), orig_exc=e)
62
- return to_text(transformed)
56
+ @accept_lazy_markers
57
+ def to_nice_yaml(a, indent=4, *_args, default_flow_style=False, **kwargs) -> str:
58
+ """Serialize input as verbose multi-line YAML."""
59
+ return to_yaml(a, indent=indent, default_flow_style=default_flow_style, **kwargs)
60
+
61
+
62
+ def from_json(a, profile: str | None = None, **kwargs) -> t.Any:
63
+ """Deserialize JSON with an optional decoder profile."""
64
+ cls = get_decoder(profile or "tagless")
65
+
66
+ return json.loads(a, cls=cls, **kwargs)
67
+
68
+
69
+ def to_json(a, profile: str | None = None, vault_to_text: t.Any = ..., preprocess_unsafe: t.Any = ..., **kwargs) -> str:
70
+ """Serialize as JSON with an optional encoder profile."""
63
71
 
72
+ if profile and vault_to_text is not ...:
73
+ raise ValueError("Only one of `vault_to_text` or `profile` can be specified.")
64
74
 
65
- def to_json(a, *args, **kw):
66
- ''' Convert the value to JSON '''
75
+ if profile and preprocess_unsafe is not ...:
76
+ raise ValueError("Only one of `preprocess_unsafe` or `profile` can be specified.")
67
77
 
68
- # defaults for filters
69
- if 'vault_to_text' not in kw:
70
- kw['vault_to_text'] = True
71
- if 'preprocess_unsafe' not in kw:
72
- kw['preprocess_unsafe'] = False
78
+ # deprecated: description='deprecate vault_to_text' core_version='2.23'
79
+ # deprecated: description='deprecate preprocess_unsafe' core_version='2.23'
73
80
 
74
- return json.dumps(a, cls=AnsibleJSONEncoder, *args, **kw)
81
+ cls = get_encoder(profile or "tagless")
75
82
 
83
+ return json.dumps(a, cls=cls, **kwargs)
76
84
 
77
- def to_nice_json(a, indent=4, sort_keys=True, *args, **kw):
78
- '''Make verbose, human-readable JSON'''
85
+
86
+ def to_nice_json(a, indent=4, sort_keys=True, **kwargs):
87
+ """Make verbose, human-readable JSON."""
79
88
  # TODO separators can be potentially exposed to the user as well
80
- kw.pop('separators', None)
81
- return to_json(a, indent=indent, sort_keys=sort_keys, separators=(',', ': '), *args, **kw)
89
+ kwargs.pop('separators', None)
90
+ return to_json(a, indent=indent, sort_keys=sort_keys, separators=(',', ': '), **kwargs)
91
+
92
+
93
+ # CAUTION: Do not put non-string values here since they can have unwanted logical equality, such as 1.0 (equal to 1 and True) or 0.0 (equal to 0 and False).
94
+ _valid_bool_true = {'yes', 'on', 'true', '1'}
95
+ _valid_bool_false = {'no', 'off', 'false', '0'}
96
+
97
+
98
+ def to_bool(value: object) -> bool:
99
+ """Convert well-known input values to a boolean value."""
100
+ value_to_check: object
101
+
102
+ if isinstance(value, str):
103
+ value_to_check = value.lower() # accept mixed case variants
104
+ elif isinstance(value, int): # bool is also an int
105
+ value_to_check = str(value).lower() # accept int (0, 1) and bool (True, False) -- not just string versions
106
+ else:
107
+ value_to_check = value
108
+
109
+ try:
110
+ if value_to_check in _valid_bool_true:
111
+ return True
112
+
113
+ if value_to_check in _valid_bool_false:
114
+ return False
82
115
 
116
+ # if we're still here, the value is unsupported- always fire a deprecation warning
117
+ result = value_to_check == 1 # backwards compatibility with the old code which checked: value in ('yes', 'on', '1', 'true', 1)
118
+ except TypeError:
119
+ result = False
83
120
 
84
- def to_bool(a):
85
- ''' return a bool for the arg '''
86
- if a is None or isinstance(a, bool):
87
- return a
88
- if isinstance(a, string_types):
89
- a = a.lower()
90
- if a in ('yes', 'on', '1', 'true', 1):
91
- return True
92
- return False
121
+ # NB: update the doc string to reflect reality once this fallback is removed
122
+ display.deprecated(
123
+ msg=f'The `bool` filter coerced invalid value {value!r} ({native_type_name(value)}) to {result!r}.',
124
+ version='2.23',
125
+ )
126
+
127
+ return result
93
128
 
94
129
 
95
130
  def to_datetime(string, format="%Y-%m-%d %H:%M:%S"):
@@ -97,7 +132,7 @@ def to_datetime(string, format="%Y-%m-%d %H:%M:%S"):
97
132
 
98
133
 
99
134
  def strftime(string_format, second=None, utc=False):
100
- ''' return a date string using string. See https://docs.python.org/3/library/time.html#time.strftime for format '''
135
+ """ return a date string using string. See https://docs.python.org/3/library/time.html#time.strftime for format """
101
136
  if utc:
102
137
  timefn = time.gmtime
103
138
  else:
@@ -111,19 +146,19 @@ def strftime(string_format, second=None, utc=False):
111
146
 
112
147
 
113
148
  def quote(a):
114
- ''' return its argument quoted for shell usage '''
149
+ """ return its argument quoted for shell usage """
115
150
  if a is None:
116
151
  a = u''
117
152
  return shlex.quote(to_text(a))
118
153
 
119
154
 
120
155
  def fileglob(pathname):
121
- ''' return list of matched regular files for glob '''
156
+ """ return list of matched regular files for glob """
122
157
  return [g for g in glob.glob(pathname) if os.path.isfile(g)]
123
158
 
124
159
 
125
160
  def regex_replace(value='', pattern='', replacement='', ignorecase=False, multiline=False, count=0, mandatory_count=0):
126
- ''' Perform a `re.sub` returning a string '''
161
+ """ Perform a `re.sub` returning a string """
127
162
 
128
163
  value = to_text(value, errors='surrogate_or_strict', nonstring='simplerepr')
129
164
 
@@ -141,7 +176,7 @@ def regex_replace(value='', pattern='', replacement='', ignorecase=False, multil
141
176
 
142
177
 
143
178
  def regex_findall(value, regex, multiline=False, ignorecase=False):
144
- ''' Perform re.findall and return the list of matches '''
179
+ """ Perform re.findall and return the list of matches """
145
180
 
146
181
  value = to_text(value, errors='surrogate_or_strict', nonstring='simplerepr')
147
182
 
@@ -154,7 +189,7 @@ def regex_findall(value, regex, multiline=False, ignorecase=False):
154
189
 
155
190
 
156
191
  def regex_search(value, regex, *args, **kwargs):
157
- ''' Perform re.search and return the list of matches or a backref '''
192
+ """ Perform re.search and return the list of matches or a backref """
158
193
 
159
194
  value = to_text(value, errors='surrogate_or_strict', nonstring='simplerepr')
160
195
 
@@ -187,7 +222,7 @@ def regex_search(value, regex, *args, **kwargs):
187
222
 
188
223
 
189
224
  def ternary(value, true_val, false_val, none_val=None):
190
- ''' value ? true_val : false_val '''
225
+ """ value ? true_val : false_val """
191
226
  if value is None and none_val is not None:
192
227
  return none_val
193
228
  elif bool(value):
@@ -216,24 +251,24 @@ def regex_escape(string, re_type='python'):
216
251
 
217
252
 
218
253
  def from_yaml(data):
219
- if isinstance(data, string_types):
220
- # The ``text_type`` call here strips any custom
221
- # string wrapper class, so that CSafeLoader can
222
- # read the data
223
- if _is_unsafe(data):
224
- data = data._strip_unsafe()
225
- return yaml_load(text_type(to_text(data, errors='surrogate_or_strict')))
254
+ if data is None:
255
+ return None
256
+
257
+ if isinstance(data, str):
258
+ return yaml.load(data, Loader=_yaml_loader.AnsibleInstrumentedLoader) # type: ignore[arg-type]
259
+
260
+ display.deprecated(f"The from_yaml filter ignored non-string input of type {native_type_name(data)!r}.", version='2.23', obj=data)
226
261
  return data
227
262
 
228
263
 
229
264
  def from_yaml_all(data):
230
- if isinstance(data, string_types):
231
- # The ``text_type`` call here strips any custom
232
- # string wrapper class, so that CSafeLoader can
233
- # read the data
234
- if _is_unsafe(data):
235
- data = data._strip_unsafe()
236
- return yaml_load_all(text_type(to_text(data, errors='surrogate_or_strict')))
265
+ if data is None:
266
+ return [] # backward compatibility; ensure consistent result between classic/native Jinja for None/empty string input
267
+
268
+ if isinstance(data, str):
269
+ return yaml.load_all(data, Loader=_yaml_loader.AnsibleInstrumentedLoader) # type: ignore[arg-type]
270
+
271
+ display.deprecated(f"The from_yaml_all filter ignored non-string input of type {native_type_name(data)!r}.", version='2.23', obj=data)
237
272
  return data
238
273
 
239
274
 
@@ -291,26 +326,10 @@ def get_encrypted_password(password, hashtype='sha512', salt=None, salt_size=Non
291
326
 
292
327
  hashtype = passlib_mapping.get(hashtype, hashtype)
293
328
 
294
- unknown_passlib_hashtype = False
295
329
  if PASSLIB_AVAILABLE and hashtype not in passlib_mapping and hashtype not in passlib_mapping.values():
296
- unknown_passlib_hashtype = True
297
- display.deprecated(
298
- f"Checking for unsupported password_hash passlib hashtype '{hashtype}'. "
299
- "This will be an error in the future as all supported hashtypes must be documented.",
300
- version='2.19'
301
- )
330
+ raise AnsibleFilterError(f"{hashtype} is not in the list of supported passlib algorithms: {', '.join(passlib_mapping)}")
302
331
 
303
- try:
304
- return do_encrypt(password, hashtype, salt=salt, salt_size=salt_size, rounds=rounds, ident=ident)
305
- except AnsibleError as e:
306
- reraise(AnsibleFilterError, AnsibleFilterError(to_native(e), orig_exc=e), sys.exc_info()[2])
307
- except Exception as e:
308
- if unknown_passlib_hashtype:
309
- # This can occur if passlib.hash has the hashtype attribute, but it has a different signature than the valid choices.
310
- # In 2.19 this will replace the deprecation warning above and the extra exception handling can be deleted.
311
- choices = ', '.join(passlib_mapping)
312
- raise AnsibleFilterError(f"{hashtype} is not in the list of supported passlib algorithms: {choices}") from e
313
- raise
332
+ return do_encrypt(password, hashtype, salt=salt, salt_size=salt_size, rounds=rounds, ident=ident)
314
333
 
315
334
 
316
335
  def to_uuid(string, namespace=UUID_NAMESPACE_ANSIBLE):
@@ -324,19 +343,21 @@ def to_uuid(string, namespace=UUID_NAMESPACE_ANSIBLE):
324
343
  return to_text(uuid.uuid5(uuid_namespace, to_native(string, errors='surrogate_or_strict')))
325
344
 
326
345
 
327
- def mandatory(a, msg=None):
346
+ @accept_args_markers
347
+ def mandatory(a: object, msg: str | None = None) -> object:
328
348
  """Make a variable mandatory."""
329
- from jinja2.runtime import Undefined
349
+ # DTFIX-FUTURE: deprecate this filter; there are much better ways via undef, etc...
350
+ # also remember to remove unit test checking for _undefined_name
351
+ if isinstance(a, UndefinedMarker):
352
+ if msg is not None:
353
+ raise AnsibleFilterError(to_text(msg))
330
354
 
331
- if isinstance(a, Undefined):
332
355
  if a._undefined_name is not None:
333
- name = "'%s' " % to_text(a._undefined_name)
356
+ name = f'{to_text(a._undefined_name)!r} '
334
357
  else:
335
358
  name = ''
336
359
 
337
- if msg is not None:
338
- raise AnsibleFilterError(to_native(msg))
339
- raise AnsibleFilterError("Mandatory variable %s not defined." % name)
360
+ raise AnsibleFilterError(f"Mandatory variable {name}not defined.")
340
361
 
341
362
  return a
342
363
 
@@ -350,9 +371,6 @@ def combine(*terms, **kwargs):
350
371
  # allow the user to do `[dict1, dict2, ...] | combine`
351
372
  dictionaries = flatten(terms, levels=1)
352
373
 
353
- # recursively check that every elements are defined (for jinja2)
354
- recursive_check_defined(dictionaries)
355
-
356
374
  if not dictionaries:
357
375
  return {}
358
376
 
@@ -398,6 +416,13 @@ def comment(text, style='plain', **kw):
398
416
  }
399
417
  }
400
418
 
419
+ if style not in comment_styles:
420
+ raise AnsibleTemplatePluginError(
421
+ message=f"Invalid style {style!r}.",
422
+ help_text=f"Available styles: {', '.join(comment_styles)}",
423
+ obj=style,
424
+ )
425
+
401
426
  # Pointer to the right comment type
402
427
  style_params = comment_styles[style]
403
428
 
@@ -458,7 +483,7 @@ def comment(text, style='plain', **kw):
458
483
 
459
484
 
460
485
  @pass_environment
461
- def extract(environment, item, container, morekeys=None):
486
+ def extract(environment: Environment, item, container, morekeys=None):
462
487
  if morekeys is None:
463
488
  keys = [item]
464
489
  elif isinstance(morekeys, list):
@@ -467,18 +492,28 @@ def extract(environment, item, container, morekeys=None):
467
492
  keys = [item, morekeys]
468
493
 
469
494
  value = container
495
+
470
496
  for key in keys:
471
- value = environment.getitem(value, key)
497
+ try:
498
+ value = environment.getitem(value, key)
499
+ except MarkerError as ex:
500
+ value = ex.source
472
501
 
473
502
  return value
474
503
 
475
504
 
476
- def b64encode(string, encoding='utf-8'):
477
- return to_text(base64.b64encode(to_bytes(string, encoding=encoding, errors='surrogate_or_strict')))
505
+ def b64encode(string, encoding='utf-8', urlsafe=False):
506
+ func = base64.b64encode
507
+ if urlsafe:
508
+ func = base64.urlsafe_b64encode
509
+ return to_text(func(to_bytes(string, encoding=encoding, errors='surrogate_or_strict')))
478
510
 
479
511
 
480
- def b64decode(string, encoding='utf-8'):
481
- return to_text(base64.b64decode(to_bytes(string, errors='surrogate_or_strict')), encoding=encoding)
512
+ def b64decode(string, encoding='utf-8', urlsafe=False):
513
+ func = base64.b64decode
514
+ if urlsafe:
515
+ func = base64.urlsafe_b64decode
516
+ return to_text(func(to_bytes(string, errors='surrogate_or_strict')), encoding=encoding)
482
517
 
483
518
 
484
519
  def flatten(mylist, levels=None, skip_nulls=True):
@@ -503,14 +538,14 @@ def flatten(mylist, levels=None, skip_nulls=True):
503
538
 
504
539
 
505
540
  def subelements(obj, subelements, skip_missing=False):
506
- '''Accepts a dict or list of dicts, and a dotted accessor and produces a product
541
+ """Accepts a dict or list of dicts, and a dotted accessor and produces a product
507
542
  of the element and the results of the dotted accessor
508
543
 
509
544
  >>> obj = [{"name": "alice", "groups": ["wheel"], "authorized": ["/tmp/alice/onekey.pub"]}]
510
545
  >>> subelements(obj, 'groups')
511
546
  [({'name': 'alice', 'groups': ['wheel'], 'authorized': ['/tmp/alice/onekey.pub']}, 'wheel')]
512
547
 
513
- '''
548
+ """
514
549
  if isinstance(obj, dict):
515
550
  element_list = list(obj.values())
516
551
  elif isinstance(obj, list):
@@ -523,7 +558,7 @@ def subelements(obj, subelements, skip_missing=False):
523
558
  elif isinstance(subelements, string_types):
524
559
  subelement_list = subelements.split('.')
525
560
  else:
526
- raise AnsibleFilterTypeError('subelements must be a list or a string')
561
+ raise AnsibleTypeError('subelements must be a list or a string')
527
562
 
528
563
  results = []
529
564
 
@@ -537,10 +572,10 @@ def subelements(obj, subelements, skip_missing=False):
537
572
  values = []
538
573
  break
539
574
  raise AnsibleFilterError("could not find %r key in iterated item %r" % (subelement, values))
540
- except TypeError:
541
- raise AnsibleFilterTypeError("the key %s should point to a dictionary, got '%s'" % (subelement, values))
575
+ except TypeError as ex:
576
+ raise AnsibleTypeError("the key %s should point to a dictionary, got '%s'" % (subelement, values)) from ex
542
577
  if not isinstance(values, list):
543
- raise AnsibleFilterTypeError("the key %r should point to a list, got %r" % (subelement, values))
578
+ raise AnsibleTypeError("the key %r should point to a list, got %r" % (subelement, values))
544
579
 
545
580
  for value in values:
546
581
  results.append((element, value))
@@ -549,11 +584,11 @@ def subelements(obj, subelements, skip_missing=False):
549
584
 
550
585
 
551
586
  def dict_to_list_of_dict_key_value_elements(mydict, key_name='key', value_name='value'):
552
- ''' takes a dictionary and transforms it into a list of dictionaries,
553
- with each having a 'key' and 'value' keys that correspond to the keys and values of the original '''
587
+ """ takes a dictionary and transforms it into a list of dictionaries,
588
+ with each having a 'key' and 'value' keys that correspond to the keys and values of the original """
554
589
 
555
590
  if not isinstance(mydict, Mapping):
556
- raise AnsibleFilterTypeError("dict2items requires a dictionary, got %s instead." % type(mydict))
591
+ raise AnsibleTypeError("dict2items requires a dictionary, got %s instead." % type(mydict))
557
592
 
558
593
  ret = []
559
594
  for key in mydict:
@@ -562,31 +597,31 @@ def dict_to_list_of_dict_key_value_elements(mydict, key_name='key', value_name='
562
597
 
563
598
 
564
599
  def list_of_dict_key_value_elements_to_dict(mylist, key_name='key', value_name='value'):
565
- ''' takes a list of dicts with each having a 'key' and 'value' keys, and transforms the list into a dictionary,
566
- effectively as the reverse of dict2items '''
600
+ """ takes a list of dicts with each having a 'key' and 'value' keys, and transforms the list into a dictionary,
601
+ effectively as the reverse of dict2items """
567
602
 
568
603
  if not is_sequence(mylist):
569
- raise AnsibleFilterTypeError("items2dict requires a list, got %s instead." % type(mylist))
604
+ raise AnsibleTypeError("items2dict requires a list, got %s instead." % type(mylist))
570
605
 
571
606
  try:
572
607
  return dict((item[key_name], item[value_name]) for item in mylist)
573
608
  except KeyError:
574
- raise AnsibleFilterTypeError(
609
+ raise AnsibleTypeError(
575
610
  "items2dict requires each dictionary in the list to contain the keys '%s' and '%s', got %s instead."
576
611
  % (key_name, value_name, mylist)
577
612
  )
578
613
  except TypeError:
579
- raise AnsibleFilterTypeError("items2dict requires a list of dictionaries, got %s instead." % mylist)
614
+ raise AnsibleTypeError("items2dict requires a list of dictionaries, got %s instead." % mylist)
580
615
 
581
616
 
582
617
  def path_join(paths):
583
- ''' takes a sequence or a string, and return a concatenation
584
- of the different members '''
618
+ """ takes a sequence or a string, and return a concatenation
619
+ of the different members """
585
620
  if isinstance(paths, string_types):
586
621
  return os.path.join(paths)
587
622
  if is_sequence(paths):
588
623
  return os.path.join(*paths)
589
- raise AnsibleFilterTypeError("|path_join expects string or sequence, got %s instead." % type(paths))
624
+ raise AnsibleTypeError("|path_join expects string or sequence, got %s instead." % type(paths))
590
625
 
591
626
 
592
627
  def commonpath(paths):
@@ -599,13 +634,92 @@ def commonpath(paths):
599
634
  :rtype: str
600
635
  """
601
636
  if not is_sequence(paths):
602
- raise AnsibleFilterTypeError("|commonpath expects sequence, got %s instead." % type(paths))
637
+ raise AnsibleTypeError("|commonpath expects sequence, got %s instead." % type(paths))
603
638
 
604
639
  return os.path.commonpath(paths)
605
640
 
606
641
 
642
+ class GroupTuple(t.NamedTuple):
643
+ """
644
+ Custom named tuple for the groupby filter with a public interface; silently ignored by unknown type checks.
645
+ This matches the internal implementation of the _GroupTuple returned by Jinja's built-in groupby filter.
646
+ """
647
+
648
+ grouper: t.Any
649
+ list: list[t.Any]
650
+
651
+ def __repr__(self) -> str:
652
+ return tuple.__repr__(self)
653
+
654
+
655
+ _lazy_containers.register_known_types(GroupTuple)
656
+
657
+
658
+ @pass_environment
659
+ def _cleansed_groupby(*args, **kwargs):
660
+ res = sync_do_groupby(*args, **kwargs)
661
+ res = [GroupTuple(grouper=g.grouper, list=g.list) for g in res]
662
+
663
+ return res
664
+
665
+ # DTFIX-FUTURE: make these dumb wrappers more dynamic
666
+
667
+
668
+ @accept_args_markers
669
+ def ansible_default(
670
+ value: t.Any,
671
+ default_value: t.Any = '',
672
+ boolean: bool = False,
673
+ ) -> t.Any:
674
+ """Updated `default` filter that only coalesces classic undefined objects; other Undefined-derived types (eg, ErrorMarker) pass through."""
675
+ validate_arg_type('boolean', boolean, bool)
676
+
677
+ if isinstance(value, UndefinedMarker):
678
+ return default_value
679
+
680
+ if boolean and not value:
681
+ return default_value
682
+
683
+ return value
684
+
685
+
686
+ @accept_lazy_markers
687
+ @functools.wraps(do_map)
688
+ def wrapped_map(*args, **kwargs) -> t.Any:
689
+ return do_map(*args, **kwargs)
690
+
691
+
692
+ @accept_lazy_markers
693
+ @functools.wraps(do_select)
694
+ def wrapped_select(*args, **kwargs) -> t.Any:
695
+ return do_select(*args, **kwargs)
696
+
697
+
698
+ @accept_lazy_markers
699
+ @functools.wraps(do_selectattr)
700
+ def wrapped_selectattr(*args, **kwargs) -> t.Any:
701
+ return do_selectattr(*args, **kwargs)
702
+
703
+
704
+ @accept_lazy_markers
705
+ @functools.wraps(do_reject)
706
+ def wrapped_reject(*args, **kwargs) -> t.Any:
707
+ return do_reject(*args, **kwargs)
708
+
709
+
710
+ @accept_lazy_markers
711
+ @functools.wraps(do_rejectattr)
712
+ def wrapped_rejectattr(*args, **kwargs) -> t.Any:
713
+ return do_rejectattr(*args, **kwargs)
714
+
715
+
716
+ @accept_args_markers
717
+ def type_debug(obj: object) -> str:
718
+ return native_type_name(obj)
719
+
720
+
607
721
  class FilterModule(object):
608
- ''' Ansible core jinja2 filters '''
722
+ """ Ansible core jinja2 filters """
609
723
 
610
724
  def filters(self):
611
725
  return {
@@ -619,7 +733,7 @@ class FilterModule(object):
619
733
  # json
620
734
  'to_json': to_json,
621
735
  'to_nice_json': to_nice_json,
622
- 'from_json': json.loads,
736
+ 'from_json': from_json,
623
737
 
624
738
  # yaml
625
739
  'to_yaml': to_yaml,
@@ -686,7 +800,7 @@ class FilterModule(object):
686
800
  'comment': comment,
687
801
 
688
802
  # debug
689
- 'type_debug': lambda o: o.__class__.__name__,
803
+ 'type_debug': type_debug,
690
804
 
691
805
  # Data structures
692
806
  'combine': combine,
@@ -696,4 +810,15 @@ class FilterModule(object):
696
810
  'items2dict': list_of_dict_key_value_elements_to_dict,
697
811
  'subelements': subelements,
698
812
  'split': partial(unicode_wrap, text_type.split),
813
+ # FDI038 - replace this with a standard type compat shim
814
+ 'groupby': _cleansed_groupby,
815
+
816
+ # Jinja builtins that need special arg handling
817
+ 'd': ansible_default, # replaces the implementation instead of wrapping it
818
+ 'default': ansible_default, # replaces the implementation instead of wrapping it
819
+ 'map': wrapped_map,
820
+ 'select': wrapped_select,
821
+ 'selectattr': wrapped_selectattr,
822
+ 'reject': wrapped_reject,
823
+ 'rejectattr': wrapped_rejectattr,
699
824
  }