diff options
| author | Benjamin Peterson <benjamin@python.org> | 2013-01-04 04:34:40 (GMT) |
|---|---|---|
| committer | Benjamin Peterson <benjamin@python.org> | 2013-01-04 04:34:40 (GMT) |
| commit | d73f369f4c52e921ba225043c0a820856369ef44 (patch) | |
| tree | 4bc702b04312d48bc99c52c7621e15ef99f3c0ac /Lib/test | |
| parent | 0a2c4f55c4d3288dce74513ef135fae167646f02 (diff) | |
| parent | c44057dfbdb4e4f651e7cc4761aa63b7e8d128c3 (diff) | |
| download | cpython-d73f369f4c52e921ba225043c0a820856369ef44.zip cpython-d73f369f4c52e921ba225043c0a820856369ef44.tar.gz cpython-d73f369f4c52e921ba225043c0a820856369ef44.tar.bz2 | |
merge heads
Diffstat (limited to 'Lib/test')
| -rwxr-xr-x | Lib/test/regrtest.py | 6 | ||||
| -rw-r--r-- | Lib/test/support.py | 78 | ||||
| -rw-r--r-- | Lib/test/test_aifc.py | 11 | ||||
| -rw-r--r-- | Lib/test/test_bz2.py | 15 | ||||
| -rw-r--r-- | Lib/test/test_cfgparser.py | 53 | ||||
| -rw-r--r-- | Lib/test/test_cmd_line.py | 6 | ||||
| -rw-r--r-- | Lib/test/test_cmd_line_script.py | 24 | ||||
| -rw-r--r-- | Lib/test/test_genericpath.py | 17 | ||||
| -rw-r--r-- | Lib/test/test_glob.py | 77 | ||||
| -rw-r--r-- | Lib/test/test_int.py | 21 | ||||
| -rw-r--r-- | Lib/test/test_multiprocessing.py | 1 | ||||
| -rw-r--r-- | Lib/test/test_os.py | 59 | ||||
| -rw-r--r-- | Lib/test/test_ssl.py | 11 | ||||
| -rw-r--r-- | Lib/test/test_subprocess.py | 3 | ||||
| -rw-r--r-- | Lib/test/test_tarfile.py | 22 | ||||
| -rw-r--r-- | Lib/test/test_urllib2.py | 36 | ||||
| -rw-r--r-- | Lib/test/test_urllib2_localnet.py | 2 | ||||
| -rwxr-xr-x | Lib/test/test_urlparse.py | 29 | ||||
| -rw-r--r-- | Lib/test/test_winreg.py | 29 |
19 files changed, 430 insertions, 70 deletions
diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index e098522..84beb8d 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -33,7 +33,7 @@ Verbosity Selecting tests --r/--random -- randomize test execution order (see below) +-r/--randomize -- randomize test execution order (see below) --randseed -- pass a random seed to reproduce a previous random run -f/--fromfile -- read names of tests to run from a file (see below) -x/--exclude -- arguments are tests to *exclude* @@ -274,11 +274,11 @@ def main(tests=None, testdir=None, verbose=0, quiet=False, try: opts, args = getopt.getopt(sys.argv[1:], 'hvqxsoS:rf:lu:t:TD:NLR:FdwWM:nj:Gm:', ['help', 'verbose', 'verbose2', 'verbose3', 'quiet', - 'exclude', 'single', 'slow', 'random', 'fromfile', 'findleaks', + 'exclude', 'single', 'slow', 'randomize', 'fromfile=', 'findleaks', 'use=', 'threshold=', 'coverdir=', 'nocoverdir', 'runleaks', 'huntrleaks=', 'memlimit=', 'randseed=', 'multiprocess=', 'coverage', 'slaveargs=', 'forever', 'debug', - 'start=', 'nowindows', 'header', 'failfast', 'match']) + 'start=', 'nowindows', 'header', 'failfast', 'match=']) except getopt.error as msg: usage(msg) diff --git a/Lib/test/support.py b/Lib/test/support.py index e1ec9e2..2130fd6 100644 --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -523,6 +523,49 @@ else: # module name. TESTFN = "{}_{}_tmp".format(TESTFN, os.getpid()) +# FS_NONASCII: non-ASCII character encodable by os.fsencode(), +# or None if there is no such character. +FS_NONASCII = None +for character in ( + # First try printable and common characters to have a readable filename. + # For each character, the encoding list are just example of encodings able + # to encode the character (the list is not exhaustive). + + # U+00E6 (Latin Small Letter Ae): cp1252, iso-8859-1 + '\u00E6', + # U+0130 (Latin Capital Letter I With Dot Above): cp1254, iso8859_3 + '\u0130', + # U+0141 (Latin Capital Letter L With Stroke): cp1250, cp1257 + '\u0141', + # U+03C6 (Greek Small Letter Phi): cp1253 + '\u03C6', + # U+041A (Cyrillic Capital Letter Ka): cp1251 + '\u041A', + # U+05D0 (Hebrew Letter Alef): Encodable to cp424 + '\u05D0', + # U+060C (Arabic Comma): cp864, cp1006, iso8859_6, mac_arabic + '\u060C', + # U+062A (Arabic Letter Teh): cp720 + '\u062A', + # U+0E01 (Thai Character Ko Kai): cp874 + '\u0E01', + + # Then try more "special" characters. "special" because they may be + # interpreted or displayed differently depending on the exact locale + # encoding and the font. + + # U+00A0 (No-Break Space) + '\u00A0', + # U+20AC (Euro Sign) + '\u20AC', +): + try: + os.fsdecode(os.fsencode(character)) + except UnicodeError: + pass + else: + FS_NONASCII = character + break # TESTFN_UNICODE is a non-ascii filename TESTFN_UNICODE = TESTFN + "-\xe0\xf2\u0258\u0141\u011f" @@ -567,6 +610,41 @@ elif sys.platform != 'darwin': # the byte 0xff. Skip some unicode filename tests. pass +# TESTFN_UNDECODABLE is a filename (bytes type) that should *not* be able to be +# decoded from the filesystem encoding (in strict mode). It can be None if we +# cannot generate such filename (ex: the latin1 encoding can decode any byte +# sequence). On UNIX, TESTFN_UNDECODABLE can be decoded by os.fsdecode() thanks +# to the surrogateescape error handler (PEP 383), but not from the filesystem +# encoding in strict mode. +TESTFN_UNDECODABLE = None +for name in ( + # b'\xff' is not decodable by os.fsdecode() with code page 932. Windows + # accepts it to create a file or a directory, or don't accept to enter to + # such directory (when the bytes name is used). So test b'\xe7' first: it is + # not decodable from cp932. + b'\xe7w\xf0', + # undecodable from ASCII, UTF-8 + b'\xff', + # undecodable from iso8859-3, iso8859-6, iso8859-7, cp424, iso8859-8, cp856 + # and cp857 + b'\xae\xd5' + # undecodable from UTF-8 (UNIX and Mac OS X) + b'\xed\xb2\x80', b'\xed\xb4\x80', + # undecodable from shift_jis, cp869, cp874, cp932, cp1250, cp1251, cp1252, + # cp1253, cp1254, cp1255, cp1257, cp1258 + b'\x81\x98', +): + try: + name.decode(TESTFN_ENCODING) + except UnicodeDecodeError: + TESTFN_UNDECODABLE = os.fsencode(TESTFN) + name + break + +if FS_NONASCII: + TESTFN_NONASCII = TESTFN + '-' + FS_NONASCII +else: + TESTFN_NONASCII = None + # Save the initial cwd SAVEDCWD = os.getcwd() diff --git a/Lib/test/test_aifc.py b/Lib/test/test_aifc.py index ee4ad6b..0b19af6 100644 --- a/Lib/test/test_aifc.py +++ b/Lib/test/test_aifc.py @@ -112,6 +112,13 @@ class AIFCTest(unittest.TestCase): self.assertEqual(testfile.closed, False) f.close() self.assertEqual(testfile.closed, True) + testfile = open(TESTFN, 'wb') + fout = aifc.open(testfile, 'wb') + self.assertFalse(testfile.closed) + with self.assertRaises(aifc.Error): + fout.close() + self.assertTrue(testfile.closed) + fout.close() # do nothing def test_write_header_comptype_sampwidth(self): for comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'): @@ -291,11 +298,13 @@ class AIFCLowLevelTest(unittest.TestCase): def test_write_header_raises(self): fout = aifc.open(io.BytesIO(), 'wb') self.assertRaises(aifc.Error, fout.close) + fout = aifc.open(io.BytesIO(), 'wb') fout.setnchannels(1) self.assertRaises(aifc.Error, fout.close) + fout = aifc.open(io.BytesIO(), 'wb') + fout.setnchannels(1) fout.setsampwidth(1) self.assertRaises(aifc.Error, fout.close) - fout.initfp(None) def test_write_header_comptype_raises(self): for comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'): diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py index 5b48e2b..977d10b 100644 --- a/Lib/test/test_bz2.py +++ b/Lib/test/test_bz2.py @@ -24,6 +24,7 @@ class BaseTest(unittest.TestCase): TEXT = b'root:x:0:0:root:/root:/bin/bash\nbin:x:1:1:bin:/bin:\ndaemon:x:2:2:daemon:/sbin:\nadm:x:3:4:adm:/var/adm:\nlp:x:4:7:lp:/var/spool/lpd:\nsync:x:5:0:sync:/sbin:/bin/sync\nshutdown:x:6:0:shutdown:/sbin:/sbin/shutdown\nhalt:x:7:0:halt:/sbin:/sbin/halt\nmail:x:8:12:mail:/var/spool/mail:\nnews:x:9:13:news:/var/spool/news:\nuucp:x:10:14:uucp:/var/spool/uucp:\noperator:x:11:0:operator:/root:\ngames:x:12:100:games:/usr/games:\ngopher:x:13:30:gopher:/usr/lib/gopher-data:\nftp:x:14:50:FTP User:/var/ftp:/bin/bash\nnobody:x:65534:65534:Nobody:/home:\npostfix:x:100:101:postfix:/var/spool/postfix:\nniemeyer:x:500:500::/home/niemeyer:/bin/bash\npostgres:x:101:102:PostgreSQL Server:/var/lib/pgsql:/bin/bash\nmysql:x:102:103:MySQL server:/var/lib/mysql:/bin/bash\nwww:x:103:104::/var/www:/bin/false\n' DATA = b'BZh91AY&SY.\xc8N\x18\x00\x01>_\x80\x00\x10@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe00\x01\x99\xaa\x00\xc0\x03F\x86\x8c#&\x83F\x9a\x03\x06\xa6\xd0\xa6\x93M\x0fQ\xa7\xa8\x06\x804hh\x12$\x11\xa4i4\xf14S\xd2<Q\xb5\x0fH\xd3\xd4\xdd\xd5\x87\xbb\xf8\x94\r\x8f\xafI\x12\xe1\xc9\xf8/E\x00pu\x89\x12]\xc9\xbbDL\nQ\x0e\t1\x12\xdf\xa0\xc0\x97\xac2O9\x89\x13\x94\x0e\x1c7\x0ed\x95I\x0c\xaaJ\xa4\x18L\x10\x05#\x9c\xaf\xba\xbc/\x97\x8a#C\xc8\xe1\x8cW\xf9\xe2\xd0\xd6M\xa7\x8bXa<e\x84t\xcbL\xb3\xa7\xd9\xcd\xd1\xcb\x84.\xaf\xb3\xab\xab\xad`n}\xa0lh\tE,\x8eZ\x15\x17VH>\x88\xe5\xcd9gd6\x0b\n\xe9\x9b\xd5\x8a\x99\xf7\x08.K\x8ev\xfb\xf7xw\xbb\xdf\xa1\x92\xf1\xdd|/";\xa2\xba\x9f\xd5\xb1#A\xb6\xf6\xb3o\xc9\xc5y\\\xebO\xe7\x85\x9a\xbc\xb6f8\x952\xd5\xd7"%\x89>V,\xf7\xa6z\xe2\x9f\xa3\xdf\x11\x11"\xd6E)I\xa9\x13^\xca\xf3r\xd0\x03U\x922\xf26\xec\xb6\xed\x8b\xc3U\x13\x9d\xc5\x170\xa4\xfa^\x92\xacDF\x8a\x97\xd6\x19\xfe\xdd\xb8\xbd\x1a\x9a\x19\xa3\x80ankR\x8b\xe5\xd83]\xa9\xc6\x08\x82f\xf6\xb9"6l$\xb8j@\xc0\x8a\xb0l1..\xbak\x83ls\x15\xbc\xf4\xc1\x13\xbe\xf8E\xb8\x9d\r\xa8\x9dk\x84\xd3n\xfa\xacQ\x07\xb1%y\xaav\xb4\x08\xe0z\x1b\x16\xf5\x04\xe9\xcc\xb9\x08z\x1en7.G\xfc]\xc9\x14\xe1B@\xbb!8`' DATA_CRLF = b'BZh91AY&SY\xaez\xbbN\x00\x01H\xdf\x80\x00\x12@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe0@\x01\xbc\xc6`\x86*\x8d=M\xa9\x9a\x86\xd0L@\x0fI\xa6!\xa1\x13\xc8\x88jdi\x8d@\x03@\x1a\x1a\x0c\x0c\x83 \x00\xc4h2\x19\x01\x82D\x84e\t\xe8\x99\x89\x19\x1ah\x00\r\x1a\x11\xaf\x9b\x0fG\xf5(\x1b\x1f?\t\x12\xcf\xb5\xfc\x95E\x00ps\x89\x12^\xa4\xdd\xa2&\x05(\x87\x04\x98\x89u\xe40%\xb6\x19\'\x8c\xc4\x89\xca\x07\x0e\x1b!\x91UIFU%C\x994!DI\xd2\xfa\xf0\xf1N8W\xde\x13A\xf5\x9cr%?\x9f3;I45A\xd1\x8bT\xb1<l\xba\xcb_\xc00xY\x17r\x17\x88\x08\x08@\xa0\ry@\x10\x04$)`\xf2\xce\x89z\xb0s\xec\x9b.iW\x9d\x81\xb5-+t\x9f\x1a\'\x97dB\xf5x\xb5\xbe.[.\xd7\x0e\x81\xe7\x08\x1cN`\x88\x10\xca\x87\xc3!"\x80\x92R\xa1/\xd1\xc0\xe6mf\xac\xbd\x99\xcca\xb3\x8780>\xa4\xc7\x8d\x1a\\"\xad\xa1\xabyBg\x15\xb9l\x88\x88\x91k"\x94\xa4\xd4\x89\xae*\xa6\x0b\x10\x0c\xd6\xd4m\xe86\xec\xb5j\x8a\x86j\';\xca.\x01I\xf2\xaaJ\xe8\x88\x8cU+t3\xfb\x0c\n\xa33\x13r2\r\x16\xe0\xb3(\xbf\x1d\x83r\xe7M\xf0D\x1365\xd8\x88\xd3\xa4\x92\xcb2\x06\x04\\\xc1\xb0\xea//\xbek&\xd8\xe6+t\xe5\xa1\x13\xada\x16\xder5"w]\xa2i\xb7[\x97R \xe2IT\xcd;Z\x04dk4\xad\x8a\t\xd3\x81z\x10\xf1:^`\xab\x1f\xc5\xdc\x91N\x14$+\x9e\xae\xd3\x80' + EMPTY_DATA = b'BZh9\x17rE8P\x90\x00\x00\x00\x00' with open(findfile("testbz2_bigmem.bz2"), "rb") as f: DATA_BIGMEM = f.read() @@ -303,6 +304,12 @@ class BZ2CompressorTest(BaseTest): data += bz2c.flush() self.assertEqual(self.decompress(data), self.TEXT) + def testCompressEmptyString(self): + bz2c = BZ2Compressor() + data = bz2c.compress(b'') + data += bz2c.flush() + self.assertEqual(data, self.EMPTY_DATA) + def testCompressChunks10(self): # "Test BZ2Compressor.compress()/flush() with chunks of 10 bytes" bz2c = BZ2Compressor() @@ -383,6 +390,10 @@ class FuncTest(BaseTest): data = bz2.compress(self.TEXT) self.assertEqual(self.decompress(data), self.TEXT) + def testCompressEmptyString(self): + text = bz2.compress(b'') + self.assertEqual(text, self.EMPTY_DATA) + def testDecompress(self): # "Test decompress() function" text = bz2.decompress(self.DATA) @@ -393,6 +404,10 @@ class FuncTest(BaseTest): text = bz2.decompress(b"") self.assertEqual(text, b"") + def testDecompressToEmptyString(self): + text = bz2.decompress(self.EMPTY_DATA) + self.assertEqual(text, b'') + def testDecompressIncomplete(self): # "Test decompress() function with incomplete data" self.assertRaises(ValueError, bz2.decompress, self.DATA[:-10]) diff --git a/Lib/test/test_cfgparser.py b/Lib/test/test_cfgparser.py index a6e9050..cec9b44 100644 --- a/Lib/test/test_cfgparser.py +++ b/Lib/test/test_cfgparser.py @@ -770,6 +770,59 @@ boolean {0[0]} NO with self.assertRaises(configparser.NoSectionError): cf.items("no such section") + def test_popitem(self): + cf = self.fromstring(""" + [section1] + name1 {0[0]} value1 + [section2] + name2 {0[0]} value2 + [section3] + name3 {0[0]} value3 + """.format(self.delimiters), defaults={"default": "<default>"}) + self.assertEqual(cf.popitem()[0], 'section1') + self.assertEqual(cf.popitem()[0], 'section2') + self.assertEqual(cf.popitem()[0], 'section3') + with self.assertRaises(KeyError): + cf.popitem() + + def test_clear(self): + cf = self.newconfig({"foo": "Bar"}) + self.assertEqual( + cf.get(self.default_section, "Foo"), "Bar", + "could not locate option, expecting case-insensitive option names") + cf['zing'] = {'option1': 'value1', 'option2': 'value2'} + self.assertEqual(cf.sections(), ['zing']) + self.assertEqual(set(cf['zing'].keys()), {'option1', 'option2', 'foo'}) + cf.clear() + self.assertEqual(set(cf.sections()), set()) + self.assertEqual(set(cf[self.default_section].keys()), {'foo'}) + + def test_setitem(self): + cf = self.fromstring(""" + [section1] + name1 {0[0]} value1 + [section2] + name2 {0[0]} value2 + [section3] + name3 {0[0]} value3 + """.format(self.delimiters), defaults={"nameD": "valueD"}) + self.assertEqual(set(cf['section1'].keys()), {'name1', 'named'}) + self.assertEqual(set(cf['section2'].keys()), {'name2', 'named'}) + self.assertEqual(set(cf['section3'].keys()), {'name3', 'named'}) + self.assertEqual(cf['section1']['name1'], 'value1') + self.assertEqual(cf['section2']['name2'], 'value2') + self.assertEqual(cf['section3']['name3'], 'value3') + self.assertEqual(cf.sections(), ['section1', 'section2', 'section3']) + cf['section2'] = {'name22': 'value22'} + self.assertEqual(set(cf['section2'].keys()), {'name22', 'named'}) + self.assertEqual(cf['section2']['name22'], 'value22') + self.assertNotIn('name2', cf['section2']) + self.assertEqual(cf.sections(), ['section1', 'section2', 'section3']) + cf['section3'] = {} + self.assertEqual(set(cf['section3'].keys()), {'named'}) + self.assertNotIn('name3', cf['section3']) + self.assertEqual(cf.sections(), ['section1', 'section2', 'section3']) + class StrictTestCase(BasicTestCase): config_class = configparser.RawConfigParser diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index c10bd76..67375cd 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -100,11 +100,11 @@ class CmdLineTest(unittest.TestCase): # All good if execution is successful assert_python_ok('-c', 'pass') - @unittest.skipIf(sys.getfilesystemencoding() == 'ascii', - 'need a filesystem encoding different than ASCII') + @unittest.skipUnless(test.support.FS_NONASCII, 'need support.FS_NONASCII') def test_non_ascii(self): # Test handling of non-ascii data - command = "assert(ord('\xe9') == 0xe9)" + command = ("assert(ord(%r) == %s)" + % (test.support.FS_NONASCII, ord(test.support.FS_NONASCII))) assert_python_ok('-c', command) # On Windows, pass bytes to subprocess doesn't test how Python decodes the diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py index 6b59d96..70f7d1e 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -294,6 +294,30 @@ class CmdLineTest(unittest.TestCase): print(out) self.assertEqual(rc, 1) + def test_non_ascii(self): + # Mac OS X denies the creation of a file with an invalid UTF-8 name. + # Windows allows to create a name with an arbitrary bytes name, but + # Python cannot a undecodable bytes argument to a subprocess. + if (support.TESTFN_UNDECODABLE + and sys.platform not in ('win32', 'darwin')): + name = os.fsdecode(support.TESTFN_UNDECODABLE) + elif support.TESTFN_NONASCII: + name = support.TESTFN_NONASCII + else: + self.skipTest("need support.TESTFN_NONASCII") + + # Issue #16218 + source = 'print(ascii(__file__))\n' + script_name = _make_test_script(os.curdir, name, source) + self.addCleanup(support.unlink, script_name) + rc, stdout, stderr = assert_python_ok(script_name) + self.assertEqual( + ascii(script_name), + stdout.rstrip().decode('ascii'), + 'stdout=%r stderr=%r' % (stdout, stderr)) + self.assertEqual(0, rc) + + def test_main(): support.run_unittest(CmdLineTest) support.reap_children() diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index 50638a1..6020923 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -292,11 +292,20 @@ class CommonTest(GenericTest): for path in ('', 'fuu', 'f\xf9\xf9', '/fuu', 'U:\\'): self.assertIsInstance(abspath(path), str) - @unittest.skipIf(sys.platform == 'darwin', - "Mac OS X denies the creation of a directory with an invalid utf8 name") def test_nonascii_abspath(self): - # Test non-ASCII, non-UTF8 bytes in the path. - with support.temp_cwd(b'\xe7w\xf0'): + if (support.TESTFN_UNDECODABLE + # Mac OS X denies the creation of a directory with an invalid + # UTF-8 name. Windows allows to create a directory with an + # arbitrary bytes name, but fails to enter this directory + # (when the bytes name is used). + and sys.platform not in ('win32', 'darwin')): + name = support.TESTFN_UNDECODABLE + elif support.TESTFN_NONASCII: + name = support.TESTFN_NONASCII + else: + self.skipTest("need support.TESTFN_NONASCII") + + with support.temp_cwd(name): self.test_abspath() diff --git a/Lib/test/test_glob.py b/Lib/test/test_glob.py index 2dba8de..1cdc24a 100644 --- a/Lib/test/test_glob.py +++ b/Lib/test/test_glob.py @@ -1,9 +1,10 @@ -import unittest -from test.support import run_unittest, TESTFN, skip_unless_symlink, can_symlink import glob import os import shutil import sys +import unittest + +from test.support import run_unittest, TESTFN, skip_unless_symlink, can_symlink class GlobTests(unittest.TestCase): @@ -31,7 +32,8 @@ class GlobTests(unittest.TestCase): self.mktemp('a', 'bcd', 'efg', 'ha') if can_symlink(): os.symlink(self.norm('broken'), self.norm('sym1')) - os.symlink(self.norm('broken'), self.norm('sym2')) + os.symlink('broken', self.norm('sym2')) + os.symlink(os.path.join('a', 'bcd'), self.norm('sym3')) def tearDown(self): shutil.rmtree(self.tempdir) @@ -44,10 +46,16 @@ class GlobTests(unittest.TestCase): p = os.path.join(self.tempdir, pattern) res = glob.glob(p) self.assertEqual(list(glob.iglob(p)), res) + bres = [os.fsencode(x) for x in res] + self.assertEqual(glob.glob(os.fsencode(p)), bres) + self.assertEqual(list(glob.iglob(os.fsencode(p))), bres) return res def assertSequencesEqual_noorder(self, l1, l2): + l1 = list(l1) + l2 = list(l2) self.assertEqual(set(l1), set(l2)) + self.assertEqual(sorted(l1), sorted(l2)) def test_glob_literal(self): eq = self.assertSequencesEqual_noorder @@ -56,15 +64,15 @@ class GlobTests(unittest.TestCase): eq(self.glob('aab'), [self.norm('aab')]) eq(self.glob('zymurgy'), []) - # test return types are unicode, but only if os.listdir - # returns unicode filenames - uniset = set([str]) - tmp = os.listdir('.') - if set(type(x) for x in tmp) == uniset: - u1 = glob.glob('*') - u2 = glob.glob('./*') - self.assertEqual(set(type(r) for r in u1), uniset) - self.assertEqual(set(type(r) for r in u2), uniset) + res = glob.glob('*') + self.assertEqual({type(r) for r in res}, {str}) + res = glob.glob(os.path.join(os.curdir, '*')) + self.assertEqual({type(r) for r in res}, {str}) + + res = glob.glob(b'*') + self.assertEqual({type(r) for r in res}, {bytes}) + res = glob.glob(os.path.join(os.fsencode(os.curdir), b'*')) + self.assertEqual({type(r) for r in res}, {bytes}) def test_glob_one_directory(self): eq = self.assertSequencesEqual_noorder @@ -93,20 +101,20 @@ class GlobTests(unittest.TestCase): eq(self.glob('*', '*a'), []) eq(self.glob('a', '*', '*', '*a'), [self.norm('a', 'bcd', 'efg', 'ha')]) - eq(self.glob('?a?', '*F'), map(self.norm, [os.path.join('aaa', 'zzzF'), - os.path.join('aab', 'F')])) + eq(self.glob('?a?', '*F'), [self.norm('aaa', 'zzzF'), + self.norm('aab', 'F')]) def test_glob_directory_with_trailing_slash(self): # Patterns ending with a slash shouldn't match non-dirs - res = glob.glob(os.path.join(self.tempdir, 'Z*Z') + os.sep) + res = glob.glob(self.norm('Z*Z') + os.sep) self.assertEqual(res, []) - res = glob.glob(os.path.join(self.tempdir, 'ZZZ') + os.sep) + res = glob.glob(self.norm('ZZZ') + os.sep) self.assertEqual(res, []) - # When there is wildcard pattern which ends with os.sep, glob() + # When there is a wildcard pattern which ends with os.sep, glob() # doesn't blow up. - res = glob.glob(os.path.join(self.tempdir, 'aa*') + os.sep) + res = glob.glob(self.norm('aa*') + os.sep) self.assertEqual(len(res), 2) - # either of these results are reasonable + # either of these results is reasonable self.assertIn(set(res), [ {self.norm('aaa'), self.norm('aab')}, {self.norm('aaa') + os.sep, self.norm('aab') + os.sep}, @@ -115,22 +123,37 @@ class GlobTests(unittest.TestCase): def test_glob_bytes_directory_with_trailing_slash(self): # Same as test_glob_directory_with_trailing_slash, but with a # bytes argument. - res = glob.glob(os.fsencode(os.path.join(self.tempdir, 'Z*Z') + os.sep)) + res = glob.glob(os.fsencode(self.norm('Z*Z') + os.sep)) self.assertEqual(res, []) - res = glob.glob(os.fsencode(os.path.join(self.tempdir, 'ZZZ') + os.sep)) + res = glob.glob(os.fsencode(self.norm('ZZZ') + os.sep)) self.assertEqual(res, []) - res = glob.glob(os.fsencode(os.path.join(self.tempdir, 'aa*') + os.sep)) + res = glob.glob(os.fsencode(self.norm('aa*') + os.sep)) self.assertEqual(len(res), 2) - # either of these results are reasonable - self.assertIn({os.fsdecode(x) for x in res}, [ - {self.norm('aaa'), self.norm('aab')}, - {self.norm('aaa') + os.sep, self.norm('aab') + os.sep}, + # either of these results is reasonable + self.assertIn(set(res), [ + {os.fsencode(self.norm('aaa')), + os.fsencode(self.norm('aab'))}, + {os.fsencode(self.norm('aaa') + os.sep), + os.fsencode(self.norm('aab') + os.sep)}, ]) @skip_unless_symlink + def test_glob_symlinks(self): + eq = self.assertSequencesEqual_noorder + eq(self.glob('sym3'), [self.norm('sym3')]) + eq(self.glob('sym3', '*'), [self.norm('sym3', 'EF'), + self.norm('sym3', 'efg')]) + self.assertIn(self.glob('sym3' + os.sep), + [[self.norm('sym3')], [self.norm('sym3') + os.sep]]) + eq(self.glob('*', '*F'), + [self.norm('aaa', 'zzzF'), + self.norm('aab', 'F'), self.norm('sym3', 'EF')]) + + @skip_unless_symlink def test_glob_broken_symlinks(self): eq = self.assertSequencesEqual_noorder - eq(self.glob('sym*'), [self.norm('sym1'), self.norm('sym2')]) + eq(self.glob('sym*'), [self.norm('sym1'), self.norm('sym2'), + self.norm('sym3')]) eq(self.glob('sym1'), [self.norm('sym1')]) eq(self.glob('sym2'), [self.norm('sym2')]) diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py index 437e323..671b20a 100644 --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -1,6 +1,7 @@ import sys import unittest +from test import support from test.support import run_unittest L = [ @@ -100,10 +101,6 @@ class IntTestCases(unittest.TestCase): self.assertRaises(ValueError, int, "0b", 2) self.assertRaises(ValueError, int, "0b", 0) - # Bug #3236: Return small longs from PyLong_FromString - self.assertTrue(int("10") is 10) - self.assertTrue(int("-1") is -1) - # SF bug 1334662: int(string, base) wrong answers # Various representations of 2**32 evaluated to 0 # rather than 2**32 in previous versions @@ -221,6 +218,22 @@ class IntTestCases(unittest.TestCase): self.assertEqual(int('2br45qc', 35), 4294967297) self.assertEqual(int('1z141z5', 36), 4294967297) + @support.cpython_only + def test_small_ints(self): + # Bug #3236: Return small longs from PyLong_FromString + self.assertIs(int('10'), 10) + self.assertIs(int('-1'), -1) + self.assertIs(int(b'10'), 10) + self.assertIs(int(b'-1'), -1) + + def test_keyword_args(self): + # Test invoking int() using keyword arguments. + self.assertEqual(int(x=1.2), 1) + self.assertEqual(int('100', base=2), 4) + self.assertEqual(int(x='100', base=2), 4) + self.assertRaises(TypeError, int, base=10) + self.assertRaises(TypeError, int, base=0) + def test_intconversion(self): # Test __int__() class ClassicMissingMethods: diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py index ab6d36a..fa4865b 100644 --- a/Lib/test/test_multiprocessing.py +++ b/Lib/test/test_multiprocessing.py @@ -1574,6 +1574,7 @@ class _TestConnection(BaseTestCase): self.assertTimingAlmostEqual(poll.elapsed, TIMEOUT1) conn.send(None) + time.sleep(.1) self.assertEqual(poll(TIMEOUT1), True) self.assertTimingAlmostEqual(poll.elapsed, 0) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 612c62a..720e78b 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -634,6 +634,50 @@ class MakedirTests(unittest.TestCase): os.removedirs(path) + +class RemoveDirsTests(unittest.TestCase): + def setUp(self): + os.makedirs(support.TESTFN) + + def tearDown(self): + support.rmtree(support.TESTFN) + + def test_remove_all(self): + dira = os.path.join(support.TESTFN, 'dira') + os.mkdir(dira) + dirb = os.path.join(dira, 'dirb') + os.mkdir(dirb) + os.removedirs(dirb) + self.assertFalse(os.path.exists(dirb)) + self.assertFalse(os.path.exists(dira)) + self.assertFalse(os.path.exists(support.TESTFN)) + + def test_remove_partial(self): + dira = os.path.join(support.TESTFN, 'dira') + os.mkdir(dira) + dirb = os.path.join(dira, 'dirb') + os.mkdir(dirb) + with open(os.path.join(dira, 'file.txt'), 'w') as f: + f.write('text') + os.removedirs(dirb) + self.assertFalse(os.path.exists(dirb)) + self.assertTrue(os.path.exists(dira)) + self.assertTrue(os.path.exists(support.TESTFN)) + + def test_remove_nothing(self): + dira = os.path.join(support.TESTFN, 'dira') + os.mkdir(dira) + dirb = os.path.join(dira, 'dirb') + os.mkdir(dirb) + with open(os.path.join(dirb, 'file.txt'), 'w') as f: + f.write('text') + with self.assertRaises(OSError): + os.removedirs(dirb) + self.assertTrue(os.path.exists(dirb)) + self.assertTrue(os.path.exists(dira)) + self.assertTrue(os.path.exists(support.TESTFN)) + + class DevNullTests(unittest.TestCase): def test_devnull(self): with open(os.devnull, 'wb') as f: @@ -642,6 +686,7 @@ class DevNullTests(unittest.TestCase): with open(os.devnull, 'rb') as f: self.assertEqual(f.read(), b'') + class URandomTests(unittest.TestCase): def test_urandom_length(self): self.assertEqual(len(os.urandom(0)), 0) @@ -968,6 +1013,8 @@ if sys.platform != 'win32': def setUp(self): if support.TESTFN_UNENCODABLE: self.dir = support.TESTFN_UNENCODABLE + elif support.TESTFN_NONASCII: + self.dir = support.TESTFN_NONASCII else: self.dir = support.TESTFN self.bdir = os.fsencode(self.dir) @@ -982,6 +1029,8 @@ if sys.platform != 'win32': add_filename(support.TESTFN_UNICODE) if support.TESTFN_UNENCODABLE: add_filename(support.TESTFN_UNENCODABLE) + if support.TESTFN_NONASCII: + add_filename(support.TESTFN_NONASCII) if not bytesfn: self.skipTest("couldn't create any non-ascii filename") @@ -1012,6 +1061,15 @@ if sys.platform != 'win32': f = open(os.path.join(self.dir, fn), 'rb') f.close() + @unittest.skipUnless(hasattr(os, 'statvfs'), + "need os.statvfs()") + def test_statvfs(self): + # issue #9645 + for fn in self.unicodefn: + # should not fail with file not found error + fullname = os.path.join(self.dir, fn) + os.statvfs(fullname) + def test_stat(self): for fn in self.unicodefn: os.stat(os.path.join(self.dir, fn)) @@ -1310,6 +1368,7 @@ def test_main(): PidTests, LoginTests, LinkTests, + RemoveDirsTests, ) if __name__ == "__main__": diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 2f0b3e6..4f254a9 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -558,6 +558,17 @@ class NetworkedTests(unittest.TestCase): finally: s.close() + def test_connect_ex_error(self): + with support.transient_internet("svn.python.org"): + s = ssl.wrap_socket(socket.socket(socket.AF_INET), + cert_reqs=ssl.CERT_REQUIRED, + ca_certs=SVN_PYTHON_ORG_ROOT_CERT) + try: + self.assertEqual(errno.ECONNREFUSED, + s.connect_ex(("svn.python.org", 444))) + finally: + s.close() + def test_connect_with_context(self): with support.transient_internet("svn.python.org"): # Same as test_connect, but with a separately created context diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index f7a7b11..75eb852 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -2023,8 +2023,7 @@ class ContextManagerTests(BaseTestCase): stderr=subprocess.PIPE) as proc: pass - if c.exception.errno != errno.ENOENT: # ignore "no such file" - raise c.exception + self.assertEqual(c.exception.errno, errno.ENOENT) def test_main(): diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index f32eb8c..a53181e 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -328,31 +328,21 @@ class MiscReadTest(CommonReadTest): @support.skip_unless_symlink def test_extract_hardlink(self): # Test hardlink extraction (e.g. bug #857297). - tar = tarfile.open(tarname, errorlevel=1, encoding="iso8859-1") - - try: + with tarfile.open(tarname, errorlevel=1, encoding="iso8859-1") as tar: tar.extract("ustar/regtype", TEMPDIR) - try: - tar.extract("ustar/lnktype", TEMPDIR) - except EnvironmentError as e: - if e.errno == errno.ENOENT: - self.fail("hardlink not extracted properly") + self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/regtype")) + tar.extract("ustar/lnktype", TEMPDIR) + self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/lnktype")) with open(os.path.join(TEMPDIR, "ustar/lnktype"), "rb") as f: data = f.read() self.assertEqual(md5sum(data), md5_regtype) - try: - tar.extract("ustar/symtype", TEMPDIR) - except EnvironmentError as e: - if e.errno == errno.ENOENT: - self.fail("symlink not extracted properly") - + tar.extract("ustar/symtype", TEMPDIR) + self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/symtype")) with open(os.path.join(TEMPDIR, "ustar/symtype"), "rb") as f: data = f.read() self.assertEqual(md5sum(data), md5_regtype) - finally: - tar.close() def test_extractall(self): # Test if extractall() correctly restores directory permissions diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index d8c302b..5eab30a 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -1438,16 +1438,32 @@ class RequestTests(unittest.TestCase): req = Request(url) self.assertEqual(req.get_full_url(), url) -def test_HTTPError_interface(): - """ - Issue 13211 reveals that HTTPError didn't implement the URLError - interface even though HTTPError is a subclass of URLError. - - >>> err = urllib.error.HTTPError(msg='something bad happened', url=None, code=None, hdrs=None, fp=None) - >>> assert hasattr(err, 'reason') - >>> err.reason - 'something bad happened' - """ + def test_HTTPError_interface(self): + """ + Issue 13211 reveals that HTTPError didn't implement the URLError + interface even though HTTPError is a subclass of URLError. + + >>> err = urllib.error.HTTPError(msg='something bad happened', url=None, code=None, hdrs=None, fp=None) + >>> assert hasattr(err, 'reason') + >>> err.reason + 'something bad happened' + """ + + def test_HTTPError_interface_call(self): + """ + Issue 15701 - HTTPError interface has info method available from URLError + """ + err = urllib.request.HTTPError(msg="something bad happened", url=None, + code=None, hdrs='Content-Length:42', fp=None) + self.assertTrue(hasattr(err, 'reason')) + assert hasattr(err, 'reason') + assert hasattr(err, 'info') + assert callable(err.info) + try: + err.info() + except AttributeError: + self.fail('err.info call failed.') + self.assertEqual(err.info(), "Content-Length:42") def test_main(verbose=None): from test import test_urllib2 diff --git a/Lib/test/test_urllib2_localnet.py b/Lib/test/test_urllib2_localnet.py index 9e1ce5b..f07471d 100644 --- a/Lib/test/test_urllib2_localnet.py +++ b/Lib/test/test_urllib2_localnet.py @@ -352,6 +352,8 @@ class TestUrlopen(unittest.TestCase): def setUp(self): super(TestUrlopen, self).setUp() + # Ignore proxies for localhost tests. + os.environ['NO_PROXY'] = '*' self.server = None def tearDown(self): diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index e9adaef..378a427 100755 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -818,6 +818,35 @@ class UrlParseTestCase(unittest.TestCase): p2 = urllib.parse.urlsplit('tel:+31641044153') self.assertEqual(p2.scheme, 'tel') self.assertEqual(p2.path, '+31641044153') + # assert the behavior for urlparse + p1 = urllib.parse.urlparse('tel:+31-641044153') + self.assertEqual(p1.scheme, 'tel') + self.assertEqual(p1.path, '+31-641044153') + p2 = urllib.parse.urlparse('tel:+31641044153') + self.assertEqual(p2.scheme, 'tel') + self.assertEqual(p2.path, '+31641044153') + + def test_telurl_params(self): + p1 = urllib.parse.urlparse('tel:123-4;phone-context=+1-650-516') + self.assertEqual(p1.scheme, 'tel') + self.assertEqual(p1.path, '123-4') + self.assertEqual(p1.params, 'phone-context=+1-650-516') + + p1 = urllib.parse.urlparse('tel:+1-201-555-0123') + self.assertEqual(p1.scheme, 'tel') + self.assertEqual(p1.path, '+1-201-555-0123') + self.assertEqual(p1.params, '') + + p1 = urllib.parse.urlparse('tel:7042;phone-context=example.com') + self.assertEqual(p1.scheme, 'tel') + self.assertEqual(p1.path, '7042') + self.assertEqual(p1.params, 'phone-context=example.com') + + p1 = urllib.parse.urlparse('tel:863-1234;phone-context=+1-914-555') + self.assertEqual(p1.scheme, 'tel') + self.assertEqual(p1.path, '863-1234') + self.assertEqual(p1.params, 'phone-context=+1-914-555') + def test_main(): support.run_unittest(UrlParseTestCase) diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index c7b50dd..a164d2f 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -323,6 +323,35 @@ class LocalWinregTests(BaseWinregTests): finally: DeleteKey(HKEY_CURRENT_USER, test_key_name) + def test_setvalueex_value_range(self): + # Test for Issue #14420, accept proper ranges for SetValueEx. + # Py2Reg, which gets called by SetValueEx, was using PyLong_AsLong, + # thus raising OverflowError. The implementation now uses + # PyLong_AsUnsignedLong to match DWORD's size. + try: + with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck: + self.assertNotEqual(ck.handle, 0) + SetValueEx(ck, "test_name", None, REG_DWORD, 0x80000000) + finally: + DeleteKey(HKEY_CURRENT_USER, test_key_name) + + def test_queryvalueex_return_value(self): + # Test for Issue #16759, return unsigned int from QueryValueEx. + # Reg2Py, which gets called by QueryValueEx, was returning a value + # generated by PyLong_FromLong. The implmentation now uses + # PyLong_FromUnsignedLong to match DWORD's size. + try: + with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck: + self.assertNotEqual(ck.handle, 0) + test_val = 0x80000000 + SetValueEx(ck, "test_name", None, REG_DWORD, test_val) + ret_val, ret_type = QueryValueEx(ck, "test_name") + self.assertEqual(ret_type, REG_DWORD) + self.assertEqual(ret_val, test_val) + finally: + DeleteKey(HKEY_CURRENT_USER, test_key_name) + + @unittest.skipUnless(REMOTE_NAME, "Skipping remote registry tests") class RemoteWinregTests(BaseWinregTests): |
