diff -r 63bbe9f80909 Lib/ctypes/test/__init__.py --- a/Lib/ctypes/test/__init__.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/__init__.py Tue Sep 15 13:09:43 2015 +0300 @@ -214,3 +214,16 @@ class BasicTestRunner: result = unittest.TestResult() test(result) return result + +def xfail(method): + """ + Poor's man xfail: remove it when all the failures have been fixed + """ + def new_method(self, *args, **kwds): + try: + method(self, *args, **kwds) + except: + pass + else: + self.assertTrue(False, "DID NOT RAISE") + return new_method diff -r 63bbe9f80909 Lib/ctypes/test/test_arrays.py --- a/Lib/ctypes/test/test_arrays.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_arrays.py Tue Sep 15 13:09:43 2015 +0300 @@ -1,14 +1,25 @@ import unittest from ctypes import * +from test.test_support import impl_detail from ctypes.test import need_symbol formats = "bBhHiIlLqQfd" +# c_longdouble commented out for PyPy, look at the commend in test_longdouble formats = c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, \ - c_long, c_ulonglong, c_float, c_double, c_longdouble + c_long, c_ulonglong, c_float, c_double #, c_longdouble class ArrayTestCase(unittest.TestCase): + + @impl_detail('long double not supported by PyPy', pypy=False) + def test_longdouble(self): + """ + This test is empty. It's just here to remind that we commented out + c_longdouble in "formats". If pypy will ever supports c_longdouble, we + should kill this test and uncomment c_longdouble inside formats. + """ + def test_simple(self): # create classes holding simple numeric types, and check # various properties. diff -r 63bbe9f80909 Lib/ctypes/test/test_bitfields.py --- a/Lib/ctypes/test/test_bitfields.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_bitfields.py Tue Sep 15 13:09:43 2015 +0300 @@ -116,23 +116,28 @@ class BitFieldTest(unittest.TestCase): def test_nonint_types(self): # bit fields are not allowed on non-integer types. result = self.fail_fields(("a", c_char_p, 1)) - self.assertEqual(result, (TypeError, 'bit fields not allowed for type c_char_p')) + self.assertEqual(result[0], TypeError) + self.assertIn('bit fields not allowed for type', result[1]) result = self.fail_fields(("a", c_void_p, 1)) - self.assertEqual(result, (TypeError, 'bit fields not allowed for type c_void_p')) + self.assertEqual(result[0], TypeError) + self.assertIn('bit fields not allowed for type', result[1]) if c_int != c_long: result = self.fail_fields(("a", POINTER(c_int), 1)) - self.assertEqual(result, (TypeError, 'bit fields not allowed for type LP_c_int')) + self.assertEqual(result[0], TypeError) + self.assertIn('bit fields not allowed for type', result[1]) result = self.fail_fields(("a", c_char, 1)) - self.assertEqual(result, (TypeError, 'bit fields not allowed for type c_char')) + self.assertEqual(result[0], TypeError) + self.assertIn('bit fields not allowed for type', result[1]) class Dummy(Structure): _fields_ = [] result = self.fail_fields(("a", Dummy, 1)) - self.assertEqual(result, (TypeError, 'bit fields not allowed for type Dummy')) + self.assertEqual(result[0], TypeError) + self.assertIn('bit fields not allowed for type', result[1]) @need_symbol('c_wchar') def test_c_wchar(self): diff -r 63bbe9f80909 Lib/ctypes/test/test_byteswap.py --- a/Lib/ctypes/test/test_byteswap.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_byteswap.py Tue Sep 15 13:09:43 2015 +0300 @@ -2,6 +2,7 @@ import sys, unittest, struct, math, ctyp from binascii import hexlify from ctypes import * +from ctypes.test import xfail def bin(s): return hexlify(memoryview(s)).upper() @@ -22,6 +23,7 @@ class Test(unittest.TestCase): setattr(bits, "i%s" % i, 1) dump(bits) + @xfail def test_endian_short(self): if sys.byteorder == "little": self.assertIs(c_short.__ctype_le__, c_short) @@ -49,6 +51,7 @@ class Test(unittest.TestCase): self.assertEqual(bin(s), "3412") self.assertEqual(s.value, 0x1234) + @xfail def test_endian_int(self): if sys.byteorder == "little": self.assertIs(c_int.__ctype_le__, c_int) @@ -77,6 +80,7 @@ class Test(unittest.TestCase): self.assertEqual(bin(s), "78563412") self.assertEqual(s.value, 0x12345678) + @xfail def test_endian_longlong(self): if sys.byteorder == "little": self.assertIs(c_longlong.__ctype_le__, c_longlong) @@ -105,6 +109,7 @@ class Test(unittest.TestCase): self.assertEqual(bin(s), "EFCDAB9078563412") self.assertEqual(s.value, 0x1234567890ABCDEF) + @xfail def test_endian_float(self): if sys.byteorder == "little": self.assertIs(c_float.__ctype_le__, c_float) @@ -123,6 +128,7 @@ class Test(unittest.TestCase): self.assertAlmostEqual(s.value, math.pi, 6) self.assertEqual(bin(struct.pack(">f", math.pi)), bin(s)) + @xfail def test_endian_double(self): if sys.byteorder == "little": self.assertIs(c_double.__ctype_le__, c_double) @@ -150,6 +156,7 @@ class Test(unittest.TestCase): self.assertIs(c_char.__ctype_le__, c_char) self.assertIs(c_char.__ctype_be__, c_char) + @xfail def test_struct_fields_1(self): if sys.byteorder == "little": base = BigEndianStructure @@ -185,6 +192,7 @@ class Test(unittest.TestCase): pass self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)]) + @xfail def test_struct_struct(self): # nested structures with different byteorders @@ -213,6 +221,7 @@ class Test(unittest.TestCase): self.assertEqual(s.point.x, 1) self.assertEqual(s.point.y, 2) + @xfail def test_struct_fields_2(self): # standard packing in struct uses no alignment. # So, we have to align using pad bytes. @@ -236,6 +245,7 @@ class Test(unittest.TestCase): s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14) self.assertEqual(bin(s1), bin(s2)) + @xfail def test_unaligned_nonnative_struct_fields(self): if sys.byteorder == "little": base = BigEndianStructure diff -r 63bbe9f80909 Lib/ctypes/test/test_callbacks.py --- a/Lib/ctypes/test/test_callbacks.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_callbacks.py Tue Sep 15 13:09:43 2015 +0300 @@ -1,6 +1,7 @@ import unittest from ctypes import * from ctypes.test import need_symbol +from ctypes.test import xfail import _ctypes_test class Callbacks(unittest.TestCase): @@ -100,6 +101,7 @@ class Callbacks(unittest.TestCase): self.check_type(c_char_p, "abc") self.check_type(c_char_p, "def") + @xfail def test_pyobject(self): o = () from sys import getrefcount as grc diff -r 63bbe9f80909 Lib/ctypes/test/test_cfuncs.py --- a/Lib/ctypes/test/test_cfuncs.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_cfuncs.py Tue Sep 15 13:09:43 2015 +0300 @@ -6,6 +6,7 @@ from ctypes import * from ctypes.test import need_symbol import _ctypes_test +from test.test_support import impl_detail class CFunctions(unittest.TestCase): _dll = CDLL(_ctypes_test.__file__) @@ -159,12 +160,14 @@ class CFunctions(unittest.TestCase): self.assertEqual(self._dll.tf_bd(0, 42.), 14.) self.assertEqual(self.S(), 42) + @impl_detail('long double not supported by PyPy', pypy=False) def test_longdouble(self): self._dll.tf_D.restype = c_longdouble self._dll.tf_D.argtypes = (c_longdouble,) self.assertEqual(self._dll.tf_D(42.), 14.) self.assertEqual(self.S(), 42) + @impl_detail('long double not supported by PyPy', pypy=False) def test_longdouble_plus(self): self._dll.tf_bD.restype = c_longdouble self._dll.tf_bD.argtypes = (c_byte, c_longdouble) diff -r 63bbe9f80909 Lib/ctypes/test/test_delattr.py --- a/Lib/ctypes/test/test_delattr.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_delattr.py Tue Sep 15 13:09:43 2015 +0300 @@ -6,15 +6,15 @@ class X(Structure): class TestCase(unittest.TestCase): def test_simple(self): - self.assertRaises(TypeError, + self.assertRaises((TypeError, AttributeError), delattr, c_int(42), "value") def test_chararray(self): - self.assertRaises(TypeError, + self.assertRaises((TypeError, AttributeError), delattr, (c_char * 5)(), "value") def test_struct(self): - self.assertRaises(TypeError, + self.assertRaises((TypeError, AttributeError), delattr, X(), "foo") if __name__ == "__main__": diff -r 63bbe9f80909 Lib/ctypes/test/test_frombuffer.py --- a/Lib/ctypes/test/test_frombuffer.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_frombuffer.py Tue Sep 15 13:09:43 2015 +0300 @@ -32,7 +32,7 @@ class Test(unittest.TestCase): del a; gc.collect(); gc.collect(); gc.collect() self.assertEqual(x[:], expected) - self.assertRaises(TypeError, + self.assertRaises((TypeError, ValueError), (c_char * 16).from_buffer, "a" * 16) def test_fom_buffer_with_offset(self): diff -r 63bbe9f80909 Lib/ctypes/test/test_functions.py --- a/Lib/ctypes/test/test_functions.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_functions.py Tue Sep 15 13:09:43 2015 +0300 @@ -8,6 +8,8 @@ Later... from ctypes import * from ctypes.test import need_symbol import sys, unittest +from ctypes.test import xfail +from test.test_support import impl_detail try: WINFUNCTYPE @@ -138,6 +140,7 @@ class FunctionTestCase(unittest.TestCase self.assertEqual(result, -21) self.assertEqual(type(result), float) + @impl_detail('long double not supported by PyPy', pypy=False) def test_longdoubleresult(self): f = dll._testfunc_D_bhilfD f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_longdouble] @@ -388,6 +391,7 @@ class FunctionTestCase(unittest.TestCase (s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h), (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9)) + @xfail def test_sf1651235(self): # see http://www.python.org/sf/1651235 diff -r 63bbe9f80909 Lib/ctypes/test/test_internals.py --- a/Lib/ctypes/test/test_internals.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_internals.py Tue Sep 15 13:09:43 2015 +0300 @@ -1,7 +1,10 @@ # This tests the internal _objects attribute import unittest from ctypes import * -from sys import getrefcount as grc +try: + from sys import getrefcount as grc +except ImportError: + grc = None # e.g. PyPy # XXX This test must be reviewed for correctness!!! @@ -22,6 +25,8 @@ class ObjectsTestCase(unittest.TestCase) self.assertEqual(id(a), id(b)) def test_ints(self): + if grc is None: + return unittest.skip("no sys.getrefcount()") i = 42000123 refcnt = grc(i) ci = c_int(i) @@ -29,11 +34,19 @@ class ObjectsTestCase(unittest.TestCase) self.assertEqual(ci._objects, None) def test_c_char_p(self): + if grc is None: + return unittest.skip("no sys.getrefcount()") s = "Hello, World" refcnt = grc(s) cs = c_char_p(s) self.assertEqual(refcnt + 1, grc(s)) - self.assertSame(cs._objects, s) + try: + # Moving gcs need to allocate a nonmoving buffer + cs._objects._obj + except AttributeError: + self.assertSame(cs._objects, s) + else: + self.assertSame(cs._objects._obj, s) def test_simple_struct(self): class X(Structure): diff -r 63bbe9f80909 Lib/ctypes/test/test_libc.py --- a/Lib/ctypes/test/test_libc.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_libc.py Tue Sep 15 13:09:43 2015 +0300 @@ -25,5 +25,14 @@ class LibTest(unittest.TestCase): lib.my_qsort(chars, len(chars)-1, sizeof(c_char), comparefunc(sort)) self.assertEqual(chars.raw, " ,,aaaadmmmnpppsss\x00") + def SKIPPED_test_no_more_xfail(self): + # We decided to not explicitly support the whole ctypes-2.7 + # and instead go for a case-by-case, demand-driven approach. + # So this test is skipped instead of failing. + import socket + import ctypes.test + self.assertTrue(not hasattr(ctypes.test, 'xfail'), + "You should incrementally grep for '@xfail' and remove them, they are real failures") + if __name__ == "__main__": unittest.main() diff -r 63bbe9f80909 Lib/ctypes/test/test_loading.py --- a/Lib/ctypes/test/test_loading.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_loading.py Tue Sep 15 13:09:43 2015 +0300 @@ -2,7 +2,7 @@ from ctypes import * import sys, unittest import os from ctypes.util import find_library -from ctypes.test import is_resource_enabled +from ctypes.test import is_resource_enabled, xfail libc_name = None if os.name == "nt": @@ -80,6 +80,7 @@ class LoaderTest(unittest.TestCase): self.assertRaises(AttributeError, dll.__getitem__, 1234) + @xfail @unittest.skipUnless(os.name == "nt", 'Windows-specific test') def test_1703286_A(self): from _ctypes import LoadLibrary, FreeLibrary @@ -91,6 +92,7 @@ class LoaderTest(unittest.TestCase): handle = LoadLibrary("advapi32") FreeLibrary(handle) + @xfail @unittest.skipUnless(os.name == "nt", 'Windows-specific test') def test_1703286_B(self): # Since on winXP 64-bit advapi32 loads like described diff -r 63bbe9f80909 Lib/ctypes/test/test_memfunctions.py --- a/Lib/ctypes/test/test_memfunctions.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_memfunctions.py Tue Sep 15 13:09:43 2015 +0300 @@ -55,7 +55,8 @@ class MemFunctionsTest(unittest.TestCase s = string_at("foo bar") # XXX The following may be wrong, depending on how Python # manages string instances - self.assertEqual(2, sys.getrefcount(s)) + if hasattr(sys, 'getrefcount'): + self.assertEqual(2, sys.getrefcount(s)) self.assertTrue(s, "foo bar") self.assertEqual(string_at("foo bar", 8), "foo bar\0") diff -r 63bbe9f80909 Lib/ctypes/test/test_numbers.py --- a/Lib/ctypes/test/test_numbers.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_numbers.py Tue Sep 15 13:09:43 2015 +0300 @@ -1,6 +1,7 @@ from ctypes import * import unittest import struct +from ctypes.test import xfail def valid_ranges(*types): # given a sequence of numeric types, collect their _type_ @@ -90,12 +91,14 @@ class NumberTestCase(unittest.TestCase): self.assertRaises(ValueError, t, l-1) self.assertRaises(ValueError, t, h+1) + @xfail def test_from_param(self): # the from_param class method attribute always # returns PyCArgObject instances for t in signed_types + unsigned_types + float_types: self.assertEqual(ArgType, type(t.from_param(0))) + @xfail def test_byref(self): # calling byref returns also a PyCArgObject instance for t in signed_types + unsigned_types + float_types + bool_types: @@ -116,6 +119,7 @@ class NumberTestCase(unittest.TestCase): self.assertEqual(t(2L).value, 2.0) self.assertEqual(t(f).value, 2.0) + @xfail def test_integers(self): class FloatLike(object): def __float__(self): diff -r 63bbe9f80909 Lib/ctypes/test/test_objects.py --- a/Lib/ctypes/test/test_objects.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_objects.py Tue Sep 15 13:09:43 2015 +0300 @@ -22,7 +22,7 @@ assigned from Python must be kept. >>> array[4] = 'foo bar' >>> array._objects -{'4': 'foo bar'} +{'4': } >>> array[4] 'foo bar' >>> @@ -47,9 +47,9 @@ of 'x' ('_b_base_' is either None, or th >>> x.array[0] = 'spam spam spam' >>> x._objects -{'0:2': 'spam spam spam'} +{'0:2': } >>> x.array._b_base_._objects -{'0:2': 'spam spam spam'} +{'0:2': } >>> ''' diff -r 63bbe9f80909 Lib/ctypes/test/test_parameters.py --- a/Lib/ctypes/test/test_parameters.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_parameters.py Tue Sep 15 13:09:43 2015 +0300 @@ -1,6 +1,8 @@ import unittest, sys from ctypes.test import need_symbol +from ctypes.test import xfail + class SimpleTypesTestCase(unittest.TestCase): def setUp(self): @@ -49,6 +51,7 @@ class SimpleTypesTestCase(unittest.TestC self.assertEqual(CWCHARP.from_param("abc"), "abcabcabc") # XXX Replace by c_char_p tests + @xfail def test_cstrings(self): from ctypes import c_char_p, byref @@ -82,7 +85,10 @@ class SimpleTypesTestCase(unittest.TestC pa = c_wchar_p.from_param(c_wchar_p(u"123")) self.assertEqual(type(pa), c_wchar_p) + if sys.platform == "win32": + test_cw_strings = xfail(test_cw_strings) + @xfail def test_int_pointers(self): from ctypes import c_short, c_uint, c_int, c_long, POINTER, pointer LPINT = POINTER(c_int) diff -r 63bbe9f80909 Lib/ctypes/test/test_pep3118.py --- a/Lib/ctypes/test/test_pep3118.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_pep3118.py Tue Sep 15 13:09:43 2015 +0300 @@ -1,6 +1,7 @@ import unittest from ctypes import * import re, sys +from ctypes.test import xfail if sys.byteorder == "little": THIS_ENDIAN = "<" @@ -19,6 +20,7 @@ def normalize(format): class Test(unittest.TestCase): + @xfail def test_native_types(self): for tp, fmt, shape, itemtp in native_types: ob = tp() @@ -46,6 +48,7 @@ class Test(unittest.TestCase): print(tp) raise + @xfail def test_endian_types(self): for tp, fmt, shape, itemtp in endian_types: ob = tp() diff -r 63bbe9f80909 Lib/ctypes/test/test_pickling.py --- a/Lib/ctypes/test/test_pickling.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_pickling.py Tue Sep 15 13:09:43 2015 +0300 @@ -3,6 +3,7 @@ import pickle from ctypes import * import _ctypes_test dll = CDLL(_ctypes_test.__file__) +from ctypes.test import xfail class X(Structure): _fields_ = [("a", c_int), ("b", c_double)] @@ -21,6 +22,7 @@ class PickleTest: def loads(self, item): return pickle.loads(item) + @xfail def test_simple(self): for src in [ c_int(42), @@ -31,6 +33,7 @@ class PickleTest: self.assertEqual(memoryview(src).tobytes(), memoryview(dst).tobytes()) + @xfail def test_struct(self): X.init_called = 0 @@ -49,6 +52,7 @@ class PickleTest: self.assertEqual(memoryview(y).tobytes(), memoryview(x).tobytes()) + @xfail def test_unpickable(self): # ctypes objects that are pointers or contain pointers are # unpickable. @@ -66,6 +70,7 @@ class PickleTest: ]: self.assertRaises(ValueError, lambda: self.dumps(item)) + @xfail def test_wchar(self): self.dumps(c_char(b"x")) # Issue 5049 diff -r 63bbe9f80909 Lib/ctypes/test/test_python_api.py --- a/Lib/ctypes/test/test_python_api.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_python_api.py Tue Sep 15 13:09:43 2015 +0300 @@ -1,6 +1,7 @@ from ctypes import * import unittest, sys from ctypes.test import requires +from ctypes.test import xfail ################################################################ # This section should be moved into ctypes\__init__.py, when it's ready. @@ -9,7 +10,10 @@ from _ctypes import PyObj_FromPtr ################################################################ -from sys import getrefcount as grc +try: + from sys import getrefcount as grc +except ImportError: + grc = None # e.g. PyPy if sys.version_info > (2, 4): c_py_ssize_t = c_size_t else: @@ -17,6 +21,7 @@ else: class PythonAPITestCase(unittest.TestCase): + @xfail def test_PyString_FromStringAndSize(self): PyString_FromStringAndSize = pythonapi.PyString_FromStringAndSize @@ -25,6 +30,7 @@ class PythonAPITestCase(unittest.TestCas self.assertEqual(PyString_FromStringAndSize("abcdefghi", 3), "abc") + @xfail def test_PyString_FromString(self): pythonapi.PyString_FromString.restype = py_object pythonapi.PyString_FromString.argtypes = (c_char_p,) @@ -56,6 +62,7 @@ class PythonAPITestCase(unittest.TestCas del res self.assertEqual(grc(42), ref42) + @xfail def test_PyObj_FromPtr(self): s = "abc def ghi jkl" ref = grc(s) @@ -67,6 +74,7 @@ class PythonAPITestCase(unittest.TestCas del pyobj self.assertEqual(grc(s), ref) + @xfail def test_PyOS_snprintf(self): PyOS_snprintf = pythonapi.PyOS_snprintf PyOS_snprintf.argtypes = POINTER(c_char), c_size_t, c_char_p @@ -81,6 +89,7 @@ class PythonAPITestCase(unittest.TestCas # not enough arguments self.assertRaises(TypeError, PyOS_snprintf, buf) + @xfail def test_pyobject_repr(self): self.assertEqual(repr(py_object()), "py_object()") self.assertEqual(repr(py_object(42)), "py_object(42)") diff -r 63bbe9f80909 Lib/ctypes/test/test_refcounts.py --- a/Lib/ctypes/test/test_refcounts.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_refcounts.py Tue Sep 15 13:09:43 2015 +0300 @@ -11,7 +11,10 @@ dll = ctypes.CDLL(_ctypes_test.__file__) class RefcountTestCase(unittest.TestCase): def test_1(self): - from sys import getrefcount as grc + try: + from sys import getrefcount as grc + except ImportError: + return unittest.skip("no sys.getrefcount()") f = dll._testfunc_callback_i_if f.restype = ctypes.c_int @@ -35,7 +38,10 @@ class RefcountTestCase(unittest.TestCase def test_refcount(self): - from sys import getrefcount as grc + try: + from sys import getrefcount as grc + except ImportError: + return unittest.skip("no sys.getrefcount()") def func(*args): pass # this is the standard refcount for func @@ -84,12 +90,17 @@ class RefcountTestCase(unittest.TestCase class AnotherLeak(unittest.TestCase): def test_callback(self): import sys + try: + from sys import getrefcount + except ImportError: + return unittest.skip("no sys.getrefcount()") proto = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int) def func(a, b): return a * b * 2 f = proto(func) + gc.collect() a = sys.getrefcount(ctypes.c_int) f(1, 2) self.assertEqual(sys.getrefcount(ctypes.c_int), a) diff -r 63bbe9f80909 Lib/ctypes/test/test_stringptr.py --- a/Lib/ctypes/test/test_stringptr.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_stringptr.py Tue Sep 15 13:09:43 2015 +0300 @@ -2,11 +2,13 @@ import unittest from ctypes import * import _ctypes_test +from ctypes.test import xfail lib = CDLL(_ctypes_test.__file__) class StringPtrTestCase(unittest.TestCase): + @xfail def test__POINTER_c_char(self): class X(Structure): _fields_ = [("str", POINTER(c_char))] @@ -27,6 +29,7 @@ class StringPtrTestCase(unittest.TestCas self.assertRaises(TypeError, setattr, x, "str", "Hello, World") + @xfail def test__c_char_p(self): class X(Structure): _fields_ = [("str", c_char_p)] diff -r 63bbe9f80909 Lib/ctypes/test/test_strings.py --- a/Lib/ctypes/test/test_strings.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_strings.py Tue Sep 15 13:09:43 2015 +0300 @@ -32,8 +32,9 @@ class StringArrayTestCase(unittest.TestC buf.value = "Hello, World" self.assertEqual(buf.value, "Hello, World") - self.assertRaises(TypeError, setattr, buf, "value", memoryview("Hello, World")) - self.assertRaises(TypeError, setattr, buf, "value", memoryview("abc")) + if test_support.check_impl_detail(): + self.assertRaises(TypeError, setattr, buf, "value", memoryview("Hello, World")) + self.assertRaises(TypeError, setattr, buf, "value", memoryview("abc")) self.assertRaises(ValueError, setattr, buf, "raw", memoryview("x" * 100)) def test_c_buffer_raw(self, memoryview=memoryview): @@ -41,7 +42,8 @@ class StringArrayTestCase(unittest.TestC buf.raw = memoryview("Hello, World") self.assertEqual(buf.value, "Hello, World") - self.assertRaises(TypeError, setattr, buf, "value", memoryview("abc")) + if test_support.check_impl_detail(): + self.assertRaises(TypeError, setattr, buf, "value", memoryview("abc")) self.assertRaises(ValueError, setattr, buf, "raw", memoryview("x" * 100)) def test_c_buffer_deprecated(self): diff -r 63bbe9f80909 Lib/ctypes/test/test_structures.py --- a/Lib/ctypes/test/test_structures.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_structures.py Tue Sep 15 13:09:43 2015 +0300 @@ -196,8 +196,8 @@ class StructureTestCase(unittest.TestCas self.assertEqual(X.b.offset, min(8, longlong_align)) - d = {"_fields_": [("a", "b"), - ("b", "q")], + d = {"_fields_": [("a", c_byte), + ("b", c_longlong)], "_pack_": -1} self.assertRaises(ValueError, type(Structure), "X", (Structure,), d) diff -r 63bbe9f80909 Lib/ctypes/test/test_values.py --- a/Lib/ctypes/test/test_values.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_values.py Tue Sep 15 13:09:43 2015 +0300 @@ -5,6 +5,7 @@ A testcase which accesses *values* in a import unittest import sys from ctypes import * +from ctypes.test import xfail import _ctypes_test @@ -26,6 +27,7 @@ class ValuesTestCase(unittest.TestCase): class Win_ValuesTestCase(unittest.TestCase): """This test only works when python itself is a dll/shared library""" + @xfail def test_optimizeflag(self): # This test accesses the Py_OptimizeFlag intger, which is # exported by the Python dll. @@ -42,6 +44,7 @@ class Win_ValuesTestCase(unittest.TestCa else: self.assertEqual(opt, 2) + @xfail def test_frozentable(self): # Python exports a PyImport_FrozenModules symbol. This is a # pointer to an array of struct _frozen entries. The end of the @@ -76,6 +79,7 @@ class Win_ValuesTestCase(unittest.TestCa from ctypes import _pointer_type_cache del _pointer_type_cache[struct_frozen] + @xfail def test_undefined(self): self.assertRaises(ValueError, c_int.in_dll, pythonapi, "Undefined_Symbol") diff -r 63bbe9f80909 Lib/ctypes/test/test_varsize_struct.py --- a/Lib/ctypes/test/test_varsize_struct.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/ctypes/test/test_varsize_struct.py Tue Sep 15 13:09:43 2015 +0300 @@ -1,7 +1,9 @@ from ctypes import * import unittest +from ctypes.test import xfail class VarSizeTest(unittest.TestCase): + @xfail def test_resize(self): class X(Structure): _fields_ = [("item", c_int), diff -r 63bbe9f80909 Lib/idlelib/idle_test/test_delegator.py --- a/Lib/idlelib/idle_test/test_delegator.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/idlelib/idle_test/test_delegator.py Tue Sep 15 13:09:43 2015 +0300 @@ -14,8 +14,8 @@ class DelegatorTest(unittest.TestCase): # add an attribute: self.assertRaises(AttributeError, mydel.__getattr__, 'xyz') bl = mydel.bit_length - self.assertIs(bl, int.bit_length) - self.assertIs(mydel.__dict__['bit_length'], int.bit_length) + self.assertEqual(bl, int.bit_length) + self.assertEqual(mydel.__dict__['bit_length'], int.bit_length) self.assertEqual(mydel._Delegator__cache, {'bit_length'}) # add a second attribute diff -r 63bbe9f80909 Lib/json/tests/test_decode.py --- a/Lib/json/tests/test_decode.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/json/tests/test_decode.py Tue Sep 15 13:09:43 2015 +0300 @@ -49,6 +49,7 @@ class TestDecode(object): self.assertEqual(self.loads('{"empty": {}}', object_pairs_hook=OrderedDict), OrderedDict([('empty', OrderedDict())])) + self.assertEqual(self.loads("{}", object_pairs_hook=list), []) def test_extra_data(self): s = '[1, 2, 3]5' diff -r 63bbe9f80909 Lib/json/tests/test_unicode.py --- a/Lib/json/tests/test_unicode.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/json/tests/test_unicode.py Tue Sep 15 13:09:43 2015 +0300 @@ -80,6 +80,12 @@ class TestUnicode(object): # Issue 10038. self.assertEqual(type(self.loads('"foo"')), unicode) + def test_encode_not_utf_8(self): + self.assertEqual(self.dumps('\xb1\xe6', encoding='iso8859-2'), + '"\\u0105\\u0107"') + self.assertEqual(self.dumps(['\xb1\xe6'], encoding='iso8859-2'), + '["\\u0105\\u0107"]') + def test_bad_encoding(self): self.assertRaises(UnicodeEncodeError, self.loads, '"a"', u"rat\xe9") self.assertRaises(TypeError, self.loads, '"a"', 1) diff -r 63bbe9f80909 Lib/lib-tk/test/test_tkinter/test_images.py --- a/Lib/lib-tk/test/test_tkinter/test_images.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/lib-tk/test/test_tkinter/test_images.py Tue Sep 15 13:09:43 2015 +0300 @@ -37,6 +37,7 @@ class BitmapImageTest(AbstractTkTest, un self.assertEqual(image.height(), 16) self.assertIn('::img::test', self.root.image_names()) del image + support.gc_collect() self.assertNotIn('::img::test', self.root.image_names()) def test_create_from_data(self): @@ -51,6 +52,7 @@ class BitmapImageTest(AbstractTkTest, un self.assertEqual(image.height(), 16) self.assertIn('::img::test', self.root.image_names()) del image + support.gc_collect() self.assertNotIn('::img::test', self.root.image_names()) def assertEqualStrList(self, actual, expected): @@ -131,6 +133,7 @@ class PhotoImageTest(AbstractTkTest, uni self.assertEqual(image['file'], testfile) self.assertIn('::img::test', self.root.image_names()) del image + support.gc_collect() self.assertNotIn('::img::test', self.root.image_names()) def check_create_from_data(self, ext): @@ -148,6 +151,7 @@ class PhotoImageTest(AbstractTkTest, uni self.assertEqual(image['file'], '') self.assertIn('::img::test', self.root.image_names()) del image + support.gc_collect() self.assertNotIn('::img::test', self.root.image_names()) def test_create_from_ppm_file(self): diff -r 63bbe9f80909 Lib/lib-tk/test/test_tkinter/test_variables.py --- a/Lib/lib-tk/test/test_tkinter/test_variables.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/lib-tk/test/test_tkinter/test_variables.py Tue Sep 15 13:09:43 2015 +0300 @@ -1,4 +1,5 @@ import unittest +from test.test_support import gc_collect from Tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl, TclError) @@ -33,6 +34,7 @@ class TestVariable(TestBase): v = Variable(self.root, "sample string", "varname") self.assertTrue(self.info_exists("varname")) del v + gc_collect() self.assertFalse(self.info_exists("varname")) def test_dont_unset_not_existing(self): @@ -40,9 +42,11 @@ class TestVariable(TestBase): v1 = Variable(self.root, name="name") v2 = Variable(self.root, name="name") del v1 + gc_collect() self.assertFalse(self.info_exists("name")) # shouldn't raise exception del v2 + gc_collect() self.assertFalse(self.info_exists("name")) def test___eq__(self): diff -r 63bbe9f80909 Lib/lib-tk/test/test_ttk/test_extensions.py --- a/Lib/lib-tk/test/test_ttk/test_extensions.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/lib-tk/test/test_ttk/test_extensions.py Tue Sep 15 13:09:43 2015 +0300 @@ -2,7 +2,7 @@ import sys import unittest import Tkinter as tkinter import ttk -from test.test_support import requires, run_unittest, swap_attr +from test.test_support import requires, run_unittest, swap_attr, gc_collect from test_ttk.support import AbstractTkTest, destroy_default_root requires('gui') @@ -18,6 +18,7 @@ class LabeledScaleTest(AbstractTkTest, u x = ttk.LabeledScale(self.root) var = x._variable._name x.destroy() + gc_collect() self.assertRaises(tkinter.TclError, x.tk.globalgetvar, var) # manually created variable @@ -25,11 +26,13 @@ class LabeledScaleTest(AbstractTkTest, u name = myvar._name x = ttk.LabeledScale(self.root, variable=myvar) x.destroy() + gc_collect() if self.wantobjects: self.assertEqual(x.tk.globalgetvar(name), myvar.get()) else: self.assertEqual(float(x.tk.globalgetvar(name)), myvar.get()) del myvar + gc_collect() self.assertRaises(tkinter.TclError, x.tk.globalgetvar, name) # checking that the tracing callback is properly removed @@ -37,6 +40,7 @@ class LabeledScaleTest(AbstractTkTest, u # LabeledScale will start tracing myvar x = ttk.LabeledScale(self.root, variable=myvar) x.destroy() + gc_collect() # Unless the tracing callback was removed, creating a new # LabeledScale with the same var will cause an error now. This # happens because the variable will be set to (possibly) a new @@ -216,6 +220,7 @@ class OptionMenuTest(AbstractTkTest, uni optmenu.destroy() self.assertEqual(optmenu.tk.globalgetvar(name), var.get()) del var + gc_collect() self.assertRaises(tkinter.TclError, optmenu.tk.globalgetvar, name) diff -r 63bbe9f80909 Lib/lib-tk/test/test_ttk/test_widgets.py --- a/Lib/lib-tk/test/test_ttk/test_widgets.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/lib-tk/test/test_ttk/test_widgets.py Tue Sep 15 13:09:43 2015 +0300 @@ -2,7 +2,7 @@ import unittest import Tkinter as tkinter from Tkinter import TclError import ttk -from test.test_support import requires, run_unittest +from test.test_support import requires, run_unittest, gc_collect import sys from test_functions import MockTclObj @@ -838,6 +838,7 @@ class ScaleTest(AbstractWidgetTest, unit self.assertEqual(conv(self.scale.get()), var.get()) self.assertEqual(conv(self.scale.get()), max + 5) del var + gc_collect() # the same happens with the value option self.scale['value'] = max + 10 diff -r 63bbe9f80909 Lib/sqlite3/test/dbapi.py --- a/Lib/sqlite3/test/dbapi.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/sqlite3/test/dbapi.py Tue Sep 15 13:09:43 2015 +0300 @@ -340,6 +340,9 @@ class CursorTests(unittest.TestCase): def __init__(self): self.value = 5 + def __iter__(self): + return self + def next(self): if self.value == 10: raise StopIteration @@ -476,6 +479,29 @@ class CursorTests(unittest.TestCase): except TypeError: pass + def CheckCurDescription(self): + self.cu.execute("select * from test") + + actual = self.cu.description + expected = [ + ('id', None, None, None, None, None, None), + ('name', None, None, None, None, None, None), + ('income', None, None, None, None, None, None), + ] + self.assertEqual(expected, actual) + + def CheckCurDescriptionVoidStatement(self): + self.cu.execute("insert into test(name) values (?)", ("foo",)) + self.assertIsNone(self.cu.description) + + def CheckCurDescriptionWithoutStatement(self): + cu = self.cx.cursor() + try: + self.assertIsNone(cu.description) + finally: + cu.close() + + @unittest.skipUnless(threading, 'This test requires threading.') class ThreadTests(unittest.TestCase): def setUp(self): @@ -835,7 +861,7 @@ class ClosedConTests(unittest.TestCase): con = sqlite.connect(":memory:") con.close() try: - con() + con("select 1") self.fail("Should have raised a ProgrammingError") except sqlite.ProgrammingError: pass diff -r 63bbe9f80909 Lib/sqlite3/test/regression.py --- a/Lib/sqlite3/test/regression.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/sqlite3/test/regression.py Tue Sep 15 13:09:43 2015 +0300 @@ -266,6 +266,28 @@ class RegressionTests(unittest.TestCase) """ self.assertRaises(sqlite.Warning, self.con, 1) + def CheckUpdateDescriptionNone(self): + """ + Call Cursor.update with an UPDATE query and check that it sets the + cursor's description to be None. + """ + cur = self.con.cursor() + cur.execute("CREATE TABLE foo (id INTEGER)") + cur.execute("UPDATE foo SET id = 3 WHERE id = 1") + self.assertEqual(cur.description, None) + + def CheckStatementCache(self): + cur = self.con.cursor() + cur.execute("CREATE TABLE foo (id INTEGER)") + values = [(i,) for i in xrange(5)] + cur.executemany("INSERT INTO foo (id) VALUES (?)", values) + + cur.execute("SELECT id FROM foo") + self.assertEqual(list(cur), values) + self.con.commit() + cur.execute("SELECT id FROM foo") + self.assertEqual(list(cur), values) + def CheckRecursiveCursorUse(self): """ http://bugs.python.org/issue10811 diff -r 63bbe9f80909 Lib/sqlite3/test/userfunctions.py --- a/Lib/sqlite3/test/userfunctions.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/sqlite3/test/userfunctions.py Tue Sep 15 13:09:43 2015 +0300 @@ -298,12 +298,14 @@ class AggregateTests(unittest.TestCase): pass def CheckAggrNoStep(self): + # XXX it's better to raise OperationalError in order to stop + # the query earlier. cur = self.con.cursor() try: cur.execute("select nostep(t) from test") - self.fail("should have raised an AttributeError") - except AttributeError, e: - self.assertEqual(e.args[0], "AggrNoStep instance has no attribute 'step'") + self.fail("should have raised an OperationalError") + except sqlite.OperationalError, e: + self.assertEqual(e.args[0], "user-defined aggregate's 'step' method raised error") def CheckAggrNoFinalize(self): cur = self.con.cursor() diff -r 63bbe9f80909 Lib/test/list_tests.py --- a/Lib/test/list_tests.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/list_tests.py Tue Sep 15 13:09:43 2015 +0300 @@ -45,8 +45,12 @@ class CommonTest(seq_tests.CommonTest): self.assertEqual(str(a2), "[0, 1, 2, [...], 3]") self.assertEqual(repr(a2), "[0, 1, 2, [...], 3]") + if test_support.check_impl_detail(): + depth = sys.getrecursionlimit() + 100 + else: + depth = 1000 * 1000 # should be enough to exhaust the stack l0 = [] - for i in xrange(sys.getrecursionlimit() + 100): + for i in xrange(depth): l0 = [l0] self.assertRaises(RuntimeError, repr, l0) @@ -472,7 +476,11 @@ class CommonTest(seq_tests.CommonTest): u += "eggs" self.assertEqual(u, self.type2test("spameggs")) - self.assertRaises(TypeError, u.__iadd__, None) + def f_iadd(u, x): + u += x + return u + + self.assertRaises(TypeError, f_iadd, u, None) def test_imul(self): u = self.type2test([0, 1]) diff -r 63bbe9f80909 Lib/test/mapping_tests.py --- a/Lib/test/mapping_tests.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/mapping_tests.py Tue Sep 15 13:09:43 2015 +0300 @@ -535,7 +535,10 @@ class TestMappingProtocol(BasicTestMappi self.assertEqual(va, int(ka)) kb, vb = tb = b.popitem() self.assertEqual(vb, int(kb)) - self.assertTrue(not(copymode < 0 and ta != tb)) + if copymode < 0 and test_support.check_impl_detail(): + # popitem() is not guaranteed to be deterministic on + # all implementations + self.assertEqual(ta, tb) self.assertTrue(not a) self.assertTrue(not b) diff -r 63bbe9f80909 Lib/test/pickletester.py --- a/Lib/test/pickletester.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/pickletester.py Tue Sep 15 13:09:43 2015 +0300 @@ -8,12 +8,14 @@ import copy_reg from test.test_support import TestFailed, verbose, have_unicode, TESTFN try: - from test.test_support import _2G, _1M, precisionbigmemtest + from test.test_support import _2G, _1M, precisionbigmemtest, impl_detail except ImportError: # this import might fail when run on older Python versions by test_xpickle _2G = _1M = 0 def precisionbigmemtest(*args, **kwargs): return lambda self: None + def impl_detail(*args, **kwargs): + return lambda self: None # Tests that try a number of pickle protocols should have a # for proto in protocols: @@ -981,6 +983,7 @@ class AbstractPickleTests(unittest.TestC "Failed protocol %d: %r != %r" % (proto, obj, loaded)) + @impl_detail("pypy does not store attribute names", pypy=False) def test_attribute_name_interning(self): # Test that attribute names of pickled objects are interned when # unpickling. @@ -1123,6 +1126,7 @@ class AbstractPickleModuleTests(unittest s = StringIO.StringIO("X''.") self.assertRaises(EOFError, self.module.load, s) + @impl_detail("no full restricted mode in pypy", pypy=False) def test_restricted(self): # issue7128: cPickle failed in restricted mode builtins = {self.module.__name__: self.module, diff -r 63bbe9f80909 Lib/test/regrtest.py --- a/Lib/test/regrtest.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/regrtest.py Tue Sep 15 13:09:43 2015 +0300 @@ -1448,7 +1448,26 @@ def printlist(x, width=70, indent=4): test_zipimport test_zlib """, - 'openbsd3': + 'openbsd4': + """ + test_ascii_formatd + test_bsddb + test_bsddb3 + test_ctypes + test_dl + test_epoll + test_gdbm + test_locale + test_normalization + test_ossaudiodev + test_pep277 + test_tcl + test_tk + test_ttk_guionly + test_ttk_textonly + test_multiprocessing + """, + 'openbsd5': """ test_ascii_formatd test_bsddb @@ -1563,13 +1582,7 @@ class _ExpectedSkips: return self.expected if __name__ == '__main__': - # findtestdir() gets the dirname out of __file__, so we have to make it - # absolute before changing the working directory. - # For example __file__ may be relative when running trace or profile. - # See issue #9323. - __file__ = os.path.abspath(__file__) - - # sanity check + # Simplification for findtestdir(). assert __file__ == os.path.abspath(sys.argv[0]) # When tests are run from the Python build directory, it is best practice diff -r 63bbe9f80909 Lib/test/seq_tests.py --- a/Lib/test/seq_tests.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/seq_tests.py Tue Sep 15 13:09:43 2015 +0300 @@ -319,12 +319,18 @@ class CommonTest(unittest.TestCase): def test_bigrepeat(self): import sys - if sys.maxint <= 2147483647: - x = self.type2test([0]) - x *= 2**16 - self.assertRaises(MemoryError, x.__mul__, 2**16) - if hasattr(x, '__imul__'): - self.assertRaises(MemoryError, x.__imul__, 2**16) + # we chose an N such as 2**16 * N does not fit into a cpu word + if sys.maxint == 2147483647: + # 32 bit system + N = 2**16 + else: + # 64 bit system + N = 2**48 + x = self.type2test([0]) + x *= 2**16 + self.assertRaises(MemoryError, x.__mul__, N) + if hasattr(x, '__imul__'): + self.assertRaises(MemoryError, x.__imul__, N) def test_subscript(self): a = self.type2test([10, 11]) diff -r 63bbe9f80909 Lib/test/string_tests.py --- a/Lib/test/string_tests.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/string_tests.py Tue Sep 15 13:09:43 2015 +0300 @@ -1022,7 +1022,10 @@ class MixinStrUnicodeUserStringTest: self.checkequal('abc', 'abc', '__mul__', 1) self.checkequal('abcabcabc', 'abc', '__mul__', 3) self.checkraises(TypeError, 'abc', '__mul__') - self.checkraises(TypeError, 'abc', '__mul__', '') + class Mul(object): + def mul(self, a, b): + return a * b + self.checkraises(TypeError, Mul(), 'mul', 'abc', '') # XXX: on a 64-bit system, this doesn't raise an overflow error, # but either raises a MemoryError, or succeeds (if you have 54TiB) #self.checkraises(OverflowError, 10000*'abc', '__mul__', 2000000000) diff -r 63bbe9f80909 Lib/test/test_abstract_numbers.py --- a/Lib/test/test_abstract_numbers.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_abstract_numbers.py Tue Sep 15 13:09:43 2015 +0300 @@ -40,7 +40,8 @@ class TestNumbers(unittest.TestCase): c1, c2 = complex(3, 2), complex(4,1) # XXX: This is not ideal, but see the comment in math_trunc(). - self.assertRaises(AttributeError, math.trunc, c1) + # Modified to suit PyPy, which gives TypeError in all cases + self.assertRaises((AttributeError, TypeError), math.trunc, c1) self.assertRaises(TypeError, float, c1) self.assertRaises(TypeError, int, c1) diff -r 63bbe9f80909 Lib/test/test_aifc.py --- a/Lib/test/test_aifc.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_aifc.py Tue Sep 15 13:09:43 2015 +0300 @@ -338,7 +338,7 @@ class AIFCLowLevelTest(unittest.TestCase def test_main(): run_unittest(AifcPCM8Test, AifcPCM16Test, AifcPCM16Test, AifcPCM24Test, - AifcPCM32Test, AifcULAWTest, + AifcPCM32Test, #AifcULAWTest, unimpl funcs in lib_pypy/audioop.py AifcMiscTest, AIFCLowLevelTest) if __name__ == "__main__": diff -r 63bbe9f80909 Lib/test/test_argparse.py --- a/Lib/test/test_argparse.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_argparse.py Tue Sep 15 13:09:43 2015 +0300 @@ -10,6 +10,7 @@ import textwrap import tempfile import unittest import argparse +import gc from StringIO import StringIO @@ -47,6 +48,9 @@ class TempDirMixin(object): def tearDown(self): os.chdir(self.old_dir) + import gc + # Force a collection which should close FileType() options + gc.collect() for root, dirs, files in os.walk(self.temp_dir, topdown=False): for name in files: os.chmod(os.path.join(self.temp_dir, name), stat.S_IWRITE) diff -r 63bbe9f80909 Lib/test/test_array.py --- a/Lib/test/test_array.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_array.py Tue Sep 15 13:09:43 2015 +0300 @@ -309,9 +309,11 @@ class BaseTest(unittest.TestCase): ) b = array.array(self.badtypecode()) - self.assertRaises(TypeError, a.__add__, b) + with self.assertRaises(TypeError): + a + b - self.assertRaises(TypeError, a.__add__, "bad") + with self.assertRaises(TypeError): + a + 'bad' def test_iadd(self): a = array.array(self.typecode, self.example[::-1]) @@ -330,9 +332,11 @@ class BaseTest(unittest.TestCase): ) b = array.array(self.badtypecode()) - self.assertRaises(TypeError, a.__add__, b) + with self.assertRaises(TypeError): + a += b - self.assertRaises(TypeError, a.__iadd__, "bad") + with self.assertRaises(TypeError): + a += 'bad' def test_mul(self): a = 5*array.array(self.typecode, self.example) @@ -359,7 +363,8 @@ class BaseTest(unittest.TestCase): array.array(self.typecode) ) - self.assertRaises(TypeError, a.__mul__, "bad") + with self.assertRaises(TypeError): + a * 'bad' def test_imul(self): a = array.array(self.typecode, self.example) @@ -388,7 +393,8 @@ class BaseTest(unittest.TestCase): a *= -1 self.assertEqual(a, array.array(self.typecode)) - self.assertRaises(TypeError, a.__imul__, "bad") + with self.assertRaises(TypeError): + a *= 'bad' def test_getitem(self): a = array.array(self.typecode, self.example) @@ -783,6 +789,7 @@ class BaseTest(unittest.TestCase): p = proxy(s) self.assertEqual(p.tostring(), s.tostring()) s = None + test_support.gc_collect() self.assertRaises(ReferenceError, len, p) @unittest.skipUnless(hasattr(sys, 'getrefcount'), diff -r 63bbe9f80909 Lib/test/test_ascii_formatd.py --- a/Lib/test/test_ascii_formatd.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_ascii_formatd.py Tue Sep 15 13:09:43 2015 +0300 @@ -4,6 +4,10 @@ import unittest from test.test_support import check_warnings, run_unittest, import_module +from test.test_support import check_impl_detail + +if not check_impl_detail(cpython=True): + raise unittest.SkipTest("this test is only for CPython") # Skip tests if _ctypes module does not exist import_module('_ctypes') diff -r 63bbe9f80909 Lib/test/test_ast.py --- a/Lib/test/test_ast.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_ast.py Tue Sep 15 13:09:43 2015 +0300 @@ -195,6 +195,10 @@ class AST_Tests(unittest.TestCase): self._assertTrueorder(value, parent_pos) def test_AST_objects(self): + if not test_support.check_impl_detail(): + # PyPy also provides a __dict__ to the ast.AST base class. + return + x = ast.AST() self.assertEqual(x._fields, ()) @@ -247,7 +251,7 @@ class AST_Tests(unittest.TestCase): def test_field_attr_existence(self): for name, item in ast.__dict__.iteritems(): - if isinstance(item, type) and name != 'AST' and name[0].isupper(): + if isinstance(item, type) and name != 'AST' and name[0].isupper(): # XXX: pypy does not allow abstract ast class instanciation x = item() if isinstance(x, ast.AST): self.assertEqual(type(x._fields), tuple) @@ -373,14 +377,16 @@ class AST_Tests(unittest.TestCase): ast.fix_missing_locations(m) with self.assertRaises(TypeError) as cm: compile(m, "", "exec") - self.assertIn("identifier must be of type str", str(cm.exception)) + if test_support.check_impl_detail(): + self.assertIn("identifier must be of type str", str(cm.exception)) def test_invalid_string(self): m = ast.Module([ast.Expr(ast.Str(43))]) ast.fix_missing_locations(m) with self.assertRaises(TypeError) as cm: compile(m, "", "exec") - self.assertIn("string must be of type str or uni", str(cm.exception)) + if test_support.check_impl_detail(): + self.assertIn("string must be of type str or uni", str(cm.exception)) class ASTHelpers_Test(unittest.TestCase): diff -r 63bbe9f80909 Lib/test/test_builtin.py --- a/Lib/test/test_builtin.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_builtin.py Tue Sep 15 13:09:43 2015 +0300 @@ -3,7 +3,8 @@ import platform import unittest from test.test_support import fcmp, have_unicode, TESTFN, unlink, \ - run_unittest, check_py3k_warnings + run_unittest, check_py3k_warnings, \ + check_impl_detail import warnings from operator import neg @@ -397,12 +398,16 @@ class BuiltinTest(unittest.TestCase): self.assertEqual(eval('dir()', g, m), list('xyz')) self.assertEqual(eval('globals()', g, m), g) self.assertEqual(eval('locals()', g, m), m) - self.assertRaises(TypeError, eval, 'a', m) + # on top of CPython, the first dictionary (the globals) has to + # be a real dict. This is not the case on top of PyPy. + if check_impl_detail(pypy=False): + self.assertRaises(TypeError, eval, 'a', m) + class A: "Non-mapping" pass m = A() - self.assertRaises(TypeError, eval, 'a', g, m) + self.assertRaises((TypeError, AttributeError), eval, 'a', g, m) # Verify that dict subclasses work as well class D(dict): @@ -1059,7 +1064,8 @@ class BuiltinTest(unittest.TestCase): def __cmp__(self, other): raise RuntimeError __hash__ = None # Invalid cmp makes this unhashable - self.assertRaises(RuntimeError, range, a, a + 1, badzero(1)) + if check_impl_detail(cpython=True): + self.assertRaises(RuntimeError, range, a, a + 1, badzero(1)) # Reject floats. self.assertRaises(TypeError, range, 1., 1., 1.) diff -r 63bbe9f80909 Lib/test/test_bytes.py --- a/Lib/test/test_bytes.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_bytes.py Tue Sep 15 13:09:43 2015 +0300 @@ -714,6 +714,7 @@ class ByteArrayTest(BaseBytesTest): self.assertEqual(b, b1) self.assertTrue(b is b1) + @test.test_support.impl_detail("undocumented bytes.__alloc__()") def test_alloc(self): b = bytearray() alloc = b.__alloc__() @@ -858,6 +859,8 @@ class ByteArrayTest(BaseBytesTest): self.assertEqual(b, b"") self.assertEqual(c, b"") + @test.test_support.impl_detail( + "resizing semantics of CPython rely on refcounting") def test_resize_forbidden(self): # #4509: can't resize a bytearray when there are buffer exports, even # if it wouldn't reallocate the underlying buffer. @@ -890,6 +893,26 @@ class ByteArrayTest(BaseBytesTest): self.assertRaises(BufferError, delslice) self.assertEqual(b, orig) + @test.test_support.impl_detail("resizing semantics", cpython=False) + def test_resize_forbidden_non_cpython(self): + # on non-CPython implementations, we cannot prevent changes to + # bytearrays just because there are buffers around. Instead, + # we get (on PyPy) a buffer that follows the changes and resizes. + b = bytearray(range(10)) + for v in [memoryview(b), buffer(b)]: + b[5] = 99 + self.assertIn(v[5], (99, chr(99))) + b[5] = 100 + b += b + b += b + b += b + self.assertEquals(len(v), 80) + self.assertIn(v[5], (100, chr(100))) + self.assertIn(v[79], (9, chr(9))) + del b[10:] + self.assertRaises(IndexError, lambda: v[10]) + self.assertEquals(len(v), 10) + def test_empty_bytearray(self): # Issue #7561: operations on empty bytearrays could crash in many # situations, due to a fragile implementation of the diff -r 63bbe9f80909 Lib/test/test_bz2.py --- a/Lib/test/test_bz2.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_bz2.py Tue Sep 15 13:09:43 2015 +0300 @@ -51,6 +51,7 @@ class BZ2FileTest(BaseTest): self.filename = TESTFN def tearDown(self): + support.gc_collect() if os.path.isfile(self.filename): os.unlink(self.filename) @@ -247,6 +248,8 @@ class BZ2FileTest(BaseTest): for i in xrange(10000): o = BZ2File(self.filename) del o + if i % 100 == 0: + support.gc_collect() def testOpenNonexistent(self): # "Test opening a nonexistent file" @@ -309,6 +312,7 @@ class BZ2FileTest(BaseTest): with support.start_threads(threads): pass + @support.impl_detail() def testMixedIterationReads(self): # Issue #8397: mixed iteration and reads should be forbidden. with bz2.BZ2File(self.filename, 'wb') as f: diff -r 63bbe9f80909 Lib/test/test_capi.py --- a/Lib/test/test_capi.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_capi.py Tue Sep 15 13:09:43 2015 +0300 @@ -17,7 +17,18 @@ except ImportError: _testcapi = support.import_module('_testcapi') -@unittest.skipUnless(threading, 'Threading required for this test.') +skips = [] +if support.check_impl_detail(pypy=True): + skips += [ + 'test_broken_memoryview', + 'test_capsule', + 'test_lazy_hash_inheritance', + 'test_widechar', + 'TestThreadState', + 'TestPendingCalls', + ] + +@unittest.skipUnless(threading and 'TestPendingCalls' not in skips, 'Threading required for this test.') class TestPendingCalls(unittest.TestCase): def pendingcalls_submit(self, l, n): @@ -96,7 +107,7 @@ class TestPendingCalls(unittest.TestCase self.pendingcalls_wait(l, n) -@unittest.skipUnless(threading and thread, 'Threading required for this test.') +@unittest.skipUnless(threading and thread and 'TestThreadState' not in skips, 'Threading required for this test.') class TestThreadState(unittest.TestCase): @support.reap_threads @@ -123,7 +134,7 @@ class TestThreadState(unittest.TestCase) def test_main(): for name in dir(_testcapi): - if name.startswith('test_'): + if name.startswith('test_') and name not in skips: test = getattr(_testcapi, name) if support.verbose: print "internal", name diff -r 63bbe9f80909 Lib/test/test_cmd_line.py --- a/Lib/test/test_cmd_line.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_cmd_line.py Tue Sep 15 13:09:43 2015 +0300 @@ -9,6 +9,7 @@ from test.script_helper import ( assert_python_ok, assert_python_failure, spawn_python, kill_python, python_exit_code ) +from test.test_support import check_impl_detail class CmdLineTest(unittest.TestCase): @@ -98,7 +99,8 @@ class CmdLineTest(unittest.TestCase): code = 'print(hash("spam"))' data = self.start_python('-R', '-c', code) hashes.append(data) - self.assertNotEqual(hashes[0], hashes[1]) + if check_impl_detail(pypy=False): # PyPy does not really implement it! + self.assertNotEqual(hashes[0], hashes[1]) # Verify that sys.flags contains hash_randomization code = 'import sys; print sys.flags' diff -r 63bbe9f80909 Lib/test/test_cmd_line_script.py --- a/Lib/test/test_cmd_line_script.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_cmd_line_script.py Tue Sep 15 13:09:43 2015 +0300 @@ -115,6 +115,8 @@ class CmdLineTest(unittest.TestCase): self._check_script(script_dir, script_name, script_dir, '') def test_directory_compiled(self): + if test.test_support.check_impl_detail(pypy=True): + raise unittest.SkipTest("pypy won't load lone .pyc files") with temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') compiled_name = compile_script(script_name) @@ -176,6 +178,8 @@ class CmdLineTest(unittest.TestCase): script_name, 'test_pkg') def test_package_compiled(self): + if test.test_support.check_impl_detail(pypy=True): + raise unittest.SkipTest("pypy won't load lone .pyc files") with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') make_pkg(pkg_dir) diff -r 63bbe9f80909 Lib/test/test_code.py --- a/Lib/test/test_code.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_code.py Tue Sep 15 13:09:43 2015 +0300 @@ -75,7 +75,7 @@ varnames: () cellvars: () freevars: () nlocals: 0 -flags: 67 +flags: 1048643 consts: ("'doc string'", 'None') """ @@ -83,6 +83,7 @@ consts: ("'doc string'", 'None') import unittest import weakref from test.test_support import run_doctest, run_unittest, cpython_only +from test.test_support import gc_collect def consts(t): @@ -134,6 +135,7 @@ class CodeWeakRefTest(unittest.TestCase) coderef = weakref.ref(f.__code__, callback) self.assertTrue(bool(coderef())) del f + gc_collect() self.assertFalse(bool(coderef())) self.assertTrue(self.called) diff -r 63bbe9f80909 Lib/test/test_codeop.py --- a/Lib/test/test_codeop.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_codeop.py Tue Sep 15 13:09:43 2015 +0300 @@ -3,7 +3,7 @@ Nick Mathewson """ import unittest -from test.test_support import run_unittest, is_jython +from test.test_support import run_unittest, is_jython, check_impl_detail from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT @@ -270,7 +270,9 @@ class CodeopTests(unittest.TestCase): ai("a = 'a\\\n") ai("a = 1","eval") - ai("a = (","eval") + if check_impl_detail(): # on PyPy it asks for more data, which is not + ai("a = (","eval") # completely correct but hard to fix and + # really a detail (in my opinion ) ai("]","eval") ai("())","eval") ai("[}","eval") diff -r 63bbe9f80909 Lib/test/test_coercion.py --- a/Lib/test/test_coercion.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_coercion.py Tue Sep 15 13:09:43 2015 +0300 @@ -1,6 +1,7 @@ import copy import unittest -from test.test_support import run_unittest, TestFailed, check_warnings +from test.test_support import ( + run_unittest, TestFailed, check_warnings, check_impl_detail) # Fake a number that implements numeric methods through __coerce__ @@ -306,12 +307,18 @@ class CoercionTest(unittest.TestCase): self.assertNotEqual(cmp(u'fish', evil_coercer), 0) self.assertNotEqual(cmp(slice(1), evil_coercer), 0) # ...but that this still works - class WackyComparer(object): - def __cmp__(slf, other): - self.assertTrue(other == 42, 'expected evil_coercer, got %r' % other) - return 0 - __hash__ = None # Invalid cmp makes this unhashable - self.assertEqual(cmp(WackyComparer(), evil_coercer), 0) + if check_impl_detail(): + # NB. I (arigo) would consider the following as implementation- + # specific. For example, in CPython, if we replace 42 with 42.0 + # both below and in CoerceTo() above, then the test fails. This + # hints that the behavior is really dependent on some obscure + # internal details. + class WackyComparer(object): + def __cmp__(slf, other): + self.assertTrue(other == 42, 'expected evil_coercer, got %r' % other) + return 0 + __hash__ = None # Invalid cmp makes this unhashable + self.assertEqual(cmp(WackyComparer(), evil_coercer), 0) # ...and classic classes too, since that code path is a little different class ClassicWackyComparer: def __cmp__(slf, other): diff -r 63bbe9f80909 Lib/test/test_collections.py --- a/Lib/test/test_collections.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_collections.py Tue Sep 15 13:09:43 2015 +0300 @@ -579,7 +579,12 @@ class TestCollectionABCs(ABCTestCase): def __repr__(self): return "MySet(%s)" % repr(list(self)) s = MySet([5,43,2,1]) - self.assertEqual(s.pop(), 1) + # changed from CPython 2.7: it was "s.pop() == 1" but I see + # nothing that guarantees a particular order here. In the + # 'all_ordered_dicts' branch of PyPy (or with OrderedDict + # instead of sets), it consistently returns 5, but this test + # should not rely on this or any other order. + self.assert_(s.pop() in [5,43,2,1]) def test_issue8750(self): empty = WithSet() @@ -1156,6 +1161,16 @@ class TestOrderedDict(unittest.TestCase) od.popitem() self.assertEqual(len(od), 0) + def test_popitem_first(self): + pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] + shuffle(pairs) + od = OrderedDict(pairs) + while pairs: + self.assertEqual(od.popitem(last=False), pairs.pop(0)) + with self.assertRaises(KeyError): + od.popitem(last=False) + self.assertEqual(len(od), 0) + def test_pop(self): pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) @@ -1227,7 +1242,11 @@ class TestOrderedDict(unittest.TestCase) od = OrderedDict(pairs) # yaml.dump(od) --> # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n' - self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1])) + + # PyPy bug fix: added [0] at the end of this line, because the + # test is really about the 2-tuples that need to be 2-lists + # inside the list of 6 of them + self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1][0])) def test_reduce_not_too_fat(self): # do not save instance dictionary if not needed @@ -1237,6 +1256,16 @@ class TestOrderedDict(unittest.TestCase) od.x = 10 self.assertEqual(len(od.__reduce__()), 3) + def test_reduce_exact_output(self): + # PyPy: test that __reduce__() produces the exact same answer as + # CPython does, even though in the 'all_ordered_dicts' branch we + # have to emulate it. + pairs = [['c', 1], ['b', 2], ['d', 4]] + od = OrderedDict(pairs) + self.assertEqual(od.__reduce__(), (OrderedDict, (pairs,))) + od.x = 10 + self.assertEqual(od.__reduce__(), (OrderedDict, (pairs,), {'x': 10})) + def test_repr(self): od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]) self.assertEqual(repr(od), diff -r 63bbe9f80909 Lib/test/test_compile.py --- a/Lib/test/test_compile.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_compile.py Tue Sep 15 13:09:43 2015 +0300 @@ -4,6 +4,7 @@ import sys import _ast from test import test_support import textwrap +from test.test_support import check_impl_detail class TestSpecifics(unittest.TestCase): @@ -140,12 +141,13 @@ def g(): self.assertEqual(m.results, ('z', g)) exec 'z = locals()' in g, m self.assertEqual(m.results, ('z', m)) - try: - exec 'z = b' in m - except TypeError: - pass - else: - self.fail('Did not validate globals as a real dict') + if check_impl_detail(): + try: + exec 'z = b' in m + except TypeError: + pass + else: + self.fail('Did not validate globals as a real dict') class A: "Non-mapping" diff -r 63bbe9f80909 Lib/test/test_copy.py --- a/Lib/test/test_copy.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_copy.py Tue Sep 15 13:09:43 2015 +0300 @@ -637,6 +637,7 @@ class TestCopy(unittest.TestCase): self.assertEqual(v[c], d) self.assertEqual(len(v), 2) del c, d + test_support.gc_collect() self.assertEqual(len(v), 1) x, y = C(), C() # The underlying containers are decoupled @@ -666,6 +667,7 @@ class TestCopy(unittest.TestCase): self.assertEqual(v[a].i, b.i) self.assertEqual(v[c].i, d.i) del c + test_support.gc_collect() self.assertEqual(len(v), 1) def test_deepcopy_weakvaluedict(self): @@ -689,6 +691,7 @@ class TestCopy(unittest.TestCase): self.assertTrue(t is d) del x, y, z, t del d + test_support.gc_collect() self.assertEqual(len(v), 1) def test_deepcopy_bound_method(self): diff -r 63bbe9f80909 Lib/test/test_cpickle.py --- a/Lib/test/test_cpickle.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_cpickle.py Tue Sep 15 13:09:43 2015 +0300 @@ -132,27 +132,27 @@ class cPickleFastPicklerTests(AbstractPi error = cPickle.BadPickleGet def test_recursive_list(self): - self.assertRaises(ValueError, + self.assertRaises((ValueError, RuntimeError), AbstractPickleTests.test_recursive_list, self) def test_recursive_tuple(self): - self.assertRaises(ValueError, + self.assertRaises((ValueError, RuntimeError), AbstractPickleTests.test_recursive_tuple, self) def test_recursive_inst(self): - self.assertRaises(ValueError, + self.assertRaises((ValueError, RuntimeError), AbstractPickleTests.test_recursive_inst, self) def test_recursive_dict(self): - self.assertRaises(ValueError, + self.assertRaises((ValueError, RuntimeError), AbstractPickleTests.test_recursive_dict, self) def test_recursive_multi(self): - self.assertRaises(ValueError, + self.assertRaises((ValueError, RuntimeError), AbstractPickleTests.test_recursive_multi, self) diff -r 63bbe9f80909 Lib/test/test_csv.py --- a/Lib/test/test_csv.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_csv.py Tue Sep 15 13:09:43 2015 +0300 @@ -20,7 +20,8 @@ class Test_Csv(unittest.TestCase): """ def _test_arg_valid(self, ctor, arg): self.assertRaises(TypeError, ctor) - self.assertRaises(TypeError, ctor, None) + # PyPy gets an AttributeError instead of a TypeError + self.assertRaises((TypeError, AttributeError), ctor, None) self.assertRaises(TypeError, ctor, arg, bad_attr = 0) self.assertRaises(TypeError, ctor, arg, delimiter = 0) self.assertRaises(TypeError, ctor, arg, delimiter = 'XX') @@ -54,10 +55,13 @@ class Test_Csv(unittest.TestCase): self.assertEqual(obj.dialect.skipinitialspace, False) self.assertEqual(obj.dialect.strict, False) # Try deleting or changing attributes (they are read-only) - self.assertRaises(TypeError, delattr, obj.dialect, 'delimiter') - self.assertRaises(TypeError, setattr, obj.dialect, 'delimiter', ':') + self.assertRaises((TypeError, AttributeError), delattr, obj.dialect, + 'delimiter') + self.assertRaises((TypeError, AttributeError), setattr, obj.dialect, + 'delimiter', ':') self.assertRaises(AttributeError, delattr, obj.dialect, 'quoting') - self.assertRaises(AttributeError, setattr, obj.dialect, + # PyPy gets a TypeError instead of an AttributeError + self.assertRaises((AttributeError, TypeError), setattr, obj.dialect, 'quoting', None) def test_reader_attrs(self): @@ -144,7 +148,8 @@ class Test_Csv(unittest.TestCase): os.unlink(name) def test_write_arg_valid(self): - self._write_error_test(csv.Error, None) + # PyPy gets a TypeError instead of a csv.Error for "not a sequence" + self._write_error_test((csv.Error, TypeError), None) self._write_test((), '') self._write_test([None], '""') self._write_error_test(csv.Error, [None], quoting = csv.QUOTE_NONE) @@ -895,7 +900,7 @@ class TestDialectValidity(unittest.TestC with self.assertRaises(csv.Error) as cm: mydialect() self.assertEqual(str(cm.exception), - '"quotechar" must be an 1-character string') + '"quotechar" must be a 1-character string') mydialect.quotechar = 4 with self.assertRaises(csv.Error) as cm: @@ -918,13 +923,13 @@ class TestDialectValidity(unittest.TestC with self.assertRaises(csv.Error) as cm: mydialect() self.assertEqual(str(cm.exception), - '"delimiter" must be an 1-character string') + '"delimiter" must be a 1-character string') mydialect.delimiter = "" with self.assertRaises(csv.Error) as cm: mydialect() self.assertEqual(str(cm.exception), - '"delimiter" must be an 1-character string') + '"delimiter" must be a 1-character string') mydialect.delimiter = u"," with self.assertRaises(csv.Error) as cm: diff -r 63bbe9f80909 Lib/test/test_deque.py --- a/Lib/test/test_deque.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_deque.py Tue Sep 15 13:09:43 2015 +0300 @@ -110,7 +110,7 @@ class TestBasic(unittest.TestCase): self.assertEqual(deque('abc', maxlen=4).maxlen, 4) self.assertEqual(deque('abc', maxlen=2).maxlen, 2) self.assertEqual(deque('abc', maxlen=0).maxlen, 0) - with self.assertRaises(AttributeError): + with self.assertRaises((AttributeError, TypeError)): d = deque('abc') d.maxlen = 10 @@ -353,7 +353,10 @@ class TestBasic(unittest.TestCase): for match in (True, False): d = deque(['ab']) d.extend([MutateCmp(d, match), 'c']) - self.assertRaises(IndexError, d.remove, 'c') + # On CPython we get IndexError: deque mutated during remove(). + # Why is it an IndexError during remove() only??? + # On PyPy it is a RuntimeError, as in the other operations. + self.assertRaises((IndexError, RuntimeError), d.remove, 'c') self.assertEqual(d, deque()) def test_repr(self): @@ -515,7 +518,7 @@ class TestBasic(unittest.TestCase): container = reversed(deque([obj, 1])) obj.x = iter(container) del obj, container - gc.collect() + test_support.gc_collect() self.assertTrue(ref() is None, "Cycle was not collected") check_sizeof = test_support.check_sizeof @@ -648,6 +651,7 @@ class TestSubclass(unittest.TestCase): p = weakref.proxy(d) self.assertEqual(str(p), str(d)) d = None + test_support.gc_collect() self.assertRaises(ReferenceError, str, p) def test_strange_subclass(self): diff -r 63bbe9f80909 Lib/test/test_descr.py --- a/Lib/test/test_descr.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_descr.py Tue Sep 15 13:09:43 2015 +0300 @@ -3,6 +3,7 @@ import gc import sys import types import unittest +import popen2 # trigger early the warning from popen2.py import weakref from copy import deepcopy @@ -1138,7 +1139,7 @@ order (MRO) for bases """ self.assertEqual(Counted.counter, 0) # Test lookup leaks [SF bug 572567] - if hasattr(gc, 'get_objects'): + if test_support.check_impl_detail(): class G(object): def __cmp__(self, other): return 0 @@ -1767,6 +1768,10 @@ order (MRO) for bases """ raise MyException for name, runner, meth_impl, ok, env in specials: + if name == '__length_hint__' or name == '__sizeof__': + if not test_support.check_impl_detail(): + continue + class X(Checker): pass for attr, obj in env.iteritems(): @@ -2006,7 +2011,9 @@ order (MRO) for bases """ except TypeError, msg: self.assertIn("weak reference", str(msg)) else: - self.fail("weakref.ref(no) should be illegal") + if test_support.check_impl_detail(pypy=False): + self.fail("weakref.ref(no) should be illegal") + #else: pypy supports taking weakrefs to some more objects class Weak(object): __slots__ = ['foo', '__weakref__'] yes = Weak() @@ -3126,7 +3133,16 @@ order (MRO) for bases """ class R(J): __slots__ = ["__dict__", "__weakref__"] - for cls, cls2 in ((G, H), (G, I), (I, H), (Q, R), (R, Q)): + if test_support.check_impl_detail(pypy=False): + lst = ((G, H), (G, I), (I, H), (Q, R), (R, Q)) + else: + # Not supported in pypy: changing the __class__ of an object + # to another __class__ that just happens to have the same slots. + # If needed, we can add the feature, but what we'll likely do + # then is to allow mostly any __class__ assignment, even if the + # classes have different __slots__, because we it's easier. + lst = ((Q, R), (R, Q)) + for cls, cls2 in lst: x = cls() x.a = 1 x.__class__ = cls2 @@ -3146,7 +3162,8 @@ order (MRO) for bases """ # Issue5283: when __class__ changes in __del__, the wrong # type gets DECREF'd. class O(object): - pass + def __del__(self): + pass class A(object): def __del__(self): self.__class__ = O @@ -3209,7 +3226,8 @@ order (MRO) for bases """ except TypeError: pass else: - self.fail("%r's __dict__ can be modified" % cls) + if test_support.check_impl_detail(pypy=False): + self.fail("%r's __dict__ can be modified" % cls) # Modules also disallow __dict__ assignment class Module1(types.ModuleType, Base): @@ -3613,6 +3631,9 @@ order (MRO) for bases """ list.__init__(a, sequence=[0, 1, 2]) self.assertEqual(a, [0, 1, 2]) + @unittest.skipIf(test_support.check_impl_detail(pypy=True) and + sys.platform == 'win32', + "XXX: https://bugs.pypy.org/issue1461") def test_recursive_call(self): # Testing recursive __call__() by setting to instance of class... class A(object): @@ -4436,7 +4457,7 @@ order (MRO) for bases """ self.assertNotEqual(l.__add__, [5].__add__) self.assertNotEqual(l.__add__, l.__mul__) self.assertEqual(l.__add__.__name__, '__add__') - if hasattr(l.__add__, '__self__'): + if hasattr(l.__add__, '__objclass__'): # CPython self.assertIs(l.__add__.__self__, l) self.assertIs(l.__add__.__objclass__, list) @@ -4633,8 +4654,12 @@ order (MRO) for bases """ str.split(fake_str) # call a slot wrapper descriptor - with self.assertRaises(TypeError): - str.__add__(fake_str, "abc") + try: + r = str.__add__(fake_str, "abc") + except TypeError: + pass + else: + self.assertEqual(r, NotImplemented) def test_repr_as_str(self): # Issue #11603: crash or infinite loop when rebinding __str__ as @@ -4676,7 +4701,8 @@ class DictProxyTests(unittest.TestCase): self.C = C def test_repr(self): - self.assertIn('dict_proxy({', repr(vars(self.C))) + if test_support.check_impl_detail(): + self.assertIn('dict_proxy({', repr(vars(self.C))) self.assertIn("'meth':", repr(vars(self.C))) def test_iter_keys(self): diff -r 63bbe9f80909 Lib/test/test_descrtut.py --- a/Lib/test/test_descrtut.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_descrtut.py Tue Sep 15 13:09:43 2015 +0300 @@ -172,46 +172,12 @@ Under the new proposal, the __methods__ AttributeError: 'list' object has no attribute '__methods__' >>> -Instead, you can get the same information from the list type: +Instead, you can get the same information from the list type +(the following example filters out the numerous method names +starting with '_'): - >>> pprint.pprint(dir(list)) # like list.__dict__.keys(), but sorted - ['__add__', - '__class__', - '__contains__', - '__delattr__', - '__delitem__', - '__delslice__', - '__doc__', - '__eq__', - '__format__', - '__ge__', - '__getattribute__', - '__getitem__', - '__getslice__', - '__gt__', - '__hash__', - '__iadd__', - '__imul__', - '__init__', - '__iter__', - '__le__', - '__len__', - '__lt__', - '__mul__', - '__ne__', - '__new__', - '__reduce__', - '__reduce_ex__', - '__repr__', - '__reversed__', - '__rmul__', - '__setattr__', - '__setitem__', - '__setslice__', - '__sizeof__', - '__str__', - '__subclasshook__', - 'append', + >>> pprint.pprint([name for name in dir(list) if not name.startswith('_')]) + ['append', 'count', 'extend', 'index', diff -r 63bbe9f80909 Lib/test/test_dict.py --- a/Lib/test/test_dict.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_dict.py Tue Sep 15 13:09:43 2015 +0300 @@ -349,7 +349,8 @@ class DictTest(unittest.TestCase): self.assertEqual(va, int(ka)) kb, vb = tb = b.popitem() self.assertEqual(vb, int(kb)) - self.assertFalse(copymode < 0 and ta != tb) + if test_support.check_impl_detail(): + self.assertFalse(copymode < 0 and ta != tb) self.assertFalse(a) self.assertFalse(b) diff -r 63bbe9f80909 Lib/test/test_dis.py --- a/Lib/test/test_dis.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_dis.py Tue Sep 15 13:09:43 2015 +0300 @@ -53,25 +53,26 @@ def bug1333982(x=[]): pass dis_bug1333982 = """\ - %-4d 0 LOAD_CONST 1 (0) - 3 POP_JUMP_IF_TRUE 41 - 6 LOAD_GLOBAL 0 (AssertionError) - 9 BUILD_LIST 0 + %-4d 0 JUMP_IF_NOT_DEBUG 41 (to 44) + 3 LOAD_CONST 1 (0) + 6 POP_JUMP_IF_TRUE 44 + 9 LOAD_GLOBAL 0 (AssertionError) 12 LOAD_FAST 0 (x) - 15 GET_ITER - >> 16 FOR_ITER 12 (to 31) - 19 STORE_FAST 1 (s) - 22 LOAD_FAST 1 (s) - 25 LIST_APPEND 2 - 28 JUMP_ABSOLUTE 16 + 15 BUILD_LIST_FROM_ARG 0 + 18 GET_ITER + >> 19 FOR_ITER 12 (to 34) + 22 STORE_FAST 1 (s) + 25 LOAD_FAST 1 (s) + 28 LIST_APPEND 2 + 31 JUMP_ABSOLUTE 19 - %-4d >> 31 LOAD_CONST 2 (1) - 34 BINARY_ADD - 35 CALL_FUNCTION 1 - 38 RAISE_VARARGS 1 + %-4d >> 34 LOAD_CONST 2 (1) + 37 BINARY_ADD + 38 CALL_FUNCTION 1 + 41 RAISE_VARARGS 1 - %-4d >> 41 LOAD_CONST 0 (None) - 44 RETURN_VALUE + %-4d >> 44 LOAD_CONST 0 (None) + 47 RETURN_VALUE """%(bug1333982.func_code.co_firstlineno + 1, bug1333982.func_code.co_firstlineno + 2, bug1333982.func_code.co_firstlineno + 3) diff -r 63bbe9f80909 Lib/test/test_doctest.py --- a/Lib/test/test_doctest.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_doctest.py Tue Sep 15 13:09:43 2015 +0300 @@ -841,7 +841,7 @@ replaced with any other string: ... >>> x = 12 ... >>> print x//0 ... Traceback (most recent call last): - ... ZeroDivisionError: integer division or modulo by zero + ... ZeroDivisionError: integer division by zero ... ''' >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) @@ -858,7 +858,7 @@ unexpected exception: ... >>> print 'pre-exception output', x//0 ... pre-exception output ... Traceback (most recent call last): - ... ZeroDivisionError: integer division or modulo by zero + ... ZeroDivisionError: integer division by zero ... ''' >>> test = doctest.DocTestFinder().find(f)[0] >>> doctest.DocTestRunner(verbose=False).run(test) @@ -869,7 +869,7 @@ unexpected exception: print 'pre-exception output', x//0 Exception raised: ... - ZeroDivisionError: integer division or modulo by zero + ZeroDivisionError: integer division by zero TestResults(failed=1, attempted=2) Exception messages may contain newlines: @@ -1064,7 +1064,7 @@ unexpected exception: Exception raised: Traceback (most recent call last): ... - ZeroDivisionError: integer division or modulo by zero + ZeroDivisionError: integer division by zero TestResults(failed=1, attempted=1) """ def displayhook(): r""" @@ -2010,7 +2010,7 @@ def test_pdb_set_trace_nested(): > (1)() -> calls_set_trace() (Pdb) print foo - *** NameError: name 'foo' is not defined + *** NameError: global name 'foo' is not defined (Pdb) continue TestResults(failed=0, attempted=2) """ @@ -2340,7 +2340,7 @@ def test_unittest_reportflags(): favorite_color Exception raised: ... - NameError: name 'favorite_color' is not defined + NameError: global name 'favorite_color' is not defined @@ -2400,7 +2400,7 @@ We don't want `-v` in sys.argv for these favorite_color Exception raised: ... - NameError: name 'favorite_color' is not defined + NameError: global name 'favorite_color' is not defined ********************************************************************** 1 items had failures: 1 of 2 in test_doctest.txt @@ -2493,7 +2493,7 @@ parameter: favorite_color Exception raised: ... - NameError: name 'favorite_color' is not defined + NameError: global name 'favorite_color' is not defined TestResults(failed=1, attempted=2) >>> doctest.master = None # Reset master. diff -r 63bbe9f80909 Lib/test/test_dumbdbm.py --- a/Lib/test/test_dumbdbm.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_dumbdbm.py Tue Sep 15 13:09:43 2015 +0300 @@ -104,9 +104,11 @@ class DumbDBMTestCase(unittest.TestCase) f.close() # Mangle the file by adding \r before each newline - data = open(_fname + '.dir').read() + with open(_fname + '.dir') as f: + data = f.read() data = data.replace('\n', '\r\n') - open(_fname + '.dir', 'wb').write(data) + with open(_fname + '.dir', 'wb') as f: + f.write(data) f = dumbdbm.open(_fname) self.assertEqual(f['1'], 'hello') diff -r 63bbe9f80909 Lib/test/test_extcall.py --- a/Lib/test/test_extcall.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_extcall.py Tue Sep 15 13:09:43 2015 +0300 @@ -90,19 +90,19 @@ Verify clearing of SF bug #733667 >>> class Nothing: pass ... - >>> g(*Nothing()) + >>> g(*Nothing()) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: g() argument after * must be a sequence, not instance + TypeError: ...argument after * must be a sequence, not instance >>> class Nothing: ... def __len__(self): return 5 ... - >>> g(*Nothing()) + >>> g(*Nothing()) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: g() argument after * must be a sequence, not instance + TypeError: ...argument after * must be a sequence, not instance >>> class Nothing(): ... def __len__(self): return 5 @@ -154,52 +154,50 @@ What about willful misconduct? ... TypeError: g() got multiple values for keyword argument 'x' - >>> f(**{1:2}) + >>> f(**{1:2}) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: f() keywords must be strings + TypeError: ...keywords must be strings >>> h(**{'e': 2}) Traceback (most recent call last): ... TypeError: h() got an unexpected keyword argument 'e' - >>> h(*h) + >>> h(*h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: h() argument after * must be a sequence, not function + TypeError: ...argument after * must be a sequence, not function - >>> dir(*h) + >>> dir(*h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: dir() argument after * must be a sequence, not function + TypeError: ...argument after * must be a sequence, not function - >>> None(*h) + >>> None(*h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: NoneType object argument after * must be a sequence, \ -not function + TypeError: ...argument after * must be a sequence, not function - >>> h(**h) + >>> h(**h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: h() argument after ** must be a mapping, not function + TypeError: ...argument after ** must be a mapping, not function - >>> dir(**h) + >>> dir(**h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: dir() argument after ** must be a mapping, not function + TypeError: ...argument after ** must be a mapping, not function - >>> None(**h) + >>> None(**h) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: NoneType object argument after ** must be a mapping, \ -not function + TypeError: ...argument after ** must be a mapping, not function - >>> dir(b=1, **{'b': 1}) + >>> dir(b=1, **{'b': 1}) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: dir() got multiple values for keyword argument 'b' + TypeError: ...got multiple values for keyword argument 'b' Another helper function @@ -247,10 +245,10 @@ TypeError if te dictionary is not empty ... False True - >>> id(1, **{'foo': 1}) + >>> id(1, **{'foo': 1}) #doctest: +ELLIPSIS Traceback (most recent call last): ... - TypeError: id() takes no keyword arguments + TypeError: id() ... keyword argument... A corner case of keyword dictionary items being deleted during the function call setup. See . diff -r 63bbe9f80909 Lib/test/test_file.py --- a/Lib/test/test_file.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_file.py Tue Sep 15 13:09:43 2015 +0300 @@ -12,7 +12,7 @@ from weakref import proxy import io import _pyio as pyio -from test.test_support import TESTFN, run_unittest +from test.test_support import TESTFN, run_unittest, gc_collect from UserList import UserList class AutoFileTests(unittest.TestCase): @@ -33,6 +33,7 @@ class AutoFileTests(unittest.TestCase): self.assertEqual(self.f.tell(), p.tell()) self.f.close() self.f = None + gc_collect() self.assertRaises(ReferenceError, getattr, p, 'tell') def testAttributes(self): diff -r 63bbe9f80909 Lib/test/test_file2k.py --- a/Lib/test/test_file2k.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_file2k.py Tue Sep 15 13:09:43 2015 +0300 @@ -15,7 +15,7 @@ except ImportError: threading = None from test import test_support -from test.test_support import TESTFN, run_unittest, requires +from test.test_support import TESTFN, run_unittest, gc_collect, requires from UserList import UserList class AutoFileTests(unittest.TestCase): @@ -36,6 +36,7 @@ class AutoFileTests(unittest.TestCase): self.assertEqual(self.f.tell(), p.tell()) self.f.close() self.f = None + gc_collect() self.assertRaises(ReferenceError, getattr, p, 'tell') def testAttributes(self): @@ -134,8 +135,12 @@ class AutoFileTests(unittest.TestCase): for methodname in methods: method = getattr(self.f, methodname) + args = {'readinto': (bytearray(''),), + 'seek': (0,), + 'write': ('',), + }.get(methodname, ()) # should raise on closed file - self.assertRaises(ValueError, method) + self.assertRaises(ValueError, method, *args) with test_support.check_py3k_warnings(): for methodname in deprecated_methods: method = getattr(self.f, methodname) @@ -165,6 +170,7 @@ class AutoFileTests(unittest.TestCase): # Remark: Do not perform more than one test per open file, # since that does NOT catch the readline error on Windows. data = 'xxx' + self.f.close() for mode in ['w', 'wb', 'a', 'ab']: for attr in ['read', 'readline', 'readlines']: self.f = open(TESTFN, mode) @@ -360,8 +366,9 @@ class OtherFileTests(unittest.TestCase): except ValueError: pass else: - self.fail("%s%r after next() didn't raise ValueError" % - (methodname, args)) + if test_support.check_impl_detail(): + self.fail("%s%r after next() didn't raise ValueError" % + (methodname, args)) f.close() # Test to see if harmless (by accident) mixing of read* and @@ -412,6 +419,7 @@ class OtherFileTests(unittest.TestCase): if lines != testlines: self.fail("readlines() after next() with empty buffer " "failed. Got %r, expected %r" % (line, testline)) + f.close() # Reading after iteration hit EOF shouldn't hurt either f = open(TESTFN) try: @@ -496,6 +504,9 @@ class FileThreadingTests(unittest.TestCa self.close_count = 0 self.close_success_count = 0 self.use_buffering = False + # to prevent running out of file descriptors on PyPy, + # we only keep the 50 most recent files open + self.all_files = [None] * 50 def tearDown(self): if self.f: @@ -514,6 +525,10 @@ class FileThreadingTests(unittest.TestCa self.f = open(self.filename, "w+", buffering=1024*16) else: self.f = open(self.filename, "w+") + self.all_files.append(self.f) + oldf = self.all_files.pop(0) + if oldf is not None: + oldf.close() def _close_file(self): with self._count_lock: @@ -554,7 +569,6 @@ class FileThreadingTests(unittest.TestCa def _test_close_open_io(self, io_func, nb_workers=5): def worker(): - self._create_file() funcs = itertools.cycle(( lambda: io_func(), lambda: self._close_and_reopen_file(), @@ -566,7 +580,11 @@ class FileThreadingTests(unittest.TestCa f() except (IOError, ValueError): pass + self._create_file() self._run_workers(worker, nb_workers) + # make sure that all files can be closed now + del self.all_files + gc_collect() if test_support.verbose: # Useful verbose statistics when tuning this test to take # less time to run but still ensuring that its still useful. diff -r 63bbe9f80909 Lib/test/test_fileio.py --- a/Lib/test/test_fileio.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_fileio.py Tue Sep 15 13:09:43 2015 +0300 @@ -13,6 +13,7 @@ from UserList import UserList from test.test_support import TESTFN, check_warnings, run_unittest, make_bad_fd from test.test_support import py3k_bytes as bytes, cpython_only +from test.test_support import gc_collect from test.script_helper import run_python from _io import FileIO as _FileIO @@ -35,6 +36,7 @@ class AutoFileTests(unittest.TestCase): self.assertEqual(self.f.tell(), p.tell()) self.f.close() self.f = None + gc_collect() self.assertRaises(ReferenceError, getattr, p, 'tell') def testSeekTell(self): @@ -138,12 +140,16 @@ class AutoFileTests(unittest.TestCase): method = getattr(self.f, methodname) # should raise on closed file self.assertRaises(ValueError, method) + # methods with one argument + self.assertRaises(ValueError, self.f.readinto, 0) + self.assertRaises(ValueError, self.f.write, 0) + self.assertRaises(ValueError, self.f.seek, 0) - self.assertRaises(ValueError, self.f.readinto) # XXX should be TypeError? + self.assertRaises(TypeError, self.f.readinto) self.assertRaises(ValueError, self.f.readinto, bytearray(1)) - self.assertRaises(ValueError, self.f.seek) + self.assertRaises(TypeError, self.f.seek) self.assertRaises(ValueError, self.f.seek, 0) - self.assertRaises(ValueError, self.f.write) + self.assertRaises(TypeError, self.f.write) self.assertRaises(ValueError, self.f.write, b'') self.assertRaises(TypeError, self.f.writelines) self.assertRaises(ValueError, self.f.writelines, b'') diff -r 63bbe9f80909 Lib/test/test_format.py --- a/Lib/test/test_format.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_format.py Tue Sep 15 13:09:43 2015 +0300 @@ -252,7 +252,7 @@ class FormatTest(unittest.TestCase): try: testformat(formatstr, args) except exception, exc: - if str(exc) == excmsg: + if str(exc) == excmsg or not test_support.check_impl_detail(): if verbose: print "yes" else: @@ -282,13 +282,16 @@ class FormatTest(unittest.TestCase): test_exc(u'no format', u'1', TypeError, "not all arguments converted during string formatting") - class Foobar(long): - def __oct__(self): - # Returning a non-string should not blow up. - return self + 1 - - test_exc('%o', Foobar(), TypeError, - "expected string or Unicode object, long found") + if test_support.check_impl_detail(): + # __oct__() is called if Foobar inherits from 'long', but + # not, say, 'object' or 'int' or 'str'. This seems strange + # enough to consider it a complete implementation detail. + class Foobar(long): + def __oct__(self): + # Returning a non-string should not blow up. + return self + 1 + test_exc('%o', Foobar(), TypeError, + "expected string or Unicode object, long found") if maxsize == 2**31-1: # crashes 2.2.1 and earlier: diff -r 63bbe9f80909 Lib/test/test_funcattrs.py --- a/Lib/test/test_funcattrs.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_funcattrs.py Tue Sep 15 13:09:43 2015 +0300 @@ -14,6 +14,8 @@ class FuncAttrsTest(unittest.TestCase): self.b = b def cannot_set_attr(self, obj, name, value, exceptions): + if not test_support.check_impl_detail(): + exceptions = (TypeError, AttributeError) # Helper method for other tests. try: setattr(obj, name, value) @@ -286,13 +288,13 @@ class FunctionDictsTest(FuncAttrsTest): def test_delete_func_dict(self): try: del self.b.__dict__ - except TypeError: + except (AttributeError, TypeError): pass else: self.fail("deleting function dictionary should raise TypeError") try: del self.b.func_dict - except TypeError: + except (AttributeError, TypeError): pass else: self.fail("deleting function dictionary should raise TypeError") diff -r 63bbe9f80909 Lib/test/test_functools.py --- a/Lib/test/test_functools.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_functools.py Tue Sep 15 13:09:43 2015 +0300 @@ -43,9 +43,9 @@ class TestPartial(unittest.TestCase): self.assertEqual(p.args, (1, 2)) self.assertEqual(p.keywords, dict(a=10, b=20)) # attributes should not be writable - self.assertRaises(TypeError, setattr, p, 'func', map) - self.assertRaises(TypeError, setattr, p, 'args', (1, 2)) - self.assertRaises(TypeError, setattr, p, 'keywords', dict(a=1, b=2)) + self.assertRaises((TypeError, AttributeError), setattr, p, 'func', map) + self.assertRaises((TypeError, AttributeError), setattr, p, 'args', (1, 2)) + self.assertRaises((TypeError, AttributeError), setattr, p, 'keywords', dict(a=1, b=2)) p = self.thetype(hex) try: @@ -136,6 +136,7 @@ class TestPartial(unittest.TestCase): p = proxy(f) self.assertEqual(f.func, p.func) f = None + test_support.gc_collect() self.assertRaises(ReferenceError, getattr, p, 'func') def test_with_bound_and_unbound_methods(self): @@ -153,6 +154,7 @@ class TestPartial(unittest.TestCase): self.assertEqual(signature(f), signature(f_copy)) # Issue 6083: Reference counting bug + @unittest.skipUnless(test_support.check_impl_detail(), "ref counting") def test_setstate_refcount(self): class BadSequence: def __len__(self): @@ -193,7 +195,7 @@ class TestUpdateWrapper(unittest.TestCas updated=functools.WRAPPER_UPDATES): # Check attributes were assigned for name in assigned: - self.assertTrue(getattr(wrapper, name) is getattr(wrapped, name)) + self.assertTrue(getattr(wrapper, name) == getattr(wrapped, name), name) # Check attributes were updated for name in updated: wrapper_attr = getattr(wrapper, name) diff -r 63bbe9f80909 Lib/test/test_gdbm.py --- a/Lib/test/test_gdbm.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_gdbm.py Tue Sep 15 13:09:43 2015 +0300 @@ -74,6 +74,40 @@ class TestGdbm(unittest.TestCase): size2 = os.path.getsize(filename) self.assertTrue(size1 > size2 >= size0) + def test_sync(self): + # check if sync works at all, not sure how to check it + self.g = gdbm.open(filename, 'cf') + self.g['x'] = 'x' * 10000 + self.g.sync() + + def test_get_key(self): + self.g = gdbm.open(filename, 'cf') + self.g['x'] = 'x' * 10000 + self.g.close() + self.g = gdbm.open(filename, 'r') + self.assertEquals(self.g['x'], 'x' * 10000) + + def test_key_with_null_bytes(self): + key = 'a\x00b' + value = 'c\x00d' + self.g = gdbm.open(filename, 'cf') + self.g[key] = value + self.g.close() + self.g = gdbm.open(filename, 'r') + self.assertEquals(self.g[key], value) + self.assertTrue(key in self.g) + self.assertTrue(self.g.has_key(key)) + + def test_unicode_key(self): + key = u'ab' + value = u'cd' + self.g = gdbm.open(filename, 'cf') + self.g[key] = value + self.g.close() + self.g = gdbm.open(filename, 'r') + self.assertEquals(self.g[key], value) + self.assertTrue(key in self.g) + self.assertTrue(self.g.has_key(key)) def test_main(): run_unittest(TestGdbm) diff -r 63bbe9f80909 Lib/test/test_generators.py --- a/Lib/test/test_generators.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_generators.py Tue Sep 15 13:09:43 2015 +0300 @@ -190,7 +190,7 @@ Specification: Generators and Exception File "", line 1, in ? File "", line 2, in g File "", line 2, in f - ZeroDivisionError: integer division or modulo by zero + ZeroDivisionError: integer division by zero >>> k.next() # and the generator cannot be resumed Traceback (most recent call last): File "", line 1, in ? @@ -734,14 +734,16 @@ syntax_tests = """ ... yield 1 Traceback (most recent call last): .. -SyntaxError: 'return' with argument inside generator (, line 3) + File "", line 3 +SyntaxError: 'return' with argument inside generator >>> def f(): ... yield 1 ... return 22 Traceback (most recent call last): .. -SyntaxError: 'return' with argument inside generator (, line 3) + File "", line 3 +SyntaxError: 'return' with argument inside generator "return None" is not the same as "return" in a generator: @@ -750,7 +752,8 @@ SyntaxError: 'return' with argument insi ... return None Traceback (most recent call last): .. -SyntaxError: 'return' with argument inside generator (, line 3) + File "", line 3 +SyntaxError: 'return' with argument inside generator These are fine: @@ -879,7 +882,9 @@ These are fine: ... if 0: ... yield 2 # because it's a generator (line 10) Traceback (most recent call last): -SyntaxError: 'return' with argument inside generator (, line 10) + ... + File "", line 10 +SyntaxError: 'return' with argument inside generator This one caused a crash (see SF bug 567538): @@ -1497,6 +1502,8 @@ True """ coroutine_tests = """\ +>>> from test.test_support import gc_collect + Sending a value into a started generator: >>> def f(): @@ -1571,13 +1578,14 @@ SyntaxError: 'yield' outside function >>> def f(): return lambda x=(yield): 1 Traceback (most recent call last): ... -SyntaxError: 'return' with argument inside generator (, line 1) + File "", line 1 +SyntaxError: 'return' with argument inside generator >>> def f(): x = yield = y Traceback (most recent call last): ... File "", line 1 -SyntaxError: assignment to yield expression not possible +SyntaxError: can't assign to yield expression >>> def f(): (yield bar) = y Traceback (most recent call last): @@ -1666,7 +1674,7 @@ ValueError: 7 >>> f().throw("abc") # throw on just-opened generator Traceback (most recent call last): ... -TypeError: exceptions must be classes, or instances, not str +TypeError: exceptions must be old-style classes or derived from BaseException, not str Now let's try closing a generator: @@ -1698,7 +1706,7 @@ And finalization: >>> g = f() >>> g.next() ->>> del g +>>> del g; gc_collect() exiting >>> class context(object): @@ -1709,7 +1717,7 @@ exiting ... yield >>> g = f() >>> g.next() ->>> del g +>>> del g; gc_collect() exiting @@ -1722,7 +1730,7 @@ GeneratorExit is not caught by except Ex >>> g = f() >>> g.next() ->>> del g +>>> del g; gc_collect() finally @@ -1748,6 +1756,7 @@ Our ill-behaved code should be invoked d >>> g = f() >>> g.next() >>> del g +>>> gc_collect() >>> sys.stderr.getvalue().startswith( ... "Exception RuntimeError: 'generator ignored GeneratorExit' in " ... ) @@ -1813,6 +1822,8 @@ Prior to adding cycle-GC support to iter references. We add it to the standard suite so the routine refleak-tests would trigger if it starts being uncleanable again. +>>> from test.test_support import gc_collect + >>> import itertools >>> def leak(): ... class gen: @@ -1864,9 +1875,10 @@ to test. ... ... l = Leaker() ... del l +... gc_collect() ... err = sys.stderr.getvalue().strip() ... err.startswith( -... "Exception RuntimeError: RuntimeError() in <" +... "Exception RuntimeError: RuntimeError() in " ... ) ... err.endswith("> ignored") ... len(err.splitlines()) diff -r 63bbe9f80909 Lib/test/test_genericpath.py --- a/Lib/test/test_genericpath.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_genericpath.py Tue Sep 15 13:09:43 2015 +0300 @@ -260,9 +260,14 @@ class CommonTest(GenericTest): unicwd = u'\xe7w\xf0' try: fsencoding = test_support.TESTFN_ENCODING or "ascii" - unicwd.encode(fsencoding) + asciival = unicwd.encode(fsencoding) + if fsencoding == "mbcs": + # http://bugs.python.org/issue850997 + v = asciival.find('?') + if v >= 0: + raise UnicodeEncodeError(fsencoding, unicwd, v, v, asciival) except (AttributeError, UnicodeEncodeError): - # FS encoding is probably ASCII + # FS encoding is probably ASCII or windows and codepage is non-Latin1 pass else: with test_support.temp_cwd(unicwd): diff -r 63bbe9f80909 Lib/test/test_genexps.py --- a/Lib/test/test_genexps.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_genexps.py Tue Sep 15 13:09:43 2015 +0300 @@ -128,8 +128,9 @@ Verify late binding for the innermost fo Verify re-use of tuples (a side benefit of using genexps over listcomps) + >>> from test.test_support import check_impl_detail >>> tupleids = map(id, ((i,i) for i in xrange(10))) - >>> int(max(tupleids) - min(tupleids)) + >>> int(max(tupleids) - min(tupleids)) if check_impl_detail() else 0 0 Verify that syntax error's are raised for genexps used as lvalues @@ -198,13 +199,13 @@ Verify exception propagation >>> g = (10 // i for i in (5, 0, 2)) >>> g.next() 2 - >>> g.next() + >>> g.next() # doctest: +ELLIPSIS Traceback (most recent call last): File "", line 1, in -toplevel- g.next() File "", line 1, in g = (10 // i for i in (5, 0, 2)) - ZeroDivisionError: integer division or modulo by zero + ZeroDivisionError: integer division...by zero >>> g.next() Traceback (most recent call last): File "", line 1, in -toplevel- diff -r 63bbe9f80909 Lib/test/test_hash.py --- a/Lib/test/test_hash.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_hash.py Tue Sep 15 13:09:43 2015 +0300 @@ -11,6 +11,7 @@ import unittest import subprocess from test import test_support +from test.test_support import impl_detail, check_impl_detail from collections import Hashable IS_64BIT = (struct.calcsize('l') == 8) @@ -150,6 +151,7 @@ class HashRandomizationTests(unittest.Te def get_hash_command(self, repr_): return 'print(hash(%s))' % repr_ + @impl_detail("PyPy does not support hash randomization", pypy=False) def get_hash(self, repr_, seed=None): env = os.environ.copy() if seed is not None: @@ -171,6 +173,11 @@ class HashRandomizationTests(unittest.Te self.assertNotEqual(run1, run2) class StringlikeHashRandomizationTests(HashRandomizationTests): + if check_impl_detail(pypy=True): + EMPTY_STRING_HASH = -1 + else: + EMPTY_STRING_HASH = 0 + def test_null_hash(self): # PYTHONHASHSEED=0 disables the randomized hash if IS_64BIT: @@ -203,20 +210,19 @@ class StrHashRandomizationTests(Stringli repr_ = repr('abc') def test_empty_string(self): - self.assertEqual(hash(""), 0) + self.assertEqual(hash(""), self.EMPTY_STRING_HASH) class UnicodeHashRandomizationTests(StringlikeHashRandomizationTests): repr_ = repr(u'abc') def test_empty_string(self): - self.assertEqual(hash(u""), 0) + self.assertEqual(hash(u""), self.EMPTY_STRING_HASH) class BufferHashRandomizationTests(StringlikeHashRandomizationTests): repr_ = 'buffer("abc")' def test_empty_string(self): - with test_support.check_py3k_warnings(): - self.assertEqual(hash(buffer("")), 0) + self.assertEqual(hash(buffer("")), self.EMPTY_STRING_HASH) class DatetimeTests(HashRandomizationTests): def get_hash_command(self, repr_): diff -r 63bbe9f80909 Lib/test/test_heapq.py --- a/Lib/test/test_heapq.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_heapq.py Tue Sep 15 13:09:43 2015 +0300 @@ -224,6 +224,11 @@ class TestHeap(TestCase): class TestHeapPython(TestHeap): module = py_heapq + def test_islice_protection(self): + m = self.module + self.assertFalse(m.nsmallest(-1, [1])) + self.assertFalse(m.nlargest(-1, [1])) + @skipUnless(c_heapq, 'requires _heapq') class TestHeapC(TestHeap): diff -r 63bbe9f80909 Lib/test/test_import.py --- a/Lib/test/test_import.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_import.py Tue Sep 15 13:09:43 2015 +0300 @@ -12,7 +12,8 @@ import textwrap import shutil from test.test_support import (unlink, TESTFN, unload, run_unittest, rmtree, - is_jython, check_warnings, EnvironmentVarGuard) + is_jython, check_warnings, EnvironmentVarGuard, + impl_detail, check_impl_detail) from test import symlink_support from test import script_helper @@ -85,7 +86,8 @@ class ImportTests(unittest.TestCase): self.assertEqual(mod.b, b, "module loaded (%s) but contents invalid" % mod) finally: - unlink(source) + if check_impl_detail(pypy=False): + unlink(source) try: if not sys.dont_write_bytecode: @@ -162,7 +164,8 @@ class ImportTests(unittest.TestCase): m2 = __import__(TESTFN) self.assertEqual(m2.x, 'rewritten') # Now delete the source file and check the pyc was rewritten - unlink(fname) + if check_impl_detail(pypy=False): + unlink(fname) unload(TESTFN) m3 = __import__(TESTFN) self.assertEqual(m3.x, 'rewritten') @@ -205,13 +208,16 @@ class ImportTests(unittest.TestCase): # Compile & remove .py file, we only need .pyc (or .pyo). with open(filename, 'r') as f: py_compile.compile(filename) - unlink(filename) + if check_impl_detail(pypy=False): + # pypy refuses to import a .pyc if the .py does not exist + unlink(filename) # Need to be able to load from current dir. sys.path.append('') # This used to crash. exec 'import ' + module + reload(longlist) # Cleanup. del sys.path[-1] @@ -459,6 +465,7 @@ func_filename = func.func_code.co_filena self.assertEqual(mod.code_filename, self.file_name) self.assertEqual(mod.func_filename, self.file_name) + @impl_detail("pypy refuses to import without a .py source", pypy=False) def test_module_without_source(self): target = "another_module.py" py_compile.compile(self.file_name, dfile=target) diff -r 63bbe9f80909 Lib/test/test_inspect.py --- a/Lib/test/test_inspect.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_inspect.py Tue Sep 15 13:09:43 2015 +0300 @@ -4,11 +4,11 @@ import types import unittest import inspect import linecache -import datetime from UserList import UserList from UserDict import UserDict from test.test_support import run_unittest, check_py3k_warnings, have_unicode +from test.test_support import check_impl_detail with check_py3k_warnings( ("tuple parameter unpacking has been removed", SyntaxWarning), @@ -77,7 +77,8 @@ class TestPredicates(IsTestBase): def test_excluding_predicates(self): self.istest(inspect.isbuiltin, 'sys.exit') - self.istest(inspect.isbuiltin, '[].append') + if check_impl_detail(): + self.istest(inspect.isbuiltin, '[].append') self.istest(inspect.iscode, 'mod.spam.func_code') self.istest(inspect.isframe, 'tb.tb_frame') self.istest(inspect.isfunction, 'mod.spam') @@ -95,9 +96,9 @@ class TestPredicates(IsTestBase): else: self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals)) if hasattr(types, 'MemberDescriptorType'): - self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days') + self.istest(inspect.ismemberdescriptor, 'type(lambda: None).func_globals') else: - self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days)) + self.assertFalse(inspect.ismemberdescriptor(type(lambda: None).func_globals)) def test_isroutine(self): self.assertTrue(inspect.isroutine(mod.spam)) @@ -678,7 +679,8 @@ class TestGetcallargsFunctions(unittest. else: self.fail('Exception not raised') self.assertIs(type(ex1), type(ex2)) - self.assertEqual(str(ex1), str(ex2)) + if check_impl_detail(): + self.assertEqual(str(ex1), str(ex2)) def makeCallable(self, signature): """Create a function that returns its locals(), excluding the diff -r 63bbe9f80909 Lib/test/test_int.py --- a/Lib/test/test_int.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_int.py Tue Sep 15 13:09:43 2015 +0300 @@ -453,9 +453,10 @@ class IntTestCases(IntLongCommonTests, u try: int(TruncReturnsNonIntegral()) except TypeError as e: - self.assertEqual(str(e), - "__trunc__ returned non-Integral" - " (type NonIntegral)") + if test_support.check_impl_detail(cpython=True): + self.assertEqual(str(e), + "__trunc__ returned non-Integral" + " (type NonIntegral)") else: self.fail("Failed to raise TypeError with %s" % ((base, trunc_result_base),)) diff -r 63bbe9f80909 Lib/test/test_io.py --- a/Lib/test/test_io.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_io.py Tue Sep 15 13:09:43 2015 +0300 @@ -1064,6 +1064,7 @@ class CBufferedReaderTest(BufferedReader support.gc_collect() self.assertIsNone(wr(), wr) + @support.impl_detail(cpython=True) def test_args_error(self): # Issue #17275 with self.assertRaisesRegexp(TypeError, "BufferedReader"): @@ -1369,6 +1370,7 @@ class CBufferedWriterTest(BufferedWriter with self.open(support.TESTFN, "rb") as f: self.assertEqual(f.read(), b"123xxx") + @support.impl_detail(cpython=True) def test_args_error(self): # Issue #17275 with self.assertRaisesRegexp(TypeError, "BufferedWriter"): @@ -1812,6 +1814,7 @@ class CBufferedRandomTest(CBufferedReade CBufferedReaderTest.test_garbage_collection(self) CBufferedWriterTest.test_garbage_collection(self) + @support.impl_detail(cpython=True) def test_args_error(self): # Issue #17275 with self.assertRaisesRegexp(TypeError, "BufferedRandom"): @@ -3057,6 +3060,31 @@ class SignalsTest(unittest.TestCase): """Check that a partial write, when it gets interrupted, properly invokes the signal handler, and bubbles up the exception raised in the latter.""" + + # XXX This test has three flaws that appear when objects are + # XXX not reference counted. + + # - if wio.write() happens to trigger a garbage collection, + # the signal exception may be raised when some __del__ + # method is running; it will not reach the assertRaises() + # call. + + # - more subtle, if the wio object is not destroyed at once + # and survives this function, the next opened file is likely + # to have the same fileno (since the file descriptor was + # actively closed). When wio.__del__ is finally called, it + # will close the other's test file... To trigger this with + # CPython, try adding "global wio" in this function. + + # - This happens only for streams created by the _pyio module, + # because a wio.close() that fails still consider that the + # file needs to be closed again. You can try adding an + # "assert wio.closed" at the end of the function. + + # Fortunately, a little gc.gollect() seems to be enough to + # work around all these issues. + support.gc_collect() + read_results = [] def _read(): s = os.read(r, 1) diff -r 63bbe9f80909 Lib/test/test_isinstance.py --- a/Lib/test/test_isinstance.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_isinstance.py Tue Sep 15 13:09:43 2015 +0300 @@ -260,7 +260,18 @@ def blowstack(fxn, arg, compare_to): # Make sure that calling isinstance with a deeply nested tuple for its # argument will raise RuntimeError eventually. tuple_arg = (compare_to,) - for cnt in xrange(sys.getrecursionlimit()+5): + + + if test_support.check_impl_detail(cpython=True): + RECURSION_LIMIT = sys.getrecursionlimit() + else: + # on non-CPython implementations, the maximum + # actual recursion limit might be higher, but + # probably not higher than 99999 + # + RECURSION_LIMIT = 99999 + + for cnt in xrange(RECURSION_LIMIT+5): tuple_arg = (tuple_arg,) fxn(arg, tuple_arg) diff -r 63bbe9f80909 Lib/test/test_iterlen.py --- a/Lib/test/test_iterlen.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_iterlen.py Tue Sep 15 13:09:43 2015 +0300 @@ -94,7 +94,11 @@ class TestRepeat(TestInvariantWithoutMut def test_no_len_for_infinite_repeat(self): # The repeat() object can also be infinite - self.assertRaises(TypeError, len, repeat(None)) + if test_support.check_impl_detail(pypy=True): + # 3.4 (PEP 424) behavior + self.assertEqual(len(repeat(None)), NotImplemented) + else: + self.assertRaises(TypeError, len, repeat(None)) class TestXrange(TestInvariantWithoutMutations): @@ -230,6 +234,7 @@ class TestLengthHintExceptions(unittest. self.assertRaises(RuntimeError, b.extend, BadLen()) self.assertRaises(RuntimeError, b.extend, BadLengthHint()) + @test_support.impl_detail("PEP 424 disallows None results", pypy=False) def test_invalid_hint(self): # Make sure an invalid result doesn't muck-up the works self.assertEqual(list(NoneLengthHint()), list(range(10))) diff -r 63bbe9f80909 Lib/test/test_itertools.py --- a/Lib/test/test_itertools.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_itertools.py Tue Sep 15 13:09:43 2015 +0300 @@ -810,11 +810,11 @@ class TestBasicOps(unittest.TestCase): self.assertRaises(ValueError, islice, xrange(10), 1, -5, -1) self.assertRaises(ValueError, islice, xrange(10), 1, 10, -1) self.assertRaises(ValueError, islice, xrange(10), 1, 10, 0) - self.assertRaises(ValueError, islice, xrange(10), 'a') - self.assertRaises(ValueError, islice, xrange(10), 'a', 1) - self.assertRaises(ValueError, islice, xrange(10), 1, 'a') - self.assertRaises(ValueError, islice, xrange(10), 'a', 1, 1) - self.assertRaises(ValueError, islice, xrange(10), 1, 'a', 1) + self.assertRaises((ValueError, TypeError), islice, xrange(10), 'a') + self.assertRaises((ValueError, TypeError), islice, xrange(10), 'a', 1) + self.assertRaises((ValueError, TypeError), islice, xrange(10), 1, 'a') + self.assertRaises((ValueError, TypeError), islice, xrange(10), 'a', 1, 1) + self.assertRaises((ValueError, TypeError), islice, xrange(10), 1, 'a', 1) self.assertEqual(len(list(islice(count(), 1, 10, maxsize))), 1) # Issue #10323: Less islice in a predictable state @@ -904,9 +904,17 @@ class TestBasicOps(unittest.TestCase): self.assertRaises(TypeError, tee, [1,2], 3, 'x') # tee object should be instantiable - a, b = tee('abc') - c = type(a)('def') - self.assertEqual(list(c), list('def')) + if test_support.check_impl_detail(): + # XXX I (arigo) would argue that 'type(a)(iterable)' has + # ill-defined semantics: it always return a fresh tee object, + # but depending on whether 'iterable' is itself a tee object + # or not, it is ok or not to continue using 'iterable' after + # the call. I cannot imagine why 'type(a)(non_tee_object)' + # would be useful, as 'iter(non_tee_obect)' is equivalent + # as far as I can see. + a, b = tee('abc') + c = type(a)('def') + self.assertEqual(list(c), list('def')) # test long-lagged and multi-way split a, b, c = tee(xrange(2000), 3) @@ -944,6 +952,7 @@ class TestBasicOps(unittest.TestCase): p = weakref.proxy(a) self.assertEqual(getattr(p, '__class__'), type(b)) del a + test_support.gc_collect() self.assertRaises(ReferenceError, getattr, p, '__class__') # Issue 13454: Crash when deleting backward iterator from tee() @@ -1376,6 +1385,7 @@ class TestVariousIteratorArgs(unittest.T class LengthTransparency(unittest.TestCase): + @test_support.impl_detail("__length_hint__() API is undocumented") def test_repeat(self): from test.test_iterlen import len self.assertEqual(len(repeat(None, 50)), 50) diff -r 63bbe9f80909 Lib/test/test_kqueue.py --- a/Lib/test/test_kqueue.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_kqueue.py Tue Sep 15 13:09:43 2015 +0300 @@ -205,6 +205,17 @@ class TestKQueue(unittest.TestCase): b.close() kq.close() + def test_control_raises_oserror(self): + kq = select.kqueue() + event = select.kevent(123456, select.KQ_FILTER_READ, select.KQ_EV_DELETE) + with self.assertRaises(OSError) as cm: + kq.control([event], 0, 0) + + self.assertEqual(cm.exception.args[0], errno.EBADF) + self.assertEqual(cm.exception.errno, errno.EBADF) + + kq.close() + def test_main(): test_support.run_unittest(TestKQueue) diff -r 63bbe9f80909 Lib/test/test_linecache.py --- a/Lib/test/test_linecache.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_linecache.py Tue Sep 15 13:09:43 2015 +0300 @@ -54,13 +54,13 @@ class LineCacheTests(unittest.TestCase): # Check whether lines correspond to those from file iteration for entry in TESTS: - filename = os.path.join(TEST_PATH, entry) + '.py' + filename = support.findfile( entry + '.py') for index, line in enumerate(open(filename)): self.assertEqual(line, getline(filename, index + 1)) # Check module loading for entry in MODULES: - filename = os.path.join(MODULE_PATH, entry) + '.py' + filename = support.findfile( entry + '.py') for index, line in enumerate(open(filename)): self.assertEqual(line, getline(filename, index + 1)) @@ -78,7 +78,7 @@ class LineCacheTests(unittest.TestCase): def test_clearcache(self): cached = [] for entry in TESTS: - filename = os.path.join(TEST_PATH, entry) + '.py' + filename = support.findfile( entry + '.py') cached.append(filename) linecache.getline(filename, 1) diff -r 63bbe9f80909 Lib/test/test_list.py --- a/Lib/test/test_list.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_list.py Tue Sep 15 13:09:43 2015 +0300 @@ -15,6 +15,10 @@ class ListTest(list_tests.CommonTest): self.assertEqual(list(''), []) self.assertEqual(list('spam'), ['s', 'p', 'a', 'm']) + # the following test also works with pypy, but eats all your address + # space's RAM before raising and takes too long. + @test_support.impl_detail("eats all your RAM before working", pypy=False) + def test_segfault_1(self): if sys.maxsize == 0x7fffffff: # This test can currently only work on 32-bit machines. # XXX If/when PySequence_Length() returns a ssize_t, it should be @@ -32,6 +36,7 @@ class ListTest(list_tests.CommonTest): # http://sources.redhat.com/ml/newlib/2002/msg00369.html self.assertRaises(MemoryError, list, xrange(sys.maxint // 2)) + def test_segfault_2(self): # This code used to segfault in Py2.4a3 x = [] x.extend(-y for y in x) diff -r 63bbe9f80909 Lib/test/test_logging.py --- a/Lib/test/test_logging.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_logging.py Tue Sep 15 13:09:43 2015 +0300 @@ -65,7 +65,8 @@ class BaseTest(unittest.TestCase): self.saved_handlers = logging._handlers.copy() self.saved_handler_list = logging._handlerList[:] self.saved_loggers = logger_dict.copy() - self.saved_level_names = logging._levelNames.copy() + self.saved_name_to_level = logging._nameToLevel.copy() + self.saved_level_to_name = logging._levelToName.copy() finally: logging._releaseLock() @@ -97,8 +98,10 @@ class BaseTest(unittest.TestCase): self.root_logger.setLevel(self.original_logging_level) logging._acquireLock() try: - logging._levelNames.clear() - logging._levelNames.update(self.saved_level_names) + logging._levelToName.clear() + logging._levelToName.update(self.saved_level_to_name) + logging._nameToLevel.clear() + logging._nameToLevel.update(self.saved_name_to_level) logging._handlers.clear() logging._handlers.update(self.saved_handlers) logging._handlerList[:] = self.saved_handler_list @@ -275,6 +278,24 @@ class BuiltinLevelsTest(BaseTest): def test_invalid_name(self): self.assertRaises(TypeError, logging.getLogger, any) + def test_get_level_name(self): + """Test getLevelName returns level constant.""" + # NOTE(flaper87): Bug #1517 + self.assertEqual(logging.getLevelName('NOTSET'), 0) + self.assertEqual(logging.getLevelName('DEBUG'), 10) + self.assertEqual(logging.getLevelName('INFO'), 20) + self.assertEqual(logging.getLevelName('WARN'), 30) + self.assertEqual(logging.getLevelName('WARNING'), 30) + self.assertEqual(logging.getLevelName('ERROR'), 40) + self.assertEqual(logging.getLevelName('CRITICAL'), 50) + + self.assertEqual(logging.getLevelName(0), 'NOTSET') + self.assertEqual(logging.getLevelName(10), 'DEBUG') + self.assertEqual(logging.getLevelName(20), 'INFO') + self.assertEqual(logging.getLevelName(30), 'WARNING') + self.assertEqual(logging.getLevelName(40), 'ERROR') + self.assertEqual(logging.getLevelName(50), 'CRITICAL') + class BasicFilterTest(BaseTest): """Test the bundled Filter class.""" diff -r 63bbe9f80909 Lib/test/test_long.py --- a/Lib/test/test_long.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_long.py Tue Sep 15 13:09:43 2015 +0300 @@ -532,9 +532,10 @@ class LongTest(test_int.IntLongCommonTes try: long(TruncReturnsNonIntegral()) except TypeError as e: - self.assertEqual(str(e), - "__trunc__ returned non-Integral" - " (type NonIntegral)") + if test_support.check_impl_detail(cpython=True): + self.assertEqual(str(e), + "__trunc__ returned non-Integral" + " (type NonIntegral)") else: self.fail("Failed to raise TypeError with %s" % ((base, trunc_result_base),)) diff -r 63bbe9f80909 Lib/test/test_marshal.py --- a/Lib/test/test_marshal.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_marshal.py Tue Sep 15 13:09:43 2015 +0300 @@ -6,25 +6,35 @@ import sys import unittest import os +class HelperMixin: + def helper(self, sample, *extra, **kwargs): + expected = kwargs.get('expected', sample) + new = marshal.loads(marshal.dumps(sample, *extra)) + self.assertEqual(expected, new) + self.assertEqual(type(expected), type(new)) + try: + with open(test_support.TESTFN, "wb") as f: + marshal.dump(sample, f, *extra) + with open(test_support.TESTFN, "rb") as f: + new = marshal.load(f) + self.assertEqual(expected, new) + self.assertEqual(type(expected), type(new)) + finally: + test_support.unlink(test_support.TESTFN) try: import _testcapi except ImportError: _testcapi = None -class IntTestCase(unittest.TestCase): + +class IntTestCase(unittest.TestCase, HelperMixin): def test_ints(self): # Test the full range of Python ints. n = sys.maxint while n: for expected in (-n, n): - s = marshal.dumps(expected) - got = marshal.loads(s) - self.assertEqual(expected, got) - marshal.dump(expected, file(test_support.TESTFN, "wb")) - got = marshal.load(file(test_support.TESTFN, "rb")) - self.assertEqual(expected, got) + self.helper(expected) n = n >> 1 - os.unlink(test_support.TESTFN) def test_int64(self): # Simulate int marshaling on a 64-bit box. This is most interesting if @@ -52,28 +62,16 @@ class IntTestCase(unittest.TestCase): def test_bool(self): for b in (True, False): - new = marshal.loads(marshal.dumps(b)) - self.assertEqual(b, new) - self.assertEqual(type(b), type(new)) - marshal.dump(b, file(test_support.TESTFN, "wb")) - new = marshal.load(file(test_support.TESTFN, "rb")) - self.assertEqual(b, new) - self.assertEqual(type(b), type(new)) + self.helper(b) -class FloatTestCase(unittest.TestCase): +class FloatTestCase(unittest.TestCase, HelperMixin): def test_floats(self): # Test a few floats small = 1e-25 n = sys.maxint * 3.7e250 while n > small: for expected in (-n, n): - f = float(expected) - s = marshal.dumps(f) - got = marshal.loads(s) - self.assertEqual(f, got) - marshal.dump(f, file(test_support.TESTFN, "wb")) - got = marshal.load(file(test_support.TESTFN, "rb")) - self.assertEqual(f, got) + self.helper(expected) n /= 123.4567 f = 0.0 @@ -89,59 +87,25 @@ class FloatTestCase(unittest.TestCase): while n < small: for expected in (-n, n): f = float(expected) + self.helper(f) + self.helper(f, 1) + n *= 123.4567 - s = marshal.dumps(f) - got = marshal.loads(s) - self.assertEqual(f, got) - - s = marshal.dumps(f, 1) - got = marshal.loads(s) - self.assertEqual(f, got) - - marshal.dump(f, file(test_support.TESTFN, "wb")) - got = marshal.load(file(test_support.TESTFN, "rb")) - self.assertEqual(f, got) - - marshal.dump(f, file(test_support.TESTFN, "wb"), 1) - got = marshal.load(file(test_support.TESTFN, "rb")) - self.assertEqual(f, got) - n *= 123.4567 - os.unlink(test_support.TESTFN) - -class StringTestCase(unittest.TestCase): +class StringTestCase(unittest.TestCase, HelperMixin): def test_unicode(self): for s in [u"", u"Andrè Previn", u"abc", u" "*10000]: - new = marshal.loads(marshal.dumps(s)) - self.assertEqual(s, new) - self.assertEqual(type(s), type(new)) - marshal.dump(s, file(test_support.TESTFN, "wb")) - new = marshal.load(file(test_support.TESTFN, "rb")) - self.assertEqual(s, new) - self.assertEqual(type(s), type(new)) - os.unlink(test_support.TESTFN) + self.helper(s) def test_string(self): for s in ["", "Andrè Previn", "abc", " "*10000]: - new = marshal.loads(marshal.dumps(s)) - self.assertEqual(s, new) - self.assertEqual(type(s), type(new)) - marshal.dump(s, file(test_support.TESTFN, "wb")) - new = marshal.load(file(test_support.TESTFN, "rb")) - self.assertEqual(s, new) - self.assertEqual(type(s), type(new)) - os.unlink(test_support.TESTFN) + self.helper(s) def test_buffer(self): for s in ["", "Andrè Previn", "abc", " "*10000]: with test_support.check_py3k_warnings(("buffer.. not supported", DeprecationWarning)): b = buffer(s) - new = marshal.loads(marshal.dumps(b)) - self.assertEqual(s, new) - marshal.dump(b, file(test_support.TESTFN, "wb")) - new = marshal.load(file(test_support.TESTFN, "rb")) - self.assertEqual(s, new) - os.unlink(test_support.TESTFN) + self.helper(b, expected=s) class ExceptionTestCase(unittest.TestCase): def test_exceptions(self): @@ -154,7 +118,7 @@ class CodeTestCase(unittest.TestCase): new = marshal.loads(marshal.dumps(co)) self.assertEqual(co, new) -class ContainerTestCase(unittest.TestCase): +class ContainerTestCase(unittest.TestCase, HelperMixin): d = {'astring': 'foo@bar.baz.spam', 'afloat': 7283.43, 'anint': 2**20, @@ -165,42 +129,20 @@ class ContainerTestCase(unittest.TestCas 'aunicode': u"Andrè Previn" } def test_dict(self): - new = marshal.loads(marshal.dumps(self.d)) - self.assertEqual(self.d, new) - marshal.dump(self.d, file(test_support.TESTFN, "wb")) - new = marshal.load(file(test_support.TESTFN, "rb")) - self.assertEqual(self.d, new) - os.unlink(test_support.TESTFN) + self.helper(self.d) def test_list(self): lst = self.d.items() - new = marshal.loads(marshal.dumps(lst)) - self.assertEqual(lst, new) - marshal.dump(lst, file(test_support.TESTFN, "wb")) - new = marshal.load(file(test_support.TESTFN, "rb")) - self.assertEqual(lst, new) - os.unlink(test_support.TESTFN) + self.helper(lst) def test_tuple(self): t = tuple(self.d.keys()) - new = marshal.loads(marshal.dumps(t)) - self.assertEqual(t, new) - marshal.dump(t, file(test_support.TESTFN, "wb")) - new = marshal.load(file(test_support.TESTFN, "rb")) - self.assertEqual(t, new) - os.unlink(test_support.TESTFN) + self.helper(t) def test_sets(self): for constructor in (set, frozenset): t = constructor(self.d.keys()) - new = marshal.loads(marshal.dumps(t)) - self.assertEqual(t, new) - self.assertTrue(isinstance(new, constructor)) - self.assertNotEqual(id(t), id(new)) - marshal.dump(t, file(test_support.TESTFN, "wb")) - new = marshal.load(file(test_support.TESTFN, "rb")) - self.assertEqual(t, new) - os.unlink(test_support.TESTFN) + self.helper(t) class BugsTestCase(unittest.TestCase): def test_bug_5888452(self): @@ -230,6 +172,7 @@ class BugsTestCase(unittest.TestCase): s = 'c' + ('X' * 4*4) + '{' * 2**20 self.assertRaises(ValueError, marshal.loads, s) + @test_support.impl_detail('specific recursion check') def test_recursion_limit(self): # Create a deeply nested structure. head = last = [] @@ -305,13 +248,13 @@ class LargeValuesTestCase(unittest.TestC self.check_unmarshallable([None] * size) @test_support.precisionbigmemtest(size=LARGE_SIZE, - memuse=pointer_size*12 + sys.getsizeof(LARGE_SIZE-1), + memuse=pointer_size*12, # + sys.getsizeof(LARGE_SIZE-1), dry_run=False) def test_set(self, size): self.check_unmarshallable(set(range(size))) @test_support.precisionbigmemtest(size=LARGE_SIZE, - memuse=pointer_size*12 + sys.getsizeof(LARGE_SIZE-1), + memuse=pointer_size*12, # + sys.getsizeof(LARGE_SIZE-1), dry_run=False) def test_frozenset(self, size): self.check_unmarshallable(frozenset(range(size))) diff -r 63bbe9f80909 Lib/test/test_memoryio.py --- a/Lib/test/test_memoryio.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_memoryio.py Tue Sep 15 13:09:43 2015 +0300 @@ -672,7 +672,7 @@ class CBytesIOTest(PyBytesIOTest): state = memio.__getstate__() self.assertEqual(len(state), 3) bytearray(state[0]) # Check if state[0] supports the buffer interface. - self.assertIsInstance(state[1], int) + self.assertIsInstance(state[1], (int, long)) if state[2] is not None: self.assertIsInstance(state[2], dict) memio.close() diff -r 63bbe9f80909 Lib/test/test_memoryview.py --- a/Lib/test/test_memoryview.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_memoryview.py Tue Sep 15 13:09:43 2015 +0300 @@ -26,7 +26,8 @@ class AbstractMemoryTests: def check_getitem_with_type(self, tp): item = self.getitem_type b = tp(self._source) - oldrefcount = sys.getrefcount(b) + if hasattr(sys, 'getrefcount'): + oldrefcount = sys.getrefcount(b) m = self._view(b) self.assertEqual(m[0], item(b"a")) self.assertIsInstance(m[0], bytes) @@ -43,7 +44,8 @@ class AbstractMemoryTests: self.assertRaises(TypeError, lambda: m[0.0]) self.assertRaises(TypeError, lambda: m["a"]) m = None - self.assertEqual(sys.getrefcount(b), oldrefcount) + if hasattr(sys, 'getrefcount'): + self.assertEqual(sys.getrefcount(b), oldrefcount) def test_getitem(self): for tp in self._types: @@ -65,7 +67,8 @@ class AbstractMemoryTests: if not self.ro_type: self.skipTest("no read-only type to test") b = self.ro_type(self._source) - oldrefcount = sys.getrefcount(b) + if hasattr(sys, 'getrefcount'): + oldrefcount = sys.getrefcount(b) m = self._view(b) def setitem(value): m[0] = value @@ -73,14 +76,16 @@ class AbstractMemoryTests: self.assertRaises(TypeError, setitem, 65) self.assertRaises(TypeError, setitem, memoryview(b"a")) m = None - self.assertEqual(sys.getrefcount(b), oldrefcount) + if hasattr(sys, 'getrefcount'): + self.assertEqual(sys.getrefcount(b), oldrefcount) def test_setitem_writable(self): if not self.rw_type: self.skipTest("no writable type to test") tp = self.rw_type b = self.rw_type(self._source) - oldrefcount = sys.getrefcount(b) + if hasattr(sys, 'getrefcount'): + oldrefcount = sys.getrefcount(b) m = self._view(b) m[0] = tp(b"0") self._check_contents(tp, b, b"0bcdef") @@ -116,7 +121,8 @@ class AbstractMemoryTests: self.assertRaises(ValueError, setitem, slice(0,2), b"a") m = None - self.assertEqual(sys.getrefcount(b), oldrefcount) + if hasattr(sys, 'getrefcount'): + self.assertEqual(sys.getrefcount(b), oldrefcount) def test_delitem(self): for tp in self._types: @@ -292,6 +298,7 @@ class BaseMemorySliceTests: def _check_contents(self, tp, obj, contents): self.assertEqual(obj[1:7], tp(contents)) + @unittest.skipUnless(hasattr(sys, 'getrefcount'), "Reference counting") def test_refs(self): for tp in self._types: m = memoryview(tp(self._source)) diff -r 63bbe9f80909 Lib/test/test_mmap.py --- a/Lib/test/test_mmap.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_mmap.py Tue Sep 15 13:09:43 2015 +0300 @@ -11,7 +11,7 @@ class MmapTests(unittest.TestCase): def setUp(self): if os.path.exists(TESTFN): - os.unlink(TESTFN) + unlink(TESTFN) def tearDown(self): try: @@ -119,7 +119,8 @@ class MmapTests(unittest.TestCase): def test_access_parameter(self): # Test for "access" keyword parameter mapsize = 10 - open(TESTFN, "wb").write("a"*mapsize) + with open(TESTFN, "wb") as f: + f.write("a"*mapsize) f = open(TESTFN, "rb") m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_READ) self.assertEqual(m[:], 'a'*mapsize, "Readonly memory map data incorrect.") @@ -168,33 +169,37 @@ class MmapTests(unittest.TestCase): else: self.fail("Able to resize readonly memory map") f.close() + m.close() del m, f - self.assertEqual(open(TESTFN, "rb").read(), 'a'*mapsize, - "Readonly memory map data file was modified") + with open(TESTFN, "rb") as f: + self.assertEqual(f.read(), 'a'*mapsize, + "Readonly memory map data file was modified") # Opening mmap with size too big import sys f = open(TESTFN, "r+b") try: - m = mmap.mmap(f.fileno(), mapsize+1) - except ValueError: - # we do not expect a ValueError on Windows - # CAUTION: This also changes the size of the file on disk, and - # later tests assume that the length hasn't changed. We need to - # repair that. + try: + m = mmap.mmap(f.fileno(), mapsize+1) + except ValueError: + # we do not expect a ValueError on Windows + # CAUTION: This also changes the size of the file on disk, and + # later tests assume that the length hasn't changed. We need to + # repair that. + if sys.platform.startswith('win'): + self.fail("Opening mmap with size+1 should work on Windows.") + else: + # we expect a ValueError on Unix, but not on Windows + if not sys.platform.startswith('win'): + self.fail("Opening mmap with size+1 should raise ValueError.") + m.close() + finally: + f.close() if sys.platform.startswith('win'): - self.fail("Opening mmap with size+1 should work on Windows.") - else: - # we expect a ValueError on Unix, but not on Windows - if not sys.platform.startswith('win'): - self.fail("Opening mmap with size+1 should raise ValueError.") - m.close() - f.close() - if sys.platform.startswith('win'): - # Repair damage from the resizing test. - f = open(TESTFN, 'r+b') - f.truncate(mapsize) - f.close() + # Repair damage from the resizing test. + f = open(TESTFN, 'r+b') + f.truncate(mapsize) + f.close() # Opening mmap with access=ACCESS_WRITE f = open(TESTFN, "r+b") @@ -220,11 +225,13 @@ class MmapTests(unittest.TestCase): self.assertEqual(m[:], 'd' * mapsize, "Copy-on-write memory map data not written correctly.") m.flush() - self.assertEqual(open(TESTFN, "rb").read(), 'c'*mapsize, - "Copy-on-write test data file should not be modified.") + f.close() + with open(TESTFN, "rb") as f: + self.assertEqual(f.read(), 'c'*mapsize, + "Copy-on-write test data file should not be modified.") # Ensuring copy-on-write maps cannot be resized self.assertRaises(TypeError, m.resize, 2*mapsize) - f.close() + m.close() del m, f # Ensuring invalid access parameter raises exception @@ -287,6 +294,7 @@ class MmapTests(unittest.TestCase): self.assertEqual(m.find('one', 1), 8) self.assertEqual(m.find('one', 1, -1), 8) self.assertEqual(m.find('one', 1, -2), -1) + m.close() def test_rfind(self): @@ -305,6 +313,7 @@ class MmapTests(unittest.TestCase): self.assertEqual(m.rfind('one', 0, -2), 0) self.assertEqual(m.rfind('one', 1, -1), 8) self.assertEqual(m.rfind('one', 1, -2), -1) + m.close() def test_double_close(self): @@ -538,7 +547,8 @@ class MmapTests(unittest.TestCase): @unittest.skipUnless(hasattr(mmap, 'PROT_READ'), "needs mmap.PROT_READ") def test_prot_readonly(self): mapsize = 10 - open(TESTFN, "wb").write("a"*mapsize) + with open(TESTFN, "wb") as f: + f.write("a"*mapsize) f = open(TESTFN, "rb") m = mmap.mmap(f.fileno(), mapsize, prot=mmap.PROT_READ) self.assertRaises(TypeError, m.write, "foo") @@ -550,7 +560,8 @@ class MmapTests(unittest.TestCase): def test_io_methods(self): data = "0123456789" - open(TESTFN, "wb").write("x"*len(data)) + with open(TESTFN, "wb") as f: + f.write("x"*len(data)) f = open(TESTFN, "r+b") m = mmap.mmap(f.fileno(), len(data)) f.close() @@ -579,6 +590,7 @@ class MmapTests(unittest.TestCase): self.assertEqual(m[:], "012bar6789") m.seek(8) self.assertRaises(ValueError, m.write, "bar") + m.close() @unittest.skipUnless(os.name == 'nt', 'requires Windows') def test_tagname(self): @@ -626,7 +638,8 @@ class MmapTests(unittest.TestCase): m.close() # Should not crash (Issue 5385) - open(TESTFN, "wb").write("x"*10) + with open(TESTFN, "wb") as f: + f.write("x"*10) f = open(TESTFN, "r+b") m = mmap.mmap(f.fileno(), 0) f.close() diff -r 63bbe9f80909 Lib/test/test_module.py --- a/Lib/test/test_module.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_module.py Tue Sep 15 13:09:43 2015 +0300 @@ -1,6 +1,6 @@ # Test the module type import unittest -from test.test_support import run_unittest, gc_collect +from test.test_support import run_unittest, gc_collect, check_impl_detail import sys ModuleType = type(sys) @@ -10,8 +10,10 @@ class ModuleTests(unittest.TestCase): # An uninitialized module has no __dict__ or __name__, # and __doc__ is None foo = ModuleType.__new__(ModuleType) - self.assertTrue(foo.__dict__ is None) - self.assertRaises(SystemError, dir, foo) + self.assertFalse(foo.__dict__) + if check_impl_detail(): + self.assertTrue(foo.__dict__ is None) + self.assertRaises(SystemError, dir, foo) try: s = foo.__name__ self.fail("__name__ = %s" % repr(s)) diff -r 63bbe9f80909 Lib/test/test_modulefinder.py --- a/Lib/test/test_modulefinder.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_modulefinder.py Tue Sep 15 13:09:43 2015 +0300 @@ -16,7 +16,7 @@ import modulefinder # library. TEST_DIR = tempfile.mkdtemp() -TEST_PATH = [TEST_DIR, os.path.dirname(__future__.__file__)] +TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)] # Each test description is a list of 5 items: # diff -r 63bbe9f80909 Lib/test/test_multibytecodec.py --- a/Lib/test/test_multibytecodec.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_multibytecodec.py Tue Sep 15 13:09:43 2015 +0300 @@ -40,7 +40,7 @@ class Test_MultibyteCodec(unittest.TestC dec = codecs.getdecoder('euc-kr') myreplace = lambda exc: (u'', sys.maxint+1) codecs.register_error('test.cjktest', myreplace) - self.assertRaises(IndexError, dec, + self.assertRaises((IndexError, OverflowError), dec, 'apple\x92ham\x93spam', 'test.cjktest') def test_errorcallback_custom_ignore(self): @@ -153,7 +153,8 @@ class Test_IncrementalDecoder(unittest.T class Test_StreamReader(unittest.TestCase): def test_bug1728403(self): try: - open(TESTFN, 'w').write('\xa1') + with open(TESTFN, 'w') as f: + f.write('\xa1') f = codecs.open(TESTFN, encoding='cp949') self.assertRaises(UnicodeDecodeError, f.read, 2) finally: diff -r 63bbe9f80909 Lib/test/test_multibytecodec_support.py --- a/Lib/test/test_multibytecodec_support.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_multibytecodec_support.py Tue Sep 15 13:09:43 2015 +0300 @@ -119,8 +119,8 @@ class TestBase: def myreplace(exc): return (u'x', sys.maxint + 1) codecs.register_error("test.cjktest", myreplace) - self.assertRaises(IndexError, self.encode, self.unmappedunicode, - 'test.cjktest') + self.assertRaises((IndexError, OverflowError), self.encode, + self.unmappedunicode, 'test.cjktest') def test_callback_None_index(self): def myreplace(exc): @@ -364,7 +364,7 @@ class TestBase_Mapping(unittest.TestCase self.assertRaises(UnicodeError, func, self.encoding, scheme) def load_teststring(name): - dir = os.path.join(os.path.dirname(__file__), 'cjkencodings') + dir = test_support.findfile('cjkencodings') with open(os.path.join(dir, name + '.txt'), 'rb') as f: encoded = f.read() with open(os.path.join(dir, name + '-utf8.txt'), 'rb') as f: diff -r 63bbe9f80909 Lib/test/test_multiprocessing.py --- a/Lib/test/test_multiprocessing.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_multiprocessing.py Tue Sep 15 13:09:43 2015 +0300 @@ -2,6 +2,11 @@ # Unit tests for the multiprocessing package # +## FIXME: remove when https://bugs.pypy.org/issue1644 is resolved +import sys +if sys.platform.startswith('freebsd'): + raise Exception("This test hangs on FreeBSD. Test deactivated for now until https://bugs.pypy.org/issue1644 get resolved") + import unittest import Queue import time @@ -1269,7 +1274,9 @@ class _TestPool(BaseTestCase): p.join() def unpickleable_result(): - return lambda: 42 + class C: + pass + return C class _TestPoolWorkerErrors(BaseTestCase): ALLOWED_TYPES = ('processes', ) @@ -1487,7 +1494,7 @@ class _TestRemoteManager(BaseTestCase): # Because we are using xmlrpclib for serialization instead of # pickle this will cause a serialization error. - self.assertRaises(Exception, queue.put, time.sleep) + self.assertRaises(Exception, queue.put, object) # Make queue finalizer run before the server is stopped del queue @@ -1520,6 +1527,7 @@ class _TestManagerRestart(BaseTestCase): queue = manager.get_queue() self.assertEqual(queue.get(), 'hello world') del queue + test_support.gc_collect() manager.shutdown() manager = QueueManager( address=addr, authkey=authkey, serializer=SERIALIZER) @@ -1922,6 +1930,10 @@ class _TestHeap(BaseTestCase): if len(blocks) > maxblocks: i = random.randrange(maxblocks) del blocks[i] + # XXX There should be a better way to release resources for a + # single block + if i % maxblocks == 0: + import gc; gc.collect() # get the heap object heap = multiprocessing.heap.BufferWrapper._heap @@ -1957,9 +1969,9 @@ class _TestHeap(BaseTestCase): if not gc.isenabled(): gc.enable() self.addCleanup(gc.disable) - thresholds = gc.get_threshold() - self.addCleanup(gc.set_threshold, *thresholds) - gc.set_threshold(10) + #thresholds = gc.get_threshold() + #self.addCleanup(gc.set_threshold, *thresholds) + #gc.set_threshold(10) # perform numerous block allocations, with cyclic references to make # sure objects are collected asynchronously by the gc @@ -2022,6 +2034,7 @@ class _TestSharedCTypes(BaseTestCase): def test_synchronize(self): self.test_sharedctypes(lock=True) + @unittest.skipUnless(test_support.check_impl_detail(pypy=False), "pypy ctypes differences") def test_copy(self): foo = _Foo(2, 5.0) bar = copy(foo) @@ -2046,6 +2059,7 @@ class _TestFinalize(BaseTestCase): a = Foo() util.Finalize(a, conn.send, args=('a',)) del a # triggers callback for a + test_support.gc_collect() b = Foo() close_b = util.Finalize(b, conn.send, args=('b',)) diff -r 63bbe9f80909 Lib/test/test_mutants.py --- a/Lib/test/test_mutants.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_mutants.py Tue Sep 15 13:09:43 2015 +0300 @@ -1,4 +1,4 @@ -from test.test_support import verbose, TESTFN +from test.test_support import verbose, TESTFN, check_impl_detail import random import os @@ -137,10 +137,16 @@ def test_one(n): while dict1 and len(dict1) == len(dict2): if verbose: print ".", - if random.random() < 0.5: - c = cmp(dict1, dict2) - else: - c = dict1 == dict2 + try: + if random.random() < 0.5: + c = cmp(dict1, dict2) + else: + c = dict1 == dict2 + except RuntimeError: + # CPython never raises RuntimeError here, but other implementations + # might, and it's fine. + if check_impl_detail(cpython=True): + raise if verbose: print diff -r 63bbe9f80909 Lib/test/test_os.py --- a/Lib/test/test_os.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_os.py Tue Sep 15 13:09:43 2015 +0300 @@ -82,7 +82,7 @@ class TemporaryFileTests(unittest.TestCa self.assertFalse(os.path.exists(name), "file already exists for temporary file") # make sure we can create the file - open(name, "w") + open(name, "w").close() self.files.append(name) @unittest.skipUnless(hasattr(os, 'tempnam'), 'test needs os.tempnam()') @@ -134,9 +134,13 @@ class TemporaryFileTests(unittest.TestCa fp = os.tmpfile() except OSError, second: self.assertEqual(first.args, second.args) + return else: - self.fail("expected os.tmpfile() to raise OSError") - return + if test_support.check_impl_detail(pypy=False): + self.fail("expected os.tmpfile() to raise OSError") + # on PyPy, os.tmpfile() uses the tempfile module + # anyway, so works even if we cannot write in root. + fp.close() else: # open() worked, therefore, tmpfile() should work. Close our # dummy file and proceed with the test as normal. @@ -275,7 +279,7 @@ class StatAttributeTests(unittest.TestCa try: result.f_bfree = 1 self.fail("No exception raised") - except TypeError: + except (TypeError, AttributeError): pass try: @@ -765,7 +769,8 @@ class PosixUidGidTests(unittest.TestCase 'import os,sys;os.setregid(-1,-1);sys.exit(0)']) -@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests") +@unittest.skipUnless(sys.platform == "win32" and hasattr(os,'kill'), + "Win32 specific tests") class Win32KillTests(unittest.TestCase): def _kill(self, sig): # Start sys.executable as a subprocess and communicate from the diff -r 63bbe9f80909 Lib/test/test_peepholer.py --- a/Lib/test/test_peepholer.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_peepholer.py Tue Sep 15 13:09:43 2015 +0300 @@ -41,7 +41,7 @@ class TestTranforms(unittest.TestCase): def test_none_as_constant(self): # LOAD_GLOBAL None --> LOAD_CONST None def f(x): - None + y = None return x asm = disassemble(f) for elem in ('LOAD_GLOBAL',): @@ -67,10 +67,13 @@ class TestTranforms(unittest.TestCase): self.assertIn(elem, asm) def test_pack_unpack(self): + # On PyPy, "a, b = ..." is even more optimized, by removing + # the ROT_TWO. But the ROT_TWO is not removed if assigning + # to more complex expressions, so check that. for line, elem in ( ('a, = a,', 'LOAD_CONST',), - ('a, b = a, b', 'ROT_TWO',), - ('a, b, c = a, b, c', 'ROT_THREE',), + ('a[1], b = a, b', 'ROT_TWO',), + ('a, b[2], c = a, b, c', 'ROT_THREE',), ): asm = dis_single(line) self.assertIn(elem, asm) @@ -78,6 +81,8 @@ class TestTranforms(unittest.TestCase): self.assertNotIn('UNPACK_TUPLE', asm) def test_folding_of_tuples_of_constants(self): + # On CPython, "a,b,c=1,2,3" turns into "a,b,c=" + # but on PyPy, it turns into "a=1;b=2;c=3". for line, elem in ( ('a = 1,2,3', '((1, 2, 3))'), ('("a","b","c")', "(('a', 'b', 'c'))"), @@ -86,7 +91,8 @@ class TestTranforms(unittest.TestCase): ('((1, 2), 3, 4)', '(((1, 2), 3, 4))'), ): asm = dis_single(line) - self.assertIn(elem, asm) + self.assert_(elem in asm or ( + line == 'a,b,c = 1,2,3' and 'UNPACK_TUPLE' not in asm)) self.assertNotIn('BUILD_TUPLE', asm) # Bug 1053819: Tuple of constants misidentified when presented with: diff -r 63bbe9f80909 Lib/test/test_pprint.py --- a/Lib/test/test_pprint.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_pprint.py Tue Sep 15 13:09:43 2015 +0300 @@ -292,7 +292,16 @@ frozenset2([0, frozenset([0, 2]), frozenset([0, 1])])}""" cube = test.test_set.cube(3) - self.assertEqual(pprint.pformat(cube), cube_repr_tgt) + # XXX issues of dictionary order, and for the case below, + # order of items in the frozenset([...]) representation. + # Whether we get precisely cube_repr_tgt or not is open + # to implementation-dependent choices (this test probably + # fails horribly in CPython if we tweak the dict order too). + got = pprint.pformat(cube) + if test.test_support.check_impl_detail(cpython=True): + self.assertEqual(got, cube_repr_tgt) + else: + self.assertEqual(eval(got), cube) cubo_repr_tgt = """\ {frozenset([frozenset([0, 2]), frozenset([0])]): frozenset([frozenset([frozenset([0, 2]), @@ -452,7 +461,11 @@ frozenset2([0, 2])])])}""" cubo = test.test_set.linegraph(cube) - self.assertEqual(pprint.pformat(cubo), cubo_repr_tgt) + got = pprint.pformat(cubo) + if test.test_support.check_impl_detail(cpython=True): + self.assertEqual(got, cubo_repr_tgt) + else: + self.assertEqual(eval(got), cubo) def test_depth(self): nested_tuple = (1, (2, (3, (4, (5, 6))))) diff -r 63bbe9f80909 Lib/test/test_pydoc.py --- a/Lib/test/test_pydoc.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_pydoc.py Tue Sep 15 13:09:43 2015 +0300 @@ -427,11 +427,10 @@ class PydocImportTest(PydocBaseTest): modname = 'testmod_xyzzy' testpairs = ( ('i_am_not_here', 'i_am_not_here'), - ('test.i_am_not_here_either', 'i_am_not_here_either'), - ('test.i_am_not_here.neither_am_i', 'i_am_not_here.neither_am_i'), - ('i_am_not_here.{}'.format(modname), - 'i_am_not_here.{}'.format(modname)), - ('test.{}'.format(modname), modname), + ('test.i_am_not_here_either', 'test.i_am_not_here_either'), + ('test.i_am_not_here.neither_am_i', 'test.i_am_not_here'), + ('i_am_not_here.{}'.format(modname), 'i_am_not_here'), + ('test.{}'.format(modname), 'test.{}'.format(modname)), ) sourcefn = os.path.join(TESTFN, modname) + os.extsep + "py" diff -r 63bbe9f80909 Lib/test/test_pyexpat.py --- a/Lib/test/test_pyexpat.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_pyexpat.py Tue Sep 15 13:09:43 2015 +0300 @@ -598,6 +598,9 @@ class ChardataBufferTest(unittest.TestCa self.assertEqual(self.n, 4) class MalformedInputText(unittest.TestCase): + # CPython seems to ship its own version of expat, they fixed it on this commit : + # http://svn.python.org/view?revision=74429&view=revision + @unittest.skipIf(sys.platform == "darwin", "Expat is broken on Mac OS X 10.6.6") def test1(self): xml = "\0\r\n" parser = expat.ParserCreate() @@ -607,6 +610,7 @@ class MalformedInputText(unittest.TestCa except expat.ExpatError as e: self.assertEqual(str(e), 'unclosed token: line 2, column 0') + @unittest.skipIf(sys.platform == "darwin", "Expat is broken on Mac OS X 10.6.6") def test2(self): xml = "\r\n" parser = expat.ParserCreate() diff -r 63bbe9f80909 Lib/test/test_readline.py --- a/Lib/test/test_readline.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_readline.py Tue Sep 15 13:09:43 2015 +0300 @@ -44,7 +44,8 @@ class TestHistoryManipulation (unittest. class TestReadline(unittest.TestCase): - @unittest.skipIf(readline._READLINE_VERSION < 0x0600 + @unittest.skipIf(hasattr(readline, '_READLINE_VERSION') + and readline._READLINE_VERSION < 0x0600 and "libedit" not in readline.__doc__, "not supported in this library version") def test_init(self): diff -r 63bbe9f80909 Lib/test/test_repr.py --- a/Lib/test/test_repr.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_repr.py Tue Sep 15 13:09:43 2015 +0300 @@ -9,6 +9,7 @@ import shutil import unittest from test.test_support import run_unittest, check_py3k_warnings +from test.test_support import check_impl_detail from repr import repr as r # Don't shadow builtin repr from repr import Repr @@ -145,8 +146,11 @@ class ReprTests(unittest.TestCase): # Functions eq(repr(hash), '') # Methods - self.assertTrue(repr(''.split).startswith( - '") def test_xrange(self): eq = self.assertEqual @@ -192,7 +196,10 @@ class ReprTests(unittest.TestCase): def test_descriptors(self): eq = self.assertEqual # method descriptors - eq(repr(dict.items), "") + if check_impl_detail(cpython=True): + eq(repr(dict.items), "") + elif check_impl_detail(pypy=True): + eq(repr(dict.items), "") # XXX member descriptors # XXX attribute descriptors # XXX slot descriptors @@ -254,8 +261,14 @@ class LongReprTest(unittest.TestCase): eq = self.assertEqual touch(os.path.join(self.subpkgname, self.pkgname + os.extsep + 'py')) from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation - eq(repr(areallylongpackageandmodulenametotestreprtruncation), - "" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__)) + # On PyPy, we use %r to format the file name; on CPython it is done + # with '%s'. It seems to me that %r is safer . + if '__pypy__' in sys.builtin_module_names: + eq(repr(areallylongpackageandmodulenametotestreprtruncation), + "" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__)) + else: + eq(repr(areallylongpackageandmodulenametotestreprtruncation), + "" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__)) eq(repr(sys), "") def test_type(self): diff -r 63bbe9f80909 Lib/test/test_runpy.py --- a/Lib/test/test_runpy.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_runpy.py Tue Sep 15 13:09:43 2015 +0300 @@ -5,10 +5,15 @@ import os.path import sys import re import tempfile -from test.test_support import verbose, run_unittest, forget +from test.test_support import verbose, run_unittest, forget, check_impl_detail from test.script_helper import (temp_dir, make_script, compile_script, make_pkg, make_zip_script, make_zip_pkg) +if check_impl_detail(pypy=True): + no_lone_pyc_file = True +else: + no_lone_pyc_file = False + from runpy import _run_code, _run_module_code, run_module, run_path # Note: This module can't safely test _run_module_as_main as it @@ -168,14 +173,15 @@ class RunModuleTest(unittest.TestCase): self.assertIn("x", d1) self.assertTrue(d1["x"] == 1) del d1 # Ensure __loader__ entry doesn't keep file open - __import__(mod_name) - os.remove(mod_fname) - if not sys.dont_write_bytecode: - if verbose: print "Running from compiled:", mod_name - d2 = run_module(mod_name) # Read from bytecode - self.assertIn("x", d2) - self.assertTrue(d2["x"] == 1) - del d2 # Ensure __loader__ entry doesn't keep file open + if not no_lone_pyc_file: + __import__(mod_name) + os.remove(mod_fname) + if not sys.dont_write_bytecode: + if verbose: print "Running from compiled:", mod_name + d2 = run_module(mod_name) # Read from bytecode + self.assertIn("x", d2) + self.assertTrue(d2["x"] == 1) + del d2 # Ensure __loader__ entry doesn't keep file open finally: self._del_pkg(pkg_dir, depth, mod_name) if verbose: print "Module executed successfully" @@ -191,14 +197,15 @@ class RunModuleTest(unittest.TestCase): self.assertIn("x", d1) self.assertTrue(d1["x"] == 1) del d1 # Ensure __loader__ entry doesn't keep file open - __import__(mod_name) - os.remove(mod_fname) - if not sys.dont_write_bytecode: - if verbose: print "Running from compiled:", pkg_name - d2 = run_module(pkg_name) # Read from bytecode - self.assertIn("x", d2) - self.assertTrue(d2["x"] == 1) - del d2 # Ensure __loader__ entry doesn't keep file open + if not no_lone_pyc_file: + __import__(mod_name) + os.remove(mod_fname) + if not sys.dont_write_bytecode: + if verbose: print "Running from compiled:", pkg_name + d2 = run_module(pkg_name) # Read from bytecode + self.assertIn("x", d2) + self.assertTrue(d2["x"] == 1) + del d2 # Ensure __loader__ entry doesn't keep file open finally: self._del_pkg(pkg_dir, depth, pkg_name) if verbose: print "Package executed successfully" @@ -246,16 +253,17 @@ from ..uncle.cousin import nephew self.assertIn("sibling", d1) self.assertIn("nephew", d1) del d1 # Ensure __loader__ entry doesn't keep file open - __import__(mod_name) - os.remove(mod_fname) - if not sys.dont_write_bytecode: - if verbose: print "Running from compiled:", mod_name - d2 = run_module(mod_name, run_name=run_name) # Read from bytecode - self.assertIn("__package__", d2) - self.assertTrue(d2["__package__"] == pkg_name) - self.assertIn("sibling", d2) - self.assertIn("nephew", d2) - del d2 # Ensure __loader__ entry doesn't keep file open + if not no_lone_pyc_file: + __import__(mod_name) + os.remove(mod_fname) + if not sys.dont_write_bytecode: + if verbose: print "Running from compiled:", mod_name + d2 = run_module(mod_name, run_name=run_name) # Read from bytecode + self.assertIn("__package__", d2) + self.assertTrue(d2["__package__"] == pkg_name) + self.assertIn("sibling", d2) + self.assertIn("nephew", d2) + del d2 # Ensure __loader__ entry doesn't keep file open finally: self._del_pkg(pkg_dir, depth, mod_name) if verbose: print "Module executed successfully" @@ -348,6 +356,8 @@ argv0 = sys.argv[0] script_dir, '') def test_directory_compiled(self): + if no_lone_pyc_file: + return with temp_dir() as script_dir: mod_name = '__main__' script_name = self._make_test_script(script_dir, mod_name) diff -r 63bbe9f80909 Lib/test/test_scope.py --- a/Lib/test/test_scope.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_scope.py Tue Sep 15 13:09:43 2015 +0300 @@ -1,6 +1,6 @@ import unittest from test.test_support import check_syntax_error, check_py3k_warnings, \ - check_warnings, run_unittest + check_warnings, run_unittest, gc_collect class ScopeTests(unittest.TestCase): @@ -432,6 +432,7 @@ self.assertEqual(g.get(), 13) for i in range(100): f1() + gc_collect() self.assertEqual(Foo.count, 0) diff -r 63bbe9f80909 Lib/test/test_select.py --- a/Lib/test/test_select.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_select.py Tue Sep 15 13:09:43 2015 +0300 @@ -57,7 +57,17 @@ class SelectTestCase(unittest.TestCase): del a[-1] return sys.__stdout__.fileno() a[:] = [F()] * 10 - self.assertEqual(select.select([], a, []), ([], a[:5], [])) + result = select.select([], a, []) + # CPython: 'a' ends up with 5 items, because each fileno() + # removes an item and at the middle the iteration stops. + # PyPy: 'a' ends up empty, because the iteration is done on + # a copy of the original list: fileno() is called 10 times. + if test_support.check_impl_detail(cpython=True): + self.assertEqual(len(result[1]), 5) + self.assertEqual(len(a), 5) + if test_support.check_impl_detail(pypy=True): + self.assertEqual(len(result[1]), 10) + self.assertEqual(len(a), 0) def test_main(): test_support.run_unittest(SelectTestCase) diff -r 63bbe9f80909 Lib/test/test_set.py --- a/Lib/test/test_set.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_set.py Tue Sep 15 13:09:43 2015 +0300 @@ -309,6 +309,7 @@ class TestJointOps(unittest.TestCase): fo.close() test_support.unlink(test_support.TESTFN) + @test_support.impl_detail(pypy=False) def test_do_not_rehash_dict_keys(self): n = 10 d = dict.fromkeys(map(HashCountingInt, xrange(n))) @@ -559,6 +560,7 @@ class TestSet(TestJointOps): p = weakref.proxy(s) self.assertEqual(str(p), str(s)) s = None + test_support.gc_collect() self.assertRaises(ReferenceError, str, p) @unittest.skipUnless(hasattr(set, "test_c_api"), @@ -590,6 +592,7 @@ class TestFrozenSet(TestJointOps): s.__init__(self.otherword) self.assertEqual(s, set(self.word)) + @test_support.impl_detail() def test_singleton_empty_frozenset(self): f = frozenset() efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''), diff -r 63bbe9f80909 Lib/test/test_sets.py --- a/Lib/test/test_sets.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_sets.py Tue Sep 15 13:09:43 2015 +0300 @@ -685,7 +685,9 @@ class TestCopying(unittest.TestCase): set_list = sorted(self.set) self.assertEqual(len(dup_list), len(set_list)) for i, el in enumerate(dup_list): - self.assertIs(el, set_list[i]) + # Object identity is not guarnteed for immutable objects, so we + # can't use assertIs here. + self.assertEqual(el, set_list[i]) def test_deep_copy(self): dup = copy.deepcopy(self.set) diff -r 63bbe9f80909 Lib/test/test_site.py --- a/Lib/test/test_site.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_site.py Tue Sep 15 13:09:43 2015 +0300 @@ -228,6 +228,10 @@ class HelperFunctionsTests(unittest.Test self.assertEqual(len(dirs), 1) wanted = os.path.join('xoxo', 'Lib', 'site-packages') self.assertEqual(dirs[0], wanted) + elif '__pypy__' in sys.builtin_module_names: + self.assertEquals(len(dirs), 1) + wanted = os.path.join('xoxo', 'site-packages') + self.assertEquals(dirs[0], wanted) elif (sys.platform == "darwin" and sysconfig.get_config_var("PYTHONFRAMEWORK")): # OS X framework builds diff -r 63bbe9f80909 Lib/test/test_socket.py --- a/Lib/test/test_socket.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_socket.py Tue Sep 15 13:09:43 2015 +0300 @@ -268,6 +268,7 @@ class GeneralModuleTests(unittest.TestCa self.assertEqual(p.fileno(), s.fileno()) s.close() s = None + test_support.gc_collect() try: p.fileno() except ReferenceError: @@ -309,32 +310,34 @@ class GeneralModuleTests(unittest.TestCa s.sendto(u'\u2620', sockname) with self.assertRaises(TypeError) as cm: s.sendto(5j, sockname) - self.assertIn('not complex', str(cm.exception)) + self.assertIn('complex', str(cm.exception)) with self.assertRaises(TypeError) as cm: s.sendto('foo', None) - self.assertIn('not NoneType', str(cm.exception)) + self.assertIn('NoneType', str(cm.exception)) # 3 args with self.assertRaises(UnicodeEncodeError): s.sendto(u'\u2620', 0, sockname) with self.assertRaises(TypeError) as cm: s.sendto(5j, 0, sockname) - self.assertIn('not complex', str(cm.exception)) + self.assertIn('complex', str(cm.exception)) with self.assertRaises(TypeError) as cm: s.sendto('foo', 0, None) - self.assertIn('not NoneType', str(cm.exception)) + if test_support.check_impl_detail(): + self.assertIn('not NoneType', str(cm.exception)) with self.assertRaises(TypeError) as cm: s.sendto('foo', 'bar', sockname) - self.assertIn('an integer is required', str(cm.exception)) + self.assertIn('integer', str(cm.exception)) with self.assertRaises(TypeError) as cm: s.sendto('foo', None, None) - self.assertIn('an integer is required', str(cm.exception)) + if test_support.check_impl_detail(): + self.assertIn('an integer is required', str(cm.exception)) # wrong number of args with self.assertRaises(TypeError) as cm: s.sendto('foo') - self.assertIn('(1 given)', str(cm.exception)) + self.assertIn(' given)', str(cm.exception)) with self.assertRaises(TypeError) as cm: s.sendto('foo', 0, sockname, 4) - self.assertIn('(4 given)', str(cm.exception)) + self.assertIn(' given)', str(cm.exception)) def testCrucialConstants(self): @@ -410,10 +413,10 @@ class GeneralModuleTests(unittest.TestCa socket.htonl(k) socket.htons(k) for k in bad_values: - self.assertRaises(OverflowError, socket.ntohl, k) - self.assertRaises(OverflowError, socket.ntohs, k) - self.assertRaises(OverflowError, socket.htonl, k) - self.assertRaises(OverflowError, socket.htons, k) + self.assertRaises((OverflowError, ValueError), socket.ntohl, k) + self.assertRaises((OverflowError, ValueError), socket.ntohs, k) + self.assertRaises((OverflowError, ValueError), socket.htonl, k) + self.assertRaises((OverflowError, ValueError), socket.htons, k) def testGetServBy(self): eq = self.assertEqual @@ -453,8 +456,8 @@ class GeneralModuleTests(unittest.TestCa if udpport is not None: eq(socket.getservbyport(udpport, 'udp'), service) # Make sure getservbyport does not accept out of range ports. - self.assertRaises(OverflowError, socket.getservbyport, -1) - self.assertRaises(OverflowError, socket.getservbyport, 65536) + self.assertRaises((OverflowError, ValueError), socket.getservbyport, -1) + self.assertRaises((OverflowError, ValueError), socket.getservbyport, 65536) def testDefaultTimeout(self): # Testing default timeout @@ -632,8 +635,8 @@ class GeneralModuleTests(unittest.TestCa port = test_support.find_unused_port() big_port = port + 65536 neg_port = port - 65536 - self.assertRaises(OverflowError, sock.bind, (HOST, big_port)) - self.assertRaises(OverflowError, sock.bind, (HOST, neg_port)) + self.assertRaises((OverflowError, ValueError), sock.bind, (HOST, big_port)) + self.assertRaises((OverflowError, ValueError), sock.bind, (HOST, neg_port)) # Since find_unused_port() is inherently subject to race conditions, we # call it a couple times if necessary. for i in itertools.count(): @@ -1147,6 +1150,9 @@ class FileObjectInterruptedTestCase(unit def recv(self, size): return self._recv_step.next()() + def _reuse(self): pass + def _drop(self): pass + @staticmethod def _raise_eintr(): raise socket.error(errno.EINTR) @@ -1479,6 +1485,8 @@ class Urllib2FileobjectTest(unittest.Tes closed = False def flush(self): pass def close(self): self.closed = True + def _reuse(self): pass + def _drop(self): pass # must not close unless we request it: the original use of _fileobject # by module socket requires that the underlying socket not be closed until diff -r 63bbe9f80909 Lib/test/test_sort.py --- a/Lib/test/test_sort.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_sort.py Tue Sep 15 13:09:43 2015 +0300 @@ -140,7 +140,10 @@ class TestBugs(unittest.TestCase): return random.random() < 0.5 L = [C() for i in range(50)] - self.assertRaises(ValueError, L.sort) + try: + L.sort() + except ValueError: + pass def test_cmpNone(self): # Testing None as a comparison function. @@ -150,8 +153,10 @@ class TestBugs(unittest.TestCase): L.sort(None) self.assertEqual(L, range(50)) + @test_support.impl_detail(pypy=False) def test_undetected_mutation(self): # Python 2.4a1 did not always detect mutation + # So does pypy... memorywaster = [] for i in range(20): def mutating_cmp(x, y): @@ -226,7 +231,10 @@ class TestDecorateSortUndecorate(unittes def __del__(self): del data[:] data[:] = range(20) - self.assertRaises(ValueError, data.sort, key=SortKiller) + try: + data.sort(key=SortKiller) + except ValueError: + pass def test_key_with_mutating_del_and_exception(self): data = range(10) diff -r 63bbe9f80909 Lib/test/test_str.py --- a/Lib/test/test_str.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_str.py Tue Sep 15 13:09:43 2015 +0300 @@ -449,10 +449,11 @@ class StrTest( for meth in ('foo'.startswith, 'foo'.endswith): with self.assertRaises(TypeError) as cm: meth(['f']) - exc = str(cm.exception) - self.assertIn('unicode', exc) - self.assertIn('str', exc) - self.assertIn('tuple', exc) + if test_support.check_impl_detail(): + exc = str(cm.exception) + self.assertIn('unicode', exc) + self.assertIn('str', exc) + self.assertIn('tuple', exc) def test_main(): test_support.run_unittest(StrTest) diff -r 63bbe9f80909 Lib/test/test_struct.py --- a/Lib/test/test_struct.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_struct.py Tue Sep 15 13:09:43 2015 +0300 @@ -553,7 +553,8 @@ class StructTest(unittest.TestCase): @unittest.skipUnless(IS32BIT, "Specific to 32bit machines") def test_crasher(self): - self.assertRaises(MemoryError, struct.pack, "357913941c", "a") + self.assertRaises((MemoryError, struct.error), struct.pack, + "357913941c", "a") def test_count_overflow(self): hugecount = '{}b'.format(sys.maxsize+1) diff -r 63bbe9f80909 Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_subprocess.py Tue Sep 15 13:09:43 2015 +0300 @@ -25,11 +25,11 @@ mswindows = (sys.platform == "win32") # Depends on the following external programs: Python # -if mswindows: - SETBINARY = ('import msvcrt; msvcrt.setmode(sys.stdout.fileno(), ' - 'os.O_BINARY);') -else: - SETBINARY = '' +#if mswindows: +# SETBINARY = ('import msvcrt; msvcrt.setmode(sys.stdout.fileno(), ' +# 'os.O_BINARY);') +#else: +# SETBINARY = '' try: @@ -475,8 +475,9 @@ class ProcessTestCase(BaseTestCase): self.assertStderrEqual(stderr, "") def test_universal_newlines(self): - p = subprocess.Popen([sys.executable, "-c", - 'import sys,os;' + SETBINARY + + # NB. replaced SETBINARY with the -u flag + p = subprocess.Popen([sys.executable, "-u", "-c", + 'import sys,os;' + #SETBINARY + 'sys.stdout.write("line1\\n");' 'sys.stdout.flush();' 'sys.stdout.write("line2\\r");' @@ -503,8 +504,9 @@ class ProcessTestCase(BaseTestCase): def test_universal_newlines_communicate(self): # universal newlines through communicate() - p = subprocess.Popen([sys.executable, "-c", - 'import sys,os;' + SETBINARY + + # NB. replaced SETBINARY with the -u flag + p = subprocess.Popen([sys.executable, "-u", "-c", + 'import sys,os;' + #SETBINARY + 'sys.stdout.write("line1\\n");' 'sys.stdout.flush();' 'sys.stdout.write("line2\\r");' @@ -1139,6 +1141,7 @@ class POSIXProcessTestCase(BaseTestCase) ident = id(p) pid = p.pid del p + test_support.gc_collect() # check that p is in the active processes list self.assertIn(ident, [id(o) for o in subprocess._active]) @@ -1158,6 +1161,7 @@ class POSIXProcessTestCase(BaseTestCase) ident = id(p) pid = p.pid del p + test_support.gc_collect() os.kill(pid, signal.SIGKILL) # check that p is in the active processes list self.assertIn(ident, [id(o) for o in subprocess._active]) diff -r 63bbe9f80909 Lib/test/test_sunau.py --- a/Lib/test/test_sunau.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_sunau.py Tue Sep 15 13:09:43 2015 +0300 @@ -94,7 +94,7 @@ class SunauULAWTest(SunauTest, unittest. def test_main(): run_unittest(SunauPCM8Test, SunauPCM16Test, SunauPCM16Test, - SunauPCM32Test, SunauULAWTest) + SunauPCM32Test)#, SunauULAWTest) unimpl funcs in lib_pypy/audioop.py if __name__ == "__main__": test_main() diff -r 63bbe9f80909 Lib/test/test_support.py --- a/Lib/test/test_support.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_support.py Tue Sep 15 13:09:43 2015 +0300 @@ -732,16 +732,20 @@ def temp_cwd(name='tempcwd', quiet=False rmtree(name) -def findfile(file, here=__file__, subdir=None): +def findfile(file, here=None, subdir=None): """Try to find a file on sys.path and the working directory. If it is not found the argument passed to the function is returned (this does not necessarily signal failure; could still be the legitimate path).""" + import test if os.path.isabs(file): return file if subdir is not None: file = os.path.join(subdir, file) path = sys.path - path = [os.path.dirname(here)] + path + if here is None: + path = test.__path__ + path + else: + path = [os.path.dirname(here)] + path for dn in path: fn = os.path.join(dn, file) if os.path.exists(fn): return fn @@ -1389,12 +1393,29 @@ def check_impl_detail(**guards): guards, default = _parse_guards(guards) return guards.get(platform.python_implementation().lower(), default) +# ---------------------------------- +# PyPy extension: you can run:: +# python ..../test_foo.py --pdb +# to get a pdb prompt in case of exceptions +ResultClass = unittest.TextTestRunner.resultclass + +class TestResultWithPdb(ResultClass): + + def addError(self, testcase, exc_info): + ResultClass.addError(self, testcase, exc_info) + if '--pdb' in sys.argv: + import pdb, traceback + traceback.print_tb(exc_info[2]) + pdb.post_mortem(exc_info[2]) + +# ---------------------------------- def _run_suite(suite): """Run tests from a unittest.TestSuite-derived class.""" if verbose: - runner = unittest.TextTestRunner(sys.stdout, verbosity=2) + runner = unittest.TextTestRunner(sys.stdout, verbosity=2, + resultclass=TestResultWithPdb) else: runner = BasicTestRunner() @@ -1410,6 +1431,34 @@ def _run_suite(suite): err += "; run in verbose mode for details" raise TestFailed(err) +# ---------------------------------- +# PyPy extension: you can run:: +# python ..../test_foo.py --filter bar +# to run only the test cases whose name contains bar + +def filter_maybe(suite): + try: + i = sys.argv.index('--filter') + filter = sys.argv[i+1] + except (ValueError, IndexError): + return suite + tests = [] + for test in linearize_suite(suite): + if filter in test._testMethodName: + tests.append(test) + return unittest.TestSuite(tests) + +def linearize_suite(suite_or_test): + try: + it = iter(suite_or_test) + except TypeError: + yield suite_or_test + return + for subsuite in it: + for item in linearize_suite(subsuite): + yield item + +# ---------------------------------- def run_unittest(*classes): """Run tests from unittest.TestCase-derived classes.""" @@ -1425,6 +1474,7 @@ def run_unittest(*classes): suite.addTest(cls) else: suite.addTest(unittest.makeSuite(cls)) + suite = filter_maybe(suite) _run_suite(suite) #======================================================================= diff -r 63bbe9f80909 Lib/test/test_syntax.py --- a/Lib/test/test_syntax.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_syntax.py Tue Sep 15 13:09:43 2015 +0300 @@ -5,7 +5,8 @@ Here's an example of the sort of thing t >>> def f(x): ... global x Traceback (most recent call last): -SyntaxError: name 'x' is local and global (, line 1) + File "", line 1 +SyntaxError: name 'x' is local and global The tests are all raise SyntaxErrors. They were created by checking each C call that raises SyntaxError. There are several modules that @@ -375,7 +376,7 @@ This should probably raise a better erro In 2.5 there was a missing exception and an assert was triggered in a debug build. The number of blocks must be greater than CO_MAXBLOCKS. SF #1565514 - >>> while 1: + >>> while 1: # doctest:+SKIP ... while 2: ... while 3: ... while 4: diff -r 63bbe9f80909 Lib/test/test_sys.py --- a/Lib/test/test_sys.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_sys.py Tue Sep 15 13:09:43 2015 +0300 @@ -257,6 +257,7 @@ class SysModuleTest(unittest.TestCase): self.assertEqual(sys.getdlopenflags(), oldflags+1) sys.setdlopenflags(oldflags) + @test.test_support.impl_detail("reference counting") def test_refcount(self): # n here must be a global in order for this test to pass while # tracing with a python function. Tracing calls PyFrame_FastToLocals @@ -280,7 +281,7 @@ class SysModuleTest(unittest.TestCase): is sys._getframe().f_code ) - # sys._current_frames() is a CPython-only gimmick. + @test.test_support.impl_detail("current_frames") def test_current_frames(self): have_threads = True try: @@ -376,7 +377,10 @@ class SysModuleTest(unittest.TestCase): self.assertEqual(len(sys.float_info), 11) self.assertEqual(sys.float_info.radix, 2) self.assertEqual(len(sys.long_info), 2) - self.assertTrue(sys.long_info.bits_per_digit % 5 == 0) + if test.test_support.check_impl_detail(cpython=True): + self.assertTrue(sys.long_info.bits_per_digit % 5 == 0) + else: + self.assertTrue(sys.long_info.bits_per_digit >= 1) self.assertTrue(sys.long_info.sizeof_digit >= 1) self.assertEqual(type(sys.long_info.bits_per_digit), int) self.assertEqual(type(sys.long_info.sizeof_digit), int) diff -r 63bbe9f80909 Lib/test/test_sys_settrace.py --- a/Lib/test/test_sys_settrace.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_sys_settrace.py Tue Sep 15 13:09:43 2015 +0300 @@ -213,12 +213,16 @@ def generator_function(): "finally" def generator_example(): # any() will leave the generator before its end - x = any(generator_function()) + x = any(generator_function()); gc.collect() # the following lines were not traced for x in range(10): y = x +# On CPython, when the generator is decref'ed to zero, we see the trace +# for the "finally:" portion. On PyPy, we don't see it before the next +# garbage collection. That's why we put gc.collect() on the same line above. + generator_example.events = ([(0, 'call'), (2, 'line'), (-6, 'call'), @@ -323,17 +327,24 @@ class TraceTestCase(unittest.TestCase): self.run_test(tighterloop_example) def test_13_genexp(self): - self.run_test(generator_example) - # issue1265: if the trace function contains a generator, - # and if the traced function contains another generator - # that is not completely exhausted, the trace stopped. - # Worse: the 'finally' clause was not invoked. - tracer = Tracer() - sys.settrace(tracer.traceWithGenexp) - generator_example() - sys.settrace(None) - self.compare_events(generator_example.__code__.co_firstlineno, - tracer.events, generator_example.events) + if self.using_gc: + test_support.gc_collect() + gc.enable() + try: + self.run_test(generator_example) + # issue1265: if the trace function contains a generator, + # and if the traced function contains another generator + # that is not completely exhausted, the trace stopped. + # Worse: the 'finally' clause was not invoked. + tracer = Tracer() + sys.settrace(tracer.traceWithGenexp) + generator_example() + sys.settrace(None) + self.compare_events(generator_example.__code__.co_firstlineno, + tracer.events, generator_example.events) + finally: + if self.using_gc: + gc.disable() def test_14_onliner_if(self): def onliners(): diff -r 63bbe9f80909 Lib/test/test_sysconfig.py --- a/Lib/test/test_sysconfig.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_sysconfig.py Tue Sep 15 13:09:43 2015 +0300 @@ -7,7 +7,8 @@ import shutil import subprocess from copy import copy, deepcopy -from test.test_support import run_unittest, TESTFN, unlink, get_attribute +from test.test_support import (run_unittest, TESTFN, unlink, get_attribute, + import_module, check_impl_detail) import sysconfig from sysconfig import (get_paths, get_platform, get_config_vars, @@ -221,6 +222,15 @@ class TestSysConfig(unittest.TestCase): '-dynamic -DNDEBUG -g -O3'%(arch,)) self.assertEqual(get_platform(), 'macosx-10.4-%s'%(arch,)) + + # macosx with ARCHFLAGS set and empty _CONFIG_VARS + os.environ['ARCHFLAGS'] = '-arch i386' + sysconfig._CONFIG_VARS = None + + # this will attempt to recreate the _CONFIG_VARS based on environment + # variables; used to check a problem with the PyPy's _init_posix + # implementation; see: issue 705 + get_config_vars() # linux debian sarge os.name = 'posix' @@ -236,13 +246,18 @@ class TestSysConfig(unittest.TestCase): def test_get_config_h_filename(self): config_h = sysconfig.get_config_h_filename() - self.assertTrue(os.path.isfile(config_h), config_h) + # import_module skips the test when the CPython C Extension API + # appears to not be supported + self.assertTrue(os.path.isfile(config_h) or + not import_module('_testcapi'), config_h) def test_get_scheme_names(self): wanted = ('nt', 'nt_user', 'os2', 'os2_home', 'osx_framework_user', - 'posix_home', 'posix_prefix', 'posix_user') + 'posix_home', 'posix_prefix', 'posix_user', 'pypy') self.assertEqual(get_scheme_names(), wanted) + @unittest.skipIf(check_impl_detail(pypy=True), + 'Test is not PyPy compatible') @unittest.skipIf(sys.platform.startswith('win'), 'Test is not Windows compatible') def test_get_makefile_filename(self): diff -r 63bbe9f80909 Lib/test/test_tarfile.py --- a/Lib/test/test_tarfile.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_tarfile.py Tue Sep 15 13:09:43 2015 +0300 @@ -43,7 +43,8 @@ class ReadTest(unittest.TestCase): mode = "r:" def setUp(self): - self.tar = tarfile.open(self.tarname, mode=self.mode, encoding="iso8859-1") + self.tar = tarfile.open(self.tarname, mode=self.mode, + encoding="iso8859-1") def tearDown(self): self.tar.close() @@ -60,12 +61,13 @@ class UstarReadTest(ReadTest): def test_fileobj_readlines(self): self.tar.extract("ustar/regtype", TEMPDIR) + with open(os.path.join(TEMPDIR, "ustar/regtype"), "rU") as fobj1: + lines1 = fobj1.readlines() + tarinfo = self.tar.getmember("ustar/regtype") - fobj1 = open(os.path.join(TEMPDIR, "ustar/regtype"), "rU") fobj2 = self.tar.extractfile(tarinfo) + lines2 = fobj2.readlines() - lines1 = fobj1.readlines() - lines2 = fobj2.readlines() self.assertTrue(lines1 == lines2, "fileobj.readlines() failed") self.assertTrue(len(lines2) == 114, @@ -76,19 +78,20 @@ class UstarReadTest(ReadTest): def test_fileobj_iter(self): self.tar.extract("ustar/regtype", TEMPDIR) + with open(os.path.join(TEMPDIR, "ustar/regtype"), "rU") as fobj1: + lines1 = fobj1.readlines() + tarinfo = self.tar.getmember("ustar/regtype") - fobj1 = open(os.path.join(TEMPDIR, "ustar/regtype"), "rU") fobj2 = self.tar.extractfile(tarinfo) - lines1 = fobj1.readlines() lines2 = [line for line in fobj2] + self.assertTrue(lines1 == lines2, "fileobj.__iter__() failed") def test_fileobj_seek(self): self.tar.extract("ustar/regtype", TEMPDIR) - fobj = open(os.path.join(TEMPDIR, "ustar/regtype"), "rb") - data = fobj.read() - fobj.close() + with open(os.path.join(TEMPDIR, "ustar/regtype"), "rb") as fobj: + data = fobj.read() tarinfo = self.tar.getmember("ustar/regtype") fobj = self.tar.extractfile(tarinfo) @@ -147,13 +150,15 @@ class UstarReadTest(ReadTest): self._test_fileobj_link("ustar/lnktype", "ustar/regtype") def test_fileobj_link2(self): - self._test_fileobj_link("./ustar/linktest2/lnktype", "ustar/linktest1/regtype") + self._test_fileobj_link("./ustar/linktest2/lnktype", + "ustar/linktest1/regtype") def test_fileobj_symlink1(self): self._test_fileobj_link("ustar/symtype", "ustar/regtype") def test_fileobj_symlink2(self): - self._test_fileobj_link("./ustar/linktest2/symtype", "ustar/linktest1/regtype") + self._test_fileobj_link("./ustar/linktest2/symtype", + "ustar/linktest1/regtype") def test_issue14160(self): self._test_fileobj_link("symtype2", "ustar/regtype") @@ -240,19 +245,24 @@ class CommonReadTest(ReadTest): # This test checks if tarfile.open() is able to open an empty tar # archive successfully. Note that an empty tar archive is not the # same as an empty file! - tarfile.open(tmpname, self.mode.replace("r", "w")).close() + with tarfile.open(tmpname, self.mode.replace("r", "w")): + pass try: tar = tarfile.open(tmpname, self.mode) tar.getnames() except tarfile.ReadError: self.fail("tarfile.open() failed on empty archive") - self.assertListEqual(tar.getmembers(), []) + else: + self.assertListEqual(tar.getmembers(), []) + finally: + tar.close() def test_null_tarfile(self): # Test for issue6123: Allow opening empty archives. # This test guarantees that tarfile.open() does not treat an empty # file as an empty tar archive. - open(tmpname, "wb").close() + with open(tmpname, "wb"): + pass self.assertRaises(tarfile.ReadError, tarfile.open, tmpname, self.mode) self.assertRaises(tarfile.ReadError, tarfile.open, tmpname) @@ -276,15 +286,17 @@ class CommonReadTest(ReadTest): for char in ('\0', 'a'): # Test if EOFHeaderError ('\0') and InvalidHeaderError ('a') # are ignored correctly. - fobj = _open(tmpname, "wb") - fobj.write(char * 1024) - fobj.write(tarfile.TarInfo("foo").tobuf()) - fobj.close() + with _open(tmpname, "wb") as fobj: + fobj.write(char * 1024) + fobj.write(tarfile.TarInfo("foo").tobuf()) tar = tarfile.open(tmpname, mode="r", ignore_zeros=True) - self.assertListEqual(tar.getnames(), ["foo"], - "ignore_zeros=True should have skipped the %r-blocks" % char) - tar.close() + try: + self.assertListEqual(tar.getnames(), ["foo"], + "ignore_zeros=True should have skipped the %r-blocks" % + char) + finally: + tar.close() def test_premature_end_of_archive(self): for size in (512, 600, 1024, 1200): @@ -315,23 +327,25 @@ class MiscReadTest(CommonReadTest): taropen = tarfile.TarFile.taropen def test_no_name_argument(self): - fobj = open(self.tarname, "rb") - tar = tarfile.open(fileobj=fobj, mode=self.mode) - self.assertEqual(tar.name, os.path.abspath(fobj.name)) + with open(self.tarname, "rb") as fobj: + with tarfile.open(fileobj=fobj, mode=self.mode) as tar: + self.assertEqual(tar.name, os.path.abspath(fobj.name)) def test_no_name_attribute(self): - data = open(self.tarname, "rb").read() + with open(self.tarname, "rb") as fobj: + data = fobj.read() fobj = StringIO.StringIO(data) self.assertRaises(AttributeError, getattr, fobj, "name") tar = tarfile.open(fileobj=fobj, mode=self.mode) self.assertEqual(tar.name, None) def test_empty_name_attribute(self): - data = open(self.tarname, "rb").read() + with open(self.tarname, "rb") as fobj: + data = fobj.read() fobj = StringIO.StringIO(data) fobj.name = "" - tar = tarfile.open(fileobj=fobj, mode=self.mode) - self.assertEqual(tar.name, None) + with tarfile.open(fileobj=fobj, mode=self.mode) as tar: + self.assertEqual(tar.name, None) def test_illegal_mode_arg(self): with open(tmpname, 'wb'): @@ -348,12 +362,14 @@ class MiscReadTest(CommonReadTest): # Skip the first member and store values from the second member # of the testtar. tar = tarfile.open(self.tarname, mode=self.mode) - tar.next() - t = tar.next() - name = t.name - offset = t.offset - data = tar.extractfile(t).read() - tar.close() + try: + tar.next() + t = tar.next() + name = t.name + offset = t.offset + data = tar.extractfile(t).read() + finally: + tar.close() # Open the testtar and seek to the offset of the second member. if self.mode.endswith(":gz"): @@ -362,27 +378,28 @@ class MiscReadTest(CommonReadTest): _open = bz2.BZ2File else: _open = open - fobj = _open(self.tarname, "rb") - fobj.seek(offset) + with _open(self.tarname, "rb") as fobj: + fobj.seek(offset) - # Test if the tarfile starts with the second member. - tar = tar.open(self.tarname, mode="r:", fileobj=fobj) - t = tar.next() - self.assertEqual(t.name, name) - # Read to the end of fileobj and test if seeking back to the - # beginning works. - tar.getmembers() - self.assertEqual(tar.extractfile(t).read(), data, - "seek back did not work") - tar.close() + # Test if the tarfile starts with the second member. + tar = tar.open(self.tarname, mode="r:", fileobj=fobj) + t = tar.next() + self.assertEqual(t.name, name) + # Read to the end of fileobj and test if seeking back to the + # beginning works. + tar.getmembers() + self.assertEqual(tar.extractfile(t).read(), data, + "seek back did not work") + tar.close() def test_fail_comp(self): # For Gzip and Bz2 Tests: fail with a ReadError on an uncompressed file. if self.mode == "r:": self.skipTest('needs a gz or bz2 mode') self.assertRaises(tarfile.ReadError, tarfile.open, tarname, self.mode) - fobj = open(tarname, "rb") - self.assertRaises(tarfile.ReadError, tarfile.open, fileobj=fobj, mode=self.mode) + with open(tarname, "rb") as fobj: + self.assertRaises(tarfile.ReadError, tarfile.open, + fileobj=fobj, mode=self.mode) def test_v7_dirtype(self): # Test old style dirtype member (bug #1336623): @@ -418,16 +435,16 @@ class MiscReadTest(CommonReadTest): # Test hardlink extraction (e.g. bug #857297). 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")) + self.addCleanup(test_support.unlink, os.path.join(TEMPDIR, "ustar/regtype")) tar.extract("ustar/lnktype", TEMPDIR) - self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/lnktype")) + self.addCleanup(test_support.unlink, 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) tar.extract("ustar/symtype", TEMPDIR) - self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/symtype")) + self.addCleanup(test_support.unlink, 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) @@ -436,22 +453,25 @@ class MiscReadTest(CommonReadTest): # Test if extractall() correctly restores directory permissions # and times (see issue1735). tar = tarfile.open(tarname, encoding="iso8859-1") - directories = [t for t in tar if t.isdir()] - tar.extractall(TEMPDIR, directories) - for tarinfo in directories: - path = os.path.join(TEMPDIR, tarinfo.name) - if sys.platform != "win32": - # Win32 has no support for fine grained permissions. - self.assertEqual(tarinfo.mode & 0777, os.stat(path).st_mode & 0777) - self.assertEqual(tarinfo.mtime, os.path.getmtime(path)) - tar.close() + try: + directories = [t for t in tar if t.isdir()] + tar.extractall(TEMPDIR, directories) + for tarinfo in directories: + path = os.path.join(TEMPDIR, tarinfo.name) + if sys.platform != "win32": + # Win32 has no support for fine grained permissions. + self.assertEqual(tarinfo.mode & 0777, os.stat(path).st_mode & 0777) + self.assertEqual(tarinfo.mtime, os.path.getmtime(path)) + finally: + tar.close() def test_init_close_fobj(self): # Issue #7341: Close the internal file object in the TarFile # constructor in case of an error. For the test we rely on # the fact that opening an empty file raises a ReadError. empty = os.path.join(TEMPDIR, "empty") - open(empty, "wb").write("") + with open(empty, "wb") as fobj: + fobj.write(b"") try: tar = object.__new__(tarfile.TarFile) @@ -462,7 +482,7 @@ class MiscReadTest(CommonReadTest): else: self.fail("ReadError not raised") finally: - os.remove(empty) + test_support.unlink(empty) def test_parallel_iteration(self): # Issue #16601: Restarting iteration over tarfile continued @@ -491,42 +511,50 @@ class StreamReadTest(CommonReadTest): def test_compare_members(self): tar1 = tarfile.open(tarname, encoding="iso8859-1") - tar2 = self.tar + try: + tar2 = self.tar - while True: - t1 = tar1.next() - t2 = tar2.next() - if t1 is None: - break - self.assertTrue(t2 is not None, "stream.next() failed.") + while True: + t1 = tar1.next() + t2 = tar2.next() + if t1 is None: + break + self.assertIsNotNone(t2, "stream.next() failed.") - if t2.islnk() or t2.issym(): - self.assertRaises(tarfile.StreamError, tar2.extractfile, t2) - continue + if t2.islnk() or t2.issym(): + with self.assertRaises(tarfile.StreamError): + tar2.extractfile(t2) + continue - v1 = tar1.extractfile(t1) - v2 = tar2.extractfile(t2) - if v1 is None: - continue - self.assertTrue(v2 is not None, "stream.extractfile() failed") - self.assertTrue(v1.read() == v2.read(), "stream extraction failed") - - tar1.close() + v1 = tar1.extractfile(t1) + v2 = tar2.extractfile(t2) + if v1 is None: + continue + self.assertIsNotNone(v2, "stream.extractfile() failed") + self.assertEqual(v1.read(), v2.read(), + "stream extraction failed") + finally: + tar1.close() class DetectReadTest(unittest.TestCase): def _testfunc_file(self, name, mode): try: - tarfile.open(name, mode) - except tarfile.ReadError: + tar = tarfile.open(name, mode) + except tarfile.ReadError as e: self.fail() + else: + tar.close() def _testfunc_fileobj(self, name, mode): try: - tarfile.open(name, mode, fileobj=open(name, "rb")) - except tarfile.ReadError: + with open(name, "rb") as f: + tar = tarfile.open(name, mode, fileobj=f) + except tarfile.ReadError as e: self.fail() + else: + tar.close() def _test_modes(self, testfunc): testfunc(tarname, "r") @@ -652,7 +680,9 @@ class MemberReadTest(ReadTest): self._test_member(tarinfo, size=7011, chksum=md5_regtype) def test_find_pax_umlauts(self): - self.tar = tarfile.open(self.tarname, mode=self.mode, encoding="iso8859-1") + self.tar.close() + self.tar = tarfile.open(self.tarname, mode=self.mode, + encoding="iso8859-1") tarinfo = self.tar.getmember("pax/umlauts-ÄÖÜäöüß") self._test_member(tarinfo, size=7011, chksum=md5_regtype) @@ -683,17 +713,18 @@ class LongnameTest(ReadTest): offset = tarinfo.offset self.tar.fileobj.seek(offset) fobj = StringIO.StringIO(self.tar.fileobj.read(3 * 512)) - self.assertRaises(tarfile.ReadError, tarfile.open, name="foo.tar", fileobj=fobj) + with self.assertRaises(tarfile.ReadError): + tarfile.open(name="foo.tar", fileobj=fobj) def test_header_offset(self): # Test if the start offset of the TarInfo object includes # the preceding extended header. longname = self.subdir + "/" + "123/" * 125 + "longname" offset = self.tar.getmember(longname).offset - fobj = open(tarname) - fobj.seek(offset) - tarinfo = tarfile.TarInfo.frombuf(fobj.read(512)) - self.assertEqual(tarinfo.type, self.longnametype) + with open(tarname, "rb") as fobj: + fobj.seek(offset) + tarinfo = tarfile.TarInfo.frombuf(fobj.read(512)) + self.assertEqual(tarinfo.type, self.longnametype) class GNUReadTest(LongnameTest): @@ -775,99 +806,117 @@ class WriteTest(WriteTestBase): # a trailing '\0'. name = "0123456789" * 10 tar = tarfile.open(tmpname, self.mode) - t = tarfile.TarInfo(name) - tar.addfile(t) - tar.close() + try: + t = tarfile.TarInfo(name) + tar.addfile(t) + finally: + tar.close() tar = tarfile.open(tmpname) - self.assertTrue(tar.getnames()[0] == name, - "failed to store 100 char filename") - tar.close() + try: + self.assertTrue(tar.getnames()[0] == name, + "failed to store 100 char filename") + finally: + tar.close() def test_tar_size(self): # Test for bug #1013882. tar = tarfile.open(tmpname, self.mode) - path = os.path.join(TEMPDIR, "file") - fobj = open(path, "wb") - fobj.write("aaa") - fobj.close() - tar.add(path) - tar.close() + try: + path = os.path.join(TEMPDIR, "file") + with open(path, "wb") as fobj: + fobj.write(b"aaa") + tar.add(path) + finally: + tar.close() self.assertTrue(os.path.getsize(tmpname) > 0, "tarfile is empty") # The test_*_size tests test for bug #1167128. def test_file_size(self): tar = tarfile.open(tmpname, self.mode) + try: + path = os.path.join(TEMPDIR, "file") + with open(path, "wb"): + pass + tarinfo = tar.gettarinfo(path) + self.assertEqual(tarinfo.size, 0) - path = os.path.join(TEMPDIR, "file") - fobj = open(path, "wb") - fobj.close() - tarinfo = tar.gettarinfo(path) - self.assertEqual(tarinfo.size, 0) - - fobj = open(path, "wb") - fobj.write("aaa") - fobj.close() - tarinfo = tar.gettarinfo(path) - self.assertEqual(tarinfo.size, 3) - - tar.close() + with open(path, "wb") as fobj: + fobj.write(b"aaa") + tarinfo = tar.gettarinfo(path) + self.assertEqual(tarinfo.size, 3) + finally: + tar.close() def test_directory_size(self): path = os.path.join(TEMPDIR, "directory") os.mkdir(path) try: tar = tarfile.open(tmpname, self.mode) - tarinfo = tar.gettarinfo(path) - self.assertEqual(tarinfo.size, 0) + try: + tarinfo = tar.gettarinfo(path) + self.assertEqual(tarinfo.size, 0) + finally: + tar.close() finally: os.rmdir(path) + @unittest.skipUnless(hasattr(os, "link"), + "Missing hardlink implementation") def test_link_size(self): - if hasattr(os, "link"): - link = os.path.join(TEMPDIR, "link") - target = os.path.join(TEMPDIR, "link_target") - fobj = open(target, "wb") - fobj.write("aaa") - fobj.close() - os.link(target, link) + link = os.path.join(TEMPDIR, "link") + target = os.path.join(TEMPDIR, "link_target") + with open(target, "wb") as fobj: + fobj.write(b"aaa") + os.link(target, link) + try: + tar = tarfile.open(tmpname, self.mode) try: - tar = tarfile.open(tmpname, self.mode) # Record the link target in the inodes list. tar.gettarinfo(target) tarinfo = tar.gettarinfo(link) self.assertEqual(tarinfo.size, 0) finally: - os.remove(target) - os.remove(link) + tar.close() + finally: + os.remove(target) + os.remove(link) + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") def test_symlink_size(self): - if hasattr(os, "symlink"): - path = os.path.join(TEMPDIR, "symlink") - os.symlink("link_target", path) + path = os.path.join(TEMPDIR, "symlink") + os.symlink("link_target", path) + try: + tar = tarfile.open(tmpname, self.mode) try: - tar = tarfile.open(tmpname, self.mode) tarinfo = tar.gettarinfo(path) self.assertEqual(tarinfo.size, 0) finally: - os.remove(path) + tar.close() + finally: + os.remove(path) def test_add_self(self): # Test for #1257255. dstname = os.path.abspath(tmpname) + tar = tarfile.open(tmpname, self.mode) + try: + self.assertEqual(tar.name, dstname, + "archive name must be absolute") + tar.add(dstname) + self.assertEqual(tar.getnames(), [], + "added the archive to itself") - tar = tarfile.open(tmpname, self.mode) - self.assertTrue(tar.name == dstname, "archive name must be absolute") - - tar.add(dstname) - self.assertTrue(tar.getnames() == [], "added the archive to itself") - - cwd = os.getcwd() - os.chdir(TEMPDIR) - tar.add(dstname) - os.chdir(cwd) - self.assertTrue(tar.getnames() == [], "added the archive to itself") + cwd = os.getcwd() + os.chdir(TEMPDIR) + tar.add(dstname) + os.chdir(cwd) + self.assertEqual(tar.getnames(), [], + "added the archive to itself") + finally: + tar.close() def test_exclude(self): tempdir = os.path.join(TEMPDIR, "exclude") @@ -880,14 +929,19 @@ class WriteTest(WriteTestBase): exclude = os.path.isfile tar = tarfile.open(tmpname, self.mode, encoding="iso8859-1") - with test_support.check_warnings(("use the filter argument", - DeprecationWarning)): - tar.add(tempdir, arcname="empty_dir", exclude=exclude) - tar.close() + try: + with test_support.check_warnings(("use the filter argument", + DeprecationWarning)): + tar.add(tempdir, arcname="empty_dir", exclude=exclude) + finally: + tar.close() tar = tarfile.open(tmpname, "r") - self.assertEqual(len(tar.getmembers()), 1) - self.assertEqual(tar.getnames()[0], "empty_dir") + try: + self.assertEqual(len(tar.getmembers()), 1) + self.assertEqual(tar.getnames()[0], "empty_dir") + finally: + tar.close() finally: shutil.rmtree(tempdir) @@ -907,15 +961,19 @@ class WriteTest(WriteTestBase): return tarinfo tar = tarfile.open(tmpname, self.mode, encoding="iso8859-1") - tar.add(tempdir, arcname="empty_dir", filter=filter) - tar.close() + try: + tar.add(tempdir, arcname="empty_dir", filter=filter) + finally: + tar.close() tar = tarfile.open(tmpname, "r") - for tarinfo in tar: - self.assertEqual(tarinfo.uid, 123) - self.assertEqual(tarinfo.uname, "foo") - self.assertEqual(len(tar.getmembers()), 3) - tar.close() + try: + for tarinfo in tar: + self.assertEqual(tarinfo.uid, 123) + self.assertEqual(tarinfo.uname, "foo") + self.assertEqual(len(tar.getmembers()), 3) + finally: + tar.close() finally: shutil.rmtree(tempdir) @@ -933,12 +991,16 @@ class WriteTest(WriteTestBase): os.mkdir(foo) tar = tarfile.open(tmpname, self.mode) - tar.add(foo, arcname=path) - tar.close() + try: + tar.add(foo, arcname=path) + finally: + tar.close() tar = tarfile.open(tmpname, "r") - t = tar.next() - tar.close() + try: + t = tar.next() + finally: + tar.close() if not dir: os.remove(foo) @@ -1105,7 +1167,8 @@ class StreamWriteTest(WriteTestBase): fobj.close() elif self.mode.endswith("bz2"): dec = bz2.BZ2Decompressor() - data = open(tmpname, "rb").read() + with open(tmpname, "rb") as fobj: + data = fobj.read() data = dec.decompress(data) self.assertTrue(len(dec.unused_data) == 0, "found trailing data") @@ -1183,13 +1246,16 @@ class GNUWriteTest(unittest.TestCase): tar.close() tar = tarfile.open(tmpname) - member = tar.next() - self.assertIsNotNone(member, - "unable to read longname member") - self.assertEqual(tarinfo.name, member.name, - "unable to read longname member") - self.assertEqual(tarinfo.linkname, member.linkname, - "unable to read longname member") + try: + member = tar.next() + self.assertIsNotNone(member, + "unable to read longname member") + self.assertEqual(tarinfo.name, member.name, + "unable to read longname member") + self.assertEqual(tarinfo.linkname, member.linkname, + "unable to read longname member") + finally: + tar.close() def test_longname_1023(self): self._test(("longnam/" * 127) + "longnam") @@ -1276,12 +1342,15 @@ class PaxWriteTest(GNUWriteTest): tar.close() tar = tarfile.open(tmpname) - if link: - l = tar.getmembers()[0].linkname - self.assertTrue(link == l, "PAX longlink creation failed") - else: - n = tar.getmembers()[0].name - self.assertTrue(name == n, "PAX longname creation failed") + try: + if link: + l = tar.getmembers()[0].linkname + self.assertTrue(link == l, "PAX longlink creation failed") + else: + n = tar.getmembers()[0].name + self.assertTrue(name == n, "PAX longname creation failed") + finally: + tar.close() def test_pax_global_header(self): pax_headers = { @@ -1298,37 +1367,45 @@ class PaxWriteTest(GNUWriteTest): # Test if the global header was written correctly. tar = tarfile.open(tmpname, encoding="iso8859-1") - self.assertEqual(tar.pax_headers, pax_headers) - self.assertEqual(tar.getmembers()[0].pax_headers, pax_headers) - - # Test if all the fields are unicode. - for key, val in tar.pax_headers.iteritems(): - self.assertTrue(type(key) is unicode) - self.assertTrue(type(val) is unicode) - if key in tarfile.PAX_NUMBER_FIELDS: - try: - tarfile.PAX_NUMBER_FIELDS[key](val) - except (TypeError, ValueError): - self.fail("unable to convert pax header field") + try: + self.assertEqual(tar.pax_headers, pax_headers) + self.assertEqual(tar.getmembers()[0].pax_headers, pax_headers) + # Test if all the fields are unicode. + for key, val in tar.pax_headers.iteritems(): + self.assertTrue(type(key) is unicode) + self.assertTrue(type(val) is unicode) + if key in tarfile.PAX_NUMBER_FIELDS: + try: + tarfile.PAX_NUMBER_FIELDS[key](val) + except (TypeError, ValueError): + self.fail("unable to convert pax header field") + finally: + tar.close() def test_pax_extended_header(self): # The fields from the pax header have priority over the # TarInfo. pax_headers = {u"path": u"foo", u"uid": u"123"} - tar = tarfile.open(tmpname, "w", format=tarfile.PAX_FORMAT, encoding="iso8859-1") - t = tarfile.TarInfo() - t.name = u"äöü" # non-ASCII - t.uid = 8**8 # too large - t.pax_headers = pax_headers - tar.addfile(t) - tar.close() + tar = tarfile.open(tmpname, "w", format=tarfile.PAX_FORMAT, + encoding="iso8859-1") + try: + t = tarfile.TarInfo() + t.name = u"äöü" # non-ASCII + t.uid = 8**8 # too large + t.pax_headers = pax_headers + tar.addfile(t) + finally: + tar.close() tar = tarfile.open(tmpname, encoding="iso8859-1") - t = tar.getmembers()[0] - self.assertEqual(t.pax_headers, pax_headers) - self.assertEqual(t.name, "foo") - self.assertEqual(t.uid, 123) + try: + t = tar.getmembers()[0] + self.assertEqual(t.pax_headers, pax_headers) + self.assertEqual(t.name, "foo") + self.assertEqual(t.uid, 123) + finally: + tar.close() class UstarUnicodeTest(unittest.TestCase): @@ -1347,40 +1424,51 @@ class UstarUnicodeTest(unittest.TestCase def _test_unicode_filename(self, encoding): tar = tarfile.open(tmpname, "w", format=self.format, encoding=encoding, errors="strict") - name = u"äöü" - tar.addfile(tarfile.TarInfo(name)) - tar.close() + try: + name = u"äöü" + tar.addfile(tarfile.TarInfo(name)) + finally: + tar.close() tar = tarfile.open(tmpname, encoding=encoding) - self.assertTrue(type(tar.getnames()[0]) is not unicode) - self.assertEqual(tar.getmembers()[0].name, name.encode(encoding)) - tar.close() + try: + self.assertTrue(type(tar.getnames()[0]) is not unicode) + self.assertEqual(tar.getmembers()[0].name, name.encode(encoding)) + finally: + tar.close() def test_unicode_filename_error(self): - tar = tarfile.open(tmpname, "w", format=self.format, encoding="ascii", errors="strict") - tarinfo = tarfile.TarInfo() + tar = tarfile.open(tmpname, "w", format=self.format, + encoding="ascii", errors="strict") + try: + tarinfo = tarfile.TarInfo() - tarinfo.name = "äöü" - if self.format == tarfile.PAX_FORMAT: + tarinfo.name = "äöü" + if self.format == tarfile.PAX_FORMAT: + self.assertRaises(UnicodeError, tar.addfile, tarinfo) + else: + tar.addfile(tarinfo) + + tarinfo.name = u"äöü" self.assertRaises(UnicodeError, tar.addfile, tarinfo) - else: - tar.addfile(tarinfo) - tarinfo.name = u"äöü" - self.assertRaises(UnicodeError, tar.addfile, tarinfo) - - tarinfo.name = "foo" - tarinfo.uname = u"äöü" - self.assertRaises(UnicodeError, tar.addfile, tarinfo) + tarinfo.name = "foo" + tarinfo.uname = u"äöü" + self.assertRaises(UnicodeError, tar.addfile, tarinfo) + finally: + tar.close() def test_unicode_argument(self): - tar = tarfile.open(tarname, "r", encoding="iso8859-1", errors="strict") - for t in tar: - self.assertTrue(type(t.name) is str) - self.assertTrue(type(t.linkname) is str) - self.assertTrue(type(t.uname) is str) - self.assertTrue(type(t.gname) is str) - tar.close() + tar = tarfile.open(tarname, "r", + encoding="iso8859-1", errors="strict") + try: + for t in tar: + self.assertTrue(type(t.name) is str) + self.assertTrue(type(t.linkname) is str) + self.assertTrue(type(t.uname) is str) + self.assertTrue(type(t.gname) is str) + finally: + tar.close() def test_uname_unicode(self): for name in (u"äöü", "äöü"): @@ -1426,6 +1514,7 @@ class PaxUnicodeTest(UstarUnicodeTest): tar = tarfile.open(tmpname, format=self.format, encoding="ascii", errors=handler) self.assertEqual(tar.getnames()[0], name) + tar.close() self.assertRaises(UnicodeError, tarfile.open, tmpname, encoding="ascii", errors="strict") @@ -1438,6 +1527,7 @@ class PaxUnicodeTest(UstarUnicodeTest): tar = tarfile.open(tmpname, format=self.format, encoding="iso8859-1", errors="utf-8") self.assertEqual(tar.getnames()[0], "äöü/" + u"¤".encode("utf8")) + tar.close() class AppendTest(unittest.TestCase): @@ -1446,25 +1536,23 @@ class AppendTest(unittest.TestCase): def setUp(self): self.tarname = tmpname if os.path.exists(self.tarname): - os.remove(self.tarname) + test_support.unlink(self.tarname) def _add_testfile(self, fileobj=None): - tar = tarfile.open(self.tarname, "a", fileobj=fileobj) - tar.addfile(tarfile.TarInfo("bar")) - tar.close() + with tarfile.open(self.tarname, "a", fileobj=fileobj) as tar: + tar.addfile(tarfile.TarInfo("bar")) def _create_testtar(self, mode="w:"): - src = tarfile.open(tarname, encoding="iso8859-1") - t = src.getmember("ustar/regtype") - t.name = "foo" - f = src.extractfile(t) - tar = tarfile.open(self.tarname, mode) - tar.addfile(t, f) - tar.close() + with tarfile.open(tarname, encoding="iso8859-1") as src: + t = src.getmember("ustar/regtype") + t.name = "foo" + f = src.extractfile(t) + with tarfile.open(self.tarname, mode) as tar: + tar.addfile(t, f) def _test(self, names=["bar"], fileobj=None): - tar = tarfile.open(self.tarname, fileobj=fileobj) - self.assertEqual(tar.getnames(), names) + with tarfile.open(self.tarname, fileobj=fileobj) as tar: + self.assertEqual(tar.getnames(), names) def test_non_existing(self): self._add_testfile() @@ -1483,7 +1571,8 @@ class AppendTest(unittest.TestCase): def test_fileobj(self): self._create_testtar() - data = open(self.tarname).read() + with open(self.tarname) as fobj: + data = fobj.read() fobj = StringIO.StringIO(data) self._add_testfile(fobj) fobj.seek(0) @@ -1507,7 +1596,8 @@ class AppendTest(unittest.TestCase): # Append mode is supposed to fail if the tarfile to append to # does not end with a zero block. def _test_error(self, data): - open(self.tarname, "wb").write(data) + with open(self.tarname, "wb") as fobj: + fobj.write(data) self.assertRaises(tarfile.ReadError, self._add_testfile) def test_null(self): @@ -1643,15 +1733,14 @@ class ContextManagerTest(unittest.TestCa def test_fileobj(self): # Test that __exit__() did not close the external file # object. - fobj = open(tmpname, "wb") - try: - with tarfile.open(fileobj=fobj, mode="w") as tar: - raise Exception - except: - pass - self.assertFalse(fobj.closed, "external file object was closed") - self.assertTrue(tar.closed, "context manager failed") - fobj.close() + with open(tmpname, "wb") as fobj: + try: + with tarfile.open(fileobj=fobj, mode="w") as tar: + raise Exception + except: + pass + self.assertFalse(fobj.closed, "external file object was closed") + self.assertTrue(tar.closed, "context manager failed") class LinkEmulationTest(ReadTest): @@ -1661,7 +1750,8 @@ class LinkEmulationTest(ReadTest): # the regular files they point to. def _test_link_extraction(self, name): self.tar.extract(name, TEMPDIR) - data = open(os.path.join(TEMPDIR, name), "rb").read() + with open(os.path.join(TEMPDIR, name), "rb") as f: + data = f.read() self.assertEqual(md5sum(data), md5_regtype) def test_hardlink_extraction1(self): diff -r 63bbe9f80909 Lib/test/test_tempfile.py --- a/Lib/test/test_tempfile.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_tempfile.py Tue Sep 15 13:09:43 2015 +0300 @@ -374,6 +374,7 @@ class test__mkstemp_inner(TestBadTempdir dir = tempfile.mkdtemp() try: self.do_create(dir=dir).write("blat") + support.gc_collect() finally: os.rmdir(dir) @@ -709,12 +710,15 @@ class test_mktemp(TC): self.do_create(suf="b") self.do_create(pre="a", suf="b") self.do_create(pre="aa", suf=".txt") + support.gc_collect() def test_many(self): # mktemp can choose many usable file names (stochastic) extant = range(TEST_FILES) for i in extant: extant[i] = self.do_create(pre="aa") + del extant + support.gc_collect() ## def test_warning(self): ## # mktemp issues a warning when used diff -r 63bbe9f80909 Lib/test/test_thread.py --- a/Lib/test/test_thread.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_thread.py Tue Sep 15 13:09:43 2015 +0300 @@ -124,6 +124,7 @@ class ThreadRunningTests(BasicThreadTest del task while not done: time.sleep(0.01) + test_support.gc_collect() self.assertEqual(thread._count(), orig) def test_save_exception_state_on_error(self): diff -r 63bbe9f80909 Lib/test/test_threading.py --- a/Lib/test/test_threading.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_threading.py Tue Sep 15 13:09:43 2015 +0300 @@ -163,6 +163,7 @@ class ThreadTests(BaseTestCase): # PyThreadState_SetAsyncExc() is a CPython-only gimmick, not (currently) # exposed at the Python level. This test relies on ctypes to get at it. + @test.test_support.cpython_only def test_PyThreadState_SetAsyncExc(self): try: import ctypes @@ -266,6 +267,7 @@ class ThreadTests(BaseTestCase): finally: threading._start_new_thread = _start_new_thread + @test.test_support.cpython_only def test_finalize_runnning_thread(self): # Issue 1402: the PyGILState_Ensure / _Release functions may be called # very late on python exit: on deallocation of a running thread for @@ -381,6 +383,7 @@ class ThreadTests(BaseTestCase): finally: sys.setcheckinterval(old_interval) + @test.test_support.cpython_only def test_no_refcycle_through_target(self): class RunSelfFunction(object): def __init__(self, should_raise): @@ -497,6 +500,9 @@ class ThreadJoinOnShutdown(BaseTestCase) def joiningfunc(mainthread): mainthread.join() print 'end of thread' + # stdout is fully buffered because not a tty, we have to flush + # before exit. + sys.stdout.flush() \n""" + script p = subprocess.Popen([sys.executable, "-c", script], stdout=subprocess.PIPE) diff -r 63bbe9f80909 Lib/test/test_threading_local.py --- a/Lib/test/test_threading_local.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_threading_local.py Tue Sep 15 13:09:43 2015 +0300 @@ -168,8 +168,9 @@ class BaseLocalTest: obj = cls() obj.x = 5 self.assertEqual(obj.__dict__, {'x': 5}) - with self.assertRaises(AttributeError): - obj.__dict__ = {} + if support.check_impl_detail(): + with self.assertRaises(AttributeError): + obj.__dict__ = {} with self.assertRaises(AttributeError): del obj.__dict__ diff -r 63bbe9f80909 Lib/test/test_traceback.py --- a/Lib/test/test_traceback.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_traceback.py Tue Sep 15 13:09:43 2015 +0300 @@ -5,6 +5,7 @@ import sys import unittest from imp import reload from test.test_support import run_unittest, is_jython, Error, cpython_only +from test.test_support import check_impl_detail, impl_detail import traceback @@ -51,10 +52,8 @@ class TracebackCases(unittest.TestCase): self.assertTrue(err[2].count('\n') == 1) # and no additional newline self.assertTrue(err[1].find("+") == err[2].find("^")) # in the right place + @impl_detail("other implementations may add a caret (why shouldn't they?)") def test_nocaret(self): - if is_jython: - # jython adds a caret in this case (why shouldn't it?) - return err = self.get_exception_format(self.syntax_error_without_caret, SyntaxError) self.assertTrue(len(err) == 3) @@ -65,8 +64,11 @@ class TracebackCases(unittest.TestCase): IndentationError) self.assertTrue(len(err) == 4) self.assertTrue(err[1].strip() == "print 2") - self.assertIn("^", err[2]) - self.assertTrue(err[1].find("2") == err[2].find("^")) + if check_impl_detail(): + # on CPython, there is a "^" at the end of the line + # on PyPy, there is a "^" too, but at the start, more logically + self.assertIn("^", err[2]) + self.assertTrue(err[1].find("2") == err[2].find("^")) def test_bug737473(self): import os, tempfile, time @@ -76,7 +78,8 @@ class TracebackCases(unittest.TestCase): try: sys.path.insert(0, testdir) testfile = os.path.join(testdir, 'test_bug737473.py') - print >> open(testfile, 'w'), """ + with open(testfile, 'w') as f: + print >> f, """ def test(): raise ValueError""" @@ -98,7 +101,8 @@ def test(): # three seconds are needed for this test to pass reliably :-( time.sleep(4) - print >> open(testfile, 'w'), """ + with open(testfile, 'w') as f: + print >> f, """ def test(): raise NotImplementedError""" reload(test_bug737473) @@ -118,7 +122,10 @@ def test(): self.assertEqual(len(err), 4) self.assertEqual(err[1].strip(), "print(2)") self.assertIn("^", err[2]) - self.assertEqual(err[1].find("p"), err[2].find("^")) + if check_impl_detail(): + self.assertEqual(err[1].find("p"), err[2].find("^")) + if check_impl_detail(pypy=True): + self.assertEqual(err[1].find("2)") + 1, err[2].find("^")) def test_base_exception(self): # Test that exceptions derived from BaseException are formatted right diff -r 63bbe9f80909 Lib/test/test_types.py --- a/Lib/test/test_types.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_types.py Tue Sep 15 13:09:43 2015 +0300 @@ -1,7 +1,8 @@ # Python test set -- part 6, built-in types from test.test_support import run_unittest, have_unicode, run_with_locale, \ - check_py3k_warnings + check_py3k_warnings, \ + impl_detail, check_impl_detail import unittest import sys import locale @@ -289,9 +290,14 @@ class TypesTests(unittest.TestCase): # array.array() returns an object that does not implement a char buffer, # something which int() uses for conversion. import array - try: int(buffer(array.array('c'))) + try: int(buffer(array.array('c', '5'))) except TypeError: pass - else: self.fail("char buffer (at C level) not working") + else: + if check_impl_detail(): + self.fail("char buffer (at C level) not working") + #else: + # it works on PyPy, which does not have the distinction + # between char buffer and binary buffer. XXX fine enough? def test_int__format__(self): def test(i, format_spec, result): @@ -741,6 +747,7 @@ class TypesTests(unittest.TestCase): for code in 'xXobns': self.assertRaises(ValueError, format, 0, ',' + code) + @impl_detail("the types' internal size attributes are CPython-only") def test_internal_sizes(self): self.assertGreater(object.__basicsize__, 0) self.assertGreater(tuple.__itemsize__, 0) diff -r 63bbe9f80909 Lib/test/test_unicode.py --- a/Lib/test/test_unicode.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_unicode.py Tue Sep 15 13:09:43 2015 +0300 @@ -667,10 +667,11 @@ class UnicodeTest( meth('\xff') with self.assertRaises(TypeError) as cm: meth(['f']) - exc = str(cm.exception) - self.assertIn('unicode', exc) - self.assertIn('str', exc) - self.assertIn('tuple', exc) + if test_support.check_impl_detail(): + exc = str(cm.exception) + self.assertIn('unicode', exc) + self.assertIn('str', exc) + self.assertIn('tuple', exc) @test_support.run_with_locale('LC_ALL', 'de_DE', 'fr_FR') def test_format_float(self): @@ -1289,7 +1290,8 @@ class UnicodeTest( @unittest.skipIf(sys.maxint > (1 << 32) or struct.calcsize('P') != 4, 'only applies to 32-bit platforms') def test_expandtabs_overflows_gracefully(self): - self.assertRaises(OverflowError, u't\tt\t'.expandtabs, sys.maxint) + self.assertRaises((OverflowError, MemoryError), + u't\tt\t'.expandtabs, sys.maxint) def test__format__(self): def test(value, format, expected): @@ -1662,6 +1664,10 @@ class UnicodeTest( # Test PyUnicode_FromFormat() def test_from_format(self): test_support.import_module('ctypes') + try: + from ctypes import pythonapi + except ImportError: + self.skipTest( "no pythonapi in ctypes") from ctypes import ( pythonapi, py_object, sizeof, c_int, c_long, c_longlong, c_ssize_t, diff -r 63bbe9f80909 Lib/test/test_unicodedata.py --- a/Lib/test/test_unicodedata.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_unicodedata.py Tue Sep 15 13:09:43 2015 +0300 @@ -233,10 +233,12 @@ class UnicodeMiscTest(UnicodeDatabaseTes # been loaded in this process. popen = subprocess.Popen(args, stderr=subprocess.PIPE) popen.wait() - self.assertEqual(popen.returncode, 1) - error = "SyntaxError: (unicode error) \N escapes not supported " \ - "(can't load unicodedata module)" - self.assertIn(error, popen.stderr.read()) + self.assertIn(popen.returncode, [0, 1]) # at least it did not segfault + if test.test_support.check_impl_detail(): + self.assertEqual(popen.returncode, 1) + error = "SyntaxError: (unicode error) \N escapes not supported " \ + "(can't load unicodedata module)" + self.assertIn(error, popen.stderr.read()) def test_decimal_numeric_consistent(self): # Test that decimal and numeric are consistent, diff -r 63bbe9f80909 Lib/test/test_unpack.py --- a/Lib/test/test_unpack.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_unpack.py Tue Sep 15 13:09:43 2015 +0300 @@ -62,14 +62,14 @@ Unpacking tuple of wrong size >>> a, b = t Traceback (most recent call last): ... - ValueError: too many values to unpack + ValueError: expected length 2, got 3 Unpacking tuple of wrong size >>> a, b = l Traceback (most recent call last): ... - ValueError: too many values to unpack + ValueError: expected length 2, got 3 Unpacking sequence too short diff -r 63bbe9f80909 Lib/test/test_urllib2.py --- a/Lib/test/test_urllib2.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_urllib2.py Tue Sep 15 13:09:43 2015 +0300 @@ -283,12 +283,15 @@ class MockHTTPResponse: self.reason = reason def read(self): return '' + def _reuse(self): pass + def _drop(self): pass class MockHTTPClass: def __init__(self): self.req_headers = [] self.data = None self.raise_on_endheaders = False + self.sock = None self._tunnel_headers = {} def __call__(self, host, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): diff -r 63bbe9f80909 Lib/test/test_urllib2net.py --- a/Lib/test/test_urllib2net.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_urllib2net.py Tue Sep 15 13:09:43 2015 +0300 @@ -253,6 +253,7 @@ class TimeoutTest(unittest.TestCase): with test_support.transient_internet(url, timeout=None): u = _urlopen_with_retry(url) self.assertIsNone(u.fp._sock.fp._sock.gettimeout()) + u.close() def test_http_default_timeout(self): self.assertIsNone(socket.getdefaulttimeout()) @@ -264,6 +265,7 @@ class TimeoutTest(unittest.TestCase): finally: socket.setdefaulttimeout(None) self.assertEqual(u.fp._sock.fp._sock.gettimeout(), 60) + u.close() def test_http_no_timeout(self): self.assertIsNone(socket.getdefaulttimeout()) @@ -275,12 +277,14 @@ class TimeoutTest(unittest.TestCase): finally: socket.setdefaulttimeout(None) self.assertIsNone(u.fp._sock.fp._sock.gettimeout()) + u.close() def test_http_timeout(self): url = "http://www.example.com" with test_support.transient_internet(url): u = _urlopen_with_retry(url, timeout=120) self.assertEqual(u.fp._sock.fp._sock.gettimeout(), 120) + u.close() FTP_HOST = 'ftp://ftp.debian.org/debian/' @@ -289,6 +293,7 @@ class TimeoutTest(unittest.TestCase): with test_support.transient_internet(self.FTP_HOST, timeout=None): u = _urlopen_with_retry(self.FTP_HOST) self.assertIsNone(u.fp.fp._sock.gettimeout()) + u.close() def test_ftp_default_timeout(self): self.assertIsNone(socket.getdefaulttimeout()) @@ -299,6 +304,7 @@ class TimeoutTest(unittest.TestCase): finally: socket.setdefaulttimeout(None) self.assertEqual(u.fp.fp._sock.gettimeout(), 60) + u.close() def test_ftp_no_timeout(self): self.assertIsNone(socket.getdefaulttimeout(),) @@ -309,11 +315,16 @@ class TimeoutTest(unittest.TestCase): finally: socket.setdefaulttimeout(None) self.assertIsNone(u.fp.fp._sock.gettimeout()) + u.close() def test_ftp_timeout(self): with test_support.transient_internet(self.FTP_HOST): - u = _urlopen_with_retry(self.FTP_HOST, timeout=60) + try: + u = _urlopen_with_retry(self.FTP_HOST, timeout=60) + except: + raise self.assertEqual(u.fp.fp._sock.gettimeout(), 60) + u.close() def test_main(): diff -r 63bbe9f80909 Lib/test/test_warnings.py --- a/Lib/test/test_warnings.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_warnings.py Tue Sep 15 13:09:43 2015 +0300 @@ -373,7 +373,8 @@ class CWarnTests(BaseTest, WarnTests): # test_support.import_fresh_module utility function def test_accelerated(self): self.assertFalse(original_warnings is self.module) - self.assertFalse(hasattr(self.module.warn, 'func_code')) + self.assertFalse(hasattr(self.module.warn, 'func_code') and + hasattr(self.module.warn.func_code, 'co_filename')) class PyWarnTests(BaseTest, WarnTests): module = py_warnings @@ -382,7 +383,8 @@ class PyWarnTests(BaseTest, WarnTests): # test_support.import_fresh_module utility function def test_pure_python(self): self.assertFalse(original_warnings is self.module) - self.assertTrue(hasattr(self.module.warn, 'func_code')) + self.assertTrue(hasattr(self.module.warn, 'func_code') and + hasattr(self.module.warn.func_code, 'co_filename')) class WCmdLineTests(unittest.TestCase): diff -r 63bbe9f80909 Lib/test/test_weakref.py --- a/Lib/test/test_weakref.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_weakref.py Tue Sep 15 13:09:43 2015 +0300 @@ -8,6 +8,7 @@ import contextlib import copy from test import test_support +from test.test_support import gc_collect # Used in ReferencesTestCase.test_ref_created_during_del() . ref_from_del = None @@ -93,6 +94,7 @@ class ReferencesTestCase(TestBase): ref1 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback) del o + gc_collect() self.assertIsNone(ref1(), "expected reference to be invalidated") self.assertIsNone(ref2(), "expected reference to be invalidated") self.assertEqual(self.cbcalled, 2, @@ -122,13 +124,16 @@ class ReferencesTestCase(TestBase): ref1 = weakref.proxy(o, self.callback) ref2 = weakref.proxy(o, self.callback) del o + gc_collect() def check(proxy): proxy.bar self.assertRaises(weakref.ReferenceError, check, ref1) self.assertRaises(weakref.ReferenceError, check, ref2) - self.assertRaises(weakref.ReferenceError, bool, weakref.proxy(C())) + ref3 = weakref.proxy(C()) + gc_collect() + self.assertRaises(weakref.ReferenceError, bool, ref3) self.assertEqual(self.cbcalled, 2) def check_basic_ref(self, factory): @@ -145,6 +150,7 @@ class ReferencesTestCase(TestBase): o = factory() ref = weakref.ref(o, self.callback) del o + gc_collect() self.assertEqual(self.cbcalled, 1, "callback did not properly set 'cbcalled'") self.assertIsNone(ref(), @@ -169,6 +175,7 @@ class ReferencesTestCase(TestBase): self.assertEqual(weakref.getweakrefcount(o), 2, "wrong weak ref count for object") del proxy + gc_collect() self.assertEqual(weakref.getweakrefcount(o), 1, "wrong weak ref count for object after deleting proxy") @@ -345,6 +352,7 @@ class ReferencesTestCase(TestBase): "got wrong number of weak reference objects") del ref1, ref2, proxy1, proxy2 + gc_collect() self.assertEqual(weakref.getweakrefcount(o), 0, "weak reference objects not unlinked from" " referent when discarded.") @@ -358,6 +366,7 @@ class ReferencesTestCase(TestBase): ref1 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback) del ref1 + gc_collect() self.assertEqual(weakref.getweakrefs(o), [ref2], "list of refs does not match") @@ -365,10 +374,12 @@ class ReferencesTestCase(TestBase): ref1 = weakref.ref(o, self.callback) ref2 = weakref.ref(o, self.callback) del ref2 + gc_collect() self.assertEqual(weakref.getweakrefs(o), [ref1], "list of refs does not match") del ref1 + gc_collect() self.assertEqual(weakref.getweakrefs(o), [], "list of refs not cleared") @@ -420,13 +431,11 @@ class ReferencesTestCase(TestBase): # when the second attempt to remove the instance from the "list # of all objects" occurs. - import gc - class C(object): pass c = C() - wr = weakref.ref(c, lambda ignore: gc.collect()) + wr = weakref.ref(c, lambda ignore: gc_collect()) del c # There endeth the first part. It gets worse. @@ -434,7 +443,7 @@ class ReferencesTestCase(TestBase): c1 = C() c1.i = C() - wr = weakref.ref(c1.i, lambda ignore: gc.collect()) + wr = weakref.ref(c1.i, lambda ignore: gc_collect()) c2 = C() c2.c1 = c1 @@ -450,8 +459,6 @@ class ReferencesTestCase(TestBase): del c2 def test_callback_in_cycle_1(self): - import gc - class J(object): pass @@ -487,11 +494,9 @@ class ReferencesTestCase(TestBase): # search II.__mro__, but that's NULL. The result was a segfault in # a release build, and an assert failure in a debug build. del I, J, II - gc.collect() + gc_collect() def test_callback_in_cycle_2(self): - import gc - # This is just like test_callback_in_cycle_1, except that II is an # old-style class. The symptom is different then: an instance of an # old-style class looks in its own __dict__ first. 'J' happens to @@ -516,11 +521,9 @@ class ReferencesTestCase(TestBase): I.wr = weakref.ref(J, I.acallback) del I, J, II - gc.collect() + gc_collect() def test_callback_in_cycle_3(self): - import gc - # This one broke the first patch that fixed the last two. In this # case, the objects reachable from the callback aren't also reachable # from the object (c1) *triggering* the callback: you can get to @@ -540,11 +543,9 @@ class ReferencesTestCase(TestBase): c2.wr = weakref.ref(c1, c2.cb) del c1, c2 - gc.collect() + gc_collect() def test_callback_in_cycle_4(self): - import gc - # Like test_callback_in_cycle_3, except c2 and c1 have different # classes. c2's class (C) isn't reachable from c1 then, so protecting # objects reachable from the dying object (c1) isn't enough to stop @@ -568,11 +569,9 @@ class ReferencesTestCase(TestBase): c2.wr = weakref.ref(c1, c2.cb) del c1, c2, C, D - gc.collect() + gc_collect() def test_callback_in_cycle_resurrection(self): - import gc - # Do something nasty in a weakref callback: resurrect objects # from dead cycles. For this to be attempted, the weakref and # its callback must also be part of the cyclic trash (else the @@ -603,7 +602,7 @@ class ReferencesTestCase(TestBase): del c1, c2, C # make them all trash self.assertEqual(alist, []) # del isn't enough to reclaim anything - gc.collect() + gc_collect() # c1.wr and c2.wr were part of the cyclic trash, so should have # been cleared without their callbacks executing. OTOH, the weakref # to C is bound to a function local (wr), and wasn't trash, so that @@ -613,12 +612,10 @@ class ReferencesTestCase(TestBase): self.assertEqual(wr(), None) del alist[:] - gc.collect() + gc_collect() self.assertEqual(alist, []) def test_callbacks_on_callback(self): - import gc - # Set up weakref callbacks *on* weakref callbacks. alist = [] def safe_callback(ignore): @@ -646,12 +643,12 @@ class ReferencesTestCase(TestBase): del callback, c, d, C self.assertEqual(alist, []) # del isn't enough to clean up cycles - gc.collect() + gc_collect() self.assertEqual(alist, ["safe_callback called"]) self.assertEqual(external_wr(), None) del alist[:] - gc.collect() + gc_collect() self.assertEqual(alist, []) def test_gc_during_ref_creation(self): @@ -661,9 +658,11 @@ class ReferencesTestCase(TestBase): self.check_gc_during_creation(weakref.proxy) def check_gc_during_creation(self, makeref): - thresholds = gc.get_threshold() - gc.set_threshold(1, 1, 1) - gc.collect() + if test_support.check_impl_detail(): + import gc + thresholds = gc.get_threshold() + gc.set_threshold(1, 1, 1) + gc_collect() class A: pass @@ -683,7 +682,8 @@ class ReferencesTestCase(TestBase): weakref.ref(referenced, callback) finally: - gc.set_threshold(*thresholds) + if test_support.check_impl_detail(): + gc.set_threshold(*thresholds) def test_ref_created_during_del(self): # Bug #1377858 @@ -703,7 +703,7 @@ class ReferencesTestCase(TestBase): r = weakref.ref(Exception) self.assertRaises(TypeError, r.__init__, 0, 0, 0, 0, 0) # No exception should be raised here - gc.collect() + gc_collect() def test_classes(self): # Check that both old-style classes and new-style classes @@ -716,12 +716,12 @@ class ReferencesTestCase(TestBase): weakref.ref(int) a = weakref.ref(A, l.append) A = None - gc.collect() + gc_collect() self.assertEqual(a(), None) self.assertEqual(l, [a]) b = weakref.ref(B, l.append) B = None - gc.collect() + gc_collect() self.assertEqual(b(), None) self.assertEqual(l, [a, b]) @@ -811,6 +811,7 @@ class SubclassableWeakrefTestCase(TestBa self.assertTrue(mr.called) self.assertEqual(mr.value, 24) del o + gc_collect() self.assertIsNone(mr()) self.assertTrue(mr.called) @@ -827,9 +828,11 @@ class SubclassableWeakrefTestCase(TestBa self.assertEqual(weakref.getweakrefcount(o), 3) refs = weakref.getweakrefs(o) self.assertEqual(len(refs), 3) - self.assertIs(r2, refs[0]) - self.assertIn(r1, refs[1:]) - self.assertIn(r3, refs[1:]) + assert set(refs) == set((r1, r2, r3)) + if test_support.check_impl_detail(): + self.assertIs(r2, refs[0]) + self.assertIn(r1, refs[1:]) + self.assertIn(r3, refs[1:]) def test_subclass_refs_dont_conflate_callbacks(self): class MyRef(weakref.ref): @@ -917,7 +920,7 @@ class MappingTestCase(TestBase): n1 = len(dct) list(it) del it - gc.collect() + test_support.gc_collect() n2 = len(dct) # iteration should prevent garbage collection here # Note that this is a test on an implementation detail. The requirement @@ -935,11 +938,11 @@ class MappingTestCase(TestBase): def check_len_race(self, dict_type, cons): # Extended sanity checks for len() in the face of cyclic collection - self.addCleanup(gc.set_threshold, *gc.get_threshold()) + #self.addCleanup(gc.set_threshold, *gc.get_threshold()) for th in range(1, 100): N = 20 - gc.collect(0) - gc.set_threshold(th, th, th) + test_support.gc_collect() + #gc.set_threshold(th, th, th) items = [RefCycle() for i in range(N)] dct = dict_type(cons(o) for o in items) del items @@ -982,15 +985,18 @@ class MappingTestCase(TestBase): del items1, items2 self.assertEqual(len(dict), self.COUNT) del objects[0] + gc_collect() self.assertEqual(len(dict), (self.COUNT - 1), "deleting object did not cause dictionary update") del objects, o + gc_collect() self.assertEqual(len(dict), 0, "deleting the values did not clear the dictionary") # regression on SF bug #447152: dict = weakref.WeakValueDictionary() self.assertRaises(KeyError, dict.__getitem__, 1) dict[2] = C() + gc_collect() self.assertRaises(KeyError, dict.__getitem__, 2) def test_weak_keys(self): @@ -1011,9 +1017,11 @@ class MappingTestCase(TestBase): del items1, items2 self.assertEqual(len(dict), self.COUNT) del objects[0] + gc_collect() self.assertEqual(len(dict), (self.COUNT - 1), "deleting object did not cause dictionary update") del objects, o + gc_collect() self.assertEqual(len(dict), 0, "deleting the keys did not clear the dictionary") o = Object(42) @@ -1211,13 +1219,13 @@ class MappingTestCase(TestBase): self.assertEqual(len(weakdict), 2) k, v = weakdict.popitem() self.assertEqual(len(weakdict), 1) - if k is key1: + if k == key1: self.assertIs(v, value1) else: self.assertIs(v, value2) k, v = weakdict.popitem() self.assertEqual(len(weakdict), 0) - if k is key1: + if k == key1: self.assertIs(v, value1) else: self.assertIs(v, value2) @@ -1362,6 +1370,7 @@ class MappingTestCase(TestBase): for o in objs: count += 1 del d[o] + gc_collect() self.assertEqual(len(d), 0) self.assertEqual(count, 2) @@ -1402,6 +1411,7 @@ True >>> o is o2 True >>> del o, o2 +>>> gc_collect() >>> print r() None @@ -1454,6 +1464,7 @@ True >>> id2obj(a_id) is a True >>> del a +>>> gc_collect() >>> try: ... id2obj(a_id) ... except KeyError: diff -r 63bbe9f80909 Lib/test/test_weakset.py --- a/Lib/test/test_weakset.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_weakset.py Tue Sep 15 13:09:43 2015 +0300 @@ -67,6 +67,7 @@ class TestWeakSet(unittest.TestCase): self.assertEqual(len(self.s), len(self.d)) self.assertEqual(len(self.fs), 1) del self.obj + test_support.gc_collect() self.assertEqual(len(self.fs), 0) def test_contains(self): @@ -76,6 +77,7 @@ class TestWeakSet(unittest.TestCase): self.assertNotIn(1, self.s) self.assertIn(self.obj, self.fs) del self.obj + test_support.gc_collect() self.assertNotIn(SomeClass('F'), self.fs) def test_union(self): @@ -234,6 +236,7 @@ class TestWeakSet(unittest.TestCase): self.assertEqual(self.s, dup) self.assertRaises(TypeError, self.s.add, []) self.fs.add(Foo()) + test_support.gc_collect() self.assertTrue(len(self.fs) == 1) self.fs.add(self.obj) self.assertTrue(len(self.fs) == 1) @@ -366,10 +369,11 @@ class TestWeakSet(unittest.TestCase): next(it) # Trigger internal iteration # Destroy an item del items[-1] - gc.collect() # just in case + test_support.gc_collect() # We have removed either the first consumed items, or another one self.assertIn(len(list(it)), [len(items), len(items) - 1]) del it + test_support.gc_collect() # The removal has been committed self.assertEqual(len(s), len(items)) @@ -418,7 +422,7 @@ class TestWeakSet(unittest.TestCase): gc.collect() n1 = len(s) del it - gc.collect() + test_support.gc_collect() n2 = len(s) # one item may be kept alive inside the iterator self.assertIn(n1, (0, 1)) @@ -426,11 +430,11 @@ class TestWeakSet(unittest.TestCase): def test_len_race(self): # Extended sanity checks for len() in the face of cyclic collection - self.addCleanup(gc.set_threshold, *gc.get_threshold()) + #self.addCleanup(gc.set_threshold, *gc.get_threshold()) for th in range(1, 100): N = 20 - gc.collect(0) - gc.set_threshold(th, th, th) + test_support.gc_collect() + #gc.set_threshold(th, th, th) items = [RefCycle() for i in range(N)] s = WeakSet(items) del items diff -r 63bbe9f80909 Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_xml_etree.py Tue Sep 15 13:09:43 2015 +0300 @@ -225,9 +225,9 @@ def simpleops(): >>> element.remove(subelement) >>> serialize(element) # 5 '' - >>> element.remove(subelement) + >>> element.remove(subelement) # doctest: +ELLIPSIS Traceback (most recent call last): - ValueError: list.remove(x): x not in list + ValueError: list.remove(... >>> serialize(element) # 6 '' >>> element[0:0] = [subelement, subelement, subelement] @@ -1647,10 +1647,10 @@ def xmltoolkit63(): Check reference leak. >>> xmltoolkit63() - >>> count = sys.getrefcount(None) + >>> count = sys.getrefcount(None) #doctest: +SKIP >>> for i in range(1000): ... xmltoolkit63() - >>> sys.getrefcount(None) - count + >>> sys.getrefcount(None) - count #doctest: +SKIP 0 """ diff -r 63bbe9f80909 Lib/test/test_xmlrpc.py --- a/Lib/test/test_xmlrpc.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_xmlrpc.py Tue Sep 15 13:09:43 2015 +0300 @@ -440,6 +440,7 @@ class BaseServerTestCase(unittest.TestCa def tearDown(self): # wait on the server thread to terminate + test_support.gc_collect() # to close the active connections self.evt.wait(10) # disable traceback reporting diff -r 63bbe9f80909 Lib/test/test_zlib.py --- a/Lib/test/test_zlib.py Sat Sep 12 17:20:47 2015 -0700 +++ b/Lib/test/test_zlib.py Tue Sep 15 13:09:43 2015 +0300 @@ -1,6 +1,7 @@ import unittest from test.test_support import TESTFN, run_unittest, import_module, unlink, requires import binascii +import os import random from test.test_support import precisionbigmemtest, _1G, _4G import sys @@ -106,14 +107,7 @@ class ExceptionTestCase(unittest.TestCas class BaseCompressTestCase(object): def check_big_compress_buffer(self, size, compress_func): - _1M = 1024 * 1024 - fmt = "%%0%dx" % (2 * _1M) - # Generate 10MB worth of random, and expand it by repeating it. - # The assumption is that zlib's memory is not big enough to exploit - # such spread out redundancy. - data = ''.join([binascii.a2b_hex(fmt % random.getrandbits(8 * _1M)) - for i in range(10)]) - data = data * (size // len(data) + 1) + data = os.urandom(size) try: compress_func(data) finally: