Added timout parameter to telnetlib.Telnet. Also created
test_telnetlib.py with a basic test and timeout ones. Docs are also updated.
This commit is contained in:
parent
30712ab82f
commit
b6a5c9d605
|
@ -23,13 +23,16 @@ Mark), BRK (Break), IP (Interrupt process), AO (Abort output), AYT
|
|||
SB (Subnegotiation Begin).
|
||||
|
||||
|
||||
\begin{classdesc}{Telnet}{\optional{host\optional{, port}}}
|
||||
\begin{classdesc}{Telnet}{\optional{host\optional{, port\optional{, timeout}}}}
|
||||
\class{Telnet} represents a connection to a Telnet server. The
|
||||
instance is initially not connected by default; the \method{open()}
|
||||
method must be used to establish a connection. Alternatively, the
|
||||
host name and optional port number can be passed to the constructor,
|
||||
to, in which case the connection to the server will be established
|
||||
before the constructor returns.
|
||||
The optional \var{timeout} parameter specifies a timeout in seconds for the
|
||||
connection attempt (if not specified, or passed as None, the global default
|
||||
timeout setting will be used).
|
||||
|
||||
Do not reopen an already connected instance.
|
||||
|
||||
|
@ -111,10 +114,13 @@ The callback should access these data when it was invoked with a
|
|||
\versionadded{2.3}
|
||||
\end{methoddesc}
|
||||
|
||||
\begin{methoddesc}{open}{host\optional{, port}}
|
||||
\begin{methoddesc}{open}{host\optional{, port\optional{, timeout}}}
|
||||
Connect to a host.
|
||||
The optional second argument is the port number, which
|
||||
defaults to the standard Telnet port (23).
|
||||
The optional \var{timeout} parameter specifies a timeout in seconds for the
|
||||
connection attempt (if not specified, or passed as None, the global default
|
||||
timeout setting will be used).
|
||||
|
||||
Do not try to reopen an already connected instance.
|
||||
\end{methoddesc}
|
||||
|
|
|
@ -184,7 +184,7 @@ class Telnet:
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, host=None, port=0):
|
||||
def __init__(self, host=None, port=0, timeout=None):
|
||||
"""Constructor.
|
||||
|
||||
When called without arguments, create an unconnected instance.
|
||||
|
@ -195,6 +195,7 @@ class Telnet:
|
|||
self.debuglevel = DEBUGLEVEL
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.timeout = timeout
|
||||
self.sock = None
|
||||
self.rawq = ''
|
||||
self.irawq = 0
|
||||
|
@ -205,9 +206,9 @@ class Telnet:
|
|||
self.sbdataq = ''
|
||||
self.option_callback = None
|
||||
if host is not None:
|
||||
self.open(host, port)
|
||||
self.open(host, port, timeout)
|
||||
|
||||
def open(self, host, port=0):
|
||||
def open(self, host, port=0, timeout=None):
|
||||
"""Connect to a host.
|
||||
|
||||
The optional second argument is the port number, which
|
||||
|
@ -221,20 +222,9 @@ class Telnet:
|
|||
port = TELNET_PORT
|
||||
self.host = host
|
||||
self.port = port
|
||||
msg = "getaddrinfo returns an empty list"
|
||||
for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
|
||||
af, socktype, proto, canonname, sa = res
|
||||
try:
|
||||
self.sock = socket.socket(af, socktype, proto)
|
||||
self.sock.connect(sa)
|
||||
except socket.error, msg:
|
||||
if self.sock:
|
||||
self.sock.close()
|
||||
self.sock = None
|
||||
continue
|
||||
break
|
||||
if not self.sock:
|
||||
raise socket.error, msg
|
||||
if timeout is not None:
|
||||
self.timeout = timeout
|
||||
self.sock = socket.create_connection((host, port), self.timeout)
|
||||
|
||||
def __del__(self):
|
||||
"""Destructor -- close the connection."""
|
||||
|
@ -661,7 +651,7 @@ def test():
|
|||
port = socket.getservbyname(portstr, 'tcp')
|
||||
tn = Telnet()
|
||||
tn.set_debuglevel(debuglevel)
|
||||
tn.open(host, port)
|
||||
tn.open(host, port, timeout=0.5)
|
||||
tn.interact()
|
||||
tn.close()
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
import socket
|
||||
import threading
|
||||
import telnetlib
|
||||
import time
|
||||
|
||||
from unittest import TestCase
|
||||
from test import test_support
|
||||
|
||||
|
||||
def server(evt):
|
||||
serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
serv.settimeout(3)
|
||||
serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
serv.bind(("", 9091))
|
||||
serv.listen(5)
|
||||
try:
|
||||
conn, addr = serv.accept()
|
||||
except socket.timeout:
|
||||
pass
|
||||
finally:
|
||||
serv.close()
|
||||
evt.set()
|
||||
|
||||
class GeneralTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.evt = threading.Event()
|
||||
threading.Thread(target=server, args=(self.evt,)).start()
|
||||
time.sleep(.1)
|
||||
|
||||
def tearDown(self):
|
||||
self.evt.wait()
|
||||
|
||||
def testBasic(self):
|
||||
# connects
|
||||
telnet = telnetlib.Telnet("localhost", 9091)
|
||||
telnet.sock.close()
|
||||
|
||||
def testTimeoutDefault(self):
|
||||
# default
|
||||
telnet = telnetlib.Telnet("localhost", 9091)
|
||||
self.assertTrue(telnet.sock.gettimeout() is None)
|
||||
telnet.sock.close()
|
||||
|
||||
def testTimeoutValue(self):
|
||||
# a value
|
||||
telnet = telnetlib.Telnet("localhost", 9091, timeout=30)
|
||||
self.assertEqual(telnet.sock.gettimeout(), 30)
|
||||
telnet.sock.close()
|
||||
|
||||
def testTimeoutDifferentOrder(self):
|
||||
telnet = telnetlib.Telnet(timeout=30)
|
||||
telnet.open("localhost", 9091)
|
||||
self.assertEqual(telnet.sock.gettimeout(), 30)
|
||||
telnet.sock.close()
|
||||
|
||||
def testTimeoutNone(self):
|
||||
# None, having other default
|
||||
previous = socket.getdefaulttimeout()
|
||||
socket.setdefaulttimeout(30)
|
||||
try:
|
||||
telnet = telnetlib.Telnet("localhost", 9091, timeout=None)
|
||||
finally:
|
||||
socket.setdefaulttimeout(previous)
|
||||
self.assertEqual(telnet.sock.gettimeout(), 30)
|
||||
telnet.sock.close()
|
||||
|
||||
|
||||
|
||||
def test_main(verbose=None):
|
||||
test_support.run_unittest(GeneralTests)
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_main()
|
|
@ -200,6 +200,11 @@ Core and builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Added a timeout parameter to the constructor of other protocols
|
||||
(telnetlib, ftplib, smtplib and poplib). This is second part of the
|
||||
work started with create_connection() and timeout in httplib, and
|
||||
closes patch #723312.
|
||||
|
||||
- Patch #1676823: Added create_connection() to socket.py, which may be
|
||||
called with a timeout, and use it from httplib (whose HTTPConnection
|
||||
now accepts an optional timeout).
|
||||
|
|
Loading…
Reference in New Issue