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
@@ -0,0 +1,55 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime as _datetime
4
+
5
+ from ansible.module_utils._internal import _datatag
6
+ from ansible.module_utils._internal._json import _profiles
7
+ from ansible.parsing import vault as _vault
8
+ from ansible._internal._datatag import _tags
9
+
10
+
11
+ class _Profile(_profiles._JSONSerializationProfile):
12
+ """Profile for external cache persistence of inventory/fact data that preserves most tags."""
13
+
14
+ serialize_map = {}
15
+ schema_id = 1
16
+
17
+ @classmethod
18
+ def post_init(cls, **kwargs):
19
+ cls.allowed_ansible_serializable_types = (
20
+ _profiles._common_module_types
21
+ | _profiles._common_module_response_types
22
+ | {
23
+ _datatag._AnsibleTaggedDate,
24
+ _datatag._AnsibleTaggedTime,
25
+ _datatag._AnsibleTaggedDateTime,
26
+ _datatag._AnsibleTaggedStr,
27
+ _datatag._AnsibleTaggedInt,
28
+ _datatag._AnsibleTaggedFloat,
29
+ _datatag._AnsibleTaggedList,
30
+ _datatag._AnsibleTaggedSet,
31
+ _datatag._AnsibleTaggedTuple,
32
+ _datatag._AnsibleTaggedDict,
33
+ _tags.SourceWasEncrypted,
34
+ _tags.Origin,
35
+ _tags.TrustedAsTemplate,
36
+ _vault.EncryptedString,
37
+ _vault.VaultedValue,
38
+ }
39
+ )
40
+
41
+ cls.serialize_map = {
42
+ set: cls.serialize_as_list,
43
+ tuple: cls.serialize_as_list,
44
+ _datetime.date: _datatag.AnsibleSerializableDate,
45
+ _datetime.time: _datatag.AnsibleSerializableTime,
46
+ _datetime.datetime: _datatag.AnsibleSerializableDateTime,
47
+ }
48
+
49
+
50
+ class Encoder(_profiles.AnsibleProfileJSONEncoder):
51
+ _profile = _Profile
52
+
53
+
54
+ class Decoder(_profiles.AnsibleProfileJSONDecoder):
55
+ _profile = _Profile
@@ -0,0 +1,40 @@
1
+ """
2
+ Backwards compatibility profile for serialization for persisted ansible-inventory output.
3
+ Behavior is equivalent to pre 2.18 `AnsibleJSONEncoder` with vault_to_text=True.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from ... import _json
9
+ from . import _legacy
10
+
11
+
12
+ class _InventoryVariableVisitor(_legacy._LegacyVariableVisitor, _json.StateTrackingMixIn):
13
+ """State-tracking visitor implementation that only applies trust to `_meta.hostvars` and `vars` inventory values."""
14
+
15
+ # DTFIX-RELEASE: does the variable visitor need to support conversion of sequence/mapping for inventory?
16
+
17
+ @property
18
+ def _allow_trust(self) -> bool:
19
+ stack = self._get_stack()
20
+
21
+ if len(stack) >= 4 and stack[:2] == ['_meta', 'hostvars']:
22
+ return True
23
+
24
+ if len(stack) >= 3 and stack[1] == 'vars':
25
+ return True
26
+
27
+ return False
28
+
29
+
30
+ class _Profile(_legacy._Profile):
31
+ visitor_type = _InventoryVariableVisitor
32
+ encode_strings_as_utf8 = True
33
+
34
+
35
+ class Encoder(_legacy.Encoder):
36
+ _profile = _Profile
37
+
38
+
39
+ class Decoder(_legacy.Decoder):
40
+ _profile = _Profile
@@ -0,0 +1,197 @@
1
+ """
2
+ Backwards compatibility profile for serialization other than inventory (which should use inventory_legacy for backward-compatible trust behavior).
3
+ Behavior is equivalent to pre 2.18 `AnsibleJSONEncoder` with vault_to_text=True.
4
+ """
5
+
6
+ from __future__ import annotations as _annotations
7
+
8
+ import datetime as _datetime
9
+ import typing as _t
10
+
11
+ from ansible._internal import _json
12
+ from ansible._internal._datatag import _tags
13
+ from ansible.module_utils._internal import _datatag
14
+ from ansible.module_utils._internal._json import _profiles
15
+ from ansible.parsing import vault as _vault
16
+
17
+
18
+ class _Untrusted:
19
+ """
20
+ Temporarily wraps strings which are not trusted for templating.
21
+ Used before serialization of strings not tagged TrustedAsTemplate when trust inversion is enabled and trust is allowed in the string's context.
22
+ Used during deserialization of `__ansible_unsafe` strings to indicate they should not be tagged TrustedAsTemplate.
23
+ """
24
+
25
+ __slots__ = ('value',)
26
+
27
+ def __init__(self, value: str) -> None:
28
+ self.value = value
29
+
30
+
31
+ class _LegacyVariableVisitor(_json.AnsibleVariableVisitor):
32
+ """Variable visitor that supports optional trust inversion for legacy serialization."""
33
+
34
+ def __init__(
35
+ self,
36
+ *,
37
+ trusted_as_template: bool = False,
38
+ invert_trust: bool = False,
39
+ origin: _tags.Origin | None = None,
40
+ convert_mapping_to_dict: bool = False,
41
+ convert_sequence_to_list: bool = False,
42
+ convert_custom_scalars: bool = False,
43
+ ):
44
+ super().__init__(
45
+ trusted_as_template=trusted_as_template,
46
+ origin=origin,
47
+ convert_mapping_to_dict=convert_mapping_to_dict,
48
+ convert_sequence_to_list=convert_sequence_to_list,
49
+ convert_custom_scalars=convert_custom_scalars,
50
+ encrypted_string_behavior=_json.EncryptedStringBehavior.PRESERVE,
51
+ )
52
+
53
+ self.invert_trust = invert_trust
54
+
55
+ if trusted_as_template and invert_trust:
56
+ raise ValueError('trusted_as_template is mutually exclusive with invert_trust')
57
+
58
+ @property
59
+ def _allow_trust(self) -> bool:
60
+ """
61
+ This profile supports trust application in all contexts.
62
+ Derived implementations can override this behavior for application-dependent/schema-aware trust.
63
+ """
64
+ return True
65
+
66
+ def _early_visit(self, value, value_type) -> _t.Any:
67
+ """Similar to base implementation, but supports an intermediate wrapper for trust inversion."""
68
+ if value_type in (str, _datatag._AnsibleTaggedStr):
69
+ # apply compatibility behavior
70
+ if self.trusted_as_template and self._allow_trust:
71
+ result = _tags.TrustedAsTemplate().tag(value)
72
+ elif self.invert_trust and not _tags.TrustedAsTemplate.is_tagged_on(value) and self._allow_trust:
73
+ result = _Untrusted(value)
74
+ else:
75
+ result = value
76
+ elif value_type is _Untrusted:
77
+ result = value.value
78
+ else:
79
+ result = _json._sentinel
80
+
81
+ return result
82
+
83
+
84
+ class _Profile(_profiles._JSONSerializationProfile["Encoder", "Decoder"]):
85
+ visitor_type = _LegacyVariableVisitor
86
+
87
+ @classmethod
88
+ def serialize_untrusted(cls, value: _Untrusted) -> dict[str, str] | str:
89
+ return dict(
90
+ __ansible_unsafe=_datatag.AnsibleTagHelper.untag(value.value),
91
+ )
92
+
93
+ @classmethod
94
+ def serialize_tagged_str(cls, value: _datatag.AnsibleTaggedObject) -> _t.Any:
95
+ if ciphertext := _vault.VaultHelper.get_ciphertext(value, with_tags=False):
96
+ return dict(
97
+ __ansible_vault=ciphertext,
98
+ )
99
+
100
+ return _datatag.AnsibleTagHelper.untag(value)
101
+
102
+ @classmethod
103
+ def deserialize_unsafe(cls, value: dict[str, _t.Any]) -> _Untrusted:
104
+ ansible_unsafe = value['__ansible_unsafe']
105
+
106
+ if type(ansible_unsafe) is not str: # pylint: disable=unidiomatic-typecheck
107
+ raise TypeError(f"__ansible_unsafe is {type(ansible_unsafe)} not {str}")
108
+
109
+ return _Untrusted(ansible_unsafe)
110
+
111
+ @classmethod
112
+ def deserialize_vault(cls, value: dict[str, _t.Any]) -> _vault.EncryptedString:
113
+ ansible_vault = value['__ansible_vault']
114
+
115
+ if type(ansible_vault) is not str: # pylint: disable=unidiomatic-typecheck
116
+ raise TypeError(f"__ansible_vault is {type(ansible_vault)} not {str}")
117
+
118
+ encrypted_string = _vault.EncryptedString(ciphertext=ansible_vault)
119
+
120
+ return encrypted_string
121
+
122
+ @classmethod
123
+ def serialize_encrypted_string(cls, value: _vault.EncryptedString) -> dict[str, str]:
124
+ return dict(
125
+ __ansible_vault=_vault.VaultHelper.get_ciphertext(value, with_tags=False),
126
+ )
127
+
128
+ @classmethod
129
+ def post_init(cls) -> None:
130
+ cls.serialize_map = {
131
+ set: cls.serialize_as_list,
132
+ tuple: cls.serialize_as_list,
133
+ _datetime.date: cls.serialize_as_isoformat, # existing devel behavior
134
+ _datetime.time: cls.serialize_as_isoformat, # always failed pre-2.18, so okay to include for consistency
135
+ _datetime.datetime: cls.serialize_as_isoformat, # existing devel behavior
136
+ _datatag._AnsibleTaggedDate: cls.discard_tags,
137
+ _datatag._AnsibleTaggedTime: cls.discard_tags,
138
+ _datatag._AnsibleTaggedDateTime: cls.discard_tags,
139
+ _vault.EncryptedString: cls.serialize_encrypted_string,
140
+ _datatag._AnsibleTaggedStr: cls.serialize_tagged_str, # for VaultedValue tagged str
141
+ _datatag._AnsibleTaggedInt: cls.discard_tags,
142
+ _datatag._AnsibleTaggedFloat: cls.discard_tags,
143
+ _datatag._AnsibleTaggedList: cls.discard_tags,
144
+ _datatag._AnsibleTaggedSet: cls.discard_tags,
145
+ _datatag._AnsibleTaggedTuple: cls.discard_tags,
146
+ _datatag._AnsibleTaggedDict: cls.discard_tags,
147
+ _Untrusted: cls.serialize_untrusted, # equivalent to AnsibleJSONEncoder(preprocess_unsafe=True) in devel
148
+ }
149
+
150
+ cls.deserialize_map = {
151
+ '__ansible_unsafe': cls.deserialize_unsafe,
152
+ '__ansible_vault': cls.deserialize_vault,
153
+ }
154
+
155
+ @classmethod
156
+ def pre_serialize(cls, encoder: Encoder, o: _t.Any) -> _t.Any:
157
+ # DTFIX-RELEASE: these conversion args probably aren't needed
158
+ avv = cls.visitor_type(invert_trust=True, convert_mapping_to_dict=True, convert_sequence_to_list=True, convert_custom_scalars=True)
159
+
160
+ return avv.visit(o)
161
+
162
+ @classmethod
163
+ def post_deserialize(cls, decoder: Decoder, o: _t.Any) -> _t.Any:
164
+ avv = cls.visitor_type(trusted_as_template=decoder._trusted_as_template, origin=decoder._origin)
165
+
166
+ return avv.visit(o)
167
+
168
+ @classmethod
169
+ def handle_key(cls, k: _t.Any) -> _t.Any:
170
+ if isinstance(k, str):
171
+ return k
172
+
173
+ # DTFIX-RELEASE: decide if this is a deprecation warning, error, or what?
174
+ # Non-string variable names have been disallowed by set_fact and other things since at least 2021.
175
+ # DTFIX-RELEASE: document why this behavior is here, also verify the legacy tagless use case doesn't need this same behavior
176
+ return str(k)
177
+
178
+
179
+ class Encoder(_profiles.AnsibleProfileJSONEncoder):
180
+ _profile = _Profile
181
+
182
+
183
+ class Decoder(_profiles.AnsibleProfileJSONDecoder):
184
+ _profile = _Profile
185
+
186
+ def __init__(self, **kwargs) -> None:
187
+ super().__init__(**kwargs)
188
+
189
+ # NB: these can only be sampled properly when loading strings, eg, `json.loads`; the global `json.load` function does not expose the file-like to us
190
+ self._origin: _tags.Origin | None = None
191
+ self._trusted_as_template: bool = False
192
+
193
+ def raw_decode(self, s: str, idx: int = 0) -> tuple[_t.Any, int]:
194
+ self._origin = _tags.Origin.get_tag(s)
195
+ self._trusted_as_template = _tags.TrustedAsTemplate.is_tagged_on(s)
196
+
197
+ return super().raw_decode(s, idx)
@@ -0,0 +1,21 @@
1
+ from __future__ import annotations
2
+
3
+ import contextlib
4
+ import fcntl
5
+ import typing as t
6
+
7
+
8
+ @contextlib.contextmanager
9
+ def named_mutex(path: str) -> t.Iterator[None]:
10
+ """
11
+ Lightweight context manager wrapper over `fcntl.flock` to provide IPC locking via a shared filename.
12
+ Entering the context manager blocks until the lock is acquired.
13
+ The lock file will be created automatically, but creation of the parent directory and deletion of the lockfile are the caller's responsibility.
14
+ """
15
+ with open(path, 'a') as file:
16
+ fcntl.flock(file, fcntl.LOCK_EX)
17
+
18
+ try:
19
+ yield
20
+ finally:
21
+ fcntl.flock(file, fcntl.LOCK_UN)
File without changes
@@ -0,0 +1,57 @@
1
+ from __future__ import annotations
2
+
3
+ import functools
4
+ import json
5
+ import json.encoder
6
+ import json.decoder
7
+ import typing as t
8
+
9
+ from .._wrapt import ObjectProxy
10
+ from .._json._profiles import _cache_persistence
11
+
12
+
13
+ class PluginInterposer(ObjectProxy):
14
+ """Proxies a Cache plugin instance to implement transparent encapsulation of serialized Ansible internal data types."""
15
+
16
+ _PAYLOAD_KEY = '__payload__'
17
+ """The key used to store the serialized payload."""
18
+
19
+ def get(self, key: str) -> dict[str, object]:
20
+ return self._decode(self.__wrapped__.get(self._get_key(key)))
21
+
22
+ def set(self, key: str, value: dict[str, object]) -> None:
23
+ self.__wrapped__.set(self._get_key(key), self._encode(value))
24
+
25
+ def keys(self) -> t.Sequence[str]:
26
+ return [k for k in (self._restore_key(k) for k in self.__wrapped__.keys()) if k is not None]
27
+
28
+ def contains(self, key: t.Any) -> bool:
29
+ return self.__wrapped__.contains(self._get_key(key))
30
+
31
+ def delete(self, key: str) -> None:
32
+ self.__wrapped__.delete(self._get_key(key))
33
+
34
+ @classmethod
35
+ def _restore_key(cls, wrapped_key: str) -> str | None:
36
+ prefix = cls._get_wrapped_key_prefix()
37
+
38
+ if not wrapped_key.startswith(prefix):
39
+ return None
40
+
41
+ return wrapped_key[len(prefix) :]
42
+
43
+ @classmethod
44
+ @functools.cache
45
+ def _get_wrapped_key_prefix(cls) -> str:
46
+ return f's{_cache_persistence._Profile.schema_id}_'
47
+
48
+ @classmethod
49
+ def _get_key(cls, key: str) -> str:
50
+ """Augment the supplied key with a schema identifier to allow for side-by-side caching across incompatible schemas."""
51
+ return f'{cls._get_wrapped_key_prefix()}{key}'
52
+
53
+ def _encode(self, value: dict[str, object]) -> dict[str, object]:
54
+ return {self._PAYLOAD_KEY: json.dumps(value, cls=_cache_persistence.Encoder)}
55
+
56
+ def _decode(self, value: dict[str, t.Any]) -> dict[str, object]:
57
+ return json.loads(value[self._PAYLOAD_KEY], cls=_cache_persistence.Decoder)
@@ -0,0 +1,78 @@
1
+ from __future__ import annotations
2
+
3
+ import dataclasses
4
+ import typing as t
5
+
6
+ from collections import abc as c
7
+
8
+ from ansible import constants
9
+ from ansible._internal._templating import _engine
10
+ from ansible._internal._templating._chain_templar import ChainTemplar
11
+ from ansible.errors import AnsibleError
12
+ from ansible.module_utils._internal._ambient_context import AmbientContextBase
13
+ from ansible.module_utils.datatag import native_type_name
14
+ from ansible.parsing import vault as _vault
15
+ from ansible.utils.display import Display
16
+
17
+ if t.TYPE_CHECKING:
18
+ from ansible.playbook.task import Task
19
+
20
+
21
+ @dataclasses.dataclass
22
+ class TaskContext(AmbientContextBase):
23
+ """Ambient context that wraps task execution on workers. It provides access to the currently executing task."""
24
+
25
+ task: Task
26
+
27
+
28
+ TaskArgsFinalizerCallback = t.Callable[[str, t.Any, _engine.TemplateEngine, t.Any], t.Any]
29
+ """Type alias for the shape of the `ActionBase.finalize_task_arg` method."""
30
+
31
+
32
+ class TaskArgsChainTemplar(ChainTemplar):
33
+ """
34
+ A ChainTemplar that carries a user-provided context object, optionally provided by `ActionBase.get_finalize_task_args_context`.
35
+ TaskArgsFinalizer provides the context to each `ActionBase.finalize_task_arg` call to allow for more complex/stateful customization.
36
+ """
37
+
38
+ def __init__(self, *sources: c.Mapping, templar: _engine.TemplateEngine, callback: TaskArgsFinalizerCallback, context: t.Any) -> None:
39
+ super().__init__(*sources, templar=templar)
40
+
41
+ self.callback = callback
42
+ self.context = context
43
+
44
+ def template(self, key: t.Any, value: t.Any) -> t.Any:
45
+ return self.callback(key, value, self.templar, self.context)
46
+
47
+
48
+ class TaskArgsFinalizer:
49
+ """Invoked during task args finalization; allows actions to override default arg processing (e.g., templating)."""
50
+
51
+ def __init__(self, *args: c.Mapping[str, t.Any] | str | None, templar: _engine.TemplateEngine) -> None:
52
+ self._args_layers = [arg for arg in args if arg is not None]
53
+ self._templar = templar
54
+
55
+ def finalize(self, callback: TaskArgsFinalizerCallback, context: t.Any) -> dict[str, t.Any]:
56
+ resolved_layers: list[c.Mapping[str, t.Any]] = []
57
+
58
+ for layer in self._args_layers:
59
+ if isinstance(layer, (str, _vault.EncryptedString)): # EncryptedString can hide a template
60
+ if constants.config.get_config_value('INJECT_FACTS_AS_VARS'):
61
+ Display().warning(
62
+ "Using a template for task args is unsafe in some situations "
63
+ "(see https://docs.ansible.com/ansible/devel/reference_appendices/faq.html#argsplat-unsafe).",
64
+ obj=layer,
65
+ )
66
+
67
+ resolved_layer = self._templar.resolve_to_container(layer, options=_engine.TemplateOptions(value_for_omit={}))
68
+ else:
69
+ resolved_layer = layer
70
+
71
+ if not isinstance(resolved_layer, dict):
72
+ raise AnsibleError(f'Task args must resolve to a {native_type_name(dict)!r} not {native_type_name(resolved_layer)!r}.', obj=layer)
73
+
74
+ resolved_layers.append(resolved_layer)
75
+
76
+ ct = TaskArgsChainTemplar(*reversed(resolved_layers), templar=self._templar, callback=callback, context=context)
77
+
78
+ return ct.as_dict()
@@ -0,0 +1,10 @@
1
+ from __future__ import annotations
2
+
3
+ from jinja2 import __version__ as _jinja2_version
4
+
5
+ # DTFIX-FUTURE: sanity test to ensure this doesn't drift from requirements
6
+ _MINIMUM_JINJA_VERSION = (3, 1)
7
+ _CURRENT_JINJA_VERSION = tuple(map(int, _jinja2_version.split('.', maxsplit=2)[:2]))
8
+
9
+ if _CURRENT_JINJA_VERSION < _MINIMUM_JINJA_VERSION:
10
+ raise RuntimeError(f'Jinja version {".".join(map(str, _MINIMUM_JINJA_VERSION))} or higher is required (current version {_jinja2_version}).')
@@ -0,0 +1,86 @@
1
+ from __future__ import annotations
2
+
3
+ import abc
4
+ import typing as t
5
+
6
+ from contextvars import ContextVar
7
+
8
+ from ansible.module_utils._internal._datatag import AnsibleTagHelper
9
+
10
+
11
+ class NotifiableAccessContextBase(metaclass=abc.ABCMeta):
12
+ """Base class for a context manager that, when active, receives notification of managed access for types/tags in which it has registered an interest."""
13
+
14
+ _type_interest: t.FrozenSet[type] = frozenset()
15
+ """Set of types (including tag types) for which this context will be notified upon access."""
16
+
17
+ _mask: t.ClassVar[bool] = False
18
+ """When true, only the innermost (most recently created) context of this type will be notified."""
19
+
20
+ def __enter__(self):
21
+ # noinspection PyProtectedMember
22
+ AnsibleAccessContext.current()._register_interest(self)
23
+ return self
24
+
25
+ def __exit__(self, exc_type, exc_val, exc_tb) -> None:
26
+ # noinspection PyProtectedMember
27
+ AnsibleAccessContext.current()._unregister_interest(self)
28
+ return None
29
+
30
+ @abc.abstractmethod
31
+ def _notify(self, o: t.Any) -> t.Any:
32
+ """Derived classes implement custom notification behavior when a registered type or tag is accessed."""
33
+
34
+
35
+ class AnsibleAccessContext:
36
+ """
37
+ Broker object for managed access registration and notification.
38
+ Each thread or other logical callstack has a dedicated `AnsibleAccessContext` object with which `NotifiableAccessContext` objects can register interest.
39
+ When a managed access occurs on an object, each active `NotifiableAccessContext` within the current callstack that has registered interest in that
40
+ object's type or a tag present on it will be notified.
41
+ """
42
+
43
+ _contextvar: t.ClassVar[ContextVar[AnsibleAccessContext]] = ContextVar('AnsibleAccessContext')
44
+
45
+ @staticmethod
46
+ def current() -> AnsibleAccessContext:
47
+ """Creates or retrieves an `AnsibleAccessContext` for the current logical callstack."""
48
+ try:
49
+ ctx: AnsibleAccessContext = AnsibleAccessContext._contextvar.get()
50
+ except LookupError:
51
+ # didn't exist; create it
52
+ ctx = AnsibleAccessContext()
53
+ AnsibleAccessContext._contextvar.set(ctx) # we ignore the token, since this should live for the life of the thread/async ctx
54
+
55
+ return ctx
56
+
57
+ def __init__(self) -> None:
58
+ self._notify_contexts: list[NotifiableAccessContextBase] = []
59
+
60
+ def _register_interest(self, context: NotifiableAccessContextBase) -> None:
61
+ self._notify_contexts.append(context)
62
+
63
+ def _unregister_interest(self, context: NotifiableAccessContextBase) -> None:
64
+ ctx = self._notify_contexts.pop()
65
+
66
+ if ctx is not context:
67
+ raise RuntimeError(f'Out-of-order context deactivation detected. Found {ctx} instead of {context}.')
68
+
69
+ def access(self, value: t.Any) -> None:
70
+ """Notify all contexts which have registered interest in the given value that it is being accessed."""
71
+ if not self._notify_contexts:
72
+ return
73
+
74
+ value_types = AnsibleTagHelper.tag_types(value) | frozenset((type(value),))
75
+ masked: set[type] = set()
76
+
77
+ for ctx in reversed(self._notify_contexts):
78
+ if ctx._mask:
79
+ if (ctx_type := type(ctx)) in masked:
80
+ continue
81
+
82
+ masked.add(ctx_type)
83
+
84
+ # noinspection PyProtectedMember
85
+ if ctx._type_interest.intersection(value_types):
86
+ ctx._notify(value)
@@ -0,0 +1,63 @@
1
+ from __future__ import annotations
2
+
3
+ import collections.abc as c
4
+ import itertools
5
+ import typing as t
6
+
7
+ from ansible.errors import AnsibleValueOmittedError, AnsibleError
8
+
9
+ from ._engine import TemplateEngine
10
+
11
+
12
+ class ChainTemplar:
13
+ """A basic variable layering mechanism that supports templating and obliteration of `omit` values."""
14
+
15
+ def __init__(self, *sources: c.Mapping, templar: TemplateEngine) -> None:
16
+ self.sources = sources
17
+ self.templar = templar
18
+
19
+ def template(self, key: t.Any, value: t.Any) -> t.Any:
20
+ """
21
+ Render the given value using the templar.
22
+ Intended to be overridden by subclasses.
23
+ """
24
+ return self.templar.template(value)
25
+
26
+ def get(self, key: t.Any) -> t.Any:
27
+ """Get the value for the given key, templating the result before returning it."""
28
+ for source in self.sources:
29
+ if key not in source:
30
+ continue
31
+
32
+ value = source[key]
33
+
34
+ try:
35
+ return self.template(key, value)
36
+ except AnsibleValueOmittedError:
37
+ break # omit == obliterate - matches historical behavior where dict layers were squashed before templating was applied
38
+ except Exception as ex:
39
+ raise AnsibleError(f'Error while resolving value for {key!r}.', obj=value) from ex
40
+
41
+ raise KeyError(key)
42
+
43
+ def keys(self) -> t.Iterable[t.Any]:
44
+ """
45
+ Returns a sorted iterable of all keys present in all source layers, without templating associated values.
46
+ Values that resolve to `omit` are thus included.
47
+ """
48
+ return sorted(set(itertools.chain.from_iterable(self.sources)))
49
+
50
+ def items(self) -> t.Iterable[t.Tuple[t.Any, t.Any]]:
51
+ """
52
+ Returns a sorted iterable of (key, templated value) tuples.
53
+ Any tuple where the templated value resolves to `omit` will not be included in the result.
54
+ """
55
+ for key in self.keys():
56
+ try:
57
+ yield key, self.get(key)
58
+ except KeyError:
59
+ pass
60
+
61
+ def as_dict(self) -> dict[t.Any, t.Any]:
62
+ """Returns a dict representing all layers, squashed and templated, with `omit` values dropped."""
63
+ return dict(self.items())