Bug report
Bug description:
Subclasses of telnetlib.Telnet may crash when used as context manager due to missing self.sock:
Exception ignored in: <function Telnet.__del__ at 0x7faeb8656ee0> Traceback (most recent call last): File "/usr/lib/python3.8/telnetlib.py", line 239, in __del__ self.close() File "/usr/lib/python3.8/telnetlib.py", line 265, in close sock = self.sock AttributeError: 'TelnetSubclass' object has no attribute 'sock'
A simple example that can trigger the issue would be a Telnet subclass where aliases to hostnames would be provided for making the telnet connection:
import telnetlib ALIAS_TO_HOST = { "alias1": "localhost", "alias2": "anotherhost" } class AliasTelnet(telnetlib.Telnet): # sock = None # this mitigates the problem def __init__(self, alias): host = ALIAS_TO_HOST.get(alias) if not host: # self.sock = None # alternatively this mitigates the problem raise ValueError(f'cannot map alias "{alias}" to host name') super().__init__(host) # this works with AliasTelnet("alias1") as tn: print(tn.read_some().decode()) # this fails with AliasTelnet("thisisnotaknownalias") as tn: pass
What happens is that upon leaving the context due to an exception Telnet.__del__ is called, which calls Telnet.close. If this happens before Telnet.__init__ was called (i.e., the line super().__init__(host) above) the sock attribute does not exist yet.
A simple solution would be to adjust the close method to this:
def close(self): """Close the connection.""" try: sock = self.sock except AttributeError: sock = None ...
Alternatively, sock = None could be attached to the class:
class Telnet: sock = None
Probably the first version is preferable since it solves the problem where it happens.
I can, of course, provide a PR for either of the changes. Question is whether it's worth it since telnetlib is going to be deprecated. (Sadly, I'd like to add. I actually like using it and telnetlib3 is not really a straight forward replacement due to being fully async. Any way to petition for telnetlib to stay?)
CPython versions tested on:
3.8, 3.12
Operating systems tested on:
Linux