[pypy-commit] pypy cpyext-old-buffers: Have strings and buffers use the PyPy buffer protocol to generate getcharbuffer.

devin.jeanpierre pypy.commits at gmail.com
Mon May 16 16:58:54 EDT 2016


Author: Devin Jeanpierre <jeanpierreda at gmail.com>
Branch: cpyext-old-buffers
Changeset: r84492:406aceba870b
Date: 2016-05-13 15:01 -0700
http://bitbucket.org/pypy/pypy/changeset/406aceba870b/

Log:	Have strings and buffers use the PyPy buffer protocol to generate
	getcharbuffer.

	I'm not sure why these would ever be different functions. I couldn't
	find any examples in the Python stdlib.

	Note that I couldn't use space.charbuf_w because that always copies
	the buffer. I don't know why it does that. Doesn't that defeat the
	point?

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
@@ -443,15 +443,14 @@
 
 @cpython_api([PyObject, Py_ssize_tP], lltype.Signed, header=None,
              error=CANNOT_FAIL)
-def str_segcount(space, w_obj, ref):
+def bf_segcount(space, w_obj, ref):
     if ref:
         ref[0] = space.len_w(w_obj)
     return 1
 
 @cpython_api([PyObject, Py_ssize_t, rffi.VOIDPP], lltype.Signed,
              header=None, error=-1)
-def str_getreadbuffer(space, w_buf, segment, ref):
-    from pypy.module.cpyext.bytesobject import PyString_AsString
+def bf_getreadbuffer(space, w_buf, segment, ref):
     if segment != 0:
         raise oefmt(space.w_SystemError,
                     "accessing non-existent string segment")
@@ -459,7 +458,8 @@
     try:
         address = buf.get_raw_address()
     except ValueError:
-        # convert to a string and leak some memory. :(
+        from pypy.module.cpyext.bytesobject import PyString_AsString
+        # convert to a string and maybe leak some memory. :(
         w_str = space.wrap(buf.as_str())
         py_str = make_ref(space, w_str)
         ref[0] = PyString_AsString(space, py_str)
@@ -475,52 +475,33 @@
         ref[0] = address
         return len(buf)
 
- at cpython_api([PyObject, Py_ssize_t, rffi.CCHARPP], lltype.Signed,
-             header=None, error=-1)
-def str_getcharbuffer(space, w_str, segment, ref):
-    from pypy.module.cpyext.bytesobject import PyString_AsString
-    if segment != 0:
-        raise oefmt(space.w_SystemError,
-                    "accessing non-existent string segment")
-    pyref = make_ref(space, w_str)
-    ref[0] = PyString_AsString(space, pyref)
-    # Stolen reference: the object has better exist somewhere else
-    Py_DecRef(space, pyref)
-    return space.len_w(w_str)
 
 @cpython_api([PyObject, Py_ssize_t, rffi.CCHARPP], lltype.Signed,
              header=None, error=-1)
-def buf_getcharbuffer(space, pyref, segment, ref):
-    from pypy.module.cpyext.bufferobject import PyBufferObject
-    if segment != 0:
-        raise oefmt(space.w_SystemError,
-                    "accessing non-existent string segment")
-    py_buf = rffi.cast(PyBufferObject, pyref)
-    ref[0] = rffi.cast(rffi.CCHARP, py_buf.c_b_ptr)
-    #Py_DecRef(space, pyref)
-    return py_buf.c_b_size
+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):
     c_buf = lltype.malloc(PyBufferProcs, flavor='raw', zero=True)
     lltype.render_immortal(c_buf)
-    c_buf.c_bf_getsegcount = llhelper(str_segcount.api_func.functype,
-                                      str_segcount.api_func.get_wrapper(space))
-    c_buf.c_bf_getreadbuffer = llhelper(str_getreadbuffer.api_func.functype,
-                                 str_getreadbuffer.api_func.get_wrapper(space))
-    c_buf.c_bf_getcharbuffer = llhelper(str_getcharbuffer.api_func.functype,
-                                 str_getcharbuffer.api_func.get_wrapper(space))
+    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
     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(str_segcount.api_func.functype,
-                                      str_segcount.api_func.get_wrapper(space))
-    c_buf.c_bf_getreadbuffer = llhelper(str_getreadbuffer.api_func.functype,
-                                 str_getreadbuffer.api_func.get_wrapper(space))
-    c_buf.c_bf_getcharbuffer = llhelper(buf_getcharbuffer.api_func.functype,
-                                 buf_getcharbuffer.api_func.get_wrapper(space))
+    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)


More information about the pypy-commit mailing list