Author: Matti Picus <matti.pi...@gmail.com> Branch: unicode-utf8 Changeset: r95499:cbf95a8a15f1 Date: 2018-12-15 23:12 +0200 http://bitbucket.org/pypy/pypy/changeset/cbf95a8a15f1/
Log: merge default into branch diff too long, truncating to 2000 out of 10025 lines diff --git a/extra_tests/cffi_tests/cffi1/test_recompiler.py b/extra_tests/cffi_tests/cffi1/test_recompiler.py --- a/extra_tests/cffi_tests/cffi1/test_recompiler.py +++ b/extra_tests/cffi_tests/cffi1/test_recompiler.py @@ -5,7 +5,7 @@ from cffi import recompiler from extra_tests.cffi_tests.udir import udir from extra_tests.cffi_tests.support import u, long -from extra_tests.cffi_tests.support import FdWriteCapture, StdErrCapture +from extra_tests.cffi_tests.support import FdWriteCapture, StdErrCapture, _verify try: import importlib @@ -36,7 +36,7 @@ # add '-Werror' to the existing 'extra_compile_args' flags kwds['extra_compile_args'] = (kwds.get('extra_compile_args', []) + ['-Werror']) - return recompiler._verify(ffi, module_name, source, *args, **kwds) + return _verify(ffi, module_name, source, *args, **kwds) def test_set_source_no_slashes(): ffi = FFI() @@ -1539,15 +1539,18 @@ assert (pt.x, pt.y) == (99*500*999, -99*500*999) def test_extern_python_1(): + import warnings ffi = FFI() - ffi.cdef(""" + with warnings.catch_warnings(record=True) as log: + ffi.cdef(""" extern "Python" { int bar(int, int); void baz(int, int); int bok(void); void boz(void); } - """) + """) + assert len(log) == 0, "got a warning: %r" % (log,) lib = verify(ffi, 'test_extern_python_1', """ static void baz(int, int); /* forward */ """) diff --git a/extra_tests/cffi_tests/cffi1/test_verify1.py b/extra_tests/cffi_tests/cffi1/test_verify1.py --- a/extra_tests/cffi_tests/cffi1/test_verify1.py +++ b/extra_tests/cffi_tests/cffi1/test_verify1.py @@ -4,6 +4,7 @@ from cffi import CDefError from cffi import recompiler from extra_tests.cffi_tests.support import * +from extra_tests.cffi_tests.support import _verify import _cffi_backend lib_m = ['m'] @@ -38,9 +39,8 @@ except AttributeError: pass self.set_source(module_name, preamble) - return recompiler._verify(self, module_name, preamble, *args, - extra_compile_args=self._extra_compile_args, - **kwds) + return _verify(self, module_name, preamble, *args, + extra_compile_args=self._extra_compile_args, **kwds) class FFI_warnings_not_error(FFI): _extra_compile_args = [] diff --git a/extra_tests/cffi_tests/support.py b/extra_tests/cffi_tests/support.py --- a/extra_tests/cffi_tests/support.py +++ b/extra_tests/cffi_tests/support.py @@ -62,3 +62,28 @@ def getvalue(self): return self._value + +def _verify(ffi, module_name, preamble, *args, **kwds): + import imp + from cffi.recompiler import recompile + from .udir import udir + assert module_name not in sys.modules, "module name conflict: %r" % ( + module_name,) + kwds.setdefault('tmpdir', str(udir)) + outputfilename = recompile(ffi, module_name, preamble, *args, **kwds) + module = imp.load_dynamic(module_name, outputfilename) + # + # hack hack hack: copy all *bound methods* from module.ffi back to the + # ffi instance. Then calls like ffi.new() will invoke module.ffi.new(). + for name in dir(module.ffi): + if not name.startswith('_'): + attr = getattr(module.ffi, name) + if attr is not getattr(ffi, name, object()): + setattr(ffi, name, attr) + def typeof_disabled(*args, **kwds): + raise NotImplementedError + ffi._typeof = typeof_disabled + for name in dir(ffi): + if not name.startswith('_') and not hasattr(module.ffi, name): + setattr(ffi, name, NotImplemented) + return module.lib diff --git a/pypy/module/test_lib_pypy/ctypes_tests/__init__.py b/extra_tests/ctypes_tests/__init__.py rename from pypy/module/test_lib_pypy/ctypes_tests/__init__.py rename to extra_tests/ctypes_tests/__init__.py diff --git a/pypy/module/test_lib_pypy/ctypes_tests/_ctypes_test.c b/extra_tests/ctypes_tests/_ctypes_test.c rename from pypy/module/test_lib_pypy/ctypes_tests/_ctypes_test.c rename to extra_tests/ctypes_tests/_ctypes_test.c diff --git a/pypy/module/test_lib_pypy/ctypes_tests/conftest.py b/extra_tests/ctypes_tests/conftest.py rename from pypy/module/test_lib_pypy/ctypes_tests/conftest.py rename to extra_tests/ctypes_tests/conftest.py --- a/pypy/module/test_lib_pypy/ctypes_tests/conftest.py +++ b/extra_tests/ctypes_tests/conftest.py @@ -3,10 +3,6 @@ import sys import os -def pytest_ignore_collect(path): - if '__pypy__' not in sys.builtin_module_names: - return True - # XXX: copied from pypy/tool/cpyext/extbuild.py if os.name != 'nt': so_ext = 'so' @@ -85,8 +81,7 @@ return outputfilename # end copy -def compile_so_file(): - udir = pytest.ensuretemp('_ctypes_test') +def compile_so_file(udir): cfile = py.path.local(__file__).dirpath().join("_ctypes_test.c") if sys.platform == 'win32': @@ -96,8 +91,12 @@ return c_compile([cfile], str(udir / '_ctypes_test'), libraries=libraries) -# we need to run after the "tmpdir" plugin which installs pytest.ensuretemp -@pytest.mark.trylast -def pytest_configure(config): - global sofile - sofile = compile_so_file() +@pytest.fixture(scope='session') +def sofile(tmpdir_factory): + udir = tmpdir_factory.mktemp('_ctypes_test') + return str(compile_so_file(udir)) + +@pytest.fixture +def dll(sofile): + from ctypes import CDLL + return CDLL(str(sofile)) diff --git a/pypy/module/test_lib_pypy/ctypes_tests/support.py b/extra_tests/ctypes_tests/support.py rename from pypy/module/test_lib_pypy/ctypes_tests/support.py rename to extra_tests/ctypes_tests/support.py diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_anon.py b/extra_tests/ctypes_tests/test_anon.py rename from pypy/module/test_lib_pypy/ctypes_tests/test_anon.py rename to extra_tests/ctypes_tests/test_anon.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_anon.py +++ b/extra_tests/ctypes_tests/test_anon.py @@ -1,86 +1,55 @@ import pytest from ctypes import * -from .support import BaseCTypesTestChecker -class TestAnon(BaseCTypesTestChecker): +@pytest.mark.pypy_only +def test_nested(): + class ANON_S(Structure): + _fields_ = [("a", c_int)] - def test_anon(self): - class ANON(Union): - _fields_ = [("a", c_int), - ("b", c_int)] + class ANON_U(Union): + _fields_ = [("_", ANON_S), + ("b", c_int)] + _anonymous_ = ["_"] - class Y(Structure): - _fields_ = [("x", c_int), - ("_", ANON), - ("y", c_int)] - _anonymous_ = ["_"] + class Y(Structure): + _fields_ = [("x", c_int), + ("_", ANON_U), + ("y", c_int)] + _anonymous_ = ["_"] - assert Y.a.offset == sizeof(c_int) - assert Y.b.offset == sizeof(c_int) + assert Y.x.offset == 0 + assert Y.a.offset == sizeof(c_int) + assert Y.b.offset == sizeof(c_int) + assert Y._.offset == sizeof(c_int) + assert Y.y.offset == sizeof(c_int) * 2 - assert ANON.a.offset == 0 - assert ANON.b.offset == 0 + assert Y._names_ == ['x', 'a', 'b', 'y'] - def test_anon_nonseq(self): - # TypeError: _anonymous_ must be a sequence - with pytest.raises(TypeError): - type(Structure)( - "Name", (Structure,), {"_fields_": [], "_anonymous_": 42}) +def test_anonymous_fields_on_instance(): + # this is about the *instance-level* access of anonymous fields, + # which you'd guess is the most common, but used not to work + # (issue #2230) - def test_anon_nonmember(self): - # AttributeError: type object 'Name' has no attribute 'x' - with pytest.raises(AttributeError): - type(Structure)( - "Name", (Structure,), {"_fields_": [], "_anonymous_": ["x"]}) + class B(Structure): + _fields_ = [("x", c_int), ("y", c_int), ("z", c_int)] + class A(Structure): + _anonymous_ = ["b"] + _fields_ = [("b", B)] - def test_nested(self): - class ANON_S(Structure): - _fields_ = [("a", c_int)] + a = A() + a.x = 5 + assert a.x == 5 + assert a.b.x == 5 + a.b.x += 1 + assert a.x == 6 - class ANON_U(Union): - _fields_ = [("_", ANON_S), - ("b", c_int)] - _anonymous_ = ["_"] + class C(Structure): + _anonymous_ = ["a"] + _fields_ = [("v", c_int), ("a", A)] - class Y(Structure): - _fields_ = [("x", c_int), - ("_", ANON_U), - ("y", c_int)] - _anonymous_ = ["_"] - - assert Y.x.offset == 0 - assert Y.a.offset == sizeof(c_int) - assert Y.b.offset == sizeof(c_int) - assert Y._.offset == sizeof(c_int) - assert Y.y.offset == sizeof(c_int) * 2 - - assert Y._names_ == ['x', 'a', 'b', 'y'] - - def test_anonymous_fields_on_instance(self): - # this is about the *instance-level* access of anonymous fields, - # which you'd guess is the most common, but used not to work - # (issue #2230) - - class B(Structure): - _fields_ = [("x", c_int), ("y", c_int), ("z", c_int)] - class A(Structure): - _anonymous_ = ["b"] - _fields_ = [("b", B)] - - a = A() - a.x = 5 - assert a.x == 5 - assert a.b.x == 5 - a.b.x += 1 - assert a.x == 6 - - class C(Structure): - _anonymous_ = ["a"] - _fields_ = [("v", c_int), ("a", A)] - - c = C() - c.v = 3 - c.y = -8 - assert c.v == 3 - assert c.y == c.a.y == c.a.b.y == -8 - assert not hasattr(c, 'b') + c = C() + c.v = 3 + c.y = -8 + assert c.v == 3 + assert c.y == c.a.y == c.a.b.y == -8 + assert not hasattr(c, 'b') diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_array.py b/extra_tests/ctypes_tests/test_array.py rename from pypy/module/test_lib_pypy/ctypes_tests/test_array.py rename to extra_tests/ctypes_tests/test_array.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_array.py +++ b/extra_tests/ctypes_tests/test_array.py @@ -1,177 +1,64 @@ import pytest from ctypes import * -from .support import BaseCTypesTestChecker -formats = "bBhHiIlLqQfd" +def test_slice(): + values = list(range(5)) + numarray = c_int * 5 -formats = c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, \ - c_long, c_ulonglong, c_float, c_double + na = numarray(*(c_int(x) for x in values)) -class TestArray(BaseCTypesTestChecker): - def test_simple(self): - # create classes holding simple numeric types, and check - # various properties. + assert list(na[0:0]) == [] + assert list(na[:]) == values + assert list(na[:10]) == values - init = range(15, 25) +def test_init_again(): + sz = (c_char * 3)() + addr1 = addressof(sz) + sz.__init__(*b"foo") + addr2 = addressof(sz) + assert addr1 == addr2 - for fmt in formats: - alen = len(init) - int_array = ARRAY(fmt, alen) +def test_array_of_structures(): + class X(Structure): + _fields_ = [('x', c_int), ('y', c_int)] - ia = int_array(*init) - # length of instance ok? - assert len(ia) == alen + Y = X * 2 + y = Y() + x = X() + x.y = 3 + y[1] = x + assert y[1].y == 3 - # slot values ok? - values = [ia[i] for i in range(len(init))] - assert values == init +def test_output_simple(): + A = c_char * 10 + TP = POINTER(A) + x = TP(A()) + assert x[0] != b'' - # change the items - from operator import setitem - new_values = range(42, 42+alen) - [setitem(ia, n, new_values[n]) for n in range(alen)] - values = [ia[i] for i in range(len(init))] - assert values == new_values + A = c_wchar * 10 + TP = POINTER(A) + x = TP(A()) + assert x[0] != b'' - # are the items initialized to 0? - ia = int_array() - values = [ia[i] for i in range(len(init))] - assert values == [0] * len(init) +def test_output_simple_array(): + A = c_char * 10 + AA = A * 10 + aa = AA() + assert aa[0] != b'' - # Too many in itializers should be caught - with pytest.raises(IndexError): - int_array(*range(alen*2)) +def test_output_complex_test(): + class Car(Structure): + _fields_ = [("brand", c_char * 10), + ("speed", c_float), + ("owner", c_char * 10)] - CharArray = ARRAY(c_char, 3) + assert isinstance(Car(b"abcdefghi", 42.0, b"12345").brand, bytes) + assert Car(b"abcdefghi", 42.0, b"12345").brand == b"abcdefghi" + assert Car(b"abcdefghio", 42.0, b"12345").brand == b"abcdefghio" + with pytest.raises(ValueError): + Car(b"abcdefghiop", 42.0, b"12345") - ca = CharArray("a", "b", "c") - - # Should this work? It doesn't: - # CharArray("abc") - with pytest.raises(TypeError): - CharArray("abc") - - assert ca[0] == "a" - assert ca[1] == "b" - assert ca[2] == "c" - assert ca[-3] == "a" - assert ca[-2] == "b" - assert ca[-1] == "c" - - assert len(ca) == 3 - - # slicing is now supported, but not extended slicing (3-argument)! - from operator import getslice, delitem - with pytest.raises(TypeError): - getslice(ca, 0, 1, -1) - - # cannot delete items - with pytest.raises(TypeError): - delitem(ca, 0) - - def test_numeric_arrays(self): - - alen = 5 - - numarray = ARRAY(c_int, alen) - - na = numarray() - values = [na[i] for i in range(alen)] - assert values == [0] * alen - - na = numarray(*[c_int()] * alen) - values = [na[i] for i in range(alen)] - assert values == [0]*alen - - na = numarray(1, 2, 3, 4, 5) - values = [i for i in na] - assert values == [1, 2, 3, 4, 5] - - na = numarray(*map(c_int, (1, 2, 3, 4, 5))) - values = [i for i in na] - assert values == [1, 2, 3, 4, 5] - - def test_slice(self): - values = range(5) - numarray = c_int * 5 - - na = numarray(*(c_int(x) for x in values)) - - assert list(na[0:0]) == [] - assert list(na[:]) == values - assert list(na[:10]) == values - - def test_classcache(self): - assert not ARRAY(c_int, 3) is ARRAY(c_int, 4) - assert ARRAY(c_int, 3) is ARRAY(c_int, 3) - - def test_from_address(self): - # Failed with 0.9.8, reported by JUrner - p = create_string_buffer("foo") - sz = (c_char * 3).from_address(addressof(p)) - assert sz[:] == "foo" - assert sz.value == "foo" - - def test_init_again(self): - sz = (c_char * 3)() - addr1 = addressof(sz) - sz.__init__(*"foo") - addr2 = addressof(sz) - assert addr1 == addr2 - - try: - create_unicode_buffer - except NameError: - pass - else: - def test_from_addressW(self): - p = create_unicode_buffer("foo") - sz = (c_wchar * 3).from_address(addressof(p)) - assert sz[:] == "foo" - assert sz.value == "foo" - -class TestSophisticatedThings(BaseCTypesTestChecker): - def test_array_of_structures(self): - class X(Structure): - _fields_ = [('x', c_int), ('y', c_int)] - - Y = X * 2 - y = Y() - x = X() - x.y = 3 - y[1] = x - assert y[1].y == 3 - - def test_output_simple(self): - A = c_char * 10 - TP = POINTER(A) - x = TP(A()) - assert x[0] != '' - - A = c_wchar * 10 - TP = POINTER(A) - x = TP(A()) - assert x[0] != '' - - def test_output_simple_array(self): - A = c_char * 10 - AA = A * 10 - aa = AA() - assert aa[0] != '' - - def test_output_complex_test(self): - class Car(Structure): - _fields_ = [("brand", c_char * 10), - ("speed", c_float), - ("owner", c_char * 10)] - - assert isinstance(Car("abcdefghi", 42.0, "12345").brand, bytes) - assert Car("abcdefghi", 42.0, "12345").brand == "abcdefghi" - assert Car("abcdefghio", 42.0, "12345").brand == "abcdefghio" - with pytest.raises(ValueError): - Car("abcdefghiop", 42.0, "12345") - - A = Car._fields_[2][1] - TP = POINTER(A) - x = TP(A()) - assert x[0] != '' + A = Car._fields_[2][1] + TP = POINTER(A) + x = TP(A()) + assert x[0] != b'' diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_base.py b/extra_tests/ctypes_tests/test_base.py rename from pypy/module/test_lib_pypy/ctypes_tests/test_base.py rename to extra_tests/ctypes_tests/test_base.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_base.py +++ b/extra_tests/ctypes_tests/test_base.py @@ -1,26 +1,24 @@ -from .support import WhiteBoxTests - +import pytest from ctypes import * -# WhiteBoxTests +pytestmark = pytest.mark.pypy_only -class TestCTypesBase(WhiteBoxTests): - def test_pointer(self): - p = pointer(pointer(c_int(2))) - x = p[0] - assert x._base is p +def test_pointer(): + p = pointer(pointer(c_int(2))) + x = p[0] + assert x._base is p - def test_structure(self): - class X(Structure): - _fields_ = [('x', POINTER(c_int)), - ('y', POINTER(c_int))] +def test_structure(): + class X(Structure): + _fields_ = [('x', POINTER(c_int)), + ('y', POINTER(c_int))] - x = X() - assert x.y._base is x - assert x.y._index == 1 + x = X() + assert x.y._base is x + assert x.y._index == 1 - def test_array(self): - X = POINTER(c_int) * 24 - x = X() - assert x[16]._base is x - assert x[16]._index == 16 +def test_array(): + X = POINTER(c_int) * 24 + x = X() + assert x[16]._base is x + assert x[16]._index == 16 diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_bitfields.py b/extra_tests/ctypes_tests/test_bitfields.py rename from pypy/module/test_lib_pypy/ctypes_tests/test_bitfields.py rename to extra_tests/ctypes_tests/test_bitfields.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_bitfields.py +++ b/extra_tests/ctypes_tests/test_bitfields.py @@ -1,249 +1,19 @@ import pytest from ctypes import * -from .support import BaseCTypesTestChecker -import os -import ctypes -signed_int_types = (c_byte, c_short, c_int, c_long, c_longlong) -unsigned_int_types = (c_ubyte, c_ushort, c_uint, c_ulong, c_ulonglong) -int_types = unsigned_int_types + signed_int_types +def test_set_fields_attr(): + class A(Structure): + pass + A._fields_ = [("a", c_byte), ("b", c_ubyte)] +def test_set_fields_attr_bitfields(): + class A(Structure): + pass + A._fields_ = [("a", POINTER(A)), ("b", c_ubyte, 4)] -def setup_module(mod): - import conftest - _ctypes_test = str(conftest.sofile) - func = CDLL(_ctypes_test).unpack_bitfields - func.argtypes = POINTER(BITS), c_char - mod.func = func - - -class BITS(Structure): - _fields_ = [("A", c_int, 1), - ("B", c_int, 2), - ("C", c_int, 3), - ("D", c_int, 4), - ("E", c_int, 5), - ("F", c_int, 6), - ("G", c_int, 7), - ("H", c_int, 8), - ("I", c_int, 9), - - ("M", c_short, 1), - ("N", c_short, 2), - ("O", c_short, 3), - ("P", c_short, 4), - ("Q", c_short, 5), - ("R", c_short, 6), - ("S", c_short, 7)] - - -class TestC: - def test_ints(self): - for i in range(512): - for name in "ABCDEFGHI": - b = BITS() - setattr(b, name, i) - assert (name, i, getattr(b, name)) == (name, i, func(byref(b), name)) - - def test_shorts(self): - for i in range(256): - for name in "MNOPQRS": - b = BITS() - setattr(b, name, i) - assert (name, i, getattr(b, name)) == (name, i, func(byref(b), name)) - - -class TestBitField: - def test_longlong(self): - class X(Structure): - _fields_ = [("a", c_longlong, 1), - ("b", c_longlong, 62), - ("c", c_longlong, 1)] - - assert sizeof(X) == sizeof(c_longlong) - x = X() - x.a, x.b, x.c = -1, 7, -1 - assert (x.a, x.b, x.c) == (-1, 7, -1) - - x = X() - x.a, x.b, x.c = -1, -7, -1 - assert (x.a, x.b, x.c) == (-1, -7, -1) - - def test_ulonglong(self): - class X(Structure): - _fields_ = [("a", c_ulonglong, 1), - ("b", c_ulonglong, 62), - ("c", c_ulonglong, 1)] - - assert sizeof(X) == sizeof(c_longlong) - x = X() - assert (x.a, x.b, x.c) == (0, 0, 0) - x.a, x.b, x.c = 7, 2305843009213693953, 7 - assert (x.a, x.b, x.c) == (1, 2305843009213693953, 1) - - def test_signed(self): - for c_typ in signed_int_types: - class X(Structure): - _fields_ = [("dummy", c_typ), - ("a", c_typ, 3), - ("b", c_typ, 3), - ("c", c_typ, 1)] - assert sizeof(X) == sizeof(c_typ)*2 - - x = X() - assert (c_typ, x.a, x.b, x.c) == (c_typ, 0, 0, 0) - x.a = -1 - assert (c_typ, x.a, x.b, x.c) == (c_typ, -1, 0, 0) - x.a, x.b = 0, -1 - assert (c_typ, x.a, x.b, x.c) == (c_typ, 0, -1, 0) - - def test_unsigned(self): - for c_typ in unsigned_int_types: - class X(Structure): - _fields_ = [("a", c_typ, 3), - ("b", c_typ, 3), - ("c", c_typ, 1)] - assert sizeof(X) == sizeof(c_typ) - - x = X() - assert (c_typ, x.a, x.b, x.c) == (c_typ, 0, 0, 0) - x.a = -1 - assert (c_typ, x.a, x.b, x.c) == (c_typ, 7, 0, 0) - x.a, x.b = 0, -1 - assert (c_typ, x.a, x.b, x.c) == (c_typ, 0, 7, 0) - - def fail_fields(self, *fields): - return self.get_except(type(Structure), "X", (), - {"_fields_": fields}) - - def test_nonint_types(self): - # bit fields are not allowed on non-integer types. - result = self.fail_fields(("a", c_char_p, 1)) - assert result == (TypeError, 'bit fields not allowed for type c_char_p') - - result = self.fail_fields(("a", c_void_p, 1)) - assert result == (TypeError, 'bit fields not allowed for type c_void_p') - - if c_int != c_long: - result = self.fail_fields(("a", POINTER(c_int), 1)) - assert result == (TypeError, 'bit fields not allowed for type LP_c_int') - - result = self.fail_fields(("a", c_char, 1)) - assert result == (TypeError, 'bit fields not allowed for type c_char') - - try: - c_wchar - except NameError: - pass - else: - result = self.fail_fields(("a", c_wchar, 1)) - assert result == (TypeError, 'bit fields not allowed for type c_wchar') - - class Dummy(Structure): - _fields_ = [] - - result = self.fail_fields(("a", Dummy, 1)) - assert result == (TypeError, 'bit fields not allowed for type Dummy') - - def test_single_bitfield_size(self): - for c_typ in int_types: - result = self.fail_fields(("a", c_typ, -1)) - assert result == (ValueError, 'number of bits invalid for bit field') - - result = self.fail_fields(("a", c_typ, 0)) - assert result == (ValueError, 'number of bits invalid for bit field') - - class X(Structure): - _fields_ = [("a", c_typ, 1)] - assert sizeof(X) == sizeof(c_typ) - - class X(Structure): - _fields_ = [("a", c_typ, sizeof(c_typ)*8)] - assert sizeof(X) == sizeof(c_typ) - - result = self.fail_fields(("a", c_typ, sizeof(c_typ)*8 + 1)) - assert result == (ValueError, 'number of bits invalid for bit field') - - def test_multi_bitfields_size(self): - class X(Structure): - _fields_ = [("a", c_short, 1), - ("b", c_short, 14), - ("c", c_short, 1)] - assert sizeof(X) == sizeof(c_short) - - class X(Structure): - _fields_ = [("a", c_short, 1), - ("a1", c_short), - ("b", c_short, 14), - ("c", c_short, 1)] - assert sizeof(X) == sizeof(c_short)*3 - assert X.a.offset == 0 - assert X.a1.offset == sizeof(c_short) - assert X.b.offset == sizeof(c_short)*2 - assert X.c.offset == sizeof(c_short)*2 - - class X(Structure): - _fields_ = [("a", c_short, 3), - ("b", c_short, 14), - ("c", c_short, 14)] - assert sizeof(X) == sizeof(c_short)*3 - assert X.a.offset == sizeof(c_short)*0 - assert X.b.offset == sizeof(c_short)*1 - assert X.c.offset == sizeof(c_short)*2 - - def get_except(self, func, *args, **kw): - try: - func(*args, **kw) - except Exception as detail: - import traceback - traceback.print_exc() - return detail.__class__, str(detail) - - def test_mixed_1(self): - class X(Structure): - _fields_ = [("a", c_byte, 4), - ("b", c_int, 4)] - if os.name in ("nt", "ce"): - assert sizeof(X) == sizeof(c_int)*2 - else: - assert sizeof(X) == sizeof(c_int) - - def test_mixed_2(self): - class X(Structure): - _fields_ = [("a", c_byte, 4), - ("b", c_int, 32)] - assert sizeof(X) == sizeof(c_int)*2 - - def test_mixed_3(self): - class X(Structure): - _fields_ = [("a", c_byte, 4), - ("b", c_ubyte, 4)] - assert sizeof(X) == sizeof(c_byte) - - def test_anon_bitfields(self): - # anonymous bit-fields gave a strange error message - class X(Structure): - _fields_ = [("a", c_byte, 4), - ("b", c_ubyte, 4)] - class Y(Structure): - _anonymous_ = ["_"] - _fields_ = [("_", X)] - - def test_set_fields_attr(self): - class A(Structure): - pass - A._fields_ = [("a", c_byte), - ("b", c_ubyte)] - - def test_set_fields_attr_bitfields(self): - class A(Structure): - pass - A._fields_ = [("a", POINTER(A)), - ("b", c_ubyte, 4)] - - def test_set_fields_cycle_fails(self): - class A(Structure): - pass - with pytest.raises(AttributeError): - A._fields_ = [("a", A)] +def test_set_fields_cycle_fails(): + class A(Structure): + pass + with pytest.raises(AttributeError): + A._fields_ = [("a", A)] diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_buffers.py b/extra_tests/ctypes_tests/test_buffers.py rename from pypy/module/test_lib_pypy/ctypes_tests/test_buffers.py rename to extra_tests/ctypes_tests/test_buffers.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_buffers.py +++ b/extra_tests/ctypes_tests/test_buffers.py @@ -1,76 +1,38 @@ from ctypes import * -from .support import BaseCTypesTestChecker -class TestStringBuffer(BaseCTypesTestChecker): +def test_buffer(): + b = create_string_buffer(32) + assert len(b) == 32 + assert sizeof(b) == 32 * sizeof(c_char) + assert type(b[0]) is str - def test_buffer(self): - b = create_string_buffer(32) - assert len(b) == 32 - assert sizeof(b) == 32 * sizeof(c_char) - assert type(b[0]) is str + b = create_string_buffer(33L) + assert len(b) == 33 + assert sizeof(b) == 33 * sizeof(c_char) + assert type(b[0]) is str - b = create_string_buffer(33L) - assert len(b) == 33 - assert sizeof(b) == 33 * sizeof(c_char) - assert type(b[0]) is str + b = create_string_buffer(b"abc") + assert len(b) == 4 # trailing nul char + assert sizeof(b) == 4 * sizeof(c_char) + assert type(b[0]) is str + assert b[0] == b"a" + assert b[:] == b"abc\0" - b = create_string_buffer("abc") - assert len(b) == 4 # trailing nul char - assert sizeof(b) == 4 * sizeof(c_char) - assert type(b[0]) is str - assert b[0] == "a" - assert b[:] == "abc\0" +def test_from_buffer(): + b1 = bytearray(b"abcde") + b = (c_char * 5).from_buffer(b1) + assert b[2] == b"c" + # + b1 = bytearray(b"abcd") + b = c_int.from_buffer(b1) + assert b.value in (1684234849, # little endian + 1633837924) # big endian - def test_string_conversion(self): - b = create_string_buffer(u"abc") - assert len(b) == 4 # trailing nul char - assert sizeof(b) == 4 * sizeof(c_char) - assert type(b[0]) is str - assert b[0] == "a" - assert b[:] == "abc\0" - - def test_from_buffer(self): - b1 = bytearray("abcde") - b = (c_char * 5).from_buffer(b1) - assert b[2] == "c" - # - b1 = bytearray("abcd") - b = c_int.from_buffer(b1) - assert b.value in (1684234849, # little endian - 1633837924) # big endian - - def test_from_buffer_keepalive(self): - # Issue #2878 - b1 = bytearray("ab") - array = (c_uint16 * 32)() - array[6] = c_uint16.from_buffer(b1) - # this is also what we get on CPython. I don't think it makes - # sense because the array contains just a copy of the number. - assert array._objects == {'6': b1} - - try: - c_wchar - except NameError: - pass - else: - def test_unicode_buffer(self): - b = create_unicode_buffer(32) - assert len(b) == 32 - assert sizeof(b) == 32 * sizeof(c_wchar) - assert type(b[0]) is unicode - - b = create_unicode_buffer(u"abc") - assert len(b) == 4 # trailing nul char - assert sizeof(b) == 4 * sizeof(c_wchar) - assert type(b[0]) is unicode - assert b[0] == u"a" - assert b[:] == "abc\0" - - def test_unicode_conversion(self): - b = create_unicode_buffer("abc") - assert len(b) == 4 # trailing nul char - assert sizeof(b) == 4 * sizeof(c_wchar) - assert type(b[0]) is unicode - assert b[0] == u"a" - assert b[:] == "abc\0" - +def test_from_buffer_keepalive(): + # Issue #2878 + b1 = bytearray(b"ab") + array = (c_uint16 * 32)() + array[6] = c_uint16.from_buffer(b1) + # this is also what we get on CPython. I don't think it makes + # sense because the array contains just a copy of the number. + assert array._objects == {'6': b1} diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_callback_traceback.py b/extra_tests/ctypes_tests/test_callback_traceback.py rename from pypy/module/test_lib_pypy/ctypes_tests/test_callback_traceback.py rename to extra_tests/ctypes_tests/test_callback_traceback.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_callback_traceback.py +++ b/extra_tests/ctypes_tests/test_callback_traceback.py @@ -1,80 +1,35 @@ # derived from test_random_things.py -import py +import pytest + from ctypes import * -import sys -def callback_func(arg): - 42 / arg - raise ValueError(arg) +_rawffi = pytest.importorskip('_rawffi') -class TestCallbackTraceback: - # When an exception is raised in a ctypes callback function, the C - # code prints a traceback. +# +# This test makes sure the exception types *and* the exception +# value is printed correctly. + +@pytest.mark.skipif("sys.flags.inspect") +def test_SystemExit(monkeypatch, capsys): + """ + When an exception is raised in a ctypes callback function, the C + code prints a traceback. When SystemExit is raised, the interpreter + normally exits immediately. + """ + def callback_func(arg): + raise SystemExit(42) + def custom_exit(value): + raise Exception("<<<exit(%r)>>>" % (value,)) + monkeypatch.setattr(_rawffi, 'exit', custom_exit) + cb = CFUNCTYPE(c_int, c_int)(callback_func) + cb2 = cast(cast(cb, c_void_p), CFUNCTYPE(c_int, c_int)) + out, err = capsys.readouterr() + assert not err + cb2(0) + out, err = capsys.readouterr() + assert err.splitlines()[-1] == "Exception: <<<exit(42)>>>" # - # This test makes sure the exception types *and* the exception - # value is printed correctly. - # - # Changed in 0.9.3: No longer is '(in callback)' prepended to the - # error message - instead a additional frame for the C code is - # created, then a full traceback printed. When SystemExit is - # raised in a callback function, the interpreter exits. - - def capture_stderr(self, func, *args, **kw): - # helper - call function 'func', and return the captured stderr - import StringIO - old_stderr = sys.stderr - logger = sys.stderr = StringIO.StringIO() - try: - func(*args, **kw) - finally: - sys.stderr = old_stderr - return logger.getvalue() - - def test_ValueError(self): - cb = CFUNCTYPE(c_int, c_int)(callback_func) - out = self.capture_stderr(cb, 42) - assert out.splitlines()[-1] == ( - "ValueError: 42") - - def test_IntegerDivisionError(self): - cb = CFUNCTYPE(c_int, c_int)(callback_func) - out = self.capture_stderr(cb, 0) - assert out.splitlines()[-1][:19] == ( - "ZeroDivisionError: ") - - def test_FloatDivisionError(self): - cb = CFUNCTYPE(c_int, c_double)(callback_func) - out = self.capture_stderr(cb, 0.0) - assert out.splitlines()[-1][:19] == ( - "ZeroDivisionError: ") - - def test_TypeErrorDivisionError(self): - cb = CFUNCTYPE(c_int, c_char_p)(callback_func) - out = self.capture_stderr(cb, "spam") - assert out.splitlines()[-1].startswith( - "TypeError: " - "unsupported operand type(s) for") - - def test_SystemExit(self): - import _rawffi - if sys.flags.inspect: - skip("requires sys.flags.inspect == 0") - def callback_func(arg): - raise SystemExit(42) - def custom_exit(value): - raise Exception("<<<exit(%r)>>>" % (value,)) - original_exit = _rawffi.exit - try: - _rawffi.exit = custom_exit - # - cb = CFUNCTYPE(c_int, c_int)(callback_func) - cb2 = cast(cast(cb, c_void_p), CFUNCTYPE(c_int, c_int)) - out = self.capture_stderr(cb2, 0) - assert out.splitlines()[-1] == "Exception: <<<exit(42)>>>" - # - cb = CFUNCTYPE(c_int, c_int)(callback_func) - out = self.capture_stderr(cb, 0) - assert out.splitlines()[-1] == "Exception: <<<exit(42)>>>" - # - finally: - _rawffi.exit = original_exit + cb = CFUNCTYPE(c_int, c_int)(callback_func) + cb(0) + out, err = capsys.readouterr() + assert err.splitlines()[-1] == "Exception: <<<exit(42)>>>" diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_callbacks.py b/extra_tests/ctypes_tests/test_callbacks.py rename from pypy/module/test_lib_pypy/ctypes_tests/test_callbacks.py rename to extra_tests/ctypes_tests/test_callbacks.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_callbacks.py +++ b/extra_tests/ctypes_tests/test_callbacks.py @@ -1,283 +1,194 @@ +import pytest + +import math from ctypes import * -import pytest from .support import BaseCTypesTestChecker -class TestCallbacks(BaseCTypesTestChecker): - functype = CFUNCTYPE - -## def tearDown(self): -## import gc -## gc.collect() - - def callback(self, *args): - self.got_args = args - return args[-1] - - def check_type(self, typ, arg): - unwrapped_types = { - c_float: (float,), - c_double: (float,), - c_char: (str,), - c_char_p: (str,), - c_uint: (int, long), - c_ulong: (int, long), - } - - PROTO = self.functype.im_func(typ, typ) - cfunc = PROTO(self.callback) - result = cfunc(arg) - if typ == c_float: - assert abs(result - arg) < 0.000001 - else: - assert self.got_args == (arg,) - assert result == arg - - result2 = cfunc(typ(arg)) - assert type(result2) in unwrapped_types.get(typ, (int, long)) - - PROTO = self.functype.im_func(typ, c_byte, typ) - result = PROTO(self.callback)(-3, arg) - if typ == c_float: - assert abs(result - arg) < 0.000001 - else: - assert self.got_args == (-3, arg) - assert result == arg - - ################ - - def test_byte(self): - self.check_type(c_byte, 42) - self.check_type(c_byte, -42) - - def test_ubyte(self): - self.check_type(c_ubyte, 42) - - def test_short(self): - self.check_type(c_short, 42) - self.check_type(c_short, -42) - - def test_ushort(self): - self.check_type(c_ushort, 42) - - def test_int(self): - self.check_type(c_int, 42) - self.check_type(c_int, -42) - - def test_uint(self): - self.check_type(c_uint, 42) - - def test_long(self): - self.check_type(c_long, 42) - self.check_type(c_long, -42) - - def test_ulong(self): - self.check_type(c_ulong, 42) - - def test_longlong(self): - self.check_type(c_longlong, 42) - self.check_type(c_longlong, -42) - - def test_ulonglong(self): - self.check_type(c_ulonglong, 42) - - def test_float(self): - # only almost equal: double -> float -> double - import math - self.check_type(c_float, math.e) - self.check_type(c_float, -math.e) - - def test_double(self): - self.check_type(c_double, 3.14) - self.check_type(c_double, -3.14) - - def test_char(self): - self.check_type(c_char, "x") - self.check_type(c_char, "a") - - # disabled: would now (correctly) raise a RuntimeWarning about - # a memory leak. A callback function cannot return a non-integral - # C type without causing a memory leak. -## def test_char_p(self): -## self.check_type(c_char_p, "abc") -## self.check_type(c_char_p, "def") - - - @pytest.mark.xfail( - reason="we are less strict about callback return type sanity") - def test_unsupported_restype_1(self): - # Only "fundamental" result types are supported for callback - # functions, the type must have a non-NULL stgdict->setfunc. - # POINTER(c_double), for example, is not supported. - - prototype = self.functype.im_func(POINTER(c_double)) - # The type is checked when the prototype is called - with pytest.raises(TypeError): - prototype(lambda: None) - +functypes = [CFUNCTYPE] try: - WINFUNCTYPE + functypes.append(WINFUNCTYPE) except NameError: pass -else: - class TestStdcallCallbacks(TestCallbacks): - functype = WINFUNCTYPE -################################################################ -class TestSampleCallbacks(BaseCTypesTestChecker): +def callback(*args): + callback.got_args = args + return args[-1] - def test_integrate(self): - # Derived from some then non-working code, posted by David Foster - import conftest - _ctypes_test = str(conftest.sofile) - dll = CDLL(_ctypes_test) +unwrapped_types = { + c_float: (float,), + c_double: (float,), + c_char: (str,), + c_char_p: (str,), + c_uint: (int, long), + c_ulong: (int, long), + } - # The function prototype called by 'integrate': double func(double); - CALLBACK = CFUNCTYPE(c_double, c_double) +@pytest.mark.parametrize("typ, arg", [ + (c_byte, 42), + (c_byte, -42), + (c_ubyte, 42), + (c_short, 42), + (c_short, -42), + (c_ushort, 42), + (c_int, 42), + (c_int, -42), + (c_uint, 42), + (c_long, 42), + (c_long, -42), + (c_ulong, 42), + (c_longlong, 42), + (c_longlong, -42), + (c_ulonglong, 42), + (c_float, math.e), # only almost equal: double -> float -> double + (c_float, -math.e), + (c_double, 3.14), + (c_double, -3.14), + (c_char, b"x"), + (c_char, b"a"), +]) +@pytest.mark.parametrize('functype', functypes) +def test_types(typ, arg, functype): + PROTO = functype(typ, typ) + cfunc = PROTO(callback) + result = cfunc(arg) + if typ == c_float: + assert abs(result - arg) < 0.000001 + else: + assert callback.got_args == (arg,) + assert result == arg - # The integrate function itself, exposed from the _ctypes_test dll - integrate = dll.integrate - integrate.argtypes = (c_double, c_double, CALLBACK, c_long) - integrate.restype = c_double + result2 = cfunc(typ(arg)) + assert type(result2) in unwrapped_types.get(typ, (int, long)) - def func(x): - print 'calculating x**2 of',x - return x**2 + PROTO = functype(typ, c_byte, typ) + result = PROTO(callback)(-3, arg) + if typ == c_float: + assert abs(result - arg) < 0.000001 + else: + assert callback.got_args == (-3, arg) + assert result == arg - result = integrate(0.0, 1.0, CALLBACK(func), 10) - diff = abs(result - 1./3.) +@pytest.mark.parametrize('functype', functypes) +def test_unsupported_restype_1(functype): + # Only "fundamental" result types are supported for callback + # functions, the type must have a non-NULL stgdict->setfunc. + # POINTER(c_double), for example, is not supported. - assert diff < 0.01, "%s not less than 0.01" % diff + prototype = functype(POINTER(c_double)) + # The type is checked when the prototype is called + with pytest.raises(TypeError): + prototype(lambda: None) -################################################################ -class TestMoreCallbacks(BaseCTypesTestChecker): +def test_callback_with_struct_argument(): + class RECT(Structure): + _fields_ = [("left", c_int), ("top", c_int), + ("right", c_int), ("bottom", c_int)] - def test_callback_with_struct_argument(self): - class RECT(Structure): - _fields_ = [("left", c_int), ("top", c_int), - ("right", c_int), ("bottom", c_int)] + proto = CFUNCTYPE(c_int, RECT) - proto = CFUNCTYPE(c_int, RECT) - def callback(point): - point.left *= -1 - return point.left+point.top+point.right+point.bottom + def callback(point): + point.left *= -1 + return point.left + point.top + point.right + point.bottom - cbp = proto(callback) + cbp = proto(callback) + rect = RECT(-1000, 100, 10, 1) + res = cbp(rect) + assert res == 1111 + assert rect.left == -1000 # must not have been changed! - rect = RECT(-1000,100,10,1) +def test_callback_from_c_with_struct_argument(dll): + class RECT(Structure): + _fields_ = [("left", c_long), ("top", c_long), + ("right", c_long), ("bottom", c_long)] - res = cbp(rect) + proto = CFUNCTYPE(c_int, RECT) - assert res == 1111 - assert rect.left == -1000 # must not have been changed! + def callback(point): + return point.left + point.top + point.right + point.bottom - def test_callback_from_c_with_struct_argument(self): - import conftest - _ctypes_test = str(conftest.sofile) - dll = CDLL(_ctypes_test) + cbp = proto(callback) + rect = RECT(1000, 100, 10, 1) - class RECT(Structure): - _fields_ = [("left", c_long), ("top", c_long), - ("right", c_long), ("bottom", c_long)] + call_callback_with_rect = dll.call_callback_with_rect + call_callback_with_rect.restype = c_int + call_callback_with_rect.argtypes = [proto, RECT] + res = call_callback_with_rect(cbp, rect) + assert res == 1111 - proto = CFUNCTYPE(c_int, RECT) - def callback(point): - return point.left+point.top+point.right+point.bottom +def test_callback_unsupported_return_struct(): + class RECT(Structure): + _fields_ = [("left", c_int), ("top", c_int), + ("right", c_int), ("bottom", c_int)] - cbp = proto(callback) - rect = RECT(1000,100,10,1) + proto = CFUNCTYPE(RECT, c_int) + with pytest.raises(TypeError): + proto(lambda r: 0) - call_callback_with_rect = dll.call_callback_with_rect - call_callback_with_rect.restype = c_int - call_callback_with_rect.argtypes = [proto, RECT] - res = call_callback_with_rect(cbp, rect) - assert res == 1111 - def test_callback_unsupported_return_struct(self): - class RECT(Structure): - _fields_ = [("left", c_int), ("top", c_int), - ("right", c_int), ("bottom", c_int)] +def test_qsort(dll): + PI = POINTER(c_int) + A = c_int*5 + a = A() + for i in range(5): + a[i] = 5-i - proto = CFUNCTYPE(RECT, c_int) - with pytest.raises(TypeError): - proto(lambda r: 0) + assert a[0] == 5 # sanity + def comp(a, b): + a = a.contents.value + b = b.contents.value + return cmp(a,b) + qs = dll.my_qsort + qs.restype = None + CMP = CFUNCTYPE(c_int, PI, PI) + qs.argtypes = (PI, c_size_t, c_size_t, CMP) - def test_qsort(self): - import conftest - _ctypes_test = str(conftest.sofile) - dll = CDLL(_ctypes_test) + qs(cast(a, PI), 5, sizeof(c_int), CMP(comp)) - PI = POINTER(c_int) - A = c_int*5 - a = A() - for i in range(5): - a[i] = 5-i + res = list(a) - assert a[0] == 5 # sanity + assert res == [1,2,3,4,5] - def comp(a, b): - a = a.contents.value - b = b.contents.value - return cmp(a,b) - qs = dll.my_qsort - qs.restype = None - CMP = CFUNCTYPE(c_int, PI, PI) - qs.argtypes = (PI, c_size_t, c_size_t, CMP) +def test_pyobject_as_opaque(dll): + def callback(arg): + return arg() - qs(cast(a, PI), 5, sizeof(c_int), CMP(comp)) + CTP = CFUNCTYPE(c_int, py_object) + cfunc = dll._testfunc_callback_opaque + cfunc.argtypes = [CTP, py_object] + cfunc.restype = c_int + res = cfunc(CTP(callback), lambda : 3) + assert res == 3 - res = list(a) +def test_callback_void(capsys, dll): + def callback(): + pass - assert res == [1,2,3,4,5] + CTP = CFUNCTYPE(None) + cfunc = dll._testfunc_callback_void + cfunc.argtypes = [CTP] + cfunc.restype = int + cfunc(CTP(callback)) + out, err = capsys.readouterr() + assert (out, err) == ("", "") - def test_pyobject_as_opaque(self): - import conftest - _ctypes_test = str(conftest.sofile) - dll = CDLL(_ctypes_test) - def callback(arg): - return arg() +def test_callback_pyobject(): + def callback(obj): + return obj - CTP = CFUNCTYPE(c_int, py_object) - cfunc = dll._testfunc_callback_opaque - cfunc.argtypes = [CTP, py_object] - cfunc.restype = c_int - res = cfunc(CTP(callback), lambda : 3) - assert res == 3 + FUNC = CFUNCTYPE(py_object, py_object) + cfunc = FUNC(callback) + param = c_int(42) + assert cfunc(param) is param - def test_callback_void(self, capsys): - import conftest - _ctypes_test = str(conftest.sofile) - dll = CDLL(_ctypes_test) - - def callback(): - pass - - CTP = CFUNCTYPE(None) - cfunc = dll._testfunc_callback_void - cfunc.argtypes = [CTP] - cfunc.restype = int - cfunc(CTP(callback)) - out, err = capsys.readouterr() - assert (out, err) == ("", "") - - - def test_callback_pyobject(self): - def callback(obj): - return obj - - FUNC = CFUNCTYPE(py_object, py_object) - cfunc = FUNC(callback) - param = c_int(42) - assert cfunc(param) is param - - def test_raise_argumenterror(self): - def callback(x): - pass - FUNC = CFUNCTYPE(None, c_void_p) - cfunc = FUNC(callback) - param = c_uint(42) - with pytest.raises(ArgumentError): - cfunc(param) +def test_raise_argumenterror(): + def callback(x): + pass + FUNC = CFUNCTYPE(None, c_void_p) + cfunc = FUNC(callback) + param = c_uint(42) + with pytest.raises(ArgumentError): + cfunc(param) diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_cast.py b/extra_tests/ctypes_tests/test_cast.py rename from pypy/module/test_lib_pypy/ctypes_tests/test_cast.py rename to extra_tests/ctypes_tests/test_cast.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_cast.py +++ b/extra_tests/ctypes_tests/test_cast.py @@ -1,106 +1,30 @@ +import pytest + from ctypes import * -import sys, py -from .support import BaseCTypesTestChecker -def setup_module(mod): - import conftest - mod.lib = CDLL(str(conftest.sofile)) +def test_cast_functype(dll): + # make sure we can cast function type + my_sqrt = dll.my_sqrt + saved_objects = my_sqrt._objects.copy() + sqrt = cast(cast(my_sqrt, c_void_p), CFUNCTYPE(c_double, c_double)) + assert sqrt(4.0) == 2.0 + assert not cast(0, CFUNCTYPE(c_int)) + # + assert sqrt._objects is my_sqrt._objects # on CPython too + my_sqrt._objects.clear() + my_sqrt._objects.update(saved_objects) -class TestCast(BaseCTypesTestChecker): +def test_cast_argumenterror(): + param = c_uint(42) + with pytest.raises(ArgumentError): + cast(param, c_void_p) - def test_array2pointer(self): - array = (c_int * 3)(42, 17, 2) - - # casting an array to a pointer works. - ptr = cast(array, POINTER(c_int)) - assert [ptr[i] for i in range(3)] == [42, 17, 2] - - if 2*sizeof(c_short) == sizeof(c_int): - ptr = cast(array, POINTER(c_short)) - if sys.byteorder == "little": - assert [ptr[i] for i in range(6)] == ( - [42, 0, 17, 0, 2, 0]) - else: - assert [ptr[i] for i in range(6)] == ( - [0, 42, 0, 17, 0, 2]) - - def test_address2pointer(self): - array = (c_int * 3)(42, 17, 2) - - address = addressof(array) - ptr = cast(c_void_p(address), POINTER(c_int)) - assert [ptr[i] for i in range(3)] == [42, 17, 2] - - ptr = cast(address, POINTER(c_int)) - assert [ptr[i] for i in range(3)] == [42, 17, 2] - - def test_p2a_objects(self): - py.test.skip("we make copies of strings") - array = (c_char_p * 5)() - assert array._objects is None - array[0] = "foo bar" - assert array._objects == {'0': "foo bar"} - - p = cast(array, POINTER(c_char_p)) - # array and p share a common _objects attribute - assert p._objects is array._objects - assert array._objects == {'0': "foo bar", id(array): array} - p[0] = "spam spam" - assert p._objects == {'0': "spam spam", id(array): array} - assert array._objects is p._objects - p[1] = "foo bar" - assert p._objects == {'1': 'foo bar', '0': "spam spam", id(array): array} - assert array._objects is p._objects - - def test_other(self): - p = cast((c_int * 4)(1, 2, 3, 4), POINTER(c_int)) - assert p[:4] == [1,2, 3, 4] - c_int() - assert p[:4] == [1, 2, 3, 4] - p[2] = 96 - assert p[:4] == [1, 2, 96, 4] - c_int() - assert p[:4] == [1, 2, 96, 4] - - def test_char_p(self): - # This didn't work: bad argument to internal function - s = c_char_p("hiho") - - assert cast(cast(s, c_void_p), c_char_p).value == ( - "hiho") - - try: - c_wchar_p - except NameError: - pass - else: - def test_wchar_p(self): - s = c_wchar_p("hiho") - assert cast(cast(s, c_void_p), c_wchar_p).value == ( - "hiho") - - def test_cast_functype(self): - # make sure we can cast function type - my_sqrt = lib.my_sqrt - saved_objects = my_sqrt._objects.copy() - sqrt = cast(cast(my_sqrt, c_void_p), CFUNCTYPE(c_double, c_double)) - assert sqrt(4.0) == 2.0 - assert not cast(0, CFUNCTYPE(c_int)) - # - assert sqrt._objects is my_sqrt._objects # on CPython too - my_sqrt._objects.clear() - my_sqrt._objects.update(saved_objects) - - def test_cast_argumenterror(self): - param = c_uint(42) - py.test.raises(ArgumentError, "cast(param, c_void_p)") - - def test_c_bool(self): - x = c_bool(42) - assert x.value is True - x = c_bool(0.0) - assert x.value is False - x = c_bool("") - assert x.value is False - x = c_bool(['yadda']) - assert x.value is True +def test_c_bool(): + x = c_bool(42) + assert x.value is True + x = c_bool(0.0) + assert x.value is False + x = c_bool("") + assert x.value is False + x = c_bool(['yadda']) + assert x.value is True diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_commethods.py b/extra_tests/ctypes_tests/test_commethods.py rename from pypy/module/test_lib_pypy/ctypes_tests/test_commethods.py rename to extra_tests/ctypes_tests/test_commethods.py diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_errno.py b/extra_tests/ctypes_tests/test_errno.py rename from pypy/module/test_lib_pypy/ctypes_tests/test_errno.py rename to extra_tests/ctypes_tests/test_errno.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_errno.py +++ b/extra_tests/ctypes_tests/test_errno.py @@ -1,26 +1,19 @@ -import py +import pytest import ctypes -from _ctypes import function +_rawffi = pytest.importorskip('_rawffi') # PyPy-only -try: - import _rawffi -except ImportError: - py.test.skip("app-level test only for PyPy") +def test_errno_saved_and_restored(): + def check(): + assert _rawffi.get_errno() == 42 + assert ctypes.get_errno() == old + check.free_temp_buffers = lambda *args: None + f = ctypes._CFuncPtr() + old = _rawffi.get_errno() + f._flags_ = _rawffi.FUNCFLAG_USE_ERRNO + ctypes.set_errno(42) + f._call_funcptr(check) + assert _rawffi.get_errno() == old + ctypes.set_errno(0) -class TestErrno: - - def test_errno_saved_and_restored(self): - def check(): - assert _rawffi.get_errno() == 42 - assert ctypes.get_errno() == old - check.free_temp_buffers = lambda *args: None - f = function.CFuncPtr() - old = _rawffi.get_errno() - f._flags_ = _rawffi.FUNCFLAG_USE_ERRNO - ctypes.set_errno(42) - f._call_funcptr(check) - assert _rawffi.get_errno() == old - ctypes.set_errno(0) - - # see also test_functions.test_errno +# see also test_functions.test_errno diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_extra.py b/extra_tests/ctypes_tests/test_extra.py rename from pypy/module/test_lib_pypy/ctypes_tests/test_extra.py rename to extra_tests/ctypes_tests/test_extra.py --- a/pypy/module/test_lib_pypy/ctypes_tests/test_extra.py +++ b/extra_tests/ctypes_tests/test_extra.py @@ -5,244 +5,239 @@ import py from ctypes import * -from .support import BaseCTypesTestChecker -class TestExtra(BaseCTypesTestChecker): - def test_primitive_pointer(self): - x = c_int(5) - assert x.value == 5 - x.value = 6 - assert x.value == 6 +def test_primitive_pointer(): + x = c_int(5) + assert x.value == 5 + x.value = 6 + assert x.value == 6 - p = pointer(x) # p ---> x = 6 - assert isinstance(p.contents, c_int) - p.contents.value += 1 - assert x.value == 7 # p ---> x = 7 + p = pointer(x) # p ---> x = 6 + assert isinstance(p.contents, c_int) + p.contents.value += 1 + assert x.value == 7 # p ---> x = 7 - y = c_int(12) - p.contents = y # p ---> y = 12 - p.contents.value += 2 # p ---> y = 14 - assert y.value == 14 - assert x.value == 7 + y = c_int(12) + p.contents = y # p ---> y = 12 + p.contents.value += 2 # p ---> y = 14 + assert y.value == 14 + assert x.value == 7 - pp = pointer(p) # pp ---> p ---> y = 14 - pp.contents.contents = x # pp ---> p ---> x = 7 - p.contents.value += 2 # pp ---> p ---> x = 9 - assert x.value == 9 + pp = pointer(p) # pp ---> p ---> y = 14 + pp.contents.contents = x # pp ---> p ---> x = 7 + p.contents.value += 2 # pp ---> p ---> x = 9 + assert x.value == 9 - assert isinstance(p[0], int) - p[0] += 1 # pp ---> p ---> x = 10 - assert x.value == 10 - z = c_int(86) - p[0] = z # pp ---> p ---> x = 86 (not z!) - assert x.value == 86 - z.value = 84 - assert x.value == 86 + assert isinstance(p[0], int) + p[0] += 1 # pp ---> p ---> x = 10 + assert x.value == 10 + z = c_int(86) + p[0] = z # pp ---> p ---> x = 86 (not z!) + assert x.value == 86 + z.value = 84 + assert x.value == 86 - assert isinstance(pp[0], POINTER(c_int)) - assert pp[0].contents.value == x.value == 86 - pp[0].contents = z # pp ---> p ---> z = 84 - assert p.contents.value == z.value == 84 + assert isinstance(pp[0], POINTER(c_int)) + assert pp[0].contents.value == x.value == 86 + pp[0].contents = z # pp ---> p ---> z = 84 + assert p.contents.value == z.value == 84 - ## *** the rest is commented out because it should work but occasionally - ## *** trigger a ctypes bug (SourceForge bug #1467852). *** - ## q = pointer(y) - ## pp[0] = q # pp ---> p ---> y = 14 - ## assert y.value == 14 # (^^^ not q! ) - ## assert p.contents.value == 14 - ## assert pp.contents.contents.value == 14 - ## q.contents = x - ## assert pp.contents.contents.value == 14 +## *** the rest is commented out because it should work but occasionally +## *** trigger a ctypes bug (SourceForge bug #1467852). *** +## q = pointer(y) +## pp[0] = q # pp ---> p ---> y = 14 +## assert y.value == 14 # (^^^ not q! ) +## assert p.contents.value == 14 +## assert pp.contents.contents.value == 14 +## q.contents = x +## assert pp.contents.contents.value == 14 - def test_char_p(self): - x = c_char_p("hello\x00world") - assert x.value == "hello" - x.value = "world" - assert x.value == "world" +def test_char_p(): + x = c_char_p(b"hello\x00world") + assert x.value == b"hello" + x.value = b"world" + assert x.value == b"world" - p = pointer(x) - assert p[0] == x.value == "world" - p[0] = "other" - assert x.value == p.contents.value == p[0] == "other" + p = pointer(x) + assert p[0] == x.value == b"world" + p[0] = b"other" + assert x.value == p.contents.value == p[0] == b"other" - myarray = (c_char_p * 10)() - myarray[7] = "hello" - assert isinstance(myarray[7], str) - assert myarray[7] == "hello" + myarray = (c_char_p * 10)() + myarray[7] = b"hello" + assert isinstance(myarray[7], str) + assert myarray[7] == b"hello" - def test_struct(self): - class tagpoint(Structure): - _fields_ = [('x', c_int), - ('p', POINTER(c_short))] +def test_struct(): + class tagpoint(Structure): + _fields_ = [('x', c_int), + ('p', POINTER(c_short))] - y = c_short(123) - z = c_short(-33) - s = tagpoint() - s.p.contents = z - assert s.p.contents.value == -33 - s.p = pointer(y) - assert s.p.contents.value == 123 - s.p.contents.value = 124 - assert y.value == 124 + y = c_short(123) + z = c_short(-33) + s = tagpoint() + s.p.contents = z + assert s.p.contents.value == -33 + s.p = pointer(y) + assert s.p.contents.value == 123 + s.p.contents.value = 124 + assert y.value == 124 - s = tagpoint(x=12) - assert s.x == 12 - s = tagpoint(17, p=pointer(z)) - assert s.x == 17 - assert s.p.contents.value == -33 + s = tagpoint(x=12) + assert s.x == 12 + s = tagpoint(17, p=pointer(z)) + assert s.x == 17 + assert s.p.contents.value == -33 - def test_ptr_array(self): - a = (POINTER(c_ushort) * 5)() - x = c_ushort(52) - y = c_ushort(1000) +def test_ptr_array(): + a = (POINTER(c_ushort) * 5)() + x = c_ushort(52) + y = c_ushort(1000) - a[2] = pointer(x) - assert a[2].contents.value == 52 - a[2].contents.value += 1 - assert x.value == 53 + a[2] = pointer(x) + assert a[2].contents.value == 52 + a[2].contents.value += 1 + assert x.value == 53 - a[3].contents = y - assert a[3].contents.value == 1000 - a[3].contents.value += 1 - assert y.value == 1001 + a[3].contents = y + assert a[3].contents.value == 1000 + a[3].contents.value += 1 + assert y.value == 1001 - def test_void_p(self): - x = c_int(12) - p1 = cast(pointer(x), c_void_p) - p2 = cast(p1, POINTER(c_int)) - assert p2.contents.value == 12 +def test_void_p(): + x = c_int(12) + p1 = cast(pointer(x), c_void_p) + p2 = cast(p1, POINTER(c_int)) + assert p2.contents.value == 12 - def test_char_array(self): - a = (c_char * 3)() - a[0] = 'x' - a[1] = 'y' - assert a.value == 'xy' - a[2] = 'z' - assert a.value == 'xyz' +def test_char_array(): + a = (c_char * 3)() + a[0] = b'x' + a[1] = b'y' + assert a.value == b'xy' + a[2] = b'z' + assert a.value == b'xyz' - b = create_string_buffer(3) - assert type(b) is type(a) - assert len(b) == 3 + b = create_string_buffer(3) + assert type(b) is type(a) + assert len(b) == 3 - b.value = "nxw" - assert b[0] == 'n' - assert b[1] == 'x' - assert b[2] == 'w' + b.value = b"nxw" + assert b[0] == b'n' + assert b[1] == b'x' + assert b[2] == b'w' - b.value = "?" - assert b[0] == '?' - assert b[1] == '\x00' - assert b[2] == 'w' + b.value = b"?" + assert b[0] == b'?' + assert b[1] == b'\x00' + assert b[2] == b'w' - class S(Structure): - _fields_ = [('p', POINTER(c_char))] + class S(Structure): + _fields_ = [('p', POINTER(c_char))] - s = S() - s.p = b - s.p.contents.value = '!' - assert b.value == '!' + s = S() + s.p = b + s.p.contents.value = b'!' + assert b.value == b'!' - assert len(create_string_buffer(0)) == 0 + assert len(create_string_buffer(0)) == 0 - def test_array(self): - a = (c_int * 10)() +def test_array(): + a = (c_int * 10)() - class S(Structure): - _fields_ = [('p', POINTER(c_int))] + class S(Structure): + _fields_ = [('p', POINTER(c_int))] - s = S() - s.p = a - s.p.contents.value = 42 - assert a[0] == 42 + s = S() + s.p = a + s.p.contents.value = 42 + assert a[0] == 42 - a = (c_int * 5)(5, 6, 7) - assert list(a) == [5, 6, 7, 0, 0] + a = (c_int * 5)(5, 6, 7) + assert list(a) == [5, 6, 7, 0, 0] - def test_truth_value(self): - p = POINTER(c_int)() - assert not p - p.contents = c_int(12) - assert p - # I can't figure out how to reset p to NULL... +def test_truth_value(): + p = POINTER(c_int)() + assert not p + p.contents = c_int(12) + assert p + # I can't figure out how to reset p to NULL... - assert c_int(12) - assert not c_int(0) # a bit strange, if you ask me - assert c_int(-1) - assert not c_byte(0) - assert not c_char('\x00') # hum - assert not c_float(0.0) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit