diff options
author | Senthil Kumaran <senthil@uthcode.com> | 2012-03-13 07:14:25 (GMT) |
---|---|---|
committer | Senthil Kumaran <senthil@uthcode.com> | 2012-03-13 07:14:25 (GMT) |
commit | 7554f0dd3ca6219db07adcc222cef776d37512a6 (patch) | |
tree | 9139b775096275084284e8b2cf459c81818ffc58 | |
parent | 9186850088a94627b60fa80102edc858c332b51c (diff) | |
parent | a9719057a2ee1875c6334b1d5fbbf66cfc02ca78 (diff) | |
download | cpython-7554f0dd3ca6219db07adcc222cef776d37512a6.zip cpython-7554f0dd3ca6219db07adcc222cef776d37512a6.tar.gz cpython-7554f0dd3ca6219db07adcc222cef776d37512a6.tar.bz2 |
merge heads
-rw-r--r-- | Lib/aifc.py | 12 | ||||
-rw-r--r-- | Lib/pickle.py | 8 | ||||
-rw-r--r-- | Lib/test/pickletester.py | 12 | ||||
-rw-r--r-- | Lib/test/test_aifc.py | 158 | ||||
-rw-r--r-- | Lib/test/test_ast.py | 9 | ||||
-rw-r--r-- | Lib/test/test_re.py | 30 | ||||
-rw-r--r-- | Lib/test/test_sys.py | 2 | ||||
-rw-r--r-- | Lib/test/test_unicode.py | 15 | ||||
-rw-r--r-- | Lib/test/test_zipimport.py | 4 | ||||
-rw-r--r-- | Lib/tkinter/__init__.py | 36 | ||||
-rw-r--r-- | Lib/tkinter/test/test_tkinter/test_variables.py | 165 | ||||
-rw-r--r-- | Lib/unittest/main.py | 76 | ||||
-rw-r--r-- | Lib/unittest/test/test_program.py | 17 | ||||
-rw-r--r-- | Misc/ACKS | 3 | ||||
-rw-r--r-- | Misc/NEWS | 14 | ||||
-rw-r--r-- | Modules/_pickle.c | 26 | ||||
-rw-r--r-- | Modules/_sre.c | 16 | ||||
-rw-r--r-- | Modules/timemodule.c | 18 | ||||
-rwxr-xr-x | Parser/asdl_c.py | 18 | ||||
-rw-r--r-- | Python/Python-ast.c | 18 | ||||
-rw-r--r-- | Python/ast.c | 10 |
21 files changed, 546 insertions, 121 deletions
diff --git a/Lib/aifc.py b/Lib/aifc.py index 775f39c..ec4f822 100644 --- a/Lib/aifc.py +++ b/Lib/aifc.py @@ -136,6 +136,7 @@ writeframesraw. import struct import builtins +import warnings __all__ = ["Error", "open", "openfp"] @@ -440,7 +441,7 @@ class Aifc_read: kludge = 0 if chunk.chunksize == 18: kludge = 1 - print('Warning: bad COMM chunk size') + warnings.warn('Warning: bad COMM chunk size') chunk.chunksize = 23 #DEBUG end self._comptype = chunk.read(4) @@ -484,11 +485,10 @@ class Aifc_read: # a position 0 and name '' self._markers.append((id, pos, name)) except EOFError: - print('Warning: MARK chunk contains only', end=' ') - print(len(self._markers), end=' ') - if len(self._markers) == 1: print('marker', end=' ') - else: print('markers', end=' ') - print('instead of', nmarkers) + w = ('Warning: MARK chunk contains only %s marker%s instead of %s' % + (len(self._markers), '' if len(self._markers) == 1 else 's', + nmarkers)) + warnings.warn(w) class Aifc_write: # Variables used in this class: diff --git a/Lib/pickle.py b/Lib/pickle.py index 20b3646..9e65368 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -438,6 +438,14 @@ class _Pickler: self.write(NONE) dispatch[type(None)] = save_none + def save_ellipsis(self, obj): + self.save_global(Ellipsis, 'Ellipsis') + dispatch[type(Ellipsis)] = save_ellipsis + + def save_notimplemented(self, obj): + self.save_global(NotImplemented, 'NotImplemented') + dispatch[type(NotImplemented)] = save_notimplemented + def save_bool(self, obj): if self.proto >= 2: self.write(obj and NEWTRUE or NEWFALSE) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 1a551c8..3686a62 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -743,6 +743,18 @@ class AbstractPickleTests(unittest.TestCase): u = self.loads(s) self.assertEqual(t, u) + def test_ellipsis(self): + for proto in protocols: + s = self.dumps(..., proto) + u = self.loads(s) + self.assertEqual(..., u) + + def test_notimplemented(self): + for proto in protocols: + s = self.dumps(NotImplemented, proto) + u = self.loads(s) + self.assertEqual(NotImplemented, u) + # Tests for protocol 2 def test_proto(self): diff --git a/Lib/test/test_aifc.py b/Lib/test/test_aifc.py index 236f9b6..ad6f610 100644 --- a/Lib/test/test_aifc.py +++ b/Lib/test/test_aifc.py @@ -1,7 +1,8 @@ -from test.support import findfile, run_unittest, TESTFN +from test.support import findfile, run_unittest, TESTFN, unlink import unittest import os import io +import struct import aifc @@ -20,10 +21,8 @@ class AIFCTest(unittest.TestCase): self.fout.close() except (aifc.Error, AttributeError): pass - try: - os.remove(TESTFN) - except OSError: - pass + unlink(TESTFN) + unlink(TESTFN + '.aiff') def test_skipunknown(self): #Issue 2245 @@ -32,6 +31,7 @@ class AIFCTest(unittest.TestCase): def test_params(self): f = self.f = aifc.open(self.sndfilepath) + self.assertEqual(f.getfp().name, self.sndfilepath) self.assertEqual(f.getnchannels(), 2) self.assertEqual(f.getsampwidth(), 2) self.assertEqual(f.getframerate(), 48000) @@ -45,6 +45,7 @@ class AIFCTest(unittest.TestCase): def test_read(self): f = self.f = aifc.open(self.sndfilepath) + self.assertEqual(f.readframes(0), b'') self.assertEqual(f.tell(), 0) self.assertEqual(f.readframes(2), b'\x00\x00\x00\x00\x0b\xd4\x0b\xd4') f.rewind() @@ -58,6 +59,10 @@ class AIFCTest(unittest.TestCase): self.assertEqual(f.readframes(2), b'\x17t\x17t"\xad"\xad') f.setpos(pos0) self.assertEqual(f.readframes(2), b'\x00\x00\x00\x00\x0b\xd4\x0b\xd4') + with self.assertRaises(aifc.Error): + f.setpos(-1) + with self.assertRaises(aifc.Error): + f.setpos(f.getnframes() + 1) def test_write(self): f = self.f = aifc.open(self.sndfilepath) @@ -92,8 +97,6 @@ class AIFCTest(unittest.TestCase): self.assertEqual(f.getparams()[0:3], fout.getparams()[0:3]) self.assertEqual(fout.getcomptype(), b'ULAW') self.assertEqual(fout.getcompname(), b'foo') - # XXX: this test fails, not sure if it should succeed or not - # self.assertEqual(f.readframes(5), fout.readframes(5)) def test_close(self): class Wrapfile(object): @@ -112,7 +115,7 @@ class AIFCTest(unittest.TestCase): def test_write_header_comptype_sampwidth(self): for comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'): - fout = self.fout = aifc.open(io.BytesIO(), 'wb') + fout = aifc.open(io.BytesIO(), 'wb') fout.setnchannels(1) fout.setframerate(1) fout.setcomptype(comptype, b'') @@ -121,7 +124,7 @@ class AIFCTest(unittest.TestCase): fout.initfp(None) def test_write_markers_values(self): - fout = self.fout = aifc.open(io.BytesIO(), 'wb') + fout = aifc.open(io.BytesIO(), 'wb') self.assertEqual(fout.getmarkers(), None) fout.setmark(1, 0, b'foo1') fout.setmark(1, 1, b'foo2') @@ -179,6 +182,143 @@ class AIFCLowLevelTest(unittest.TestCase): with self.assertRaises(ValueError): aifc._write_string(f, b'too long' * 255) + def test_wrong_open_mode(self): + with self.assertRaises(aifc.Error): + aifc.open(TESTFN, 'wrong_mode') + + def test_read_wrong_form(self): + b1 = io.BytesIO(b'WRNG' + struct.pack('>L', 0)) + b2 = io.BytesIO(b'FORM' + struct.pack('>L', 4) + b'WRNG') + self.assertRaises(aifc.Error, aifc.open, b1) + self.assertRaises(aifc.Error, aifc.open, b2) + + def test_read_no_comm_chunk(self): + b = io.BytesIO(b'FORM' + struct.pack('>L', 4) + b'AIFF') + self.assertRaises(aifc.Error, aifc.open, b) + + def test_read_wrong_compression_type(self): + b = b'FORM' + struct.pack('>L', 4) + b'AIFC' + b += b'COMM' + struct.pack('>LhlhhLL', 23, 0, 0, 0, 0, 0, 0) + b += b'WRNG' + struct.pack('B', 0) + self.assertRaises(aifc.Error, aifc.open, io.BytesIO(b)) + + def test_read_wrong_marks(self): + b = b'FORM' + struct.pack('>L', 4) + b'AIFF' + b += b'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0) + b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8 + b += b'MARK' + struct.pack('>LhB', 3, 1, 1) + with self.assertWarns(UserWarning): + f = aifc.open(io.BytesIO(b)) + self.assertEqual(f.getmarkers(), None) + + def test_read_comm_kludge_compname_even(self): + b = b'FORM' + struct.pack('>L', 4) + b'AIFC' + b += b'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0) + b += b'NONE' + struct.pack('B', 4) + b'even' + b'\x00' + b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8 + with self.assertWarns(UserWarning): + f = aifc.open(io.BytesIO(b)) + self.assertEqual(f.getcompname(), b'even') + + def test_read_comm_kludge_compname_odd(self): + b = b'FORM' + struct.pack('>L', 4) + b'AIFC' + b += b'COMM' + struct.pack('>LhlhhLL', 18, 0, 0, 0, 0, 0, 0) + b += b'NONE' + struct.pack('B', 3) + b'odd' + b += b'SSND' + struct.pack('>L', 8) + b'\x00' * 8 + with self.assertWarns(UserWarning): + f = aifc.open(io.BytesIO(b)) + self.assertEqual(f.getcompname(), b'odd') + + def test_write_params_raises(self): + fout = aifc.open(io.BytesIO(), 'wb') + wrong_params = (0, 0, 0, 0, b'WRNG', '') + self.assertRaises(aifc.Error, fout.setparams, wrong_params) + self.assertRaises(aifc.Error, fout.getparams) + self.assertRaises(aifc.Error, fout.setnchannels, 0) + self.assertRaises(aifc.Error, fout.getnchannels) + self.assertRaises(aifc.Error, fout.setsampwidth, 0) + self.assertRaises(aifc.Error, fout.getsampwidth) + self.assertRaises(aifc.Error, fout.setframerate, 0) + self.assertRaises(aifc.Error, fout.getframerate) + self.assertRaises(aifc.Error, fout.setcomptype, b'WRNG', '') + fout.aiff() + fout.setnchannels(1) + fout.setsampwidth(1) + fout.setframerate(1) + fout.setnframes(1) + fout.writeframes(b'\x00') + self.assertRaises(aifc.Error, fout.setparams, (1, 1, 1, 1, 1, 1)) + self.assertRaises(aifc.Error, fout.setnchannels, 1) + self.assertRaises(aifc.Error, fout.setsampwidth, 1) + self.assertRaises(aifc.Error, fout.setframerate, 1) + self.assertRaises(aifc.Error, fout.setnframes, 1) + self.assertRaises(aifc.Error, fout.setcomptype, b'NONE', '') + self.assertRaises(aifc.Error, fout.aiff) + self.assertRaises(aifc.Error, fout.aifc) + + def test_write_params_singles(self): + fout = aifc.open(io.BytesIO(), 'wb') + fout.aifc() + fout.setnchannels(1) + fout.setsampwidth(2) + fout.setframerate(3) + fout.setnframes(4) + fout.setcomptype(b'NONE', b'name') + self.assertEqual(fout.getnchannels(), 1) + self.assertEqual(fout.getsampwidth(), 2) + self.assertEqual(fout.getframerate(), 3) + self.assertEqual(fout.getnframes(), 0) + self.assertEqual(fout.tell(), 0) + self.assertEqual(fout.getcomptype(), b'NONE') + self.assertEqual(fout.getcompname(), b'name') + fout.writeframes(b'\x00' * 4 * fout.getsampwidth() * fout.getnchannels()) + self.assertEqual(fout.getnframes(), 4) + self.assertEqual(fout.tell(), 4) + + def test_write_params_bunch(self): + fout = aifc.open(io.BytesIO(), 'wb') + fout.aifc() + p = (1, 2, 3, 4, b'NONE', b'name') + fout.setparams(p) + self.assertEqual(fout.getparams(), p) + fout.initfp(None) + + def test_write_header_raises(self): + fout = aifc.open(io.BytesIO(), 'wb') + self.assertRaises(aifc.Error, fout.close) + fout.setnchannels(1) + self.assertRaises(aifc.Error, fout.close) + 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'): + fout = aifc.open(io.BytesIO(), 'wb') + fout.setsampwidth(1) + fout.setcomptype(comptype, b'') + self.assertRaises(aifc.Error, fout.close) + fout.initfp(None) + + def test_write_markers_raises(self): + fout = aifc.open(io.BytesIO(), 'wb') + self.assertRaises(aifc.Error, fout.setmark, 0, 0, b'') + self.assertRaises(aifc.Error, fout.setmark, 1, -1, b'') + self.assertRaises(aifc.Error, fout.setmark, 1, 0, None) + self.assertRaises(aifc.Error, fout.getmark, 1) + fout.initfp(None) + + def test_write_aiff_by_extension(self): + sampwidth = 2 + fout = self.fout = aifc.open(TESTFN + '.aiff', 'wb') + fout.setparams((1, sampwidth, 1, 1, b'ULAW', b'')) + frames = b'\x00' * fout.getnchannels() * sampwidth + fout.writeframes(frames) + fout.close() + f = self.f = aifc.open(TESTFN + '.aiff', 'rb') + self.assertEqual(f.getcomptype(), b'NONE') + f.close() + def test_main(): run_unittest(AIFCTest) diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index b809d24..064c669 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -196,16 +196,13 @@ class AST_Tests(unittest.TestCase): def test_AST_objects(self): x = ast.AST() self.assertEqual(x._fields, ()) + x.foobar = 42 + self.assertEqual(x.foobar, 42) + self.assertEqual(x.__dict__["foobar"], 42) with self.assertRaises(AttributeError): x.vararg - with self.assertRaises(AttributeError): - x.foobar = 21 - - with self.assertRaises(AttributeError): - ast.AST(lineno=2) - with self.assertRaises(TypeError): # "_ast.AST constructor takes 0 positional arguments" ast.AST(2) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 34c4a5f..74a7b71 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -652,6 +652,26 @@ class ReTests(unittest.TestCase): self.assertEqual([item.group(0) for item in iter], [":", "::", ":::"]) + pat = re.compile(r":+") + iter = pat.finditer("a:b::c:::d", 1, 10) + self.assertEqual([item.group(0) for item in iter], + [":", "::", ":::"]) + + pat = re.compile(r":+") + iter = pat.finditer("a:b::c:::d", pos=1, endpos=10) + self.assertEqual([item.group(0) for item in iter], + [":", "::", ":::"]) + + pat = re.compile(r":+") + iter = pat.finditer("a:b::c:::d", endpos=10, pos=1) + self.assertEqual([item.group(0) for item in iter], + [":", "::", ":::"]) + + pat = re.compile(r":+") + iter = pat.finditer("a:b::c:::d", pos=3, endpos=8) + self.assertEqual([item.group(0) for item in iter], + ["::", "::"]) + def test_bug_926075(self): self.assertTrue(re.compile('bug_926075') is not re.compile(b'bug_926075')) @@ -825,6 +845,16 @@ class ReTests(unittest.TestCase): self.assertIsNotNone(re.search("123.*-", '123\U0010ffff-')) self.assertIsNotNone(re.search("123.*-", '123\xe9\u20ac\U0010ffff-')) + def test_compile(self): + # Test return value when given string and pattern as parameter + pattern = re.compile('random pattern') + self.assertIsInstance(pattern, re._pattern_type) + same_pattern = re.compile(pattern) + self.assertIsInstance(same_pattern, re._pattern_type) + self.assertIs(same_pattern, pattern) + # Test behaviour when not given a string or pattern as parameter + self.assertRaises(TypeError, re.compile, 0) + def run_re_tests(): from test.re_tests import tests, SUCCEED, FAIL, SYNTAX_ERROR if verbose: diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 551c3a5..9f6af7f 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -882,7 +882,7 @@ class SizeofTest(unittest.TestCase): check = self.check_sizeof # _ast.AST import _ast - check(_ast.AST(), size(h + '')) + check(_ast.AST(), size(h + 'P')) # imp.NullImporter import imp check(imp.NullImporter(self.file.name), size(h + '')) diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index 33d7b35..813d59f 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -957,12 +957,15 @@ class UnicodeTest(string_tests.CommonTest, self.assertEqual('{foo._x}'.format_map({'foo': C(20)}), '20') # test various errors - self.assertRaises(TypeError, '{'.format_map) - self.assertRaises(TypeError, '}'.format_map) - self.assertRaises(TypeError, 'a{'.format_map) - self.assertRaises(TypeError, 'a}'.format_map) - self.assertRaises(TypeError, '{a'.format_map) - self.assertRaises(TypeError, '}a'.format_map) + self.assertRaises(TypeError, ''.format_map) + self.assertRaises(TypeError, 'a'.format_map) + + self.assertRaises(ValueError, '{'.format_map, {}) + self.assertRaises(ValueError, '}'.format_map, {}) + self.assertRaises(ValueError, 'a{'.format_map, {}) + self.assertRaises(ValueError, 'a}'.format_map, {}) + self.assertRaises(ValueError, '{a'.format_map, {}) + self.assertRaises(ValueError, '}a'.format_map, {}) # issue #12579: can't supply positional params to format_map self.assertRaises(ValueError, '{}'.format_map, {'a' : 2}) diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index 358910b..f7cb8b9 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -205,6 +205,10 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase): mod = zi.load_module(TESTPACK) self.assertEqual(zi.get_filename(TESTPACK), mod.__file__) + existing_pack_path = __import__(TESTPACK).__path__[0] + expected_path_path = os.path.join(TEMP_ZIP, TESTPACK) + self.assertEqual(existing_pack_path, expected_path_path) + self.assertEqual(zi.is_package(packdir + '__init__'), False) self.assertEqual(zi.is_package(packdir + TESTPACK2), True) self.assertEqual(zi.is_package(packdir2 + TESTMOD), False) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index f4f9583..35f724f 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -155,6 +155,7 @@ class Variable: Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations that constrain the type of the value returned from get().""" _default = "" + _tk = None def __init__(self, master=None, value=None, name=None): """Construct a variable @@ -165,6 +166,11 @@ class Variable: If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ + # check for type of NAME parameter to override weird error message + # raised from Modules/_tkinter.c:SetVar like: + # TypeError: setvar() takes exactly 3 arguments (2 given) + if name is not None and not isinstance(name, str): + raise TypeError("name must be a string") global _varnum if not master: master = _default_root @@ -176,18 +182,21 @@ class Variable: self._name = 'PY_VAR' + repr(_varnum) _varnum += 1 if value is not None: - self.set(value) + self.initialize(value) elif not self._tk.call("info", "exists", self._name): - self.set(self._default) + self.initialize(self._default) def __del__(self): """Unset the variable in Tcl.""" - self._tk.globalunsetvar(self._name) + if (self._tk is not None and self._tk.call("info", "exists", + self._name)): + self._tk.globalunsetvar(self._name) def __str__(self): """Return the name of the variable in Tcl.""" return self._name def set(self, value): """Set the variable to VALUE.""" return self._tk.globalsetvar(self._name, value) + initialize = set def get(self): """Return value of variable.""" return self._tk.globalgetvar(self._name) @@ -262,12 +271,6 @@ class IntVar(Variable): """ Variable.__init__(self, master, value, name) - def set(self, value): - """Set the variable to value, converting booleans to integers.""" - if isinstance(value, bool): - value = int(value) - return Variable.set(self, value) - def get(self): """Return the value of the variable as an integer.""" return getint(self._tk.globalgetvar(self._name)) @@ -308,7 +311,10 @@ class BooleanVar(Variable): def get(self): """Return the value of the variable as a bool.""" - return self._tk.getboolean(self._tk.globalgetvar(self._name)) + try: + return self._tk.getboolean(self._tk.globalgetvar(self._name)) + except TclError: + raise ValueError("invalid literal for getboolean()") def mainloop(n=0): """Run the main loop of Tcl.""" @@ -320,7 +326,10 @@ getdouble = float def getboolean(s): """Convert true and false to integer values 1 and 0.""" - return _default_root.tk.getboolean(s) + try: + return _default_root.tk.getboolean(s) + except TclError: + raise ValueError("invalid literal for getboolean()") # Methods defined on both toplevel and interior widgets class Misc: @@ -410,7 +419,10 @@ class Misc: getdouble = float def getboolean(self, s): """Return a boolean value for Tcl boolean values true and false given as parameter.""" - return self.tk.getboolean(s) + try: + return self.tk.getboolean(s) + except TclError: + raise ValueError("invalid literal for getboolean()") def focus_set(self): """Direct input focus to this widget. diff --git a/Lib/tkinter/test/test_tkinter/test_variables.py b/Lib/tkinter/test/test_tkinter/test_variables.py new file mode 100644 index 0000000..8db7aca --- /dev/null +++ b/Lib/tkinter/test/test_tkinter/test_variables.py @@ -0,0 +1,165 @@ +import unittest + +from tkinter import Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tk + + +class Var(Variable): + + _default = "default" + side_effect = False + + def set(self, value): + self.side_effect = True + super().set(value) + + +class TestBase(unittest.TestCase): + + def setUp(self): + self.root = Tk() + + def tearDown(self): + self.root.destroy() + + +class TestVariable(TestBase): + + def test_default(self): + v = Variable(self.root) + self.assertEqual("", v.get()) + self.assertRegex(str(v), r"^PY_VAR(\d+)$") + + def test_name_and_value(self): + v = Variable(self.root, "sample string", "varname") + self.assertEqual("sample string", v.get()) + self.assertEqual("varname", str(v)) + + def test___del__(self): + self.assertFalse(self.root.call("info", "exists", "varname")) + v = Variable(self.root, "sample string", "varname") + self.assertTrue(self.root.call("info", "exists", "varname")) + del v + self.assertFalse(self.root.call("info", "exists", "varname")) + + def test_dont_unset_not_existing(self): + self.assertFalse(self.root.call("info", "exists", "varname")) + v1 = Variable(self.root, name="name") + v2 = Variable(self.root, name="name") + del v1 + self.assertFalse(self.root.call("info", "exists", "name")) + # shouldn't raise exception + del v2 + self.assertFalse(self.root.call("info", "exists", "name")) + + def test___eq__(self): + # values doesn't matter, only class and name are checked + v1 = Variable(self.root, name="abc") + v2 = Variable(self.root, name="abc") + self.assertEqual(v1, v2) + + v3 = Variable(self.root, name="abc") + v4 = StringVar(self.root, name="abc") + self.assertNotEqual(v3, v4) + + def test_invalid_name(self): + with self.assertRaises(TypeError): + Variable(self.root, name=123) + + def test_initialize(self): + v = Var() + self.assertFalse(v.side_effect) + v.set("value") + self.assertTrue(v.side_effect) + + +class TestStringVar(TestBase): + + def test_default(self): + v = StringVar(self.root) + self.assertEqual("", v.get()) + + def test_get(self): + v = StringVar(self.root, "abc", "name") + self.assertEqual("abc", v.get()) + self.root.globalsetvar("name", True) + self.assertEqual("1", v.get()) + + +class TestIntVar(TestBase): + + def test_default(self): + v = IntVar(self.root) + self.assertEqual(0, v.get()) + + def test_get(self): + v = IntVar(self.root, 123, "name") + self.assertEqual(123, v.get()) + self.root.globalsetvar("name", "345") + self.assertEqual(345, v.get()) + + def test_invalid_value(self): + v = IntVar(self.root, name="name") + self.root.globalsetvar("name", "value") + with self.assertRaises(ValueError): + v.get() + self.root.globalsetvar("name", "345.0") + with self.assertRaises(ValueError): + v.get() + + +class TestDoubleVar(TestBase): + + def test_default(self): + v = DoubleVar(self.root) + self.assertEqual(0.0, v.get()) + + def test_get(self): + v = DoubleVar(self.root, 1.23, "name") + self.assertAlmostEqual(1.23, v.get()) + self.root.globalsetvar("name", "3.45") + self.assertAlmostEqual(3.45, v.get()) + + def test_get_from_int(self): + v = DoubleVar(self.root, 1.23, "name") + self.assertAlmostEqual(1.23, v.get()) + self.root.globalsetvar("name", "3.45") + self.assertAlmostEqual(3.45, v.get()) + self.root.globalsetvar("name", "456") + self.assertAlmostEqual(456, v.get()) + + def test_invalid_value(self): + v = DoubleVar(self.root, name="name") + self.root.globalsetvar("name", "value") + with self.assertRaises(ValueError): + v.get() + + +class TestBooleanVar(TestBase): + + def test_default(self): + v = BooleanVar(self.root) + self.assertEqual(False, v.get()) + + def test_get(self): + v = BooleanVar(self.root, True, "name") + self.assertAlmostEqual(True, v.get()) + self.root.globalsetvar("name", "0") + self.assertAlmostEqual(False, v.get()) + + def test_invalid_value_domain(self): + v = BooleanVar(self.root, name="name") + self.root.globalsetvar("name", "value") + with self.assertRaises(ValueError): + v.get() + self.root.globalsetvar("name", "1.0") + with self.assertRaises(ValueError): + v.get() + + +tests_gui = (TestVariable, TestStringVar, TestIntVar, + TestDoubleVar, TestBooleanVar) + + +if __name__ == "__main__": + from test.support import run_unittest + run_unittest(*tests_gui) diff --git a/Lib/unittest/main.py b/Lib/unittest/main.py index c50066f..a25a2f8 100644 --- a/Lib/unittest/main.py +++ b/Lib/unittest/main.py @@ -1,6 +1,7 @@ """Unittest main program""" import sys +import optparse import os from . import loader, runner @@ -76,6 +77,7 @@ def _convert_name(name): def _convert_names(names): return [_convert_name(name) for name in names] + class TestProgram(object): """A command-line program that runs a set of tests; this is primarily for making test modules conveniently executable. @@ -142,33 +144,9 @@ class TestProgram(object): self._do_discovery(argv[2:]) return - import getopt - long_opts = ['help', 'verbose', 'quiet', 'failfast', 'catch', 'buffer'] - try: - options, args = getopt.getopt(argv[1:], 'hHvqfcb', long_opts) - except getopt.error as msg: - self.usageExit(msg) - return - - for opt, value in options: - if opt in ('-h','-H','--help'): - self.usageExit() - if opt in ('-q','--quiet'): - self.verbosity = 0 - if opt in ('-v','--verbose'): - self.verbosity = 2 - if opt in ('-f','--failfast'): - if self.failfast is None: - self.failfast = True - # Should this raise an exception if -f is not valid? - if opt in ('-c','--catch'): - if self.catchbreak is None: - self.catchbreak = True - # Should this raise an exception if -c is not valid? - if opt in ('-b','--buffer'): - if self.buffer is None: - self.buffer = True - # Should this raise an exception if -b is not valid? + parser = self._getOptParser() + options, args = parser.parse_args(argv[1:]) + self._setAttributesFromOptions(options) if len(args) == 0 and self.module is None: # this allows "python -m unittest -v" to still work for @@ -196,14 +174,14 @@ class TestProgram(object): self.test = self.testLoader.loadTestsFromNames(self.testNames, self.module) - def _do_discovery(self, argv, Loader=loader.TestLoader): - # handle command line args for test discovery - self.progName = '%s discover' % self.progName - import optparse + def _getOptParser(self): parser = optparse.OptionParser() parser.prog = self.progName parser.add_option('-v', '--verbose', dest='verbose', default=False, help='Verbose output', action='store_true') + parser.add_option('-q', '--quiet', dest='quiet', default=False, + help='Quiet output', action='store_true') + if self.failfast != False: parser.add_option('-f', '--failfast', dest='failfast', default=False, help='Stop on first fail or error', @@ -216,6 +194,24 @@ class TestProgram(object): parser.add_option('-b', '--buffer', dest='buffer', default=False, help='Buffer stdout and stderr during tests', action='store_true') + return parser + + def _setAttributesFromOptions(self, options): + # only set options from the parsing here + # if they weren't set explicitly in the constructor + if self.failfast is None: + self.failfast = options.failfast + if self.catchbreak is None: + self.catchbreak = options.catchbreak + if self.buffer is None: + self.buffer = options.buffer + + if options.verbose: + self.verbosity = 2 + elif options.quiet: + self.verbosity = 0 + + def _addDiscoveryOptions(self, parser): parser.add_option('-s', '--start-directory', dest='start', default='.', help="Directory to start discovery ('.' default)") parser.add_option('-p', '--pattern', dest='pattern', default='test*.py', @@ -223,6 +219,12 @@ class TestProgram(object): parser.add_option('-t', '--top-level-directory', dest='top', default=None, help='Top level directory of project (defaults to start directory)') + def _do_discovery(self, argv, Loader=loader.TestLoader): + # handle command line args for test discovery + self.progName = '%s discover' % self.progName + parser = self._getOptParser() + self._addDiscoveryOptions(parser) + options, args = parser.parse_args(argv) if len(args) > 3: self.usageExit() @@ -230,17 +232,7 @@ class TestProgram(object): for name, value in zip(('start', 'pattern', 'top'), args): setattr(options, name, value) - # only set options from the parsing here - # if they weren't set explicitly in the constructor - if self.failfast is None: - self.failfast = options.failfast - if self.catchbreak is None: - self.catchbreak = options.catchbreak - if self.buffer is None: - self.buffer = options.buffer - - if options.verbose: - self.verbosity = 2 + self._setAttributesFromOptions(options) start_dir = options.start pattern = options.pattern diff --git a/Lib/unittest/test/test_program.py b/Lib/unittest/test/test_program.py index d5d0f5a..9794868 100644 --- a/Lib/unittest/test/test_program.py +++ b/Lib/unittest/test/test_program.py @@ -131,23 +131,6 @@ class TestCommandLineArgs(unittest.TestCase): FakeRunner.test = None FakeRunner.raiseError = False - def testHelpAndUnknown(self): - program = self.program - def usageExit(msg=None): - program.msg = msg - program.exit = True - program.usageExit = usageExit - - for opt in '-h', '-H', '--help': - program.exit = False - program.parseArgs([None, opt]) - self.assertTrue(program.exit) - self.assertIsNone(program.msg) - - program.parseArgs([None, '-$']) - self.assertTrue(program.exit) - self.assertIsNotNone(program.msg) - def testVerbosity(self): program = self.program @@ -602,6 +602,7 @@ Christopher Tur Lesniewski-Laas Alain Leufroy Mark Levinson William Lewis +Akira Li Xuanji Li Robert van Liere Ross Light @@ -686,6 +687,7 @@ Andrii V. Mishkovskyi Dom Mitchell Dustin J. Mitchell Zubin Mithra +Florian Mladitsch Doug Moen The Dragon De Monsyne Skip Montanaro @@ -883,6 +885,7 @@ George Sakkis Rich Salz Kevin Samborn Adrian Sampson +James Sanders Ilya Sandler Mark Sapiro Ty Sarna @@ -10,6 +10,8 @@ What's New in Python 3.3.0 Alpha 2? Core and Builtins ----------------- +- Give the ast.AST class a __dict__. + - Issue #1469629: Allow cycles through an object's __dict__ slot to be collected. (For example if ``x.__dict__ is x``). @@ -22,6 +24,15 @@ Core and Builtins Library ------- +- Issue #1178863: Separate initialisation from setting when initializing + Tkinter.Variables; harmonize exceptions to ValueError; only delete variables + that have not been deleted; assert that variable names are strings. + +- Issue #14104: Implement time.monotonic() on Mac OS X, patch written by + Nicholas Riley. + +- Issue #13394: the aifc module now uses warnings.warn() to signal warnings. + - Issue #14252: Fix subprocess.Popen.terminate() to not raise an error under Windows when the child process has already exited. @@ -49,6 +60,9 @@ Extension Modules - Issue #14212: The re module didn't retain a reference to buffers it was scanning, resulting in segfaults. +- Issue #14259: The finditer() method of re objects did not take any + keyword arguments, contrary to the documentation. + What's New in Python 3.3.0 Alpha 1? =================================== diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 2dc3a41..9410e52 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -2812,6 +2812,24 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name) } static int +save_ellipsis(PicklerObject *self, PyObject *obj) +{ + PyObject *str = PyUnicode_FromString("Ellipsis"); + if (str == NULL) + return -1; + return save_global(self, Py_Ellipsis, str); +} + +static int +save_notimplemented(PicklerObject *self, PyObject *obj) +{ + PyObject *str = PyUnicode_FromString("NotImplemented"); + if (str == NULL) + return -1; + return save_global(self, Py_NotImplemented, str); +} + +static int save_pers(PicklerObject *self, PyObject *obj, PyObject *func) { PyObject *pid = NULL; @@ -3114,6 +3132,14 @@ save(PicklerObject *self, PyObject *obj, int pers_save) status = save_none(self, obj); goto done; } + else if (obj == Py_Ellipsis) { + status = save_ellipsis(self, obj); + goto done; + } + else if (obj == Py_NotImplemented) { + status = save_notimplemented(self, obj); + goto done; + } else if (obj == Py_False || obj == Py_True) { status = save_bool(self, obj); goto done; diff --git a/Modules/_sre.c b/Modules/_sre.c index 9254480..cb1f791 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -1596,7 +1596,7 @@ SRE_SEARCH(SRE_STATE* state, SRE_CODE* pattern) /* see sre.h for object declarations */ static PyObject*pattern_new_match(PatternObject*, SRE_STATE*, int); -static PyObject*pattern_scanner(PatternObject*, PyObject*); +static PyObject*pattern_scanner(PatternObject*, PyObject*, PyObject* kw); static int sre_literal_template(int charsize, char* ptr, Py_ssize_t len) @@ -2132,13 +2132,13 @@ error: #if PY_VERSION_HEX >= 0x02020000 static PyObject* -pattern_finditer(PatternObject* pattern, PyObject* args) +pattern_finditer(PatternObject* pattern, PyObject* args, PyObject* kw) { PyObject* scanner; PyObject* search; PyObject* iterator; - scanner = pattern_scanner(pattern, args); + scanner = pattern_scanner(pattern, args, kw); if (!scanner) return NULL; @@ -2576,10 +2576,10 @@ static PyMethodDef pattern_methods[] = { {"findall", (PyCFunction) pattern_findall, METH_VARARGS|METH_KEYWORDS, pattern_findall_doc}, #if PY_VERSION_HEX >= 0x02020000 - {"finditer", (PyCFunction) pattern_finditer, METH_VARARGS, + {"finditer", (PyCFunction) pattern_finditer, METH_VARARGS|METH_KEYWORDS, pattern_finditer_doc}, #endif - {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS}, + {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS|METH_KEYWORDS}, {"__copy__", (PyCFunction) pattern_copy, METH_NOARGS}, {"__deepcopy__", (PyCFunction) pattern_deepcopy, METH_O}, {NULL, NULL} @@ -3822,7 +3822,7 @@ static PyTypeObject Scanner_Type = { }; static PyObject* -pattern_scanner(PatternObject* pattern, PyObject* args) +pattern_scanner(PatternObject* pattern, PyObject* args, PyObject* kw) { /* create search state object */ @@ -3831,7 +3831,9 @@ pattern_scanner(PatternObject* pattern, PyObject* args) PyObject* string; Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; - if (!PyArg_ParseTuple(args, "O|nn:scanner", &string, &start, &end)) + static char* kwlist[] = { "source", "pos", "endpos", NULL }; + if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:scanner", kwlist, + &string, &start, &end)) return NULL; /* create scanner object */ diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 59fe3ee..6ebd3ef 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -40,6 +40,10 @@ #include <sys/time.h> #endif +#if defined(__APPLE__) +#include <mach/mach_time.h> +#endif + /* Forward declarations */ static int floatsleep(double); static double floattime(void); @@ -816,7 +820,8 @@ of the returned value is undefined so only the difference of consecutive\n\ calls is valid."); #if (defined(MS_WINDOWS) && !defined(__BORLANDC__)) \ - || (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)) + || (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)) \ + || (defined(__APPLE__)) # define HAVE_PYTIME_MONOTONIC #endif @@ -826,6 +831,17 @@ time_monotonic(PyObject *self, PyObject *unused) { #if defined(MS_WINDOWS) && !defined(__BORLANDC__) return win32_clock(0); +#elif defined(__APPLE__) + uint64_t time = mach_absolute_time(); + double secs; + + static mach_timebase_info_data_t timebase; + if (timebase.denom == 0) + mach_timebase_info(&timebase); + + secs = (double)time * timebase.numer / timebase.denom * 1e-9; + + return PyFloat_FromDouble(secs); #else static int clk_index = 0; clockid_t clk_ids[] = { diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index 07c06de..0be6c7f 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -603,6 +603,11 @@ class PyTypesVisitor(PickleVisitor): def visitModule(self, mod): self.emit(""" +typedef struct { + PyObject_HEAD + PyObject *dict; +} AST_object; + static int ast_type_init(PyObject *self, PyObject *args, PyObject *kw) { @@ -681,10 +686,15 @@ static PyMethodDef ast_type_methods[] = { {NULL} }; +static PyGetSetDef ast_type_getsets[] = { + {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, + {NULL} +}; + static PyTypeObject AST_type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "_ast.AST", - sizeof(PyObject), + sizeof(AST_object), 0, 0, /* tp_dealloc */ 0, /* tp_print */ @@ -711,12 +721,12 @@ static PyTypeObject AST_type = { 0, /* tp_iternext */ ast_type_methods, /* tp_methods */ 0, /* tp_members */ - 0, /* tp_getset */ + ast_type_getsets, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ + offsetof(AST_object, dict),/* tp_dictoffset */ (initproc)ast_type_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ @@ -1185,6 +1195,8 @@ def main(srcfile): p = os.path.join(SRC_DIR, str(mod.name) + "-ast.c") f = open(p, "w") f.write(auto_gen_msg) + f.write('#include <stddef.h>\n') + f.write('\n') f.write('#include "Python.h"\n') f.write('#include "%s-ast.h"\n' % mod.name) f.write('\n') diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 2603b81..1178d74 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -1,5 +1,7 @@ /* File automatically generated by Parser/asdl_c.py. */ +#include <stddef.h> + #include "Python.h" #include "Python-ast.h" @@ -453,6 +455,11 @@ static char *withitem_fields[]={ }; +typedef struct { + PyObject_HEAD + PyObject *dict; +} AST_object; + static int ast_type_init(PyObject *self, PyObject *args, PyObject *kw) { @@ -531,10 +538,15 @@ static PyMethodDef ast_type_methods[] = { {NULL} }; +static PyGetSetDef ast_type_getsets[] = { + {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, + {NULL} +}; + static PyTypeObject AST_type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "_ast.AST", - sizeof(PyObject), + sizeof(AST_object), 0, 0, /* tp_dealloc */ 0, /* tp_print */ @@ -561,12 +573,12 @@ static PyTypeObject AST_type = { 0, /* tp_iternext */ ast_type_methods, /* tp_methods */ 0, /* tp_members */ - 0, /* tp_getset */ + ast_type_getsets, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ + offsetof(AST_object, dict),/* tp_dictoffset */ (initproc)ast_type_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ diff --git a/Python/ast.c b/Python/ast.c index 0f93098..eb8aed2 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -1153,7 +1153,7 @@ seq_for_testlist(struct compiling *c, const node *n) } static arg_ty -compiler_arg(struct compiling *c, const node *n) +ast_for_arg(struct compiling *c, const node *n) { identifier name; expr_ty annotation = NULL; @@ -1174,12 +1174,6 @@ compiler_arg(struct compiling *c, const node *n) } return arg(name, annotation, c->c_arena); -#if 0 - result = Tuple(args, Store, LINENO(n), n->n_col_offset, c->c_arena); - if (!set_context(c, result, Store, n)) - return NULL; - return result; -#endif } /* returns -1 if failed to handle keyword only arguments @@ -1367,7 +1361,7 @@ ast_for_arguments(struct compiling *c, const node *n) "non-default argument follows default argument"); return NULL; } - arg = compiler_arg(c, ch); + arg = ast_for_arg(c, ch); if (!arg) return NULL; asdl_seq_SET(posargs, k++, arg); |