[pypy-svn] r77454 - in pypy/branch/fast-forward/pypy/objspace/std: . test

afa at codespeak.net afa at codespeak.net
Tue Sep 28 16:28:03 CEST 2010


Author: afa
Date: Tue Sep 28 16:28:01 2010
New Revision: 77454

Added:
   pypy/branch/fast-forward/pypy/objspace/std/bytearrayobject.py
   pypy/branch/fast-forward/pypy/objspace/std/bytearraytype.py
   pypy/branch/fast-forward/pypy/objspace/std/test/test_bytes.py
Modified:
   pypy/branch/fast-forward/pypy/objspace/std/model.py
Log:
First implementation of a bytearray object.
For now, it's a non mutable array of chars...


Added: pypy/branch/fast-forward/pypy/objspace/std/bytearrayobject.py
==============================================================================
--- (empty file)
+++ pypy/branch/fast-forward/pypy/objspace/std/bytearrayobject.py	Tue Sep 28 16:28:01 2010
@@ -0,0 +1,192 @@
+from pypy.interpreter.error import OperationError
+from pypy.objspace.std.model import registerimplementation, W_Object
+from pypy.objspace.std.register_all import register_all
+from pypy.objspace.std.inttype import wrapint
+from pypy.objspace.std.multimethod import FailedToImplement
+from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.rstring import StringBuilder
+from pypy.objspace.std.intobject import W_IntObject
+from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
+from pypy.objspace.std import slicetype
+from pypy.interpreter import gateway
+
+class W_BytearrayObject(W_Object):
+    from pypy.objspace.std.bytearraytype import bytearray_typedef as typedef
+
+    def __init__(w_self, data):
+        w_self.data = list(data)
+
+    def __repr__(w_self):
+        """ representation for debugging purposes """
+        return "%s(%s)" % (w_self.__class__.__name__, ''.join(w_self.data))
+
+    def unwrap(w_bytearray, space):
+        return bytearray(w_self.data)
+
+registerimplementation(W_BytearrayObject)
+
+
+def len__Bytearray(space, w_bytearray):
+    result = len(w_bytearray.data)
+    return wrapint(space, result)
+
+def getitem__Bytearray_ANY(space, w_bytearray, w_index):
+    # getindex_w should get a second argument space.w_IndexError,
+    # but that doesn't exist the first time this is called.
+    try:
+        w_IndexError = space.w_IndexError
+    except AttributeError:
+        w_IndexError = None
+    index = space.getindex_w(w_index, w_IndexError, "bytearray index")
+    try:
+        return space.newint(ord(w_bytearray.data[index]))
+    except IndexError:
+        raise OperationError(space.w_IndexError,
+                             space.wrap("bytearray index out of range"))
+
+def getitem__Bytearray_Slice(space, w_bytearray, w_slice):
+    data = w_bytearray.data
+    length = len(data)
+    start, stop, step, slicelength = w_slice.indices4(space, length)
+    assert slicelength >= 0
+    return W_BytearrayObject(data[start:stop:step])
+
+def getslice__Bytearray_ANY_ANY(space, w_bytearray, w_start, w_stop):
+    length = len(w_bytearray.data)
+    start, stop = normalize_simple_slice(space, length, w_start, w_stop)
+    return W_BytearrayObject(w_bytearray.data[start:stop])
+
+def contains__Bytearray_Int(space, w_bytearray, w_char):
+    char = w_char.intval
+    if not 0 <= char < 256:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("byte must be in range(0, 256)"))
+    for c in w_bytearray.data:
+        if ord(c) == char:
+            return space.w_True
+    return space.w_False
+
+def add__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2):
+    data1 = w_bytearray1.data
+    data2 = w_bytearray2.data
+    return W_BytearrayObject(data1 + data2)
+
+def mul_bytearray_times(space, w_bytearray, w_times):
+    try:
+        times = space.getindex_w(w_times, space.w_OverflowError)
+    except OperationError, e:
+        if e.match(space, space.w_TypeError):
+            raise FailedToImplement
+        raise
+    if times == 1 and space.type(w_bytearray) == space.w_bytearray:
+        return w_bytearray
+    data = w_bytearray.data
+    return W_BytearrayObject(data * times)
+
+def mul__Bytearray_ANY(space, w_bytearray, w_times):
+    return mul_bytearray_times(space, w_bytearray, w_times)
+
+def mul__ANY_Bytearray(space, w_times, w_bytearray):
+    return mul_bytearray_times(space, w_bytearray, w_times)
+
+def eq__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2):
+    data1 = w_bytearray1.data
+    data2 = w_bytearray2.data
+    if len(data1) != len(data2):
+        return space.w_False
+    for i in range(len(data1)):
+        if data1[i] != data2[i]:
+            return space.w_False
+    return space.w_True
+
+def _min(a, b):
+    if a < b:
+        return a
+    return b
+
+def lt__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2):
+    data1 = w_bytearray1.data
+    data2 = w_bytearray2.data
+    ncmp = _min(len(data1), len(data2))
+    # Search for the first index where items are different
+    for p in range(ncmp):
+        if data1[p] != data2[p]:
+            return space.newbool(data1[p] < data2[p])
+    # No more items to compare -- compare sizes
+    return space.newbool(len(data1) < len(data2))
+
+def gt__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2):
+    data1 = w_bytearray1.data
+    data2 = w_bytearray2.data
+    ncmp = _min(len(data1), len(data2))
+    # Search for the first index where items are different
+    for p in range(ncmp):
+        if data1[p] != data2[p]:
+            return space.newbool(data1[p] > data2[p])
+    # No more items to compare -- compare sizes
+    return space.newbool(len(data1) > len(data2))
+
+# Mostly copied from repr__String, but without the "smart quote"
+# functionality.
+def repr__Bytearray(space, w_bytearray):
+    s = w_bytearray.data
+
+    buf = StringBuilder(50)
+
+    buf.append("bytearray(b'")
+
+    for i in range(len(s)):
+        c = s[i]
+
+        if c == '\\' or c == "'":
+            buf.append('\\')
+            buf.append(c)
+        elif c == '\t':
+            buf.append('\\t')
+        elif c == '\r':
+            buf.append('\\r')
+        elif c == '\n':
+            buf.append('\\n')
+        elif not '\x20' <= c < '\x7f':
+            n = ord(c)
+            buf.append('\\x')
+            buf.append("0123456789abcdef"[n>>4])
+            buf.append("0123456789abcdef"[n&0xF])
+        else:
+            buf.append(c)
+
+    buf.append("')")
+
+    return space.wrap(buf.build())
+
+def getnewargs__Bytearray(space, w_bytearray):
+    return space.newbytearray([W_BytearrayObject(w_bytearray.wrappeditems)])
+
+def bytearray_count__Bytearray_ANY(space, w_bytearray, w_obj):
+    count = 0
+    for w_item in w_bytearray.wrappeditems:
+        if space.eq_w(w_item, w_obj):
+            count += 1
+    return space.wrap(count)
+
+def bytearray_index__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_obj, w_start, w_stop):
+    start = slicetype._Eval_SliceIndex(space, w_start)
+    stop = slicetype._Eval_SliceIndex(space, w_stop)
+    length = len(w_bytearray.wrappeditems)
+    if start < 0:
+        start += length
+        if start < 0:
+            start = 0
+    if stop < 0:
+        stop += length
+        if stop < 0:
+            stop = 0
+    for i in range(start, min(stop, length)):
+        w_item = w_bytearray.wrappeditems[i]
+        if space.eq_w(w_item, w_obj):
+            return space.wrap(i)
+    raise OperationError(space.w_ValueError,
+                         space.wrap("bytearray.index(x): x not in bytearray"))
+
+from pypy.objspace.std import bytearraytype
+register_all(vars(), bytearraytype)

Added: pypy/branch/fast-forward/pypy/objspace/std/bytearraytype.py
==============================================================================
--- (empty file)
+++ pypy/branch/fast-forward/pypy/objspace/std/bytearraytype.py	Tue Sep 28 16:28:01 2010
@@ -0,0 +1,41 @@
+import sys
+from pypy.interpreter import gateway
+from pypy.interpreter.baseobjspace import ObjSpace, W_Root
+from pypy.objspace.std.register_all import register_all
+from pypy.objspace.std.stdtypedef import StdTypeDef, SMM, no_hash_descr
+
+
+bytearray_count = SMM(
+    "count", 2,
+    doc="B.count(sub [,start [,end]]) -> int\n"
+    "Return the number of non-overlapping occurrences of subsection sub in\n"
+    "bytes B[start:end].  Optional arguments start and end are interpreted\n"
+    "as in slice notation.")
+
+bytearray_index = SMM("index", 4, defaults=(0, sys.maxint),
+                  doc="index(obj, [start, [stop]]) -> first index that obj "
+                  "appears in the bytearray")
+
+ at gateway.unwrap_spec(ObjSpace, W_Root, W_Root, W_Root, W_Root)
+def descr__new__(space, w_bytearraytype,
+                 w_source='', w_encoding=None, w_errors=None):
+    from pypy.objspace.std.bytearrayobject import W_BytearrayObject
+    if w_source is None:
+        data = []
+    else:
+        data = space.str_w(w_source)
+    w_obj = space.allocate_instance(W_BytearrayObject, w_bytearraytype)
+    W_BytearrayObject.__init__(w_obj, data)
+    return w_obj
+
+# ____________________________________________________________
+
+bytearray_typedef = StdTypeDef("bytearray",
+    __doc__ = '''bytearray() -> an empty bytearray
+bytearray(sequence) -> bytearray initialized from sequence\'s items
+
+If the argument is a bytearray, the return value is the same object.''',
+    __new__ = gateway.interp2app(descr__new__),
+    __hash__ = no_hash_descr,
+    )
+bytearray_typedef.registermethods(globals())

Modified: pypy/branch/fast-forward/pypy/objspace/std/model.py
==============================================================================
--- pypy/branch/fast-forward/pypy/objspace/std/model.py	(original)
+++ pypy/branch/fast-forward/pypy/objspace/std/model.py	Tue Sep 28 16:28:01 2010
@@ -47,6 +47,7 @@
             from pypy.objspace.std.dicttype   import dict_typedef
             from pypy.objspace.std.basestringtype import basestring_typedef
             from pypy.objspace.std.stringtype import str_typedef
+            from pypy.objspace.std.bytearraytype import bytearray_typedef
             from pypy.objspace.std.typetype   import type_typedef
             from pypy.objspace.std.slicetype  import slice_typedef
             from pypy.objspace.std.longtype   import long_typedef
@@ -71,6 +72,7 @@
         from pypy.objspace.std import listobject
         from pypy.objspace.std import dictmultiobject
         from pypy.objspace.std import stringobject
+        from pypy.objspace.std import bytearrayobject
         from pypy.objspace.std import ropeobject
         from pypy.objspace.std import ropeunicodeobject
         from pypy.objspace.std import strsliceobject
@@ -102,6 +104,7 @@
             dictmultiobject.W_DictMultiObject: [],
             dictmultiobject.W_DictMultiIterObject: [],
             stringobject.W_StringObject: [],
+            bytearrayobject.W_BytearrayObject: [],
             typeobject.W_TypeObject: [],
             sliceobject.W_SliceObject: [],
             longobject.W_LongObject: [],

Added: pypy/branch/fast-forward/pypy/objspace/std/test/test_bytes.py
==============================================================================
--- (empty file)
+++ pypy/branch/fast-forward/pypy/objspace/std/test/test_bytes.py	Tue Sep 28 16:28:01 2010
@@ -0,0 +1,43 @@
+
+class AppTestBytesArray:
+    def test_basics(self):
+        b = bytearray()
+        assert type(b) is bytearray
+        assert b.__class__ is bytearray
+
+    def test_len(self):
+        b = bytearray('test')
+        assert len(b) == 4
+
+    def test_nohash(self):
+        raises(TypeError, hash, bytearray())
+
+    def test_repr(self):
+        assert repr(bytearray()) == "bytearray(b'')"
+        assert repr(bytearray('test')) == "bytearray(b'test')"
+        assert repr(bytearray("d'oh")) == r"bytearray(b'd\'oh')"
+
+    def test_getitem(self):
+        b = bytearray('test')
+        assert b[0] == ord('t')
+        assert b[2] == ord('s')
+        raises(IndexError, b.__getitem__, 4)
+        assert b[1:5] == bytearray('est')
+        assert b[slice(1,5)] == bytearray('est')
+
+    def test_arithmetic(self):
+        b1 = bytearray('hello ')
+        b2 = bytearray('world')
+        assert b1 + b2 == bytearray('hello world')
+        assert b1 * 2 == bytearray('hello hello ')
+
+    def test_contains(self):
+        assert ord('l') in bytearray('hello')
+
+    def test_iter(self):
+        assert list(bytearray('hello')) == [104, 101, 108, 108, 111]
+
+    def test_compare(self):
+        assert bytearray('hello') < bytearray('world')
+        assert bytearray('world') > bytearray('hello')
+



More information about the Pypy-commit mailing list