[Python-3000-checkins] r56954 - in python/branches/py3k-buffer: Include/object.h Modules/arraymodule.c Objects/abstract.c Objects/bufferobject.c Objects/bytesobject.c Objects/memoryobject.c Objects/unicodeobject.c Python/getargs.c Python/marshal.c

travis.oliphant python-3000-checkins at python.org
Sun Aug 12 10:24:13 CEST 2007


Author: travis.oliphant
Date: Sun Aug 12 10:24:12 2007
New Revision: 56954

Modified:
   python/branches/py3k-buffer/Include/object.h
   python/branches/py3k-buffer/Modules/arraymodule.c
   python/branches/py3k-buffer/Objects/abstract.c
   python/branches/py3k-buffer/Objects/bufferobject.c
   python/branches/py3k-buffer/Objects/bytesobject.c
   python/branches/py3k-buffer/Objects/memoryobject.c
   python/branches/py3k-buffer/Objects/unicodeobject.c
   python/branches/py3k-buffer/Python/getargs.c
   python/branches/py3k-buffer/Python/marshal.c
Log:
Code compiles now.  Need to finish testing and fix up mmap and ctypes

Modified: python/branches/py3k-buffer/Include/object.h
==============================================================================
--- python/branches/py3k-buffer/Include/object.h	(original)
+++ python/branches/py3k-buffer/Include/object.h	Sun Aug 12 10:24:12 2007
@@ -146,12 +146,14 @@
 	void *buf;         
         Py_ssize_t len;
         int readonly;
+        Py_ssize_t itemsize;  /* This is Py_ssize_t so it can
+                                 be the strides array for the most
+                                 common case */
         char *format;
         int ndim;
         Py_ssize_t *shape;
         Py_ssize_t *strides;
         Py_ssize_t *suboffsets;
-        Py_ssize_t itemsize;
         void *internal;
 } PyBuffer;
 
@@ -160,14 +162,15 @@
 
         /* Flags for getting buffers */
 #define PyBUF_SIMPLE 0
-#define PyBUF_REQ_WRITEABLE 0x0001
-#define PyBUF_REQ_LOCKDATA 0x0002
-#define PyBUF_REQ_FORMAT 0x0004
-#define PyBUF_ALW_ND 0x0008
-#define PyBUF_ALW_STRIDES (0x0010 | PyBUF_ALW_ND)
-#define PyBUF_REQ_C_CONTIGUOUS (0x0020 | PyBUF_ALW_STRIDES)
-#define PyBUF_REQ_F_CONTIGUOUS (0x0040 | PyBUF_ALW_STRIDES)
-#define PyBUF_REQ_ANY_CONTIGUOUS (0x0080 | PyBUF_ALW_STRIDES)
+#define PyBUF_CHARACTER 1
+#define PyBUF_REQ_WRITEABLE 0x0002
+#define PyBUF_REQ_LOCKDATA 0x0004
+#define PyBUF_REQ_FORMAT 0x0008
+#define PyBUF_ALW_ND 0x0010
+#define PyBUF_ALW_STRIDES (0x0020 | PyBUF_ALW_ND)
+#define PyBUF_REQ_C_CONTIGUOUS (0x0040 | PyBUF_ALW_STRIDES)
+#define PyBUF_REQ_F_CONTIGUOUS (0x0080 | PyBUF_ALW_STRIDES)
+#define PyBUF_REQ_ANY_CONTIGUOUS (0x0100 | PyBUF_ALW_STRIDES)
 #define PyBUF_ALW_INDIRECT (0x0200 | PyBUF_ALW_STRIDES)
 
 #define PyBUF_CONTIG (PyBUF_ALW_ND | PyBUF_REQ_WRITEABLE)

Modified: python/branches/py3k-buffer/Modules/arraymodule.c
==============================================================================
--- python/branches/py3k-buffer/Modules/arraymodule.c	(original)
+++ python/branches/py3k-buffer/Modules/arraymodule.c	Sun Aug 12 10:24:12 2007
@@ -1420,7 +1420,7 @@
 
         if (!PyArg_ParseTuple(args, "u#:fromunicode", &ustr, &n))
 		return NULL;
-	if (self->ob_descr->typecode != PyARR_UNI) {
+	if (self->ob_descr->typecode != PyArr_UNI) {
 		PyErr_SetString(PyExc_ValueError,
 			"fromunicode() may only be called on "
 			"unicode type arrays");
@@ -1776,7 +1776,7 @@
         return 0;
 }
 
-static int
+static void
 array_buffer_relbuf(arrayobject *self, PyBuffer *view)
 {
         free(view->format);
@@ -1925,7 +1925,7 @@
     'H'         unsigned integer   2 \n\
     'i'         signed integer     2 \n\
     'I'         unsigned integer   2 \n\
-    'w'         unicode character  4
+    'w'         unicode character  4 \n\
     'l'         signed integer     4 \n\
     'L'         unsigned integer   4 \n\
     'f'         floating point     4 \n\

Modified: python/branches/py3k-buffer/Objects/abstract.c
==============================================================================
--- python/branches/py3k-buffer/Objects/abstract.c	(original)
+++ python/branches/py3k-buffer/Objects/abstract.c	Sun Aug 12 10:24:12 2007
@@ -215,6 +215,9 @@
 	return ret;
 }
 
+/* We release the buffer right after use of this function which could
+   cause issues later on.  Don't use these functions in new code. 
+ */
 int
 PyObject_AsCharBuffer(PyObject *obj,
                       const char **buffer,
@@ -233,13 +236,12 @@
 				"expected an object with the buffer interface");
 		return -1;
         }
-        if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE)) return -1;
+        if ((*pb->bf_getbuffer)(obj, &view, PyBUF_CHARACTER)) return -1;
 
 	*buffer = view.buf;
 	*buffer_len = view.len;
-        if (pb->bf_releasebuffer != NULL) {
+        if (pb->bf_releasebuffer != NULL)
                 (*pb->bf_releasebuffer)(obj, &view);
-        }
 	return 0;
 }
 
@@ -325,7 +327,7 @@
                                 "object does not have the buffer interface");
                 return -1;
         }
-         return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags);
+        return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags);
 }
 
 void
@@ -553,7 +555,6 @@
 int PyObject_CopyData(PyObject *dest, PyObject *src) 
 {
         PyBuffer view_dest, view_src;
-        getbufferproc func;
         int k;
         Py_ssize_t *indices, elements;
         char *dptr, *sptr;
@@ -566,11 +567,11 @@
                 return -1;
         }
 
-        func = Py_Type(dest)->tp_as_buffer->bf_getbuffer;        
         if (PyObject_GetBuffer(dest, &view_dest, PyBUF_FULL) != 0) return -1;
-
-        func = Py_Type(src)->tp_as_buffer->bf_getbuffer;
-        if (PyObject_GetBuffer(src, &view_src, PyBUF_FULL_RO) != 0) return -1;
+        if (PyObject_GetBuffer(src, &view_src, PyBUF_FULL_RO) != 0) {
+                PyObject_ReleaseBuffer(dest, &view_dest);
+                return -1;
+        }
 
         if (view_dest.len < view_src.len) {
                 PyErr_SetString(PyExc_BufferError, 
@@ -647,30 +648,36 @@
 PyBuffer_FillInfo(PyBuffer *view, void *buf, Py_ssize_t len,
               int readonly, int flags)
 {        
-        if ((flags & PyBUF_REQ_LOCKDATA) == PyBUF_REQ_LOCKDATA && 
+        if (view == NULL) return 0;
+        if (((flags & PyBUF_REQ_LOCKDATA) == PyBUF_REQ_LOCKDATA) && 
             readonly != -1) {
                 PyErr_SetString(PyExc_BufferError, 
                                 "Cannot make this object read-only.");
                 return -1;
         }
+        if (((flags & PyBUF_REQ_WRITEABLE) == PyBUF_REQ_WRITEABLE) &&
+            readonly == 1) {
+                PyErr_SetString(PyExc_BufferError,
+                                "Object is not writeable.");
+                return -1;
+        }
+        
         view->buf = buf;
         view->len = len;
         view->readonly = readonly;
+        view->itemsize = 1;
         view->format = NULL;
         if ((flags & PyBUF_REQ_FORMAT) == PyBUF_REQ_FORMAT) 
                 view->format = "B";
         view->ndim = 1;
+        view->shape = NULL;
         if ((flags & PyBUF_ALW_ND) == PyBUF_ALW_ND)
                 view->shape = &(view->len);
-        else
-                view->shape = NULL;
-        view->itemsize = 1;
+        view->strides = NULL;
         if ((flags & PyBUF_ALW_STRIDES) == PyBUF_ALW_STRIDES)
                 view->strides = &(view->itemsize);
-        else
-                view->strides = NULL;
         view->suboffsets = NULL;
-        view->internal = NULL;        
+        view->internal = NULL;
         return 0;
 }
 

Modified: python/branches/py3k-buffer/Objects/bufferobject.c
==============================================================================
--- python/branches/py3k-buffer/Objects/bufferobject.c	(original)
+++ python/branches/py3k-buffer/Objects/bufferobject.c	Sun Aug 12 10:24:12 2007
@@ -337,7 +337,7 @@
         if (!(view.readonly)) {
                 PyErr_SetString(PyExc_TypeError,
                                 "writable buffers are not hashable");
-                PyObject_ReleaseBuffer((PyObject *)self, &view);
+                PyObject_ReleaseBuffer(self->b_base, &view);
 		return -1;
 	}
                 
@@ -350,7 +350,7 @@
 	if (x == -1)
 		x = -2;
 	self->b_hash = x;
-        PyObject_ReleaseBuffer((PyObject *)self, &view);
+        PyObject_ReleaseBuffer(self->b_base, &view);
 	return x;
 }
 
@@ -363,7 +363,7 @@
 	if (!get_buf(self, &view))
 		return NULL;
 	res = PyString_FromStringAndSize((const char *)view.buf, view.len);
-        PyObject_ReleaseBuffer((PyObject *)self, &view);
+        PyObject_ReleaseBuffer(self->b_base, &view);
         return res;
 }
 
@@ -376,7 +376,7 @@
 
 	if (!get_buf(self, &view))
 		return -1;
-        PyObject_ReleaseBuffer((PyObject *)self, &view);
+        PyObject_ReleaseBuffer(self->b_base, &view);
 	return view.len;
 }
 
@@ -401,19 +401,19 @@
 	/* optimize special case */
         /* XXX bad idea type-wise */
 	if ( view.len == 0 ) {
-                PyObject_ReleaseBuffer((PyObject *)self, &view);
+                PyObject_ReleaseBuffer(self->b_base, &view);
                 Py_INCREF(other);
                 return other;
 	}
 
-        if (PyObject_GetBuffer((PyObject *)self, &view2, PyBUF_SIMPLE) < 0) {
-                PyObject_ReleaseBuffer((PyObject *)self, &view);
+        if (PyObject_GetBuffer((PyObject *)other, &view2, PyBUF_SIMPLE) < 0) {
+                PyObject_ReleaseBuffer(self->b_base, &view);
                 return NULL;
         }
 
  	ob = PyBytes_FromStringAndSize(NULL, view.len+view2.len);
 	if ( ob == NULL ) {
-                PyObject_ReleaseBuffer((PyObject *)self, &view);
+                PyObject_ReleaseBuffer(self->b_base, &view);
                 PyObject_ReleaseBuffer(other, &view2);
 		return NULL;
         }
@@ -421,7 +421,7 @@
  	memcpy(p, view.buf, view.len);
  	memcpy(p + view.len, view2.buf, view2.len);
 
-        PyObject_ReleaseBuffer((PyObject *)self, &view);
+        PyObject_ReleaseBuffer(self->b_base, &view);
         PyObject_ReleaseBuffer(other, &view2);
         return ob;
 }
@@ -448,7 +448,7 @@
 	    p += view.len;
 	}
 
-        PyObject_ReleaseBuffer((PyObject *)self, &view);
+        PyObject_ReleaseBuffer(self->b_base, &view);
 	return ob;
 }
 
@@ -465,7 +465,7 @@
 		return NULL;
 	}
 	ob = PyBytes_FromStringAndSize((char *)view.buf + idx, 1);
-        PyObject_ReleaseBuffer((PyObject *)self, &view);
+        PyObject_ReleaseBuffer(self->b_base, &view);
         return ob;
 }
 
@@ -486,7 +486,7 @@
 		right = left;
 	ob = PyBytes_FromStringAndSize((char *)view.buf + left,
                                        right - left);
-        PyObject_ReleaseBuffer((PyObject *)self, &view);
+        PyObject_ReleaseBuffer(self->b_base, &view);
         return ob;
 }
 
@@ -502,11 +502,12 @@
 	if ( self->b_readonly || view.readonly ) {
 		PyErr_SetString(PyExc_TypeError,
 				"buffer is read-only");
-                PyObject_ReleaseBuffer((PyObject *)self, &view);
+                PyObject_ReleaseBuffer(self->b_base, &view);
 		return -1;
 	}
 
 	if (idx < 0 || idx >= view.len) {
+                PyObject_ReleaseBuffer(self->b_base, &view);
 		PyErr_SetString(PyExc_IndexError,
 				"buffer assignment index out of range");
 		return -1;
@@ -516,16 +517,16 @@
 	if ( pb == NULL ||
 	     pb->bf_getbuffer == NULL) {
 		PyErr_BadArgument();
-                PyObject_ReleaseBuffer((PyObject *)self, &view);
+                PyObject_ReleaseBuffer(self->b_base, &view);
 		return -1;
 	}
         
         if (PyObject_GetBuffer(other, &view2, PyBUF_SIMPLE) < 0) {
-                PyObject_ReleaseBuffer((PyObject *)self, &view);
+                PyObject_ReleaseBuffer(self->b_base, &view);
                 return -1;
         }
 	if ( view.len != 1 ) {
-                PyObject_ReleaseBuffer((PyObject *)self, &view);
+                PyObject_ReleaseBuffer(self->b_base, &view);
                 PyObject_ReleaseBuffer(other, &view2);
 		PyErr_SetString(PyExc_TypeError,
 				"right operand must be a single byte");
@@ -533,7 +534,7 @@
 	}
 
 	((char *)(view.buf))[idx] = *((char *)(view2.buf));
-        PyObject_ReleaseBuffer((PyObject *)self, &view);
+        PyObject_ReleaseBuffer(self->b_base, &view);
         PyObject_ReleaseBuffer(other, &view2);
 	return 0;
 }
@@ -558,12 +559,12 @@
 	if ( self->b_readonly || v1.readonly) {
 		PyErr_SetString(PyExc_TypeError,
 				"buffer is read-only");
-                PyObject_ReleaseBuffer((PyObject *)self, &v1);
+                PyObject_ReleaseBuffer(self->b_base, &v1);
 		return -1;
 	}
 
         if ((*pb->bf_getbuffer)(other, &v2, PyBUF_SIMPLE) < 0) {
-                PyObject_ReleaseBuffer((PyObject *)self, &v1);
+                PyObject_ReleaseBuffer(self->b_base, &v1);
                 return -1;
         }
 
@@ -581,13 +582,15 @@
 		PyErr_SetString(
 			PyExc_TypeError,
 			"right operand length must match slice length");
+                PyObject_ReleaseBuffer(self->b_base, &v1);
+                PyObject_ReleaseBuffer(other, &v2);
 		return -1;
 	}
 
 	if ( slice_len )
 	    memcpy((char *)v1.buf + left, v2.buf, slice_len);
 
-        PyObject_ReleaseBuffer((PyObject *)self, &v1);        
+        PyObject_ReleaseBuffer(self->b_base, &v1);
         PyObject_ReleaseBuffer(other, &v2);        
 	return 0;
 }

Modified: python/branches/py3k-buffer/Objects/bytesobject.c
==============================================================================
--- python/branches/py3k-buffer/Objects/bytesobject.c	(original)
+++ python/branches/py3k-buffer/Objects/bytesobject.c	Sun Aug 12 10:24:12 2007
@@ -173,6 +173,9 @@
     }
 
     if (((PyBytesObject *)self)->ob_exports > 0) {
+            /*
+            fprintf(stderr, "%d: %s", ((PyBytesObject *)self)->ob_exports, ((PyBytesObject *)self)->ob_bytes);
+            */
             PyErr_SetString(PyExc_BufferError,
                             "Existing exports of data: object cannot be re-sized");
             return -1;
@@ -272,6 +275,7 @@
             return NULL;
     }
     memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
+    PyObject_ReleaseBuffer(other, &vo);
     Py_INCREF(self);
     return (PyObject *)self;
 }
@@ -953,6 +957,7 @@
 
     other_size = _getbuffer(other, &other_bytes);
     if (other_size < 0) {
+        PyObject_ReleaseBuffer(self, &self_bytes);
         Py_INCREF(Py_NotImplemented);
         return Py_NotImplemented;
     }
@@ -987,6 +992,8 @@
     }
 
     res = cmp ? Py_True : Py_False;
+    PyObject_ReleaseBuffer(self, &self_bytes);
+    PyObject_ReleaseBuffer(other, &other_bytes);    
     Py_INCREF(res);
     return res;
 }

Modified: python/branches/py3k-buffer/Objects/memoryobject.c
==============================================================================
--- python/branches/py3k-buffer/Objects/memoryobject.c	(original)
+++ python/branches/py3k-buffer/Objects/memoryobject.c	Sun Aug 12 10:24:12 2007
@@ -206,10 +206,8 @@
         if (mem == NULL) return NULL;
 
         view = &PyMemoryView(mem);
+        flags = PyBUF_FULL_RO;
         switch(buffertype) {
-        case PyBUF_READ:
-                flags = PyBUF_FULL_RO;
-                break;
         case PyBUF_WRITE:
                 flags = PyBUF_FULL;
                 break;

Modified: python/branches/py3k-buffer/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k-buffer/Objects/unicodeobject.c	(original)
+++ python/branches/py3k-buffer/Objects/unicodeobject.c	Sun Aug 12 10:24:12 2007
@@ -7792,9 +7792,19 @@
 static int
 unicode_buffer_getbuffer(PyUnicodeObject *self, PyBuffer *view, int flags)
 {
-    
-    return PyBuffer_FillInfo(view, (void *)self->str, PyUnicode_GET_DATA_SIZE(self),
-                             1, flags);
+
+    if (flags & PyBUF_CHARACTER) {
+        PyObject *str;
+        
+        str = _PyUnicode_AsDefaultEncodedString((PyObject *)self, NULL);
+        if (str == NULL) return -1;
+        return PyBuffer_FillInfo(view, (void *)PyString_AS_STRING(str),
+                                 PyString_GET_SIZE(str), 1, flags);
+    }
+    else {
+        return PyBuffer_FillInfo(view, (void *)self->str, 
+                                 PyUnicode_GET_DATA_SIZE(self), 1, flags);
+    }
 }
 
 

Modified: python/branches/py3k-buffer/Python/getargs.c
==============================================================================
--- python/branches/py3k-buffer/Python/getargs.c	(original)
+++ python/branches/py3k-buffer/Python/getargs.c	Sun Aug 12 10:24:12 2007
@@ -1179,15 +1179,21 @@
 		void **p = va_arg(*p_va, void **);
 		PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
 		int count;
+                int temp=-1;
                 PyBuffer view;
 			
 		if (pb == NULL || 
-		    pb->bf_getbuffer == NULL)
-			return converterr("read-write buffer", arg, msgbuf, bufsize);
-		if ((*pb->bf_getbuffer)(arg, &view, PyBUF_SIMPLE) != 0 || 
-                    view.readonly == 1)
+		    pb->bf_getbuffer == NULL ||
+                    ((temp = (*pb->bf_getbuffer)(arg, &view, 
+                                                 PyBUF_SIMPLE)) != 0) ||
+                    view.readonly == 1) {
+                        if (temp==0 && pb->bf_releasebuffer != NULL) {
+                                (*pb->bf_releasebuffer)(arg, &view);
+                        }
 			return converterr("single-segment read-write buffer", 
 					  arg, msgbuf, bufsize);
+                }
+                        
                 if ((count = view.len) < 0)
 			return converterr("(unspecified)", arg, msgbuf, bufsize);
                 *p = view.buf;
@@ -1196,7 +1202,8 @@
 			STORE_SIZE(count);
 			format++;
 		}
-                /* XXX : Buffer not released (warn about that)!*/
+                if (pb->bf_releasebuffer != NULL)
+                        (*pb->bf_releasebuffer)(arg, &view);
 		break;
 	}
 		
@@ -1221,6 +1228,10 @@
 
                 count = view.len;
                 *p = view.buf;
+                /* XXX : shouldn't really release buffer, but it should be O.K.
+                */
+                if (pb->bf_releasebuffer != NULL) 
+                        (*pb->bf_releasebuffer)(arg, &view);
 		if (count < 0)
 			return converterr("(unspecified)", arg, msgbuf, bufsize);
 		{
@@ -1246,6 +1257,7 @@
 	Py_ssize_t count;
         PyBuffer view;
 
+        *p = NULL;
 	if (pb == NULL ||
 	    pb->bf_getbuffer == NULL) {
 		*errmsg = "string or read-only buffer";
@@ -1258,6 +1270,8 @@
 	}
         count = view.len;
         *p = view.buf;
+        if (pb->bf_releasebuffer != NULL)
+                (*pb->bf_releasebuffer)(arg, &view);
 	return count;
 }
 

Modified: python/branches/py3k-buffer/Python/marshal.c
==============================================================================
--- python/branches/py3k-buffer/Python/marshal.c	(original)
+++ python/branches/py3k-buffer/Python/marshal.c	Sun Aug 12 10:24:12 2007
@@ -377,6 +377,8 @@
 		}
 		w_long((long)n, p);
 		w_string(s, (int)n, p);
+                if (pb->bf_releasebuffer != NULL)
+                        (*pb->bf_releasebuffer)(v, &view);
 	}
 	else {
 		w_byte(TYPE_UNKNOWN, p);


More information about the Python-3000-checkins mailing list