[pypy-commit] pypy refactor-translator: hg merge default

Manuel Jacob noreply at buildbot.pypy.org
Sun Jan 19 21:03:20 CET 2014


Author: Manuel Jacob
Branch: refactor-translator
Changeset: r68768:9a92c5bf6242
Date: 2014-01-19 17:29 +0100
http://bitbucket.org/pypy/pypy/changeset/9a92c5bf6242/

Log:	hg merge default

diff too long, truncating to 2000 out of 10346 lines

diff --git a/lib-python/2.7/test/test_memoryview.py b/lib-python/2.7/test/test_memoryview.py
--- a/lib-python/2.7/test/test_memoryview.py
+++ b/lib-python/2.7/test/test_memoryview.py
@@ -166,11 +166,18 @@
             self.assertTrue(m[0:6] == m[:])
             self.assertFalse(m[0:5] == m)
 
-            # Comparison with objects which don't support the buffer API
-            self.assertFalse(m == u"abcdef")
-            self.assertTrue(m != u"abcdef")
-            self.assertFalse(u"abcdef" == m)
-            self.assertTrue(u"abcdef" != m)
+            if test_support.check_impl_detail(cpython=True):
+                # what is supported and what is not supported by memoryview is
+                # very inconsisten on CPython. In PyPy, memoryview supports
+                # the buffer interface, and thus the following comparison
+                # succeeds. See also the comment in
+                # pypy.modules.__builtin__.interp_memoryview.W_MemoryView.descr_buffer
+                #
+                # Comparison with objects which don't support the buffer API
+                self.assertFalse(m == u"abcdef", "%s %s" % (self, tp))
+                self.assertTrue(m != u"abcdef")
+                self.assertFalse(u"abcdef" == m)
+                self.assertTrue(u"abcdef" != m)
 
             # Unordered comparisons are unimplemented, and therefore give
             # arbitrary results (they raise a TypeError in py3k)
diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py
--- a/lib_pypy/_ctypes/array.py
+++ b/lib_pypy/_ctypes/array.py
@@ -20,10 +20,13 @@
                     # we don't want to have buffers here
                     if len(val) > self._length_:
                         raise ValueError("%r too long" % (val,))
-                    for i in range(len(val)):
-                        self[i] = val[i]
+                    if isinstance(val, str):
+                        _rawffi.rawstring2charp(self._buffer.buffer, val)
+                    else:
+                        for i in range(len(val)):
+                            self[i] = val[i]
                     if len(val) < self._length_:
-                        self[len(val)] = '\x00'
+                        self._buffer[len(val)] = '\x00'
                 res.value = property(getvalue, setvalue)
 
                 def getraw(self):
@@ -33,8 +36,7 @@
                 def setraw(self, buffer):
                     if len(buffer) > self._length_:
                         raise ValueError("%r too long" % (buffer,))
-                    for i in range(len(buffer)):
-                        self[i] = buffer[i]
+                    _rawffi.rawstring2charp(self._buffer.buffer, buffer)
                 res.raw = property(getraw, setraw)
             elif subletter == 'u':
                 def getvalue(self):
@@ -45,10 +47,14 @@
                     # we don't want to have buffers here
                     if len(val) > self._length_:
                         raise ValueError("%r too long" % (val,))
+                    if isinstance(val, unicode):
+                        target = self._buffer
+                    else:
+                        target = self
                     for i in range(len(val)):
-                        self[i] = val[i]
+                        target[i] = val[i]
                     if len(val) < self._length_:
-                        self[len(val)] = '\x00'
+                        target[len(val)] = u'\x00'
                 res.value = property(getvalue, setvalue)
                 
             if '_length_' in typedict:
diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst
--- a/pypy/doc/project-ideas.rst
+++ b/pypy/doc/project-ideas.rst
@@ -74,6 +74,10 @@
 The actual details would be rather differen in PyPy, but we would like to have
 the same optimization implemented.
 
+Or maybe not.  We can also play around with the idea of using a single
+representation: as a byte string in utf-8.  (This idea needs some extra logic
+for efficient indexing, like a cache.)
+
 .. _`optimized unicode representation`: http://www.python.org/dev/peps/pep-0393/
 
 Translation Toolchain
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -41,3 +41,6 @@
 Fix 3 broken links on PyPy published papers in docs.
 
 .. branch: jit-ordereddict
+
+.. branch: refactor-str-types
+Remove multimethods on str/unicode/bytearray and make the implementations share code.
diff --git a/pypy/goal/getnightly.py b/pypy/goal/getnightly.py
--- a/pypy/goal/getnightly.py
+++ b/pypy/goal/getnightly.py
@@ -26,7 +26,12 @@
 if branch == 'default':
     branch = 'trunk'
 
-filename = 'pypy-c-jit-latest-%s.tar.bz2' % arch
+if '--nojit' in sys.argv:
+    kind = 'nojit'
+else:
+    kind = 'jit'
+
+filename = 'pypy-c-%s-latest-%s.tar.bz2' % (kind, arch)
 url = 'http://buildbot.pypy.org/nightly/%s/%s' % (branch, filename)
 tmp = py.path.local.mkdtemp()
 mydir = tmp.chdir()
diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -1234,6 +1234,8 @@
             flags |= consts.CO_NESTED
         if scope.is_generator:
             flags |= consts.CO_GENERATOR
+        if scope.has_yield_inside_try:
+            flags |= consts.CO_YIELD_INSIDE_TRY
         if scope.has_variable_arg:
             flags |= consts.CO_VARARGS
         if scope.has_keywords_arg:
diff --git a/pypy/interpreter/astcompiler/consts.py b/pypy/interpreter/astcompiler/consts.py
--- a/pypy/interpreter/astcompiler/consts.py
+++ b/pypy/interpreter/astcompiler/consts.py
@@ -17,6 +17,7 @@
 CO_FUTURE_UNICODE_LITERALS = 0x20000
 #pypy specific:
 CO_KILL_DOCSTRING = 0x100000
+CO_YIELD_INSIDE_TRY = 0x200000
 
 PyCF_SOURCE_IS_UTF8 = 0x0100
 PyCF_DONT_IMPLY_DEDENT = 0x0200
diff --git a/pypy/interpreter/astcompiler/symtable.py b/pypy/interpreter/astcompiler/symtable.py
--- a/pypy/interpreter/astcompiler/symtable.py
+++ b/pypy/interpreter/astcompiler/symtable.py
@@ -43,6 +43,7 @@
         self.child_has_free = False
         self.nested = False
         self.doc_removable = False
+        self._in_try_body_depth = 0
 
     def lookup(self, name):
         """Find the scope of identifier 'name'."""
@@ -75,6 +76,14 @@
             self.varnames.append(mangled)
         return mangled
 
+    def note_try_start(self, try_node):
+        """Called when a try is found, before visiting the body."""
+        self._in_try_body_depth += 1
+
+    def note_try_end(self, try_node):
+        """Called after visiting a try body."""
+        self._in_try_body_depth -= 1
+
     def note_yield(self, yield_node):
         """Called when a yield is found."""
         raise SyntaxError("'yield' outside function", yield_node.lineno,
@@ -210,6 +219,7 @@
         self.has_variable_arg = False
         self.has_keywords_arg = False
         self.is_generator = False
+        self.has_yield_inside_try = False
         self.optimized = True
         self.return_with_value = False
         self.import_star = None
@@ -220,6 +230,8 @@
             raise SyntaxError("'return' with argument inside generator",
                               self.ret.lineno, self.ret.col_offset)
         self.is_generator = True
+        if self._in_try_body_depth > 0:
+            self.has_yield_inside_try = True
 
     def note_return(self, ret):
         if ret.value:
@@ -463,7 +475,12 @@
         self.scope.new_temporary_name()
         if wih.optional_vars:
             self.scope.new_temporary_name()
-        ast.GenericASTVisitor.visit_With(self, wih)
+        wih.context_expr.walkabout(self)
+        if wih.optional_vars:
+            wih.optional_vars.walkabout(self)
+        self.scope.note_try_start(wih)
+        self.visit_sequence(wih.body)
+        self.scope.note_try_end(wih)
 
     def visit_arguments(self, arguments):
         scope = self.scope
@@ -505,3 +522,16 @@
         else:
             role = SYM_ASSIGNED
         self.note_symbol(name.id, role)
+
+    def visit_TryExcept(self, node):
+        self.scope.note_try_start(node)
+        self.visit_sequence(node.body)
+        self.scope.note_try_end(node)
+        self.visit_sequence(node.handlers)
+        self.visit_sequence(node.orelse)
+
+    def visit_TryFinally(self, node):
+        self.scope.note_try_start(node)
+        self.visit_sequence(node.body)
+        self.scope.note_try_end(node)
+        self.visit_sequence(node.finalbody)
diff --git a/pypy/interpreter/astcompiler/test/test_symtable.py b/pypy/interpreter/astcompiler/test/test_symtable.py
--- a/pypy/interpreter/astcompiler/test/test_symtable.py
+++ b/pypy/interpreter/astcompiler/test/test_symtable.py
@@ -346,6 +346,25 @@
             assert exc.msg == "'return' with argument inside generator"
         scp = self.func_scope("def f():\n    return\n    yield x")
 
+    def test_yield_inside_try(self):
+        scp = self.func_scope("def f(): yield x")
+        assert not scp.has_yield_inside_try
+        scp = self.func_scope("def f():\n  try:\n    yield x\n  except: pass")
+        assert scp.has_yield_inside_try
+        scp = self.func_scope("def f():\n  try:\n    yield x\n  finally: pass")
+        assert scp.has_yield_inside_try
+        scp = self.func_scope("def f():\n    with x: yield y")
+        assert scp.has_yield_inside_try
+
+    def test_yield_outside_try(self):
+        for input in ("try: pass\n    except: pass",
+                      "try: pass\n    except: yield y",
+                      "try: pass\n    finally: pass",
+                      "try: pass\n    finally: yield y",
+                      "with x: pass"):
+            input = "def f():\n    yield y\n    %s\n    yield y" % (input,)
+            assert not self.func_scope(input).has_yield_inside_try
+
     def test_return(self):
         for input in ("class x: return", "return"):
             exc = py.test.raises(SyntaxError, self.func_scope, input).value
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -231,6 +231,11 @@
         msg = "__int__ returned non-int (type '%T')"
         raise operationerrfmt(space.w_TypeError, msg, w_result)
 
+    def ord(self, space):
+        typename = space.type(self).getname(space)
+        msg = "ord() expected string of length 1, but %s found"
+        raise operationerrfmt(space.w_TypeError, msg, typename)
+
     def __spacebind__(self, space):
         return self
 
@@ -1396,6 +1401,9 @@
         # This is here mostly just for gateway.int_unwrapping_space_method().
         return bool(self.int_w(w_obj))
 
+    def ord(self, w_obj):
+        return w_obj.ord(self)
+
     # This is all interface for gateway.py.
     def gateway_int_w(self, w_obj):
         if self.isinstance_w(w_obj, self.w_float):
diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py
--- a/pypy/interpreter/gateway.py
+++ b/pypy/interpreter/gateway.py
@@ -520,12 +520,13 @@
     # When a BuiltinCode is stored in a Function object,
     # you get the functionality of CPython's built-in function type.
 
-    def __init__(self, func, unwrap_spec=None, self_type=None, descrmismatch=None):
+    def __init__(self, func, unwrap_spec=None, self_type=None,
+                 descrmismatch=None, doc=None):
         "NOT_RPYTHON"
         # 'implfunc' is the interpreter-level function.
         # Note that this uses a lot of (construction-time) introspection.
         Code.__init__(self, func.__name__)
-        self.docstring = func.__doc__
+        self.docstring = doc or func.__doc__
 
         self.identifier = "%s-%s-%s" % (func.__module__, func.__name__,
                                         getattr(self_type, '__name__', '*'))
@@ -832,7 +833,7 @@
     instancecache = {}
 
     def __new__(cls, f, app_name=None, unwrap_spec=None, descrmismatch=None,
-                as_classmethod=False):
+                as_classmethod=False, doc=None):
 
         "NOT_RPYTHON"
         # f must be a function whose name does NOT start with 'app_'
@@ -861,7 +862,8 @@
         cls.instancecache[key] = self
         self._code = BuiltinCode(f, unwrap_spec=unwrap_spec,
                                  self_type=self_type,
-                                 descrmismatch=descrmismatch)
+                                 descrmismatch=descrmismatch,
+                                 doc=doc)
         self.__name__ = f.func_name
         self.name = app_name
         self.as_classmethod = as_classmethod
diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -155,20 +155,6 @@
         code_name = self.pycode.co_name
         return space.wrap(code_name)
 
-    def __del__(self):
-        # Only bother enqueuing self to raise an exception if the frame is
-        # still not finished and finally or except blocks are present.
-        self.clear_all_weakrefs()
-        if self.frame is not None:
-            block = self.frame.lastblock
-            while block is not None:
-                if not isinstance(block, LoopBlock):
-                    self.enqueue_for_destruction(self.space,
-                                                 GeneratorIterator.descr_close,
-                                                 "interrupting generator of ")
-                    break
-                block = block.previous
-
     # Results can be either an RPython list of W_Root, or it can be an
     # app-level W_ListObject, which also has an append() method, that's why we
     # generate 2 versions of the function and 2 jit drivers.
@@ -211,3 +197,20 @@
         return unpack_into
     unpack_into = _create_unpack_into()
     unpack_into_w = _create_unpack_into()
+
+
+class GeneratorIteratorWithDel(GeneratorIterator):
+
+    def __del__(self):
+        # Only bother enqueuing self to raise an exception if the frame is
+        # still not finished and finally or except blocks are present.
+        self.clear_all_weakrefs()
+        if self.frame is not None:
+            block = self.frame.lastblock
+            while block is not None:
+                if not isinstance(block, LoopBlock):
+                    self.enqueue_for_destruction(self.space,
+                                                 GeneratorIterator.descr_close,
+                                                 "interrupting generator of ")
+                    break
+                block = block.previous
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -12,7 +12,7 @@
 from pypy.interpreter.gateway import unwrap_spec
 from pypy.interpreter.astcompiler.consts import (
     CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED,
-    CO_GENERATOR, CO_KILL_DOCSTRING)
+    CO_GENERATOR, CO_KILL_DOCSTRING, CO_YIELD_INSIDE_TRY)
 from pypy.tool.stdlib_opcode import opcodedesc, HAVE_ARGUMENT
 from rpython.rlib.rarithmetic import intmask
 from rpython.rlib.objectmodel import compute_hash
@@ -31,7 +31,7 @@
 # Magic numbers for the bytecode version in code objects.
 # See comments in pypy/module/imp/importing.
 cpython_magic, = struct.unpack("<i", imp.get_magic())   # host magic number
-default_magic = (0xf303 + 6) | 0x0a0d0000               # this PyPy's magic
+default_magic = (0xf303 + 7) | 0x0a0d0000               # this PyPy's magic
                                                         # (from CPython 2.7.0)
 
 # cpython_code_signature helper
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -167,8 +167,12 @@
     def run(self):
         """Start this frame's execution."""
         if self.getcode().co_flags & pycode.CO_GENERATOR:
-            from pypy.interpreter.generator import GeneratorIterator
-            return self.space.wrap(GeneratorIterator(self))
+            if self.getcode().co_flags & pycode.CO_YIELD_INSIDE_TRY:
+                from pypy.interpreter.generator import GeneratorIteratorWithDel
+                return self.space.wrap(GeneratorIteratorWithDel(self))
+            else:
+                from pypy.interpreter.generator import GeneratorIterator
+                return self.space.wrap(GeneratorIterator(self))
         else:
             return self.execute_frame()
 
diff --git a/pypy/interpreter/test/test_gateway.py b/pypy/interpreter/test/test_gateway.py
--- a/pypy/interpreter/test/test_gateway.py
+++ b/pypy/interpreter/test/test_gateway.py
@@ -708,6 +708,18 @@
             never_called
         py.test.raises(AssertionError, space.wrap, gateway.interp2app_temp(g))
 
+    def test_interp2app_doc(self):
+        space = self.space
+        def f(space, w_x):
+            """foo"""
+        w_f = space.wrap(gateway.interp2app_temp(f))
+        assert space.unwrap(space.getattr(w_f, space.wrap('__doc__'))) == 'foo'
+        #
+        def g(space, w_x):
+            never_called
+        w_g = space.wrap(gateway.interp2app_temp(g, doc='bar'))
+        assert space.unwrap(space.getattr(w_g, space.wrap('__doc__'))) == 'bar'
+
 
 class AppTestPyTestMark:
     @py.test.mark.unlikely_to_exist
diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py
--- a/pypy/interpreter/unicodehelper.py
+++ b/pypy/interpreter/unicodehelper.py
@@ -30,7 +30,7 @@
 # ____________________________________________________________
 
 def encode(space, w_data, encoding=None, errors='strict'):
-    from pypy.objspace.std.unicodetype import encode_object
+    from pypy.objspace.std.unicodeobject import encode_object
     return encode_object(space, w_data, encoding, errors)
 
 # These functions take and return unwrapped rpython strings and unicodes
diff --git a/pypy/module/__builtin__/interp_memoryview.py b/pypy/module/__builtin__/interp_memoryview.py
--- a/pypy/module/__builtin__/interp_memoryview.py
+++ b/pypy/module/__builtin__/interp_memoryview.py
@@ -68,10 +68,14 @@
         return W_MemoryView(buf)
 
     def descr_buffer(self, space):
-        """Note that memoryview() objects in PyPy support buffer(), whereas
-        not in CPython; but CPython supports passing memoryview() to most
-        built-in functions that accept buffers, with the notable exception
-        of the buffer() built-in."""
+        """
+        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.
+        """
         return space.wrap(self.buf)
 
     def descr_tobytes(self, space):
diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py
--- a/pypy/module/_codecs/interp_codecs.py
+++ b/pypy/module/_codecs/interp_codecs.py
@@ -709,7 +709,7 @@
 
 @unwrap_spec(data=str, errors='str_or_None')
 def escape_encode(space, data, errors='strict'):
-    from pypy.objspace.std.stringobject import string_escape_encode
+    from pypy.objspace.std.bytesobject import string_escape_encode
     result = string_escape_encode(data, quote="'")
     start = 1
     end = len(result) - 1
diff --git a/pypy/module/_pickle_support/maker.py b/pypy/module/_pickle_support/maker.py
--- a/pypy/module/_pickle_support/maker.py
+++ b/pypy/module/_pickle_support/maker.py
@@ -5,7 +5,7 @@
 from pypy.interpreter.module import Module
 from pypy.interpreter.pyframe import PyFrame
 from pypy.interpreter.pytraceback import PyTraceback
-from pypy.interpreter.generator import GeneratorIterator
+from pypy.interpreter.generator import GeneratorIteratorWithDel
 from rpython.rlib.objectmodel import instantiate
 from pypy.interpreter.gateway import unwrap_spec
 from pypy.objspace.std.iterobject import W_SeqIterObject, W_ReverseSeqIterObject
@@ -60,7 +60,7 @@
     return space.wrap(tb)
 
 def generator_new(space):
-    new_generator = instantiate(GeneratorIterator)
+    new_generator = instantiate(GeneratorIteratorWithDel)
     return space.wrap(new_generator)
 
 @unwrap_spec(current=int, remaining=int, step=int)
diff --git a/pypy/module/_rawffi/__init__.py b/pypy/module/_rawffi/__init__.py
--- a/pypy/module/_rawffi/__init__.py
+++ b/pypy/module/_rawffi/__init__.py
@@ -19,6 +19,7 @@
         'wcharp2unicode'     : 'interp_rawffi.wcharp2unicode',
         'charp2rawstring'    : 'interp_rawffi.charp2rawstring',
         'wcharp2rawunicode'  : 'interp_rawffi.wcharp2rawunicode',
+        'rawstring2charp'    : 'interp_rawffi.rawstring2charp',
         'CallbackPtr'        : 'callback.W_CallbackPtr',
         '_num_of_allocated_objects' : 'tracker.num_of_allocated_objects',
         'get_libc'           : 'interp_rawffi.get_libc',
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
@@ -579,6 +579,13 @@
     s = rffi.wcharpsize2unicode(rffi.cast(rffi.CWCHARP, address), maxlength)
     return space.wrap(s)
 
+ at unwrap_spec(address=r_uint, newcontent=str)
+def rawstring2charp(space, address, newcontent):
+    from rpython.rtyper.annlowlevel import llstr
+    from rpython.rtyper.lltypesystem.rstr import copy_string_to_raw
+    array = rffi.cast(rffi.CCHARP, address)
+    copy_string_to_raw(llstr(newcontent), array, 0, len(newcontent))
+
 if _MS_WINDOWS:
     @unwrap_spec(code=int)
     def FormatError(space, code):
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
@@ -323,6 +323,14 @@
         assert res == u'xx'
         a.free()
 
+    def test_rawstring2charp(self):
+        import _rawffi
+        A = _rawffi.Array('c')
+        a = A(10, 'x'*10)
+        _rawffi.rawstring2charp(a.buffer, "foobar")
+        assert ''.join([a[i] for i in range(10)]) == "foobarxxxx"
+        a.free()
+
     def test_raw_callable(self):
         import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -12,7 +12,7 @@
 from pypy.module.cpyext.stringobject import PyString_Check
 from pypy.module.sys.interp_encoding import setdefaultencoding
 from pypy.module._codecs.interp_codecs import CodecState
-from pypy.objspace.std import unicodeobject, unicodetype
+from pypy.objspace.std import unicodeobject
 from rpython.rlib import rstring, runicode
 from rpython.tool.sourcetools import func_renamer
 import sys
@@ -262,7 +262,7 @@
 def PyUnicode_GetDefaultEncoding(space):
     """Returns the currently active default encoding."""
     if default_encoding[0] == '\x00':
-        encoding = unicodetype.getdefaultencoding(space)
+        encoding = unicodeobject.getdefaultencoding(space)
         i = 0
         while i < len(encoding) and i < DEFAULT_ENCODING_SIZE:
             default_encoding[i] = encoding[i]
@@ -295,7 +295,7 @@
         encoding = rffi.charp2str(llencoding)
     if llerrors:
         errors = rffi.charp2str(llerrors)
-    return unicodetype.encode_object(space, w_unicode, encoding, errors)
+    return unicodeobject.encode_object(space, w_unicode, encoding, errors)
 
 @cpython_api([PyObject, CONST_STRING, CONST_STRING], PyObject)
 def PyUnicode_AsEncodedString(space, w_unicode, llencoding, llerrors):
@@ -318,7 +318,7 @@
     if not PyUnicode_Check(space, w_unicode):
         PyErr_BadArgument(space)
 
-    return unicodetype.encode_object(space, w_unicode, 'unicode-escape', 'strict')
+    return unicodeobject.encode_object(space, w_unicode, 'unicode-escape', 'strict')
 
 @cpython_api([CONST_WSTRING, Py_ssize_t], PyObject)
 def PyUnicode_FromUnicode(space, wchar_p, length):
@@ -471,7 +471,7 @@
         exception was raised by the codec."""
         if not PyUnicode_Check(space, w_unicode):
             PyErr_BadArgument(space)
-        return unicodetype.encode_object(space, w_unicode, encoding, "strict")
+        return unicodeobject.encode_object(space, w_unicode, encoding, "strict")
 
     @cpython_api([CONST_STRING, Py_ssize_t, CONST_STRING], PyObject)
     @func_renamer('PyUnicode_Decode%s' % suffix)
diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -837,11 +837,11 @@
 # CPython leaves a gap of 10 when it increases its own magic number.
 # To avoid assigning exactly the same numbers as CPython, we can pick
 # any number between CPython + 2 and CPython + 9.  Right now,
-# default_magic = CPython + 6.
+# default_magic = CPython + 7.
 #
-#     default_magic - 6    -- used by CPython without the -U option
-#     default_magic - 5    -- used by CPython with the -U option
-#     default_magic        -- used by PyPy [because of CALL_METHOD]
+#     CPython + 0                  -- used by CPython without the -U option
+#     CPython + 1                  -- used by CPython with the -U option
+#     CPython + 7 = default_magic  -- used by PyPy (incompatible!)
 #
 from pypy.interpreter.pycode import default_magic
 MARSHAL_VERSION_FOR_PYC = 2
diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py
--- a/pypy/module/micronumpy/interp_boxes.py
+++ b/pypy/module/micronumpy/interp_boxes.py
@@ -2,9 +2,9 @@
 from pypy.interpreter.error import operationerrfmt, OperationError
 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.typedef import TypeDef, GetSetProperty
+from pypy.objspace.std.bytesobject import W_BytesObject
 from pypy.objspace.std.floattype import float_typedef
-from pypy.objspace.std.stringtype import str_typedef
-from pypy.objspace.std.unicodetype import unicode_typedef, unicode_from_object
+from pypy.objspace.std.unicodeobject import W_UnicodeObject
 from pypy.objspace.std.inttype import int_typedef
 from pypy.objspace.std.complextype import complex_typedef
 from rpython.rlib.rarithmetic import LONG_BIT
@@ -510,7 +510,7 @@
 
         from pypy.module.micronumpy.interp_dtype import new_unicode_dtype
 
-        arg = space.unicode_w(unicode_from_object(space, w_arg))
+        arg = space.unicode_w(space.unicode_from_object(w_arg))
         # XXX size computations, we need tests anyway
         arr = VoidBoxStorage(len(arg), new_unicode_dtype(space, len(arg)))
         # XXX not this way, we need store
@@ -773,13 +773,13 @@
     __module__ = "numpy",
 )
 
-W_StringBox.typedef = TypeDef("string_", (W_CharacterBox.typedef, str_typedef),
+W_StringBox.typedef = TypeDef("string_", (W_CharacterBox.typedef, W_BytesObject.typedef),
     __module__ = "numpy",
     __new__ = interp2app(W_StringBox.descr__new__string_box.im_func),
     __len__ = interp2app(W_StringBox.descr_len),
 )
 
-W_UnicodeBox.typedef = TypeDef("unicode_", (W_CharacterBox.typedef, unicode_typedef),
+W_UnicodeBox.typedef = TypeDef("unicode_", (W_CharacterBox.typedef, W_UnicodeObject.typedef),
     __module__ = "numpy",
     __new__ = interp2app(W_UnicodeBox.descr__new__unicode_box.im_func),
     __len__ = interp2app(W_UnicodeBox.descr_len),
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/support.py b/pypy/module/test_lib_pypy/ctypes_tests/support.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/support.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/support.py
@@ -31,8 +31,10 @@
             import gc
             for _ in range(4):
                 gc.collect()
-            cls.old_num = _rawffi._num_of_allocated_objects()
-
+            try:
+                cls.old_num = _rawffi._num_of_allocated_objects()
+            except RuntimeError:
+                pass
 
     def teardown_class(cls):
         if sys.pypy_translation_info['translation.gc'] == 'boehm':
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
@@ -290,6 +290,9 @@
         ec._py_repr = None
         return ec
 
+    def unicode_from_object(self, w_obj):
+        return w_some_obj()
+
     # ----------
 
     def translates(self, func=None, argtypes=None, seeobj_w=[], **kwds):
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
@@ -1,25 +1,23 @@
 """The builtin bytearray implementation"""
 
+from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.buffer import RWBuffer
 from pypy.interpreter.error import OperationError, operationerrfmt
+from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
 from pypy.interpreter.signature import Signature
-from pypy.objspace.std import stringobject
-from pypy.objspace.std.bytearraytype import (
-    getbytevalue, makebytearraydata_w, new_bytearray)
-from pypy.objspace.std.intobject import W_IntObject
-from pypy.objspace.std.model import W_Object, registerimplementation
-from pypy.objspace.std.multimethod import FailedToImplement
-from pypy.objspace.std.noneobject import W_NoneObject
-from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
-from pypy.objspace.std.stringobject import W_StringObject
-from pypy.objspace.std.unicodeobject import W_UnicodeObject
+from pypy.objspace.std.sliceobject import W_SliceObject
+from pypy.objspace.std.stdtypedef import StdTypeDef
+from pypy.objspace.std.stringmethods import StringMethods
 from pypy.objspace.std.util import get_positive_index
+from rpython.rlib.objectmodel import newlist_hint, resizelist_hint, import_from_mixin
 from rpython.rlib.rstring import StringBuilder
 
 
-class W_BytearrayObject(W_Object):
-    from pypy.objspace.std.bytearraytype import bytearray_typedef as typedef
+def _make_data(s):
+    return [s[i] for i in range(len(s))]
+
+class W_BytearrayObject(W_Root):
+    import_from_mixin(StringMethods)
 
     def __init__(w_self, data):
         w_self.data = data
@@ -28,310 +26,984 @@
         """ representation for debugging purposes """
         return "%s(%s)" % (w_self.__class__.__name__, ''.join(w_self.data))
 
-registerimplementation(W_BytearrayObject)
+    def _new(self, value):
+        return W_BytearrayObject(_make_data(value))
+
+    def _new_from_list(self, value):
+        return W_BytearrayObject(value)
+
+    def _empty(self):
+        return W_BytearrayObject([])
+
+    def _len(self):
+        return len(self.data)
+
+    def _val(self, space):
+        return space.bufferstr_w(self)
+
+    def _op_val(self, space, w_other):
+        return space.bufferstr_new_w(w_other)
+
+    def _chr(self, char):
+        assert len(char) == 1
+        return str(char)[0]
+
+    _builder = StringBuilder
+
+    def _newlist_unwrapped(self, space, res):
+        return space.newlist([W_BytearrayObject(_make_data(i)) for i in res])
+
+    def _isupper(self, ch):
+        return ch.isupper()
+
+    def _islower(self, ch):
+        return ch.islower()
+
+    def _istitle(self, ch):
+        return ch.isupper()
+
+    def _isspace(self, ch):
+        return ch.isspace()
+
+    def _isalpha(self, ch):
+        return ch.isalpha()
+
+    def _isalnum(self, ch):
+        return ch.isalnum()
+
+    def _isdigit(self, ch):
+        return ch.isdigit()
+
+    _iscased = _isalpha
+
+    def _islinebreak(self, ch):
+        return (ch == '\n') or (ch == '\r')
+
+    def _upper(self, ch):
+        if ch.islower():
+            o = ord(ch) - 32
+            return chr(o)
+        else:
+            return ch
+
+    def _lower(self, ch):
+        if ch.isupper():
+            o = ord(ch) + 32
+            return chr(o)
+        else:
+            return ch
+
+    _title = _upper
+
+    def _join_return_one(self, space, w_obj):
+        return False
+
+    def _join_check_item(self, space, w_obj):
+        if (space.isinstance_w(w_obj, space.w_str) or
+            space.isinstance_w(w_obj, space.w_bytearray)):
+            return 0
+        return 1
+
+    def ord(self, space):
+        if len(self.data) != 1:
+            msg = "ord() expected a character, but string of length %d found"
+            raise operationerrfmt(space.w_TypeError, msg, len(self.data))
+        return space.wrap(ord(self.data[0]))
+
+    @staticmethod
+    def descr_new(space, w_bytearraytype, __args__):
+        return new_bytearray(space, w_bytearraytype, [])
+
+    def descr_reduce(self, space):
+        assert isinstance(self, W_BytearrayObject)
+        w_dict = self.getdict(space)
+        if w_dict is None:
+            w_dict = space.w_None
+        return space.newtuple([
+            space.type(self), space.newtuple([
+                space.wrap(''.join(self.data).decode('latin-1')),
+                space.wrap('latin-1')]),
+            w_dict])
+
+    @staticmethod
+    def descr_fromhex(space, w_bytearraytype, w_hexstring):
+        "bytearray.fromhex(string) -> bytearray\n"
+        "\n"
+        "Create a bytearray object from a string of hexadecimal numbers.\n"
+        "Spaces between two numbers are accepted.\n"
+        "Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')."
+        hexstring = space.str_w(w_hexstring)
+        hexstring = hexstring.lower()
+        data = []
+        length = len(hexstring)
+        i = -2
+        while True:
+            i += 2
+            while i < length and hexstring[i] == ' ':
+                i += 1
+            if i >= length:
+                break
+            if i+1 == length:
+                raise OperationError(space.w_ValueError, space.wrap(
+                    "non-hexadecimal number found in fromhex() arg at position %d" % i))
+
+            top = _hex_digit_to_int(hexstring[i])
+            if top == -1:
+                raise OperationError(space.w_ValueError, space.wrap(
+                    "non-hexadecimal number found in fromhex() arg at position %d" % i))
+            bot = _hex_digit_to_int(hexstring[i+1])
+            if bot == -1:
+                raise OperationError(space.w_ValueError, space.wrap(
+                    "non-hexadecimal number found in fromhex() arg at position %d" % (i+1,)))
+            data.append(chr(top*16 + bot))
+
+        # in CPython bytearray.fromhex is a staticmethod, so
+        # we ignore w_type and always return a bytearray
+        return new_bytearray(space, space.w_bytearray, data)
+
+    def descr_init(self, space, __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.unicodeobject 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:
+            if count < 0:
+                raise OperationError(space.w_ValueError,
+                                     space.wrap("bytearray negative count"))
+            self.data = ['\0'] * count
+            return
+
+        data = makebytearraydata_w(space, w_source)
+        self.data = data
+
+    def descr_repr(self, space):
+        s = self.data
+
+        # Good default if there are no replacements.
+        buf = StringBuilder(len("bytearray(b'')") + len(s))
+
+        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 descr_str(self, space):
+        return space.wrap(''.join(self.data))
+
+    def descr_eq(self, space, w_other):
+        try:
+            return space.newbool(self._val(space) == self._op_val(space, w_other))
+        except OperationError, e:
+            if e.match(space, space.w_TypeError):
+                return space.w_NotImplemented
+            raise
+
+    def descr_ne(self, space, w_other):
+        try:
+            return space.newbool(self._val(space) != self._op_val(space, w_other))
+        except OperationError, e:
+            if e.match(space, space.w_TypeError):
+                return space.w_NotImplemented
+            raise
+
+    def descr_lt(self, space, w_other):
+        try:
+            return space.newbool(self._val(space) < self._op_val(space, w_other))
+        except OperationError, e:
+            if e.match(space, space.w_TypeError):
+                return space.w_NotImplemented
+            raise
+
+    def descr_le(self, space, w_other):
+        try:
+            return space.newbool(self._val(space) <= self._op_val(space, w_other))
+        except OperationError, e:
+            if e.match(space, space.w_TypeError):
+                return space.w_NotImplemented
+            raise
+
+    def descr_gt(self, space, w_other):
+        try:
+            return space.newbool(self._val(space) > self._op_val(space, w_other))
+        except OperationError, e:
+            if e.match(space, space.w_TypeError):
+                return space.w_NotImplemented
+            raise
+
+    def descr_ge(self, space, w_other):
+        try:
+            return space.newbool(self._val(space) >= self._op_val(space, w_other))
+        except OperationError, e:
+            if e.match(space, space.w_TypeError):
+                return space.w_NotImplemented
+            raise
+
+    def descr_buffer(self, space):
+        return BytearrayBuffer(self.data)
+
+    def descr_inplace_add(self, space, w_other):
+        if isinstance(w_other, W_BytearrayObject):
+            self.data += w_other.data
+        else:
+            self.data += self._op_val(space, w_other)
+        return self
+
+    def descr_inplace_mul(self, space, w_times):
+        try:
+            times = space.getindex_w(w_times, space.w_OverflowError)
+        except OperationError, e:
+            if e.match(space, space.w_TypeError):
+                return space.w_NotImplemented
+            raise
+        self.data *= times
+        return self
+
+    def descr_setitem(self, space, w_index, w_other):
+        if isinstance(w_index, W_SliceObject):
+            oldsize = len(self.data)
+            start, stop, step, slicelength = w_index.indices4(space, oldsize)
+            sequence2 = makebytearraydata_w(space, w_other)
+            _setitem_slice_helper(space, self.data, start, step,
+                                  slicelength, sequence2, empty_elem='\x00')
+        else:
+            idx = space.getindex_w(w_index, space.w_IndexError, "bytearray index")
+            try:
+                self.data[idx] = getbytevalue(space, w_other)
+            except IndexError:
+                raise OperationError(space.w_IndexError,
+                                     space.wrap("bytearray index out of range"))
+
+    def descr_delitem(self, space, w_idx):
+        if isinstance(w_idx, W_SliceObject):
+            start, stop, step, slicelength = w_idx.indices4(space,
+                                                            len(self.data))
+            _delitem_slice_helper(space, self.data, start, step, slicelength)
+        else:
+            idx = space.getindex_w(w_idx, space.w_IndexError, "bytearray index")
+            try:
+                del self.data[idx]
+            except IndexError:
+                raise OperationError(space.w_IndexError,
+                                     space.wrap("bytearray deletion index out of range"))
+
+    def descr_append(self, space, w_item):
+        self.data.append(getbytevalue(space, w_item))
+
+    def descr_extend(self, space, w_other):
+        if isinstance(w_other, W_BytearrayObject):
+            self.data += w_other.data
+        else:
+            self.data += makebytearraydata_w(space, w_other)
+        return self
+
+    def descr_insert(self, space, w_idx, w_other):
+        where = space.int_w(w_idx)
+        length = len(self.data)
+        index = get_positive_index(where, length)
+        val = getbytevalue(space, w_other)
+        self.data.insert(index, val)
+        return space.w_None
+
+    @unwrap_spec(w_idx=WrappedDefault(-1))
+    def descr_pop(self, space, w_idx):
+        index = space.int_w(w_idx)
+        try:
+            result = self.data.pop(index)
+        except IndexError:
+            if not self.data:
+                raise OperationError(space.w_IndexError, space.wrap(
+                    "pop from empty bytearray"))
+            raise OperationError(space.w_IndexError, space.wrap(
+                "pop index out of range"))
+        return space.wrap(ord(result))
+
+    def descr_remove(self, space, w_char):
+        char = space.int_w(space.index(w_char))
+        try:
+            self.data.remove(chr(char))
+        except ValueError:
+            raise OperationError(space.w_ValueError, space.wrap(
+                "value not found in bytearray"))
+
+    def descr_reverse(self, space):
+        self.data.reverse()
+
+def getbytevalue(space, w_value):
+    if space.isinstance_w(w_value, space.w_str):
+        string = space.str_w(w_value)
+        if len(string) != 1:
+            raise OperationError(space.w_ValueError, space.wrap(
+                "string must be of size 1"))
+        return string[0]
+
+    value = space.getindex_w(w_value, None)
+    if not 0 <= value < 256:
+        # this includes the OverflowError in case the long is too large
+        raise OperationError(space.w_ValueError, space.wrap(
+            "byte must be in range(0, 256)"))
+    return chr(value)
+
+def new_bytearray(space, w_bytearraytype, data):
+    w_obj = space.allocate_instance(W_BytearrayObject, w_bytearraytype)
+    W_BytearrayObject.__init__(w_obj, data)
+    return w_obj
+
+
+def makebytearraydata_w(space, w_source):
+    # String-like argument
+    try:
+        string = space.bufferstr_new_w(w_source)
+    except OperationError, e:
+        if not e.match(space, space.w_TypeError):
+            raise
+    else:
+        return [c for c in string]
+
+    # sequence of bytes
+    w_iter = space.iter(w_source)
+    length_hint = space.length_hint(w_source, 0)
+    data = newlist_hint(length_hint)
+    extended = 0
+    while True:
+        try:
+            w_item = space.next(w_iter)
+        except OperationError, e:
+            if not e.match(space, space.w_StopIteration):
+                raise
+            break
+        value = getbytevalue(space, w_item)
+        data.append(value)
+        extended += 1
+    if extended < length_hint:
+        resizelist_hint(data, extended)
+    return data
+
+def _hex_digit_to_int(d):
+    val = ord(d)
+    if 47 < val < 58:
+        return val - 48
+    if 96 < val < 103:
+        return val - 87
+    return -1
+
+
+class BytearrayDocstrings:
+    """bytearray(iterable_of_ints) -> bytearray
+    bytearray(string, encoding[, errors]) -> bytearray
+    bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray
+    bytearray(memory_view) -> bytearray
+
+    Construct an mutable bytearray object from:
+      - an iterable yielding integers in range(256)
+      - a text string encoded using the specified encoding
+      - a bytes or a bytearray object
+      - any object implementing the buffer API.
+
+    bytearray(int) -> bytearray.
+
+    Construct a zero-initialized bytearray of the given length.
+
+    """
+
+    def __add__():
+        """x.__add__(y) <==> x+y"""
+
+    def __alloc__():
+        """B.__alloc__() -> int
+
+        Return the number of bytes actually allocated.
+        """
+
+    def __contains__():
+        """x.__contains__(y) <==> y in x"""
+
+    def __delitem__():
+        """x.__delitem__(y) <==> del x[y]"""
+
+    def __eq__():
+        """x.__eq__(y) <==> x==y"""
+
+    def __ge__():
+        """x.__ge__(y) <==> x>=y"""
+
+    def __getattribute__():
+        """x.__getattribute__('name') <==> x.name"""
+
+    def __getitem__():
+        """x.__getitem__(y) <==> x[y]"""
+
+    def __gt__():
+        """x.__gt__(y) <==> x>y"""
+
+    def __iadd__():
+        """x.__iadd__(y) <==> x+=y"""
+
+    def __imul__():
+        """x.__imul__(y) <==> x*=y"""
+
+    def __init__():
+        """x.__init__(...) initializes x; see help(type(x)) for signature"""
+
+    def __iter__():
+        """x.__iter__() <==> iter(x)"""
+
+    def __le__():
+        """x.__le__(y) <==> x<=y"""
+
+    def __len__():
+        """x.__len__() <==> len(x)"""
+
+    def __lt__():
+        """x.__lt__(y) <==> x<y"""
+
+    def __mul__():
+        """x.__mul__(n) <==> x*n"""
+
+    def __ne__():
+        """x.__ne__(y) <==> x!=y"""
+
+    def __reduce__():
+        """Return state information for pickling."""
+
+    def __repr__():
+        """x.__repr__() <==> repr(x)"""
+
+    def __rmul__():
+        """x.__rmul__(n) <==> n*x"""
+
+    def __setitem__():
+        """x.__setitem__(i, y) <==> x[i]=y"""
+
+    def __sizeof__():
+        """B.__sizeof__() -> int
+
+        Returns the size of B in memory, in bytes
+        """
+
+    def __str__():
+        """x.__str__() <==> str(x)"""
+
+    def append():
+        """B.append(int) -> None
+
+        Append a single item to the end of B.
+        """
+
+    def capitalize():
+        """B.capitalize() -> copy of B
+
+        Return a copy of B with only its first character capitalized (ASCII)
+        and the rest lower-cased.
+        """
+
+    def center():
+        """B.center(width[, fillchar]) -> copy of B
+
+        Return B centered in a string of length width.  Padding is
+        done using the specified fill character (default is a space).
+        """
+
+    def count():
+        """B.count(sub[, start[, end]]) -> int
+
+        Return the number of non-overlapping occurrences of subsection sub in
+        bytes B[start:end].  Optional arguments start and end are interpreted
+        as in slice notation.
+        """
+
+    def decode():
+        """B.decode(encoding=None, errors='strict') -> unicode
+
+        Decode B using the codec registered for encoding. encoding defaults
+        to the default encoding. errors may be given to set a different error
+        handling scheme.  Default is 'strict' meaning that encoding errors raise
+        a UnicodeDecodeError.  Other possible values are 'ignore' and 'replace'
+        as well as any other name registered with codecs.register_error that is
+        able to handle UnicodeDecodeErrors.
+        """
+
+    def endswith():
+        """B.endswith(suffix[, start[, end]]) -> bool
+
+        Return True if B ends with the specified suffix, False otherwise.
+        With optional start, test B beginning at that position.
+        With optional end, stop comparing B at that position.
+        suffix can also be a tuple of strings to try.
+        """
+
+    def expandtabs():
+        """B.expandtabs([tabsize]) -> copy of B
+
+        Return a copy of B where all tab characters are expanded using spaces.
+        If tabsize is not given, a tab size of 8 characters is assumed.
+        """
+
+    def extend():
+        """B.extend(iterable_of_ints) -> None
+
+        Append all the elements from the iterator or sequence to the
+        end of B.
+        """
+
+    def find():
+        """B.find(sub[, start[, end]]) -> int
+
+        Return the lowest index in B where subsection sub is found,
+        such that sub is contained within B[start,end].  Optional
+        arguments start and end are interpreted as in slice notation.
+
+        Return -1 on failure.
+        """
+
+    def fromhex():
+        """bytearray.fromhex(string) -> bytearray (static method)
+
+        Create a bytearray object from a string of hexadecimal numbers.
+        Spaces between two numbers are accepted.
+        Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\xb9\x01\xef').
+        """
+
+    def index():
+        """B.index(sub[, start[, end]]) -> int
+
+        Like B.find() but raise ValueError when the subsection is not found.
+        """
+
+    def insert():
+        """B.insert(index, int) -> None
+
+        Insert a single item into the bytearray before the given index.
+        """
+
+    def isalnum():
+        """B.isalnum() -> bool
+
+        Return True if all characters in B are alphanumeric
+        and there is at least one character in B, False otherwise.
+        """
+
+    def isalpha():
+        """B.isalpha() -> bool
+
+        Return True if all characters in B are alphabetic
+        and there is at least one character in B, False otherwise.
+        """
+
+    def isdigit():
+        """B.isdigit() -> bool
+
+        Return True if all characters in B are digits
+        and there is at least one character in B, False otherwise.
+        """
+
+    def islower():
+        """B.islower() -> bool
+
+        Return True if all cased characters in B are lowercase and there is
+        at least one cased character in B, False otherwise.
+        """
+
+    def isspace():
+        """B.isspace() -> bool
+
+        Return True if all characters in B are whitespace
+        and there is at least one character in B, False otherwise.
+        """
+
+    def istitle():
+        """B.istitle() -> bool
+
+        Return True if B is a titlecased string and there is at least one
+        character in B, i.e. uppercase characters may only follow uncased
+        characters and lowercase characters only cased ones. Return False
+        otherwise.
+        """
+
+    def isupper():
+        """B.isupper() -> bool
+
+        Return True if all cased characters in B are uppercase and there is
+        at least one cased character in B, False otherwise.
+        """
+
+    def join():
+        """B.join(iterable_of_bytes) -> bytearray
+
+        Concatenate any number of str/bytearray objects, with B
+        in between each pair, and return the result as a new bytearray.
+        """
+
+    def ljust():
+        """B.ljust(width[, fillchar]) -> copy of B
+
+        Return B left justified in a string of length width. Padding is
+        done using the specified fill character (default is a space).
+        """
+
+    def lower():
+        """B.lower() -> copy of B
+
+        Return a copy of B with all ASCII characters converted to lowercase.
+        """
+
+    def lstrip():
+        """B.lstrip([bytes]) -> bytearray
+
+        Strip leading bytes contained in the argument
+        and return the result as a new bytearray.
+        If the argument is omitted, strip leading ASCII whitespace.
+        """
+
+    def partition():
+        """B.partition(sep) -> (head, sep, tail)
+
+        Search for the separator sep in B, and return the part before it,
+        the separator itself, and the part after it.  If the separator is not
+        found, returns B and two empty bytearray objects.
+        """
+
+    def pop():
+        """B.pop([index]) -> int
+
+        Remove and return a single item from B. If no index
+        argument is given, will pop the last value.
+        """
+
+    def remove():
+        """B.remove(int) -> None
+
+        Remove the first occurrence of a value in B.
+        """
+
+    def replace():
+        """B.replace(old, new[, count]) -> bytearray
+
+        Return a copy of B with all occurrences of subsection
+        old replaced by new.  If the optional argument count is
+        given, only the first count occurrences are replaced.
+        """
+
+    def reverse():
+        """B.reverse() -> None
+
+        Reverse the order of the values in B in place.
+        """
+
+    def rfind():
+        """B.rfind(sub[, start[, end]]) -> int
+
+        Return the highest index in B where subsection sub is found,
+        such that sub is contained within B[start,end].  Optional
+        arguments start and end are interpreted as in slice notation.
+
+        Return -1 on failure.
+        """
+
+    def rindex():
+        """B.rindex(sub[, start[, end]]) -> int
+
+        Like B.rfind() but raise ValueError when the subsection is not found.
+        """
+
+    def rjust():
+        """B.rjust(width[, fillchar]) -> copy of B
+
+        Return B right justified in a string of length width. Padding is
+        done using the specified fill character (default is a space)
+        """
+
+    def rpartition():
+        """B.rpartition(sep) -> (head, sep, tail)
+
+        Search for the separator sep in B, starting at the end of B,
+        and return the part before it, the separator itself, and the
+        part after it.  If the separator is not found, returns two empty
+        bytearray objects and B.
+        """
+
+    def rsplit():
+        """B.rsplit(sep=None, maxsplit=-1) -> list of bytearrays
+
+        Return a list of the sections in B, using sep as the delimiter,
+        starting at the end of B and working to the front.
+        If sep is not given, B is split on ASCII whitespace characters
+        (space, tab, return, newline, formfeed, vertical tab).
+        If maxsplit is given, at most maxsplit splits are done.
+        """
+
+    def rstrip():
+        """B.rstrip([bytes]) -> bytearray
+
+        Strip trailing bytes contained in the argument
+        and return the result as a new bytearray.
+        If the argument is omitted, strip trailing ASCII whitespace.
+        """
+
+    def split():
+        """B.split(sep=None, maxsplit=-1) -> list of bytearrays
+
+        Return a list of the sections in B, using sep as the delimiter.
+        If sep is not given, B is split on ASCII whitespace characters
+        (space, tab, return, newline, formfeed, vertical tab).
+        If maxsplit is given, at most maxsplit splits are done.
+        """
+
+    def splitlines():
+        """B.splitlines(keepends=False) -> list of lines
+
+        Return a list of the lines in B, breaking at line boundaries.
+        Line breaks are not included in the resulting list unless keepends
+        is given and true.
+        """
+
+    def startswith():
+        """B.startswith(prefix[, start[, end]]) -> bool
+
+        Return True if B starts with the specified prefix, False otherwise.
+        With optional start, test B beginning at that position.
+        With optional end, stop comparing B at that position.
+        prefix can also be a tuple of strings to try.
+        """
+
+    def strip():
+        """B.strip([bytes]) -> bytearray
+
+        Strip leading and trailing bytes contained in the argument
+        and return the result as a new bytearray.
+        If the argument is omitted, strip ASCII whitespace.
+        """
+
+    def swapcase():
+        """B.swapcase() -> copy of B
+
+        Return a copy of B with uppercase ASCII characters converted
+        to lowercase ASCII and vice versa.
+        """
+
+    def title():
+        """B.title() -> copy of B
+
+        Return a titlecased version of B, i.e. ASCII words start with uppercase
+        characters, all remaining cased characters have lowercase.
+        """
+
+    def translate():
+        """B.translate(table[, deletechars]) -> bytearray
+
+        Return a copy of B, where all characters occurring in the
+        optional argument deletechars are removed, and the remaining
+        characters have been mapped through the given translation
+        table, which must be a bytes object of length 256.
+        """
+
+    def upper():
+        """B.upper() -> copy of B
+
+        Return a copy of B with all ASCII characters converted to uppercase.
+        """
+
+    def zfill():
+        """B.zfill(width) -> copy of B
+
+        Pad a numeric string B with zeros on the left, to fill a field
+        of the specified width.  B is never truncated.
+        """
+
+
+W_BytearrayObject.typedef = StdTypeDef(
+    "bytearray",
+    __doc__ = BytearrayDocstrings.__doc__,
+    __new__ = interp2app(W_BytearrayObject.descr_new),
+    __hash__ = None,
+    __reduce__ = interp2app(W_BytearrayObject.descr_reduce,
+                            doc=BytearrayDocstrings.__reduce__.__doc__),
+    fromhex = interp2app(W_BytearrayObject.descr_fromhex, as_classmethod=True,
+                         doc=BytearrayDocstrings.fromhex.__doc__),
+
+    __repr__ = interp2app(W_BytearrayObject.descr_repr,
+                          doc=BytearrayDocstrings.__repr__.__doc__),
+    __str__ = interp2app(W_BytearrayObject.descr_str,
+                         doc=BytearrayDocstrings.__str__.__doc__),
+
+    __eq__ = interp2app(W_BytearrayObject.descr_eq,
+                        doc=BytearrayDocstrings.__eq__.__doc__),
+    __ne__ = interp2app(W_BytearrayObject.descr_ne,
+                        doc=BytearrayDocstrings.__ne__.__doc__),
+    __lt__ = interp2app(W_BytearrayObject.descr_lt,
+                        doc=BytearrayDocstrings.__lt__.__doc__),
+    __le__ = interp2app(W_BytearrayObject.descr_le,
+                        doc=BytearrayDocstrings.__le__.__doc__),
+    __gt__ = interp2app(W_BytearrayObject.descr_gt,
+                        doc=BytearrayDocstrings.__gt__.__doc__),
+    __ge__ = interp2app(W_BytearrayObject.descr_ge,
+                        doc=BytearrayDocstrings.__ge__.__doc__),
+
+    __len__ = interp2app(W_BytearrayObject.descr_len,
+                         doc=BytearrayDocstrings.__len__.__doc__),
+    __contains__ = interp2app(W_BytearrayObject.descr_contains,
+                              doc=BytearrayDocstrings.__contains__.__doc__),
+
+    __add__ = interp2app(W_BytearrayObject.descr_add,
+                         doc=BytearrayDocstrings.__add__.__doc__),
+    __mul__ = interp2app(W_BytearrayObject.descr_mul,
+                         doc=BytearrayDocstrings.__mul__.__doc__),
+    __rmul__ = interp2app(W_BytearrayObject.descr_mul,
+                          doc=BytearrayDocstrings.__rmul__.__doc__),
+
+    __getitem__ = interp2app(W_BytearrayObject.descr_getitem,
+                             doc=BytearrayDocstrings.__getitem__.__doc__),
+
+    capitalize = interp2app(W_BytearrayObject.descr_capitalize,
+                            doc=BytearrayDocstrings.capitalize.__doc__),
+    center = interp2app(W_BytearrayObject.descr_center,
+                        doc=BytearrayDocstrings.center.__doc__),
+    count = interp2app(W_BytearrayObject.descr_count,
+                       doc=BytearrayDocstrings.count.__doc__),
+    decode = interp2app(W_BytearrayObject.descr_decode,
+                        doc=BytearrayDocstrings.decode.__doc__),
+    expandtabs = interp2app(W_BytearrayObject.descr_expandtabs,
+                            doc=BytearrayDocstrings.expandtabs.__doc__),
+    find = interp2app(W_BytearrayObject.descr_find,
+                      doc=BytearrayDocstrings.find.__doc__),
+    rfind = interp2app(W_BytearrayObject.descr_rfind,
+                       doc=BytearrayDocstrings.rfind.__doc__),
+    index = interp2app(W_BytearrayObject.descr_index,
+                       doc=BytearrayDocstrings.index.__doc__),
+    rindex = interp2app(W_BytearrayObject.descr_rindex,
+                        doc=BytearrayDocstrings.rindex.__doc__),
+    isalnum = interp2app(W_BytearrayObject.descr_isalnum,
+                         doc=BytearrayDocstrings.isalnum.__doc__),
+    isalpha = interp2app(W_BytearrayObject.descr_isalpha,
+                         doc=BytearrayDocstrings.isalpha.__doc__),
+    isdigit = interp2app(W_BytearrayObject.descr_isdigit,
+                         doc=BytearrayDocstrings.isdigit.__doc__),
+    islower = interp2app(W_BytearrayObject.descr_islower,
+                         doc=BytearrayDocstrings.islower.__doc__),
+    isspace = interp2app(W_BytearrayObject.descr_isspace,
+                         doc=BytearrayDocstrings.isspace.__doc__),
+    istitle = interp2app(W_BytearrayObject.descr_istitle,
+                         doc=BytearrayDocstrings.istitle.__doc__),
+    isupper = interp2app(W_BytearrayObject.descr_isupper,
+                         doc=BytearrayDocstrings.isupper.__doc__),
+    join = interp2app(W_BytearrayObject.descr_join,
+                      doc=BytearrayDocstrings.join.__doc__),
+    ljust = interp2app(W_BytearrayObject.descr_ljust,
+                       doc=BytearrayDocstrings.ljust.__doc__),
+    rjust = interp2app(W_BytearrayObject.descr_rjust,
+                       doc=BytearrayDocstrings.rjust.__doc__),
+    lower = interp2app(W_BytearrayObject.descr_lower,
+                       doc=BytearrayDocstrings.lower.__doc__),
+    partition = interp2app(W_BytearrayObject.descr_partition,
+                           doc=BytearrayDocstrings.partition.__doc__),
+    rpartition = interp2app(W_BytearrayObject.descr_rpartition,
+                            doc=BytearrayDocstrings.rpartition.__doc__),
+    replace = interp2app(W_BytearrayObject.descr_replace,
+                         doc=BytearrayDocstrings.replace.__doc__),
+    split = interp2app(W_BytearrayObject.descr_split,
+                       doc=BytearrayDocstrings.split.__doc__),
+    rsplit = interp2app(W_BytearrayObject.descr_rsplit,
+                        doc=BytearrayDocstrings.rsplit.__doc__),
+    splitlines = interp2app(W_BytearrayObject.descr_splitlines,
+                            doc=BytearrayDocstrings.splitlines.__doc__),
+    startswith = interp2app(W_BytearrayObject.descr_startswith,
+                            doc=BytearrayDocstrings.startswith.__doc__),
+    endswith = interp2app(W_BytearrayObject.descr_endswith,
+                          doc=BytearrayDocstrings.endswith.__doc__),
+    strip = interp2app(W_BytearrayObject.descr_strip,
+                       doc=BytearrayDocstrings.strip.__doc__),
+    lstrip = interp2app(W_BytearrayObject.descr_lstrip,
+                        doc=BytearrayDocstrings.lstrip.__doc__),
+    rstrip = interp2app(W_BytearrayObject.descr_rstrip,
+                        doc=BytearrayDocstrings.rstrip.__doc__),
+    swapcase = interp2app(W_BytearrayObject.descr_swapcase,
+                          doc=BytearrayDocstrings.swapcase.__doc__),
+    title = interp2app(W_BytearrayObject.descr_title,
+                       doc=BytearrayDocstrings.title.__doc__),
+    translate = interp2app(W_BytearrayObject.descr_translate,
+                           doc=BytearrayDocstrings.translate.__doc__),
+    upper = interp2app(W_BytearrayObject.descr_upper,
+                       doc=BytearrayDocstrings.upper.__doc__),
+    zfill = interp2app(W_BytearrayObject.descr_zfill,
+                       doc=BytearrayDocstrings.zfill.__doc__),
+
+    __init__ = interp2app(W_BytearrayObject.descr_init,
+                          doc=BytearrayDocstrings.__init__.__doc__),
+    __buffer__ = interp2app(W_BytearrayObject.descr_buffer),
+
+    __iadd__ = interp2app(W_BytearrayObject.descr_inplace_add,
+                          doc=BytearrayDocstrings.__iadd__.__doc__),
+    __imul__ = interp2app(W_BytearrayObject.descr_inplace_mul,
+                          doc=BytearrayDocstrings.__imul__.__doc__),
+    __setitem__ = interp2app(W_BytearrayObject.descr_setitem,
+                             doc=BytearrayDocstrings.__setitem__.__doc__),
+    __delitem__ = interp2app(W_BytearrayObject.descr_delitem,
+                             doc=BytearrayDocstrings.__delitem__.__doc__),
+
+    append = interp2app(W_BytearrayObject.descr_append,
+                        doc=BytearrayDocstrings.append.__doc__),
+    extend = interp2app(W_BytearrayObject.descr_extend,
+                        doc=BytearrayDocstrings.extend.__doc__),
+    insert = interp2app(W_BytearrayObject.descr_insert,
+                        doc=BytearrayDocstrings.insert.__doc__),
+    pop = interp2app(W_BytearrayObject.descr_pop,
+                     doc=BytearrayDocstrings.pop.__doc__),
+    remove = interp2app(W_BytearrayObject.descr_remove,
+                        doc=BytearrayDocstrings.remove.__doc__),
+    reverse = interp2app(W_BytearrayObject.descr_reverse,
+                         doc=BytearrayDocstrings.reverse.__doc__),
+)
 
 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:
-        if count < 0:
-            raise OperationError(space.w_ValueError,
-                                 space.wrap("bytearray negative count"))
-        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)
-    return space.newint(result)
-
-def ord__Bytearray(space, w_bytearray):
-    if len(w_bytearray.data) != 1:
-        raise OperationError(space.w_TypeError,
-                             space.wrap("expected a character, but string"
-                            "of length %s found" % len(w_bytearray.data)))
-    return space.wrap(ord(w_bytearray.data[0]))
-
-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
-    if step == 1 and 0 <= start <= stop:
-        newdata = data[start:stop]
-    else:
-        newdata = _getitem_slice_multistep(data, start, step, slicelength)
-    return W_BytearrayObject(newdata)
-
-def _getitem_slice_multistep(data, start, step, slicelength):
-    return [data[start + i*step] for i in range(slicelength)]
-
-def contains__Bytearray_Int(space, w_bytearray, w_char):
-    char = space.int_w(w_char)
-    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 contains__Bytearray_String(space, w_bytearray, w_str):
-    # XXX slow - copies, needs rewriting
-    w_str2 = str__Bytearray(space, w_bytearray)
-    return stringobject.contains__String_String(space, w_str2, w_str)
-
-def contains__Bytearray_ANY(space, w_bytearray, w_sub):
-    # XXX slow - copies, needs rewriting
-    w_str = space.wrap(space.bufferstr_new_w(w_sub))
-    w_str2 = str__Bytearray(space, w_bytearray)
-    return stringobject.contains__String_String(space, w_str2, w_str)
-
-def add__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2):
-    data1 = w_bytearray1.data
-    data2 = w_bytearray2.data
-    return W_BytearrayObject(data1 + data2)
-
-def add__Bytearray_ANY(space, w_bytearray1, w_other):
-    data1 = w_bytearray1.data
-    data2 = [c for c in space.bufferstr_new_w(w_other)]
-    return W_BytearrayObject(data1 + data2)
-
-def add__String_Bytearray(space, w_str, w_bytearray):
-    data2 = w_bytearray.data
-    data1 = [c for c in space.str_w(w_str)]
-    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
-    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 inplace_mul__Bytearray_ANY(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
-    w_bytearray.data *= times
-    return w_bytearray
-
-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 String2Bytearray(space, w_str):
-    data = [c for c in space.str_w(w_str)]
-    return W_BytearrayObject(data)
-
-def eq__Bytearray_String(space, w_bytearray, w_other):
-    return space.eq(str__Bytearray(space, w_bytearray), w_other)
-
-def eq__Bytearray_Unicode(space, w_bytearray, w_other):
-    return space.w_False
-
-def eq__Unicode_Bytearray(space, w_other, w_bytearray):
-    return space.w_False
-
-def ne__Bytearray_String(space, w_bytearray, w_other):
-    return space.ne(str__Bytearray(space, w_bytearray), w_other)
-
-def ne__Bytearray_Unicode(space, w_bytearray, w_other):
-    return space.w_True
-
-def ne__Unicode_Bytearray(space, w_other, w_bytearray):
-    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))
-
-def str_translate__Bytearray_ANY_ANY(space, w_bytearray1, w_table, w_deletechars):
-    # XXX slow, copies *twice* needs proper implementation
-    w_str_copy = str__Bytearray(space, w_bytearray1)
-    w_res = stringobject.str_translate__String_ANY_ANY(space, w_str_copy,
-                                                       w_table, w_deletechars)
-    return String2Bytearray(space, w_res)
-
-# Mostly copied from repr__String, but without the "smart quote"
-# functionality.
-def repr__Bytearray(space, w_bytearray):
-    s = w_bytearray.data
-
-    # Good default if there are no replacements.
-    buf = StringBuilder(len("bytearray(b'')") + len(s))
-
-    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 str__Bytearray(space, w_bytearray):
-    return space.wrap(''.join(w_bytearray.data))
-
-def str_count__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
-    w_char = space.wrap(space.bufferstr_new_w(w_char))
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_count__String_String_ANY_ANY(space, w_str, w_char,
-                                                         w_start, w_stop)
-
-def str_index__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
-    w_char = space.wrap(space.bufferstr_new_w(w_char))
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_index__String_String_ANY_ANY(space, w_str, w_char,
-                                                         w_start, w_stop)
-
-def str_rindex__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
-    w_char = space.wrap(space.bufferstr_new_w(w_char))
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_rindex__String_String_ANY_ANY(space, w_str, w_char,
-                                                         w_start, w_stop)
-
-def str_find__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
-    w_char = space.wrap(space.bufferstr_new_w(w_char))
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_find__String_String_ANY_ANY(space, w_str, w_char,
-                                                         w_start, w_stop)
-
-def str_rfind__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
-    w_char = space.wrap(space.bufferstr_new_w(w_char))
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_rfind__String_String_ANY_ANY(space, w_str, w_char,
-                                                         w_start, w_stop)
-
-def str_startswith__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_prefix, w_start, w_stop):
-    if space.isinstance_w(w_prefix, space.w_tuple):
-        w_str = str__Bytearray(space, w_bytearray)
-        w_prefix = space.newtuple([space.wrap(space.bufferstr_new_w(w_entry)) for w_entry in
-                                   space.fixedview(w_prefix)])
-        return stringobject.str_startswith__String_ANY_ANY_ANY(space, w_str, w_prefix,
-                                                                  w_start, w_stop)
-
-    w_prefix = space.wrap(space.bufferstr_new_w(w_prefix))
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_startswith__String_String_ANY_ANY(space, w_str, w_prefix,
-                                                              w_start, w_stop)
-
-def str_endswith__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_suffix, w_start, w_stop):
-    if space.isinstance_w(w_suffix, space.w_tuple):
-        w_str = str__Bytearray(space, w_bytearray)
-        w_suffix = space.newtuple([space.wrap(space.bufferstr_new_w(w_entry)) for w_entry in
-                                   space.fixedview(w_suffix)])
-        return stringobject.str_endswith__String_ANY_ANY_ANY(space, w_str, w_suffix,
-                                                                  w_start, w_stop)
-    w_suffix = space.wrap(space.bufferstr_new_w(w_suffix))
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_endswith__String_String_ANY_ANY(space, w_str, w_suffix,
-                                                              w_start, w_stop)
-
+# XXX consider moving to W_BytearrayObject or remove
 def str_join__Bytearray_ANY(space, w_self, w_list):
     list_w = space.listview(w_list)
     if not list_w:
@@ -350,251 +1022,8 @@
         newdata.extend([c for c in space.bufferstr_new_w(w_s)])
     return W_BytearrayObject(newdata)
 
-def str_decode__Bytearray_ANY_ANY(space, w_bytearray, w_encoding, w_errors):
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_decode__String_ANY_ANY(space, w_str, w_encoding, w_errors)
-
-def str_islower__Bytearray(space, w_bytearray):
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_islower__String(space, w_str)
-
-def str_isupper__Bytearray(space, w_bytearray):
-    w_str = str__Bytearray(space, w_bytearray)
-    return stringobject.str_isupper__String(space, w_str)
-
-def str_isalpha__Bytearray(space, w_bytearray):


More information about the pypy-commit mailing list