1 """Regresssion tests for urllib"""
6 from test
import test_support
13 """Escape char as RFC 2396 specifies"""
14 hex_repr
= hex(ord(char
))[2:].upper()
15 if len(hex_repr
) == 1:
16 hex_repr
= "0%s" % hex_repr
19 class urlopen_FileTests(unittest
.TestCase
):
20 """Test urlopen() opening a temporary file.
22 Try to test as much functionality as possible so as to cut down on reliance
23 on connecting to the Net for testing.
28 """Setup of a temp file to use for testing"""
29 self
.text
= "test_urllib: %s\n" % self
.__class
__.__name
__
30 FILE
= file(test_support
.TESTFN
, 'wb')
35 self
.pathname
= test_support
.TESTFN
36 self
.returned_obj
= urllib
.urlopen("file:%s" % self
.pathname
)
39 """Shut down the open object"""
40 self
.returned_obj
.close()
41 os
.remove(test_support
.TESTFN
)
43 def test_interface(self
):
44 # Make sure object returned by urlopen() has the specified methods
45 for attr
in ("read", "readline", "readlines", "fileno",
46 "close", "info", "geturl", "getcode", "__iter__"):
47 self
.assertTrue(hasattr(self
.returned_obj
, attr
),
48 "object returned by urlopen() lacks %s attribute" %
52 self
.assertEqual(self
.text
, self
.returned_obj
.read())
54 def test_readline(self
):
55 self
.assertEqual(self
.text
, self
.returned_obj
.readline())
56 self
.assertEqual('', self
.returned_obj
.readline(),
57 "calling readline() after exhausting the file did not"
58 " return an empty string")
60 def test_readlines(self
):
61 lines_list
= self
.returned_obj
.readlines()
62 self
.assertEqual(len(lines_list
), 1,
63 "readlines() returned the wrong number of lines")
64 self
.assertEqual(lines_list
[0], self
.text
,
65 "readlines() returned improper text")
67 def test_fileno(self
):
68 file_num
= self
.returned_obj
.fileno()
69 self
.assertTrue(isinstance(file_num
, int),
70 "fileno() did not return an int")
71 self
.assertEqual(os
.read(file_num
, len(self
.text
)), self
.text
,
72 "Reading on the file descriptor returned by fileno() "
73 "did not return the expected text")
76 # Test close() by calling it hear and then having it be called again
77 # by the tearDown() method for the test
78 self
.returned_obj
.close()
81 self
.assertTrue(isinstance(self
.returned_obj
.info(), mimetools
.Message
))
83 def test_geturl(self
):
84 self
.assertEqual(self
.returned_obj
.geturl(), self
.pathname
)
86 def test_getcode(self
):
87 self
.assertEqual(self
.returned_obj
.getcode(), None)
91 # Don't need to count number of iterations since test would fail the
92 # instant it returned anything beyond the first line from the
94 for line
in self
.returned_obj
.__iter
__():
95 self
.assertEqual(line
, self
.text
)
98 class ProxyTests(unittest
.TestCase
):
101 # Records changes to env vars
102 self
.env
= test_support
.EnvironmentVarGuard()
103 # Delete all proxy related env vars
104 for k
, v
in os
.environ
.iteritems():
105 if 'proxy' in k
.lower():
109 # Restore all proxy related env vars
113 def test_getproxies_environment_keep_no_proxies(self
):
114 self
.env
.set('NO_PROXY', 'localhost')
115 proxies
= urllib
.getproxies_environment()
116 # getproxies_environment use lowered case truncated (no '_proxy') keys
117 self
.assertEquals('localhost', proxies
['no'])
120 class urlopen_HttpTests(unittest
.TestCase
):
121 """Test urlopen() opening a fake http connection."""
123 def fakehttp(self
, fakedata
):
124 class FakeSocket(StringIO
.StringIO
):
125 def sendall(self
, str): pass
126 def makefile(self
, mode
, name
): return self
127 def read(self
, amt
=None):
128 if self
.closed
: return ''
129 return StringIO
.StringIO
.read(self
, amt
)
130 def readline(self
, length
=None):
131 if self
.closed
: return ''
132 return StringIO
.StringIO
.readline(self
, length
)
133 class FakeHTTPConnection(httplib
.HTTPConnection
):
135 self
.sock
= FakeSocket(fakedata
)
136 assert httplib
.HTTP
._connection
_class
== httplib
.HTTPConnection
137 httplib
.HTTP
._connection
_class
= FakeHTTPConnection
139 def unfakehttp(self
):
140 httplib
.HTTP
._connection
_class
= httplib
.HTTPConnection
143 self
.fakehttp('Hello!')
145 fp
= urllib
.urlopen("http://python.org/")
146 self
.assertEqual(fp
.readline(), 'Hello!')
147 self
.assertEqual(fp
.readline(), '')
148 self
.assertEqual(fp
.geturl(), 'http://python.org/')
149 self
.assertEqual(fp
.getcode(), 200)
153 def test_read_bogus(self
):
154 # urlopen() should raise IOError for many error codes.
155 self
.fakehttp('''HTTP/1.1 401 Authentication Required
156 Date: Wed, 02 Jan 2008 03:03:54 GMT
157 Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
159 Content-Type: text/html; charset=iso-8859-1
162 self
.assertRaises(IOError, urllib
.urlopen
, "http://python.org/")
166 def test_empty_socket(self
):
167 # urlopen() raises IOError if the underlying socket does not send any
171 self
.assertRaises(IOError, urllib
.urlopen
, 'http://something')
175 class urlretrieve_FileTests(unittest
.TestCase
):
176 """Test urllib.urlretrieve() on local files"""
179 # Create a list of temporary files. Each item in the list is a file
180 # name (absolute path or relative to the current working directory).
181 # All files in this list will be deleted in the tearDown method. Note,
182 # this only helps to makes sure temporary files get deleted, but it
183 # does nothing about trying to close files that may still be open. It
184 # is the responsibility of the developer to properly close files even
185 # when exceptional conditions occur.
188 # Create a temporary file.
189 self
.registerFileForCleanUp(test_support
.TESTFN
)
190 self
.text
= 'testing urllib.urlretrieve'
192 FILE
= file(test_support
.TESTFN
, 'wb')
193 FILE
.write(self
.text
)
200 # Delete the temporary files.
201 for each
in self
.tempFiles
:
205 def constructLocalFileUrl(self
, filePath
):
206 return "file://%s" % urllib
.pathname2url(os
.path
.abspath(filePath
))
208 def createNewTempFile(self
, data
=""):
209 """Creates a new temporary file containing the specified data,
210 registers the file for deletion during the test fixture tear down, and
211 returns the absolute path of the file."""
213 newFd
, newFilePath
= tempfile
.mkstemp()
215 self
.registerFileForCleanUp(newFilePath
)
216 newFile
= os
.fdopen(newFd
, "wb")
224 def registerFileForCleanUp(self
, fileName
):
225 self
.tempFiles
.append(fileName
)
227 def test_basic(self
):
228 # Make sure that a local file just gets its own location returned and
229 # a headers value is returned.
230 result
= urllib
.urlretrieve("file:%s" % test_support
.TESTFN
)
231 self
.assertEqual(result
[0], test_support
.TESTFN
)
232 self
.assertTrue(isinstance(result
[1], mimetools
.Message
),
233 "did not get a mimetools.Message instance as second "
237 # Test that setting the filename argument works.
238 second_temp
= "%s.2" % test_support
.TESTFN
239 self
.registerFileForCleanUp(second_temp
)
240 result
= urllib
.urlretrieve(self
.constructLocalFileUrl(
241 test_support
.TESTFN
), second_temp
)
242 self
.assertEqual(second_temp
, result
[0])
243 self
.assertTrue(os
.path
.exists(second_temp
), "copy of the file was not "
245 FILE
= file(second_temp
, 'rb')
252 self
.assertEqual(self
.text
, text
)
254 def test_reporthook(self
):
255 # Make sure that the reporthook works.
256 def hooktester(count
, block_size
, total_size
, count_holder
=[0]):
257 self
.assertTrue(isinstance(count
, int))
258 self
.assertTrue(isinstance(block_size
, int))
259 self
.assertTrue(isinstance(total_size
, int))
260 self
.assertEqual(count
, count_holder
[0])
261 count_holder
[0] = count_holder
[0] + 1
262 second_temp
= "%s.2" % test_support
.TESTFN
263 self
.registerFileForCleanUp(second_temp
)
264 urllib
.urlretrieve(self
.constructLocalFileUrl(test_support
.TESTFN
),
265 second_temp
, hooktester
)
267 def test_reporthook_0_bytes(self
):
268 # Test on zero length file. Should call reporthook only 1 time.
270 def hooktester(count
, block_size
, total_size
, _report
=report
):
271 _report
.append((count
, block_size
, total_size
))
272 srcFileName
= self
.createNewTempFile()
273 urllib
.urlretrieve(self
.constructLocalFileUrl(srcFileName
),
274 test_support
.TESTFN
, hooktester
)
275 self
.assertEqual(len(report
), 1)
276 self
.assertEqual(report
[0][2], 0)
278 def test_reporthook_5_bytes(self
):
279 # Test on 5 byte file. Should call reporthook only 2 times (once when
280 # the "network connection" is established and once when the block is
281 # read). Since the block size is 8192 bytes, only one block read is
282 # required to read the entire file.
284 def hooktester(count
, block_size
, total_size
, _report
=report
):
285 _report
.append((count
, block_size
, total_size
))
286 srcFileName
= self
.createNewTempFile("x" * 5)
287 urllib
.urlretrieve(self
.constructLocalFileUrl(srcFileName
),
288 test_support
.TESTFN
, hooktester
)
289 self
.assertEqual(len(report
), 2)
290 self
.assertEqual(report
[0][1], 8192)
291 self
.assertEqual(report
[0][2], 5)
293 def test_reporthook_8193_bytes(self
):
294 # Test on 8193 byte file. Should call reporthook only 3 times (once
295 # when the "network connection" is established, once for the next 8192
296 # bytes, and once for the last byte).
298 def hooktester(count
, block_size
, total_size
, _report
=report
):
299 _report
.append((count
, block_size
, total_size
))
300 srcFileName
= self
.createNewTempFile("x" * 8193)
301 urllib
.urlretrieve(self
.constructLocalFileUrl(srcFileName
),
302 test_support
.TESTFN
, hooktester
)
303 self
.assertEqual(len(report
), 3)
304 self
.assertEqual(report
[0][1], 8192)
305 self
.assertEqual(report
[0][2], 8193)
307 class QuotingTests(unittest
.TestCase
):
308 """Tests for urllib.quote() and urllib.quote_plus()
310 According to RFC 2396 ("Uniform Resource Identifiers), to escape a
311 character you write it as '%' + <2 character US-ASCII hex value>. The Python
312 code of ``'%' + hex(ord(<character>))[2:]`` escapes a character properly.
313 Case does not matter on the hex letters.
315 The various character sets specified are:
317 Reserved characters : ";/?:@&=+$,"
318 Have special meaning in URIs and must be escaped if not being used for
319 their special meaning
320 Data characters : letters, digits, and "-_.!~*'()"
321 Unreserved and do not need to be escaped; can be, though, if desired
322 Control characters : 0x00 - 0x1F, 0x7F
323 Have no use in URIs so must be escaped
333 def test_never_quote(self
):
334 # Make sure quote() does not quote letters, digits, and "_,.-"
335 do_not_quote
= '' .join(["ABCDEFGHIJKLMNOPQRSTUVWXYZ",
336 "abcdefghijklmnopqrstuvwxyz",
339 result
= urllib
.quote(do_not_quote
)
340 self
.assertEqual(do_not_quote
, result
,
341 "using quote(): %s != %s" % (do_not_quote
, result
))
342 result
= urllib
.quote_plus(do_not_quote
)
343 self
.assertEqual(do_not_quote
, result
,
344 "using quote_plus(): %s != %s" % (do_not_quote
, result
))
346 def test_default_safe(self
):
347 # Test '/' is default value for 'safe' parameter
348 self
.assertEqual(urllib
.quote
.func_defaults
[0], '/')
351 # Test setting 'safe' parameter does what it should do
352 quote_by_default
= "<>"
353 result
= urllib
.quote(quote_by_default
, safe
=quote_by_default
)
354 self
.assertEqual(quote_by_default
, result
,
355 "using quote(): %s != %s" % (quote_by_default
, result
))
356 result
= urllib
.quote_plus(quote_by_default
, safe
=quote_by_default
)
357 self
.assertEqual(quote_by_default
, result
,
358 "using quote_plus(): %s != %s" %
359 (quote_by_default
, result
))
361 def test_default_quoting(self
):
362 # Make sure all characters that should be quoted are by default sans
363 # space (separate test for that).
364 should_quote
= [chr(num
) for num
in range(32)] # For 0x00 - 0x1F
365 should_quote
.append('<>#%"{}|\^[]`')
366 should_quote
.append(chr(127)) # For 0x7F
367 should_quote
= ''.join(should_quote
)
368 for char
in should_quote
:
369 result
= urllib
.quote(char
)
370 self
.assertEqual(hexescape(char
), result
,
371 "using quote(): %s should be escaped to %s, not %s" %
372 (char
, hexescape(char
), result
))
373 result
= urllib
.quote_plus(char
)
374 self
.assertEqual(hexescape(char
), result
,
375 "using quote_plus(): "
376 "%s should be escapes to %s, not %s" %
377 (char
, hexescape(char
), result
))
379 partial_quote
= "ab[]cd"
380 expected
= "ab%5B%5Dcd"
381 result
= urllib
.quote(partial_quote
)
382 self
.assertEqual(expected
, result
,
383 "using quote(): %s != %s" % (expected
, result
))
384 self
.assertEqual(expected
, result
,
385 "using quote_plus(): %s != %s" % (expected
, result
))
387 def test_quoting_space(self
):
388 # Make sure quote() and quote_plus() handle spaces as specified in
390 result
= urllib
.quote(' ')
391 self
.assertEqual(result
, hexescape(' '),
392 "using quote(): %s != %s" % (result
, hexescape(' ')))
393 result
= urllib
.quote_plus(' ')
394 self
.assertEqual(result
, '+',
395 "using quote_plus(): %s != +" % result
)
397 expect
= given
.replace(' ', hexescape(' '))
398 result
= urllib
.quote(given
)
399 self
.assertEqual(expect
, result
,
400 "using quote(): %s != %s" % (expect
, result
))
401 expect
= given
.replace(' ', '+')
402 result
= urllib
.quote_plus(given
)
403 self
.assertEqual(expect
, result
,
404 "using quote_plus(): %s != %s" % (expect
, result
))
406 def test_quoting_plus(self
):
407 self
.assertEqual(urllib
.quote_plus('alpha+beta gamma'),
408 'alpha%2Bbeta+gamma')
409 self
.assertEqual(urllib
.quote_plus('alpha+beta gamma', '+'),
412 class UnquotingTests(unittest
.TestCase
):
413 """Tests for unquote() and unquote_plus()
415 See the doc string for quoting_Tests for details on quoting and such.
419 def test_unquoting(self
):
420 # Make sure unquoting of all ASCII values works
422 for num
in range(128):
423 given
= hexescape(chr(num
))
425 result
= urllib
.unquote(given
)
426 self
.assertEqual(expect
, result
,
427 "using unquote(): %s != %s" % (expect
, result
))
428 result
= urllib
.unquote_plus(given
)
429 self
.assertEqual(expect
, result
,
430 "using unquote_plus(): %s != %s" %
432 escape_list
.append(given
)
433 escape_string
= ''.join(escape_list
)
435 result
= urllib
.unquote(escape_string
)
436 self
.assertEqual(result
.count('%'), 1,
437 "using quote(): not all characters escaped; %s" %
439 result
= urllib
.unquote(escape_string
)
440 self
.assertEqual(result
.count('%'), 1,
441 "using unquote(): not all characters escaped: "
444 def test_unquoting_parts(self
):
445 # Make sure unquoting works when have non-quoted characters
447 given
= 'ab%sd' % hexescape('c')
449 result
= urllib
.unquote(given
)
450 self
.assertEqual(expect
, result
,
451 "using quote(): %s != %s" % (expect
, result
))
452 result
= urllib
.unquote_plus(given
)
453 self
.assertEqual(expect
, result
,
454 "using unquote_plus(): %s != %s" % (expect
, result
))
456 def test_unquoting_plus(self
):
457 # Test difference between unquote() and unquote_plus()
458 given
= "are+there+spaces..."
460 result
= urllib
.unquote(given
)
461 self
.assertEqual(expect
, result
,
462 "using unquote(): %s != %s" % (expect
, result
))
463 expect
= given
.replace('+', ' ')
464 result
= urllib
.unquote_plus(given
)
465 self
.assertEqual(expect
, result
,
466 "using unquote_plus(): %s != %s" % (expect
, result
))
468 def test_unquote_with_unicode(self
):
469 r
= urllib
.unquote(u
'br%C3%BCckner_sapporo_20050930.doc')
470 self
.assertEqual(r
, u
'br\xc3\xbcckner_sapporo_20050930.doc')
472 class urlencode_Tests(unittest
.TestCase
):
473 """Tests for urlencode()"""
475 def help_inputtype(self
, given
, test_type
):
476 """Helper method for testing different input types.
478 'given' must lead to only the pairs:
483 Test cannot assume anything about order. Docs make no guarantee and
484 have possible dictionary input.
487 expect_somewhere
= ["1st=1", "2nd=2", "3rd=3"]
488 result
= urllib
.urlencode(given
)
489 for expected
in expect_somewhere
:
490 self
.assertTrue(expected
in result
,
491 "testing %s: %s not found in %s" %
492 (test_type
, expected
, result
))
493 self
.assertEqual(result
.count('&'), 2,
494 "testing %s: expected 2 '&'s; got %s" %
495 (test_type
, result
.count('&')))
496 amp_location
= result
.index('&')
497 on_amp_left
= result
[amp_location
- 1]
498 on_amp_right
= result
[amp_location
+ 1]
499 self
.assertTrue(on_amp_left
.isdigit() and on_amp_right
.isdigit(),
500 "testing %s: '&' not located in proper place in %s" %
502 self
.assertEqual(len(result
), (5 * 3) + 2, #5 chars per thing and amps
504 "unexpected number of characters: %s != %s" %
505 (test_type
, len(result
), (5 * 3) + 2))
507 def test_using_mapping(self
):
508 # Test passing in a mapping object as an argument.
509 self
.help_inputtype({"1st":'1', "2nd":'2', "3rd":'3'},
510 "using dict as input type")
512 def test_using_sequence(self
):
513 # Test passing in a sequence of two-item sequences as an argument.
514 self
.help_inputtype([('1st', '1'), ('2nd', '2'), ('3rd', '3')],
515 "using sequence of two-item tuples as input")
517 def test_quoting(self
):
518 # Make sure keys and values are quoted using quote_plus()
520 expect
= "%s=%s" % (hexescape('&'), hexescape('='))
521 result
= urllib
.urlencode(given
)
522 self
.assertEqual(expect
, result
)
523 given
= {"key name":"A bunch of pluses"}
524 expect
= "key+name=A+bunch+of+pluses"
525 result
= urllib
.urlencode(given
)
526 self
.assertEqual(expect
, result
)
528 def test_doseq(self
):
529 # Test that passing True for 'doseq' parameter works correctly
530 given
= {'sequence':['1', '2', '3']}
531 expect
= "sequence=%s" % urllib
.quote_plus(str(['1', '2', '3']))
532 result
= urllib
.urlencode(given
)
533 self
.assertEqual(expect
, result
)
534 result
= urllib
.urlencode(given
, True)
535 for value
in given
["sequence"]:
536 expect
= "sequence=%s" % value
537 self
.assertTrue(expect
in result
,
538 "%s not found in %s" % (expect
, result
))
539 self
.assertEqual(result
.count('&'), 2,
540 "Expected 2 '&'s, got %s" % result
.count('&'))
542 class Pathname_Tests(unittest
.TestCase
):
543 """Test pathname2url() and url2pathname()"""
545 def test_basic(self
):
546 # Make sure simple tests pass
547 expected_path
= os
.path
.join("parts", "of", "a", "path")
548 expected_url
= "parts/of/a/path"
549 result
= urllib
.pathname2url(expected_path
)
550 self
.assertEqual(expected_url
, result
,
551 "pathname2url() failed; %s != %s" %
552 (result
, expected_url
))
553 result
= urllib
.url2pathname(expected_url
)
554 self
.assertEqual(expected_path
, result
,
555 "url2pathame() failed; %s != %s" %
556 (result
, expected_path
))
558 def test_quoting(self
):
559 # Test automatic quoting and unquoting works for pathnam2url() and
560 # url2pathname() respectively
561 given
= os
.path
.join("needs", "quot=ing", "here")
562 expect
= "needs/%s/here" % urllib
.quote("quot=ing")
563 result
= urllib
.pathname2url(given
)
564 self
.assertEqual(expect
, result
,
565 "pathname2url() failed; %s != %s" %
568 result
= urllib
.url2pathname(result
)
569 self
.assertEqual(expect
, result
,
570 "url2pathname() failed; %s != %s" %
572 given
= os
.path
.join("make sure", "using_quote")
573 expect
= "%s/using_quote" % urllib
.quote("make sure")
574 result
= urllib
.pathname2url(given
)
575 self
.assertEqual(expect
, result
,
576 "pathname2url() failed; %s != %s" %
578 given
= "make+sure/using_unquote"
579 expect
= os
.path
.join("make+sure", "using_unquote")
580 result
= urllib
.url2pathname(given
)
581 self
.assertEqual(expect
, result
,
582 "url2pathname() failed; %s != %s" %
585 class Utility_Tests(unittest
.TestCase
):
586 """Testcase to test the various utility functions in the urllib."""
588 def test_splitpasswd(self
):
589 """Some of the password examples are not sensible, but it is added to
590 confirming to RFC2617 and addressing issue4675.
592 self
.assertEqual(('user', 'ab'),urllib
.splitpasswd('user:ab'))
593 self
.assertEqual(('user', 'a\nb'),urllib
.splitpasswd('user:a\nb'))
594 self
.assertEqual(('user', 'a\tb'),urllib
.splitpasswd('user:a\tb'))
595 self
.assertEqual(('user', 'a\rb'),urllib
.splitpasswd('user:a\rb'))
596 self
.assertEqual(('user', 'a\fb'),urllib
.splitpasswd('user:a\fb'))
597 self
.assertEqual(('user', 'a\vb'),urllib
.splitpasswd('user:a\vb'))
598 self
.assertEqual(('user', 'a:b'),urllib
.splitpasswd('user:a:b'))
601 class URLopener_Tests(unittest
.TestCase
):
602 """Testcase to test the open method of URLopener class."""
604 def test_quoted_open(self
):
605 class DummyURLopener(urllib
.URLopener
):
606 def open_spam(self
, url
):
609 self
.assertEqual(DummyURLopener().open(
610 'spam://example/ /'),'//example/%20/')
613 # Just commented them out.
614 # Can't really tell why keep failing in windows and sparc.
615 # Everywhere else they work ok, but on those machines, someteimes
616 # fail in one of the tests, sometimes in other. I have a linux, and
618 # If anybody has one of the problematic enviroments, please help!
622 # import socket, time
623 # serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
625 # serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
626 # serv.bind(("", 9093))
629 # conn, addr = serv.accept()
630 # conn.send("1 Hola mundo\n")
632 # while cantdata < 13:
633 # data = conn.recv(13-cantdata)
634 # cantdata += len(data)
636 # conn.send("2 No more lines\n")
638 # except socket.timeout:
644 # class FTPWrapperTests(unittest.TestCase):
647 # import ftplib, time, threading
648 # ftplib.FTP.port = 9093
649 # self.evt = threading.Event()
650 # threading.Thread(target=server, args=(self.evt,)).start()
653 # def tearDown(self):
656 # def testBasic(self):
658 # ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
661 # def testTimeoutNone(self):
662 # # global default timeout is ignored
664 # self.assertTrue(socket.getdefaulttimeout() is None)
665 # socket.setdefaulttimeout(30)
667 # ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
669 # socket.setdefaulttimeout(None)
670 # self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
673 # def testTimeoutDefault(self):
674 # # global default timeout is used
676 # self.assertTrue(socket.getdefaulttimeout() is None)
677 # socket.setdefaulttimeout(30)
679 # ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
681 # socket.setdefaulttimeout(None)
682 # self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
685 # def testTimeoutValue(self):
686 # ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [],
688 # self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
695 with warnings
.catch_warnings():
696 warnings
.filterwarnings('ignore', ".*urllib\.urlopen.*Python 3.0",
698 test_support
.run_unittest(
701 urlretrieve_FileTests
,
714 if __name__
== '__main__':