[pypy-commit] pypy PyBuffer-backport: Backport cpyext changes
rlamy
pypy.commits at gmail.com
Mon May 8 11:51:16 EDT 2017
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: PyBuffer-backport
Changeset: r91202:302a031b3560
Date: 2017-05-08 16:50 +0100
http://bitbucket.org/pypy/pypy/changeset/302a031b3560/
Log: Backport cpyext changes
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -221,7 +221,8 @@
if w_impl is not None:
w_result = space.get_and_call_function(w_impl, self,
space.newint(flags))
- if space.isinstance_w(w_result, space.w_buffer):
+ if (space.isinstance_w(w_result, space.w_buffer) or
+ space.isinstance_w(w_result, space.w_memoryview)):
return w_result.buffer_w(space, flags)
raise BufferInterfaceNotFound
@@ -233,7 +234,8 @@
if w_impl is not None:
w_result = space.get_and_call_function(w_impl, self,
space.newint(space.BUF_FULL_RO))
- if space.isinstance_w(w_result, space.w_buffer):
+ if (space.isinstance_w(w_result, space.w_buffer) or
+ space.isinstance_w(w_result, space.w_memoryview)):
return w_result.readbuf_w(space)
raise BufferInterfaceNotFound
@@ -245,7 +247,8 @@
if w_impl is not None:
w_result = space.get_and_call_function(w_impl, self,
space.newint(space.BUF_FULL))
- if space.isinstance_w(w_result, space.w_buffer):
+ if (space.isinstance_w(w_result, space.w_buffer) or
+ space.isinstance_w(w_result, space.w_memoryview)):
return w_result.writebuf_w(space)
raise BufferInterfaceNotFound
@@ -254,7 +257,8 @@
if w_impl is not None:
w_result = space.get_and_call_function(w_impl, self,
space.newint(space.BUF_FULL_RO))
- if space.isinstance_w(w_result, space.w_buffer):
+ if (space.isinstance_w(w_result, space.w_buffer) or
+ space.isinstance_w(w_result, space.w_memoryview)):
return w_result.charbuf_w(space)
raise BufferInterfaceNotFound
diff --git a/pypy/module/cpyext/memoryobject.py b/pypy/module/cpyext/memoryobject.py
--- a/pypy/module/cpyext/memoryobject.py
+++ b/pypy/module/cpyext/memoryobject.py
@@ -41,15 +41,15 @@
assert isinstance(w_obj, W_MemoryView)
py_obj = rffi.cast(PyMemoryViewObject, py_obj)
view = py_obj.c_view
- ndim = w_obj.buf.getndim()
+ ndim = w_obj.getndim()
if ndim >= Py_MAX_NDIMS:
# XXX warn?
return
- fill_Py_buffer(space, w_obj.buf, view)
+ fill_Py_buffer(space, w_obj.view, view)
try:
- view.c_buf = rffi.cast(rffi.VOIDP, w_obj.buf.get_raw_address())
+ view.c_buf = rffi.cast(rffi.VOIDP, w_obj.view.get_raw_address())
view.c_obj = make_ref(space, w_userdata)
- rffi.setintfield(view, 'c_readonly', w_obj.buf.readonly)
+ rffi.setintfield(view, 'c_readonly', w_obj.view.readonly)
except ValueError:
w_s = w_obj.descr_tobytes(space)
view.c_obj = make_ref(space, w_s)
@@ -95,7 +95,6 @@
mem_obj.c_view.c_obj = rffi.cast(PyObject, 0)
_dealloc(space, py_obj)
-
def fill_Py_buffer(space, buf, view):
# c_buf, c_obj have been filled in
ndim = buf.getndim()
diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py
--- a/pypy/module/cpyext/slotdefs.py
+++ b/pypy/module/cpyext/slotdefs.py
@@ -19,8 +19,10 @@
from pypy.module.cpyext.memoryobject import fill_Py_buffer
from pypy.module.cpyext.state import State
from pypy.module.cpyext import userslot
+from pypy.interpreter.buffer import BufferView
from pypy.interpreter.error import OperationError, oefmt
from pypy.interpreter.argument import Arguments
+
from rpython.rlib.buffer import Buffer
from rpython.rlib.unroll import unrolling_iterable
from rpython.rlib.objectmodel import specialize, not_rpython
@@ -322,7 +324,7 @@
space.fromcache(State).check_and_raise_exception(always=True)
return space.newint(res)
-class CPyBuffer(Buffer):
+class CPyBuffer(BufferView):
# Similar to Py_buffer
_immutable_ = True
@@ -333,9 +335,12 @@
self.space = space
self.ptr = ptr
self.size = size
- self.w_obj = w_obj # kept alive
+ self.w_obj = w_obj # kept alive
self.pyobj = as_pyobj(space, w_obj)
self.format = format
+ self.ndim = ndim
+ self.itemsize = itemsize
+
if not shape:
self.shape = [size]
else:
@@ -344,8 +349,6 @@
self.strides = [1]
else:
self.strides = strides
- self.ndim = ndim
- self.itemsize = itemsize
self.readonly = readonly
self.needs_decref = needs_decref
self.releasebufferproc = releasebufferproc
@@ -378,8 +381,20 @@
def getlength(self):
return self.size
- def getitem(self, index):
- return self.ptr[index]
+ def getbytes(self, start, size):
+ return ''.join([self.ptr[i] for i in range(start, start + size)])
+
+ def setbytes(self, start, string):
+ # absolutely no safety checks, what could go wrong?
+ for i in range(len(string)):
+ self.ptr[start + i] = string[i]
+
+ def as_readbuf(self):
+ return CBuffer(self)
+
+ def as_writebuf(self):
+ assert not self.readonly
+ return CBuffer(self)
def get_raw_address(self):
return rffi.cast(rffi.CCHARP, self.ptr)
@@ -399,10 +414,6 @@
def getndim(self):
return self.ndim
- def setitem(self, index, char):
- # absolutely no safety checks, what could go wrong?
- self.ptr[index] = char
-
class FQ(rgc.FinalizerQueue):
Class = CPyBuffer
def finalizer_trigger(self):
@@ -414,6 +425,37 @@
fq = FQ()
+
+class CBuffer(Buffer):
+ _immutable_ = True
+ def __init__(self, view):
+ self.view = view
+ self.readonly = view.readonly
+
+ def getlength(self):
+ return self.view.getlength()
+
+ def getitem(self, index):
+ return self.view.ptr[index]
+
+ def getslice(self, start, stop, step, size):
+ assert step == 1
+ assert stop - start == size
+ ptr = rffi.ptradd(cts.cast('char *', self.view.ptr), start)
+ return rffi.charpsize2str(ptr, size)
+
+ def setitem(self, index, char):
+ self.view.ptr[index] = char
+
+ def setslice(self, index, s):
+ assert s is not None
+ ptr = rffi.ptradd(cts.cast('char *', self.view.ptr), index)
+ rffi.str2chararray(s, ptr, len(s))
+
+ def get_raw_address(self):
+ return cts.cast('char *', self.view.ptr)
+
+
def wrap_getreadbuffer(space, w_self, w_args, func):
func_target = rffi.cast(readbufferproc, func)
py_obj = make_ref(space, w_self)
@@ -430,7 +472,7 @@
buf = CPyBuffer(space, ptr[0], size, w_self,
releasebufferproc=rbp)
fq.register_finalizer(buf)
- return space.newbuffer(buf)
+ return buf.wrap(space)
def wrap_getwritebuffer(space, w_self, w_args, func):
func_target = rffi.cast(readbufferproc, func)
@@ -448,7 +490,7 @@
buf = CPyBuffer(space, ptr[0], size, w_self, readonly=False,
releasebufferproc=rbp)
fq.register_finalizer(buf)
- return space.newbuffer(buf)
+ return buf.wrap(space)
def wrap_getbuffer(space, w_self, w_args, func):
func_target = rffi.cast(getbufferproc, func)
@@ -490,7 +532,7 @@
needs_decref=True,
releasebufferproc = rbp)
fq.register_finalizer(buf)
- return space.newbuffer(buf)
+ return buf.wrap(space)
def get_richcmp_func(OP_CONST):
def inner(space, w_self, w_args, func):
@@ -667,6 +709,7 @@
def slot_tp_getattro(space, w_self, w_name):
return space.call_function(getattr_fn, w_self, w_name)
slot_func = slot_tp_getattro
+
elif name == 'tp_call':
call_fn = w_type.getdictvalue(space, '__call__')
if call_fn is None:
@@ -744,24 +787,24 @@
@slot_function([PyObject, Py_bufferP, rffi.INT_real],
rffi.INT_real, error=-1)
@func_renamer("cpyext_%s_%s" % (name, typedef.name))
- def buff_w(space, w_self, view, flags):
+ def buff_w(space, w_self, c_view, flags):
args = Arguments(space, [space.newint(flags)])
w_obj = space.call_args(space.get(buff_fn, w_self), args)
- if view:
+ if c_view:
#like PyObject_GetBuffer
flags = widen(flags)
buf = space.buffer_w(w_obj, flags)
try:
- view.c_buf = rffi.cast(rffi.VOIDP, buf.get_raw_address())
- view.c_obj = make_ref(space, w_obj)
+ c_view.c_buf = rffi.cast(rffi.VOIDP, buf.get_raw_address())
+ c_view.c_obj = make_ref(space, w_obj)
except ValueError:
s = buf.as_str()
w_s = space.newbytes(s)
- view.c_obj = make_ref(space, w_s)
- view.c_buf = rffi.cast(rffi.VOIDP, rffi.str2charp(
+ c_view.c_obj = make_ref(space, w_s)
+ c_view.c_buf = rffi.cast(rffi.VOIDP, rffi.str2charp(
s, track_allocation=False))
- rffi.setintfield(view, 'c_readonly', 1)
- ret = fill_Py_buffer(space, buf, view)
+ rffi.setintfield(c_view, 'c_readonly', 1)
+ ret = fill_Py_buffer(space, buf, c_view)
return ret
return 0
return buff_w
@@ -771,23 +814,23 @@
@slot_function([PyObject, Py_bufferP, rffi.INT_real],
rffi.INT_real, error=-1)
@func_renamer("cpyext_%s_%s" % (name, typedef.name))
- def buff_w(space, w_self, view, flags):
+ def buff_w(space, w_self, c_view, flags):
w_obj = w_self
- if view:
+ if c_view:
#like PyObject_GetBuffer
flags = widen(flags)
buf = space.buffer_w(w_obj, flags)
try:
- view.c_buf = rffi.cast(rffi.VOIDP, buf.get_raw_address())
- view.c_obj = make_ref(space, w_obj)
+ c_view.c_buf = rffi.cast(rffi.VOIDP, buf.get_raw_address())
+ c_view.c_obj = make_ref(space, w_obj)
except ValueError:
s = buf.as_str()
w_s = space.newbytes(s)
- view.c_obj = make_ref(space, w_s)
- view.c_buf = rffi.cast(rffi.VOIDP, rffi.str2charp(
+ c_view.c_obj = make_ref(space, w_s)
+ c_view.c_buf = rffi.cast(rffi.VOIDP, rffi.str2charp(
s, track_allocation=False))
- rffi.setintfield(view, 'c_readonly', 1)
- ret = fill_Py_buffer(space, buf, view)
+ rffi.setintfield(c_view, 'c_readonly', 1)
+ ret = fill_Py_buffer(space, buf, c_view)
return ret
return 0
return buff_w
diff --git a/pypy/module/cpyext/test/buffer_test.c b/pypy/module/cpyext/test/buffer_test.c
--- a/pypy/module/cpyext/test/buffer_test.c
+++ b/pypy/module/cpyext/test/buffer_test.c
@@ -344,6 +344,7 @@
#endif
if (m == NULL)
INITERROR;
+ PyMyArrayType.tp_new = PyType_GenericNew;
if (PyType_Ready(&PyMyArrayType) < 0)
INITERROR;
Py_INCREF(&PyMyArrayType);
diff --git a/pypy/module/cpyext/test/test_memoryobject.py b/pypy/module/cpyext/test/test_memoryobject.py
--- a/pypy/module/cpyext/test/test_memoryobject.py
+++ b/pypy/module/cpyext/test/test_memoryobject.py
@@ -111,7 +111,7 @@
PyObject* obj = PyTuple_GetItem(args, 0);
PyObject* memoryview = PyMemoryView_FromObject(obj);
if (memoryview == NULL)
- return PyLong_FromLong(-1);
+ return NULL;
view = PyMemoryView_GET_BUFFER(memoryview);
Py_DECREF(memoryview);
return PyLong_FromLong(view->len / view->itemsize);
More information about the pypy-commit
mailing list