[pypy-commit] cffi python3-port: Fix test_c to pass both on Python 2.6-2.7 and on Python 3.3.

arigo noreply at buildbot.pypy.org
Sun Aug 12 18:50:55 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: python3-port
Changeset: r821:2440a94675da
Date: 2012-08-12 18:50 +0200
http://bitbucket.org/cffi/cffi/changeset/2440a94675da/

Log:	Fix test_c to pass both on Python 2.6-2.7 and on Python 3.3.

	Will not care about Python 3.0-3.2 for the test suite because of the
	u'' syntax used everywhere, which was re-added in Python 3.3.

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -2326,7 +2326,10 @@
     }
 #endif
     else if (PyBytes_Check(ob)) {
-      value = (unsigned char)_convert_to_char(ob);
+        int res = _convert_to_char(ob);
+        if (res < 0)
+            return NULL;
+        value = (unsigned char)res;
     }
     else {
         value = _my_PyLong_AsUnsignedLongLong(ob, 0);
@@ -3702,6 +3705,7 @@
     py_rawerr = PyBytes_FromStringAndSize(NULL, size);
     if (py_rawerr == NULL)
         return NULL;
+    memset(PyBytes_AS_STRING(py_rawerr), 0, size);
     if (error_ob != Py_None) {
         if (convert_from_object_fficallback(
                 PyBytes_AS_STRING(py_rawerr), ctresult, error_ob) < 0) {
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -12,9 +12,21 @@
 
 if sys.version_info < (3,):
     type_or_class = "type"
+    mandatory_b_prefix = ''
+    mandatory_u_prefix = 'u'
+    readbuf = str
+    bufchar = lambda x: x
+    bytechr = chr
 else:
     type_or_class = "class"
     long = int
+    unicode = str
+    unichr = chr
+    mandatory_b_prefix = 'b'
+    mandatory_u_prefix = ''
+    readbuf = lambda buf: buf.tobytes()
+    bufchar = ord
+    bytechr = lambda n: bytes([n])
 
 def size_of_int():
     BInt = new_primitive_type("int")
@@ -179,9 +191,9 @@
     assert type(int(cast(p, 'A'))) is int
     assert type(long(cast(p, 'A'))) is long
     assert str(cast(p, 'A')) == repr(cast(p, 'A'))
-    assert repr(cast(p, 'A')) == "<cdata 'char' 'A'>"
-    assert repr(cast(p, 255)) == r"<cdata 'char' '\xff'>"
-    assert repr(cast(p, 0)) == r"<cdata 'char' '\x00'>"
+    assert repr(cast(p, 'A')) == "<cdata 'char' %s'A'>" % mandatory_b_prefix
+    assert repr(cast(p, 255)) == r"<cdata 'char' %s'\xff'>" % mandatory_b_prefix
+    assert repr(cast(p, 0)) == r"<cdata 'char' %s'\x00'>" % mandatory_b_prefix
 
 def test_pointer_type():
     p = new_primitive_type("int")
@@ -278,15 +290,17 @@
     py.test.raises(TypeError, newp, BChar, None)
     BPtr = new_pointer_type(BChar)
     p = newp(BPtr, None)
-    assert p[0] == '\x00'
-    p = newp(BPtr, 'A')
-    assert p[0] == 'A'
+    assert p[0] == b'\x00'
+    p = newp(BPtr, b'A')
+    assert p[0] == b'A'
     py.test.raises(TypeError, newp, BPtr, 65)
-    py.test.raises(TypeError, newp, BPtr, "foo")
-    c = cast(BChar, 'A')
+    py.test.raises(TypeError, newp, BPtr, b"foo")
+    py.test.raises(TypeError, newp, BPtr, u"foo")
+    c = cast(BChar, b'A')
     assert str(c) == repr(c)
-    assert int(c) == ord('A')
-    py.test.raises(TypeError, cast, BChar, 'foo')
+    assert int(c) == ord(b'A')
+    py.test.raises(TypeError, cast, BChar, b'foo')
+    py.test.raises(TypeError, cast, BChar, u'foo')
 
 def test_reading_pointer_to_pointer():
     BVoidP = new_pointer_type(new_void_type())
@@ -410,9 +424,9 @@
     assert repr(p2) == "<ctype 'int[][42]'>"
     #
     py.test.raises(OverflowError,
-                   new_array_type, new_pointer_type(p), sys.maxint+1)
+                   new_array_type, new_pointer_type(p), sys.maxsize+1)
     py.test.raises(OverflowError,
-                   new_array_type, new_pointer_type(p), sys.maxint // 3)
+                   new_array_type, new_pointer_type(p), sys.maxsize // 3)
 
 def test_array_instance():
     LENGTH = 1423
@@ -453,7 +467,7 @@
 def test_array_of_unknown_length_instance_with_initializer():
     p = new_primitive_type("int")
     p1 = new_array_type(new_pointer_type(p), None)
-    a = newp(p1, range(42))
+    a = newp(p1, list(range(42)))
     assert len(a) == 42
     a = newp(p1, tuple(range(142)))
     assert len(a) == 142
@@ -461,7 +475,7 @@
 def test_array_initializer():
     p = new_primitive_type("int")
     p1 = new_array_type(new_pointer_type(p), None)
-    a = newp(p1, range(100, 142))
+    a = newp(p1, list(range(100, 142)))
     for i in range(42):
         assert a[i] == 100 + i
     #
@@ -475,7 +489,7 @@
     p = new_primitive_type("int")
     p1 = new_array_type(new_pointer_type(p), 5)    # int[5]
     p2 = new_array_type(new_pointer_type(p1), 3)   # int[3][5]
-    a = newp(p2, [range(n, n+5) for n in [100, 200, 300]])
+    a = newp(p2, [list(range(n, n+5)) for n in [100, 200, 300]])
     assert repr(a) == "<cdata 'int[3][5]' owning %d bytes>" % (
         3*5*size_of_int(),)
     assert repr(a + 0).startswith("<cdata 'int(*)[5]' 0x")
@@ -545,7 +559,7 @@
     p = new_primitive_type("char")
     p1 = new_pointer_type(p)
     n = newp(p1, cast(p, "A"))
-    assert n[0] == "A"
+    assert n[0] == b"A"
 
 def test_cast_between_pointers():
     BIntP = new_pointer_type(new_primitive_type("int"))
@@ -650,7 +664,7 @@
     s.a2 = 123
     assert s.a1 == 0
     assert s.a2 == 123
-    py.test.raises(OverflowError, "s.a1 = sys.maxint+1")
+    py.test.raises(OverflowError, "s.a1 = sys.maxsize+1")
     assert s.a1 == 0
     py.test.raises(AttributeError, "p.foobar")
     py.test.raises(AttributeError, "s.foobar")
@@ -852,12 +866,12 @@
                                        ('a2', BShort, -1)])
     BFunc7 = new_function_type((BStruct,), BShort, False)
     f = cast(BFunc7, _testfunc(7))
-    res = f({'a1': 'A', 'a2': -4042})
-    assert res == -4042 + ord('A')
+    res = f({'a1': b'A', 'a2': -4042})
+    assert res == -4042 + ord(b'A')
     #
-    x = newp(BStructPtr, {'a1': 'A', 'a2': -4042})
+    x = newp(BStructPtr, {'a1': b'A', 'a2': -4042})
     res = f(x[0])
-    assert res == -4042 + ord('A')
+    assert res == -4042 + ord(b'A')
 
 def test_call_function_20():
     BChar = new_primitive_type("char")
@@ -868,11 +882,11 @@
                                        ('a2', BShort, -1)])
     BFunc18 = new_function_type((BStructPtr,), BShort, False)
     f = cast(BFunc18, _testfunc(20))
-    x = newp(BStructPtr, {'a1': 'A', 'a2': -4042})
+    x = newp(BStructPtr, {'a1': b'A', 'a2': -4042})
     # test the exception that allows us to pass a 'struct foo' where the
     # function really expects a 'struct foo *'.
     res = f(x[0])
-    assert res == -4042 + ord('A')
+    assert res == -4042 + ord(b'A')
     assert res == f(x)
 
 def test_call_function_9():
@@ -908,7 +922,7 @@
     BCharA = new_array_type(BCharP, None)
     x = newp(BCharA, 42)
     assert len(x) == 42
-    x = newp(BCharA, "foobar")
+    x = newp(BCharA, b"foobar")
     assert len(x) == 7
 
 def test_load_and_call_function():
@@ -918,10 +932,10 @@
     BFunc = new_function_type((BCharP,), BLong, False)
     ll = find_and_load_library('c')
     strlen = ll.load_function(BFunc, "strlen")
-    input = newp(new_array_type(BCharP, None), "foobar")
+    input = newp(new_array_type(BCharP, None), b"foobar")
     assert strlen(input) == 6
     #
-    assert strlen("foobarbaz") == 9
+    assert strlen(b"foobarbaz") == 9
     #
     BVoidP = new_pointer_type(new_void_type())
     strlenaddr = ll.load_function(BVoidP, "strlen")
@@ -957,7 +971,8 @@
     f = make_callback()
     assert f(-142) == -141
     assert repr(f).startswith(
-        "<cdata 'int(*)(int)' calling <function cb at 0x")
+        "<cdata 'int(*)(int)' calling <function ")
+    assert "cb at 0x" in repr(f)
     e = py.test.raises(TypeError, f)
     assert str(e.value) == "'int(*)(int)' expects 1 arguments, got 0"
 
@@ -1077,18 +1092,20 @@
     BInt = new_primitive_type("int")
     BChar = new_primitive_type("char")
     def cb(n):
-        return chr(n)
+        return bytechr(n)
     BFunc = new_function_type((BInt,), BChar)
     f = callback(BFunc, cb)
-    assert f(0) == '\x00'
-    assert f(255) == '\xFF'
+    assert f(0) == b'\x00'
+    assert f(255) == b'\xFF'
 
 def test_callback_returning_wchar_t():
     BInt = new_primitive_type("int")
     BWChar = new_primitive_type("wchar_t")
     def cb(n):
-        if n < 0:
+        if n == -1:
             return u'\U00012345'
+        if n == -2:
+            raise ValueError
         return unichr(n)
     BFunc = new_function_type((BInt,), BWChar)
     f = callback(BFunc, cb)
@@ -1097,6 +1114,7 @@
     assert f(0x1234) == u'\u1234'
     if sizeof(BWChar) == 4:
         assert f(-1) == u'\U00012345'
+    assert f(-2) == u'\x00'   # and an exception printed to stderr
 
 def test_struct_with_bitfields():
     BLong = new_primitive_type("long")
@@ -1194,14 +1212,14 @@
     BChar = new_primitive_type("char")
     BArray1 = new_array_type(new_pointer_type(BChar), 5)
     BArray2 = new_array_type(new_pointer_type(BArray1), 5)
-    a = newp(BArray2, ["abc", "de", "ghij"])
-    assert string(a[1]) == "de"
-    assert string(a[2]) == "ghij"
-    a[2] = "."
-    assert string(a[2]) == "."
-    a[2] = "12345"
-    assert string(a[2]) == "12345"
-    e = py.test.raises(IndexError, 'a[2] = "123456"')
+    a = newp(BArray2, [b"abc", b"de", b"ghij"])
+    assert string(a[1]) == b"de"
+    assert string(a[2]) == b"ghij"
+    a[2] = b"."
+    assert string(a[2]) == b"."
+    a[2] = b"12345"
+    assert string(a[2]) == b"12345"
+    e = py.test.raises(IndexError, 'a[2] = b"123456"')
     assert 'char[5]' in str(e.value)
     assert 'got 6 characters' in str(e.value)
 
@@ -1220,13 +1238,13 @@
 def test_too_many_items():
     BChar = new_primitive_type("char")
     BArray = new_array_type(new_pointer_type(BChar), 5)
-    py.test.raises(IndexError, newp, BArray, ('1', '2', '3', '4', '5', '6'))
-    py.test.raises(IndexError, newp, BArray, ['1', '2', '3', '4', '5', '6'])
-    py.test.raises(IndexError, newp, BArray, '123456')
+    py.test.raises(IndexError, newp, BArray, tuple(b'123456'))
+    py.test.raises(IndexError, newp, BArray, list(b'123456'))
+    py.test.raises(IndexError, newp, BArray, b'123456')
     BStruct = new_struct_type("foo")
     complete_struct_or_union(BStruct, [])
-    py.test.raises(TypeError, newp, new_pointer_type(BStruct), '')
-    py.test.raises(ValueError, newp, new_pointer_type(BStruct), ['1'])
+    py.test.raises(TypeError, newp, new_pointer_type(BStruct), b'')
+    py.test.raises(ValueError, newp, new_pointer_type(BStruct), [b'1'])
 
 def test_more_type_errors():
     BInt = new_primitive_type("int")
@@ -1257,7 +1275,7 @@
     #
     BChar = new_primitive_type("char")
     p = newp(new_pointer_type(BChar), cast(BChar, '!'))
-    assert p[0] == '!'
+    assert p[0] == b'!'
     #
     BFloat = new_primitive_type("float")
     p = newp(new_pointer_type(BFloat), cast(BFloat, 12.25))
@@ -1295,37 +1313,37 @@
 
 def test_string():
     BChar = new_primitive_type("char")
-    assert string(cast(BChar, 42)) == '*'
-    assert string(cast(BChar, 0)) == '\x00'
+    assert string(cast(BChar, 42)) == b'*'
+    assert string(cast(BChar, 0)) == b'\x00'
     BCharP = new_pointer_type(BChar)
     BArray = new_array_type(BCharP, 10)
-    a = newp(BArray, "hello")
+    a = newp(BArray, b"hello")
     assert len(a) == 10
-    assert string(a) == "hello"
+    assert string(a) == b"hello"
     p = a + 2
-    assert string(p) == "llo"
-    assert string(newp(new_array_type(BCharP, 4), "abcd")) == "abcd"
+    assert string(p) == b"llo"
+    assert string(newp(new_array_type(BCharP, 4), b"abcd")) == b"abcd"
     py.test.raises(RuntimeError, string, cast(BCharP, 0))
-    assert string(a, 4) == "hell"
-    assert string(a, 5) == "hello"
-    assert string(a, 6) == "hello"
+    assert string(a, 4) == b"hell"
+    assert string(a, 5) == b"hello"
+    assert string(a, 6) == b"hello"
 
 def test_string_byte():
     BByte = new_primitive_type("signed char")
-    assert string(cast(BByte, 42)) == '*'
-    assert string(cast(BByte, 0)) == '\x00'
+    assert string(cast(BByte, 42)) == b'*'
+    assert string(cast(BByte, 0)) == b'\x00'
     BArray = new_array_type(new_pointer_type(BByte), None)
     a = newp(BArray, [65, 66, 67])
-    assert type(string(a)) is str and string(a) == 'ABC'
+    assert type(string(a)) is bytes and string(a) == b'ABC'
     #
     BByte = new_primitive_type("unsigned char")
-    assert string(cast(BByte, 42)) == '*'
-    assert string(cast(BByte, 0)) == '\x00'
+    assert string(cast(BByte, 42)) == b'*'
+    assert string(cast(BByte, 0)) == b'\x00'
     BArray = new_array_type(new_pointer_type(BByte), None)
     a = newp(BArray, [65, 66, 67])
-    assert type(string(a)) is str and string(a) == 'ABC'
-    if 'PY_DOT_PY' not in globals():
-        assert string(a, 8).startswith('ABC')  # may contain additional garbage
+    assert type(string(a)) is bytes and string(a) == b'ABC'
+    if 'PY_DOT_PY' not in globals() and sys.version_info < (3,):
+        assert string(a, 8).startswith(b'ABC')  # may contain additional garbage
 
 def test_string_wchar():
     BWChar = new_primitive_type("wchar_t")
@@ -1335,7 +1353,7 @@
     BArray = new_array_type(new_pointer_type(BWChar), None)
     a = newp(BArray, [u'A', u'B', u'C'])
     assert type(string(a)) is unicode and string(a) == u'ABC'
-    if 'PY_DOT_PY' not in globals():
+    if 'PY_DOT_PY' not in globals() and sys.version_info < (3,):
         assert string(a, 8).startswith(u'ABC') # may contain additional garbage
 
 def test_string_typeerror():
@@ -1359,12 +1377,12 @@
     BStructPtr = new_pointer_type(BStruct)
     complete_struct_or_union(BStruct, [('a1', BCharArray10, -1)])
     p = newp(BStructPtr, None)
-    assert string(p.a1) == ''
-    p.a1 = 'foo'
-    assert string(p.a1) == 'foo'
-    assert list(p.a1) == ['f', 'o', 'o'] + ['\x00'] * 7
-    p.a1 = ['x', 'y']
-    assert string(p.a1) == 'xyo'
+    assert string(p.a1) == b''
+    p.a1 = b'foo'
+    assert string(p.a1) == b'foo'
+    assert list(p.a1) == [b'f', b'o', b'o'] + [b'\x00'] * 7
+    p.a1 = [b'x', b'y']
+    assert string(p.a1) == b'xyo'
 
 def test_invalid_function_result_types():
     BFunc = new_function_type((), new_void_type())
@@ -1390,7 +1408,7 @@
     f = cast(BFunc10, _testfunc(10))
     s = f(40)
     assert repr(s) == "<cdata 'struct foo_s' owning 4 bytes>"
-    assert s.a1 == chr(40)
+    assert s.a1 == bytechr(40)
     assert s.a2 == 40 * 40
     #
     BStruct11 = new_struct_type("test11")
@@ -1489,11 +1507,14 @@
     BInt = new_primitive_type("int")
     pyuni4 = {1: True, 2: False}[len(u'\U00012345')]
     wchar4 = {2: False, 4: True}[sizeof(BWChar)]
-    assert str(cast(BWChar, 0x45)) == "<cdata 'wchar_t' u'E'>"
-    assert str(cast(BWChar, 0x1234)) == "<cdata 'wchar_t' u'\u1234'>"
+    assert str(cast(BWChar, 0x45)) == "<cdata 'wchar_t' %s'E'>" % (
+        mandatory_u_prefix,)
+    assert str(cast(BWChar, 0x1234)) == "<cdata 'wchar_t' %s'\u1234'>" % (
+        mandatory_u_prefix,)
     if wchar4:
         x = cast(BWChar, 0x12345)
-        assert str(x) == "<cdata 'wchar_t' u'\U00012345'>"
+        assert str(x) == "<cdata 'wchar_t' %s'\U00012345'>" % (
+            mandatory_u_prefix,)
         assert int(x) == 0x12345
     else:
         assert not pyuni4
@@ -1506,8 +1527,8 @@
     s = newp(BStructPtr)
     s.a1 = u'\x00'
     assert s.a1 == u'\x00'
-    py.test.raises(TypeError, "s.a1 = 'a'")
-    py.test.raises(TypeError, "s.a1 = '\xFF'")
+    py.test.raises(TypeError, "s.a1 = b'a'")
+    py.test.raises(TypeError, "s.a1 = bytechr(0xFF)")
     s.a1 = u'\u1234'
     assert s.a1 == u'\u1234'
     if pyuni4:
@@ -1547,17 +1568,17 @@
         py.test.raises(IndexError, 'a[4]')
     #
     w = cast(BWChar, 'a')
-    assert repr(w) == "<cdata 'wchar_t' u'a'>"
+    assert repr(w) == "<cdata 'wchar_t' %s'a'>" % mandatory_u_prefix
     assert str(w) == repr(w)
     assert string(w) == u'a'
     assert int(w) == ord('a')
     w = cast(BWChar, 0x1234)
-    assert repr(w) == "<cdata 'wchar_t' u'\u1234'>"
+    assert repr(w) == "<cdata 'wchar_t' %s'\u1234'>" % mandatory_u_prefix
     assert str(w) == repr(w)
     assert string(w) == u'\u1234'
     assert int(w) == 0x1234
     w = cast(BWChar, u'\u8234')
-    assert repr(w) == "<cdata 'wchar_t' u'\u8234'>"
+    assert repr(w) == "<cdata 'wchar_t' %s'\u8234'>" % mandatory_u_prefix
     assert str(w) == repr(w)
     assert string(w) == u'\u8234'
     assert int(w) == 0x8234
@@ -1565,7 +1586,8 @@
     assert repr(w) == "<cdata 'int' 4660>"
     if wchar4:
         w = cast(BWChar, u'\U00012345')
-        assert repr(w) == "<cdata 'wchar_t' u'\U00012345'>"
+        assert repr(w) == "<cdata 'wchar_t' %s'\U00012345'>" % (
+            mandatory_u_prefix,)
         assert str(w) == repr(w)
         assert string(w) == u'\U00012345'
         assert int(w) == 0x12345
@@ -1700,27 +1722,31 @@
     s = newp(new_pointer_type(BShort), 100)
     assert sizeof(s) == size_of_ptr()
     assert sizeof(BShort) == 2
-    assert len(str(buffer(s))) == 2
+    assert len(readbuf(buffer(s))) == 2
     #
     BChar = new_primitive_type("char")
     BCharArray = new_array_type(new_pointer_type(BChar), None)
-    c = newp(BCharArray, "hi there")
+    c = newp(BCharArray, b"hi there")
     buf = buffer(c)
-    assert str(buf) == "hi there\x00"
-    assert len(buf) == len("hi there\x00")
-    assert buf[0] == 'h'
-    assert buf[2] == ' '
-    assert list(buf) == ['h', 'i', ' ', 't', 'h', 'e', 'r', 'e', '\x00']
-    buf[2] = '-'
-    assert c[2] == '-'
-    assert str(buf) == "hi-there\x00"
-    buf[:2] = 'HI'
-    assert string(c) == 'HI-there'
-    assert buf[:4:2] == 'H-'
+    assert readbuf(buf) == b"hi there\x00"
+    assert len(buf) == len(b"hi there\x00")
+    assert buf[0] == bufchar('h')
+    assert buf[2] == bufchar(' ')
+    assert list(buf) == list(map(bufchar, "hi there\x00"))
+    buf[2] = bufchar('-')
+    assert c[2] == b'-'
+    assert readbuf(buf) == b"hi-there\x00"
+    c[2] = b'!'
+    assert buf[2] == bufchar('!')
+    assert readbuf(buf) == b"hi!there\x00"
+    c[2] = b'-'
+    buf[:2] = b'HI'
+    assert string(c) == b'HI-there'
+    assert buf[:4:2] == b'H-'
     if '__pypy__' not in sys.builtin_module_names:
         # XXX pypy doesn't support the following assignment so far
-        buf[:4:2] = 'XY'
-        assert string(c) == 'XIYthere'
+        buf[:4:2] = b'XY'
+        assert string(c) == b'XIYthere'
 
 def test_getcname():
     BUChar = new_primitive_type("unsigned char")


More information about the pypy-commit mailing list