[pypy-svn] pypy pyarg-parsebuffer: Very basic, incomplete implementation of some Py_buffer APIs

exarkun commits-noreply at bitbucket.org
Mon Apr 18 18:47:32 CEST 2011


Author: Jean-Paul Calderone <exarkun at twistedmatrix.com>
Branch: pyarg-parsebuffer
Changeset: r43456:db5434774665
Date: 2011-04-18 12:46 -0400
http://bitbucket.org/pypy/pypy/changeset/db5434774665/

Log:	Very basic, incomplete implementation of some Py_buffer APIs

diff --git a/pypy/module/cpyext/include/object.h b/pypy/module/cpyext/include/object.h
--- a/pypy/module/cpyext/include/object.h
+++ b/pypy/module/cpyext/include/object.h
@@ -16,9 +16,6 @@
 */
 #define staticforward static
 
-typedef void* Py_buffer;
-
-
 #define PyObject_HEAD  \
     long ob_refcnt;       \
     struct _typeobject *ob_type;
@@ -130,6 +127,25 @@
 typedef int (*visitproc)(PyObject *, void *);
 typedef int (*traverseproc)(PyObject *, visitproc, void *);
 
+/* Py3k buffer interface */
+typedef struct bufferinfo {
+    void *buf;
+    PyObject *obj;        /* owned reference */
+    Py_ssize_t len;
+    Py_ssize_t itemsize;  /* This is Py_ssize_t so it can be
+                             pointed to by strides in simple case.*/
+    int readonly;
+    int ndim;
+    char *format;
+    Py_ssize_t *shape;
+    Py_ssize_t *strides;
+    Py_ssize_t *suboffsets;
+    Py_ssize_t smalltable[2];  /* static store for shape and strides of
+                                  mono-dimensional buffers. */
+    void *internal;
+} Py_buffer;
+
+
 typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
 typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
 

diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -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, Py_ssize_tP,
-    PyVarObject, Py_TPFLAGS_HEAPTYPE, Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT,
+    PyVarObject, Py_buffer,
+    Py_TPFLAGS_HEAPTYPE, Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT,
     Py_GE, CONST_STRING, FILEP, fwrite, build_type_checkers)
 from pypy.module.cpyext.pyobject import (
     PyObject, PyObjectP, create_ref, from_ref, Py_IncRef, Py_DecRef,
@@ -466,3 +467,15 @@
     w_filename = space.wrap(rffi.charp2str(filename))
     w_mode = space.wrap(rffi.charp2str(mode))
     return space.call_method(space.builtin, 'file', w_filename, w_mode)
+
+
+ at cpython_api([lltype.Ptr(Py_buffer), PyObject, rffi.VOIDP, Py_ssize_t,
+              lltype.Signed, lltype.Signed], rffi.INT, error=CANNOT_FAIL)
+def PyBuffer_FillInfo(space, view, obj, buf, length, readonly, flags):
+    view.c_buf = buf
+    view.c_len = length
+
+
+ at cpython_api([lltype.Ptr(Py_buffer)], lltype.Void, error=CANNOT_FAIL)
+def PyBuffer_Release(space, view):
+    pass

diff --git a/pypy/module/cpyext/src/getargs.c b/pypy/module/cpyext/src/getargs.c
--- a/pypy/module/cpyext/src/getargs.c
+++ b/pypy/module/cpyext/src/getargs.c
@@ -135,13 +135,11 @@
 	PyMem_FREE(ptr);
 }
 
-#if 0
 static void
 cleanup_buffer(void *ptr)
 {
 	PyBuffer_Release((Py_buffer *) ptr);
 }
-#endif
 
 static int
 addcleanup(void *ptr, PyObject **freelist, void (*destr)(void *))
@@ -775,16 +773,22 @@
 		break;
 	}
 	case 's': {/* string */
+            printf("Hello, string\n");
 		if (*format == '*') {
-      Py_FatalError("* format unsupported for strings in PyArg_*\n");
-#if 0
+                    printf("hello, buffer\n");
 			Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
 
 			if (PyString_Check(arg)) {
 				PyBuffer_FillInfo(p, arg,
 						  PyString_AS_STRING(arg), PyString_GET_SIZE(arg),
 						  1, 0);
-			}
+			} else {
+                            PyErr_SetString(
+                                PyExc_NotImplementedError,
+                                "s* not implemented for non-string values");
+                            return NULL;
+                        }
+#if 0
 #ifdef Py_USING_UNICODE
 			else if (PyUnicode_Check(arg)) {
 				uarg = UNICODE_DEFAULT_ENCODING(arg);
@@ -801,13 +805,13 @@
 				if (getbuffer(arg, p, &buf) < 0)
 					return converterr(buf, arg, msgbuf, bufsize);
 			}
+#endif
 			if (addcleanup(p, freelist, cleanup_buffer)) {
 				return converterr(
 					"(cleanup problem)",
 					arg, msgbuf, bufsize);
 			}
 			format++;
-#endif
 		} else if (*format == '#') {
 			void **p = (void **)va_arg(*p_va, char **);
 			FETCH_SIZE;
@@ -1616,7 +1620,7 @@
 			int match = 0;
 			char *ks;
 			if (!PyString_Check(key)) {
-				PyErr_SetString(PyExc_TypeError, 
+                            PyErr_SetString(PyExc_TypeError, 
 					        "keywords must be strings");
 				return cleanreturn(0, freelist);
 			}

diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -415,6 +415,23 @@
 PyVarObjectStruct = cpython_struct("PyVarObject", PyVarObjectFields)
 PyVarObject = lltype.Ptr(PyVarObjectStruct)
 
+Py_buffer = cpython_struct(
+    "Py_buffer", (
+        ('buf', rffi.VOIDP),
+        # ('obj', PyObject),
+        ('len', Py_ssize_t),
+        # ('itemsize', Py_ssize_t),
+
+        # ('readonly', lltype.Signed),
+        # ('ndim', lltype.Signed),
+        # ('format', rffi.CCHARP),
+        # ('shape', Py_ssize_tP),
+        # ('strides', Py_ssize_tP),
+        # ('suboffets', Py_ssize_tP),
+        # ('smalltable', rffi.CFixedArray(Py_ssize_t, 2)),
+        # ('internal', rffi.VOIDP)
+        ))
+
 @specialize.memo()
 def is_PyObject(TYPE):
     if not isinstance(TYPE, lltype.Ptr):


More information about the Pypy-commit mailing list