[pypy-svn] pypy bytearray: (lac, mfoord) bytearray initialisation now done in __init__ not __new__

mfoord commits-noreply at bitbucket.org
Thu Jan 20 13:44:45 CET 2011


Author: Michael Foord <michael at voidspace.org.uk>
Branch: bytearray
Changeset: r41012:0ca36383f0be
Date: 2011-01-20 13:42 +0100
http://bitbucket.org/pypy/pypy/changeset/0ca36383f0be/

Log:	(lac, mfoord) bytearray initialisation now done in __init__ not
	__new__ bytearray.__new__ takes arbitrary args to allow subclassing
	and overriding __init__ only

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
@@ -18,6 +18,7 @@
 from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
 from pypy.objspace.std import slicetype
 from pypy.interpreter import gateway
+from pypy.interpreter.argument import Signature
 from pypy.interpreter.buffer import RWBuffer
 from pypy.objspace.std.bytearraytype import (
     makebytearraydata_w, getbytevalue,
@@ -44,6 +45,45 @@
 
 registerimplementation(W_BytearrayObject)
 
+init_signature = Signature(['source', 'encoding', 'errors'], None, None)
+init_defaults = [None, None, None]
+
+def init__Bytearray(space, w_bytearray, __args__):
+    # this is on the silly side
+    w_source, w_encoding, w_errors = __args__.parse_obj(
+            None, 'bytearray', init_signature, init_defaults)
+
+    if w_source is None:
+        w_source = space.wrap('')
+    if w_encoding is None:
+        w_encoding = space.w_None
+    if w_errors is None:
+        w_errors = space.w_None
+
+    # Unicode argument
+    if not space.is_w(w_encoding, space.w_None):
+        from pypy.objspace.std.unicodetype import (
+            _get_encoding_and_errors, encode_object
+        )
+        encoding, errors = _get_encoding_and_errors(space, w_encoding, w_errors)
+
+        # if w_source is an integer this correctly raises a TypeError
+        # the CPython error message is: "encoding or errors without a string argument"
+        # ours is: "expected unicode, got int object"
+        w_source = encode_object(space, w_source, encoding, errors)
+
+    # Is it an int?
+    try:
+        count = space.int_w(w_source)
+    except OperationError, e:
+        if not e.match(space, space.w_TypeError):
+            raise
+    else:
+        w_bytearray.data[:] = ['\0'] * count
+        return
+
+    data = makebytearraydata_w(space, w_source)
+    w_bytearray.data[:] = data
 
 def len__Bytearray(space, w_bytearray):
     result = len(w_bytearray.data)

diff --git a/pypy/objspace/std/test/test_bytes.py b/pypy/objspace/std/test/test_bytes.py
--- a/pypy/objspace/std/test/test_bytes.py
+++ b/pypy/objspace/std/test/test_bytes.py
@@ -15,6 +15,13 @@
         raises(ValueError, bytearray, [65, -3])
         raises(TypeError, bytearray, [65.0])
 
+    def test_init_override(self):
+        class subclass(bytearray):
+            def __init__(self, newarg=1, *args, **kwargs):
+                bytearray.__init__(self, *args, **kwargs)
+        x = subclass(4, source="abcd")
+        assert x == "abcd"
+
     def test_encoding(self):
         data = u"Hello world\n\u1234\u5678\u9abc\def0\def0"
         for encoding in 'utf8', 'utf16':

diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py
--- a/pypy/objspace/std/bytearraytype.py
+++ b/pypy/objspace/std/bytearraytype.py
@@ -72,33 +72,10 @@
     W_BytearrayObject.__init__(w_obj, data)
     return w_obj
 
- 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):
-    # Unicode argument
-    if not space.is_w(w_encoding, space.w_None):
-        from pypy.objspace.std.unicodetype import (
-            _get_encoding_and_errors, encode_object
-        )
-        encoding, errors = _get_encoding_and_errors(space, w_encoding, w_errors)
 
-        # if w_source is an integer this correctly raises a TypeError
-        # the CPython error message is: "encoding or errors without a string argument"
-        # ours is: "expected unicode, got int object"
-        w_source = encode_object(space, w_source, encoding, errors)
+def descr__new__(space, w_bytearraytype, __args__):
+    return new_bytearray(space,w_bytearraytype, [])
 
-    # Is it an int?
-    try:
-        count = space.int_w(w_source)
-    except OperationError, e:
-        if not e.match(space, space.w_TypeError):
-            raise
-    else:
-        data = ['\0'] * count
-        return new_bytearray(space, w_bytearraytype, data)
-
-    data = makebytearraydata_w(space, w_source)
-    return new_bytearray(space, w_bytearraytype, data)
 
 def makebytearraydata_w(space, w_source):
     # String-like argument
@@ -187,7 +164,9 @@
 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__),
+    __new__ = gateway.interp2app(descr__new__, unwrap_spec=[gateway.ObjSpace,
+                                               gateway.W_Root,
+                                               gateway.Arguments]),
     __hash__ = None,
     __reduce__ = gateway.interp2app(descr_bytearray__reduce__),
     fromhex = gateway.interp2app(descr_fromhex, as_classmethod=True)


More information about the Pypy-commit mailing list