|
315 | 315 | import shlex |
316 | 316 | import socket |
317 | 317 | import tempfile |
| 318 | +import traceback |
318 | 319 | import typing as t |
319 | 320 |
|
320 | 321 | from ansible.errors import ( |
|
323 | 324 | AnsibleError, |
324 | 325 | ) |
325 | 326 | from ansible_collections.community.general.plugins.module_utils._filelock import FileLock, LockTimeout |
| 327 | +from ansible_collections.community.general.plugins.module_utils.version import LooseVersion |
326 | 328 | from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text |
327 | | -from ansible.module_utils.compat.paramiko import PARAMIKO_IMPORT_ERR, paramiko |
328 | | -from ansible.module_utils.compat.version import LooseVersion |
329 | 329 | from ansible.playbook.play_context import PlayContext |
330 | 330 | from ansible.plugins.connection import ConnectionBase |
331 | 331 | from ansible.utils.display import Display |
332 | 332 | from ansible.utils.path import makedirs_safe |
333 | 333 | from binascii import hexlify |
334 | 334 | from subprocess import list2cmdline |
335 | 335 |
|
| 336 | +try: |
| 337 | + import paramiko |
| 338 | + PARAMIKO_IMPORT_ERR = None |
| 339 | +except ImportError: |
| 340 | + paramiko = None |
| 341 | + PARAMIKO_IMPORT_ERR = traceback.format_exc() |
336 | 342 |
|
337 | | -if t.TYPE_CHECKING and paramiko: |
| 343 | + |
| 344 | +if t.TYPE_CHECKING and PARAMIKO_IMPORT_ERR is None: |
338 | 345 | from paramiko import MissingHostKeyPolicy |
339 | 346 | from paramiko.client import SSHClient |
340 | 347 | from paramiko.pkey import PKey |
@@ -437,7 +444,7 @@ def _parse_proxy_command(self, port: int = 22) -> dict[str, t.Any]: |
437 | 444 | def _connect(self) -> Connection: |
438 | 445 | """ activates the connection object """ |
439 | 446 |
|
440 | | - if paramiko is None: |
| 447 | + if PARAMIKO_IMPORT_ERR is not None: |
441 | 448 | raise AnsibleError(f'paramiko is not installed: {to_native(PARAMIKO_IMPORT_ERR)}') |
442 | 449 |
|
443 | 450 | port = self.get_option('port') |
|
0 commit comments