From 4f1b1ed975fe25170d00559e63f992c9bf8e9b8a Mon Sep 17 00:00:00 2001 From: Facundo Batista Date: Thu, 29 May 2008 16:39:26 +0000 Subject: Fixed the semantic of timeout for socket.create_connection and all the upper level libraries that use it, including urllib2. Added and fixed some tests, and changed docs correspondingly. Thanks to John J Lee for the patch and the pusing, :) --- Doc/library/ftplib.rst | 10 ++++------ Doc/library/httplib.rst | 2 +- Doc/library/poplib.rst | 4 ++-- Doc/library/smtplib.rst | 8 ++++---- Doc/library/socket.rst | 11 +++++------ Doc/library/telnetlib.rst | 8 ++++++-- Doc/library/urllib2.rst | 12 ++++++------ Lib/ftplib.py | 9 +++++---- Lib/httplib.py | 5 +++-- Lib/poplib.py | 3 ++- Lib/smtplib.py | 6 ++++-- Lib/socket.py | 17 ++++++++++------- Lib/telnetlib.py | 16 +++++++--------- Lib/test/test_ftplib.py | 43 +++++++++++++++++++++++------------------- Lib/test/test_httplib.py | 29 ++++++++++++++++------------ Lib/test/test_poplib.py | 25 ++++++++++++------------ Lib/test/test_smtplib.py | 34 +++++++++++++++++---------------- Lib/test/test_socket.py | 32 ++++++++++++++++++------------- Lib/test/test_telnetlib.py | 34 +++++++++++++++++---------------- Lib/test/test_urllib.py | 40 +++++++++++++++++++++++---------------- Lib/test/test_urllib2.py | 8 +++++--- Lib/test/test_urllib2net.py | 46 ++++++++++++++++++++++++++++----------------- Lib/urllib.py | 3 ++- Lib/urllib2.py | 4 ++-- 24 files changed, 230 insertions(+), 179 deletions(-) diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst index 1785a26..728eeab 100644 --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -44,8 +44,8 @@ The module defines the following items: the method call ``login(user, passwd, acct)`` is made (where *passwd* and *acct* default to the empty string when not given). The optional *timeout* parameter specifies a timeout in seconds for blocking operations like the - connection attempt (if is not specified, or passed as None, the global - default timeout setting will be used). + connection attempt (if is not specified, the global default timeout setting + will be used). .. versionchanged:: 2.6 *timeout* was added. @@ -126,10 +126,8 @@ followed by ``lines`` for the text version or ``binary`` for the binary version. made. The optional *timeout* parameter specifies a timeout in seconds for the - connection attempt. If is not specified, or passed as None, the object - timeout is used (the timeout that you passed when instantiating the class); - if the object timeout is also None, the global default timeout setting will - be used. + connection attempt. If no *timeout* is passed, the global default timeout + setting will be used. .. versionchanged:: 2.6 *timeout* was added. diff --git a/Doc/library/httplib.rst b/Doc/library/httplib.rst index ce6222b..4c87d17 100644 --- a/Doc/library/httplib.rst +++ b/Doc/library/httplib.rst @@ -44,7 +44,7 @@ The module provides the following classes: be raised if the status line can't be parsed as a valid HTTP/1.0 or 1.1 status line. If the optional *timeout* parameter is given, blocking operations (like connection attempts) will timeout after that many seconds - (if it is not given or ``None``, the global default timeout setting is used). + (if it is not given, the global default timeout setting is used). For example, the following calls all create instances that connect to the server at the same host and port:: diff --git a/Doc/library/poplib.rst b/Doc/library/poplib.rst index 2cf3402..e5f693d 100644 --- a/Doc/library/poplib.rst +++ b/Doc/library/poplib.rst @@ -29,8 +29,8 @@ A single class is provided by the :mod:`poplib` module: This class implements the actual POP3 protocol. The connection is created when the instance is initialized. If *port* is omitted, the standard POP3 port (110) is used. The optional *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). + connection attempt (if not specified, the global default timeout setting will + be used). .. versionchanged:: 2.6 *timeout* was added. diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst index dfa5e8f..ff580da 100644 --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -25,8 +25,8 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). with those parameters during initialization. An :exc:`SMTPConnectError` is raised if the specified host doesn't respond correctly. The optional *timeout* parameter specifies a timeout in seconds for blocking operations - like the connection attempt (if not specified, or passed as None, the global - default timeout setting will be used). + like the connection attempt (if not specified, the global default timeout + setting will be used). For normal use, you should only require the initialization/connect, :meth:`sendmail`, and :meth:`quit` methods. An example is included below. @@ -45,8 +45,8 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). and *certfile* are also optional, and can contain a PEM formatted private key and certificate chain file for the SSL connection. The optional *timeout* parameter specifies a timeout in seconds for blocking operations like the - connection attempt (if not specified, or passed as None, the global default - timeout setting will be used). + connection attempt (if not specified, the global default timeout setting + will be used). .. versionchanged:: 2.6 *timeout* was added. diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index e5a8167..16feee5 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -207,12 +207,11 @@ The module :mod:`socket` exports the following constants and functions: .. function:: create_connection(address[, timeout]) - Connects to the *address* received (as usual, a ``(host, port)`` pair), with an - optional timeout for the connection. Especially useful for higher-level - protocols, it is not normally used directly from application-level code. - Passing the optional *timeout* parameter will set the timeout on the socket - instance (if it is not given or ``None``, the global default timeout setting is - used). + Convenience function. Connect to *address* (a 2-tuple ``(host, port)``), + and return the socket object. Passing the optional *timeout* parameter will + set the timeout on the socket instance before attempting to connect. If no + *timeout* is supplied, the global default timeout setting returned by + :func:`getdefaulttimeout` is used. .. versionadded:: 2.6 diff --git a/Doc/library/telnetlib.rst b/Doc/library/telnetlib.rst index b0c1683..b326da9 100644 --- a/Doc/library/telnetlib.rst +++ b/Doc/library/telnetlib.rst @@ -28,6 +28,11 @@ Character), EL (Erase Line), GA (Go Ahead), SB (Subnegotiation Begin). :class:`Telnet` represents a connection to a Telnet server. The instance is initially not connected by default; the :meth:`open` method must be used to establish a connection. Alternatively, the host name and optional port + and timeout can be passed to the constructor, in which case the connection to + the server will be established before the constructor returns. The optional + *timeout* parameter specifies a timeout in seconds for the connection attempt (if + not specified, the global default timeout setting will be used). + 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 *timeout* parameter specifies a timeout in seconds for blocking operations @@ -128,8 +133,7 @@ Telnet Objects Connect to a host. The optional second argument is the port number, which defaults to the standard Telnet port (23). The optional *timeout* parameter specifies a timeout in seconds for blocking operations like the connection - attempt (if not specified, or passed as None, the global default timeout - setting will be used). + attempt (if not specified, the global default timeout setting will be used). Do not try to reopen an already connected instance. diff --git a/Doc/library/urllib2.rst b/Doc/library/urllib2.rst index 0bdc8be..ff664f5 100644 --- a/Doc/library/urllib2.rst +++ b/Doc/library/urllib2.rst @@ -27,9 +27,9 @@ The :mod:`urllib2` module defines the following functions: returns a string in this format. The optional *timeout* parameter specifies a timeout in seconds for blocking - operations like the connection attempt (if not specified, or passed as - ``None``, the global default timeout setting will be used). This actually - only works for HTTP, HTTPS, FTP and FTPS connections. + operations like the connection attempt (if not specified, the global default + timeout setting will be used). This actually only works for HTTP, HTTPS, + FTP and FTPS connections. This function returns a file-like object with two additional methods: @@ -411,9 +411,9 @@ OpenerDirector Objects the same as those of :func:`urlopen` (which simply calls the :meth:`open` method on the currently installed global :class:`OpenerDirector`). The optional *timeout* parameter specifies a timeout in seconds for blocking - operations like the connection attempt (if not specified, or passed as - ``None``, the global default timeout setting will be used; this actually only - works for HTTP, HTTPS, FTP and FTPS connections). + operations like the connection attempt (if not specified, the global default + timeout setting will be usedi). The timeout feature actually works only for + HTTP, HTTPS, FTP and FTPS connections). .. versionchanged:: 2.6 *timeout* was added. diff --git a/Lib/ftplib.py b/Lib/ftplib.py index a915b2d..820c345 100644 --- a/Lib/ftplib.py +++ b/Lib/ftplib.py @@ -44,6 +44,7 @@ try: from socket import getfqdn; socket.getfqdn = getfqdn; del getfqdn except ImportError: import socket +from socket import _GLOBAL_DEFAULT_TIMEOUT __all__ = ["FTP","Netrc"] @@ -71,7 +72,6 @@ all_errors = (Error, IOError, EOFError) # Line terminators (we always output CRLF, but accept any of CRLF, CR, LF) CRLF = '\r\n' - # The class itself class FTP: @@ -109,14 +109,15 @@ class FTP: # Initialize host to localhost, port to standard ftp port # Optional arguments are host (for connect()), # and user, passwd, acct (for login()) - def __init__(self, host='', user='', passwd='', acct='', timeout=None): + def __init__(self, host='', user='', passwd='', acct='', + timeout=_GLOBAL_DEFAULT_TIMEOUT): self.timeout = timeout if host: self.connect(host) if user: self.login(user, passwd, acct) - def connect(self, host='', port=0, timeout=None): + def connect(self, host='', port=0, timeout=-999): '''Connect to host. Arguments are: - host: hostname to connect to (string, default previous host) - port: port to connect to (integer, default previous port) @@ -125,7 +126,7 @@ class FTP: self.host = host if port > 0: self.port = port - if timeout is not None: + if timeout != -999: self.timeout = timeout self.sock = socket.create_connection((self.host, self.port), self.timeout) self.af = self.sock.family diff --git a/Lib/httplib.py b/Lib/httplib.py index 5696467..1bca5da 100644 --- a/Lib/httplib.py +++ b/Lib/httplib.py @@ -639,7 +639,8 @@ class HTTPConnection: debuglevel = 0 strict = 0 - def __init__(self, host, port=None, strict=None, timeout=None): + def __init__(self, host, port=None, strict=None, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT): self.timeout = timeout self.sock = None self._buffer = [] @@ -1055,7 +1056,7 @@ else: default_port = HTTPS_PORT def __init__(self, host, port=None, key_file=None, cert_file=None, - strict=None, timeout=None): + strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): HTTPConnection.__init__(self, host, port, strict, timeout) self.key_file = key_file self.cert_file = cert_file diff --git a/Lib/poplib.py b/Lib/poplib.py index 4cffb04..e2b33ef 100644 --- a/Lib/poplib.py +++ b/Lib/poplib.py @@ -76,7 +76,8 @@ class POP3: """ - def __init__(self, host, port=POP3_PORT, timeout=None): + def __init__(self, host, port=POP3_PORT, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT): self.host = host self.port = port self.sock = socket.create_connection((host, port), timeout) diff --git a/Lib/smtplib.py b/Lib/smtplib.py index 5ac9fc3..afa38bc 100755 --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -220,7 +220,8 @@ class SMTP: ehlo_resp = None does_esmtp = 0 - def __init__(self, host='', port=0, local_hostname=None, timeout=None): + def __init__(self, host='', port=0, local_hostname=None, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT): """Initialize a new instance. If specified, `host' is the name of the remote host to which to @@ -741,7 +742,8 @@ if _have_ssl: certificate chain file for the SSL connection. """ def __init__(self, host='', port=0, local_hostname=None, - keyfile=None, certfile=None, timeout=None): + keyfile=None, certfile=None, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT): self.keyfile = keyfile self.certfile = certfile SMTP.__init__(self, host, port, local_hostname, timeout) diff --git a/Lib/socket.py b/Lib/socket.py index 2a52547..6dcd1a6 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -480,14 +480,17 @@ class _fileobject(object): raise StopIteration return line +_GLOBAL_DEFAULT_TIMEOUT = object() -def create_connection(address, timeout=None): - """Connect to address (host, port) with an optional timeout. +def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT): + """Connect to *address* and return the socket object. - Provides access to socketobject timeout for higher-level - protocols. Passing a timeout will set the timeout on the - socket instance (if not present, or passed as None, the - default global timeout setting will be used). + Convenience function. Connect to *address* (a 2-tuple ``(host, + port)``) and return the socket object. Passing the optional + *timeout* parameter will set the timeout on the socket instance + before attempting to connect. If no *timeout* is supplied, the + global default timeout setting returned by :func:`getdefaulttimeout` + is used. """ msg = "getaddrinfo returns an empty list" @@ -497,7 +500,7 @@ def create_connection(address, timeout=None): sock = None try: sock = socket(af, socktype, proto) - if timeout is not None: + if timeout is not _GLOBAL_DEFAULT_TIMEOUT: sock.settimeout(timeout) sock.connect(sa) return sock diff --git a/Lib/telnetlib.py b/Lib/telnetlib.py index f4c01e4..2bfd9cd 100644 --- a/Lib/telnetlib.py +++ b/Lib/telnetlib.py @@ -184,13 +184,13 @@ class Telnet: """ - def __init__(self, host=None, port=0, timeout=None): + def __init__(self, host=None, port=0, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT): """Constructor. When called without arguments, create an unconnected instance. - With a hostname argument, it connects the instance; a port - number is optional. - + With a hostname argument, it connects the instance; port number + and timeout are optional. """ self.debuglevel = DEBUGLEVEL self.host = host @@ -208,23 +208,21 @@ class Telnet: if host is not None: self.open(host, port, timeout) - def open(self, host, port=0, timeout=None): + def open(self, host, port=0, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): """Connect to a host. The optional second argument is the port number, which defaults to the standard telnet port (23). Don't try to reopen an already connected instance. - """ self.eof = 0 if not port: port = TELNET_PORT self.host = host self.port = port - if timeout is not None: - self.timeout = timeout - self.sock = socket.create_connection((host, port), self.timeout) + self.timeout = timeout + self.sock = socket.create_connection((host, port), timeout) def __del__(self): """Destructor -- close the connection.""" diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py index 5f961d2..c7cd3a5 100644 --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -53,35 +53,52 @@ class GeneralTests(TestCase): # connects ftp = ftplib.FTP(HOST) self.evt.wait() - ftp.sock.close() + ftp.close() def testTimeoutDefault(self): - # default - ftp = ftplib.FTP(HOST) + # default -- use global socket timeout + self.assert_(socket.getdefaulttimeout() is None) + socket.setdefaulttimeout(30) + try: + ftp = ftplib.FTP("localhost") + finally: + socket.setdefaulttimeout(None) + self.assertEqual(ftp.sock.gettimeout(), 30) + self.evt.wait() + ftp.close() + + def testTimeoutNone(self): + # no timeout -- do not use global socket timeout + self.assert_(socket.getdefaulttimeout() is None) + socket.setdefaulttimeout(30) + try: + ftp = ftplib.FTP("localhost", timeout=None) + finally: + socket.setdefaulttimeout(None) self.assertTrue(ftp.sock.gettimeout() is None) self.evt.wait() - ftp.sock.close() + ftp.close() def testTimeoutValue(self): # a value ftp = ftplib.FTP(HOST, timeout=30) self.assertEqual(ftp.sock.gettimeout(), 30) self.evt.wait() - ftp.sock.close() + ftp.close() def testTimeoutConnect(self): ftp = ftplib.FTP() ftp.connect(HOST, timeout=30) self.assertEqual(ftp.sock.gettimeout(), 30) self.evt.wait() - ftp.sock.close() + ftp.close() def testTimeoutDifferentOrder(self): ftp = ftplib.FTP(timeout=30) ftp.connect(HOST) self.assertEqual(ftp.sock.gettimeout(), 30) self.evt.wait() - ftp.sock.close() + ftp.close() def testTimeoutDirectAccess(self): ftp = ftplib.FTP() @@ -89,18 +106,6 @@ class GeneralTests(TestCase): ftp.connect(HOST) self.assertEqual(ftp.sock.gettimeout(), 30) self.evt.wait() - ftp.sock.close() - - def testTimeoutNone(self): - # None, having other default - previous = socket.getdefaulttimeout() - socket.setdefaulttimeout(30) - try: - ftp = ftplib.FTP(HOST, timeout=None) - finally: - socket.setdefaulttimeout(previous) - self.assertEqual(ftp.sock.gettimeout(), 30) - self.evt.wait() ftp.close() diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index fcbddd0..e2560b6 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -214,27 +214,32 @@ class TimeoutTest(TestCase): '''This will prove that the timeout gets through HTTPConnection and into the socket. ''' - # default - httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT) - httpConn.connect() - self.assertTrue(httpConn.sock.gettimeout() is None) - httpConn.close() - - # a value - httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT, timeout=30) - httpConn.connect() + # default -- use global socket timeout + self.assert_(socket.getdefaulttimeout() is None) + socket.setdefaulttimeout(30) + try: + httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT) + httpConn.connect() + finally: + socket.setdefaulttimeout(None) self.assertEqual(httpConn.sock.gettimeout(), 30) httpConn.close() - # None, having other default - previous = socket.getdefaulttimeout() + # no timeout -- do not use global socket default + self.assert_(socket.getdefaulttimeout() is None) socket.setdefaulttimeout(30) try: httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT, timeout=None) httpConn.connect() finally: - socket.setdefaulttimeout(previous) + socket.setdefaulttimeout(None) + self.assertEqual(httpConn.sock.gettimeout(), None) + httpConn.close() + + # a value + httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT, timeout=30) + httpConn.connect() self.assertEqual(httpConn.sock.gettimeout(), 30) httpConn.close() diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py index 54b8786..18ed224 100644 --- a/Lib/test/test_poplib.py +++ b/Lib/test/test_poplib.py @@ -40,28 +40,29 @@ class GeneralTests(TestCase): pop.sock.close() def testTimeoutDefault(self): - # default - pop = poplib.POP3(HOST, self.port) - self.assertTrue(pop.sock.gettimeout() is None) - pop.sock.close() - - def testTimeoutValue(self): - # a value - pop = poplib.POP3(HOST, self.port, timeout=30) + self.assertTrue(socket.getdefaulttimeout() is None) + socket.setdefaulttimeout(30) + try: + pop = poplib.POP3("localhost", self.port) + finally: + socket.setdefaulttimeout(None) self.assertEqual(pop.sock.gettimeout(), 30) pop.sock.close() def testTimeoutNone(self): - # None, having other default - previous = socket.getdefaulttimeout() + self.assertTrue(socket.getdefaulttimeout() is None) socket.setdefaulttimeout(30) try: pop = poplib.POP3(HOST, self.port, timeout=None) finally: - socket.setdefaulttimeout(previous) - self.assertEqual(pop.sock.gettimeout(), 30) + socket.setdefaulttimeout(None) + self.assertTrue(pop.sock.gettimeout() is None) pop.sock.close() + def testTimeoutValue(self): + pop = poplib.POP3("localhost", self.port, timeout=30) + self.assertEqual(pop.sock.gettimeout(), 30) + pop.sock.close() def test_main(verbose=None): diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index 9e63110..be28de7 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -54,41 +54,43 @@ class GeneralTests(TestCase): def testBasic1(self): # connects smtp = smtplib.SMTP(HOST, self.port) - smtp.sock.close() + smtp.close() def testBasic2(self): # connects, include port in host name smtp = smtplib.SMTP("%s:%s" % (HOST, self.port)) - smtp.sock.close() + smtp.close() def testLocalHostName(self): # check that supplied local_hostname is used smtp = smtplib.SMTP(HOST, self.port, local_hostname="testhost") self.assertEqual(smtp.local_hostname, "testhost") - smtp.sock.close() + smtp.close() def testTimeoutDefault(self): - # default - smtp = smtplib.SMTP(HOST, self.port) - self.assertTrue(smtp.sock.gettimeout() is None) - smtp.sock.close() - - def testTimeoutValue(self): - # a value - smtp = smtplib.SMTP(HOST, self.port, timeout=30) + self.assertTrue(socket.getdefaulttimeout() is None) + socket.setdefaulttimeout(30) + try: + smtp = smtplib.SMTP(HOST, self.port) + finally: + socket.setdefaulttimeout(None) self.assertEqual(smtp.sock.gettimeout(), 30) - smtp.sock.close() + smtp.close() def testTimeoutNone(self): - # None, having other default - previous = socket.getdefaulttimeout() + self.assertTrue(socket.getdefaulttimeout() is None) socket.setdefaulttimeout(30) try: smtp = smtplib.SMTP(HOST, self.port, timeout=None) finally: - socket.setdefaulttimeout(previous) + socket.setdefaulttimeout(None) + self.assertTrue(smtp.sock.gettimeout() is None) + smtp.close() + + def testTimeoutValue(self): + smtp = smtplib.SMTP(HOST, self.port, timeout=30) self.assertEqual(smtp.sock.gettimeout(), 30) - smtp.sock.close() + smtp.close() # Test server thread using the specified SMTP server class diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 48c9346..ba5eea9 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -901,8 +901,25 @@ class NetworkConnectionAttributesTest(SocketTCPTest, ThreadableTest): testTimeoutDefault = _justAccept def _testTimeoutDefault(self): - self.cli = socket.create_connection((HOST, self.port)) - self.assertTrue(self.cli.gettimeout() is None) + # passing no explicit timeout uses socket's global default + self.assert_(socket.getdefaulttimeout() is None) + socket.setdefaulttimeout(42) + try: + self.cli = socket.create_connection((HOST, self.port)) + finally: + socket.setdefaulttimeout(None) + self.assertEquals(self.cli.gettimeout(), 42) + + testTimeoutNone = _justAccept + def _testTimeoutNone(self): + # None timeout means the same as sock.settimeout(None) + self.assert_(socket.getdefaulttimeout() is None) + socket.setdefaulttimeout(30) + try: + self.cli = socket.create_connection((HOST, self.port), timeout=None) + finally: + socket.setdefaulttimeout(None) + self.assertEqual(self.cli.gettimeout(), None) testTimeoutValueNamed = _justAccept def _testTimeoutValueNamed(self): @@ -914,17 +931,6 @@ class NetworkConnectionAttributesTest(SocketTCPTest, ThreadableTest): self.cli = socket.create_connection((HOST, self.port), 30) self.assertEqual(self.cli.gettimeout(), 30) - testTimeoutNone = _justAccept - def _testTimeoutNone(self): - previous = socket.getdefaulttimeout() - socket.setdefaulttimeout(30) - try: - self.cli = socket.create_connection((HOST, self.port), timeout=None) - finally: - socket.setdefaulttimeout(previous) - self.assertEqual(self.cli.gettimeout(), 30) - - class NetworkConnectionBehaviourTest(SocketTCPTest, ThreadableTest): def __init__(self, methodName='runTest'): diff --git a/Lib/test/test_telnetlib.py b/Lib/test/test_telnetlib.py index e4ee1b5..838f6fb 100644 --- a/Lib/test/test_telnetlib.py +++ b/Lib/test/test_telnetlib.py @@ -40,34 +40,36 @@ class GeneralTests(TestCase): telnet.sock.close() def testTimeoutDefault(self): - # default - telnet = telnetlib.Telnet(HOST, self.port) - self.assertTrue(telnet.sock.gettimeout() is None) - telnet.sock.close() - - def testTimeoutValue(self): - # a value - telnet = telnetlib.Telnet(HOST, self.port, timeout=30) - self.assertEqual(telnet.sock.gettimeout(), 30) - telnet.sock.close() - - def testTimeoutDifferentOrder(self): - telnet = telnetlib.Telnet(timeout=30) - telnet.open(HOST, self.port) + self.assertTrue(socket.getdefaulttimeout() is None) + socket.setdefaulttimeout(30) + try: + telnet = telnetlib.Telnet("localhost", self.port) + finally: + socket.setdefaulttimeout(None) self.assertEqual(telnet.sock.gettimeout(), 30) telnet.sock.close() def testTimeoutNone(self): # None, having other default - previous = socket.getdefaulttimeout() + self.assertTrue(socket.getdefaulttimeout() is None) socket.setdefaulttimeout(30) try: telnet = telnetlib.Telnet(HOST, self.port, timeout=None) finally: - socket.setdefaulttimeout(previous) + socket.setdefaulttimeout(None) + self.assertTrue(telnet.sock.gettimeout() is None) + telnet.sock.close() + + def testTimeoutValue(self): + telnet = telnetlib.Telnet("localhost", self.port, timeout=30) self.assertEqual(telnet.sock.gettimeout(), 30) telnet.sock.close() + def testTimeoutOpen(self): + telnet = telnetlib.Telnet() + telnet.open("localhost", self.port, timeout=30) + self.assertEqual(telnet.sock.gettimeout(), 30) + telnet.sock.close() def test_main(verbose=None): diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index 0c669d0..61e0202 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -568,6 +568,7 @@ class Pathname_Tests(unittest.TestCase): # . Facundo # # def server(evt): +# import socket, time # serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # serv.settimeout(3) # serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) @@ -592,6 +593,7 @@ class Pathname_Tests(unittest.TestCase): # class FTPWrapperTests(unittest.TestCase): # # def setUp(self): +# import ftplib, time, threading # ftplib.FTP.port = 9093 # self.evt = threading.Event() # threading.Thread(target=server, args=(self.evt,)).start() @@ -603,31 +605,37 @@ class Pathname_Tests(unittest.TestCase): # def testBasic(self): # # connects # ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, []) -# ftp.ftp.sock.close() +# ftp.close() # -# def testTimeoutDefault(self): -# # default -# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, []) -# self.assertTrue(ftp.ftp.sock.gettimeout() is None) -# ftp.ftp.sock.close() -# -# def testTimeoutValue(self): -# # a value -# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [], timeout=30) +# def testTimeoutNone(self): +# # global default timeout is ignored +# import socket +# self.assert_(socket.getdefaulttimeout() is None) +# socket.setdefaulttimeout(30) +# try: +# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, []) +# finally: +# socket.setdefaulttimeout(None) # self.assertEqual(ftp.ftp.sock.gettimeout(), 30) -# ftp.ftp.sock.close() +# ftp.close() # -# def testTimeoutNone(self): -# # None, having other default -# previous = socket.getdefaulttimeout() +# def testTimeoutDefault(self): +# # global default timeout is used +# import socket +# self.assert_(socket.getdefaulttimeout() is None) # socket.setdefaulttimeout(30) # try: # ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, []) # finally: -# socket.setdefaulttimeout(previous) +# socket.setdefaulttimeout(None) # self.assertEqual(ftp.ftp.sock.gettimeout(), 30) -# ftp.ftp.close() +# ftp.close() # +# def testTimeoutValue(self): +# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [], +# timeout=30) +# self.assertEqual(ftp.ftp.sock.gettimeout(), 30) +# ftp.close() diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index 8d17e05..1e93fdb 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -2,6 +2,7 @@ import unittest from test import test_support import os +import socket import StringIO import urllib2 @@ -551,14 +552,15 @@ class HandlerTests(unittest.TestCase): class NullFTPHandler(urllib2.FTPHandler): def __init__(self, data): self.data = data - def connect_ftp(self, user, passwd, host, port, dirs, timeout=None): + def connect_ftp(self, user, passwd, host, port, dirs, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT): self.user, self.passwd = user, passwd self.host, self.port = host, port self.dirs = dirs self.ftpwrapper = MockFTPWrapper(self.data) return self.ftpwrapper - import ftplib, socket + import ftplib data = "rheum rhaponicum" h = NullFTPHandler(data) o = h.parent = MockOpener() @@ -691,7 +693,7 @@ class HandlerTests(unittest.TestCase): self.req_headers = [] self.data = None self.raise_on_endheaders = False - def __call__(self, host, timeout=None): + def __call__(self, host, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): self.host = host self.timeout = timeout return self diff --git a/Lib/test/test_urllib2net.py b/Lib/test/test_urllib2net.py index 1ebaf8f..ee21c55 100644 --- a/Lib/test/test_urllib2net.py +++ b/Lib/test/test_urllib2net.py @@ -189,46 +189,58 @@ class OtherNetworkTests(unittest.TestCase): class TimeoutTest(unittest.TestCase): def test_http_basic(self): + self.assertTrue(socket.getdefaulttimeout() is None) u = _urlopen_with_retry("http://www.python.org") self.assertTrue(u.fp._sock.fp._sock.gettimeout() is None) - def test_http_NoneWithdefault(self): - prev = socket.getdefaulttimeout() + def test_http_default_timeout(self): + self.assertTrue(socket.getdefaulttimeout() is None) + socket.setdefaulttimeout(60) + try: + u = _urlopen_with_retry("http://www.python.org") + finally: + socket.setdefaulttimeout(None) + self.assertEqual(u.fp._sock.fp._sock.gettimeout(), 60) + + def test_http_no_timeout(self): + self.assertTrue(socket.getdefaulttimeout() is None) socket.setdefaulttimeout(60) try: u = _urlopen_with_retry("http://www.python.org", timeout=None) - self.assertEqual(u.fp._sock.fp._sock.gettimeout(), 60) finally: - socket.setdefaulttimeout(prev) + socket.setdefaulttimeout(None) + self.assertTrue(u.fp._sock.fp._sock.gettimeout() is None) - def test_http_Value(self): + def test_http_timeout(self): u = _urlopen_with_retry("http://www.python.org", timeout=120) self.assertEqual(u.fp._sock.fp._sock.gettimeout(), 120) - def test_http_NoneNodefault(self): - u = _urlopen_with_retry("http://www.python.org", timeout=None) - self.assertTrue(u.fp._sock.fp._sock.gettimeout() is None) - FTP_HOST = "ftp://ftp.mirror.nl/pub/mirror/gnu/" def test_ftp_basic(self): + self.assertTrue(socket.getdefaulttimeout() is None) u = _urlopen_with_retry(self.FTP_HOST) self.assertTrue(u.fp.fp._sock.gettimeout() is None) - def test_ftp_NoneWithdefault(self): - prev = socket.getdefaulttimeout() + def test_ftp_default_timeout(self): + self.assertTrue(socket.getdefaulttimeout() is None) socket.setdefaulttimeout(60) try: - u = _urlopen_with_retry(self.FTP_HOST, timeout=None) - self.assertEqual(u.fp.fp._sock.gettimeout(), 60) + u = _urlopen_with_retry(self.FTP_HOST) finally: - socket.setdefaulttimeout(prev) + socket.setdefaulttimeout(None) + self.assertEqual(u.fp.fp._sock.gettimeout(), 60) - def test_ftp_NoneNodefault(self): - u = _urlopen_with_retry(self.FTP_HOST, timeout=None) + def test_ftp_no_timeout(self): + self.assertTrue(socket.getdefaulttimeout() is None) + socket.setdefaulttimeout(60) + try: + u = _urlopen_with_retry(self.FTP_HOST, timeout=None) + finally: + socket.setdefaulttimeout(None) self.assertTrue(u.fp.fp._sock.gettimeout() is None) - def test_ftp_Value(self): + def test_ftp_timeout(self): u = _urlopen_with_retry(self.FTP_HOST, timeout=60) self.assertEqual(u.fp.fp._sock.gettimeout(), 60) diff --git a/Lib/urllib.py b/Lib/urllib.py index bf5fc97..ab22a95 100644 --- a/Lib/urllib.py +++ b/Lib/urllib.py @@ -832,7 +832,8 @@ def noheaders(): class ftpwrapper: """Class used by open_ftp() for cache of open FTP connections.""" - def __init__(self, user, passwd, host, port, dirs, timeout=None): + def __init__(self, user, passwd, host, port, dirs, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT): self.user = user self.passwd = passwd self.host = host diff --git a/Lib/urllib2.py b/Lib/urllib2.py index 546cea6..156c6f8 100644 --- a/Lib/urllib2.py +++ b/Lib/urllib2.py @@ -117,7 +117,7 @@ from urllib import localhost, url2pathname, getproxies __version__ = sys.version[:3] _opener = None -def urlopen(url, data=None, timeout=None): +def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): global _opener if _opener is None: _opener = build_opener() @@ -359,7 +359,7 @@ class OpenerDirector: if result is not None: return result - def open(self, fullurl, data=None, timeout=None): + def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): # accept a URL or a Request object if isinstance(fullurl, basestring): req = Request(fullurl, data) -- cgit v0.12