Change PyBuffer to Py_buffer to be consistent with other non-object structures like Py_complex.  Add some more functionality to the memoryview object.
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 284eb33..141996d 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -224,7 +224,7 @@
                       Py_ssize_t *buffer_len)
 {
 	PyBufferProcs *pb;
-        PyBuffer view;
+        Py_buffer view;
 
 	if (obj == NULL || buffer == NULL || buffer_len == NULL) {
 		null_error();
@@ -267,7 +267,7 @@
 			  Py_ssize_t *buffer_len)
 {
 	PyBufferProcs *pb;
-        PyBuffer view;
+        Py_buffer view;
 
 	if (obj == NULL || buffer == NULL || buffer_len == NULL) {
 		null_error();
@@ -295,7 +295,7 @@
 			   Py_ssize_t *buffer_len)
 {
 	PyBufferProcs *pb;
-        PyBuffer view;
+        Py_buffer view;
 
 	if (obj == NULL || buffer == NULL || buffer_len == NULL) {
 		null_error();
@@ -320,7 +320,7 @@
 /* Buffer C-API for Python 3.0 */
 
 int
-PyObject_GetBuffer(PyObject *obj, PyBuffer *view, int flags)
+PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
 {
         if (!PyObject_CheckBuffer(obj)) {
                 PyErr_SetString(PyExc_TypeError,
@@ -331,7 +331,7 @@
 }
 
 void
-PyObject_ReleaseBuffer(PyObject *obj, PyBuffer *view)
+PyObject_ReleaseBuffer(PyObject *obj, Py_buffer *view)
 {
         if (obj->ob_type->tp_as_buffer != NULL && 
             obj->ob_type->tp_as_buffer->bf_releasebuffer != NULL) {
@@ -341,7 +341,7 @@
 
 
 static int
-_IsFortranContiguous(PyBuffer *view)
+_IsFortranContiguous(Py_buffer *view)
 {
         Py_ssize_t sd, dim;
         int i;
@@ -362,7 +362,7 @@
 }
 
 static int
-_IsCContiguous(PyBuffer *view)
+_IsCContiguous(Py_buffer *view)
 {
         Py_ssize_t sd, dim;
         int i;
@@ -383,7 +383,7 @@
 }
 
 int
-PyBuffer_IsContiguous(PyBuffer *view, char fort)
+PyBuffer_IsContiguous(Py_buffer *view, char fort)
 {
 
         if (view->suboffsets != NULL) return 0;
@@ -399,7 +399,7 @@
 
 
 void* 
-PyBuffer_GetPointer(PyBuffer *view, Py_ssize_t *indices)
+PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices)
 {
         char* pointer;
         int i;
@@ -452,7 +452,7 @@
   */
 
 int 
-PyBuffer_ToContiguous(void *buf, PyBuffer *view, Py_ssize_t len, char fort)
+PyBuffer_ToContiguous(void *buf, Py_buffer *view, Py_ssize_t len, char fort)
 {
         int k;
         void (*addone)(int, Py_ssize_t *, Py_ssize_t *);
@@ -503,7 +503,7 @@
 }
 
 int
-PyBuffer_FromContiguous(PyBuffer *view, void *buf, Py_ssize_t len, char fort)
+PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort)
 {
         int k;
         void (*addone)(int, Py_ssize_t *, Py_ssize_t *);
@@ -556,7 +556,7 @@
 
 int PyObject_CopyData(PyObject *dest, PyObject *src) 
 {
-        PyBuffer view_dest, view_src;
+        Py_buffer view_dest, view_src;
         int k;
         Py_ssize_t *indices, elements;
         char *dptr, *sptr;
@@ -649,7 +649,7 @@
 }
 
 int
-PyBuffer_FillInfo(PyBuffer *view, void *buf, Py_ssize_t len,
+PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len,
               int readonly, int flags)
 {        
         if (view == NULL) return 0;
diff --git a/Objects/bufferobject.c b/Objects/bufferobject.c
index d697d26..62b869b 100644
--- a/Objects/bufferobject.c
+++ b/Objects/bufferobject.c
@@ -16,11 +16,12 @@
 
 
 static int
-get_buf(PyBufferObject *self, PyBuffer *view, int flags)
+get_buf(PyBufferObject *self, Py_buffer *view, int flags)
 {
 	if (self->b_base == NULL) {
 		view->buf = self->b_ptr;
 		view->len = self->b_size;
+		view->readonly = 0;
 	}
 	else {
 		Py_ssize_t count, offset;
@@ -46,7 +47,7 @@
 
 
 static int
-buffer_getbuf(PyBufferObject *self, PyBuffer *view, int flags)
+buffer_getbuf(PyBufferObject *self, Py_buffer *view, int flags)
 {
         if (view == NULL) return 0;
         if (!get_buf(self, view, flags))
@@ -57,7 +58,7 @@
 
 
 static void
-buffer_releasebuf(PyBufferObject *self, PyBuffer *view) 
+buffer_releasebuf(PyBufferObject *self, Py_buffer *view) 
 {
         /* No-op if there is no self->b_base */
 	if (self->b_base != NULL) {
@@ -229,7 +230,7 @@
 }
 
 static int
-get_bufx(PyObject *obj, PyBuffer *view, int flags)
+get_bufx(PyObject *obj, Py_buffer *view, int flags)
 {
 	PyBufferProcs *bp;
 
@@ -256,7 +257,7 @@
 	void *p1, *p2;
 	Py_ssize_t len1, len2, min_len;
 	int cmp, ok;
-        PyBuffer v1, v2;
+        Py_buffer v1, v2;
 
 	ok = 1;
 	if (!get_bufx(self, &v1, PyBUF_SIMPLE))
@@ -318,7 +319,7 @@
 static long
 buffer_hash(PyBufferObject *self)
 {
-        PyBuffer view;
+        Py_buffer view;
 	register Py_ssize_t len;
 	register unsigned char *p;
 	register long x;
@@ -351,7 +352,7 @@
 static PyObject *
 buffer_str(PyBufferObject *self)
 {
-        PyBuffer view;
+        Py_buffer view;
         PyObject *res;
 
 	if (!get_buf(self, &view, PyBUF_SIMPLE))
@@ -366,7 +367,7 @@
 static Py_ssize_t
 buffer_length(PyBufferObject *self)
 {
-        PyBuffer view;
+        Py_buffer view;
 
 	if (!get_buf(self, &view, PyBUF_SIMPLE))
 		return -1;
@@ -380,7 +381,7 @@
 	PyBufferProcs *pb = other->ob_type->tp_as_buffer;
 	char *p;
 	PyObject *ob;
-        PyBuffer view, view2;
+        Py_buffer view, view2;
 
 	if (pb == NULL ||
             pb->bf_getbuffer == NULL)
@@ -426,7 +427,7 @@
 {
 	PyObject *ob;
 	register char *p;
-        PyBuffer view;
+        Py_buffer view;
 
 	if (count < 0)
 		count = 0;
@@ -450,7 +451,7 @@
 static PyObject *
 buffer_item(PyBufferObject *self, Py_ssize_t idx)
 {
-        PyBuffer view;
+        Py_buffer view;
         PyObject *ob;
 
 	if (!get_buf(self, &view, PyBUF_SIMPLE))
@@ -467,7 +468,7 @@
 static PyObject *
 buffer_subscript(PyBufferObject *self, PyObject *item)
 {
-	PyBuffer view;
+	Py_buffer view;
 	PyObject *ob;
 	
 	if (!get_buf(self, &view, PyBUF_SIMPLE))
@@ -537,7 +538,7 @@
 buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
 {
 	PyBufferProcs *pb;
-        PyBuffer view, view2;
+        Py_buffer view, view2;
 
 	if (!get_buf(self, &view, PyBUF_SIMPLE))
 		return -1;
@@ -585,7 +586,7 @@
 static int
 buffer_ass_subscript(PyBufferObject *self, PyObject *item, PyObject *value)
 {
-	PyBuffer v1;
+	Py_buffer v1;
 
 	if (!get_buf(self, &v1, PyBUF_SIMPLE))
 		return -1;
@@ -606,7 +607,7 @@
 	}
 	else if (PySlice_Check(item)) {
 		Py_ssize_t start, stop, step, slicelength;
-		PyBuffer v2;
+		Py_buffer v2;
 		PyBufferProcs *pb;
 		
 		if (PySlice_GetIndicesEx((PySliceObject *)item, v1.len,
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index 1486c5e..c7fe751 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -50,7 +50,7 @@
 }
 
 static int
-bytes_getbuffer(PyBytesObject *obj, PyBuffer *view, int flags)
+bytes_getbuffer(PyBytesObject *obj, Py_buffer *view, int flags)
 {
         int ret;
         void *ptr;
@@ -70,13 +70,13 @@
 }
 
 static void
-bytes_releasebuffer(PyBytesObject *obj, PyBuffer *view)
+bytes_releasebuffer(PyBytesObject *obj, Py_buffer *view)
 {
         obj->ob_exports--;
 }
 
 static Py_ssize_t
-_getbuffer(PyObject *obj, PyBuffer *view)
+_getbuffer(PyObject *obj, Py_buffer *view)
 {
     PyBufferProcs *buffer = Py_Type(obj)->tp_as_buffer;
 
@@ -213,7 +213,7 @@
 PyBytes_Concat(PyObject *a, PyObject *b)
 {
     Py_ssize_t size;
-    PyBuffer va, vb;
+    Py_buffer va, vb;
     PyBytesObject *result;
 
     va.len = -1;
@@ -266,7 +266,7 @@
 {
     Py_ssize_t mysize;
     Py_ssize_t size;
-    PyBuffer vo;
+    Py_buffer vo;
 
     if (_getbuffer(other, &vo) < 0) {
         PyErr_Format(PyExc_TypeError, "can't concat bytes to %.100s",
@@ -462,7 +462,7 @@
 {
     Py_ssize_t avail, needed;
     void *bytes;
-    PyBuffer vbytes;
+    Py_buffer vbytes;
     int res = 0;
 
     vbytes.len = -1;
@@ -814,7 +814,7 @@
     /* Use the modern buffer interface */
     if (PyObject_CheckBuffer(arg)) {
         Py_ssize_t size;
-        PyBuffer view;
+        Py_buffer view;
         if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
             return -1;
         size = view.len;
@@ -954,7 +954,7 @@
 bytes_richcompare(PyObject *self, PyObject *other, int op)
 {
     Py_ssize_t self_size, other_size;
-    PyBuffer self_bytes, other_bytes;
+    Py_buffer self_bytes, other_bytes;
     PyObject *res;
     Py_ssize_t minsize;
     int cmp;
@@ -1067,7 +1067,7 @@
 bytes_find_internal(PyBytesObject *self, PyObject *args, int dir)
 {
     PyObject *subobj;
-    PyBuffer subbuf;
+    Py_buffer subbuf;
     Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
     Py_ssize_t res;
 
@@ -2033,7 +2033,7 @@
 {
     Py_ssize_t count = -1;
     PyObject *from, *to, *res;
-    PyBuffer vfrom, vto;
+    Py_buffer vfrom, vto;
 
     if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
         return NULL;
@@ -2187,7 +2187,7 @@
     Py_ssize_t maxsplit = -1, count = 0;
     const char *s = PyBytes_AS_STRING(self), *sub;
     PyObject *list, *str, *subobj = Py_None;
-    PyBuffer vsub;
+    Py_buffer vsub;
 #ifdef USE_FAST
     Py_ssize_t pos;
 #endif
@@ -2396,7 +2396,7 @@
     Py_ssize_t maxsplit = -1, count = 0;
     const char *s = PyBytes_AS_STRING(self), *sub;
     PyObject *list, *str, *subobj = Py_None;
-    PyBuffer vsub;
+    Py_buffer vsub;
 
     if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
         return NULL;
@@ -2647,7 +2647,7 @@
     Py_ssize_t left, right, mysize, argsize;
     void *myptr, *argptr;
     PyObject *arg = Py_None;
-    PyBuffer varg;
+    Py_buffer varg;
     if (!PyArg_ParseTuple(args, "|O:strip", &arg))
         return NULL;
     if (arg == Py_None) {
@@ -2683,7 +2683,7 @@
     Py_ssize_t left, right, mysize, argsize;
     void *myptr, *argptr;
     PyObject *arg = Py_None;
-    PyBuffer varg;
+    Py_buffer varg;
     if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
         return NULL;
     if (arg == Py_None) {
@@ -2716,7 +2716,7 @@
     Py_ssize_t left, right, mysize, argsize;
     void *myptr, *argptr;
     PyObject *arg = Py_None;
-    PyBuffer varg;
+    Py_buffer varg;
     if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
         return NULL;
     if (arg == Py_None) {
diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c
index f0a7053..3d7e42e 100644
--- a/Objects/memoryobject.c
+++ b/Objects/memoryobject.c
@@ -4,16 +4,16 @@
 #include "Python.h"
 
 static int
-memory_getbuf(PyMemoryViewObject *self, PyBuffer *view, int flags)
+memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
 {
         if (view != NULL) 
-                memcpy(view, &(self->view), sizeof(PyBuffer));
+		*view = self->view;
         return self->base->ob_type->tp_as_buffer->bf_getbuffer(self->base, 
                                                                NULL, PyBUF_FULL);
 }
 
 static void
-memory_releasebuf(PyMemoryViewObject *self, PyBuffer *view) 
+memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view) 
 {
         PyObject_ReleaseBuffer(self->base, NULL);
 }
@@ -24,11 +24,16 @@
 Create a new memoryview object which references the given object.");
 
 PyObject *
-PyMemoryView_FromMemory(PyBuffer *info)
+PyMemoryView_FromMemory(Py_buffer *info)
 {
-	/* XXX(nnorwitz): need to implement something here? */
-        PyErr_SetString(PyExc_NotImplementedError, "need to implement");
-        return NULL;
+	PyMemoryViewObject *mview;
+
+	mview = (PyMemoryViewObject *)PyObject_New(PyMemoryViewObject,
+						   &PyMemoryView_Type);
+	if (mview == NULL) return NULL;
+	mview->base = NULL;
+	mview->view = *info;
+	return (PyObject *)mview;
 }
 
 PyObject *
@@ -130,7 +135,7 @@
 void _add_one_to_index_C(int nd, Py_ssize_t *index, Py_ssize_t *shape);
 
 static int
-_indirect_copy_nd(char *dest, PyBuffer *view, char fort)
+_indirect_copy_nd(char *dest, Py_buffer *view, char fort)
 {
         Py_ssize_t *indices;
         int k;
@@ -196,7 +201,7 @@
 {
         PyMemoryViewObject *mem;
         PyObject *bytes;
-        PyBuffer *view;
+        Py_buffer *view;
         int flags;
         char *dest;
 
@@ -264,8 +269,11 @@
                 /* return a shadowed memory-view object */
                 view->buf = dest;
                 mem->base = PyTuple_Pack(2, obj, bytes);
-		/* XXX(nnorwitz): need to verify alloc was successful. */
                 Py_DECREF(bytes);
+		if (mem->base == NULL) {
+			PyObject_ReleaseBuffer(obj, view);
+			return NULL;
+		}
         }
         else {
                 PyObject_ReleaseBuffer(obj, view);
@@ -364,13 +372,15 @@
 static PyObject *
 memory_tobytes(PyMemoryViewObject *mem, PyObject *noargs)
 {
-        /* Create new Bytes object for data */
         return PyBytes_FromObject((PyObject *)mem);
 }
 
 static PyObject *
 memory_tolist(PyMemoryViewObject *mem, PyObject *noargs)
 {
+	/* This should construct a (nested) list of unpacked objects
+	   possibly using the struct module. 
+	 */
         Py_INCREF(Py_NotImplemented);
         return Py_NotImplemented;
 }
@@ -429,7 +439,7 @@
 static PyObject *
 memory_str(PyMemoryViewObject *self)
 {
-        PyBuffer view;
+        Py_buffer view;
         PyObject *res;
 
         if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0)
@@ -446,7 +456,7 @@
 static Py_ssize_t
 memory_length(PyMemoryViewObject *self)
 {
-        PyBuffer view;
+        Py_buffer view;
 
         if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0)
                 return -1;
@@ -454,9 +464,58 @@
 	return view.len;
 }
 
+/*  
+  mem[obj] returns a bytes object holding the data for one element if
+           obj fully indexes the memory view or another memory-view object
+	   if it does not.
+	   
+	   0-d memory-view objects can be referenced using ... or () but
+	   not with anything else. 
+ */
 static PyObject *
 memory_subscript(PyMemoryViewObject *self, PyObject *key)
 {
+	Py_buffer *view;
+	view = &(self->view);
+
+	if (view->ndim == 0) {
+		if (key == Py_Ellipsis ||
+		    (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
+			Py_INCREF(self);
+			return (PyObject *)self;
+		}
+		else {
+			PyErr_SetString(PyExc_IndexError, "invalid indexing of 0-dim memory");
+			return NULL;
+		}
+	}
+	if (PyIndex_Check(key)) {
+		Py_ssize_t result;
+		result = PyNumber_AsSsize_t(key, NULL);
+		if (result == -1 && PyErr_Occurred())
+			return NULL;
+		if (view->ndim == 1) {
+			/* Return a bytes object */
+			char *ptr;
+			ptr = (char *)view->buf;
+			if (view->strides == NULL) 
+				ptr += view->itemsize * result;
+			else
+				ptr += view->strides[0] * result;
+			if (view->suboffsets != NULL && view->suboffsets[0] >= 0) {
+				ptr = *((char **)ptr) + view->suboffsets[0];
+			}
+			return PyBytes_FromStringAndSize(ptr, view->itemsize);
+		}
+		else {
+			/* Return a new memory-view object */	   
+			Py_buffer newview;
+			PyMemoryView_FromMemory(&newview);
+		}
+	}
+	
+	
+
         Py_INCREF(Py_NotImplemented);
         return Py_NotImplemented;
 }
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index d263812..648711d 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -1160,7 +1160,7 @@
 }
 
 static int
-string_buffer_getbuffer(PyStringObject *self, PyBuffer *view, int flags)
+string_buffer_getbuffer(PyStringObject *self, Py_buffer *view, int flags)
 {
         return PyBuffer_FillInfo(view, (void *)self->ob_sval, Py_Size(self), 0, flags);
 }
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 2a6a087..c40f0be 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -8104,7 +8104,7 @@
 
 
 static int
-unicode_buffer_getbuffer(PyUnicodeObject *self, PyBuffer *view, int flags)
+unicode_buffer_getbuffer(PyUnicodeObject *self, Py_buffer *view, int flags)
 {
 
     if (flags & PyBUF_CHARACTER) {