ansible-core 2.15.4rc1__py3-none-any.whl → 2.16.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.

Potentially problematic release.


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

Files changed (427) hide show
  1. ansible/cli/__init__.py +3 -3
  2. ansible/cli/adhoc.py +1 -1
  3. ansible/cli/arguments/option_helpers.py +15 -5
  4. ansible/cli/config.py +2 -2
  5. ansible/cli/console.py +21 -17
  6. ansible/cli/doc.py +8 -9
  7. ansible/cli/galaxy.py +60 -27
  8. ansible/cli/inventory.py +1 -1
  9. ansible/cli/playbook.py +1 -1
  10. ansible/cli/pull.py +2 -2
  11. ansible/cli/scripts/ansible_connection_cli_stub.py +1 -1
  12. ansible/cli/vault.py +11 -6
  13. ansible/collections/__init__.py +0 -29
  14. ansible/collections/list.py +23 -44
  15. ansible/config/ansible_builtin_runtime.yml +8 -4
  16. ansible/config/base.yml +34 -22
  17. ansible/config/manager.py +1 -1
  18. ansible/constants.py +3 -5
  19. ansible/errors/__init__.py +1 -1
  20. ansible/executor/interpreter_discovery.py +1 -1
  21. ansible/executor/module_common.py +39 -32
  22. ansible/executor/play_iterator.py +0 -15
  23. ansible/executor/playbook_executor.py +3 -3
  24. ansible/executor/powershell/module_manifest.py +1 -1
  25. ansible/executor/powershell/module_wrapper.ps1 +4 -1
  26. ansible/executor/process/worker.py +22 -7
  27. ansible/executor/task_executor.py +39 -40
  28. ansible/executor/task_queue_manager.py +8 -11
  29. ansible/galaxy/__init__.py +1 -1
  30. ansible/galaxy/api.py +8 -11
  31. ansible/galaxy/collection/__init__.py +17 -4
  32. ansible/galaxy/collection/concrete_artifact_manager.py +7 -2
  33. ansible/galaxy/collection/galaxy_api_proxy.py +1 -1
  34. ansible/galaxy/data/container/README.md +3 -5
  35. ansible/galaxy/dependency_resolution/__init__.py +1 -6
  36. ansible/galaxy/dependency_resolution/dataclasses.py +22 -1
  37. ansible/galaxy/dependency_resolution/providers.py +61 -69
  38. ansible/galaxy/role.py +31 -13
  39. ansible/galaxy/token.py +2 -2
  40. ansible/inventory/group.py +1 -1
  41. ansible/inventory/manager.py +1 -1
  42. ansible/module_utils/ansible_release.py +2 -2
  43. ansible/module_utils/basic.py +11 -41
  44. ansible/module_utils/common/file.py +0 -100
  45. ansible/module_utils/common/json.py +1 -1
  46. ansible/module_utils/common/locale.py +1 -1
  47. ansible/module_utils/common/text/converters.py +2 -2
  48. ansible/module_utils/common/validation.py +1 -1
  49. ansible/module_utils/compat/_selectors2.py +4 -4
  50. ansible/module_utils/compat/datetime.py +40 -0
  51. ansible/module_utils/compat/selinux.py +1 -1
  52. ansible/module_utils/compat/typing.py +1 -1
  53. ansible/module_utils/connection.py +1 -1
  54. ansible/module_utils/facts/hardware/linux.py +2 -2
  55. ansible/module_utils/facts/hardware/openbsd.py +1 -1
  56. ansible/module_utils/facts/network/linux.py +3 -3
  57. ansible/module_utils/facts/other/facter.py +8 -15
  58. ansible/module_utils/facts/sysctl.py +1 -1
  59. ansible/module_utils/facts/system/date_time.py +2 -2
  60. ansible/module_utils/facts/system/distribution.py +1 -1
  61. ansible/module_utils/facts/system/local.py +6 -2
  62. ansible/module_utils/facts/system/pkg_mgr.py +6 -1
  63. ansible/module_utils/facts/system/service_mgr.py +4 -2
  64. ansible/module_utils/parsing/convert_bool.py +1 -1
  65. ansible/module_utils/service.py +9 -6
  66. ansible/module_utils/urls.py +40 -22
  67. ansible/modules/add_host.py +2 -2
  68. ansible/modules/apt.py +48 -31
  69. ansible/modules/apt_key.py +4 -4
  70. ansible/modules/apt_repository.py +5 -5
  71. ansible/modules/assemble.py +7 -7
  72. ansible/modules/assert.py +1 -1
  73. ansible/modules/async_status.py +11 -7
  74. ansible/modules/async_wrapper.py +1 -1
  75. ansible/modules/blockinfile.py +60 -17
  76. ansible/modules/command.py +37 -15
  77. ansible/modules/copy.py +35 -30
  78. ansible/modules/cron.py +14 -14
  79. ansible/modules/deb822_repository.py +4 -3
  80. ansible/modules/debconf.py +35 -14
  81. ansible/modules/debug.py +1 -1
  82. ansible/modules/dnf.py +29 -27
  83. ansible/modules/dnf5.py +22 -22
  84. ansible/modules/dpkg_selections.py +9 -2
  85. ansible/modules/expect.py +4 -4
  86. ansible/modules/fetch.py +7 -7
  87. ansible/modules/file.py +30 -30
  88. ansible/modules/find.py +82 -22
  89. ansible/modules/gather_facts.py +6 -2
  90. ansible/modules/get_url.py +29 -29
  91. ansible/modules/getent.py +4 -4
  92. ansible/modules/git.py +27 -27
  93. ansible/modules/group.py +5 -12
  94. ansible/modules/hostname.py +21 -2
  95. ansible/modules/include_role.py +5 -5
  96. ansible/modules/include_tasks.py +2 -2
  97. ansible/modules/include_vars.py +5 -5
  98. ansible/modules/iptables.py +70 -65
  99. ansible/modules/known_hosts.py +7 -7
  100. ansible/modules/lineinfile.py +33 -33
  101. ansible/modules/meta.py +13 -13
  102. ansible/modules/package.py +8 -8
  103. ansible/modules/package_facts.py +3 -3
  104. ansible/modules/pause.py +2 -2
  105. ansible/modules/ping.py +5 -5
  106. ansible/modules/pip.py +80 -46
  107. ansible/modules/reboot.py +8 -4
  108. ansible/modules/replace.py +20 -15
  109. ansible/modules/rpm_key.py +2 -2
  110. ansible/modules/script.py +16 -10
  111. ansible/modules/service.py +26 -98
  112. ansible/modules/service_facts.py +36 -12
  113. ansible/modules/set_fact.py +2 -2
  114. ansible/modules/set_stats.py +2 -2
  115. ansible/modules/setup.py +18 -18
  116. ansible/modules/shell.py +3 -3
  117. ansible/modules/stat.py +9 -30
  118. ansible/modules/subversion.py +9 -9
  119. ansible/modules/systemd.py +20 -19
  120. ansible/modules/systemd_service.py +20 -19
  121. ansible/modules/sysvinit.py +26 -21
  122. ansible/modules/tempfile.py +5 -4
  123. ansible/modules/template.py +60 -6
  124. ansible/modules/unarchive.py +21 -18
  125. ansible/modules/uri.py +39 -39
  126. ansible/modules/user.py +81 -53
  127. ansible/modules/wait_for.py +22 -21
  128. ansible/modules/wait_for_connection.py +4 -4
  129. ansible/modules/yum.py +38 -38
  130. ansible/modules/yum_repository.py +58 -80
  131. ansible/parsing/dataloader.py +27 -27
  132. ansible/parsing/mod_args.py +1 -1
  133. ansible/parsing/plugin_docs.py +3 -3
  134. ansible/parsing/splitter.py +14 -16
  135. ansible/parsing/utils/yaml.py +1 -1
  136. ansible/parsing/vault/__init__.py +8 -6
  137. ansible/parsing/yaml/constructor.py +1 -1
  138. ansible/parsing/yaml/objects.py +1 -1
  139. ansible/playbook/__init__.py +1 -1
  140. ansible/playbook/base.py +2 -2
  141. ansible/playbook/block.py +0 -1
  142. ansible/playbook/conditional.py +40 -114
  143. ansible/playbook/helpers.py +5 -28
  144. ansible/playbook/included_file.py +8 -7
  145. ansible/playbook/play.py +1 -1
  146. ansible/playbook/play_context.py +2 -2
  147. ansible/playbook/playbook_include.py +2 -2
  148. ansible/playbook/role/__init__.py +1 -1
  149. ansible/playbook/role/include.py +1 -1
  150. ansible/playbook/role/metadata.py +1 -1
  151. ansible/playbook/role_include.py +1 -1
  152. ansible/playbook/task.py +2 -2
  153. ansible/playbook/task_include.py +1 -24
  154. ansible/plugins/__init__.py +13 -5
  155. ansible/plugins/action/__init__.py +17 -43
  156. ansible/plugins/action/add_host.py +2 -3
  157. ansible/plugins/action/assemble.py +1 -1
  158. ansible/plugins/action/assert.py +2 -1
  159. ansible/plugins/action/copy.py +2 -2
  160. ansible/plugins/action/debug.py +2 -1
  161. ansible/plugins/action/fail.py +1 -0
  162. ansible/plugins/action/fetch.py +3 -1
  163. ansible/plugins/action/gather_facts.py +37 -13
  164. ansible/plugins/action/group_by.py +1 -0
  165. ansible/plugins/action/include_vars.py +3 -2
  166. ansible/plugins/action/normal.py +3 -3
  167. ansible/plugins/action/pause.py +1 -1
  168. ansible/plugins/action/reboot.py +21 -16
  169. ansible/plugins/action/script.py +23 -8
  170. ansible/plugins/action/set_fact.py +1 -0
  171. ansible/plugins/action/set_stats.py +1 -0
  172. ansible/plugins/action/shell.py +6 -0
  173. ansible/plugins/action/template.py +1 -1
  174. ansible/plugins/action/unarchive.py +1 -1
  175. ansible/plugins/action/uri.py +1 -1
  176. ansible/plugins/action/validate_argument_spec.py +1 -0
  177. ansible/plugins/action/wait_for_connection.py +4 -4
  178. ansible/plugins/become/__init__.py +1 -1
  179. ansible/plugins/become/su.py +1 -1
  180. ansible/plugins/cache/__init__.py +1 -1
  181. ansible/plugins/callback/junit.py +1 -1
  182. ansible/plugins/callback/oneline.py +1 -1
  183. ansible/plugins/callback/tree.py +1 -1
  184. ansible/plugins/cliconf/__init__.py +2 -2
  185. ansible/plugins/connection/__init__.py +65 -37
  186. ansible/plugins/connection/local.py +9 -8
  187. ansible/plugins/connection/paramiko_ssh.py +34 -28
  188. ansible/plugins/connection/psrp.py +56 -43
  189. ansible/plugins/connection/ssh.py +67 -43
  190. ansible/plugins/connection/winrm.py +77 -30
  191. ansible/plugins/doc_fragments/constructed.py +4 -4
  192. ansible/plugins/doc_fragments/files.py +12 -12
  193. ansible/plugins/doc_fragments/inventory_cache.py +0 -6
  194. ansible/plugins/doc_fragments/result_format_callback.py +5 -5
  195. ansible/plugins/doc_fragments/shell_common.py +2 -2
  196. ansible/plugins/doc_fragments/shell_windows.py +1 -1
  197. ansible/plugins/doc_fragments/template_common.py +6 -6
  198. ansible/plugins/doc_fragments/url.py +10 -10
  199. ansible/plugins/doc_fragments/url_windows.py +15 -15
  200. ansible/plugins/doc_fragments/vars_plugin_staging.py +4 -4
  201. ansible/plugins/filter/b64decode.yml +1 -1
  202. ansible/plugins/filter/b64encode.yml +2 -2
  203. ansible/plugins/filter/bool.yml +5 -5
  204. ansible/plugins/filter/combine.yml +1 -1
  205. ansible/plugins/filter/commonpath.yml +2 -1
  206. ansible/plugins/filter/core.py +6 -8
  207. ansible/plugins/filter/dict2items.yml +11 -1
  208. ansible/plugins/filter/difference.yml +1 -0
  209. ansible/plugins/filter/encryption.py +1 -1
  210. ansible/plugins/filter/extract.yml +1 -1
  211. ansible/plugins/filter/flatten.yml +1 -1
  212. ansible/plugins/filter/from_yaml.yml +1 -1
  213. ansible/plugins/filter/from_yaml_all.yml +2 -2
  214. ansible/plugins/filter/hash.yml +1 -1
  215. ansible/plugins/filter/human_readable.yml +1 -1
  216. ansible/plugins/filter/human_to_bytes.yml +2 -2
  217. ansible/plugins/filter/intersect.yml +1 -0
  218. ansible/plugins/filter/mandatory.yml +7 -0
  219. ansible/plugins/filter/mathstuff.py +15 -17
  220. ansible/plugins/filter/normpath.yml +1 -1
  221. ansible/plugins/filter/path_join.yml +8 -1
  222. ansible/plugins/filter/realpath.yml +3 -2
  223. ansible/plugins/filter/regex_findall.yml +8 -2
  224. ansible/plugins/filter/regex_replace.yml +9 -3
  225. ansible/plugins/filter/regex_search.yml +8 -2
  226. ansible/plugins/filter/relpath.yml +2 -2
  227. ansible/plugins/filter/root.yml +1 -1
  228. ansible/plugins/filter/splitext.yml +1 -1
  229. ansible/plugins/filter/subelements.yml +2 -2
  230. ansible/plugins/filter/symmetric_difference.yml +1 -0
  231. ansible/plugins/filter/ternary.yml +5 -5
  232. ansible/plugins/filter/to_json.yml +7 -7
  233. ansible/plugins/filter/to_nice_json.yml +5 -5
  234. ansible/plugins/filter/to_yaml.yml +2 -2
  235. ansible/plugins/filter/type_debug.yml +1 -1
  236. ansible/plugins/filter/union.yml +1 -0
  237. ansible/plugins/filter/unvault.yml +2 -2
  238. ansible/plugins/filter/urldecode.yml +13 -32
  239. ansible/plugins/filter/urlsplit.py +1 -1
  240. ansible/plugins/filter/vault.yml +1 -1
  241. ansible/plugins/filter/zip.yml +1 -1
  242. ansible/plugins/filter/zip_longest.yml +1 -1
  243. ansible/plugins/inventory/__init__.py +1 -1
  244. ansible/plugins/inventory/advanced_host_list.py +1 -1
  245. ansible/plugins/inventory/constructed.py +2 -2
  246. ansible/plugins/inventory/host_list.py +1 -1
  247. ansible/plugins/inventory/ini.py +6 -3
  248. ansible/plugins/inventory/script.py +8 -2
  249. ansible/plugins/inventory/toml.py +1 -1
  250. ansible/plugins/inventory/yaml.py +1 -1
  251. ansible/plugins/list.py +21 -17
  252. ansible/plugins/loader.py +66 -88
  253. ansible/plugins/lookup/__init__.py +1 -1
  254. ansible/plugins/lookup/config.py +16 -6
  255. ansible/plugins/lookup/csvfile.py +7 -4
  256. ansible/plugins/lookup/env.py +1 -1
  257. ansible/plugins/lookup/file.py +5 -2
  258. ansible/plugins/lookup/fileglob.py +5 -2
  259. ansible/plugins/lookup/first_found.py +20 -14
  260. ansible/plugins/lookup/ini.py +6 -3
  261. ansible/plugins/lookup/lines.py +2 -1
  262. ansible/plugins/lookup/password.py +7 -7
  263. ansible/plugins/lookup/pipe.py +1 -0
  264. ansible/plugins/lookup/random_choice.py +2 -2
  265. ansible/plugins/lookup/sequence.py +1 -1
  266. ansible/plugins/lookup/subelements.py +2 -2
  267. ansible/plugins/lookup/template.py +4 -1
  268. ansible/plugins/lookup/unvault.py +4 -1
  269. ansible/plugins/lookup/url.py +6 -6
  270. ansible/plugins/lookup/varnames.py +1 -1
  271. ansible/plugins/netconf/__init__.py +3 -3
  272. ansible/plugins/shell/__init__.py +1 -1
  273. ansible/plugins/shell/cmd.py +7 -7
  274. ansible/plugins/shell/powershell.py +1 -1
  275. ansible/plugins/strategy/__init__.py +8 -10
  276. ansible/plugins/strategy/free.py +1 -1
  277. ansible/plugins/strategy/linear.py +3 -3
  278. ansible/plugins/terminal/__init__.py +2 -2
  279. ansible/plugins/test/abs.yml +1 -1
  280. ansible/plugins/test/all.yml +1 -1
  281. ansible/plugins/test/any.yml +1 -1
  282. ansible/plugins/test/change.yml +2 -2
  283. ansible/plugins/test/changed.yml +2 -2
  284. ansible/plugins/test/contains.yml +1 -1
  285. ansible/plugins/test/core.py +1 -1
  286. ansible/plugins/test/directory.yml +1 -1
  287. ansible/plugins/test/exists.yml +3 -2
  288. ansible/plugins/test/failed.yml +2 -2
  289. ansible/plugins/test/failure.yml +2 -2
  290. ansible/plugins/test/falsy.yml +2 -2
  291. ansible/plugins/test/file.yml +1 -1
  292. ansible/plugins/test/finished.yml +2 -2
  293. ansible/plugins/test/is_abs.yml +1 -1
  294. ansible/plugins/test/is_dir.yml +1 -1
  295. ansible/plugins/test/is_file.yml +1 -1
  296. ansible/plugins/test/is_link.yml +1 -1
  297. ansible/plugins/test/is_mount.yml +1 -1
  298. ansible/plugins/test/is_same_file.yml +1 -1
  299. ansible/plugins/test/isnan.yml +1 -1
  300. ansible/plugins/test/issubset.yml +1 -2
  301. ansible/plugins/test/issuperset.yml +1 -2
  302. ansible/plugins/test/link.yml +1 -1
  303. ansible/plugins/test/link_exists.yml +1 -1
  304. ansible/plugins/test/match.yml +2 -2
  305. ansible/plugins/test/mount.yml +1 -1
  306. ansible/plugins/test/nan.yml +1 -1
  307. ansible/plugins/test/reachable.yml +2 -2
  308. ansible/plugins/test/regex.yml +1 -1
  309. ansible/plugins/test/same_file.yml +1 -1
  310. ansible/plugins/test/search.yml +2 -2
  311. ansible/plugins/test/skip.yml +3 -3
  312. ansible/plugins/test/skipped.yml +3 -3
  313. ansible/plugins/test/started.yml +2 -2
  314. ansible/plugins/test/subset.yml +1 -2
  315. ansible/plugins/test/succeeded.yml +2 -2
  316. ansible/plugins/test/success.yml +2 -2
  317. ansible/plugins/test/successful.yml +2 -2
  318. ansible/plugins/test/superset.yml +1 -2
  319. ansible/plugins/test/truthy.yml +3 -3
  320. ansible/plugins/test/unreachable.yml +2 -2
  321. ansible/plugins/test/uri.yml +1 -1
  322. ansible/plugins/test/url.yml +1 -1
  323. ansible/plugins/test/urn.yml +1 -1
  324. ansible/plugins/test/vault_encrypted.yml +1 -1
  325. ansible/plugins/test/version.yml +7 -7
  326. ansible/plugins/test/version_compare.yml +7 -7
  327. ansible/plugins/vars/host_group_vars.py +1 -1
  328. ansible/release.py +2 -2
  329. ansible/template/__init__.py +24 -26
  330. ansible/template/native_helpers.py +1 -1
  331. ansible/template/vars.py +1 -1
  332. ansible/utils/_junit_xml.py +1 -1
  333. ansible/utils/cmd_functions.py +1 -1
  334. ansible/utils/collection_loader/_collection_finder.py +12 -1
  335. ansible/utils/display.py +113 -62
  336. ansible/utils/encrypt.py +11 -14
  337. ansible/utils/hashing.py +1 -1
  338. ansible/utils/jsonrpc.py +1 -1
  339. ansible/utils/path.py +1 -1
  340. ansible/utils/plugin_docs.py +1 -1
  341. ansible/utils/py3compat.py +1 -1
  342. ansible/utils/shlex.py +2 -10
  343. ansible/utils/ssh_functions.py +5 -4
  344. ansible/utils/unicode.py +1 -1
  345. ansible/utils/unsafe_proxy.py +1 -1
  346. ansible/utils/vars.py +4 -29
  347. ansible/vars/hostvars.py +1 -2
  348. ansible/vars/manager.py +13 -9
  349. ansible/vars/plugins.py +2 -2
  350. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/COPYING +4 -5
  351. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/METADATA +2 -4
  352. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/RECORD +424 -425
  353. ansible_test/_data/completion/docker.txt +9 -9
  354. ansible_test/_data/completion/remote.txt +4 -7
  355. ansible_test/_data/completion/windows.txt +0 -2
  356. ansible_test/_data/requirements/ansible-test.txt +2 -1
  357. ansible_test/_data/requirements/ansible.txt +0 -3
  358. ansible_test/_data/requirements/constraints.txt +0 -2
  359. ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -5
  360. ansible_test/_data/requirements/sanity.changelog.in +1 -2
  361. ansible_test/_data/requirements/sanity.changelog.txt +4 -6
  362. ansible_test/_data/requirements/sanity.import.plugin.txt +2 -4
  363. ansible_test/_data/requirements/sanity.import.txt +1 -3
  364. ansible_test/_data/requirements/sanity.integration-aliases.txt +1 -3
  365. ansible_test/_data/requirements/sanity.mypy.txt +12 -12
  366. ansible_test/_data/requirements/sanity.pep8.txt +1 -1
  367. ansible_test/_data/requirements/sanity.pylint.txt +6 -12
  368. ansible_test/_data/requirements/sanity.runtime-metadata.txt +1 -3
  369. ansible_test/_data/requirements/sanity.validate-modules.in +1 -1
  370. ansible_test/_data/requirements/sanity.validate-modules.txt +3 -5
  371. ansible_test/_data/requirements/sanity.yamllint.txt +3 -5
  372. ansible_test/_data/requirements/units.txt +0 -1
  373. ansible_test/_internal/ci/azp.py +4 -4
  374. ansible_test/_internal/cli/environments.py +0 -13
  375. ansible_test/_internal/commands/coverage/analyze/targets/__init__.py +4 -4
  376. ansible_test/_internal/commands/coverage/combine.py +1 -1
  377. ansible_test/_internal/commands/integration/cloud/acme.py +6 -8
  378. ansible_test/_internal/commands/integration/cloud/cs.py +4 -9
  379. ansible_test/_internal/commands/integration/cloud/galaxy.py +103 -96
  380. ansible_test/_internal/commands/integration/cloud/httptester.py +0 -3
  381. ansible_test/_internal/commands/integration/cloud/nios.py +7 -9
  382. ansible_test/_internal/commands/integration/cloud/openshift.py +2 -7
  383. ansible_test/_internal/commands/integration/cloud/vcenter.py +11 -95
  384. ansible_test/_internal/commands/sanity/__init__.py +10 -0
  385. ansible_test/_internal/commands/sanity/import.py +8 -2
  386. ansible_test/_internal/commands/sanity/pylint.py +27 -1
  387. ansible_test/_internal/commands/units/__init__.py +2 -1
  388. ansible_test/_internal/config.py +0 -7
  389. ansible_test/_internal/containers.py +11 -56
  390. ansible_test/_internal/core_ci.py +0 -7
  391. ansible_test/_internal/coverage_util.py +8 -3
  392. ansible_test/_internal/delegation.py +0 -1
  393. ansible_test/_internal/diff.py +1 -1
  394. ansible_test/_internal/docker_util.py +9 -2
  395. ansible_test/_internal/host_profiles.py +6 -6
  396. ansible_test/_internal/http.py +1 -1
  397. ansible_test/_internal/junit_xml.py +1 -1
  398. ansible_test/_internal/pypi_proxy.py +1 -1
  399. ansible_test/_internal/python_requirements.py +3 -8
  400. ansible_test/_internal/util.py +1 -6
  401. ansible_test/_util/controller/sanity/code-smell/no-get-exception.json +4 -0
  402. ansible_test/_util/controller/sanity/code-smell/replace-urlopen.json +4 -0
  403. ansible_test/_util/controller/sanity/code-smell/use-compat-six.json +4 -0
  404. ansible_test/_util/controller/sanity/mypy/ansible-core.ini +3 -0
  405. ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +2 -0
  406. ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +0 -1
  407. ansible_test/_util/controller/sanity/pylint/config/collection.cfg +1 -0
  408. ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +172 -10
  409. ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +13 -2
  410. ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +7 -1
  411. ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +6 -6
  412. ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +1 -1
  413. ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -1
  414. ansible_test/_util/controller/sanity/yamllint/yamllinter.py +3 -3
  415. ansible_test/_util/controller/tools/collection_detail.py +2 -2
  416. ansible_test/_util/target/common/constants.py +2 -2
  417. ansible_test/_util/target/pytest/plugins/ansible_forked.py +103 -0
  418. ansible_test/_util/target/sanity/import/importer.py +0 -8
  419. ansible_test/_util/target/setup/bootstrap.sh +36 -16
  420. ansible_test/_util/target/setup/quiet_pip.py +0 -4
  421. ansible/modules/_include.py +0 -80
  422. ansible_test/_internal/commands/integration/cloud/foreman.py +0 -102
  423. ansible_test/_util/target/setup/ConfigureRemotingForAnsible.ps1 +0 -435
  424. {ansible_core-2.15.4rc1.data → ansible_core-2.16.0b2.data}/scripts/ansible-test +0 -0
  425. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/WHEEL +0 -0
  426. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/entry_points.txt +0 -0
  427. {ansible_core-2.15.4rc1.dist-info → ansible_core-2.16.0b2.dist-info}/top_level.txt +0 -0
@@ -2,10 +2,12 @@
2
2
  # (c) 2015 Toshio Kuratomi <tkuratomi@ansible.com>
3
3
  # (c) 2017, Peter Sprygada <psprygad@redhat.com>
4
4
  # (c) 2017 Ansible Project
5
- from __future__ import (absolute_import, division, print_function)
5
+ from __future__ import (annotations, absolute_import, division, print_function)
6
6
  __metaclass__ = type
7
7
 
8
+ import collections.abc as c
8
9
  import fcntl
10
+ import io
9
11
  import os
10
12
  import shlex
11
13
  import typing as t
@@ -14,8 +16,11 @@ from abc import abstractmethod
14
16
  from functools import wraps
15
17
 
16
18
  from ansible import constants as C
17
- from ansible.module_utils._text import to_bytes, to_text
19
+ from ansible.module_utils.common.text.converters import to_bytes, to_text
20
+ from ansible.playbook.play_context import PlayContext
18
21
  from ansible.plugins import AnsiblePlugin
22
+ from ansible.plugins.become import BecomeBase
23
+ from ansible.plugins.shell import ShellBase
19
24
  from ansible.utils.display import Display
20
25
  from ansible.plugins.loader import connection_loader, get_shell_plugin
21
26
  from ansible.utils.path import unfrackpath
@@ -27,10 +32,15 @@ __all__ = ['ConnectionBase', 'ensure_connect']
27
32
 
28
33
  BUFSIZE = 65536
29
34
 
35
+ P = t.ParamSpec('P')
36
+ T = t.TypeVar('T')
30
37
 
31
- def ensure_connect(func):
38
+
39
+ def ensure_connect(
40
+ func: c.Callable[t.Concatenate[ConnectionBase, P], T],
41
+ ) -> c.Callable[t.Concatenate[ConnectionBase, P], T]:
32
42
  @wraps(func)
33
- def wrapped(self, *args, **kwargs):
43
+ def wrapped(self: ConnectionBase, *args: P.args, **kwargs: P.kwargs) -> T:
34
44
  if not self._connected:
35
45
  self._connect()
36
46
  return func(self, *args, **kwargs)
@@ -57,9 +67,16 @@ class ConnectionBase(AnsiblePlugin):
57
67
  supports_persistence = False
58
68
  force_persistence = False
59
69
 
60
- default_user = None
70
+ default_user: str | None = None
61
71
 
62
- def __init__(self, play_context, new_stdin=None, shell=None, *args, **kwargs):
72
+ def __init__(
73
+ self,
74
+ play_context: PlayContext,
75
+ new_stdin: io.TextIOWrapper | None = None,
76
+ shell: ShellBase | None = None,
77
+ *args: t.Any,
78
+ **kwargs: t.Any,
79
+ ) -> None:
63
80
 
64
81
  super(ConnectionBase, self).__init__()
65
82
 
@@ -77,7 +94,7 @@ class ConnectionBase(AnsiblePlugin):
77
94
  self.success_key = None
78
95
  self.prompt = None
79
96
  self._connected = False
80
- self._socket_path = None
97
+ self._socket_path: str | None = None
81
98
 
82
99
  # helper plugins
83
100
  self._shell = shell
@@ -87,10 +104,10 @@ class ConnectionBase(AnsiblePlugin):
87
104
  shell_type = play_context.shell if play_context.shell else getattr(self, '_shell_type', None)
88
105
  self._shell = get_shell_plugin(shell_type=shell_type, executable=self._play_context.executable)
89
106
 
90
- self.become = None
107
+ self.become: BecomeBase | None = None
91
108
 
92
109
  @property
93
- def _new_stdin(self):
110
+ def _new_stdin(self) -> io.TextIOWrapper | None:
94
111
  display.deprecated(
95
112
  "The connection's stdin object is deprecated. "
96
113
  "Call display.prompt_until(msg) instead.",
@@ -98,21 +115,21 @@ class ConnectionBase(AnsiblePlugin):
98
115
  )
99
116
  return self.__new_stdin
100
117
 
101
- def set_become_plugin(self, plugin):
118
+ def set_become_plugin(self, plugin: BecomeBase) -> None:
102
119
  self.become = plugin
103
120
 
104
121
  @property
105
- def connected(self):
122
+ def connected(self) -> bool:
106
123
  '''Read-only property holding whether the connection to the remote host is active or closed.'''
107
124
  return self._connected
108
125
 
109
126
  @property
110
- def socket_path(self):
127
+ def socket_path(self) -> str | None:
111
128
  '''Read-only property holding the connection socket path for this remote host'''
112
129
  return self._socket_path
113
130
 
114
131
  @staticmethod
115
- def _split_ssh_args(argstring):
132
+ def _split_ssh_args(argstring: str) -> list[str]:
116
133
  """
117
134
  Takes a string like '-o Foo=1 -o Bar="foo bar"' and returns a
118
135
  list ['-o', 'Foo=1', '-o', 'Bar=foo bar'] that can be added to
@@ -123,17 +140,17 @@ class ConnectionBase(AnsiblePlugin):
123
140
 
124
141
  @property
125
142
  @abstractmethod
126
- def transport(self):
143
+ def transport(self) -> str:
127
144
  """String used to identify this Connection class from other classes"""
128
145
  pass
129
146
 
130
147
  @abstractmethod
131
- def _connect(self):
148
+ def _connect(self: T) -> T:
132
149
  """Connect to the host we've been initialized with"""
133
150
 
134
151
  @ensure_connect
135
152
  @abstractmethod
136
- def exec_command(self, cmd, in_data=None, sudoable=True):
153
+ def exec_command(self, cmd: str, in_data: bytes | None = None, sudoable: bool = True) -> tuple[int, bytes, bytes]:
137
154
  """Run a command on the remote host.
138
155
 
139
156
  :arg cmd: byte string containing the command
@@ -201,36 +218,36 @@ class ConnectionBase(AnsiblePlugin):
201
218
 
202
219
  @ensure_connect
203
220
  @abstractmethod
204
- def put_file(self, in_path, out_path):
221
+ def put_file(self, in_path: str, out_path: str) -> None:
205
222
  """Transfer a file from local to remote"""
206
223
  pass
207
224
 
208
225
  @ensure_connect
209
226
  @abstractmethod
210
- def fetch_file(self, in_path, out_path):
227
+ def fetch_file(self, in_path: str, out_path: str) -> None:
211
228
  """Fetch a file from remote to local; callers are expected to have pre-created the directory chain for out_path"""
212
229
  pass
213
230
 
214
231
  @abstractmethod
215
- def close(self):
232
+ def close(self) -> None:
216
233
  """Terminate the connection"""
217
234
  pass
218
235
 
219
- def connection_lock(self):
236
+ def connection_lock(self) -> None:
220
237
  f = self._play_context.connection_lockfd
221
238
  display.vvvv('CONNECTION: pid %d waiting for lock on %d' % (os.getpid(), f), host=self._play_context.remote_addr)
222
239
  fcntl.lockf(f, fcntl.LOCK_EX)
223
240
  display.vvvv('CONNECTION: pid %d acquired lock on %d' % (os.getpid(), f), host=self._play_context.remote_addr)
224
241
 
225
- def connection_unlock(self):
242
+ def connection_unlock(self) -> None:
226
243
  f = self._play_context.connection_lockfd
227
244
  fcntl.lockf(f, fcntl.LOCK_UN)
228
245
  display.vvvv('CONNECTION: pid %d released lock on %d' % (os.getpid(), f), host=self._play_context.remote_addr)
229
246
 
230
- def reset(self):
247
+ def reset(self) -> None:
231
248
  display.warning("Reset is not implemented for this connection")
232
249
 
233
- def update_vars(self, variables):
250
+ def update_vars(self, variables: dict[str, t.Any]) -> None:
234
251
  '''
235
252
  Adds 'magic' variables relating to connections to the variable dictionary provided.
236
253
  In case users need to access from the play, this is a legacy from runner.
@@ -246,7 +263,7 @@ class ConnectionBase(AnsiblePlugin):
246
263
  elif varname == 'ansible_connection':
247
264
  # its me mom!
248
265
  value = self._load_name
249
- elif varname == 'ansible_shell_type':
266
+ elif varname == 'ansible_shell_type' and self._shell:
250
267
  # its my cousin ...
251
268
  value = self._shell._load_name
252
269
  else:
@@ -279,9 +296,15 @@ class NetworkConnectionBase(ConnectionBase):
279
296
  # Do not use _remote_is_local in other connections
280
297
  _remote_is_local = True
281
298
 
282
- def __init__(self, play_context, new_stdin=None, *args, **kwargs):
299
+ def __init__(
300
+ self,
301
+ play_context: PlayContext,
302
+ new_stdin: io.TextIOWrapper | None = None,
303
+ *args: t.Any,
304
+ **kwargs: t.Any,
305
+ ) -> None:
283
306
  super(NetworkConnectionBase, self).__init__(play_context, new_stdin, *args, **kwargs)
284
- self._messages = []
307
+ self._messages: list[tuple[str, str]] = []
285
308
  self._conn_closed = False
286
309
 
287
310
  self._network_os = self._play_context.network_os
@@ -289,7 +312,7 @@ class NetworkConnectionBase(ConnectionBase):
289
312
  self._local = connection_loader.get('local', play_context, '/dev/null')
290
313
  self._local.set_options()
291
314
 
292
- self._sub_plugin = {}
315
+ self._sub_plugin: dict[str, t.Any] = {}
293
316
  self._cached_variables = (None, None, None)
294
317
 
295
318
  # reconstruct the socket_path and set instance values accordingly
@@ -308,10 +331,10 @@ class NetworkConnectionBase(ConnectionBase):
308
331
  return method
309
332
  raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, name))
310
333
 
311
- def exec_command(self, cmd, in_data=None, sudoable=True):
334
+ def exec_command(self, cmd: str, in_data: bytes | None = None, sudoable: bool = True) -> tuple[int, bytes, bytes]:
312
335
  return self._local.exec_command(cmd, in_data, sudoable)
313
336
 
314
- def queue_message(self, level, message):
337
+ def queue_message(self, level: str, message: str) -> None:
315
338
  """
316
339
  Adds a message to the queue of messages waiting to be pushed back to the controller process.
317
340
 
@@ -321,19 +344,19 @@ class NetworkConnectionBase(ConnectionBase):
321
344
  """
322
345
  self._messages.append((level, message))
323
346
 
324
- def pop_messages(self):
347
+ def pop_messages(self) -> list[tuple[str, str]]:
325
348
  messages, self._messages = self._messages, []
326
349
  return messages
327
350
 
328
- def put_file(self, in_path, out_path):
351
+ def put_file(self, in_path: str, out_path: str) -> None:
329
352
  """Transfer a file from local to remote"""
330
353
  return self._local.put_file(in_path, out_path)
331
354
 
332
- def fetch_file(self, in_path, out_path):
355
+ def fetch_file(self, in_path: str, out_path: str) -> None:
333
356
  """Fetch a file from remote to local"""
334
357
  return self._local.fetch_file(in_path, out_path)
335
358
 
336
- def reset(self):
359
+ def reset(self) -> None:
337
360
  '''
338
361
  Reset the connection
339
362
  '''
@@ -342,12 +365,17 @@ class NetworkConnectionBase(ConnectionBase):
342
365
  self.close()
343
366
  self.queue_message('vvvv', 'reset call on connection instance')
344
367
 
345
- def close(self):
368
+ def close(self) -> None:
346
369
  self._conn_closed = True
347
370
  if self._connected:
348
371
  self._connected = False
349
372
 
350
- def set_options(self, task_keys=None, var_options=None, direct=None):
373
+ def set_options(
374
+ self,
375
+ task_keys: dict[str, t.Any] | None = None,
376
+ var_options: dict[str, t.Any] | None = None,
377
+ direct: dict[str, t.Any] | None = None,
378
+ ) -> None:
351
379
  super(NetworkConnectionBase, self).set_options(task_keys=task_keys, var_options=var_options, direct=direct)
352
380
  if self.get_option('persistent_log_messages'):
353
381
  warning = "Persistent connection logging is enabled for %s. This will log ALL interactions" % self._play_context.remote_addr
@@ -362,7 +390,7 @@ class NetworkConnectionBase(ConnectionBase):
362
390
  except AttributeError:
363
391
  pass
364
392
 
365
- def _update_connection_state(self):
393
+ def _update_connection_state(self) -> None:
366
394
  '''
367
395
  Reconstruct the connection socket_path and check if it exists
368
396
 
@@ -385,6 +413,6 @@ class NetworkConnectionBase(ConnectionBase):
385
413
  self._connected = True
386
414
  self._socket_path = socket_path
387
415
 
388
- def _log_messages(self, message):
416
+ def _log_messages(self, message: str) -> None:
389
417
  if self.get_option('persistent_log_messages'):
390
418
  self.queue_message('log', message)
@@ -2,7 +2,7 @@
2
2
  # (c) 2015, 2017 Toshio Kuratomi <tkuratomi@ansible.com>
3
3
  # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
4
4
 
5
- from __future__ import (absolute_import, division, print_function)
5
+ from __future__ import (annotations, absolute_import, division, print_function)
6
6
  __metaclass__ = type
7
7
 
8
8
  DOCUMENTATION = '''
@@ -24,12 +24,13 @@ import os
24
24
  import pty
25
25
  import shutil
26
26
  import subprocess
27
+ import typing as t
27
28
 
28
29
  import ansible.constants as C
29
30
  from ansible.errors import AnsibleError, AnsibleFileNotFound
30
31
  from ansible.module_utils.compat import selectors
31
32
  from ansible.module_utils.six import text_type, binary_type
32
- from ansible.module_utils._text import to_bytes, to_native, to_text
33
+ from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
33
34
  from ansible.plugins.connection import ConnectionBase
34
35
  from ansible.utils.display import Display
35
36
  from ansible.utils.path import unfrackpath
@@ -43,7 +44,7 @@ class Connection(ConnectionBase):
43
44
  transport = 'local'
44
45
  has_pipelining = True
45
46
 
46
- def __init__(self, *args, **kwargs):
47
+ def __init__(self, *args: t.Any, **kwargs: t.Any) -> None:
47
48
 
48
49
  super(Connection, self).__init__(*args, **kwargs)
49
50
  self.cwd = None
@@ -53,7 +54,7 @@ class Connection(ConnectionBase):
53
54
  display.vv("Current user (uid=%s) does not seem to exist on this system, leaving user empty." % os.getuid())
54
55
  self.default_user = ""
55
56
 
56
- def _connect(self):
57
+ def _connect(self) -> Connection:
57
58
  ''' connect to the local host; nothing to do here '''
58
59
 
59
60
  # Because we haven't made any remote connection we're running as
@@ -65,7 +66,7 @@ class Connection(ConnectionBase):
65
66
  self._connected = True
66
67
  return self
67
68
 
68
- def exec_command(self, cmd, in_data=None, sudoable=True):
69
+ def exec_command(self, cmd: str, in_data: bytes | None = None, sudoable: bool = True) -> tuple[int, bytes, bytes]:
69
70
  ''' run a command on the local host '''
70
71
 
71
72
  super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
@@ -163,7 +164,7 @@ class Connection(ConnectionBase):
163
164
  display.debug("done with local.exec_command()")
164
165
  return (p.returncode, stdout, stderr)
165
166
 
166
- def put_file(self, in_path, out_path):
167
+ def put_file(self, in_path: str, out_path: str) -> None:
167
168
  ''' transfer a file from local to local '''
168
169
 
169
170
  super(Connection, self).put_file(in_path, out_path)
@@ -181,7 +182,7 @@ class Connection(ConnectionBase):
181
182
  except IOError as e:
182
183
  raise AnsibleError("failed to transfer file to {0}: {1}".format(to_native(out_path), to_native(e)))
183
184
 
184
- def fetch_file(self, in_path, out_path):
185
+ def fetch_file(self, in_path: str, out_path: str) -> None:
185
186
  ''' fetch a file from local to local -- for compatibility '''
186
187
 
187
188
  super(Connection, self).fetch_file(in_path, out_path)
@@ -189,6 +190,6 @@ class Connection(ConnectionBase):
189
190
  display.vvv(u"FETCH {0} TO {1}".format(in_path, out_path), host=self._play_context.remote_addr)
190
191
  self.put_file(in_path, out_path)
191
192
 
192
- def close(self):
193
+ def close(self) -> None:
193
194
  ''' terminate the connection; nothing to do here '''
194
195
  self._connected = False
@@ -1,15 +1,15 @@
1
1
  # (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
2
2
  # (c) 2017 Ansible Project
3
3
  # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
4
- from __future__ import (absolute_import, division, print_function)
4
+ from __future__ import (annotations, absolute_import, division, print_function)
5
5
  __metaclass__ = type
6
6
 
7
7
  DOCUMENTATION = """
8
8
  author: Ansible Core Team
9
9
  name: paramiko
10
- short_description: Run tasks via python ssh (paramiko)
10
+ short_description: Run tasks via Python SSH (paramiko)
11
11
  description:
12
- - Use the python ssh implementation (Paramiko) to connect to targets
12
+ - Use the Python SSH implementation (Paramiko) to connect to targets
13
13
  - The paramiko transport is provided because many distributions, in particular EL6 and before do not support ControlPersist
14
14
  in their SSH implementations.
15
15
  - This is needed on the Ansible control machine to be reasonably efficient with connections.
@@ -86,7 +86,7 @@ DOCUMENTATION = """
86
86
  description:
87
87
  - Whether or not to enable RSA SHA2 algorithms for pubkeys and hostkeys
88
88
  - On paramiko versions older than 2.9, this only affects hostkeys
89
- - For behavior matching paramiko<2.9 set this to C(False)
89
+ - For behavior matching paramiko<2.9 set this to V(False)
90
90
  vars:
91
91
  - name: ansible_paramiko_use_rsa_sha2_algorithms
92
92
  ini:
@@ -293,6 +293,7 @@ import tempfile
293
293
  import traceback
294
294
  import fcntl
295
295
  import re
296
+ import typing as t
296
297
 
297
298
  from ansible.module_utils.compat.version import LooseVersion
298
299
  from binascii import hexlify
@@ -307,7 +308,7 @@ from ansible.module_utils.compat.paramiko import PARAMIKO_IMPORT_ERR, paramiko
307
308
  from ansible.plugins.connection import ConnectionBase
308
309
  from ansible.utils.display import Display
309
310
  from ansible.utils.path import makedirs_safe
310
- from ansible.module_utils._text import to_bytes, to_native, to_text
311
+ from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
311
312
 
312
313
  display = Display()
313
314
 
@@ -321,8 +322,12 @@ Are you sure you want to continue connecting (yes/no)?
321
322
  # SSH Options Regex
322
323
  SETTINGS_REGEX = re.compile(r'(\w+)(?:\s*=\s*|\s+)(.+)')
323
324
 
325
+ MissingHostKeyPolicy: type = object
326
+ if paramiko:
327
+ MissingHostKeyPolicy = paramiko.MissingHostKeyPolicy
324
328
 
325
- class MyAddPolicy(object):
329
+
330
+ class MyAddPolicy(MissingHostKeyPolicy):
326
331
  """
327
332
  Based on AutoAddPolicy in paramiko so we can determine when keys are added
328
333
 
@@ -332,11 +337,11 @@ class MyAddPolicy(object):
332
337
  local L{HostKeys} object, and saving it. This is used by L{SSHClient}.
333
338
  """
334
339
 
335
- def __init__(self, connection):
340
+ def __init__(self, connection: Connection) -> None:
336
341
  self.connection = connection
337
342
  self._options = connection._options
338
343
 
339
- def missing_host_key(self, client, hostname, key):
344
+ def missing_host_key(self, client, hostname, key) -> None:
340
345
 
341
346
  if all((self.connection.get_option('host_key_checking'), not self.connection.get_option('host_key_auto_add'))):
342
347
 
@@ -367,20 +372,20 @@ class MyAddPolicy(object):
367
372
 
368
373
  # keep connection objects on a per host basis to avoid repeated attempts to reconnect
369
374
 
370
- SSH_CONNECTION_CACHE = {} # type: dict[str, paramiko.client.SSHClient]
371
- SFTP_CONNECTION_CACHE = {} # type: dict[str, paramiko.sftp_client.SFTPClient]
375
+ SSH_CONNECTION_CACHE: dict[str, paramiko.client.SSHClient] = {}
376
+ SFTP_CONNECTION_CACHE: dict[str, paramiko.sftp_client.SFTPClient] = {}
372
377
 
373
378
 
374
379
  class Connection(ConnectionBase):
375
380
  ''' SSH based connections with Paramiko '''
376
381
 
377
382
  transport = 'paramiko'
378
- _log_channel = None
383
+ _log_channel: str | None = None
379
384
 
380
- def _cache_key(self):
385
+ def _cache_key(self) -> str:
381
386
  return "%s__%s__" % (self.get_option('remote_addr'), self.get_option('remote_user'))
382
387
 
383
- def _connect(self):
388
+ def _connect(self) -> Connection:
384
389
  cache_key = self._cache_key()
385
390
  if cache_key in SSH_CONNECTION_CACHE:
386
391
  self.ssh = SSH_CONNECTION_CACHE[cache_key]
@@ -390,11 +395,11 @@ class Connection(ConnectionBase):
390
395
  self._connected = True
391
396
  return self
392
397
 
393
- def _set_log_channel(self, name):
398
+ def _set_log_channel(self, name: str) -> None:
394
399
  '''Mimic paramiko.SSHClient.set_log_channel'''
395
400
  self._log_channel = name
396
401
 
397
- def _parse_proxy_command(self, port=22):
402
+ def _parse_proxy_command(self, port: int = 22) -> dict[str, t.Any]:
398
403
  proxy_command = None
399
404
  # Parse ansible_ssh_common_args, specifically looking for ProxyCommand
400
405
  ssh_args = [
@@ -439,7 +444,7 @@ class Connection(ConnectionBase):
439
444
 
440
445
  return sock_kwarg
441
446
 
442
- def _connect_uncached(self):
447
+ def _connect_uncached(self) -> paramiko.SSHClient:
443
448
  ''' activates the connection object '''
444
449
 
445
450
  if paramiko is None:
@@ -453,10 +458,11 @@ class Connection(ConnectionBase):
453
458
 
454
459
  # Set pubkey and hostkey algorithms to disable, the only manipulation allowed currently
455
460
  # is keeping or omitting rsa-sha2 algorithms
461
+ # default_keys: t.Tuple[str] = ()
456
462
  paramiko_preferred_pubkeys = getattr(paramiko.Transport, '_preferred_pubkeys', ())
457
463
  paramiko_preferred_hostkeys = getattr(paramiko.Transport, '_preferred_keys', ())
458
464
  use_rsa_sha2_algorithms = self.get_option('use_rsa_sha2_algorithms')
459
- disabled_algorithms = {}
465
+ disabled_algorithms: t.Dict[str, t.Iterable[str]] = {}
460
466
  if not use_rsa_sha2_algorithms:
461
467
  if paramiko_preferred_pubkeys:
462
468
  disabled_algorithms['pubkeys'] = tuple(a for a in paramiko_preferred_pubkeys if 'rsa-sha2' in a)
@@ -533,7 +539,7 @@ class Connection(ConnectionBase):
533
539
 
534
540
  return ssh
535
541
 
536
- def exec_command(self, cmd, in_data=None, sudoable=True):
542
+ def exec_command(self, cmd: str, in_data: bytes | None = None, sudoable: bool = True) -> tuple[int, bytes, bytes]:
537
543
  ''' run a command on the remote host '''
538
544
 
539
545
  super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
@@ -576,7 +582,7 @@ class Connection(ConnectionBase):
576
582
  display.debug('Waiting for Privilege Escalation input')
577
583
 
578
584
  chunk = chan.recv(bufsize)
579
- display.debug("chunk is: %s" % chunk)
585
+ display.debug("chunk is: %r" % chunk)
580
586
  if not chunk:
581
587
  if b'unknown user' in become_output:
582
588
  n_become_user = to_native(self.become.get_option('become_user'))
@@ -606,14 +612,14 @@ class Connection(ConnectionBase):
606
612
  no_prompt_out += become_output
607
613
  no_prompt_err += become_output
608
614
  except socket.timeout:
609
- raise AnsibleError('ssh timed out waiting for privilege escalation.\n' + become_output)
615
+ raise AnsibleError('ssh timed out waiting for privilege escalation.\n' + to_text(become_output))
610
616
 
611
617
  stdout = b''.join(chan.makefile('rb', bufsize))
612
618
  stderr = b''.join(chan.makefile_stderr('rb', bufsize))
613
619
 
614
620
  return (chan.recv_exit_status(), no_prompt_out + stdout, no_prompt_out + stderr)
615
621
 
616
- def put_file(self, in_path, out_path):
622
+ def put_file(self, in_path: str, out_path: str) -> None:
617
623
  ''' transfer a file from local to remote '''
618
624
 
619
625
  super(Connection, self).put_file(in_path, out_path)
@@ -633,7 +639,7 @@ class Connection(ConnectionBase):
633
639
  except IOError:
634
640
  raise AnsibleError("failed to transfer file to %s" % out_path)
635
641
 
636
- def _connect_sftp(self):
642
+ def _connect_sftp(self) -> paramiko.sftp_client.SFTPClient:
637
643
 
638
644
  cache_key = "%s__%s__" % (self.get_option('remote_addr'), self.get_option('remote_user'))
639
645
  if cache_key in SFTP_CONNECTION_CACHE:
@@ -642,7 +648,7 @@ class Connection(ConnectionBase):
642
648
  result = SFTP_CONNECTION_CACHE[cache_key] = self._connect().ssh.open_sftp()
643
649
  return result
644
650
 
645
- def fetch_file(self, in_path, out_path):
651
+ def fetch_file(self, in_path: str, out_path: str) -> None:
646
652
  ''' save a remote file to the specified path '''
647
653
 
648
654
  super(Connection, self).fetch_file(in_path, out_path)
@@ -659,7 +665,7 @@ class Connection(ConnectionBase):
659
665
  except IOError:
660
666
  raise AnsibleError("failed to transfer file from %s" % in_path)
661
667
 
662
- def _any_keys_added(self):
668
+ def _any_keys_added(self) -> bool:
663
669
 
664
670
  for hostname, keys in self.ssh._host_keys.items():
665
671
  for keytype, key in keys.items():
@@ -668,14 +674,14 @@ class Connection(ConnectionBase):
668
674
  return True
669
675
  return False
670
676
 
671
- def _save_ssh_host_keys(self, filename):
677
+ def _save_ssh_host_keys(self, filename: str) -> None:
672
678
  '''
673
679
  not using the paramiko save_ssh_host_keys function as we want to add new SSH keys at the bottom so folks
674
680
  don't complain about it :)
675
681
  '''
676
682
 
677
683
  if not self._any_keys_added():
678
- return False
684
+ return
679
685
 
680
686
  path = os.path.expanduser("~/.ssh")
681
687
  makedirs_safe(path)
@@ -698,13 +704,13 @@ class Connection(ConnectionBase):
698
704
  if added_this_time:
699
705
  f.write("%s %s %s\n" % (hostname, keytype, key.get_base64()))
700
706
 
701
- def reset(self):
707
+ def reset(self) -> None:
702
708
  if not self._connected:
703
709
  return
704
710
  self.close()
705
711
  self._connect()
706
712
 
707
- def close(self):
713
+ def close(self) -> None:
708
714
  ''' terminate the connection '''
709
715
 
710
716
  cache_key = self._cache_key()