[pypy-commit] pypy refactor-buffer-api: get tests passing

bdkearns noreply at buildbot.pypy.org
Tue Apr 22 20:34:03 CEST 2014


Author: Brian Kearns <bdkearns at gmail.com>
Branch: refactor-buffer-api
Changeset: r70861:f71f35155a2b
Date: 2014-03-21 13:23 -0400
http://bitbucket.org/pypy/pypy/changeset/f71f35155a2b/

Log:	get tests passing

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1345,6 +1345,11 @@
                                  self.wrap('cannot convert negative integer '
                                            'to unsigned int'))
 
+    BUF_SIMPLE = 0
+    BUF_FULL_RO = 1
+    BUF_CONTIG = 2
+    BUF_CONTIG_RO = 3
+
     def buffer_w(self, w_obj, flags):
         # New buffer interface, returns a buffer based on flags
         return w_obj.buffer_w(self, flags)
@@ -1377,6 +1382,14 @@
                 raise
         return self.readbuf_w(w_obj).as_str()
 
+    def bufferchar_w(self, w_obj):
+        try:
+            return self.str_w(w_obj)
+        except OperationError, e:
+            if not e.match(self, self.w_TypeError):
+                raise
+        return self.charbuf_w(w_obj)
+
     def str_or_None_w(self, w_obj):
         if self.is_w(w_obj, self.w_None):
             return None
diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py
--- a/pypy/module/_file/interp_file.py
+++ b/pypy/module/_file/interp_file.py
@@ -468,7 +468,7 @@
         """readinto() -> Undocumented.  Don't use this; it may go away."""
         # XXX not the most efficient solution as it doesn't avoid the copying
         space = self.space
-        rwbuffer = space.rwbuffer_w(w_rwbuffer)
+        rwbuffer = space.writebuf_w(w_rwbuffer)
         w_data = self.file_read(rwbuffer.getlength())
         data = space.str_w(w_data)
         rwbuffer.setslice(0, data)
diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py
--- a/pypy/module/_io/interp_bufferedio.py
+++ b/pypy/module/_io/interp_bufferedio.py
@@ -80,7 +80,7 @@
         self._unsupportedoperation(space, "detach")
 
     def readinto_w(self, space, w_buffer):
-        rwbuffer = space.rwbuffer_w(w_buffer)
+        rwbuffer = space.buffer_w(w_buffer, space.BUF_CONTIG)
         length = rwbuffer.getlength()
         w_data = space.call_method(self, "read", space.wrap(length))
 
diff --git a/pypy/module/_io/interp_bytesio.py b/pypy/module/_io/interp_bytesio.py
--- a/pypy/module/_io/interp_bytesio.py
+++ b/pypy/module/_io/interp_bytesio.py
@@ -41,7 +41,7 @@
 
     def readinto_w(self, space, w_buffer):
         self._check_closed(space)
-        rwbuffer = space.rwbuffer_w(w_buffer)
+        rwbuffer = space.buffer_w(w_buffer, space.BUF_CONTIG)
         size = rwbuffer.getlength()
 
         output = self.read(size)
diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py
--- a/pypy/module/_io/interp_fileio.py
+++ b/pypy/module/_io/interp_fileio.py
@@ -366,7 +366,7 @@
     def readinto_w(self, space, w_buffer):
         self._check_closed(space)
         self._check_readable(space)
-        rwbuffer = space.rwbuffer_w(w_buffer)
+        rwbuffer = space.buffer_w(w_buffer, space.BUF_CONTIG)
         length = rwbuffer.getlength()
         try:
             buf = os.read(self.fd, length)
diff --git a/pypy/module/_multiprocessing/interp_connection.py b/pypy/module/_multiprocessing/interp_connection.py
--- a/pypy/module/_multiprocessing/interp_connection.py
+++ b/pypy/module/_multiprocessing/interp_connection.py
@@ -122,7 +122,7 @@
 
     @unwrap_spec(offset='index')
     def recv_bytes_into(self, space, w_buffer, offset=0):
-        rwbuffer = space.rwbuffer_w(w_buffer)
+        rwbuffer = space.writebuf_w(w_buffer)
         length = rwbuffer.getlength()
 
         res, newbuf = self.do_recv_string(
diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py
--- a/pypy/module/_rawffi/interp_rawffi.py
+++ b/pypy/module/_rawffi/interp_rawffi.py
@@ -16,6 +16,7 @@
 
 from rpython.tool.sourcetools import func_with_new_name
 from rpython.rlib.rarithmetic import intmask, r_uint
+from pypy.module._rawffi.buffer import RawFFIBuffer
 from pypy.module._rawffi.tracker import tracker
 
 TYPEMAP = {
@@ -352,8 +353,13 @@
         lltype.free(self.ll_buffer, flavor='raw')
         self.ll_buffer = lltype.nullptr(rffi.VOIDP.TO)
 
-    def buffer_w(self, space):
-        from pypy.module._rawffi.buffer import RawFFIBuffer
+    def buffer_w(self, space, flags):
+        return RawFFIBuffer(self)
+
+    def readbuf_w(self, space):
+        return RawFFIBuffer(self)
+
+    def writebuf_w(self, space):
         return RawFFIBuffer(self)
 
     def getrawsize(self):
diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py
--- a/pypy/module/_rawffi/test/test__rawffi.py
+++ b/pypy/module/_rawffi/test/test__rawffi.py
@@ -1100,6 +1100,12 @@
         assert a[3] == 'z'
         assert a[4] == 't'
 
+        b = memoryview(a)
+        assert len(b) == 10
+        assert b[3] == 'z'
+        b[3] = 'x'
+        assert b[3] == 'x'
+
     def test_union(self):
         import _rawffi
         longsize = _rawffi.sizeof('l')
diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py
--- a/pypy/module/_socket/interp_socket.py
+++ b/pypy/module/_socket/interp_socket.py
@@ -419,7 +419,7 @@
 
     @unwrap_spec(nbytes=int, flags=int)
     def recv_into_w(self, space, w_buffer, nbytes=0, flags=0):
-        rwbuffer = space.rwbuffer_w(w_buffer)
+        rwbuffer = space.writebuf_w(w_buffer)
         lgt = rwbuffer.getlength()
         if nbytes == 0 or nbytes > lgt:
             nbytes = lgt
@@ -430,7 +430,7 @@
 
     @unwrap_spec(nbytes=int, flags=int)
     def recvfrom_into_w(self, space, w_buffer, nbytes=0, flags=0):
-        rwbuffer = space.rwbuffer_w(w_buffer)
+        rwbuffer = space.writebuf_w(w_buffer)
         lgt = rwbuffer.getlength()
         if nbytes == 0 or nbytes > lgt:
             nbytes = lgt
diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py
--- a/pypy/module/array/interp_array.py
+++ b/pypy/module/array/interp_array.py
@@ -132,7 +132,10 @@
         self.len = 0
         self.allocated = 0
 
-    def buffer_w(self, space):
+    def readbuf_w(self, space):
+        return ArrayBuffer(self)
+
+    def writebuf_w(self, space):
         return ArrayBuffer(self)
 
     def descr_append(self, space, w_x):
diff --git a/pypy/module/cppyy/converter.py b/pypy/module/cppyy/converter.py
--- a/pypy/module/cppyy/converter.py
+++ b/pypy/module/cppyy/converter.py
@@ -49,7 +49,7 @@
 
 def get_rawbuffer(space, w_obj):
     try:
-        buf = space.buffer_w(w_obj)
+        buf = space.buffer_w(w_obj, space.BUF_SIMPLE)
         return rffi.cast(rffi.VOIDP, buf.get_raw_address())
     except Exception:
         pass
@@ -151,7 +151,7 @@
     def to_memory(self, space, w_obj, w_value, offset):
         # copy the full array (uses byte copy for now)
         address = rffi.cast(rffi.CCHARP, self._get_raw_address(space, w_obj, offset))
-        buf = space.buffer_w(w_value)
+        buf = space.buffer_w(w_value, space.BUF_SIMPLE)
         # TODO: report if too many items given?
         for i in range(min(self.size*self.typesize, buf.getlength())):
             address[i] = buf.getitem(i)
@@ -192,7 +192,7 @@
         # copy only the pointer value
         rawobject = get_rawobject_nonnull(space, w_obj)
         byteptr = rffi.cast(rffi.CCHARPP, capi.direct_ptradd(rawobject, offset))
-        buf = space.buffer_w(w_value)
+        buf = space.buffer_w(w_value, space.BUF_SIMPLE)
         try:
             byteptr[0] = buf.get_raw_address()
         except ValueError:
diff --git a/pypy/module/fcntl/interp_fcntl.py b/pypy/module/fcntl/interp_fcntl.py
--- a/pypy/module/fcntl/interp_fcntl.py
+++ b/pypy/module/fcntl/interp_fcntl.py
@@ -209,7 +209,7 @@
 
     if mutate_flag != 0:
         try:
-            rwbuffer = space.rwbuffer_w(w_arg)
+            rwbuffer = space.writebuf_w(w_arg)
         except OperationError, e:
             if not e.match(space, space.w_TypeError):
                 raise
diff --git a/pypy/module/marshal/interp_marshal.py b/pypy/module/marshal/interp_marshal.py
--- a/pypy/module/marshal/interp_marshal.py
+++ b/pypy/module/marshal/interp_marshal.py
@@ -220,7 +220,7 @@
         space = self.space
         if space.type(w_obj).is_heaptype():
             try:
-                buf = space.buffer_w(w_obj)
+                buf = space.readbuf_w(w_obj)
             except OperationError as e:
                 if not e.match(space, space.w_TypeError):
                     raise
diff --git a/pypy/module/micronumpy/boxes.py b/pypy/module/micronumpy/boxes.py
--- a/pypy/module/micronumpy/boxes.py
+++ b/pypy/module/micronumpy/boxes.py
@@ -342,8 +342,14 @@
     def descr_copy(self, space):
         return self.convert_to(space, self.get_dtype(space))
 
-    def buffer_w(self, space):
-        return self.descr_ravel(space).buffer_w(space)
+    def buffer_w(self, space, flags):
+        return self.descr_ravel(space).buffer_w(space, flags)
+
+    def readbuf_w(self, space):
+        return self.descr_ravel(space).readbuf_w(space)
+
+    def charbuf_w(self, space):
+        return self.descr_ravel(space).charbuf_w(space)
 
     def descr_byteswap(self, space):
         return self.get_dtype(space).itemtype.byteswap(self)
diff --git a/pypy/module/micronumpy/ndarray.py b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -602,11 +602,20 @@
         raise OperationError(space.w_NotImplementedError, space.wrap(
             "ctypes not implemented yet"))
 
-    def buffer_w(self, space):
+    def buffer_w(self, space, flags):
         return self.implementation.get_buffer(space)
 
+    def readbuf_w(self, space):
+        return self.implementation.get_buffer(space)
+
+    def writebuf_w(self, space):
+        return self.implementation.get_buffer(space)
+
+    def charbuf_w(self, space):
+        return self.implementation.get_buffer(space).as_str()
+
     def descr_get_data(self, space):
-        return space.newbuffer(self.buffer_w(space))
+        return space.newbuffer(self.implementation.get_buffer(space))
 
     @unwrap_spec(offset=int, axis1=int, axis2=int)
     def descr_diagonal(self, space, offset=0, axis1=0, axis2=1):
@@ -1159,7 +1168,10 @@
             raise OperationError(space.w_NotImplementedError,
                                  space.wrap("unsupported param"))
 
-        buf = space.buffer_w(w_buffer)
+        try:
+            buf = space.writebuf_w(w_buffer)
+        except OperationError:
+            buf = space.readbuf_w(w_buffer)
         try:
             raw_ptr = buf.get_raw_address()
         except ValueError:
diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py
--- a/pypy/module/mmap/interp_mmap.py
+++ b/pypy/module/mmap/interp_mmap.py
@@ -17,7 +17,7 @@
         self.space = space
         self.mmap = mmap_obj
 
-    def buffer_w(self, space):
+    def readbuf_w(self, space):
         self.check_valid()
         return MMapBuffer(self.space, self.mmap)
 
diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py
--- a/pypy/objspace/fake/objspace.py
+++ b/pypy/objspace/fake/objspace.py
@@ -1,6 +1,7 @@
 from rpython.annotator.model import SomeInstance, s_None
 from pypy.interpreter import argument, gateway
 from pypy.interpreter.baseobjspace import W_Root, ObjSpace, SpaceCache
+from pypy.interpreter.buffer import Buffer
 from pypy.interpreter.typedef import TypeDef, GetSetProperty
 from pypy.objspace.std.stdtypedef import StdTypeDef
 from pypy.objspace.std.sliceobject import W_SliceObject
@@ -295,8 +296,11 @@
         ec._py_repr = None
         return ec
 
-    def buffer_w(self, w_obj):
-        from pypy.interpreter.buffer import Buffer
+    def readbuf_w(self, w_obj):
+        is_root(w_obj)
+        return Buffer()
+
+    def writebuf_w(self, w_obj):
         is_root(w_obj)
         return Buffer()
 
diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -27,8 +27,17 @@
         """representation for debugging purposes"""
         return "%s(%s)" % (w_self.__class__.__name__, ''.join(w_self.data))
 
-    def buffer_w(w_self, space):
-        return BytearrayBuffer(w_self.data)
+    def buffer_w(self, space, flags):
+        return BytearrayBuffer(self.data)
+
+    def readbuf_w(self, space):
+        return BytearrayBuffer(self.data)
+
+    def writebuf_w(self, space):
+        return BytearrayBuffer(self.data)
+
+    def charbuf_w(self, space):
+        return ''.join(self.data)
 
     def _new(self, value):
         return W_BytearrayObject(_make_data(value))
@@ -50,10 +59,10 @@
         return space.wrap(ord(character))
 
     def _val(self, space):
-        return space.bufferstr_w(self)
+        return space.buffer_w(self, space.BUF_SIMPLE).as_str()
 
     def _op_val(self, space, w_other):
-        return space.buffer_w(w_other).as_str()
+        return space.buffer_w(w_other, space.BUF_SIMPLE).as_str()
 
     def _chr(self, char):
         assert len(char) == 1
@@ -432,7 +441,7 @@
 def makebytearraydata_w(space, w_source):
     # String-like argument
     try:
-        buf = space.buffer_w(w_source)
+        buf = space.buffer_w(w_source, space.BUF_FULL_RO)
     except OperationError as e:
         if not e.match(space, space.w_TypeError):
             raise
diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py
--- a/pypy/objspace/std/bytesobject.py
+++ b/pypy/objspace/std/bytesobject.py
@@ -442,8 +442,14 @@
     def str_w(self, space):
         return self._value
 
-    def buffer_w(w_self, space):
-        return StringBuffer(w_self._value)
+    def buffer_w(self, space, flags):
+        return StringBuffer(self._value)
+
+    def readbuf_w(self, space):
+        return StringBuffer(self._value)
+
+    def charbuf_w(self, space):
+        return self._value
 
     def listview_bytes(self):
         return _create_list_from_bytes(self._value)
@@ -471,8 +477,7 @@
         return self._value
 
     def _op_val(self, space, w_other):
-        return space.bufferstr_w(w_other)
-        #return w_other._value
+        return space.bufferchar_w(w_other)
 
     def _chr(self, char):
         assert len(char) == 1
diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -692,7 +692,7 @@
         else:
             # If object supports the buffer interface
             try:
-                buf = space.buffer_w(w_value)
+                buf = space.charbuf_w(w_value)
             except OperationError as e:
                 if not e.match(space, space.w_TypeError):
                     raise
@@ -700,8 +700,7 @@
                             "int() argument must be a string or a number, "
                             "not '%T'", w_value)
             else:
-                value, w_longval = _string_to_int_or_long(space, w_value,
-                                                          buf.as_str())
+                value, w_longval = _string_to_int_or_long(space, w_value, buf)
     else:
         base = space.int_w(w_base)
 
diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py
--- a/pypy/objspace/std/longobject.py
+++ b/pypy/objspace/std/longobject.py
@@ -512,7 +512,7 @@
                                      unicode_to_decimal_w(space, w_value))
         else:
             try:
-                buf = space.buffer_w(w_value)
+                buf = space.charbuf_w(w_value)
             except OperationError, e:
                 if not e.match(space, space.w_TypeError):
                     raise
@@ -520,8 +520,7 @@
                             "long() argument must be a string or a number, "
                             "not '%T'", w_value)
             else:
-                return _string_to_w_long(space, w_longtype, w_value,
-                                         buf.as_str())
+                return _string_to_w_long(space, w_longtype, w_value, buf)
     else:
         base = space.int_w(w_base)
 
diff --git a/pypy/objspace/std/memoryview.py b/pypy/objspace/std/memoryview.py
--- a/pypy/objspace/std/memoryview.py
+++ b/pypy/objspace/std/memoryview.py
@@ -40,9 +40,18 @@
         assert isinstance(buf, buffer.Buffer)
         self.buf = buf
 
-    def buffer_w(self, space):
+    def buffer_w(self, space, flags):
         return self.buf
 
+    def readbuf_w(self, space):
+        return self.buf
+
+    def writebuf_w(self, space):
+        return self.buf
+
+    def charbuf_w(self, space):
+        return self.buf.as_str()
+
     @staticmethod
     @unwrap_spec(offset=int, size=int)
     def descr_new_buffer(space, w_subtype, w_object, offset=0, size=-1):
@@ -57,7 +66,7 @@
             from pypy.interpreter.buffer import StringBuffer
             buf = StringBuffer(builder.build())
         else:
-            buf = space.buffer_w(w_object)
+            buf = space.readbuf_w(w_object)
 
         if offset == 0 and size == -1:
             return W_Buffer(buf)
@@ -175,20 +184,12 @@
         assert isinstance(buf, buffer.Buffer)
         self.buf = buf
 
-    def buffer_w(self, space):
-        """
-        Note that memoryview() is very inconsistent in CPython: it does not
-        support the buffer interface but does support the new buffer
-        interface: as a result, it is possible to pass memoryview to
-        e.g. socket.send() but not to file.write().  For simplicity and
-        consistency, in PyPy memoryview DOES support buffer(), which means
-        that it is accepted in more places than CPython.
-        """
+    def buffer_w(self, space, flags):
         return self.buf
 
     @staticmethod
     def descr_new_memoryview(space, w_subtype, w_object):
-        return W_MemoryView(space.buffer_w(w_object))
+        return W_MemoryView(space.buffer_w(w_object, space.BUF_FULL_RO))
 
     def _make_descr__cmp(name):
         def descr__cmp(self, space, w_other):
@@ -199,7 +200,7 @@
                 return space.wrap(getattr(operator, name)(str1, str2))
 
             try:
-                buf = space.buffer_w(w_other)
+                buf = space.buffer_w(w_other, space.BUF_CONTIG_RO)
             except OperationError, e:
                 if not e.match(space, space.w_TypeError):
                     raise
diff --git a/pypy/objspace/std/strbufobject.py b/pypy/objspace/std/strbufobject.py
--- a/pypy/objspace/std/strbufobject.py
+++ b/pypy/objspace/std/strbufobject.py
@@ -36,7 +36,10 @@
     def str_w(self, space):
         return self.force()
 
-    def buffer_w(self, space):
+    def buffer_w(self, space, flags):
+        return StringBuffer(self.force())
+
+    def readbuf_w(self, space):
         return StringBuffer(self.force())
 
     def descr_len(self, space):
diff --git a/pypy/objspace/std/test/test_bytesobject.py b/pypy/objspace/std/test/test_bytesobject.py
--- a/pypy/objspace/std/test/test_bytesobject.py
+++ b/pypy/objspace/std/test/test_bytesobject.py
@@ -634,7 +634,8 @@
 
         table = maketrans('abc', 'xyz')
         assert 'xyzxyz' == 'xyzabcdef'.translate(table, 'def')
-        assert 'xyzxyz' == 'xyzabcdef'.translate(memoryview(table), 'def')
+        exc = raises(TypeError, "'xyzabcdef'.translate(memoryview(table), 'def')")
+        assert 'character buffer' in str(exc.value)
 
         table = maketrans('a', 'A')
         assert 'Abc' == 'abc'.translate(table)
diff --git a/pypy/objspace/std/test/test_strbufobject.py b/pypy/objspace/std/test/test_strbufobject.py
--- a/pypy/objspace/std/test/test_strbufobject.py
+++ b/pypy/objspace/std/test/test_strbufobject.py
@@ -44,6 +44,11 @@
         assert len(r) == 2
         assert len(t) == 4
 
+    def test_buffer(self):
+        s = 'a'.__add__('b')
+        assert buffer(s) == buffer('ab')
+        assert memoryview(s) == 'ab'
+
     def test_add_strbuf(self):
         # make three strbuf objects
         s = 'a'.__add__('b')


More information about the pypy-commit mailing list