Is your feature request related to a problem? Please describe.
netdiff cannot be installed with OpenWISP Controller in one Python environment. netdiff depends on Exscript>=2.6.32, whose metadata requires paramiko<5, while Controller requires paramiko~=5.0.0. Installing both leaves one requirement unsatisfied.
Exscript is used only for the telnet:// retrieval path in netdiff.parsers.base.BaseParser._get_telnet. Python 3.13 compatibility also requires a maintained replacement for the removed standard-library telnetlib.
Describe the solution you'd like
Replace Exscript with telnetlib3>=5,<6 and use its explicit vendored legacy API:
from telnetlib3 import telnetlib
This preserves the existing Telnet(url.hostname, url.port, timeout=...), byte write, read_all, and close flow without a Paramiko dependency. Update the test mock targets to netdiff.parsers.base.telnetlib.Telnet.
Describe alternatives you've considered
- Use
socket directly. This removes the dependency but requires custom Telnet negotiation and EOF-delimited stream handling.
- Keep Exscript and use Paramiko 4. This conflicts with Controller's required Paramiko 5 dependency.
- Use
telnetlib3.sync.TelnetConnection. It is not a drop-in replacement and introduces a background asyncio thread per connection.
Additional context
Use from telnetlib3 import telnetlib, rather than bare import telnetlib, so Python 3.10 to 3.12 and Python 3.13+ use the same implementation.
Related OpenWISP RADIUS issue: to be linked after creation.
Is your feature request related to a problem? Please describe.
netdiff cannot be installed with OpenWISP Controller in one Python environment. netdiff depends on
Exscript>=2.6.32, whose metadata requiresparamiko<5, while Controller requiresparamiko~=5.0.0. Installing both leaves one requirement unsatisfied.Exscript is used only for the
telnet://retrieval path innetdiff.parsers.base.BaseParser._get_telnet. Python 3.13 compatibility also requires a maintained replacement for the removed standard-librarytelnetlib.Describe the solution you'd like
Replace Exscript with
telnetlib3>=5,<6and use its explicit vendored legacy API:This preserves the existing
Telnet(url.hostname, url.port, timeout=...), bytewrite,read_all, andcloseflow without a Paramiko dependency. Update the test mock targets tonetdiff.parsers.base.telnetlib.Telnet.Describe alternatives you've considered
socketdirectly. This removes the dependency but requires custom Telnet negotiation and EOF-delimited stream handling.telnetlib3.sync.TelnetConnection. It is not a drop-in replacement and introduces a background asyncio thread per connection.Additional context
Use
from telnetlib3 import telnetlib, rather than bareimport telnetlib, so Python 3.10 to 3.12 and Python 3.13+ use the same implementation.Related OpenWISP RADIUS issue: to be linked after creation.