Index: Doc/library/urllib2.rst =================================================================== --- Doc/library/urllib2.rst (revision 62045) +++ Doc/library/urllib2.rst (working copy) @@ -27,9 +27,8 @@ returns a string in this format. 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). This actually only work for HTTP, HTTPS, FTP and - FTPS connections. + connection attempt (if not specified, the global default timeout setting will be + used). This actually only work for HTTP, HTTPS, FTP and FTPS connections. This function returns a file-like object with two additional methods: @@ -410,9 +409,9 @@ passing the given *data*. Arguments, return values and exceptions raised are 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 the connection attempt (if not - specified, or passed as None, the global default timeout setting will be used; - this actually only work for HTTP, HTTPS, FTP and FTPS connections). + parameter specifies a timeout in seconds for the connection attempt (if not + specified, the global default timeout setting will be used). The timeout feature + actually only work for HTTP, HTTPS, FTP and FTPS connections). .. versionchanged:: 2.6 *timeout* was added. Index: Doc/library/ftplib.rst =================================================================== --- Doc/library/ftplib.rst (revision 62045) +++ Doc/library/ftplib.rst (working copy) @@ -44,7 +44,7 @@ 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 the connection attempt (if is not specified, - or passed as None, the global default timeout setting will be used). + the global default timeout setting will be used). .. versionchanged:: 2.6 *timeout* was added. @@ -124,9 +124,8 @@ 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 timeout specified at object + construction time is used. .. versionchanged:: 2.6 *timeout* was added. Index: Doc/library/socket.rst =================================================================== --- Doc/library/socket.rst (revision 62045) +++ Doc/library/socket.rst (working copy) @@ -207,12 +207,11 @@ .. 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 Index: Doc/library/smtplib.rst =================================================================== --- Doc/library/smtplib.rst (revision 62045) +++ Doc/library/smtplib.rst (working copy) @@ -24,8 +24,8 @@ port parameters are given, the SMTP :meth:`connect` method is called 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 the connection attempt (if not specified, or - passed as None, the global default timeout setting will be used). + specifies a timeout in seconds for 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. @@ -38,13 +38,13 @@ A :class:`SMTP_SSL` instance behaves exactly the same as instances of :class:`SMTP`. :class:`SMTP_SSL` should be used for situations where SSL is - required from the beginning of the connection and using :meth:`starttls` is not + required from the beginning of the connection and using :meth:`starttls` is not appropriate. If *host* is not specified, the local host is used. If *port* is omitted, the standard SMTP-over-SSL port (465) is used. *keyfile* 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 the connection attempt (if not specified, or passed as - None, the global default timeout setting will be used). + timeout in seconds for the connection attempt (if not specified, the global + default timeout setting will be used). .. versionchanged:: 2.6 *timeout* was added. Index: Doc/library/httplib.rst =================================================================== --- Doc/library/httplib.rst (revision 62045) +++ Doc/library/httplib.rst (working copy) @@ -39,8 +39,8 @@ the optional parameter *strict* causes ``BadStatusLine`` to 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, connection attempts will timeout after - that many seconds (if it is not given or ``None``, the global default timeout - setting is used). + that many seconds (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:: Index: Doc/library/poplib.rst =================================================================== --- Doc/library/poplib.rst (revision 62045) +++ Doc/library/poplib.rst (working copy) @@ -29,8 +29,8 @@ 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. Index: Doc/library/telnetlib.rst =================================================================== --- Doc/library/telnetlib.rst (revision 62045) +++ Doc/library/telnetlib.rst (working copy) @@ -28,10 +28,10 @@ :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 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 the connection attempt (if not - specified, or passed as None, the global default timeout setting will be used). + and timeout 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 the connection attempt (if + not specified, the global default timeout setting will be used). Do not reopen an already connected instance. @@ -126,8 +126,8 @@ 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 the connection attempt (if not specified, or - passed as None, the global default timeout setting will be used). + specifies a timeout in seconds for the connection attempt (if not specified, the + global default timeout setting will be used). Do not try to reopen an already connected instance. Index: Lib/smtplib.py =================================================================== --- Lib/smtplib.py (revision 62045) +++ Lib/smtplib.py (working copy) @@ -220,7 +220,8 @@ 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 @@ 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) Index: Lib/ftplib.py =================================================================== --- Lib/ftplib.py (revision 62045) +++ Lib/ftplib.py (working copy) @@ -44,6 +44,7 @@ from socket import getfqdn; socket.getfqdn = getfqdn; del getfqdn except ImportError: import socket +from socket import _GLOBAL_DEFAULT_TIMEOUT __all__ = ["FTP","Netrc"] @@ -109,14 +110,15 @@ # 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=-1): '''Connect to host. Arguments are: - host: hostname to connect to (string, default previous host) - port: port to connect to (integer, default previous port) @@ -125,9 +127,10 @@ self.host = host if port > 0: self.port = port - if timeout is not None: + if timeout != -1: # not passed self.timeout = timeout - self.sock = socket.create_connection((self.host, self.port), self.timeout) + self.sock = socket.create_connection((self.host, self.port), + self.timeout) self.af = self.sock.family self.file = self.sock.makefile('rb') self.welcome = self.getresp() Index: Lib/socket.py =================================================================== --- Lib/socket.py (revision 62045) +++ Lib/socket.py (working copy) @@ -437,13 +437,17 @@ return line -def create_connection(address, timeout=None): - """Connect to address (host, port) with an optional timeout. +_GLOBAL_DEFAULT_TIMEOUT = 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). +def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT): + """Connect to *address* and return the socket object. + + 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" @@ -453,7 +457,7 @@ 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 Index: Lib/urllib.py =================================================================== --- Lib/urllib.py (revision 62045) +++ Lib/urllib.py (working copy) @@ -832,7 +832,8 @@ 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 Index: Lib/telnetlib.py =================================================================== --- Lib/telnetlib.py (revision 62045) +++ Lib/telnetlib.py (working copy) @@ -184,12 +184,13 @@ """ - 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 @@ -208,11 +209,11 @@ 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). + 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. @@ -222,9 +223,8 @@ 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.""" Index: Lib/httplib.py =================================================================== --- Lib/httplib.py (revision 62045) +++ Lib/httplib.py (working copy) @@ -639,7 +639,8 @@ 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 @@ 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 @@ -1063,7 +1064,8 @@ def connect(self): "Connect to a host on a given (SSL) port." - sock = socket.create_connection((self.host, self.port), self.timeout) + sock = socket.create_connection((self.host, self.port), + self.timeout) self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file) __all__.append("HTTPSConnection") Index: Lib/urllib2.py =================================================================== --- Lib/urllib2.py (revision 62045) +++ Lib/urllib2.py (working copy) @@ -117,7 +117,7 @@ __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 @@ 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) @@ -1326,7 +1326,8 @@ if key in self.cache: self.timeout[key] = time.time() + self.delay else: - self.cache[key] = ftpwrapper(user, passwd, host, port, dirs, timeout) + self.cache[key] = ftpwrapper(user, passwd, host, port, dirs, + timeout) self.timeout[key] = time.time() + self.delay self.check_cache() return self.cache[key] Index: Lib/test/test_smtplib.py =================================================================== --- Lib/test/test_smtplib.py (revision 62045) +++ Lib/test/test_smtplib.py (working copy) @@ -61,41 +61,43 @@ def testBasic1(self): # connects smtp = smtplib.SMTP(HOST, PORT) - smtp.sock.close() + smtp.close() def testBasic2(self): # connects, include port in host name smtp = smtplib.SMTP("%s:%s" % (HOST, PORT)) - smtp.sock.close() + smtp.close() def testLocalHostName(self): # check that supplied local_hostname is used smtp = smtplib.SMTP(HOST, PORT, local_hostname="testhost") self.assertEqual(smtp.local_hostname, "testhost") - smtp.sock.close() + smtp.close() def testTimeoutDefault(self): - # default - smtp = smtplib.SMTP(HOST, PORT) - self.assertTrue(smtp.sock.gettimeout() is None) - smtp.sock.close() - - def testTimeoutValue(self): - # a value - smtp = smtplib.SMTP(HOST, PORT, timeout=30) + self.assertTrue(socket.getdefaulttimeout() is None) + socket.setdefaulttimeout(30) + try: + smtp = smtplib.SMTP(HOST, 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, 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, PORT, timeout=30) self.assertEqual(smtp.sock.gettimeout(), 30) - smtp.sock.close() + smtp.close() # Test server thread using the specified SMTP server class Index: Lib/test/test_socket.py =================================================================== --- Lib/test/test_socket.py (revision 62045) +++ Lib/test/test_socket.py (working copy) @@ -879,9 +879,26 @@ testTimeoutDefault = _justAccept def _testTimeoutDefault(self): - self.cli = socket.create_connection((HOST, 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, 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, PORT), timeout=None) + finally: + socket.setdefaulttimeout(None) + self.assertEqual(self.cli.gettimeout(), None) + testTimeoutValueNamed = _justAccept def _testTimeoutValueNamed(self): self.cli = socket.create_connection((HOST, PORT), timeout=30) @@ -892,17 +909,7 @@ self.cli = socket.create_connection((HOST, 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, PORT), timeout=None) - finally: - socket.setdefaulttimeout(previous) - self.assertEqual(self.cli.gettimeout(), 30) - class NetworkConnectionBehaviourTest(SocketTCPTest, ThreadableTest): def __init__(self, methodName='runTest'): Index: Lib/test/test_httplib.py =================================================================== --- Lib/test/test_httplib.py (revision 62045) +++ Lib/test/test_httplib.py (working copy) @@ -216,26 +216,31 @@ '''This will prove that the timeout gets through HTTPConnection and into the socket. ''' - # default - httpConn = httplib.HTTPConnection(HOST, PORT) - httpConn.connect() - self.assertTrue(httpConn.sock.gettimeout() is None) - httpConn.close() - - # a value - httpConn = httplib.HTTPConnection(HOST, PORT, timeout=30) - httpConn.connect() + # default -- use global socket timeout + self.assert_(socket.getdefaulttimeout() is None) + socket.setdefaulttimeout(30) + try: + httpConn = httplib.HTTPConnection(HOST, 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, 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, PORT, timeout=30) + httpConn.connect() self.assertEqual(httpConn.sock.gettimeout(), 30) httpConn.close() @@ -250,7 +255,8 @@ self.assertEqual(h.timeout, 30) def test_main(verbose=None): - test_support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest, HTTPSTimeoutTest) + test_support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest, + HTTPSTimeoutTest) if __name__ == '__main__': test_main() Index: Lib/test/test_poplib.py =================================================================== --- Lib/test/test_poplib.py (revision 62045) +++ Lib/test/test_poplib.py (working copy) @@ -6,12 +6,14 @@ from unittest import TestCase from test import test_support +_TEST_PORT = 9091 + 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.bind(("", _TEST_PORT)) serv.listen(5) try: conn, addr = serv.accept() @@ -36,34 +38,35 @@ def testBasic(self): # connects - pop = poplib.POP3("localhost", 9091) + pop = poplib.POP3("localhost", _TEST_PORT) pop.sock.close() def testTimeoutDefault(self): - # default - pop = poplib.POP3("localhost", 9091) - self.assertTrue(pop.sock.gettimeout() is None) - pop.sock.close() - - def testTimeoutValue(self): - # a value - pop = poplib.POP3("localhost", 9091, timeout=30) + self.assertTrue(socket.getdefaulttimeout() is None) + socket.setdefaulttimeout(30) + try: + pop = poplib.POP3("localhost", _TEST_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("localhost", 9091, timeout=None) + pop = poplib.POP3("localhost", _TEST_PORT, timeout=None) finally: - socket.setdefaulttimeout(previous) + socket.setdefaulttimeout(None) + self.assertTrue(pop.sock.gettimeout() is None) + pop.sock.close() + + def testTimeoutValue(self): + pop = poplib.POP3("localhost", _TEST_PORT, timeout=30) self.assertEqual(pop.sock.gettimeout(), 30) pop.sock.close() - def test_main(verbose=None): test_support.run_unittest(GeneralTests) Index: Lib/test/test_ftplib.py =================================================================== --- Lib/test/test_ftplib.py (revision 62045) +++ Lib/test/test_ftplib.py (working copy) @@ -59,32 +59,49 @@ ftp.sock.close() def testTimeoutDefault(self): - # default - ftp = ftplib.FTP("localhost") + # 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("localhost", timeout=30) self.assertEqual(ftp.sock.gettimeout(), 30) self.evt.wait() - ftp.sock.close() + ftp.close() def testTimeoutConnect(self): ftp = ftplib.FTP() ftp.connect("localhost", 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("localhost") self.assertEqual(ftp.sock.gettimeout(), 30) self.evt.wait() - ftp.sock.close() + ftp.close() def testTimeoutDirectAccess(self): ftp = ftplib.FTP() @@ -92,18 +109,6 @@ ftp.connect("localhost") 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("localhost", timeout=None) - finally: - socket.setdefaulttimeout(previous) - self.assertEqual(ftp.sock.gettimeout(), 30) - self.evt.wait() ftp.close() Index: Lib/test/test_telnetlib.py =================================================================== --- Lib/test/test_telnetlib.py (revision 62045) +++ Lib/test/test_telnetlib.py (working copy) @@ -42,34 +42,35 @@ telnet.sock.close() def testTimeoutDefault(self): - # default - telnet = telnetlib.Telnet("localhost", PORT) - self.assertTrue(telnet.sock.gettimeout() is None) - telnet.sock.close() - - def testTimeoutValue(self): - # a value - telnet = telnetlib.Telnet("localhost", PORT, timeout=30) + self.assertTrue(socket.getdefaulttimeout() is None) + socket.setdefaulttimeout(30) + try: + telnet = telnetlib.Telnet("localhost", PORT) + finally: + socket.setdefaulttimeout(None) self.assertEqual(telnet.sock.gettimeout(), 30) telnet.sock.close() - def testTimeoutDifferentOrder(self): - telnet = telnetlib.Telnet(timeout=30) - telnet.open("localhost", PORT) - 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("localhost", 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", PORT, timeout=30) self.assertEqual(telnet.sock.gettimeout(), 30) telnet.sock.close() + def testTimeoutOpen(self): + telnet = telnetlib.Telnet() + telnet.open("localhost", PORT, timeout=30) + self.assertEqual(telnet.sock.gettimeout(), 30) + telnet.sock.close() def test_main(verbose=None): Index: Lib/test/test_urllib.py =================================================================== --- Lib/test/test_urllib.py (revision 62045) +++ Lib/test/test_urllib.py (working copy) @@ -568,6 +568,8 @@ # . Facundo # # def server(evt): +# import socket +# import time # serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # serv.settimeout(3) # serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) @@ -588,49 +590,57 @@ # finally: # serv.close() # evt.set() -# + # class FTPWrapperTests(unittest.TestCase): -# + # def setUp(self): +# import ftplib +# import time +# import threading # ftplib.FTP.port = 9093 # 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 # ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, []) -# ftp.ftp.sock.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) -# self.assertEqual(ftp.ftp.sock.gettimeout(), 30) -# ftp.ftp.sock.close() -# +# ftp.close() + # def testTimeoutNone(self): -# # None, having other default -# previous = socket.getdefaulttimeout() +# # 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(previous) +# socket.setdefaulttimeout(None) # self.assertEqual(ftp.ftp.sock.gettimeout(), 30) -# ftp.ftp.close() -# +# ftp.close() +# 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(None) +# self.assertEqual(ftp.ftp.sock.gettimeout(), 30) +# ftp.close() +# def testTimeoutValue(self): +# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [], +# timeout=30) +# self.assertEqual(ftp.ftp.sock.gettimeout(), 30) +# ftp.close() + def test_main(): test_support.run_unittest( urlopen_FileTests, @@ -644,6 +654,5 @@ ) - if __name__ == '__main__': test_main() Index: Lib/test/test_urllib2.py =================================================================== --- Lib/test/test_urllib2.py (revision 62045) +++ Lib/test/test_urllib2.py (working copy) @@ -2,6 +2,7 @@ from test import test_support import os +import socket import StringIO import urllib2 @@ -551,14 +552,15 @@ 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 @@ 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 Index: Lib/test/test_urllib2net.py =================================================================== --- Lib/test/test_urllib2net.py (revision 62045) +++ Lib/test/test_urllib2net.py (working copy) @@ -11,20 +11,26 @@ import mimetools -def _urlopen_with_retry(host, *args, **kwargs): - # Connecting to remote hosts is flaky. Make it more robust - # by retrying the connection several times. +def _retry_thrice(func, exc, *args, **kwargs): for i in range(3): try: - return urllib2.urlopen(host, *args, **kwargs) - except urllib2.URLError, last_exc: + return func(*args, **kwargs) + except exc, last_exc: continue except: raise raise last_exc +def _wrap_with_retry_thrice(func, exc): + def wrapped(*args, **kwargs): + return _retry_thrice(func, exc, *args, **kwargs) + return wrapped +# Connecting to remote hosts is flaky. Make it more robust by retrying +# the connection several times. +_urlopen_with_retry = _wrap_with_retry_thrice(urllib2.urlopen, urllib2.URLError) + class AuthTests(unittest.TestCase): """Tests urllib2 authentication features.""" @@ -115,7 +121,7 @@ 'file:'+sanepathname2url(os.path.abspath(TESTFN)), ('file:///nonsensename/etc/passwd', None, urllib2.URLError), ] - self._test_urls(urls, self._extra_handlers(), urllib2.urlopen) + self._test_urls(urls, self._extra_handlers(), retry=True) finally: os.remove(TESTFN) @@ -147,13 +153,15 @@ ## self._test_urls(urls, self._extra_handlers()+[bauth, dauth]) - def _test_urls(self, urls, handlers, urlopen=_urlopen_with_retry): + def _test_urls(self, urls, handlers, retry=True): import socket import time import logging debug = logging.getLogger("test_urllib2").debug - urllib2.install_opener(urllib2.build_opener(*handlers)) + urlopen = urllib2.build_opener(*handlers).open + if retry: + urlopen = _wrap_with_retry_thrice(urlopen, urllib2.URLError) for url in urls: if isinstance(url, tuple): @@ -166,8 +174,8 @@ except EnvironmentError, err: debug(err) if expected_err: - msg = ("Didn't get expected error(s) %s for %s %s, got %s: %s" % - (expected_err, url, req, type(err), err)) + msg = ("Didn't get expected error(s) %s for %s %s, got %s: " + "%s" % (expected_err, url, req, type(err), err)) self.assert_(isinstance(err, expected_err), msg) else: with test_support.transient_internet(): @@ -189,46 +197,58 @@ 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) + finally: + socket.setdefaulttimeout(None) + self.assertEqual(u.fp.fp._sock.gettimeout(), 60) + + 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) - self.assertEqual(u.fp.fp._sock.gettimeout(), 60) finally: - socket.setdefaulttimeout(prev) - - def test_ftp_NoneNodefault(self): - u = _urlopen_with_retry(self.FTP_HOST, timeout=None) + 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) Index: Lib/poplib.py =================================================================== --- Lib/poplib.py (revision 62045) +++ Lib/poplib.py (working copy) @@ -76,7 +76,8 @@ """ - 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)