[pypy-commit] pypy default: Update to cffi/70927696eb9c
arigo
noreply at buildbot.pypy.org
Sat Feb 16 10:29:22 CET 2013
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r61308:c44d9205dbb4
Date: 2013-02-16 10:29 +0100
http://bitbucket.org/pypy/pypy/changeset/c44d9205dbb4/
Log: Update to cffi/70927696eb9c
diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py
--- a/pypy/module/_cffi_backend/newtype.py
+++ b/pypy/module/_cffi_backend/newtype.py
@@ -264,8 +264,8 @@
# ____________________________________________________________
- at unwrap_spec(name=str)
-def new_enum_type(space, name, w_enumerators, w_enumvalues):
+ at unwrap_spec(name=str, basectype=ctypeobj.W_CType)
+def new_enum_type(space, name, w_enumerators, w_enumvalues, basectype):
enumerators_w = space.fixedview(w_enumerators)
enumvalues_w = space.fixedview(w_enumvalues)
if len(enumerators_w) != len(enumvalues_w):
@@ -273,53 +273,26 @@
space.wrap("tuple args must have the same size"))
enumerators = [space.str_w(w) for w in enumerators_w]
#
- smallest_value = 0
- largest_value = r_uint(0)
- i = 0
+ if (not isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned) and
+ not isinstance(basectype, ctypeprim.W_CTypePrimitiveUnsigned)):
+ raise OperationError(space.w_TypeError,
+ space.wrap("expected a primitive signed or unsigned base type"))
+ #
+ lvalue = lltype.malloc(rffi.CCHARP.TO, basectype.size, flavor='raw')
try:
for w in enumvalues_w:
- try:
- ulvalue = space.uint_w(w)
- except OperationError, e:
- if not e.match(space, space.w_ValueError):
- raise
- lvalue = space.int_w(w)
- if lvalue < smallest_value:
- smallest_value = lvalue
- else:
- if ulvalue > largest_value:
- largest_value = ulvalue
- i += 1 # 'i' is here for the exception case, see below
- except OperationError, e:
- if not e.match(space, space.w_OverflowError):
- raise
- raise operationerrfmt(space.w_OverflowError,
- "enum '%s' declaration for '%s' does not fit "
- "a long or unsigned long",
- name, enumerators[i])
+ # detects out-of-range or badly typed values
+ basectype.convert_from_object(lvalue, w)
+ finally:
+ lltype.free(lvalue, flavor='raw')
#
- if smallest_value < 0:
- if (smallest_value >= intmask(most_neg_value_of(rffi.INT)) and
- largest_value <= r_uint(most_pos_value_of(rffi.INT))):
- size = rffi.sizeof(rffi.INT)
- align = alignment(rffi.INT)
- elif largest_value <= r_uint(most_pos_value_of(rffi.LONG)):
- size = rffi.sizeof(rffi.LONG)
- align = alignment(rffi.LONG)
- else:
- raise operationerrfmt(space.w_OverflowError,
- "enum '%s' values don't all fit into either 'long' "
- "or 'unsigned long'", name)
+ size = basectype.size
+ align = basectype.align
+ if isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned):
enumvalues = [space.int_w(w) for w in enumvalues_w]
ctype = ctypeenum.W_CTypeEnumSigned(space, name, size, align,
enumerators, enumvalues)
else:
- if largest_value <= r_uint(most_pos_value_of(rffi.UINT)):
- size = rffi.sizeof(rffi.UINT)
- align = alignment(rffi.UINT)
- else:
- size = rffi.sizeof(rffi.ULONG)
- align = alignment(rffi.ULONG)
enumvalues = [space.uint_w(w) for w in enumvalues_w]
ctype = ctypeenum.W_CTypeEnumUnsigned(space, name, size, align,
enumerators, enumvalues)
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -1264,25 +1264,29 @@
py.test.raises(TypeError, callback, BFunc, cb, -42)
def test_enum_type():
- BEnum = new_enum_type("foo", (), ())
+ BUInt = new_primitive_type("unsigned int")
+ BEnum = new_enum_type("foo", (), (), BUInt)
assert repr(BEnum) == "<ctype 'enum foo'>"
assert BEnum.kind == "enum"
assert BEnum.cname == "enum foo"
assert BEnum.elements == {}
#
- BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20))
+ BInt = new_primitive_type("int")
+ BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt)
assert BEnum.kind == "enum"
assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'}
# 'elements' is not the real dict, but merely a copy
BEnum.elements[2] = '??'
assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'}
#
- BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5))
+ BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5), BUInt)
assert BEnum.elements == {5: 'ab'}
assert BEnum.relements == {'ab': 5, 'cd': 5}
def test_cast_to_enum():
- BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20))
+ BInt = new_primitive_type("int")
+ BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt)
+ assert sizeof(BEnum) == sizeof(BInt)
e = cast(BEnum, 0)
assert repr(e) == "<cdata 'enum foo' 0: def>"
assert repr(cast(BEnum, -42)) == "<cdata 'enum foo' -42>"
@@ -1294,18 +1298,27 @@
assert int(cast(BEnum, -242 + 2**128)) == -242
assert string(cast(BEnum, -242 + 2**128)) == '-242'
#
- BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20))
+ BUInt = new_primitive_type("unsigned int")
+ BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20), BUInt)
e = cast(BEnum, -1)
assert repr(e) == "<cdata 'enum bar' 4294967295>" # unsigned int
+ #
+ BLong = new_primitive_type("long")
+ BEnum = new_enum_type("baz", (), (), BLong)
+ assert sizeof(BEnum) == sizeof(BLong)
+ e = cast(BEnum, -1)
+ assert repr(e) == "<cdata 'enum baz' -1>"
def test_enum_with_non_injective_mapping():
- BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7))
+ BInt = new_primitive_type("int")
+ BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7), BInt)
e = cast(BEnum, 7)
assert repr(e) == "<cdata 'enum foo' 7: ab>"
assert string(e) == 'ab'
def test_enum_in_struct():
- BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20))
+ BInt = new_primitive_type("int")
+ BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt)
BStruct = new_struct_type("bar")
BStructPtr = new_pointer_type(BStruct)
complete_struct_or_union(BStruct, [('a1', BEnum, -1)])
@@ -1318,7 +1331,7 @@
"unsupported operand type for int(): 'NoneType'" in str(e.value)) #PyPy
py.test.raises(TypeError, 'p.a1 = "def"')
if sys.version_info < (3,):
- BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,))
+ BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,), BInt)
assert string(cast(BEnum2, 5)) == 'abc'
assert type(string(cast(BEnum2, 5))) is str
@@ -1327,66 +1340,25 @@
max_int = max_uint // 2
max_ulong = 2 ** (size_of_long()*8) - 1
max_long = max_ulong // 2
- # 'unsigned int' case
- e = new_enum_type("foo", ('a', 'b'), (0, 3))
- assert sizeof(e) == size_of_int()
- assert int(cast(e, -1)) == max_uint # 'e' is unsigned
- e = new_enum_type("foo", ('a', 'b'), (0, max_uint))
- assert sizeof(e) == size_of_int()
- assert int(cast(e, -1)) == max_uint
- assert e.elements == {0: 'a', max_uint: 'b'}
- assert e.relements == {'a': 0, 'b': max_uint}
- # 'signed int' case
- e = new_enum_type("foo", ('a', 'b'), (-1, max_int))
- assert sizeof(e) == size_of_int()
- assert int(cast(e, -1)) == -1
- assert e.elements == {-1: 'a', max_int: 'b'}
- assert e.relements == {'a': -1, 'b': max_int}
- e = new_enum_type("foo", ('a', 'b'), (-max_int-1, max_int))
- assert sizeof(e) == size_of_int()
- assert int(cast(e, -1)) == -1
- assert e.elements == {-max_int-1: 'a', max_int: 'b'}
- assert e.relements == {'a': -max_int-1, 'b': max_int}
- # 'unsigned long' case
- e = new_enum_type("foo", ('a', 'b'), (0, max_long))
- assert sizeof(e) == size_of_long()
- assert int(cast(e, -1)) == max_ulong # 'e' is unsigned
- e = new_enum_type("foo", ('a', 'b'), (0, max_ulong))
- assert sizeof(e) == size_of_long()
- assert int(cast(e, -1)) == max_ulong
- assert e.elements == {0: 'a', max_ulong: 'b'}
- assert e.relements == {'a': 0, 'b': max_ulong}
- # 'signed long' case
- e = new_enum_type("foo", ('a', 'b'), (-1, max_long))
- assert sizeof(e) == size_of_long()
- assert int(cast(e, -1)) == -1
- assert e.elements == {-1: 'a', max_long: 'b'}
- assert e.relements == {'a': -1, 'b': max_long}
- e = new_enum_type("foo", ('a', 'b'), (-max_long-1, max_long))
- assert sizeof(e) == size_of_long()
- assert int(cast(e, -1)) == -1
- assert e.elements == {-max_long-1: 'a', max_long: 'b'}
- assert e.relements == {'a': -max_long-1, 'b': max_long}
- # overflow: both negative items and items larger than max_long
- e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'),
- (-1, max_long + 1))
- assert str(e.value) == (
- "enum 'foo' values don't all fit into either 'long' "
- "or 'unsigned long'")
- # overflow: items smaller than -max_long-1
- e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'),
- (-max_long-2, 5))
- assert str(e.value) == (
- "enum 'foo' declaration for 'a' does not fit a long or unsigned long")
- # overflow: items larger than max_ulong
- e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'),
- (5, max_ulong+1))
- assert str(e.value) == (
- "enum 'foo' declaration for 'b' does not fit a long or unsigned long")
+ for BPrimitive in [new_primitive_type("int"),
+ new_primitive_type("unsigned int"),
+ new_primitive_type("long"),
+ new_primitive_type("unsigned long")]:
+ for x in [max_uint, max_int, max_ulong, max_long]:
+ for testcase in [x, x+1, -x-1, -x-2]:
+ if int(cast(BPrimitive, testcase)) == testcase:
+ # fits
+ BEnum = new_enum_type("foo", ("AA",), (testcase,),
+ BPrimitive)
+ assert int(cast(BEnum, testcase)) == testcase
+ else:
+ # overflows
+ py.test.raises(OverflowError, new_enum_type,
+ "foo", ("AA",), (testcase,), BPrimitive)
def test_callback_returning_enum():
BInt = new_primitive_type("int")
- BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20))
+ BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt)
def cb(n):
if n & 1:
return cast(BEnum, n)
@@ -1402,7 +1374,8 @@
def test_callback_returning_enum_unsigned():
BInt = new_primitive_type("int")
- BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20))
+ BUInt = new_primitive_type("unsigned int")
+ BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20), BUInt)
def cb(n):
if n & 1:
return cast(BEnum, n)
More information about the pypy-commit
mailing list