[pypy-commit] pypy cpyext-old-buffers: Make the buffer protocol something anyone can opt into, not just str/buffer.
devin.jeanpierre
pypy.commits at gmail.com
Mon May 16 16:58:57 EDT 2016
Author: Devin Jeanpierre <jeanpierreda at gmail.com>
Branch: cpyext-old-buffers
Changeset: r84494:de3b021f7d37
Date: 2016-05-16 13:57 -0700
http://bitbucket.org/pypy/pypy/changeset/de3b021f7d37/
Log: Make the buffer protocol something anyone can opt into, not just
str/buffer.
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -12,7 +12,8 @@
class TypeDef(object):
- def __init__(self, __name, __base=None, __total_ordering__=None, **rawdict):
+ def __init__(self, __name, __base=None, __total_ordering__=None,
+ __buffer=None, **rawdict):
"NOT_RPYTHON: initialization-time only"
self.name = __name
if __base is None:
@@ -22,6 +23,8 @@
else:
bases = [__base]
self.bases = bases
+ assert __buffer in {None, 'read-write', 'read'}, "Unknown value for __buffer"
+ self.buffer = __buffer
self.heaptype = False
self.hasdict = '__dict__' in rawdict
# no __del__: use an RPython _finalize_() method and register_finalizer
diff --git a/pypy/module/cpyext/test/test_abstract.py b/pypy/module/cpyext/test/test_abstract.py
--- a/pypy/module/cpyext/test/test_abstract.py
+++ b/pypy/module/cpyext/test/test_abstract.py
@@ -70,3 +70,12 @@
assert s == buffer_support.readbuffer_as_string(mm)
assert s == buffer_support.writebuffer_as_string(mm)
assert s == buffer_support.charbuffer_as_string(mm)
+
+ def test_nonbuffer(self):
+ # e.g. int
+ buffer_support = self.get_buffer_support()
+
+ assert not buffer_support.check_readbuffer(42)
+ assert raises(TypeError, buffer_support.readbuffer_as_string, 42)
+ assert raises(TypeError, buffer_support.writebuffer_as_string, 42)
+ assert raises(TypeError, buffer_support.charbuffer_as_string, 42)
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
@@ -475,13 +475,16 @@
ref[0] = address
return len(buf)
-
@cpython_api([PyObject, Py_ssize_t, rffi.CCHARPP], lltype.Signed,
header=None, error=-1)
def bf_getcharbuffer(space, w_buf, segment, ref):
return bf_getreadbuffer(space, w_buf, segment, rffi.cast(rffi.VOIDPP, ref))
-def setup_string_buffer_procs(space, pto):
+def setup_buffer_procs(space, w_type, pto):
+ bufspec = w_type.layout.typedef.buffer
+ if bufspec is None:
+ # not a buffer
+ return
c_buf = lltype.malloc(PyBufferProcs, flavor='raw', zero=True)
lltype.render_immortal(c_buf)
c_buf.c_bf_getsegcount = llhelper(bf_segcount.api_func.functype,
@@ -490,20 +493,11 @@
bf_getreadbuffer.api_func.get_wrapper(space))
c_buf.c_bf_getcharbuffer = llhelper(bf_getcharbuffer.api_func.functype,
bf_getcharbuffer.api_func.get_wrapper(space))
+ if bufspec == 'read-write':
+ pass # TODO: write buffer here.
pto.c_tp_as_buffer = c_buf
pto.c_tp_flags |= Py_TPFLAGS_HAVE_GETCHARBUFFER
-def setup_buffer_buffer_procs(space, pto):
- c_buf = lltype.malloc(PyBufferProcs, flavor='raw', zero=True)
- lltype.render_immortal(c_buf)
- c_buf.c_bf_getsegcount = llhelper(bf_segcount.api_func.functype,
- bf_segcount.api_func.get_wrapper(space))
- c_buf.c_bf_getreadbuffer = llhelper(bf_getreadbuffer.api_func.functype,
- bf_getreadbuffer.api_func.get_wrapper(space))
- c_buf.c_bf_getcharbuffer = llhelper(bf_getcharbuffer.api_func.functype,
- bf_getcharbuffer.api_func.get_wrapper(space))
- pto.c_tp_as_buffer = c_buf
-
@cpython_api([PyObject], lltype.Void, header=None)
def type_dealloc(space, obj):
from pypy.module.cpyext.object import PyObject_dealloc
@@ -567,10 +561,7 @@
subtype_dealloc.api_func.functype,
subtype_dealloc.api_func.get_wrapper(space))
# buffer protocol
- if space.is_w(w_type, space.w_str):
- setup_string_buffer_procs(space, pto)
- if space.is_w(w_type, space.w_buffer):
- setup_buffer_buffer_procs(space, pto)
+ setup_buffer_procs(space, w_type, pto)
pto.c_tp_free = llhelper(PyObject_Free.api_func.functype,
PyObject_Free.api_func.get_wrapper(space))
diff --git a/pypy/objspace/std/bufferobject.py b/pypy/objspace/std/bufferobject.py
--- a/pypy/objspace/std/bufferobject.py
+++ b/pypy/objspace/std/bufferobject.py
@@ -135,7 +135,7 @@
return space.wrap(rffi.cast(lltype.Signed, ptr))
W_Buffer.typedef = TypeDef(
- "buffer",
+ "buffer", None, None, "read-write",
__doc__ = """\
buffer(object [, offset[, size]])
diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py
--- a/pypy/objspace/std/bytesobject.py
+++ b/pypy/objspace/std/bytesobject.py
@@ -848,7 +848,7 @@
W_BytesObject.typedef = TypeDef(
- "str", basestring_typedef,
+ "str", basestring_typedef, None, "read",
__new__ = interp2app(W_BytesObject.descr_new),
__doc__ = """str(object='') -> string
More information about the pypy-commit
mailing list