Skip to content

subclasses of telnetlib.Telnet may crash when used as context manager #118042

Description

@NichtJens

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

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions