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,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
35
  from ansible.module_utils.common.yaml import yaml_load, yaml_load_all
31
- from ansible.parsing.ajson import AnsibleJSONEncoder
32
36
  from ansible.parsing.yaml.dumper import AnsibleDumper
33
- from ansible.template import recursive_check_defined
37
+ from ansible.plugins import accept_args_markers, accept_lazy_markers
38
+ from ansible._internal._templating._jinja_common import MarkerError, UndefinedMarker, validate_arg_type
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,77 @@ 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
+ def to_yaml(a, *_args, default_flow_style: bool | None = None, dump_vault_tags: bool | None = None, **kwargs) -> str:
51
+ """Serialize input as terse flow-style YAML."""
52
+ dumper = partial(AnsibleDumper, dump_vault_tags=dump_vault_tags)
54
53
 
54
+ return yaml.dump(a, Dumper=dumper, allow_unicode=True, default_flow_style=default_flow_style, **kwargs)
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
+
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)
63
67
 
64
68
 
65
- def to_json(a, *args, **kw):
66
- ''' Convert the value to JSON '''
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."""
67
71
 
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
72
+ if profile and vault_to_text is not ...:
73
+ raise ValueError("Only one of `vault_to_text` or `profile` can be specified.")
73
74
 
74
- return json.dumps(a, cls=AnsibleJSONEncoder, *args, **kw)
75
+ if profile and preprocess_unsafe is not ...:
76
+ raise ValueError("Only one of `preprocess_unsafe` or `profile` can be specified.")
75
77
 
78
+ # deprecated: description='deprecate vault_to_text' core_version='2.23'
79
+ # deprecated: description='deprecate preprocess_unsafe' core_version='2.23'
76
80
 
77
- def to_nice_json(a, indent=4, sort_keys=True, *args, **kw):
78
- '''Make verbose, human-readable JSON'''
81
+ cls = get_encoder(profile or "tagless")
82
+
83
+ return json.dumps(a, cls=cls, **kwargs)
84
+
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
+
82
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'}
83
96
 
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):
97
+
98
+ def to_bool(value: object) -> bool:
99
+ """Convert well-known input values to a boolean value."""
100
+ value_to_check: object
101
+ if isinstance(value, str):
102
+ value_to_check = value.lower() # accept mixed case variants
103
+ elif isinstance(value, int): # bool is also an int
104
+ value_to_check = str(value).lower() # accept int (0, 1) and bool (True, False) -- not just string versions
105
+ else:
106
+ value_to_check = value
107
+
108
+ if value_to_check in _valid_bool_true:
91
109
  return True
92
- return False
110
+
111
+ if value_to_check in _valid_bool_false:
112
+ return False
113
+
114
+ # if we're still here, the value is unsupported- always fire a deprecation warning
115
+ result = value_to_check == 1 # backwards compatibility with the old code which checked: value in ('yes', 'on', '1', 'true', 1)
116
+
117
+ # NB: update the doc string to reflect reality once this fallback is removed
118
+ display.deprecated(f'The `bool` filter coerced invalid value {value!r} ({native_type_name(value)}) to {result!r}.', version='2.23')
119
+
120
+ return result
93
121
 
94
122
 
95
123
  def to_datetime(string, format="%Y-%m-%d %H:%M:%S"):
@@ -97,7 +125,7 @@ def to_datetime(string, format="%Y-%m-%d %H:%M:%S"):
97
125
 
98
126
 
99
127
  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 '''
128
+ """ return a date string using string. See https://docs.python.org/3/library/time.html#time.strftime for format """
101
129
  if utc:
102
130
  timefn = time.gmtime
103
131
  else:
@@ -111,19 +139,19 @@ def strftime(string_format, second=None, utc=False):
111
139
 
112
140
 
113
141
  def quote(a):
114
- ''' return its argument quoted for shell usage '''
142
+ """ return its argument quoted for shell usage """
115
143
  if a is None:
116
144
  a = u''
117
145
  return shlex.quote(to_text(a))
118
146
 
119
147
 
120
148
  def fileglob(pathname):
121
- ''' return list of matched regular files for glob '''
149
+ """ return list of matched regular files for glob """
122
150
  return [g for g in glob.glob(pathname) if os.path.isfile(g)]
123
151
 
124
152
 
125
153
  def regex_replace(value='', pattern='', replacement='', ignorecase=False, multiline=False, count=0, mandatory_count=0):
126
- ''' Perform a `re.sub` returning a string '''
154
+ """ Perform a `re.sub` returning a string """
127
155
 
128
156
  value = to_text(value, errors='surrogate_or_strict', nonstring='simplerepr')
129
157
 
@@ -141,7 +169,7 @@ def regex_replace(value='', pattern='', replacement='', ignorecase=False, multil
141
169
 
142
170
 
143
171
  def regex_findall(value, regex, multiline=False, ignorecase=False):
144
- ''' Perform re.findall and return the list of matches '''
172
+ """ Perform re.findall and return the list of matches """
145
173
 
146
174
  value = to_text(value, errors='surrogate_or_strict', nonstring='simplerepr')
147
175
 
@@ -154,7 +182,7 @@ def regex_findall(value, regex, multiline=False, ignorecase=False):
154
182
 
155
183
 
156
184
  def regex_search(value, regex, *args, **kwargs):
157
- ''' Perform re.search and return the list of matches or a backref '''
185
+ """ Perform re.search and return the list of matches or a backref """
158
186
 
159
187
  value = to_text(value, errors='surrogate_or_strict', nonstring='simplerepr')
160
188
 
@@ -187,7 +215,7 @@ def regex_search(value, regex, *args, **kwargs):
187
215
 
188
216
 
189
217
  def ternary(value, true_val, false_val, none_val=None):
190
- ''' value ? true_val : false_val '''
218
+ """ value ? true_val : false_val """
191
219
  if value is None and none_val is not None:
192
220
  return none_val
193
221
  elif bool(value):
@@ -220,8 +248,6 @@ def from_yaml(data):
220
248
  # The ``text_type`` call here strips any custom
221
249
  # string wrapper class, so that CSafeLoader can
222
250
  # read the data
223
- if _is_unsafe(data):
224
- data = data._strip_unsafe()
225
251
  return yaml_load(text_type(to_text(data, errors='surrogate_or_strict')))
226
252
  return data
227
253
 
@@ -231,8 +257,6 @@ def from_yaml_all(data):
231
257
  # The ``text_type`` call here strips any custom
232
258
  # string wrapper class, so that CSafeLoader can
233
259
  # read the data
234
- if _is_unsafe(data):
235
- data = data._strip_unsafe()
236
260
  return yaml_load_all(text_type(to_text(data, errors='surrogate_or_strict')))
237
261
  return data
238
262
 
@@ -291,26 +315,10 @@ def get_encrypted_password(password, hashtype='sha512', salt=None, salt_size=Non
291
315
 
292
316
  hashtype = passlib_mapping.get(hashtype, hashtype)
293
317
 
294
- unknown_passlib_hashtype = False
295
318
  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
- )
319
+ raise AnsibleFilterError(f"{hashtype} is not in the list of supported passlib algorithms: {', '.join(passlib_mapping)}")
302
320
 
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
321
+ return do_encrypt(password, hashtype, salt=salt, salt_size=salt_size, rounds=rounds, ident=ident)
314
322
 
315
323
 
316
324
  def to_uuid(string, namespace=UUID_NAMESPACE_ANSIBLE):
@@ -324,19 +332,21 @@ def to_uuid(string, namespace=UUID_NAMESPACE_ANSIBLE):
324
332
  return to_text(uuid.uuid5(uuid_namespace, to_native(string, errors='surrogate_or_strict')))
325
333
 
326
334
 
327
- def mandatory(a, msg=None):
335
+ @accept_args_markers
336
+ def mandatory(a: object, msg: str | None = None) -> object:
328
337
  """Make a variable mandatory."""
329
- from jinja2.runtime import Undefined
338
+ # DTFIX-RELEASE: deprecate this filter; there are much better ways via undef, etc...
339
+ # also remember to remove unit test checking for _undefined_name
340
+ if isinstance(a, UndefinedMarker):
341
+ if msg is not None:
342
+ raise AnsibleFilterError(to_text(msg))
330
343
 
331
- if isinstance(a, Undefined):
332
344
  if a._undefined_name is not None:
333
- name = "'%s' " % to_text(a._undefined_name)
345
+ name = f'{to_text(a._undefined_name)!r} '
334
346
  else:
335
347
  name = ''
336
348
 
337
- if msg is not None:
338
- raise AnsibleFilterError(to_native(msg))
339
- raise AnsibleFilterError("Mandatory variable %s not defined." % name)
349
+ raise AnsibleFilterError(f"Mandatory variable {name}not defined.")
340
350
 
341
351
  return a
342
352
 
@@ -350,9 +360,6 @@ def combine(*terms, **kwargs):
350
360
  # allow the user to do `[dict1, dict2, ...] | combine`
351
361
  dictionaries = flatten(terms, levels=1)
352
362
 
353
- # recursively check that every elements are defined (for jinja2)
354
- recursive_check_defined(dictionaries)
355
-
356
363
  if not dictionaries:
357
364
  return {}
358
365
 
@@ -398,6 +405,13 @@ def comment(text, style='plain', **kw):
398
405
  }
399
406
  }
400
407
 
408
+ if style not in comment_styles:
409
+ raise AnsibleTemplatePluginError(
410
+ message=f"Invalid style {style!r}.",
411
+ help_text=f"Available styles: {', '.join(comment_styles)}",
412
+ obj=style,
413
+ )
414
+
401
415
  # Pointer to the right comment type
402
416
  style_params = comment_styles[style]
403
417
 
@@ -458,7 +472,7 @@ def comment(text, style='plain', **kw):
458
472
 
459
473
 
460
474
  @pass_environment
461
- def extract(environment, item, container, morekeys=None):
475
+ def extract(environment: Environment, item, container, morekeys=None):
462
476
  if morekeys is None:
463
477
  keys = [item]
464
478
  elif isinstance(morekeys, list):
@@ -467,18 +481,28 @@ def extract(environment, item, container, morekeys=None):
467
481
  keys = [item, morekeys]
468
482
 
469
483
  value = container
484
+
470
485
  for key in keys:
471
- value = environment.getitem(value, key)
486
+ try:
487
+ value = environment.getitem(value, key)
488
+ except MarkerError as ex:
489
+ value = ex.source
472
490
 
473
491
  return value
474
492
 
475
493
 
476
- def b64encode(string, encoding='utf-8'):
477
- return to_text(base64.b64encode(to_bytes(string, encoding=encoding, errors='surrogate_or_strict')))
494
+ def b64encode(string, encoding='utf-8', urlsafe=False):
495
+ func = base64.b64encode
496
+ if urlsafe:
497
+ func = base64.urlsafe_b64encode
498
+ return to_text(func(to_bytes(string, encoding=encoding, errors='surrogate_or_strict')))
478
499
 
479
500
 
480
- def b64decode(string, encoding='utf-8'):
481
- return to_text(base64.b64decode(to_bytes(string, errors='surrogate_or_strict')), encoding=encoding)
501
+ def b64decode(string, encoding='utf-8', urlsafe=False):
502
+ func = base64.b64decode
503
+ if urlsafe:
504
+ func = base64.urlsafe_b64decode
505
+ return to_text(func(to_bytes(string, errors='surrogate_or_strict')), encoding=encoding)
482
506
 
483
507
 
484
508
  def flatten(mylist, levels=None, skip_nulls=True):
@@ -503,14 +527,14 @@ def flatten(mylist, levels=None, skip_nulls=True):
503
527
 
504
528
 
505
529
  def subelements(obj, subelements, skip_missing=False):
506
- '''Accepts a dict or list of dicts, and a dotted accessor and produces a product
530
+ """Accepts a dict or list of dicts, and a dotted accessor and produces a product
507
531
  of the element and the results of the dotted accessor
508
532
 
509
533
  >>> obj = [{"name": "alice", "groups": ["wheel"], "authorized": ["/tmp/alice/onekey.pub"]}]
510
534
  >>> subelements(obj, 'groups')
511
535
  [({'name': 'alice', 'groups': ['wheel'], 'authorized': ['/tmp/alice/onekey.pub']}, 'wheel')]
512
536
 
513
- '''
537
+ """
514
538
  if isinstance(obj, dict):
515
539
  element_list = list(obj.values())
516
540
  elif isinstance(obj, list):
@@ -523,7 +547,7 @@ def subelements(obj, subelements, skip_missing=False):
523
547
  elif isinstance(subelements, string_types):
524
548
  subelement_list = subelements.split('.')
525
549
  else:
526
- raise AnsibleFilterTypeError('subelements must be a list or a string')
550
+ raise AnsibleTypeError('subelements must be a list or a string')
527
551
 
528
552
  results = []
529
553
 
@@ -537,10 +561,10 @@ def subelements(obj, subelements, skip_missing=False):
537
561
  values = []
538
562
  break
539
563
  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))
564
+ except TypeError as ex:
565
+ raise AnsibleTypeError("the key %s should point to a dictionary, got '%s'" % (subelement, values)) from ex
542
566
  if not isinstance(values, list):
543
- raise AnsibleFilterTypeError("the key %r should point to a list, got %r" % (subelement, values))
567
+ raise AnsibleTypeError("the key %r should point to a list, got %r" % (subelement, values))
544
568
 
545
569
  for value in values:
546
570
  results.append((element, value))
@@ -549,11 +573,11 @@ def subelements(obj, subelements, skip_missing=False):
549
573
 
550
574
 
551
575
  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 '''
576
+ """ takes a dictionary and transforms it into a list of dictionaries,
577
+ with each having a 'key' and 'value' keys that correspond to the keys and values of the original """
554
578
 
555
579
  if not isinstance(mydict, Mapping):
556
- raise AnsibleFilterTypeError("dict2items requires a dictionary, got %s instead." % type(mydict))
580
+ raise AnsibleTypeError("dict2items requires a dictionary, got %s instead." % type(mydict))
557
581
 
558
582
  ret = []
559
583
  for key in mydict:
@@ -562,31 +586,31 @@ def dict_to_list_of_dict_key_value_elements(mydict, key_name='key', value_name='
562
586
 
563
587
 
564
588
  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 '''
589
+ """ takes a list of dicts with each having a 'key' and 'value' keys, and transforms the list into a dictionary,
590
+ effectively as the reverse of dict2items """
567
591
 
568
592
  if not is_sequence(mylist):
569
- raise AnsibleFilterTypeError("items2dict requires a list, got %s instead." % type(mylist))
593
+ raise AnsibleTypeError("items2dict requires a list, got %s instead." % type(mylist))
570
594
 
571
595
  try:
572
596
  return dict((item[key_name], item[value_name]) for item in mylist)
573
597
  except KeyError:
574
- raise AnsibleFilterTypeError(
598
+ raise AnsibleTypeError(
575
599
  "items2dict requires each dictionary in the list to contain the keys '%s' and '%s', got %s instead."
576
600
  % (key_name, value_name, mylist)
577
601
  )
578
602
  except TypeError:
579
- raise AnsibleFilterTypeError("items2dict requires a list of dictionaries, got %s instead." % mylist)
603
+ raise AnsibleTypeError("items2dict requires a list of dictionaries, got %s instead." % mylist)
580
604
 
581
605
 
582
606
  def path_join(paths):
583
- ''' takes a sequence or a string, and return a concatenation
584
- of the different members '''
607
+ """ takes a sequence or a string, and return a concatenation
608
+ of the different members """
585
609
  if isinstance(paths, string_types):
586
610
  return os.path.join(paths)
587
611
  if is_sequence(paths):
588
612
  return os.path.join(*paths)
589
- raise AnsibleFilterTypeError("|path_join expects string or sequence, got %s instead." % type(paths))
613
+ raise AnsibleTypeError("|path_join expects string or sequence, got %s instead." % type(paths))
590
614
 
591
615
 
592
616
  def commonpath(paths):
@@ -599,13 +623,92 @@ def commonpath(paths):
599
623
  :rtype: str
600
624
  """
601
625
  if not is_sequence(paths):
602
- raise AnsibleFilterTypeError("|commonpath expects sequence, got %s instead." % type(paths))
626
+ raise AnsibleTypeError("|commonpath expects sequence, got %s instead." % type(paths))
603
627
 
604
628
  return os.path.commonpath(paths)
605
629
 
606
630
 
631
+ class GroupTuple(t.NamedTuple):
632
+ """
633
+ Custom named tuple for the groupby filter with a public interface; silently ignored by unknown type checks.
634
+ This matches the internal implementation of the _GroupTuple returned by Jinja's built-in groupby filter.
635
+ """
636
+
637
+ grouper: t.Any
638
+ list: list[t.Any]
639
+
640
+ def __repr__(self) -> str:
641
+ return tuple.__repr__(self)
642
+
643
+
644
+ _lazy_containers.register_known_types(GroupTuple)
645
+
646
+
647
+ @pass_environment
648
+ def _cleansed_groupby(*args, **kwargs):
649
+ res = sync_do_groupby(*args, **kwargs)
650
+ res = [GroupTuple(grouper=g.grouper, list=g.list) for g in res]
651
+
652
+ return res
653
+
654
+ # DTFIX-RELEASE: make these dumb wrappers more dynamic
655
+
656
+
657
+ @accept_args_markers
658
+ def ansible_default(
659
+ value: t.Any,
660
+ default_value: t.Any = '',
661
+ boolean: bool = False,
662
+ ) -> t.Any:
663
+ """Updated `default` filter that only coalesces classic undefined objects; other Undefined-derived types (eg, ErrorMarker) pass through."""
664
+ validate_arg_type('boolean', boolean, bool)
665
+
666
+ if isinstance(value, UndefinedMarker):
667
+ return default_value
668
+
669
+ if boolean and not value:
670
+ return default_value
671
+
672
+ return value
673
+
674
+
675
+ @accept_lazy_markers
676
+ @functools.wraps(do_map)
677
+ def wrapped_map(*args, **kwargs) -> t.Any:
678
+ return do_map(*args, **kwargs)
679
+
680
+
681
+ @accept_lazy_markers
682
+ @functools.wraps(do_select)
683
+ def wrapped_select(*args, **kwargs) -> t.Any:
684
+ return do_select(*args, **kwargs)
685
+
686
+
687
+ @accept_lazy_markers
688
+ @functools.wraps(do_selectattr)
689
+ def wrapped_selectattr(*args, **kwargs) -> t.Any:
690
+ return do_selectattr(*args, **kwargs)
691
+
692
+
693
+ @accept_lazy_markers
694
+ @functools.wraps(do_reject)
695
+ def wrapped_reject(*args, **kwargs) -> t.Any:
696
+ return do_reject(*args, **kwargs)
697
+
698
+
699
+ @accept_lazy_markers
700
+ @functools.wraps(do_rejectattr)
701
+ def wrapped_rejectattr(*args, **kwargs) -> t.Any:
702
+ return do_rejectattr(*args, **kwargs)
703
+
704
+
705
+ @accept_args_markers
706
+ def type_debug(obj: object) -> str:
707
+ return native_type_name(obj)
708
+
709
+
607
710
  class FilterModule(object):
608
- ''' Ansible core jinja2 filters '''
711
+ """ Ansible core jinja2 filters """
609
712
 
610
713
  def filters(self):
611
714
  return {
@@ -619,7 +722,7 @@ class FilterModule(object):
619
722
  # json
620
723
  'to_json': to_json,
621
724
  'to_nice_json': to_nice_json,
622
- 'from_json': json.loads,
725
+ 'from_json': from_json,
623
726
 
624
727
  # yaml
625
728
  'to_yaml': to_yaml,
@@ -686,7 +789,7 @@ class FilterModule(object):
686
789
  'comment': comment,
687
790
 
688
791
  # debug
689
- 'type_debug': lambda o: o.__class__.__name__,
792
+ 'type_debug': type_debug,
690
793
 
691
794
  # Data structures
692
795
  'combine': combine,
@@ -696,4 +799,18 @@ class FilterModule(object):
696
799
  'items2dict': list_of_dict_key_value_elements_to_dict,
697
800
  'subelements': subelements,
698
801
  'split': partial(unicode_wrap, text_type.split),
802
+ # FDI038 - replace this with a standard type compat shim
803
+ 'groupby': _cleansed_groupby,
804
+
805
+ # Jinja builtins that need special arg handling
806
+ # DTFIX-RELEASE: document these now that they're overridden, or hide them so they don't show up as undocumented
807
+ 'd': ansible_default, # replaces the implementation instead of wrapping it
808
+ 'default': ansible_default, # replaces the implementation instead of wrapping it
809
+ 'map': wrapped_map,
810
+ 'select': wrapped_select,
811
+ 'selectattr': wrapped_selectattr,
812
+ 'reject': wrapped_reject,
813
+ 'rejectattr': wrapped_rejectattr,
699
814
  }
815
+
816
+ # DTFIX-RELEASE: document protomatter plugins, or hide them from ansible-doc/galaxy (not related to this code, but needed some place to put this comment)