Author: Ronan Lamy <ronan.l...@gmail.com> Branch: Changeset: r91676:b22fbf59ad0f Date: 2017-07-04 18:18 +0100 http://bitbucket.org/pypy/pypy/changeset/b22fbf59ad0f/
Log: Move CPyBuffer and dependencies to buffer.py diff --git a/pypy/module/cpyext/buffer.py b/pypy/module/cpyext/buffer.py --- a/pypy/module/cpyext/buffer.py +++ b/pypy/module/cpyext/buffer.py @@ -1,10 +1,148 @@ from rpython.rtyper.lltypesystem import rffi, lltype +from rpython.rlib import rgc # Force registration of gc.collect +from rpython.rlib.buffer import RawBuffer from pypy.interpreter.error import oefmt +from pypy.interpreter.buffer import BufferView from pypy.module.cpyext.api import ( cpython_api, Py_buffer, Py_ssize_t, Py_ssize_tP, CONST_STRINGP, cts, generic_cpy_call, PyBUF_WRITABLE, PyBUF_FORMAT, PyBUF_ND, PyBUF_STRIDES) -from pypy.module.cpyext.pyobject import PyObject, incref +from pypy.module.cpyext.typeobjectdefs import releasebufferproc +from pypy.module.cpyext.pyobject import PyObject, incref, decref, as_pyobj + +class CBuffer(RawBuffer): + _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) + +class CPyBuffer(BufferView): + # Similar to Py_buffer + _immutable_ = True + + def __init__(self, space, ptr, size, w_obj, format='B', shape=None, + strides=None, ndim=1, itemsize=1, readonly=True, + needs_decref=False, + releasebufferproc=rffi.cast(rffi.VOIDP, 0)): + self.space = space + self.ptr = ptr + self.size = size + 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: + self.shape = shape + if not strides: + self.strides = [1] + else: + self.strides = strides + self.readonly = readonly + self.needs_decref = needs_decref + self.releasebufferproc = releasebufferproc + + def releasebuffer(self): + if self.pyobj: + if self.needs_decref: + if self.releasebufferproc: + func_target = rffi.cast(releasebufferproc, self.releasebufferproc) + with lltype.scoped_alloc(Py_buffer) as pybuf: + pybuf.c_buf = self.ptr + pybuf.c_len = self.size + pybuf.c_ndim = cts.cast('int', self.ndim) + pybuf.c_shape = cts.cast('Py_ssize_t*', pybuf.c__shape) + pybuf.c_strides = cts.cast('Py_ssize_t*', pybuf.c__strides) + for i in range(self.ndim): + pybuf.c_shape[i] = self.shape[i] + pybuf.c_strides[i] = self.strides[i] + if self.format: + pybuf.c_format = rffi.str2charp(self.format) + else: + pybuf.c_format = rffi.str2charp("B") + generic_cpy_call(self.space, func_target, self.pyobj, pybuf) + decref(self.space, self.pyobj) + self.pyobj = lltype.nullptr(PyObject.TO) + else: + #do not call twice + return + + def getlength(self): + return self.size + + 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_str(self): + return CBuffer(self).as_str() + + 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) + + def getformat(self): + return self.format + + def getshape(self): + return self.shape + + def getstrides(self): + return self.strides + + def getitemsize(self): + return self.itemsize + + def getndim(self): + return self.ndim + +class FQ(rgc.FinalizerQueue): + Class = CPyBuffer + def finalizer_trigger(self): + while 1: + buf = self.next_dead() + if not buf: + break + buf.releasebuffer() + +fq = FQ() + @cpython_api([PyObject, CONST_STRINGP, Py_ssize_tP], rffi.INT_real, error=-1) def PyObject_AsCharBuffer(space, obj, bufferp, sizep): 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 @@ -9,6 +9,7 @@ from pypy.objspace.std.memoryobject import W_MemoryView from pypy.module.cpyext.object import _dealloc from pypy.module.cpyext.import_ import PyImport_Import +from pypy.module.cpyext.buffer import CPyBuffer, fq cts.parse_header(parse_dir / 'cpyext_memoryobject.h') PyMemoryViewObject = cts.gettype('PyMemoryViewObject*') @@ -53,7 +54,6 @@ """ Creates the memory object in the interpreter """ - from pypy.module.cpyext.slotdefs import CPyBuffer, fq py_mem = rffi.cast(PyMemoryViewObject, obj) view = py_mem.c_view ndim = widen(view.c_ndim) 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 @@ -4,7 +4,6 @@ from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rlib.rarithmetic import widen -from rpython.rlib import rgc # Force registration of gc.collect from pypy.module.cpyext.api import ( slot_function, generic_cpy_call, PyObject, Py_ssize_t, Py_TPFLAGS_CHECKTYPES, Py_buffer, Py_bufferP, PyTypeObjectPtr, cts) @@ -13,22 +12,20 @@ getattrfunc, getattrofunc, setattrofunc, lenfunc, ssizeargfunc, inquiry, ssizessizeargfunc, ssizeobjargproc, iternextfunc, initproc, richcmpfunc, cmpfunc, hashfunc, descrgetfunc, descrsetfunc, objobjproc, objobjargproc, - readbufferproc, getbufferproc, releasebufferproc, ssizessizeobjargproc) -from pypy.module.cpyext.pyobject import make_ref, decref, as_pyobj, from_ref + readbufferproc, getbufferproc, ssizessizeobjargproc) +from pypy.module.cpyext.pyobject import make_ref, decref, from_ref from pypy.module.cpyext.pyerrors import PyErr_Occurred 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.module.cpyext.buffer import CBuffer, CPyBuffer, fq from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.argument import Arguments -from rpython.rlib.buffer import RawBuffer from rpython.rlib.unroll import unrolling_iterable from rpython.rlib.objectmodel import specialize, not_rpython from rpython.tool.sourcetools import func_renamer from rpython.flowspace.model import Constant from rpython.flowspace.specialcase import register_flow_sc -from rpython.rtyper.annlowlevel import llhelper from pypy.module.sys.version import CPYTHON_VERSION PY3 = CPYTHON_VERSION[0] == 3 @@ -324,141 +321,6 @@ space.fromcache(State).check_and_raise_exception(always=True) return space.newint(res) -class CPyBuffer(BufferView): - # Similar to Py_buffer - _immutable_ = True - - def __init__(self, space, ptr, size, w_obj, format='B', shape=None, - strides=None, ndim=1, itemsize=1, readonly=True, - needs_decref=False, - releasebufferproc=rffi.cast(rffi.VOIDP, 0)): - self.space = space - self.ptr = ptr - self.size = size - 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: - self.shape = shape - if not strides: - self.strides = [1] - else: - self.strides = strides - self.readonly = readonly - self.needs_decref = needs_decref - self.releasebufferproc = releasebufferproc - - def releasebuffer(self): - if self.pyobj: - if self.needs_decref: - if self.releasebufferproc: - func_target = rffi.cast(releasebufferproc, self.releasebufferproc) - with lltype.scoped_alloc(Py_buffer) as pybuf: - pybuf.c_buf = self.ptr - pybuf.c_len = self.size - pybuf.c_ndim = cts.cast('int', self.ndim) - pybuf.c_shape = cts.cast('Py_ssize_t*', pybuf.c__shape) - pybuf.c_strides = cts.cast('Py_ssize_t*', pybuf.c__strides) - for i in range(self.ndim): - pybuf.c_shape[i] = self.shape[i] - pybuf.c_strides[i] = self.strides[i] - if self.format: - pybuf.c_format = rffi.str2charp(self.format) - else: - pybuf.c_format = rffi.str2charp("B") - generic_cpy_call(self.space, func_target, self.pyobj, pybuf) - decref(self.space, self.pyobj) - self.pyobj = lltype.nullptr(PyObject.TO) - else: - #do not call twice - return - - def getlength(self): - return self.size - - 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_str(self): - return CBuffer(self).as_str() - - 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) - - def getformat(self): - return self.format - - def getshape(self): - return self.shape - - def getstrides(self): - return self.strides - - def getitemsize(self): - return self.itemsize - - def getndim(self): - return self.ndim - -class FQ(rgc.FinalizerQueue): - Class = CPyBuffer - def finalizer_trigger(self): - while 1: - buf = self.next_dead() - if not buf: - break - buf.releasebuffer() - -fq = FQ() - - -class CBuffer(RawBuffer): - _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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit