Author: Ronan Lamy <[email protected]>
Branch: py3.5
Changeset: r91682:a5510f559b24
Date: 2017-07-04 20:24 +0100
http://bitbucket.org/pypy/pypy/changeset/a5510f559b24/
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,158 @@
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, PyBUF_SIMPLE)
-from pypy.module.cpyext.pyobject import PyObject, incref, Py_DecRef
+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
+
+ # cf. Objects/memoryobject.c:init_shape_strides()
+ if ndim == 0:
+ self.shape = []
+ self.strides = []
+ elif ndim == 1:
+ if shape is None:
+ self.shape = [size // itemsize]
+ else:
+ self.shape = shape
+ if strides is None:
+ self.strides = [itemsize]
+ else:
+ self.strides = strides
+ else:
+ assert len(shape) == ndim
+ self.shape = shape
+ # XXX: missing init_strides_from_shape
+ 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):
@@ -32,7 +180,7 @@
if pb.c_bf_releasebuffer:
generic_cpy_call(space, pb.c_bf_releasebuffer,
obj, view)
- Py_DecRef(space, view.c_obj)
+ decref(space, view.c_obj)
return 0
def fill_buffer(space, view, pybuf, py_obj):
@@ -71,7 +219,6 @@
share a contiguous chunk of memory of "unsigned bytes" of the given
length. Returns 0 on success and -1 (with raising an error) on error.
"""
- flags = rffi.cast(lltype.Signed, flags)
if flags & PyBUF_WRITABLE and readonly:
raise oefmt(space.w_ValueError, "Object is not writable")
view.c_buf = buf
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
@@ -6,11 +6,11 @@
get_typedescr, track_reference)
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.rlib.rarithmetic import widen
-from pypy.interpreter.error import oefmt
from pypy.module.cpyext.api import PyBUF_WRITE
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*')
@@ -55,7 +55,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)
@@ -169,7 +168,6 @@
(fort is 'A'). Return 0 otherwise."""
# traverse the strides, checking for consistent stride increases from
# right-to-left (c) or left-to-right (fortran). Copied from cpython
-
if view.c_suboffsets:
return 0
if (fort == 'C'):
@@ -193,7 +191,6 @@
PyBUF_READ or PyBUF_WRITE. view->format is set to "B" (unsigned bytes).
The memoryview has complete buffer information.
"""
- from pypy.module.cpyext.slotdefs import CPyBuffer
readonly = int(widen(flags) == PyBUF_WRITE)
view = CPyBuffer(space, cts.cast('void*', mem), size, None,
readonly=readonly)
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_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,
- getbufferproc, releasebufferproc, ssizessizeobjargproc)
-from pypy.module.cpyext.pyobject import make_ref, decref, as_pyobj, from_ref
+ 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
@@ -315,151 +312,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
-
- # cf. Objects/memoryobject.c:init_shape_strides()
- if ndim == 0:
- self.shape = []
- self.strides = []
- elif ndim == 1:
- if shape is None:
- self.shape = [size // itemsize]
- else:
- self.shape = shape
- if strides is None:
- self.strides = [itemsize]
- else:
- self.strides = strides
- else:
- assert len(shape) == ndim
- self.shape = shape
- # XXX: missing init_strides_from_shape
- 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