Author: Ronan Lamy <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit