diff options
Diffstat (limited to 'Lib')
33 files changed, 520 insertions, 128 deletions
diff --git a/Lib/SocketServer.py b/Lib/SocketServer.py index 1594321..26611b7 100644 --- a/Lib/SocketServer.py +++ b/Lib/SocketServer.py @@ -701,7 +701,12 @@ class StreamRequestHandler(BaseRequestHandler): def finish(self): if not self.wfile.closed: - self.wfile.flush() + try: + self.wfile.flush() + except socket.error: + # An final socket error may have occurred here, such as + # the local error ECONNABORTED. + pass self.wfile.close() self.rfile.close() diff --git a/Lib/aifc.py b/Lib/aifc.py index b8adc85..a0cfe5f 100644 --- a/Lib/aifc.py +++ b/Lib/aifc.py @@ -732,22 +732,28 @@ class Aifc_write: self._patchheader() def close(self): - self._ensure_header_written(0) - if self._datawritten & 1: - # quick pad to even size - self._file.write(chr(0)) - self._datawritten = self._datawritten + 1 - self._writemarkers() - if self._nframeswritten != self._nframes or \ - self._datalength != self._datawritten or \ - self._marklength: - self._patchheader() - if self._comp: - self._comp.CloseCompressor() - self._comp = None - # Prevent ref cycles - self._convert = None - self._file.close() + if self._file is None: + return + try: + self._ensure_header_written(0) + if self._datawritten & 1: + # quick pad to even size + self._file.write(chr(0)) + self._datawritten = self._datawritten + 1 + self._writemarkers() + if self._nframeswritten != self._nframes or \ + self._datalength != self._datawritten or \ + self._marklength: + self._patchheader() + if self._comp: + self._comp.CloseCompressor() + self._comp = None + finally: + # Prevent ref cycles + self._convert = None + f = self._file + self._file = None + f.close() # # Internal methods. @@ -37,7 +37,6 @@ __version__ = "2.6" from operator import attrgetter import sys import os -import urllib import UserDict import urlparse diff --git a/Lib/ctypes/test/test_bitfields.py b/Lib/ctypes/test/test_bitfields.py index 090fb4d..3bcc67f 100644 --- a/Lib/ctypes/test/test_bitfields.py +++ b/Lib/ctypes/test/test_bitfields.py @@ -246,9 +246,9 @@ class BitFieldTest(unittest.TestCase): _fields_ = [("a", c_uint32, 32)] x = X() x.a = 10 - self.assertEquals(x.a, 10) + self.assertEqual(x.a, 10) x.a = 0xFDCBA987 - self.assertEquals(x.a, 0xFDCBA987) + self.assertEqual(x.a, 0xFDCBA987) @unittest.skipUnless(hasattr(ctypes, "c_uint64"), "c_int64 is required") def test_uint64(self): @@ -256,9 +256,9 @@ class BitFieldTest(unittest.TestCase): _fields_ = [("a", c_uint64, 64)] x = X() x.a = 10 - self.assertEquals(x.a, 10) + self.assertEqual(x.a, 10) x.a = 0xFEDCBA9876543211 - self.assertEquals(x.a, 0xFEDCBA9876543211) + self.assertEqual(x.a, 0xFEDCBA9876543211) if __name__ == "__main__": unittest.main() diff --git a/Lib/curses/__init__.py b/Lib/curses/__init__.py index bd7d5f6..ecf59de 100644 --- a/Lib/curses/__init__.py +++ b/Lib/curses/__init__.py @@ -5,7 +5,7 @@ the package, and perhaps a particular module inside it. import curses from curses import textpad - curses.initwin() + curses.initscr() ... """ diff --git a/Lib/idlelib/ColorDelegator.py b/Lib/idlelib/ColorDelegator.py index 7f4d740..0610c4b 100644 --- a/Lib/idlelib/ColorDelegator.py +++ b/Lib/idlelib/ColorDelegator.py @@ -20,10 +20,11 @@ def make_pat(): # 1st 'file' colorized normal, 2nd as builtin, 3rd as string builtin = r"([^.'\"\\#]\b|^)" + any("BUILTIN", builtinlist) + r"\b" comment = any("COMMENT", [r"#[^\n]*"]) - sqstring = r"(\b[rRuU])?'[^'\\\n]*(\\.[^'\\\n]*)*'?" - dqstring = r'(\b[rRuU])?"[^"\\\n]*(\\.[^"\\\n]*)*"?' - sq3string = r"(\b[rRuU])?'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?" - dq3string = r'(\b[rRuU])?"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?' + stringprefix = r"(\br|u|ur|R|U|UR|Ur|uR|b|B|br|Br|bR|BR)?" + sqstring = stringprefix + r"'[^'\\\n]*(\\.[^'\\\n]*)*'?" + dqstring = stringprefix + r'"[^"\\\n]*(\\.[^"\\\n]*)*"?' + sq3string = stringprefix + r"'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?" + dq3string = stringprefix + r'"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?' string = any("STRING", [sq3string, dq3string, sqstring, dqstring]) return kw + "|" + builtin + "|" + comment + "|" + string +\ "|" + any("SYNC", [r"\n"]) diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py index 241bd38..0a01c9e 100644 --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -172,13 +172,13 @@ class EditorWindow(object): 'recent-files.lst') self.text_frame = text_frame = Frame(top) self.vbar = vbar = Scrollbar(text_frame, name='vbar') - self.width = idleConf.GetOption('main','EditorWindow','width') + self.width = idleConf.GetOption('main','EditorWindow','width', type='int') text_options = { 'name': 'text', 'padx': 5, 'wrap': 'none', 'width': self.width, - 'height': idleConf.GetOption('main', 'EditorWindow', 'height')} + 'height': idleConf.GetOption('main', 'EditorWindow', 'height', type='int')} if TkVersion >= 8.5: # Starting with tk 8.5 we have to set the new tabstyle option # to 'wordprocessor' to achieve the same display of tabs as in @@ -255,7 +255,8 @@ class EditorWindow(object): if idleConf.GetOption('main', 'EditorWindow', 'font-bold', type='bool'): fontWeight='bold' text.config(font=(idleConf.GetOption('main', 'EditorWindow', 'font'), - idleConf.GetOption('main', 'EditorWindow', 'font-size'), + idleConf.GetOption('main', 'EditorWindow', + 'font-size', type='int'), fontWeight)) text_frame.pack(side=LEFT, fill=BOTH, expand=1) text.pack(side=TOP, fill=BOTH, expand=1) @@ -763,7 +764,8 @@ class EditorWindow(object): if idleConf.GetOption('main','EditorWindow','font-bold',type='bool'): fontWeight='bold' self.text.config(font=(idleConf.GetOption('main','EditorWindow','font'), - idleConf.GetOption('main','EditorWindow','font-size'), + idleConf.GetOption('main','EditorWindow','font-size', + type='int'), fontWeight)) def RemoveKeybindings(self): @@ -1609,7 +1611,7 @@ class IndentSearcher(object): try: try: _tokenize.tokenize(self.readline, self.tokeneater) - except _tokenize.TokenError: + except (_tokenize.TokenError, SyntaxError): # since we cut off the tokenizer early, we can trigger # spurious errors pass diff --git a/Lib/idlelib/FormatParagraph.py b/Lib/idlelib/FormatParagraph.py index 6a5f9b5..557d8a9 100644 --- a/Lib/idlelib/FormatParagraph.py +++ b/Lib/idlelib/FormatParagraph.py @@ -32,7 +32,8 @@ class FormatParagraph: self.editwin = None def format_paragraph_event(self, event): - maxformatwidth = int(idleConf.GetOption('main','FormatParagraph','paragraph')) + maxformatwidth = int(idleConf.GetOption('main','FormatParagraph', + 'paragraph', type='int')) text = self.editwin.text first, last = self.editwin.get_selection_indices() if first and last: diff --git a/Lib/idlelib/configDialog.py b/Lib/idlelib/configDialog.py index 9884d5e..b707fc3 100644 --- a/Lib/idlelib/configDialog.py +++ b/Lib/idlelib/configDialog.py @@ -947,7 +947,7 @@ class ConfigDialog(Toplevel): self.listFontName.select_anchor(currentFontIndex) ##font size dropdown fontSize=idleConf.GetOption('main','EditorWindow','font-size', - default='10') + type='int', default='10') self.optMenuFontSize.SetMenu(('7','8','9','10','11','12','13','14', '16','18','20','22'),fontSize ) ##fontWeight @@ -1033,10 +1033,13 @@ class ConfigDialog(Toplevel): self.autoSave.set(idleConf.GetOption('main', 'General', 'autosave', default=0, type='bool')) #initial window size - self.winWidth.set(idleConf.GetOption('main','EditorWindow','width')) - self.winHeight.set(idleConf.GetOption('main','EditorWindow','height')) + self.winWidth.set(idleConf.GetOption('main','EditorWindow','width', + type='int')) + self.winHeight.set(idleConf.GetOption('main','EditorWindow','height', + type='int')) #initial paragraph reformat size - self.paraWidth.set(idleConf.GetOption('main','FormatParagraph','paragraph')) + self.paraWidth.set(idleConf.GetOption('main','FormatParagraph','paragraph', + type='int')) # default source encoding self.encoding.set(idleConf.GetOption('main', 'EditorWindow', 'encoding', default='none')) diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py index dd13a0e..ce28d08 100644 --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -237,24 +237,39 @@ class IdleConf: printed to stderr. """ - if self.userCfg[configType].has_option(section,option): - return self.userCfg[configType].Get(section, option, - type=type, raw=raw) - elif self.defaultCfg[configType].has_option(section,option): - return self.defaultCfg[configType].Get(section, option, - type=type, raw=raw) - else: #returning default, print warning - if warn_on_default: - warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n' - ' problem retrieving configuration option %r\n' - ' from section %r.\n' - ' returning default value: %r\n' % - (option, section, default)) - try: - sys.stderr.write(warning) - except IOError: - pass - return default + try: + if self.userCfg[configType].has_option(section,option): + return self.userCfg[configType].Get(section, option, + type=type, raw=raw) + except ValueError: + warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n' + ' invalid %r value for configuration option %r\n' + ' from section %r: %r\n' % + (type, option, section, + self.userCfg[configType].Get(section, option, + raw=raw))) + try: + sys.stderr.write(warning) + except IOError: + pass + try: + if self.defaultCfg[configType].has_option(section,option): + return self.defaultCfg[configType].Get(section, option, + type=type, raw=raw) + except ValueError: + pass + #returning default, print warning + if warn_on_default: + warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n' + ' problem retrieving configuration option %r\n' + ' from section %r.\n' + ' returning default value: %r\n' % + (option, section, default)) + try: + sys.stderr.write(warning) + except IOError: + pass + return default def SetOption(self, configType, section, option, value): """In user's config file, set section's option to value. diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py index 4421ac5..6c398fd 100644 --- a/Lib/multiprocessing/connection.py +++ b/Lib/multiprocessing/connection.py @@ -200,6 +200,27 @@ if sys.platform != 'win32': return c1, c2 else: + if hasattr(select, 'poll'): + def _poll(fds, timeout): + if timeout is not None: + timeout = int(timeout) * 1000 # timeout is in milliseconds + fd_map = {} + pollster = select.poll() + for fd in fds: + pollster.register(fd, select.POLLIN) + if hasattr(fd, 'fileno'): + fd_map[fd.fileno()] = fd + else: + fd_map[fd] = fd + ls = [] + for fd, event in pollster.poll(timeout): + if event & select.POLLNVAL: + raise ValueError('invalid file descriptor %i' % fd) + ls.append(fd_map[fd]) + return ls + else: + def _poll(fds, timeout): + return select.select(fds, [], [], timeout)[0] from _multiprocessing import win32 diff --git a/Lib/socket.py b/Lib/socket.py index bd364e7..aac04f6 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -319,8 +319,8 @@ class _fileobject(object): self._wbuf.append(data) self._wbuf_len += len(data) if (self._wbufsize == 0 or - self._wbufsize == 1 and '\n' in data or - self._wbuf_len >= self._wbufsize): + (self._wbufsize == 1 and '\n' in data) or + (self._wbufsize > 1 and self._wbuf_len >= self._wbufsize)): self.flush() def writelines(self, list): @@ -313,17 +313,19 @@ class SSLSocket(socket): self.cert_reqs, self.ssl_version, self.ca_certs, self.ciphers) try: - socket.connect(self, addr) - if self.do_handshake_on_connect: - self.do_handshake() - except socket_error as e: if return_errno: - return e.errno + rc = socket.connect_ex(self, addr) else: - self._sslobj = None - raise e - self._connected = True - return 0 + rc = None + socket.connect(self, addr) + if not rc: + if self.do_handshake_on_connect: + self.do_handshake() + self._connected = True + return rc + except socket_error: + self._sslobj = None + raise def connect(self, addr): """Connects to remote ADDR, and then wraps the connection in diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 104d6ec..19a5188 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -1292,7 +1292,7 @@ class Popen(object): def _internal_poll(self, _deadstate=None, _waitpid=os.waitpid, - _WNOHANG=os.WNOHANG, _os_error=os.error): + _WNOHANG=os.WNOHANG, _os_error=os.error, _ECHILD=errno.ECHILD): """Check if child process has terminated. Returns returncode attribute. @@ -1308,7 +1308,7 @@ class Popen(object): except _os_error as e: if _deadstate is not None: self.returncode = _deadstate - if e.errno == errno.ECHILD: + if e.errno == _ECHILD: # This happens if SIGCLD is set to be ignored or # waiting for child processes has otherwise been # disabled for our process. This child is dead, we diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index f01dcef..dd47cc3 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -32,7 +32,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* @@ -258,7 +258,7 @@ def main(tests=None, testdir=None, verbose=0, quiet=False, try: opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:FwWM:j:', ['help', 'verbose', 'verbose2', 'verbose3', 'quiet', - 'exclude', 'single', 'slow', 'random', 'fromfile', 'findleaks', + 'exclude', 'single', 'slow', 'randomize', 'fromfile=', 'findleaks', 'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir', 'runleaks', 'huntrleaks=', 'memlimit=', 'randseed=', 'multiprocess=', 'slaveargs=', 'forever', 'header']) diff --git a/Lib/test/test_aifc.py b/Lib/test/test_aifc.py index e492838..62b3d18 100644 --- a/Lib/test/test_aifc.py +++ b/Lib/test/test_aifc.py @@ -106,6 +106,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 class AIFCLowLevelTest(unittest.TestCase): diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 1d35a6a..d75c44a 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -680,6 +680,8 @@ class BuiltinTest(unittest.TestCase): # Test input() later, together with raw_input + # test_int(): see test_int.py for int() tests. + def test_intern(self): self.assertRaises(TypeError, intern) # This fails if the test is run twice with a constant string, diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 5d6549c..0f91d29 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -261,7 +261,7 @@ class CalendarTestCase(unittest.TestCase): return calendar.LocaleHTMLCalendar(locale='').formatmonthname(2010, 10) new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) - self.assertEquals(old_october, new_october) + self.assertEqual(old_october, new_october) def test_itermonthdates(self): # ensure itermonthdates doesn't overflow after datetime.MAXYEAR diff --git a/Lib/test/test_glob.py b/Lib/test/test_glob.py index fee3a60..b360d09 100644 --- a/Lib/test/test_glob.py +++ b/Lib/test/test_glob.py @@ -1,9 +1,14 @@ -import unittest -from test.test_support import run_unittest, TESTFN import glob import os import shutil import sys +import unittest + +from test.test_support import run_unittest, TESTFN + + +def fsdecode(s): + return unicode(s, sys.getfilesystemencoding()) class GlobTests(unittest.TestCase): @@ -31,7 +36,8 @@ class GlobTests(unittest.TestCase): self.mktemp('a', 'bcd', 'efg', 'ha') if hasattr(os, '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 +50,16 @@ class GlobTests(unittest.TestCase): p = os.path.join(self.tempdir, pattern) res = glob.glob(p) self.assertEqual(list(glob.iglob(p)), res) + ures = [fsdecode(x) for x in res] + self.assertEqual(glob.glob(fsdecode(p)), ures) + self.assertEqual(list(glob.iglob(fsdecode(p))), ures) 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 +68,19 @@ class GlobTests(unittest.TestCase): eq(self.glob('aab'), [self.norm('aab')]) eq(self.glob('zymurgy'), []) + 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}) + # test return types are unicode, but only if os.listdir # returns unicode filenames - uniset = set([unicode]) - tmp = os.listdir(u'.') - if set(type(x) for x in tmp) == uniset: - u1 = glob.glob(u'*') - u2 = glob.glob(u'./*') - self.assertEqual(set(type(r) for r in u1), uniset) - self.assertEqual(set(type(r) for r in u2), uniset) + tmp = os.listdir(fsdecode(os.curdir)) + if {type(x) for x in tmp} == {unicode}: + res = glob.glob(u'*') + self.assertEqual({type(r) for r in res}, {unicode}) + res = glob.glob(os.path.join(fsdecode(os.curdir), u'*')) + self.assertEqual({type(r) for r in res}, {unicode}) def test_glob_one_directory(self): eq = self.assertSequencesEqual_noorder @@ -93,23 +109,60 @@ 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): - # We are verifying that when there is wildcard pattern which - # ends with os.sep doesn't blow up. - res = glob.glob(self.tempdir + '*' + os.sep) - self.assertEqual(len(res), 1) - # either of these results are reasonable - self.assertIn(res[0], [self.tempdir, self.tempdir + os.sep]) - + # Patterns ending with a slash shouldn't match non-dirs + res = glob.glob(self.norm('Z*Z') + os.sep) + self.assertEqual(res, []) + res = glob.glob(self.norm('ZZZ') + os.sep) + self.assertEqual(res, []) + # When there is a wildcard pattern which ends with os.sep, glob() + # doesn't blow up. + res = glob.glob(self.norm('aa*') + os.sep) + self.assertEqual(len(res), 2) + # 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}, + ]) + + def test_glob_unicode_directory_with_trailing_slash(self): + # Same as test_glob_directory_with_trailing_slash, but with an + # unicode argument. + res = glob.glob(fsdecode(self.norm('Z*Z') + os.sep)) + self.assertEqual(res, []) + res = glob.glob(fsdecode(self.norm('ZZZ') + os.sep)) + self.assertEqual(res, []) + res = glob.glob(fsdecode(self.norm('aa*') + os.sep)) + self.assertEqual(len(res), 2) + # either of these results is reasonable + self.assertIn(set(res), [ + {fsdecode(self.norm('aaa')), fsdecode(self.norm('aab'))}, + {fsdecode(self.norm('aaa') + os.sep), + fsdecode(self.norm('aab') + os.sep)}, + ]) + + @unittest.skipUnless(hasattr(os, 'symlink'), "Requires symlink support") + 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')]) + + @unittest.skipUnless(hasattr(os, 'symlink'), "Requires symlink support") def test_glob_broken_symlinks(self): - if hasattr(os, 'symlink'): - eq = self.assertSequencesEqual_noorder - eq(self.glob('sym*'), [self.norm('sym1'), self.norm('sym2')]) - eq(self.glob('sym1'), [self.norm('sym1')]) - eq(self.glob('sym2'), [self.norm('sym2')]) + eq = self.assertSequencesEqual_noorder + 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')]) @unittest.skipUnless(sys.platform == "win32", "Win32 specific test") def test_glob_magic_in_drive(self): diff --git a/Lib/test/test_import.py b/Lib/test/test_import.py index edd1869..ea50d34 100644 --- a/Lib/test/test_import.py +++ b/Lib/test/test_import.py @@ -5,6 +5,7 @@ import os import py_compile import random import stat +import struct import sys import unittest import textwrap @@ -350,6 +351,46 @@ class ImportTests(unittest.TestCase): del sys.path[0] remove_files(TESTFN) + def test_pyc_mtime(self): + # Test for issue #13863: .pyc timestamp sometimes incorrect on Windows. + sys.path.insert(0, os.curdir) + try: + # Jan 1, 2012; Jul 1, 2012. + mtimes = 1325376000, 1341100800 + + # Different names to avoid running into import caching. + tails = "spam", "eggs" + for mtime, tail in zip(mtimes, tails): + module = TESTFN + tail + source = module + ".py" + compiled = source + ('c' if __debug__ else 'o') + + # Create a new Python file with the given mtime. + with open(source, 'w') as f: + f.write("# Just testing\nx=1, 2, 3\n") + os.utime(source, (mtime, mtime)) + + # Generate the .pyc/o file; if it couldn't be created + # for some reason, skip the test. + m = __import__(module) + if not os.path.exists(compiled): + unlink(source) + self.skipTest("Couldn't create .pyc/.pyo file.") + + # Actual modification time of .py file. + mtime1 = int(os.stat(source).st_mtime) & 0xffffffff + + # mtime that was encoded in the .pyc file. + with open(compiled, 'rb') as f: + mtime2 = struct.unpack('<L', f.read(8)[4:])[0] + + unlink(compiled) + unlink(source) + + self.assertEqual(mtime1, mtime2) + finally: + sys.path.pop(0) + class PycRewritingTests(unittest.TestCase): # Test that the `co_filename` attribute on code objects always points diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py index fa46212..365f9a2 100644 --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -1,6 +1,7 @@ import sys import unittest +from test import test_support from test.test_support import run_unittest, have_unicode import math @@ -44,7 +45,27 @@ if have_unicode: (unichr(0x200), ValueError), ] -class IntTestCases(unittest.TestCase): +class IntLongCommonTests(object): + + """Mixin of test cases to share between both test_int and test_long.""" + + # Change to int or long in the TestCase subclass. + ntype = None + + def test_no_args(self): + self.assertEqual(self.ntype(), 0) + + def test_keyword_args(self): + # Test invoking constructor using keyword arguments. + self.assertEqual(self.ntype(x=1.2), 1) + self.assertEqual(self.ntype('100', base=2), 4) + self.assertEqual(self.ntype(x='100', base=2), 4) + self.assertRaises(TypeError, self.ntype, base=10) + self.assertRaises(TypeError, self.ntype, base=0) + +class IntTestCases(IntLongCommonTests, unittest.TestCase): + + ntype = int def test_basic(self): self.assertEqual(int(314), 314) @@ -315,6 +336,46 @@ class IntTestCases(unittest.TestCase): self.assertEqual(int(float(2**54+10)), 2**54+8) self.assertEqual(int(float(2**54+11)), 2**54+12) + def test_valid_non_numeric_input_types_for_x(self): + # Test possible valid non-numeric types for x, including subclasses + # of the allowed built-in types. + class CustomStr(str): pass + values = ['100', CustomStr('100')] + + if have_unicode: + class CustomUnicode(unicode): pass + values += [unicode('100'), CustomUnicode(unicode('100'))] + + for x in values: + msg = 'x has value %s and type %s' % (x, type(x).__name__) + try: + self.assertEqual(int(x), 100, msg=msg) + self.assertEqual(int(x, 2), 4, msg=msg) + except TypeError, err: + raise AssertionError('For %s got TypeError: %s' % + (type(x).__name__, err)) + + def test_error_on_string_float_for_x(self): + self.assertRaises(ValueError, int, '1.2') + + def test_error_on_bytearray_for_x(self): + self.assertRaises(TypeError, int, bytearray('100'), 2) + + def test_error_on_invalid_int_bases(self): + for base in [-1, 1, 1000]: + self.assertRaises(ValueError, int, '100', base) + + def test_error_on_string_base(self): + self.assertRaises(TypeError, int, 100, base='foo') + + @test_support.cpython_only + def test_small_ints(self): + self.assertIs(int('10'), 10) + self.assertIs(int('-1'), -1) + if have_unicode: + self.assertIs(int(u'10'), 10) + self.assertIs(int(u'-1'), -1) + def test_intconversion(self): # Test __int__() class ClassicMissingMethods: diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py index 58cfc3a..f0847e7 100644 --- a/Lib/test/test_long.py +++ b/Lib/test/test_long.py @@ -1,10 +1,11 @@ import unittest -from test import test_support import sys import random import math +from test import test_int, test_support + # Used for lazy formatting of failure messages class Frm(object): def __init__(self, format, *args): @@ -78,8 +79,9 @@ if test_support.have_unicode: (unichr(0x200), ValueError), ] +class LongTest(test_int.IntLongCommonTests, unittest.TestCase): -class LongTest(unittest.TestCase): + ntype = long # Get quasi-random long consisting of ndigits digits (in base BASE). # quasi == the most-significant digit will not be 0, and the number diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py index 1587057..f140aca 100644 --- a/Lib/test/test_multiprocessing.py +++ b/Lib/test/test_multiprocessing.py @@ -1513,6 +1513,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_mutex.py b/Lib/test/test_mutex.py index 2882213..030080e 100644 --- a/Lib/test/test_mutex.py +++ b/Lib/test/test_mutex.py @@ -14,7 +14,7 @@ class MutexTest(unittest.TestCase): m.lock(called_by_mutex2, "eggs") def called_by_mutex2(some_data): - self.assertEquals(some_data, "eggs") + self.assertEqual(some_data, "eggs") self.assertTrue(m.test(), "mutex not held") self.assertTrue(ready_for_2, "called_by_mutex2 called too soon") diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 053c6fe..fec62ef 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -962,8 +962,8 @@ class FileObjectClassTestCase(SocketConnectedTest): def tearDown(self): self.serv_file.close() self.assertTrue(self.serv_file.closed) - self.serv_file = None SocketConnectedTest.tearDown(self) + self.serv_file = None def clientSetUp(self): SocketConnectedTest.clientSetUp(self) @@ -1151,6 +1151,64 @@ class LineBufferedFileObjectClassTestCase(FileObjectClassTestCase): bufsize = 1 # Default-buffered for reading; line-buffered for writing + class SocketMemo(object): + """A wrapper to keep track of sent data, needed to examine write behaviour""" + def __init__(self, sock): + self._sock = sock + self.sent = [] + + def send(self, data, flags=0): + n = self._sock.send(data, flags) + self.sent.append(data[:n]) + return n + + def sendall(self, data, flags=0): + self._sock.sendall(data, flags) + self.sent.append(data) + + def __getattr__(self, attr): + return getattr(self._sock, attr) + + def getsent(self): + return [e.tobytes() if isinstance(e, memoryview) else e for e in self.sent] + + def setUp(self): + FileObjectClassTestCase.setUp(self) + self.serv_file._sock = self.SocketMemo(self.serv_file._sock) + + def testLinebufferedWrite(self): + # Write two lines, in small chunks + msg = MSG.strip() + print >> self.serv_file, msg, + print >> self.serv_file, msg + + # second line: + print >> self.serv_file, msg, + print >> self.serv_file, msg, + print >> self.serv_file, msg + + # third line + print >> self.serv_file, '' + + self.serv_file.flush() + + msg1 = "%s %s\n"%(msg, msg) + msg2 = "%s %s %s\n"%(msg, msg, msg) + msg3 = "\n" + self.assertEqual(self.serv_file._sock.getsent(), [msg1, msg2, msg3]) + + def _testLinebufferedWrite(self): + msg = MSG.strip() + msg1 = "%s %s\n"%(msg, msg) + msg2 = "%s %s %s\n"%(msg, msg, msg) + msg3 = "\n" + l1 = self.cli_file.readline() + self.assertEqual(l1, msg1) + l2 = self.cli_file.readline() + self.assertEqual(l2, msg2) + l3 = self.cli_file.readline() + self.assertEqual(l3, msg3) + class SmallBufferedFileObjectClassTestCase(FileObjectClassTestCase): diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 58da942..9f51387 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -280,6 +280,34 @@ class NetworkedTests(unittest.TestCase): finally: s.close() + def test_timeout_connect_ex(self): + # Issue #12065: on a timeout, connect_ex() should return the original + # errno (mimicking the behaviour of non-SSL sockets). + with test_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, + do_handshake_on_connect=False) + try: + s.settimeout(0.0000001) + rc = s.connect_ex(('svn.python.org', 443)) + if rc == 0: + self.skipTest("svn.python.org responded too quickly") + self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK)) + finally: + s.close() + + def test_connect_ex_error(self): + with test_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() + @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows") def test_makefile_close(self): # Issue #5238: creating a file-like object with makefile() shouldn't diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index a3685ea..af59e27 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -297,26 +297,21 @@ class MiscReadTest(CommonReadTest): def test_extract_hardlink(self): # Test hardlink extraction (e.g. bug #857297). - tar = tarfile.open(tarname, errorlevel=1, encoding="iso8859-1") + with tarfile.open(tarname, errorlevel=1, encoding="iso8859-1") as tar: + tar.extract("ustar/regtype", TEMPDIR) + self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/regtype")) - tar.extract("ustar/regtype", TEMPDIR) - try: tar.extract("ustar/lnktype", TEMPDIR) - except EnvironmentError, e: - if e.errno == errno.ENOENT: - self.fail("hardlink not extracted properly") - - data = open(os.path.join(TEMPDIR, "ustar/lnktype"), "rb").read() - self.assertEqual(md5sum(data), md5_regtype) + 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, e: - if e.errno == errno.ENOENT: - self.fail("symlink not extracted properly") - - data = open(os.path.join(TEMPDIR, "ustar/symtype"), "rb").read() - self.assertEqual(md5sum(data), md5_regtype) + 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) def test_extractall(self): # Test if extractall() correctly restores directory permissions @@ -858,7 +853,7 @@ class WriteTest(WriteTestBase): tar = tarfile.open(tmpname, "r") for t in tar: - self.assert_(t.name == "." or t.name.startswith("./")) + self.assertTrue(t.name == "." or t.name.startswith("./")) tar.close() finally: os.chdir(cwd) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index 12263b3..eac9950 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -1336,16 +1336,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 = urllib2.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 = urllib2.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 = urllib2.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() 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 0fda770..ec34375 100644 --- a/Lib/test/test_urllib2_localnet.py +++ b/Lib/test/test_urllib2_localnet.py @@ -5,7 +5,9 @@ import urllib2 import BaseHTTPServer import unittest import hashlib + from test import test_support + mimetools = test_support.import_module('mimetools', deprecated=True) threading = test_support.import_module('threading') @@ -346,6 +348,12 @@ class TestUrlopen(BaseTestCase): for transparent redirection have been written. """ + def setUp(self): + proxy_handler = urllib2.ProxyHandler({}) + opener = urllib2.build_opener(proxy_handler) + urllib2.install_opener(opener) + super(TestUrlopen, self).setUp() + def start_server(self, responses): handler = GetRequestHandler(responses) diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index 3f316d3..72ebfaa 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -446,10 +446,43 @@ class UrlParseTestCase(unittest.TestCase): p1 = urlparse.urlsplit('tel:+31-641044153') self.assertEqual(p1.scheme, 'tel') self.assertEqual(p1.path, '+31-641044153') + p2 = urlparse.urlsplit('tel:+31641044153') self.assertEqual(p2.scheme, 'tel') self.assertEqual(p2.path, '+31641044153') + # Assert for urlparse + p1 = urlparse.urlparse('tel:+31-641044153') + self.assertEqual(p1.scheme, 'tel') + self.assertEqual(p1.path, '+31-641044153') + + p2 = urlparse.urlparse('tel:+31641044153') + self.assertEqual(p2.scheme, 'tel') + self.assertEqual(p2.path, '+31641044153') + + + def test_telurl_params(self): + p1 = urlparse.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 = urlparse.urlparse('tel:+1-201-555-0123') + self.assertEqual(p1.scheme, 'tel') + self.assertEqual(p1.path, '+1-201-555-0123') + self.assertEqual(p1.params, '') + + p1 = urlparse.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 = urlparse.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_attributes_bad_port(self): """Check handling of non-integer ports.""" p = urlparse.urlsplit("http://www.example.net:foo") diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index a741b65..2799e19 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -314,6 +314,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): diff --git a/Lib/urllib2.py b/Lib/urllib2.py index ebf5811..aadeb73 100644 --- a/Lib/urllib2.py +++ b/Lib/urllib2.py @@ -173,6 +173,9 @@ class HTTPError(URLError, addinfourl): def reason(self): return self.msg + def info(self): + return self.hdrs + # copied from cookielib.py _cut_port_re = re.compile(r":\d+$") def request_host(request): diff --git a/Lib/urlparse.py b/Lib/urlparse.py index abc53c6..f370ce3 100644 --- a/Lib/urlparse.py +++ b/Lib/urlparse.py @@ -42,7 +42,7 @@ uses_netloc = ['ftp', 'http', 'gopher', 'nntp', 'telnet', 'svn', 'svn+ssh', 'sftp','nfs','git', 'git+ssh'] uses_params = ['ftp', 'hdl', 'prospero', 'http', 'imap', 'https', 'shttp', 'rtsp', 'rtspu', 'sip', 'sips', - 'mms', '', 'sftp'] + 'mms', '', 'sftp', 'tel'] # These are not actually used anymore, but should stay for backwards # compatibility. (They are undocumented, but have a public-looking name.) |
