[pypy-commit] pypy py3.5: hg merge default
arigo
pypy.commits at gmail.com
Sun Feb 19 10:07:44 EST 2017
Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r90201:bd18926a5492
Date: 2017-02-19 16:05 +0100
http://bitbucket.org/pypy/pypy/changeset/bd18926a5492/
Log: hg merge default
diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -604,7 +604,8 @@
"""
# hack for performance: if restype is a "simple" primitive type, don't
# allocate the buffer because it's going to be thrown away immediately
- if self._is_primitive(restype) and not restype._is_pointer_like():
+ if (self._is_primitive(restype) and restype._type_ != '?'
+ and not restype._is_pointer_like()):
return result
#
shape = restype._ffishape_
diff --git a/lib_pypy/cffi/backend_ctypes.py b/lib_pypy/cffi/backend_ctypes.py
--- a/lib_pypy/cffi/backend_ctypes.py
+++ b/lib_pypy/cffi/backend_ctypes.py
@@ -112,11 +112,20 @@
def _make_cmp(name):
cmpfunc = getattr(operator, name)
def cmp(self, other):
- if isinstance(other, CTypesData):
+ v_is_ptr = not isinstance(self, CTypesGenericPrimitive)
+ w_is_ptr = (isinstance(other, CTypesData) and
+ not isinstance(other, CTypesGenericPrimitive))
+ if v_is_ptr and w_is_ptr:
return cmpfunc(self._convert_to_address(None),
other._convert_to_address(None))
+ elif v_is_ptr or w_is_ptr:
+ return NotImplemented
else:
- return NotImplemented
+ if isinstance(self, CTypesGenericPrimitive):
+ self = self._value
+ if isinstance(other, CTypesGenericPrimitive):
+ other = other._value
+ return cmpfunc(self, other)
cmp.func_name = name
return cmp
@@ -128,7 +137,7 @@
__ge__ = _make_cmp('__ge__')
def __hash__(self):
- return hash(type(self)) ^ hash(self._convert_to_address(None))
+ return hash(self._convert_to_address(None))
def _to_string(self, maxlen):
raise TypeError("string(): %r" % (self,))
@@ -137,14 +146,8 @@
class CTypesGenericPrimitive(CTypesData):
__slots__ = []
- def __eq__(self, other):
- return self is other
-
- def __ne__(self, other):
- return self is not other
-
def __hash__(self):
- return object.__hash__(self)
+ return hash(self._value)
def _get_own_repr(self):
return repr(self._from_ctypes(self._value))
diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -99,27 +99,39 @@
raise oefmt(space.w_TypeError,
"cdata of type '%s' has no len()", self.ctype.name)
+ def _compare_mode(self, w_other):
+ from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitive
+ zero = rffi.cast(lltype.Unsigned, 0)
+ self_is_ptr = not isinstance(self.ctype, W_CTypePrimitive)
+ other_is_ptr = (isinstance(w_other, W_CData) and
+ not isinstance(w_other.ctype, W_CTypePrimitive))
+ if other_is_ptr and self_is_ptr:
+ with self as ptr1, w_other as ptr2:
+ ptr1 = rffi.cast(lltype.Unsigned, ptr1)
+ ptr2 = rffi.cast(lltype.Unsigned, ptr2)
+ return (0, ptr1, ptr2, None, None)
+ elif other_is_ptr or self_is_ptr:
+ return (-1, zero, zero, None, None)
+ else:
+ w_ob1 = self.convert_to_object()
+ if isinstance(w_other, W_CData):
+ w_ob2 = w_other.convert_to_object()
+ else:
+ w_ob2 = w_other
+ return (1, zero, zero, w_ob1, w_ob2)
+
def _make_comparison(name):
op = getattr(operator, name)
- requires_ordering = name not in ('eq', 'ne')
#
def _cmp(self, w_other):
- from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitive
space = self.space
- if not isinstance(w_other, W_CData):
+ mode, adr1, adr2, w_ob1, w_ob2 = self._compare_mode(w_other)
+ if mode == 0:
+ return space.newbool(op(adr1, adr2))
+ elif mode == 1:
+ return getattr(space, name)(w_ob1, w_ob2)
+ else:
return space.w_NotImplemented
-
- with self as ptr1, w_other as ptr2:
- if requires_ordering:
- if (isinstance(self.ctype, W_CTypePrimitive) or
- isinstance(w_other.ctype, W_CTypePrimitive)):
- raise oefmt(space.w_TypeError,
- "cannot do comparison on a primitive "
- "cdata")
- ptr1 = rffi.cast(lltype.Unsigned, ptr1)
- ptr2 = rffi.cast(lltype.Unsigned, ptr2)
- result = op(ptr1, ptr2)
- return space.newbool(result)
#
return func_with_new_name(_cmp, name)
@@ -131,6 +143,11 @@
ge = _make_comparison('ge')
def hash(self):
+ from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitive
+ if isinstance(self.ctype, W_CTypePrimitive):
+ w_ob = self.convert_to_object()
+ if not isinstance(w_ob, W_CData):
+ return self.space.hash(w_ob)
ptr = self.unsafe_escaping_ptr()
h = rffi.cast(lltype.Signed, ptr)
# To hash pointers in dictionaries. Assumes that h shows some
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
@@ -16,6 +16,7 @@
.replace(r'\\U', r'\U'))
u = U()
str2bytes = str
+ strict_compare = False
else:
type_or_class = "class"
long = int
@@ -27,6 +28,7 @@
bitem2bchr = bytechr
u = ""
str2bytes = lambda s: bytes(s, "ascii")
+ strict_compare = True
def size_of_int():
BInt = new_primitive_type("int")
@@ -95,11 +97,11 @@
x = cast(p, -66 + (1<<199)*256)
assert repr(x) == "<cdata 'signed char' -66>"
assert int(x) == -66
- assert (x == cast(p, -66)) is False
- assert (x != cast(p, -66)) is True
+ assert (x == cast(p, -66)) is True
+ assert (x != cast(p, -66)) is False
q = new_primitive_type("short")
- assert (x == cast(q, -66)) is False
- assert (x != cast(q, -66)) is True
+ assert (x == cast(q, -66)) is True
+ assert (x != cast(q, -66)) is False
def test_sizeof_type():
py.test.raises(TypeError, sizeof, 42.5)
@@ -164,7 +166,7 @@
assert float(cast(p, 1.1)) != 1.1 # rounding error
assert float(cast(p, 1E200)) == INF # limited range
- assert cast(p, -1.1) != cast(p, -1.1)
+ assert cast(p, -1.1) == cast(p, -1.1)
assert repr(float(cast(p, -0.0))) == '-0.0'
assert float(cast(p, b'\x09')) == 9.0
assert float(cast(p, u+'\x09')) == 9.0
@@ -208,7 +210,7 @@
p = new_primitive_type("char")
assert bool(cast(p, 'A')) is True
assert bool(cast(p, '\x00')) is False # since 1.7
- assert cast(p, '\x00') != cast(p, -17*256)
+ assert cast(p, '\x00') == cast(p, -17*256)
assert int(cast(p, 'A')) == 65
assert long(cast(p, 'A')) == 65
assert type(int(cast(p, 'A'))) is int
@@ -371,23 +373,6 @@
# that it is already loaded too, so it should work
assert x.load_function(BVoidP, 'sqrt')
-def test_hash_differences():
- BChar = new_primitive_type("char")
- BInt = new_primitive_type("int")
- BFloat = new_primitive_type("float")
- for i in range(1, 20):
- x1 = cast(BChar, chr(i))
- x2 = cast(BInt, i)
- if hash(x1) != hash(x2):
- break
- else:
- raise AssertionError("hashes are equal")
- for i in range(1, 20):
- if hash(cast(BFloat, i)) != hash(float(i)):
- break
- else:
- raise AssertionError("hashes are equal")
-
def test_no_len_on_nonarray():
p = new_primitive_type("int")
py.test.raises(TypeError, len, cast(p, 42))
@@ -2250,12 +2235,17 @@
BVoidP = new_pointer_type(new_void_type())
p = newp(BIntP, 123)
q = cast(BInt, 124)
- py.test.raises(TypeError, "p < q")
- py.test.raises(TypeError, "p <= q")
assert (p == q) is False
assert (p != q) is True
- py.test.raises(TypeError, "p > q")
- py.test.raises(TypeError, "p >= q")
+ assert (q == p) is False
+ assert (q != p) is True
+ if strict_compare:
+ py.test.raises(TypeError, "p < q")
+ py.test.raises(TypeError, "p <= q")
+ py.test.raises(TypeError, "q < p")
+ py.test.raises(TypeError, "q <= p")
+ py.test.raises(TypeError, "p > q")
+ py.test.raises(TypeError, "p >= q")
r = cast(BVoidP, p)
assert (p < r) is False
assert (p <= r) is True
@@ -3829,3 +3819,86 @@
assert len(w) == 2
# check that the warnings are associated with lines in this file
assert w[1].lineno == w[0].lineno + 4
+
+def test_primitive_comparison():
+ def assert_eq(a, b):
+ assert (a == b) is True
+ assert (b == a) is True
+ assert (a != b) is False
+ assert (b != a) is False
+ assert (a < b) is False
+ assert (a <= b) is True
+ assert (a > b) is False
+ assert (a >= b) is True
+ assert (b < a) is False
+ assert (b <= a) is True
+ assert (b > a) is False
+ assert (b >= a) is True
+ assert hash(a) == hash(b)
+ def assert_lt(a, b):
+ assert (a == b) is False
+ assert (b == a) is False
+ assert (a != b) is True
+ assert (b != a) is True
+ assert (a < b) is True
+ assert (a <= b) is True
+ assert (a > b) is False
+ assert (a >= b) is False
+ assert (b < a) is False
+ assert (b <= a) is False
+ assert (b > a) is True
+ assert (b >= a) is True
+ assert hash(a) != hash(b) # (or at least, it is unlikely)
+ def assert_gt(a, b):
+ assert_lt(b, a)
+ def assert_ne(a, b):
+ assert (a == b) is False
+ assert (b == a) is False
+ assert (a != b) is True
+ assert (b != a) is True
+ if strict_compare:
+ py.test.raises(TypeError, "a < b")
+ py.test.raises(TypeError, "a <= b")
+ py.test.raises(TypeError, "a > b")
+ py.test.raises(TypeError, "a >= b")
+ py.test.raises(TypeError, "b < a")
+ py.test.raises(TypeError, "b <= a")
+ py.test.raises(TypeError, "b > a")
+ py.test.raises(TypeError, "b >= a")
+ elif a < b:
+ assert_lt(a, b)
+ else:
+ assert_lt(b, a)
+ assert_eq(5, 5)
+ assert_lt(3, 5)
+ assert_ne('5', 5)
+ #
+ t1 = new_primitive_type("char")
+ t2 = new_primitive_type("int")
+ t3 = new_primitive_type("unsigned char")
+ t4 = new_primitive_type("unsigned int")
+ t5 = new_primitive_type("float")
+ t6 = new_primitive_type("double")
+ assert_eq(cast(t1, 65), b'A')
+ assert_lt(cast(t1, 64), b'\x99')
+ assert_gt(cast(t1, 200), b'A')
+ assert_ne(cast(t1, 65), 65)
+ assert_eq(cast(t2, -25), -25)
+ assert_lt(cast(t2, -25), -24)
+ assert_gt(cast(t2, -25), -26)
+ assert_eq(cast(t3, 65), 65)
+ assert_ne(cast(t3, 65), b'A')
+ assert_ne(cast(t3, 65), cast(t1, 65))
+ assert_gt(cast(t4, -1), -1)
+ assert_gt(cast(t4, -1), cast(t2, -1))
+ assert_gt(cast(t4, -1), 99999)
+ assert_eq(cast(t4, -1), 256 ** size_of_int() - 1)
+ assert_eq(cast(t5, 3.0), 3)
+ assert_eq(cast(t5, 3.5), 3.5)
+ assert_lt(cast(t5, 3.3), 3.3) # imperfect rounding
+ assert_eq(cast(t6, 3.3), 3.3)
+ assert_eq(cast(t5, 3.5), cast(t6, 3.5))
+ assert_lt(cast(t5, 3.1), cast(t6, 3.1)) # imperfect rounding
+ assert_eq(cast(t5, 7.0), cast(t3, 7))
+ assert_lt(cast(t5, 3.1), 3.101)
+ assert_gt(cast(t5, 3.1), 3)
diff --git a/pypy/module/cpyext/test/test_userslots.py b/pypy/module/cpyext/test/test_userslots.py
--- a/pypy/module/cpyext/test/test_userslots.py
+++ b/pypy/module/cpyext/test/test_userslots.py
@@ -39,12 +39,12 @@
arg = space.newtuple([one, one, one])
# call w_date.__new__
w_obj = space.call_function(w_date, one, one, one)
- w_year = space.getattr(w_obj, space.newbytes('year'))
+ w_year = space.getattr(w_obj, space.newtext('year'))
assert space.int_w(w_year) == 1
w_obj = generic_cpy_call(space, py_datetype.c_tp_new, py_datetype,
arg, space.newdict({}))
- w_year = space.getattr(w_obj, space.newbytes('year'))
+ w_year = space.getattr(w_obj, space.newtext('year'))
assert space.int_w(w_year) == 1
class AppTestUserSlots(AppTestCpythonExtensionBase):
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
@@ -55,7 +55,8 @@
min = int(min)
max = int(max)
p = ffi.cast(c_decl, min)
- assert p != min # no __eq__(int)
+ assert p == min
+ assert hash(p) == hash(min)
assert bool(p) is bool(min)
assert int(p) == min
p = ffi.cast(c_decl, max)
@@ -66,9 +67,9 @@
assert ffi.typeof(q) is ffi.typeof(p) and int(q) == max
q = ffi.cast(c_decl, long(min - 1))
assert ffi.typeof(q) is ffi.typeof(p) and int(q) == max
- assert q != p
+ assert q == p
assert int(q) == int(p)
- assert hash(q) != hash(p) # unlikely
+ assert hash(q) == hash(p)
c_decl_ptr = '%s *' % c_decl
py.test.raises(OverflowError, ffi.new, c_decl_ptr, min - 1)
py.test.raises(OverflowError, ffi.new, c_decl_ptr, max + 1)
@@ -883,9 +884,9 @@
assert ffi.string(ffi.cast("enum bar", -2)) == "B1"
assert ffi.string(ffi.cast("enum bar", -1)) == "CC1"
assert ffi.string(ffi.cast("enum bar", 1)) == "E1"
- assert ffi.cast("enum bar", -2) != ffi.cast("enum bar", -2)
- assert ffi.cast("enum foo", 0) != ffi.cast("enum bar", 0)
- assert ffi.cast("enum bar", 0) != ffi.cast("int", 0)
+ assert ffi.cast("enum bar", -2) == ffi.cast("enum bar", -2)
+ assert ffi.cast("enum foo", 0) == ffi.cast("enum bar", 0)
+ assert ffi.cast("enum bar", 0) == ffi.cast("int", 0)
assert repr(ffi.cast("enum bar", -1)) == "<cdata 'enum bar' -1: CC1>"
assert repr(ffi.cast("enum foo", -1)) == ( # enums are unsigned, if
"<cdata 'enum foo' 4294967295>") # they contain no neg value
@@ -1114,15 +1115,15 @@
assert (q == None) is False
assert (q != None) is True
- def test_no_integer_comparison(self):
+ def test_integer_comparison(self):
ffi = FFI(backend=self.Backend())
x = ffi.cast("int", 123)
y = ffi.cast("int", 456)
- py.test.raises(TypeError, "x < y")
+ assert x < y
#
z = ffi.cast("double", 78.9)
- py.test.raises(TypeError, "x < z")
- py.test.raises(TypeError, "z < y")
+ assert x > z
+ assert y > z
def test_ffi_buffer_ptr(self):
ffi = FFI(backend=self.Backend())
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py
@@ -138,7 +138,7 @@
min = int(min)
max = int(max)
p = ffi.cast(c_decl, min)
- assert p != min # no __eq__(int)
+ assert p == min
assert bool(p) is bool(min)
assert int(p) == min
p = ffi.cast(c_decl, max)
@@ -149,9 +149,9 @@
assert ffi.typeof(q) is ffi.typeof(p) and int(q) == max
q = ffi.cast(c_decl, long(min - 1))
assert ffi.typeof(q) is ffi.typeof(p) and int(q) == max
- assert q != p
+ assert q == p
assert int(q) == int(p)
- assert hash(q) != hash(p) # unlikely
+ assert hash(q) == hash(p)
c_decl_ptr = '%s *' % c_decl
py.test.raises(OverflowError, ffi.new, c_decl_ptr, min - 1)
py.test.raises(OverflowError, ffi.new, c_decl_ptr, max + 1)
@@ -897,9 +897,9 @@
assert ffi.string(ffi.cast("enum bar", -2)) == "B1"
assert ffi.string(ffi.cast("enum bar", -1)) == "CC1"
assert ffi.string(ffi.cast("enum bar", 1)) == "E1"
- assert ffi.cast("enum bar", -2) != ffi.cast("enum bar", -2)
- assert ffi.cast("enum foq", 0) != ffi.cast("enum bar", 0)
- assert ffi.cast("enum bar", 0) != ffi.cast("int", 0)
+ assert ffi.cast("enum bar", -2) == ffi.cast("enum bar", -2)
+ assert ffi.cast("enum foq", 0) == ffi.cast("enum bar", 0)
+ assert ffi.cast("enum bar", 0) == ffi.cast("int", 0)
assert repr(ffi.cast("enum bar", -1)) == "<cdata 'enum bar' -1: CC1>"
assert repr(ffi.cast("enum foq", -1)) == ( # enums are unsigned, if
"<cdata 'enum foq' 4294967295>") or ( # they contain no neg value
@@ -1106,14 +1106,14 @@
assert (q == None) is False
assert (q != None) is True
- def test_no_integer_comparison(self):
+ def test_integer_comparison(self):
x = ffi.cast("int", 123)
y = ffi.cast("int", 456)
- py.test.raises(TypeError, "x < y")
+ assert x < y
#
z = ffi.cast("double", 78.9)
- py.test.raises(TypeError, "x < z")
- py.test.raises(TypeError, "z < y")
+ assert x > z
+ assert y > z
def test_ffi_buffer_ptr(self):
a = ffi.new("short *", 100)
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py b/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_functions.py
@@ -99,6 +99,15 @@
result = f(0, 0, 0, 0, 0, 0)
assert result == b'\x00'
+ def test_boolresult(self):
+ f = dll._testfunc_i_bhilfd
+ f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
+ f.restype = c_bool
+ false_result = f(0, 0, 0, 0, 0, 0)
+ assert false_result is False
+ true_result = f(1, 0, 0, 0, 0, 0)
+ assert true_result is True
+
def test_voidresult(self):
f = dll._testfunc_v
f.restype = None
More information about the pypy-commit
mailing list