Skip to content

Python 3.13 support: vendor telnetlib, paramiko 3.x — cloudshell-cli 6.0 - #138

Merged
nahumtimerman merged 1 commit into
masterfrom
feature/python313
Sep 6, 2026
Merged

Python 3.13 support: vendor telnetlib, paramiko 3.x — cloudshell-cli 6.0#138
nahumtimerman merged 1 commit into
masterfrom
feature/python313

Conversation

@nahumtimerman

Copy link
Copy Markdown
Contributor

Why

cloudshell-cli 5.0.2 cannot run on Python 3.13:

  1. telnetlib was removed from the stdlib in Python 3.13 (PEP 594) — TelnetSession fails at import.
  2. paramiko~=2.12 is EOL-ish and creates friction with modern cryptography (the ecosystem now ships cryptography>=43 via cloudshell-snmp 6.0).

What changed

  • Vendored telnetlib: CPython 3.12's Lib/telnetlib.py copied to cloudshell/cli/session/_telnetlib.py (PSF-2.0, provenance header, CLI test()/__main__ scaffolding and the 3.13 deprecation call removed). telnet_session.py does try: import telnetlib / except ImportError: ... _telnetlib as telnetlib — the stdlib module is still preferred on <=3.12, so behavior there is unchanged. No other module in the repo imports telnetlib.
  • paramiko >=3.4,<4 (resolves to 3.5.1). Capped below 4.x deliberately: SSHSession._get_pkey_object still supports paramiko.DSSKey, which paramiko 4.0 removed; the _transport_factory server_extensions ssh-rsa workaround is already hasattr-guarded. scp~=0.14 left as-is (resolves to 0.16.1, compatible).
  • Version 6.0.0 (major: dependency major + vendored module), python_requires>=3.9, classifiers 3.9–3.13.
  • CI: package-tox-py-37-39.ymlpackage-tox-py-39.yml; tox envlist py39 only.
  • Lint: setuptools<81 pinned into the flake8 hook (its plugins need pkg_resources, gone from newer setuptools/py3.12+ venvs); vendored module excluded from hooks/flake8; per-file-ignores for E231/E702 false positives from the py3.12+ f-string tokenizer in tl1_session.py and A005 for the intentional cloudshell/cli/types.py module name.

Evidence

  • Tests: full suite 130/130 passed on Python 3.13.x and 3.9.0 (fresh venvs, paramiko 3.5.1). The SSH tests spin up a real in-process paramiko Transport server (password + RSA-key auth, SCP and SFTP upload) — a live handshake against paramiko 3.x. No mock changes were needed.
  • Telnet smoke (py3.13): import telnetlib confirmed to fail on 3.13; a local asyncio telnet server on port 2323 + TelnetSession.connect() completed the full login/password action-map flow and prompt match through the vendored module (telnetlib module in use: cloudshell.cli.session._telnetlib, CONNECTED, active = True).
  • SSH smoke (py3.13): paramiko 3.5.1 import + SSHSession instantiation OK (plus the live-handshake unit tests above).
  • pre-commit: pyupgrade, isort, black, flake8 all pass.

🤖 Generated with Claude Code

- Vendor CPython 3.12's telnetlib as cloudshell/cli/session/_telnetlib.py
  (PSF-2.0; telnetlib was removed from the stdlib in 3.13 by PEP 594).
  telnet_session.py prefers the stdlib module when it exists (<=3.12) and
  falls back to the vendored copy on 3.13+ - zero behavior change on <=3.12.
- paramiko ~=2.12 -> >=3.4,<4. Capped below 4 because _get_pkey_object
  still supports paramiko.DSSKey, which paramiko 4.0 removed.
- Version 6.0.0, python_requires >=3.9, classifiers 3.9-3.13.
- CI: package-tox-py-37-39.yml -> package-tox-py-39.yml; tox envlist py39.
- Lint: pin setuptools<81 for the flake8 hook (pkg_resources); exclude the
  vendored module; per-file-ignores for py3.12+ f-string tokenizer false
  positives (E231/E702) and the intentional types.py name (A005).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@nahumtimerman
nahumtimerman merged commit 4030c10 into master Sep 6, 2026
4 of 5 checks passed
@nahumtimerman
nahumtimerman deleted the feature/python313 branch September 6, 2026 15:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant