[pypy-svn] r74529 - in pypy/trunk/pypy/module/cpyext: . test

afa at codespeak.net afa at codespeak.net
Mon May 17 16:35:34 CEST 2010


Author: afa
Date: Mon May 17 16:35:32 2010
New Revision: 74529

Modified:
   pypy/trunk/pypy/module/cpyext/object.py
   pypy/trunk/pypy/module/cpyext/stubs.py
   pypy/trunk/pypy/module/cpyext/test/test_bufferobject.py
   pypy/trunk/pypy/module/cpyext/test/test_stringobject.py
Log:
PyObject_AsCharBuffer, implemented only for strings and PyBuffer objects


Modified: pypy/trunk/pypy/module/cpyext/object.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/object.py	(original)
+++ pypy/trunk/pypy/module/cpyext/object.py	Mon May 17 16:35:32 2010
@@ -1,7 +1,8 @@
 from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import cpython_api, generic_cpy_call, CANNOT_FAIL,\
-        Py_ssize_t, PyVarObject, Py_TPFLAGS_HEAPTYPE,\
-        Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, Py_GE, CONST_STRING
+from pypy.module.cpyext.api import (
+    cpython_api, generic_cpy_call, CANNOT_FAIL, Py_ssize_t, Py_ssize_tP,
+    PyVarObject, Py_TPFLAGS_HEAPTYPE, Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT,
+    Py_GE, CONST_STRING)
 from pypy.module.cpyext.pyobject import (
     PyObject, PyObjectP, create_ref, from_ref, Py_IncRef, Py_DecRef,
     track_reference)
@@ -341,3 +342,29 @@
     Compute and return the hash value of an object o.  On failure, return -1.
     This is the equivalent of the Python expression hash(o)."""
     return space.int_w(space.hash(w_obj))
+
+ at cpython_api([PyObject, rffi.CCHARPP, Py_ssize_tP], rffi.INT_real, error=-1)
+def PyObject_AsCharBuffer(space, obj, bufferp, sizep):
+    """Returns a pointer to a read-only memory location usable as
+    character-based input.  The obj argument must support the single-segment
+    character buffer interface.  On success, returns 0, sets buffer to the
+    memory location and size to the buffer length.  Returns -1 and sets a
+    TypeError on error.
+    """
+    pto = obj.c_ob_type
+
+    pb = pto.c_tp_as_buffer
+    if not (pb and pb.c_bf_getreadbuffer and pb.c_bf_getsegcount):
+        raise OperationError(space.w_TypeError, space.wrap(
+            "expected a character buffer object"))
+    if generic_cpy_call(space, pb.c_bf_getsegcount,
+                        obj, lltype.nullptr(rffi.INTP.TO)) != 1:
+        raise OperationError(space.w_TypeError, space.wrap(
+            "expected a single-segment buffer object"))
+    size = generic_cpy_call(space, pb.c_bf_getreadbuffer,
+                            obj, 0, bufferp)
+    if size < 0:
+        return -1
+    sizep[0] = size
+    return 0
+

Modified: pypy/trunk/pypy/module/cpyext/stubs.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/stubs.py	(original)
+++ pypy/trunk/pypy/module/cpyext/stubs.py	Mon May 17 16:35:32 2010
@@ -2373,20 +2373,6 @@
     """
     raise NotImplementedError
 
- at cpython_api([PyObject, rffi.CCHARPP, Py_ssize_t], rffi.INT_real, error=-1)
-def PyObject_AsCharBuffer(space, obj, buffer, buffer_len):
-    """Returns a pointer to a read-only memory location usable as character-based
-    input.  The obj argument must support the single-segment character buffer
-    interface.  On success, returns 0, sets buffer to the memory location
-    and buffer_len to the buffer length.  Returns -1 and sets a
-    TypeError on error.
-    
-    
-    
-    This function used an int * type for buffer_len. This might
-    require changes in your code for properly supporting 64-bit systems."""
-    raise NotImplementedError
-
 @cpython_api([PyObject, rffi.CCHARP], rffi.INT_real, error=-1)
 def PyObject_DelAttrString(space, o, attr_name):
     """Delete attribute named attr_name, for object o. Returns -1 on failure.

Modified: pypy/trunk/pypy/module/cpyext/test/test_bufferobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/test/test_bufferobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/test/test_bufferobject.py	Mon May 17 16:35:32 2010
@@ -20,10 +20,21 @@
              """
                  free(cbuf);
                  Py_RETURN_NONE;
+             """),
+            ("check_ascharbuffer", "METH_O",
+             """
+                 char *ptr;
+                 Py_ssize_t size;
+                 if (PyObject_AsCharBuffer(args, &ptr, &size) < 0)
+                     return NULL;
+                 return PyString_FromStringAndSize(ptr, size);
              """)
             ], prologue = """
             static char* cbuf = NULL;
             """)
-        buffer = module.get_FromMemory()
-        assert str(buffer) == 'abc\0'
+        buf = module.get_FromMemory()
+        assert str(buf) == 'abc\0'
+
+        assert module.check_ascharbuffer(buf) == 'abc\0'
+
         module.free_buffer()

Modified: pypy/trunk/pypy/module/cpyext/test/test_stringobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/test/test_stringobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/test/test_stringobject.py	Mon May 17 16:35:32 2010
@@ -2,7 +2,7 @@
 from pypy.module.cpyext.test.test_api import BaseApiTest
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 from pypy.module.cpyext.stringobject import new_empty_str, PyStringObject
-from pypy.module.cpyext.api import PyObjectP, PyObject
+from pypy.module.cpyext.api import PyObjectP, PyObject, Py_ssize_tP
 from pypy.module.cpyext.pyobject import Py_DecRef, from_ref, make_ref
 
 import py
@@ -234,3 +234,15 @@
     def test_format(self, space, api):
         assert "1 2" == space.unwrap(
             api.PyString_Format(space.wrap('%s %d'), space.wrap((1, 2))))
+
+    def test_asbuffer(self, space, api):
+        bufp = lltype.malloc(rffi.VOIDPP.TO, 1, flavor='raw')
+        lenp = lltype.malloc(Py_ssize_tP.TO, 1, flavor='raw')
+
+        w_text = space.wrap("text")
+        assert api.PyObject_AsCharBuffer(w_text, bufp, lenp) == 0
+        assert lenp[0] == 4
+        assert rffi.charp2str(bufp[0]) == 'text'
+
+        lltype.free(bufp, flavor='raw')
+        lltype.free(lenp, flavor='raw')



More information about the Pypy-commit mailing list