Author: Ronan Lamy <[email protected]>
Branch: py3.5
Changeset: r92312:965ce7010d54
Date: 2017-09-03 16:44 +0100
http://bitbucket.org/pypy/pypy/changeset/965ce7010d54/
Log: hg merge default
diff --git a/lib-python/2.7/ctypes/test/test_byteswap.py
b/lib-python/2.7/ctypes/test/test_byteswap.py
--- a/lib-python/2.7/ctypes/test/test_byteswap.py
+++ b/lib-python/2.7/ctypes/test/test_byteswap.py
@@ -23,7 +23,6 @@
setattr(bits, "i%s" % i, 1)
dump(bits)
- @xfail
def test_endian_short(self):
if sys.byteorder == "little":
self.assertIs(c_short.__ctype_le__, c_short)
@@ -51,7 +50,6 @@
self.assertEqual(bin(s), "3412")
self.assertEqual(s.value, 0x1234)
- @xfail
def test_endian_int(self):
if sys.byteorder == "little":
self.assertIs(c_int.__ctype_le__, c_int)
@@ -80,7 +78,6 @@
self.assertEqual(bin(s), "78563412")
self.assertEqual(s.value, 0x12345678)
- @xfail
def test_endian_longlong(self):
if sys.byteorder == "little":
self.assertIs(c_longlong.__ctype_le__, c_longlong)
@@ -109,7 +106,6 @@
self.assertEqual(bin(s), "EFCDAB9078563412")
self.assertEqual(s.value, 0x1234567890ABCDEF)
- @xfail
def test_endian_float(self):
if sys.byteorder == "little":
self.assertIs(c_float.__ctype_le__, c_float)
@@ -128,7 +124,6 @@
self.assertAlmostEqual(s.value, math.pi, 6)
self.assertEqual(bin(struct.pack(">f", math.pi)), bin(s))
- @xfail
def test_endian_double(self):
if sys.byteorder == "little":
self.assertIs(c_double.__ctype_le__, c_double)
@@ -156,7 +151,6 @@
self.assertIs(c_char.__ctype_le__, c_char)
self.assertIs(c_char.__ctype_be__, c_char)
- @xfail
def test_struct_fields_1(self):
if sys.byteorder == "little":
base = BigEndianStructure
@@ -192,7 +186,6 @@
pass
self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)])
- @xfail
def test_struct_struct(self):
# nested structures with different byteorders
@@ -221,7 +214,6 @@
self.assertEqual(s.point.x, 1)
self.assertEqual(s.point.y, 2)
- @xfail
def test_struct_fields_2(self):
# standard packing in struct uses no alignment.
# So, we have to align using pad bytes.
@@ -245,7 +237,6 @@
s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
self.assertEqual(bin(s1), bin(s2))
- @xfail
def test_unaligned_nonnative_struct_fields(self):
if sys.byteorder == "little":
base = BigEndianStructure
diff --git a/lib-python/2.7/ctypes/test/test_unaligned_structures.py
b/lib-python/2.7/ctypes/test/test_unaligned_structures.py
--- a/lib-python/2.7/ctypes/test/test_unaligned_structures.py
+++ b/lib-python/2.7/ctypes/test/test_unaligned_structures.py
@@ -37,10 +37,7 @@
for typ in byteswapped_structures:
## print >> sys.stderr, typ.value
self.assertEqual(typ.value.offset, 1)
- try:
- o = typ()
- except NotImplementedError as e:
- self.skipTest(str(e)) # for PyPy
+ o = typ()
o.value = 4
self.assertEqual(o.value, 4)
diff --git a/lib_pypy/_ctypes/pointer.py b/lib_pypy/_ctypes/pointer.py
--- a/lib_pypy/_ctypes/pointer.py
+++ b/lib_pypy/_ctypes/pointer.py
@@ -141,6 +141,10 @@
ptr._buffer = tp._ffiarray(1, autofree=True)
ptr._buffer[0] = obj._buffer
result = ptr
+ elif isinstance(obj, bytes):
+ result = tp()
+ result._buffer[0] = buffer(obj)._pypy_raw_address()
+ return result
elif not (isinstance(obj, _CData) and type(obj)._is_pointer_like()):
raise TypeError("cast() argument 1 must be a pointer, not %s"
% (type(obj),))
diff --git a/lib_pypy/_ctypes/primitive.py b/lib_pypy/_ctypes/primitive.py
--- a/lib_pypy/_ctypes/primitive.py
+++ b/lib_pypy/_ctypes/primitive.py
@@ -61,6 +61,54 @@
pyobj_container = GlobalPyobjContainer()
+def swap_bytes(value, sizeof, typeof, get_or_set):
+ def swap_2():
+ return ((value >> 8) & 0x00FF) | ((value << 8) & 0xFF00)
+
+ def swap_4():
+ return ((value & 0x000000FF) << 24) | \
+ ((value & 0x0000FF00) << 8) | \
+ ((value & 0x00FF0000) >> 8) | \
+ ((value >> 24) & 0xFF)
+
+ def swap_8():
+ return ((value & 0x00000000000000FFL) << 56) | \
+ ((value & 0x000000000000FF00L) << 40) | \
+ ((value & 0x0000000000FF0000L) << 24) | \
+ ((value & 0x00000000FF000000L) << 8) | \
+ ((value & 0x000000FF00000000L) >> 8) | \
+ ((value & 0x0000FF0000000000L) >> 24) | \
+ ((value & 0x00FF000000000000L) >> 40) | \
+ ((value >> 56) & 0xFF)
+
+ def swap_double_float(typ):
+ from struct import pack, unpack
+ if get_or_set == 'set':
+ if sys.byteorder == 'little':
+ st = pack(''.join(['>', typ]), value)
+ else:
+ st = pack(''.join(['<', typ]), value)
+ return unpack(typ, st)[0]
+ else:
+ packed = pack(typ, value)
+ if sys.byteorder == 'little':
+ st = unpack(''.join(['>', typ]), packed)
+ else:
+ st = unpack(''.join(['<', typ]), packed)
+ return st[0]
+
+ if typeof in ('c_float', 'c_float_le', 'c_float_be'):
+ return swap_double_float('f')
+ elif typeof in ('c_double', 'c_double_le', 'c_double_be'):
+ return swap_double_float('d')
+ else:
+ if sizeof == 2:
+ return swap_2()
+ elif sizeof == 4:
+ return swap_4()
+ elif sizeof == 8:
+ return swap_8()
+
def generic_xxx_p_from_param(cls, value):
if value is None:
return cls(None)
@@ -265,6 +313,31 @@
def _as_ffi_pointer_(self, ffitype):
return as_ffi_pointer(self, ffitype)
result._as_ffi_pointer_ = _as_ffi_pointer_
+ if name[-2:] != '_p' and name[-3:] not in ('_le', '_be') \
+ and name not in ('c_wchar', '_SimpleCData', 'c_longdouble',
'c_bool', 'py_object'):
+ from sys import byteorder
+ if byteorder == 'big':
+ name += '_le'
+ swapped = self.__new__(self, name, bases, dct)
+ result.__ctype_le__ = swapped
+ result.__ctype_be__ = result
+ swapped.__ctype_be__ = result
+ swapped.__ctype_le__ = swapped
+ else:
+ name += '_be'
+ swapped = self.__new__(self, name, bases, dct)
+ result.__ctype_be__ = swapped
+ result.__ctype_le__ = result
+ swapped.__ctype_le__ = result
+ swapped.__ctype_be__ = swapped
+ from _ctypes import sizeof
+ def _getval(self):
+ return swap_bytes(self._buffer[0], sizeof(self), name, 'get')
+ def _setval(self, value):
+ d = result()
+ d.value = value
+ self._buffer[0] = swap_bytes(d.value, sizeof(self), name,
'set')
+ swapped.value = property(_getval, _setval)
return result
diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -146,6 +146,7 @@
obj._buffer.__setattr__(self.name, arg)
+
def _set_shape(tp, rawfields, is_union=False):
tp._ffistruct_ = _rawffi.Structure(rawfields, is_union,
getattr(tp, '_pack_', 0))
@@ -240,18 +241,26 @@
res.__dict__['_index'] = -1
return res
-
class StructOrUnion(_CData, metaclass=StructOrUnionMeta):
def __new__(cls, *args, **kwds):
from _ctypes import union
- self = super(_CData, cls).__new__(cls)
- if ('_abstract_' in cls.__dict__ or cls is Structure
+ if ('_abstract_' in cls.__dict__ or cls is Structure
or cls is union.Union):
raise TypeError("abstract class")
if hasattr(cls, '_swappedbytes_'):
- raise NotImplementedError("missing in PyPy: structure/union with "
- "swapped (non-native) byte ordering")
+ fields = [None] * len(cls._fields_)
+ for i in range(len(cls._fields_)):
+ if cls._fields_[i][1] ==
cls._fields_[i][1].__dict__.get('__ctype_be__', None):
+ swapped = cls._fields_[i][1].__dict__.get('__ctype_le__',
cls._fields_[i][1])
+ else:
+ swapped = cls._fields_[i][1].__dict__.get('__ctype_be__',
cls._fields_[i][1])
+ if len(cls._fields_[i]) < 3:
+ fields[i] = (cls._fields_[i][0], swapped)
+ else:
+ fields[i] = (cls._fields_[i][0], swapped,
cls._fields_[i][2])
+ names_and_fields(cls, fields, _CData,
cls.__dict__.get('_anonymous_', None))
+ self = super(_CData, cls).__new__(cls)
if hasattr(cls, '_ffistruct_'):
self.__dict__['_buffer'] = self._ffistruct_(autofree=True)
return self
diff --git a/pypy/doc/build.rst b/pypy/doc/build.rst
--- a/pypy/doc/build.rst
+++ b/pypy/doc/build.rst
@@ -119,8 +119,15 @@
To run untranslated tests, you need the Boehm garbage collector libgc.
-On Debian and Ubuntu, this is the command to install all build-time
-dependencies::
+On recent Debian and Ubuntu (like 17.04), this is the command to install
+all build-time dependencies::
+
+ apt-get install gcc make libffi-dev pkg-config zlib1g-dev libbz2-dev \
+ libsqlite3-dev libncurses5-dev libexpat1-dev libssl-dev libgdbm-dev \
+ tk-dev libgc-dev python-cffi \
+ liblzma-dev libncursesw5-dev # these two only needed on PyPy3
+
+On older Debian and Ubuntu (12.04 to 16.04)::
apt-get install gcc make libffi-dev pkg-config libz-dev libbz2-dev \
libsqlite3-dev libncurses-dev libexpat1-dev libssl-dev libgdbm-dev \
diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst
--- a/pypy/doc/cpython_differences.rst
+++ b/pypy/doc/cpython_differences.rst
@@ -548,6 +548,11 @@
or ``float`` subtypes. Currently PyPy does not support the
``__class__`` attribute assignment for any non heaptype subtype.
+* In PyPy, module and class dictionaries are optimized under the assumption
+ that deleting attributes from them are rare. Because of this, e.g.
+ ``del foo.bar`` where ``foo`` is a module (or class) that contains the
+ function ``bar``, is significantly slower than CPython.
+
.. _`is ignored in PyPy`: http://bugs.python.org/issue14621
.. _`little point`:
http://events.ccc.de/congress/2012/Fahrplan/events/5152.en.html
.. _`#2072`: https://bitbucket.org/pypy/pypy/issue/2072/
diff --git a/pypy/module/cpyext/test/test_eval.py
b/pypy/module/cpyext/test/test_eval.py
--- a/pypy/module/cpyext/test/test_eval.py
+++ b/pypy/module/cpyext/test/test_eval.py
@@ -366,3 +366,56 @@
)
excinfo = raises(RecursionError, module.call_recursive)
assert 'while calling recurse' in str(excinfo.value)
+
+ def test_build_class(self):
+ # make sure PyObject_Call generates a proper PyTypeObject,
+ # along the way verify that userslot has iter and next
+ module = self.import_extension('foo', [
+ ("object_call", "METH_O",
+ '''
+ return PyObject_Call((PyObject*)&PyType_Type, args, NULL);
+ '''),
+ ('iter', "METH_O",
+ '''
+ if (NULL == args->ob_type->tp_iter)
+ {
+ PyErr_SetString(PyExc_TypeError, "NULL tp_iter");
+ return NULL;
+ }
+ return args->ob_type->tp_iter(args);
+ '''),
+ ('next', "METH_O",
+ '''
+ if (NULL == args->ob_type->tp_iternext)
+ {
+ PyErr_SetString(PyExc_TypeError, "NULL tp_iternext");
+ return NULL;
+ }
+ return args->ob_type->tp_iternext(args);
+ '''),])
+ def __init__(self, N):
+ self.N = N
+ self.i = 0
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ if self.i < self.N:
+ i = self.i
+ self.i += 1
+ return i
+ raise StopIteration
+
+ d = {'__init__': __init__, '__iter__': __iter__, 'next': __next__,
+ '__next__': __next__}
+ C = module.object_call(('Iterable', (object,), d))
+ c = C(5)
+ i = module.iter(c)
+ out = []
+ try:
+ while 1:
+ out.append(module.next(i))
+ except StopIteration:
+ pass
+ assert out == [0, 1, 2, 3, 4]
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -311,13 +311,18 @@
setattr(pto, slot_names[0], slot_func_helper)
elif ((w_type is space.w_list or w_type is space.w_tuple) and
slot_names[0] == 'c_tp_as_number'):
- # XXX hack - hwo can we generalize this? The problem is method
+ # XXX hack - how can we generalize this? The problem is method
# names like __mul__ map to more than one slot, and we have no
# convenient way to indicate which slots CPython have filled
#
# We need at least this special case since Numpy checks that
# (list, tuple) do __not__ fill tp_as_number
pass
+ elif ((space.issubtype_w(w_type, space.w_bytes) or
+ space.issubtype_w(w_type, space.w_unicode)) and
+ slot_names[0] == 'c_tp_as_number'):
+ # like above but for any str type
+ pass
else:
assert len(slot_names) == 2
struct = getattr(pto, slot_names[0])
diff --git a/pypy/module/cpyext/userslot.py b/pypy/module/cpyext/userslot.py
--- a/pypy/module/cpyext/userslot.py
+++ b/pypy/module/cpyext/userslot.py
@@ -122,3 +122,11 @@
else:
space.delete(w_self, w_obj)
return 0
+
+@slot_function([PyObject], PyObject)
+def slot_tp_iter(space, w_self):
+ return space.iter(w_self)
+
+@slot_function([PyObject], PyObject)
+def slot_tp_iternext(space, w_self):
+ return space.next(w_self)
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
b/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
@@ -22,7 +22,6 @@
assert X._fields_ == [("a", c_int)]
assert Y._fields_ == [("b", c_int)]
assert Z._fields_ == [("a", c_int)]
-
assert Y._names_ == ['a', 'b']
def test_subclass_delayed(self):
@@ -455,6 +454,39 @@
p = pointer(obj)
assert p.contents._b_base_ is p
+ def test_swapped_bytes(self):
+ import sys
+
+ for i in [c_short, c_int, c_long, c_longlong,
+ c_float, c_double, c_ushort, c_uint,
+ c_ulong, c_ulonglong]:
+ FIELDS = [
+ ('n', i)
+ ]
+
+ class Native(Structure):
+ _fields_ = FIELDS
+
+ class Big(BigEndianStructure):
+ _fields_ = FIELDS
+
+ class Little(LittleEndianStructure):
+ _fields_ = FIELDS
+
+ def dostruct(c):
+ ba = create_string_buffer(sizeof(c))
+ ms = c.from_buffer(ba)
+ ms.n = 0xff00
+ return repr(ba[:])
+
+ if sys.byteorder == 'little':
+ assert dostruct(Native) == dostruct(Little)
+ assert dostruct(Native) != dostruct(Big)
+ else:
+ assert dostruct(Native) == dostruct(Big)
+ assert dostruct(Native) != dostruct(Little)
+
+
class TestPointerMember(BaseCTypesTestChecker):
def test_1(self):
# a Structure with a POINTER field
diff --git a/pypy/objspace/std/sliceobject.py b/pypy/objspace/std/sliceobject.py
--- a/pypy/objspace/std/sliceobject.py
+++ b/pypy/objspace/std/sliceobject.py
@@ -132,6 +132,18 @@
else:
return space.w_False
+ def descr_ne(self, space, w_other):
+ if space.is_w(self, w_other):
+ return space.w_False
+ if not isinstance(w_other, W_SliceObject):
+ return space.w_NotImplemented
+ if space.eq_w(self.w_start, w_other.w_start) and \
+ space.eq_w(self.w_stop, w_other.w_stop) and \
+ space.eq_w(self.w_step, w_other.w_step):
+ return space.w_False
+ else:
+ return space.w_True
+
def descr_lt(self, space, w_other):
if space.is_w(self, w_other):
return space.w_False # see comments in descr_eq()
@@ -179,6 +191,7 @@
__reduce__ = gateway.interp2app(W_SliceObject.descr__reduce__),
__eq__ = gateway.interp2app(W_SliceObject.descr_eq),
+ __ne__ = gateway.interp2app(W_SliceObject.descr_ne),
__lt__ = gateway.interp2app(W_SliceObject.descr_lt),
start = slicewprop('w_start'),
diff --git a/pypy/objspace/std/test/test_sliceobject.py
b/pypy/objspace/std/test/test_sliceobject.py
--- a/pypy/objspace/std/test/test_sliceobject.py
+++ b/pypy/objspace/std/test/test_sliceobject.py
@@ -94,6 +94,7 @@
slice1 = slice(1, 2, 3)
slice2 = slice(1, 2, 3)
assert slice1 == slice2
+ assert not slice1 != slice2
slice2 = slice(1, 2)
assert slice1 != slice2
diff --git a/rpython/flowspace/test/test_objspace.py
b/rpython/flowspace/test/test_objspace.py
--- a/rpython/flowspace/test/test_objspace.py
+++ b/rpython/flowspace/test/test_objspace.py
@@ -839,15 +839,15 @@
return x[s]
graph = self.codetest(myfunc)
+ @py.test.mark.xfail
def test_unichr_constfold(self):
- py.test.skip("not working")
def myfunc():
return unichr(1234)
graph = self.codetest(myfunc)
assert graph.startblock.exits[0].target is graph.returnblock
+ @py.test.mark.xfail
def test_unicode_constfold(self):
- py.test.skip("not working for now")
def myfunc():
return unicode("1234")
graph = self.codetest(myfunc)
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py
b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -10,7 +10,7 @@
from rpython.jit.metainterp.optimizeopt.info import INFO_NONNULL, INFO_NULL
from rpython.jit.metainterp.optimizeopt.util import _findall,
make_dispatcher_method
from rpython.jit.metainterp.resoperation import rop, ResOperation, opclasses,\
- OpHelpers
+ OpHelpers, AbstractResOp
from rpython.rlib.rarithmetic import highest_bit
from rpython.rtyper.lltypesystem import llmemory
from rpython.rtyper import rclass
@@ -490,6 +490,11 @@
def postprocess_GUARD_TRUE(self, op):
box = self.get_box_replacement(op.getarg(0))
+ if (isinstance(box, AbstractResOp) and
+ box.getopnum() == rop.INT_IS_TRUE):
+ # we can't use the (current) range analysis for this because
+ # "anything but 0" is not a valid range
+ self.pure_from_args(rop.INT_IS_ZERO, [box.getarg(0)], CONST_0)
self.make_constant(box, CONST_1)
def optimize_GUARD_FALSE(self, op):
@@ -497,6 +502,11 @@
def postprocess_GUARD_FALSE(self, op):
box = self.get_box_replacement(op.getarg(0))
+ if (isinstance(box, AbstractResOp) and
+ box.getopnum() == rop.INT_IS_ZERO):
+ # we can't use the (current) range analysis for this because
+ # "anything but 0" is not a valid range
+ self.pure_from_args(rop.INT_IS_TRUE, [box.getarg(0)], CONST_1)
self.make_constant(box, CONST_0)
def optimize_ASSERT_NOT_NONE(self, op):
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -288,7 +288,6 @@
self.optimize_loop(ops, expected)
def test_int_is_true_is_zero(self):
- py.test.skip("XXX implement me")
ops = """
[i0]
i1 = int_is_true(i0)
@@ -305,6 +304,22 @@
"""
self.optimize_loop(ops, expected)
+ ops = """
+ [i0]
+ i2 = int_is_zero(i0)
+ guard_false(i2) []
+ i1 = int_is_true(i0)
+ guard_true(i1) []
+ jump(i0)
+ """
+ expected = """
+ [i0]
+ i2 = int_is_zero(i0)
+ guard_false(i2) []
+ jump(i0)
+ """
+ self.optimize_loop(ops, expected)
+
def test_int_is_zero_int_is_true(self):
ops = """
[i0]
diff --git a/rpython/jit/metainterp/resoperation.py
b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -400,7 +400,7 @@
return rop.can_raise(self.getopnum())
def is_foldable_guard(self):
- return rop.is_foldable_guard(self.getopnun())
+ return rop.is_foldable_guard(self.getopnum())
def is_primitive_array_access(self):
""" Indicates that this operations loads/stores a
diff --git a/rpython/jit/metainterp/test/test_bridgeopt.py
b/rpython/jit/metainterp/test/test_bridgeopt.py
--- a/rpython/jit/metainterp/test/test_bridgeopt.py
+++ b/rpython/jit/metainterp/test/test_bridgeopt.py
@@ -76,8 +76,11 @@
box_strategy = strategies.builds(InputArgInt) | strategies.builds(InputArgRef)
-tuples = strategies.tuples(box_strategy, strategies.booleans()).filter(
- lambda (box, known_class): isinstance(box, InputArgRef) or not
known_class)
+def _make_tup(box, known_class):
+ if isinstance(box, InputArgInt):
+ known_class = False
+ return box, known_class
+tuples = strategies.builds(_make_tup, box_strategy, strategies.booleans())
boxes_known_classes = strategies.lists(tuples, min_size=1)
@given(boxes_known_classes)
diff --git a/rpython/translator/sandbox/rsandbox.py
b/rpython/translator/sandbox/rsandbox.py
--- a/rpython/translator/sandbox/rsandbox.py
+++ b/rpython/translator/sandbox/rsandbox.py
@@ -27,17 +27,20 @@
ll_read_not_sandboxed = rposix.external('read',
[rffi.INT, rffi.CCHARP, rffi.SIZE_T],
rffi.SIZE_T,
- sandboxsafe=True)
+ sandboxsafe=True,
+ _nowrapper=True)
ll_write_not_sandboxed = rposix.external('write',
[rffi.INT, rffi.CCHARP, rffi.SIZE_T],
rffi.SIZE_T,
- sandboxsafe=True)
+ sandboxsafe=True,
+ _nowrapper=True)
@signature(types.int(), types.ptr(rffi.CCHARP.TO), types.int(),
returns=types.none())
def writeall_not_sandboxed(fd, buf, length):
+ fd = rffi.cast(rffi.INT, fd)
while length > 0:
size = rffi.cast(rffi.SIZE_T, length)
count = rffi.cast(lltype.Signed, ll_write_not_sandboxed(fd, buf, size))
@@ -58,7 +61,8 @@
buflen = self.buflen
with lltype.scoped_alloc(rffi.CCHARP.TO, buflen) as buf:
buflen = rffi.cast(rffi.SIZE_T, buflen)
- count = ll_read_not_sandboxed(self.fd, buf, buflen)
+ fd = rffi.cast(rffi.INT, self.fd)
+ count = ll_read_not_sandboxed(fd, buf, buflen)
count = rffi.cast(lltype.Signed, count)
if count <= 0:
raise IOError
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit