[pypy-commit] pypy kill-single-impl-multimethods: Refactor the entire world. Removes some multimethods from bytearray. One side effect of this is that ByteArrayObject now subclasses Wrappable, rather than W_Object, because of a mess of circular imports with gateway. Not sure if this is a problem. All tests pass.
alex_gaynor
noreply at buildbot.pypy.org
Sat Aug 6 01:32:46 CEST 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: kill-single-impl-multimethods
Changeset: r46297:53ea358ad6d5
Date: 2011-08-05 16:33 -0700
http://bitbucket.org/pypy/pypy/changeset/53ea358ad6d5/
Log: Refactor the entire world. Removes some multimethods from
bytearray. One side effect of this is that ByteArrayObject now
subclasses Wrappable, rather than W_Object, because of a mess of
circular imports with gateway. Not sure if this is a problem. All
tests pass.
diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py
--- a/pypy/interpreter/gateway.py
+++ b/pypy/interpreter/gateway.py
@@ -7,27 +7,28 @@
"""
-import types, sys, os
-from pypy.tool.compat import md5
-NoneNotWrapped = object()
+import os
+import sys
+import types
-from pypy.tool.sourcetools import func_with_new_name
+from pypy.interpreter import eval
+from pypy.interpreter.argument import Arguments, Signature
+from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable, SpaceCache, DescrMismatch
from pypy.interpreter.error import OperationError
-from pypy.interpreter import eval
-from pypy.interpreter.function import Function, Method, ClassMethod
-from pypy.interpreter.function import FunctionWithFixedCode
-from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable
-from pypy.interpreter.baseobjspace import Wrappable, SpaceCache, DescrMismatch
-from pypy.interpreter.argument import Arguments, Signature
-from pypy.tool.sourcetools import NiceCompile, compile2
-from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint
+from pypy.interpreter.function import Function, Method, ClassMethod, FunctionWithFixedCode
from pypy.rlib import rstackovf
from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint
+from pypy.tool.compat import md5
+from pypy.tool.sourcetools import func_with_new_name, NiceCompile, compile2
# internal non-translatable parts:
import py
+
+NoneNotWrapped = object()
+
class SignatureBuilder(object):
"NOT_RPYTHON"
def __init__(self, func=None, argnames=None, varargname=None,
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -1,11 +1,13 @@
import operator
+
+from pypy.interpreter.argument import Arguments
+from pypy.interpreter.baseobjspace import ObjSpace
from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.interpreter.baseobjspace import ObjSpace
from pypy.interpreter.function import Function, Method, FunctionWithFixedCode
-from pypy.interpreter.argument import Arguments
from pypy.interpreter.typedef import default_identity_hash
+from pypy.module.__builtin__.interp_classobj import W_InstanceObject
from pypy.tool.sourcetools import compile2, func_with_new_name
-from pypy.module.__builtin__.interp_classobj import W_InstanceObject
+
def object_getattribute(space):
"Utility that returns the app-level descriptor object.__getattribute__."
diff --git a/pypy/objspace/std/__init__.py b/pypy/objspace/std/__init__.py
--- a/pypy/objspace/std/__init__.py
+++ b/pypy/objspace/std/__init__.py
@@ -1,2 +1,4 @@
from pypy.objspace.std.objspace import StdObjSpace
-Space = StdObjSpace
+
+# There's code that relies on the StdObjSpace name being available here.
+Space = StdObjSpace
\ No newline at end of file
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,200 +1,3 @@
-from pypy.interpreter.error import OperationError, operationerrfmt
-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.objspace.std.noneobject import W_NoneObject
-from pypy.rlib.rarithmetic import intmask
-from pypy.rlib.rstring import StringBuilder
-from pypy.rlib.debug import check_annotation
-from pypy.objspace.std import stringobject
-from pypy.objspace.std.intobject import W_IntObject
-from pypy.objspace.std.listobject import (
- _delitem_slice_helper, _setitem_slice_helper,
- get_positive_index
-)
-from pypy.objspace.std.listtype import get_list_index
-from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
-from pypy.objspace.std.stringobject import W_StringObject
-from pypy.objspace.std.tupleobject import W_TupleObject
-from pypy.objspace.std.unicodeobject import W_UnicodeObject
-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,
- new_bytearray
-)
-from pypy.tool.sourcetools import func_with_new_name
-
-
-class W_BytearrayObject(W_Object):
- from pypy.objspace.std.bytearraytype import bytearray_typedef as typedef
-
- def __init__(w_self, data):
- w_self.data = data
-
- def __repr__(w_self):
- """ representation for debugging purposes """
- return "%s(%s)" % (w_self.__class__.__name__, ''.join(w_self.data))
-
-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:
- 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 wrapint(space, 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
- newdata = [data[start + i*step] for i in range(slicelength)]
- return W_BytearrayObject(newdata)
-
-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
@@ -202,20 +5,12 @@
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
@@ -227,449 +22,3 @@
# 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
-
- 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 str__Bytearray(space, w_bytearray):
- return space.wrap(''.join(w_bytearray.data))
-
-def _convert_idx_params(space, w_self, w_start, w_stop):
- start = slicetype.eval_slice_index(space, w_start)
- stop = slicetype.eval_slice_index(space, w_stop)
- length = len(w_self.data)
- if start < 0:
- start += length
- if start < 0:
- start = 0
- if stop < 0:
- stop += length
- if stop < 0:
- stop = 0
- return start, stop, length
-
-def str_count__Bytearray_Int_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
- char = w_char.intval
- start, stop, length = _convert_idx_params(space, w_bytearray, w_start, w_stop)
- count = 0
- for i in range(start, min(stop, length)):
- c = w_bytearray.data[i]
- if ord(c) == char:
- count += 1
- return space.wrap(count)
-
-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):
- 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_startswith__Bytearray_Tuple_ANY_ANY(space, w_bytearray, w_prefix, w_start, w_stop):
- w_str = str__Bytearray(space, w_bytearray)
- w_prefix = space.newtuple([space.wrap(space.bufferstr_new_w(w_entry)) for w_entry in
- space.unpackiterable(w_prefix)])
- return stringobject.str_startswith__String_Tuple_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):
- 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)
-
-def str_endswith__Bytearray_Tuple_ANY_ANY(space, w_bytearray, w_suffix, w_start, w_stop):
- w_str = str__Bytearray(space, w_bytearray)
- w_suffix = space.newtuple([space.wrap(space.bufferstr_new_w(w_entry)) for w_entry in
- space.unpackiterable(w_suffix)])
- return stringobject.str_endswith__String_Tuple_ANY_ANY(space, w_str, w_suffix,
- w_start, w_stop)
-
-def str_join__Bytearray_ANY(space, w_self, w_list):
- list_w = space.listview(w_list)
- if not list_w:
- return W_BytearrayObject([])
- data = w_self.data
- newdata = []
- for i in range(len(list_w)):
- w_s = list_w[i]
- if not (space.is_true(space.isinstance(w_s, space.w_str)) or
- space.is_true(space.isinstance(w_s, space.w_bytearray))):
- raise operationerrfmt(
- space.w_TypeError,
- "sequence item %d: expected string, %s "
- "found", i, space.type(w_s).getname(space))
-
- if data and i != 0:
- newdata.extend(data)
- 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):
- w_str = str__Bytearray(space, w_bytearray)
- return stringobject.str_isalpha__String(space, w_str)
-
-def str_isalnum__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- return stringobject.str_isalnum__String(space, w_str)
-
-def str_isdigit__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- return stringobject.str_isdigit__String(space, w_str)
-
-def str_istitle__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- return stringobject.str_istitle__String(space, w_str)
-
-def str_isspace__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- return stringobject.str_isspace__String(space, w_str)
-
-def bytearray_insert__Bytearray_Int_ANY(space, w_bytearray, w_idx, w_other):
- where = space.int_w(w_idx)
- length = len(w_bytearray.data)
- index = get_positive_index(where, length)
- val = getbytevalue(space, w_other)
- w_bytearray.data.insert(index, val)
- return space.w_None
-
-def bytearray_pop__Bytearray_Int(space, w_bytearray, w_idx):
- index = space.int_w(w_idx)
- try:
- result = w_bytearray.data.pop(index)
- except IndexError:
- if not w_bytearray.data:
- raise OperationError(space.w_OverflowError, space.wrap(
- "cannot pop an empty bytearray"))
- raise OperationError(space.w_IndexError, space.wrap(
- "pop index out of range"))
- return space.wrap(ord(result))
-
-def bytearray_remove__Bytearray_ANY(space, w_bytearray, w_char):
- char = space.int_w(space.index(w_char))
- try:
- result = w_bytearray.data.remove(chr(char))
- except ValueError:
- raise OperationError(space.w_ValueError, space.wrap(
- "value not found in bytearray"))
-
-def bytearray_reverse__Bytearray(space, w_bytearray):
- w_bytearray.data.reverse()
- return space.w_None
-
-_space_chars = ''.join([chr(c) for c in [9, 10, 11, 12, 13, 32]])
-
-def bytearray_strip__Bytearray_None(space, w_bytearray, w_chars):
- return _strip(space, w_bytearray, _space_chars, 1, 1)
-
-def bytearray_strip__Bytearray_ANY(space, w_bytearray, w_chars):
- return _strip(space, w_bytearray, space.bufferstr_new_w(w_chars), 1, 1)
-
-def bytearray_lstrip__Bytearray_None(space, w_bytearray, w_chars):
- return _strip(space, w_bytearray, _space_chars, 1, 0)
-
-def bytearray_lstrip__Bytearray_ANY(space, w_bytearray, w_chars):
- return _strip(space, w_bytearray, space.bufferstr_new_w(w_chars), 1, 0)
-
-def bytearray_rstrip__Bytearray_None(space, w_bytearray, w_chars):
- return _strip(space, w_bytearray, _space_chars, 0, 1)
-
-def bytearray_rstrip__Bytearray_ANY(space, w_bytearray, w_chars):
- return _strip(space, w_bytearray, space.bufferstr_new_w(w_chars), 0, 1)
-
-# These methods could just delegate to the string implementation,
-# but they have to return a bytearray.
-def str_replace__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_str1, w_str2, w_max):
- w_str = str__Bytearray(space, w_bytearray)
- w_res = stringobject.str_replace__String_ANY_ANY_ANY(space, w_str, w_str1,
- w_str2, w_max)
- return String2Bytearray(space, w_res)
-
-def str_upper__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- w_res = stringobject.str_upper__String(space, w_str)
- return String2Bytearray(space, w_res)
-
-def str_lower__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- w_res = stringobject.str_lower__String(space, w_str)
- return String2Bytearray(space, w_res)
-
-def str_title__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- w_res = stringobject.str_title__String(space, w_str)
- return String2Bytearray(space, w_res)
-
-def str_swapcase__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- w_res = stringobject.str_swapcase__String(space, w_str)
- return String2Bytearray(space, w_res)
-
-def str_capitalize__Bytearray(space, w_bytearray):
- w_str = str__Bytearray(space, w_bytearray)
- w_res = stringobject.str_capitalize__String(space, w_str)
- return String2Bytearray(space, w_res)
-
-def str_ljust__Bytearray_ANY_ANY(space, w_bytearray, w_width, w_fillchar):
- w_str = str__Bytearray(space, w_bytearray)
- w_res = stringobject.str_ljust__String_ANY_ANY(space, w_str, w_width,
- w_fillchar)
- return String2Bytearray(space, w_res)
-
-def str_rjust__Bytearray_ANY_ANY(space, w_bytearray, w_width, w_fillchar):
- w_str = str__Bytearray(space, w_bytearray)
- w_res = stringobject.str_rjust__String_ANY_ANY(space, w_str, w_width,
- w_fillchar)
- return String2Bytearray(space, w_res)
-
-def str_center__Bytearray_ANY_ANY(space, w_bytearray, w_width, w_fillchar):
- w_str = str__Bytearray(space, w_bytearray)
- w_res = stringobject.str_center__String_ANY_ANY(space, w_str, w_width,
- w_fillchar)
- return String2Bytearray(space, w_res)
-
-def str_zfill__Bytearray_ANY(space, w_bytearray, w_width):
- w_str = str__Bytearray(space, w_bytearray)
- w_res = stringobject.str_zfill__String_ANY(space, w_str, w_width)
- return String2Bytearray(space, w_res)
-
-def str_expandtabs__Bytearray_ANY(space, w_bytearray, w_tabsize):
- w_str = str__Bytearray(space, w_bytearray)
- w_res = stringobject.str_expandtabs__String_ANY(space, w_str, w_tabsize)
- return String2Bytearray(space, w_res)
-
-def str_splitlines__Bytearray_ANY(space, w_bytearray, w_keepends):
- w_str = str__Bytearray(space, w_bytearray)
- w_result = stringobject.str_splitlines__String_ANY(space, w_str, w_keepends)
- return space.newlist([
- new_bytearray(space, space.w_bytearray, makebytearraydata_w(space, w_entry))
- for w_entry in space.unpackiterable(w_result)
- ])
-
-def str_split__Bytearray_ANY_ANY(space, w_bytearray, w_by, w_maxsplit=-1):
- w_str = str__Bytearray(space, w_bytearray)
- if not space.is_w(w_by, space.w_None):
- w_by = space.wrap(space.bufferstr_new_w(w_by))
- w_list = space.call_method(w_str, "split", w_by, w_maxsplit)
- length = space.int_w(space.len(w_list))
- for i in range(length):
- w_i = space.wrap(i)
- space.setitem(w_list, w_i, String2Bytearray(space, space.getitem(w_list, w_i)))
- return w_list
-
-def str_rsplit__Bytearray_ANY_ANY(space, w_bytearray, w_by, w_maxsplit=-1):
- w_str = str__Bytearray(space, w_bytearray)
- if not space.is_w(w_by, space.w_None):
- w_by = space.wrap(space.bufferstr_new_w(w_by))
- w_list = space.call_method(w_str, "rsplit", w_by, w_maxsplit)
- length = space.int_w(space.len(w_list))
- for i in range(length):
- w_i = space.wrap(i)
- space.setitem(w_list, w_i, String2Bytearray(space, space.getitem(w_list, w_i)))
- return w_list
-
-def str_partition__Bytearray_ANY(space, w_bytearray, w_sub):
- w_str = str__Bytearray(space, w_bytearray)
- w_sub = space.wrap(space.bufferstr_new_w(w_sub))
- w_tuple = stringobject.str_partition__String_String(space, w_str, w_sub)
- w_a, w_b, w_c = space.fixedview(w_tuple, 3)
- return space.newtuple([
- String2Bytearray(space, w_a),
- String2Bytearray(space, w_b),
- String2Bytearray(space, w_c)])
-
-def str_rpartition__Bytearray_ANY(space, w_bytearray, w_sub):
- w_str = str__Bytearray(space, w_bytearray)
- w_sub = space.wrap(space.bufferstr_new_w(w_sub))
- w_tuple = stringobject.str_rpartition__String_String(space, w_str, w_sub)
- w_a, w_b, w_c = space.fixedview(w_tuple, 3)
- return space.newtuple([
- String2Bytearray(space, w_a),
- String2Bytearray(space, w_b),
- String2Bytearray(space, w_c)])
-
-# __________________________________________________________
-# Mutability methods
-
-def list_append__Bytearray_ANY(space, w_bytearray, w_item):
- from pypy.objspace.std.bytearraytype import getbytevalue
- w_bytearray.data.append(getbytevalue(space, w_item))
-
-def list_extend__Bytearray_Bytearray(space, w_bytearray, w_other):
- w_bytearray.data += w_other.data
-
-def list_extend__Bytearray_ANY(space, w_bytearray, w_other):
- w_bytearray.data += makebytearraydata_w(space, w_other)
-
-def inplace_add__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2):
- list_extend__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2)
- return w_bytearray1
-
-def inplace_add__Bytearray_ANY(space, w_bytearray1, w_iterable2):
- w_bytearray1.data += space.bufferstr_new_w(w_iterable2)
- return w_bytearray1
-
-def setitem__Bytearray_ANY_ANY(space, w_bytearray, w_index, w_item):
- from pypy.objspace.std.bytearraytype import getbytevalue
- idx = space.getindex_w(w_index, space.w_IndexError, "bytearray index")
- try:
- w_bytearray.data[idx] = getbytevalue(space, w_item)
- except IndexError:
- raise OperationError(space.w_IndexError,
- space.wrap("bytearray index out of range"))
-
-def setitem__Bytearray_Slice_ANY(space, w_bytearray, w_slice, w_other):
- oldsize = len(w_bytearray.data)
- start, stop, step, slicelength = w_slice.indices4(space, oldsize)
- sequence2 = makebytearraydata_w(space, w_other)
- setitem_slice_helper(space, w_bytearray.data, start, step, slicelength, sequence2, empty_elem='\x00')
-
-def delitem__Bytearray_ANY(space, w_bytearray, w_idx):
- idx = get_list_index(space, w_idx)
- try:
- del w_bytearray.data[idx]
- except IndexError:
- raise OperationError(space.w_IndexError,
- space.wrap("bytearray deletion index out of range"))
- return space.w_None
-
-def delitem__Bytearray_Slice(space, w_bytearray, w_slice):
- start, stop, step, slicelength = w_slice.indices4(space,
- len(w_bytearray.data))
- delitem_slice_helper(space, w_bytearray.data, start, step, slicelength)
-
-# create new helper functions with different list type specialisation
-delitem_slice_helper = func_with_new_name(_delitem_slice_helper,
- 'delitem_slice_helper')
-setitem_slice_helper = func_with_new_name(_setitem_slice_helper,
- 'setitem_slice_helper')
-
-def _strip(space, w_bytearray, u_chars, left, right):
- # note: mostly copied from stringobject._strip
- # should really be shared
- u_self = w_bytearray.data
-
- lpos = 0
- rpos = len(u_self)
-
- if left:
- while lpos < rpos and u_self[lpos] in u_chars:
- lpos += 1
-
- if right:
- while rpos > lpos and u_self[rpos - 1] in u_chars:
- rpos -= 1
- assert rpos >= 0
-
- return new_bytearray(space, space.w_bytearray, u_self[lpos:rpos])
-
-# __________________________________________________________
-# Buffer interface
-
-class BytearrayBuffer(RWBuffer):
- def __init__(self, data):
- self.data = data
-
- def getlength(self):
- return len(self.data)
-
- def getitem(self, index):
- return self.data[index]
-
- def setitem(self, index, char):
- self.data[index] = char
-
-def buffer__Bytearray(space, self):
- b = BytearrayBuffer(self.data)
- return space.wrap(b)
-
-from pypy.objspace.std import bytearraytype
-register_all(vars(), bytearraytype)
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
@@ -1,55 +1,165 @@
import sys
+
from pypy.interpreter import gateway
-from pypy.interpreter.baseobjspace import ObjSpace, W_Root
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.argument import Signature
+from pypy.interpreter.baseobjspace import ObjSpace, Wrappable
+from pypy.interpreter.buffer import RWBuffer
+from pypy.interpreter.error import OperationError, operationerrfmt
+from pypy.objspace.std import stringobject, slicetype
+from pypy.objspace.std.intobject import W_IntObject
+from pypy.objspace.std.listobject import (_delitem_slice_helper,
+ _setitem_slice_helper, get_positive_index, get_list_index)
+from pypy.objspace.std.model import registerimplementation
+from pypy.objspace.std.multimethod import FailedToImplement
from pypy.objspace.std.register_all import register_all
+from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.objspace.std.stdtypedef import StdTypeDef, SMM
+from pypy.objspace.std.stringobject import W_StringObject
+from pypy.objspace.std.stringtype import (str_decode, str_count, str_index,
+ str_rindex, str_find, str_rfind, str_replace, str_startswith, str_endswith,
+ str_islower, str_isupper, str_isalpha, str_isalnum, str_isdigit,
+ str_isspace, str_istitle, str_upper, str_lower, str_title, str_swapcase,
+ str_capitalize, str_expandtabs, str_ljust, str_rjust, str_center,
+ str_zfill, str_join, str_split, str_rsplit, str_partition, str_rpartition,
+ str_splitlines, str_translate)
+from pypy.objspace.std.tupleobject import W_TupleObject
+from pypy.rlib.debug import check_annotation
+from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.rstring import StringBuilder
+from pypy.tool.sourcetools import func_with_new_name
-from pypy.objspace.std.stringtype import (
- str_decode,
- str_count, str_index, str_rindex, str_find, str_rfind, str_replace,
- str_startswith, str_endswith, str_islower, str_isupper, str_isalpha,
- str_isalnum, str_isdigit, str_isspace, str_istitle,
- str_upper, str_lower, str_title, str_swapcase, str_capitalize,
- str_expandtabs, str_ljust, str_rjust, str_center, str_zfill,
- str_join, str_split, str_rsplit, str_partition, str_rpartition,
- str_splitlines, str_translate)
-from pypy.objspace.std.listtype import (
- list_append, list_extend)
+_space_chars = ''.join([chr(c) for c in [9, 10, 11, 12, 13, 32]])
-bytearray_insert = SMM('insert', 3,
- doc="B.insert(index, int) -> None\n\n"
- "Insert a single item into the bytearray before "
- "the given index.")
+class W_BytearrayObject(Wrappable):
+ def __init__(w_self, data):
+ w_self.data = data
-bytearray_pop = SMM('pop', 2, defaults=(-1,),
- doc="B.pop([index]) -> int\n\nRemove and return a "
- "single item from B. If no index\nargument is given, "
- "will pop the last value.")
+ def __repr__(w_self):
+ """ representation for debugging purposes """
+ return "%s(%s)" % (w_self.__class__.__name__, ''.join(w_self.data))
-bytearray_remove = SMM('remove', 2,
- doc="B.remove(int) -> None\n\n"
- "Remove the first occurance of a value in B.")
+ def _strip(self, space, w_chars, left, right):
+ if not space.is_w(w_chars, space.w_None):
+ chars = space.bufferstr_new_w(w_chars)
+ else:
+ chars = _space_chars
-bytearray_reverse = SMM('reverse', 1,
- doc="B.reverse() -> None\n\n"
- "Reverse the order of the values in B in place.")
+ s = self.data
+ lpos = 0
+ rpos = len(s)
-bytearray_strip = SMM('strip', 2, defaults=(None,),
- doc="B.strip([bytes]) -> bytearray\n\nStrip leading "
- "and trailing bytes contained in the argument.\nIf "
- "the argument is omitted, strip ASCII whitespace.")
+ if left:
+ while lpos < rpos and s[lpos] in chars:
+ lpos += 1
-bytearray_lstrip = SMM('lstrip', 2, defaults=(None,),
- doc="B.lstrip([bytes]) -> bytearray\n\nStrip leading "
- "bytes contained in the argument.\nIf the argument is "
- "omitted, strip leading ASCII whitespace.")
+ if right:
+ while rpos > lpos and s[rpos - 1] in chars:
+ rpos -= 1
+ assert rpos >= 0
+ return new_bytearray(space, space.w_bytearray, s[lpos:rpos])
-bytearray_rstrip = SMM('rstrip', 2, defaults=(None,),
- doc="'B.rstrip([bytes]) -> bytearray\n\nStrip trailing "
- "bytes contained in the argument.\nIf the argument is "
- "omitted, strip trailing ASCII whitespace.")
+ def descr__new__(space, w_subtype, __args__):
+ return new_bytearray(space, w_subtype, [])
+
+ def descr__reduce__(self, space):
+ 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
+ ])
+
+ @gateway.unwrap_spec(idx=int)
+ def descr_insert(self, space, idx, w_other):
+ """B.insert(index, int) -> None
+
+ Insert a single item into the bytearray before
+ the given index."""
+ length = len(self.data)
+ index = get_positive_index(idx, length)
+ val = getbytevalue(space, w_other)
+ self.data.insert(index, val)
+
+ def descr_strip(self, space, w_chars=None):
+ return self._strip(space, w_chars, True, True)
+
+ def descr_lstrip(self, space, w_chars=None):
+ """B.lstrip([bytes]) -> bytearray
+
+ Strip leading bytes contained in the argument.
+ If the argument is omitted, strip leading ASCII whitespace."""
+ return self._strip(space, w_chars, True, False)
+
+ def descr_rstrip(self, space, w_chars=None):
+ """'B.rstrip([bytes]) -> bytearray
+
+ Strip trailing bytes contained in the argument.
+ If the argument is omitted, strip trailing ASCII whitespace."""
+ return self._strip(space, w_chars, False, True)
+
+ def descr_append(self, space, w_item):
+ self.data.append(getbytevalue(space, w_item))
+
+ def descr_extend(self, space, w_other):
+ if space.isinstance_w(w_other, space.w_bytearray):
+ self.data += w_other.data
+ else:
+ self.data += makebytearraydata_w(space, w_other)
+
+ @gateway.unwrap_spec(idx=int)
+ def descr_pop(self, space, idx=-1):
+ """B.pop([index]) -> int
+
+ Remove and return a single item from B. If no index
+ argument is given, will pop the last value."""
+ try:
+ result = self.data.pop(idx)
+ except IndexError:
+ if not self.data:
+ raise OperationError(space.w_OverflowError, space.wrap(
+ "cannot pop an empty bytearray"))
+ raise OperationError(space.w_IndexError, space.wrap(
+ "pop index out of range"))
+ return space.wrap(ord(result))
+
+ @gateway.unwrap_spec(char="index")
+ def descr_remove(self, space, char):
+ """B.remove(int) -> None
+
+ Remove the first occurance of a value in B."""
+ try:
+ self.data.remove(chr(char))
+ except ValueError:
+ raise OperationError(space.w_ValueError, space.wrap(
+ "value not found in bytearray"))
+
+ def descr_reverse(self):
+ """B.reverse() -> None
+
+ Reverse the order of the values in B in place."""
+ self.data.reverse()
+
+
+
+class BytearrayBuffer(RWBuffer):
+ def __init__(self, data):
+ self.data = data
+
+ def getlength(self):
+ return len(self.data)
+
+ def getitem(self, index):
+ return self.data[index]
+
+ def setitem(self, index, char):
+ self.data[index] = char
+
def getbytevalue(space, w_value):
if space.isinstance_w(w_value, space.w_str):
@@ -67,16 +177,11 @@
return chr(value)
def new_bytearray(space, w_bytearraytype, data):
- from pypy.objspace.std.bytearrayobject import W_BytearrayObject
w_obj = space.allocate_instance(W_BytearrayObject, w_bytearraytype)
W_BytearrayObject.__init__(w_obj, data)
return w_obj
-def descr__new__(space, w_bytearraytype, __args__):
- return new_bytearray(space,w_bytearraytype, [])
-
-
def makebytearraydata_w(space, w_source):
# String-like argument
try:
@@ -101,18 +206,6 @@
data.append(value)
return data
-def descr_bytearray__reduce__(space, w_self):
- from pypy.objspace.std.bytearrayobject import W_BytearrayObject
- assert isinstance(w_self, W_BytearrayObject)
- w_dict = w_self.getdict(space)
- if w_dict is None:
- w_dict = space.w_None
- return space.newtuple([
- space.type(w_self), space.newtuple([
- space.wrap(''.join(w_self.data).decode('latin-1')),
- space.wrap('latin-1')]),
- w_dict])
-
def _hex_digit_to_int(d):
val = ord(d)
if 47 < val < 58:
@@ -155,16 +248,542 @@
# we ignore w_type and always return a bytearray
return new_bytearray(space, space.w_bytearray, data)
+### MULTIMETHODS: KILL THEM
+
+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:
+ 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 str__Bytearray(space, w_bytearray):
+ return space.wrap(''.join(w_bytearray.data))
+
+def eq__Bytearray_String(space, w_bytearray, w_other):
+ return space.eq(str__Bytearray(space, w_bytearray), w_other)
+
+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 len__Bytearray(space, w_bytearray):
+ result = len(w_bytearray.data)
+ return space.wrap(result)
+
+# Mostly copied from repr__String, but without the "smart quote"
+# functionality.
+def repr__Bytearray(space, w_bytearray):
+ s = w_bytearray.data
+
+ # Good default for the common case of no special quoting.
+ 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 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 delitem__Bytearray_ANY(space, w_bytearray, w_idx):
+ idx = get_list_index(space, w_idx)
+ try:
+ del w_bytearray.data[idx]
+ except IndexError:
+ raise OperationError(space.w_IndexError,
+ space.wrap("bytearray deletion index out of range"))
+ return space.w_None
+
+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
+ newdata = [data[start + i*step] for i in range(slicelength)]
+ return W_BytearrayObject(newdata)
+
+def setitem__Bytearray_ANY_ANY(space, w_bytearray, w_index, w_item):
+ from pypy.objspace.std.bytearraytype import getbytevalue
+ idx = space.getindex_w(w_index, space.w_IndexError, "bytearray index")
+ try:
+ w_bytearray.data[idx] = getbytevalue(space, w_item)
+ except IndexError:
+ raise OperationError(space.w_IndexError,
+ space.wrap("bytearray index out of range"))
+
+def setitem__Bytearray_Slice_ANY(space, w_bytearray, w_slice, w_other):
+ oldsize = len(w_bytearray.data)
+ start, stop, step, slicelength = w_slice.indices4(space, oldsize)
+ sequence2 = makebytearraydata_w(space, w_other)
+ setitem_slice_helper(space, w_bytearray.data, start, step, slicelength, sequence2, empty_elem='\x00')
+
+def delitem__Bytearray_Slice(space, w_bytearray, w_slice):
+ start, stop, step, slicelength = w_slice.indices4(space,
+ len(w_bytearray.data))
+ delitem_slice_helper(space, w_bytearray.data, start, step, slicelength)
+
+# create new helper functions with different list type specialisation
+delitem_slice_helper = func_with_new_name(_delitem_slice_helper,
+ 'delitem_slice_helper')
+setitem_slice_helper = func_with_new_name(_setitem_slice_helper,
+ 'setitem_slice_helper')
+
+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 inplace_add__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2):
+ list_extend__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2)
+ return w_bytearray1
+
+def inplace_add__Bytearray_ANY(space, w_bytearray1, w_iterable2):
+ w_bytearray1.data += space.bufferstr_new_w(w_iterable2)
+ return w_bytearray1
+
+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 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 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_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 buffer__Bytearray(space, self):
+ b = BytearrayBuffer(self.data)
+ return space.wrap(b)
+
+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 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 ne__Bytearray_String(space, w_bytearray, w_other):
+ return space.ne(str__Bytearray(space, w_bytearray), w_other)
+
+
+### THESE MULTIMETHODS WORK BY PRETENDING TO BE A STRING, WTF
+
+def String2Bytearray(space, w_str):
+ data = [c for c in space.str_w(w_str)]
+ return W_BytearrayObject(data)
+
+def _convert_idx_params(space, w_self, w_start, w_stop):
+ start = slicetype.eval_slice_index(space, w_start)
+ stop = slicetype.eval_slice_index(space, w_stop)
+ length = len(w_self.data)
+ if start < 0:
+ start += length
+ if start < 0:
+ start = 0
+ if stop < 0:
+ stop += length
+ if stop < 0:
+ stop = 0
+ return start, stop, length
+
+def str_splitlines__Bytearray_ANY(space, w_bytearray, w_keepends):
+ w_str = str__Bytearray(space, w_bytearray)
+ w_result = stringobject.str_splitlines__String_ANY(space, w_str, w_keepends)
+ return space.newlist([
+ new_bytearray(space, space.w_bytearray, makebytearraydata_w(space, w_entry))
+ for w_entry in space.unpackiterable(w_result)
+ ])
+
+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)
+
+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):
+ w_str = str__Bytearray(space, w_bytearray)
+ return stringobject.str_isalpha__String(space, w_str)
+
+def str_isalnum__Bytearray(space, w_bytearray):
+ w_str = str__Bytearray(space, w_bytearray)
+ return stringobject.str_isalnum__String(space, w_str)
+
+def str_isdigit__Bytearray(space, w_bytearray):
+ w_str = str__Bytearray(space, w_bytearray)
+ return stringobject.str_isdigit__String(space, w_str)
+
+def str_isspace__Bytearray(space, w_bytearray):
+ w_str = str__Bytearray(space, w_bytearray)
+ return stringobject.str_isspace__String(space, w_str)
+
+def str_istitle__Bytearray(space, w_bytearray):
+ w_str = str__Bytearray(space, w_bytearray)
+ return stringobject.str_istitle__String(space, w_str)
+
+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_count__Bytearray_Int_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
+ char = w_char.intval
+ start, stop, length = _convert_idx_params(space, w_bytearray, w_start, w_stop)
+ count = 0
+ for i in range(start, min(stop, length)):
+ c = w_bytearray.data[i]
+ if ord(c) == char:
+ count += 1
+ return space.wrap(count)
+
+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):
+ 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_startswith__Bytearray_Tuple_ANY_ANY(space, w_bytearray, w_prefix, w_start, w_stop):
+ w_str = str__Bytearray(space, w_bytearray)
+ w_prefix = space.newtuple([space.wrap(space.bufferstr_new_w(w_entry)) for w_entry in
+ space.unpackiterable(w_prefix)])
+ return stringobject.str_startswith__String_Tuple_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):
+ 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)
+
+def str_endswith__Bytearray_Tuple_ANY_ANY(space, w_bytearray, w_suffix, w_start, w_stop):
+ w_str = str__Bytearray(space, w_bytearray)
+ w_suffix = space.newtuple([space.wrap(space.bufferstr_new_w(w_entry)) for w_entry in
+ space.unpackiterable(w_suffix)])
+ return stringobject.str_endswith__String_Tuple_ANY_ANY(space, w_str, w_suffix,
+ w_start, w_stop)
+
+def str_replace__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_str1, w_str2, w_max):
+ w_str = str__Bytearray(space, w_bytearray)
+ w_res = stringobject.str_replace__String_ANY_ANY_ANY(space, w_str, w_str1,
+ w_str2, w_max)
+ return String2Bytearray(space, w_res)
+
+def str_upper__Bytearray(space, w_bytearray):
+ w_str = str__Bytearray(space, w_bytearray)
+ w_res = stringobject.str_upper__String(space, w_str)
+ return String2Bytearray(space, w_res)
+
+def str_lower__Bytearray(space, w_bytearray):
+ w_str = str__Bytearray(space, w_bytearray)
+ w_res = stringobject.str_lower__String(space, w_str)
+ return String2Bytearray(space, w_res)
+
+def str_title__Bytearray(space, w_bytearray):
+ w_str = str__Bytearray(space, w_bytearray)
+ w_res = stringobject.str_title__String(space, w_str)
+ return String2Bytearray(space, w_res)
+
+def str_swapcase__Bytearray(space, w_bytearray):
+ w_str = str__Bytearray(space, w_bytearray)
+ w_res = stringobject.str_swapcase__String(space, w_str)
+ return String2Bytearray(space, w_res)
+
+def str_capitalize__Bytearray(space, w_bytearray):
+ w_str = str__Bytearray(space, w_bytearray)
+ w_res = stringobject.str_capitalize__String(space, w_str)
+ return String2Bytearray(space, w_res)
+
+def str_ljust__Bytearray_ANY_ANY(space, w_bytearray, w_width, w_fillchar):
+ w_str = str__Bytearray(space, w_bytearray)
+ w_res = stringobject.str_ljust__String_ANY_ANY(space, w_str, w_width,
+ w_fillchar)
+ return String2Bytearray(space, w_res)
+
+def str_rjust__Bytearray_ANY_ANY(space, w_bytearray, w_width, w_fillchar):
+ w_str = str__Bytearray(space, w_bytearray)
+ w_res = stringobject.str_rjust__String_ANY_ANY(space, w_str, w_width,
+ w_fillchar)
+ return String2Bytearray(space, w_res)
+
+def str_center__Bytearray_ANY_ANY(space, w_bytearray, w_width, w_fillchar):
+ w_str = str__Bytearray(space, w_bytearray)
+ w_res = stringobject.str_center__String_ANY_ANY(space, w_str, w_width,
+ w_fillchar)
+ return String2Bytearray(space, w_res)
+
+def str_zfill__Bytearray_ANY(space, w_bytearray, w_width):
+ w_str = str__Bytearray(space, w_bytearray)
+ w_res = stringobject.str_zfill__String_ANY(space, w_str, w_width)
+ return String2Bytearray(space, w_res)
+
+def str_expandtabs__Bytearray_ANY(space, w_bytearray, w_tabsize):
+ w_str = str__Bytearray(space, w_bytearray)
+ w_res = stringobject.str_expandtabs__String_ANY(space, w_str, w_tabsize)
+ return String2Bytearray(space, w_res)
+
+def str_join__Bytearray_ANY(space, w_self, w_list):
+ list_w = space.listview(w_list)
+ if not list_w:
+ return W_BytearrayObject([])
+ data = w_self.data
+ newdata = []
+ for i in range(len(list_w)):
+ w_s = list_w[i]
+ if not (space.is_true(space.isinstance(w_s, space.w_str)) or
+ space.is_true(space.isinstance(w_s, space.w_bytearray))):
+ raise operationerrfmt(
+ space.w_TypeError,
+ "sequence item %d: expected string, %s "
+ "found", i, space.type(w_s).getname(space))
+
+ if data and i != 0:
+ newdata.extend(data)
+ newdata.extend([c for c in space.bufferstr_new_w(w_s)])
+ return W_BytearrayObject(newdata)
+
+def str_split__Bytearray_ANY_ANY(space, w_bytearray, w_by, w_maxsplit=-1):
+ w_str = str__Bytearray(space, w_bytearray)
+ if not space.is_w(w_by, space.w_None):
+ w_by = space.wrap(space.bufferstr_new_w(w_by))
+ w_list = space.call_method(w_str, "split", w_by, w_maxsplit)
+ length = space.int_w(space.len(w_list))
+ for i in range(length):
+ w_i = space.wrap(i)
+ space.setitem(w_list, w_i, String2Bytearray(space, space.getitem(w_list, w_i)))
+ return w_list
+
+def str_rsplit__Bytearray_ANY_ANY(space, w_bytearray, w_by, w_maxsplit=-1):
+ w_str = str__Bytearray(space, w_bytearray)
+ if not space.is_w(w_by, space.w_None):
+ w_by = space.wrap(space.bufferstr_new_w(w_by))
+ w_list = space.call_method(w_str, "rsplit", w_by, w_maxsplit)
+ length = space.int_w(space.len(w_list))
+ for i in range(length):
+ w_i = space.wrap(i)
+ space.setitem(w_list, w_i, String2Bytearray(space, space.getitem(w_list, w_i)))
+ return w_list
+
+def str_partition__Bytearray_ANY(space, w_bytearray, w_sub):
+ w_str = str__Bytearray(space, w_bytearray)
+ w_sub = space.wrap(space.bufferstr_new_w(w_sub))
+ w_tuple = stringobject.str_partition__String_String(space, w_str, w_sub)
+ w_a, w_b, w_c = space.fixedview(w_tuple, 3)
+ return space.newtuple([
+ String2Bytearray(space, w_a),
+ String2Bytearray(space, w_b),
+ String2Bytearray(space, w_c)])
+
+def str_rpartition__Bytearray_ANY(space, w_bytearray, w_sub):
+ w_str = str__Bytearray(space, w_bytearray)
+ w_sub = space.wrap(space.bufferstr_new_w(w_sub))
+ w_tuple = stringobject.str_rpartition__String_String(space, w_str, w_sub)
+ w_a, w_b, w_c = space.fixedview(w_tuple, 3)
+ return space.newtuple([
+ String2Bytearray(space, w_a),
+ String2Bytearray(space, w_b),
+ String2Bytearray(space, w_c)])
+
+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)
+
+
+
# ____________________________________________________________
-bytearray_typedef = StdTypeDef("bytearray",
+W_BytearrayObject.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__),
+
+ __new__ = gateway.interp2app(W_BytearrayObject.descr__new__.im_func),
+ fromhex = gateway.interp2app(descr_fromhex, as_classmethod=True),
+
+ __reduce__ = gateway.interp2app(W_BytearrayObject.descr__reduce__),
__hash__ = None,
- __reduce__ = gateway.interp2app(descr_bytearray__reduce__),
- fromhex = gateway.interp2app(descr_fromhex, as_classmethod=True)
- )
-bytearray_typedef.registermethods(globals())
+
+ append = gateway.interp2app(W_BytearrayObject.descr_append),
+ extend = gateway.interp2app(W_BytearrayObject.descr_extend),
+ insert = gateway.interp2app(W_BytearrayObject.descr_insert),
+ pop = gateway.interp2app(W_BytearrayObject.descr_pop),
+ remove = gateway.interp2app(W_BytearrayObject.descr_remove),
+ reverse = gateway.interp2app(W_BytearrayObject.descr_reverse),
+
+ strip = gateway.interp2app(W_BytearrayObject.descr_strip),
+ lstrip = gateway.interp2app(W_BytearrayObject.descr_lstrip),
+ rstrip = gateway.interp2app(W_BytearrayObject.descr_rstrip),
+)
+
+W_BytearrayObject.typedef.registermethods(globals())
+register_all(vars(), sys.modules[__name__])
\ No newline at end of file
diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py
--- a/pypy/objspace/std/model.py
+++ b/pypy/objspace/std/model.py
@@ -5,13 +5,11 @@
from pypy.objspace.std.multimethod import MultiMethodTable, FailedToImplement
from pypy.interpreter.baseobjspace import W_Root, ObjSpace
-import pypy.interpreter.pycode
-import pypy.interpreter.special
_registered_implementations = set()
def registerimplementation(implcls):
"""Hint to objspace.std.model to register the implementation class."""
- assert issubclass(implcls, W_Object)
+ assert issubclass(implcls, W_Root)
_registered_implementations.add(implcls)
option_to_typename = {
@@ -37,6 +35,8 @@
"""NOT_RPYTHON: inititialization only"""
self.config = config
# All the Python types that we want to provide in this StdObjSpace
+ from pypy.objspace.std.bytearraytype import W_BytearrayObject
+
class result:
from pypy.objspace.std.objecttype import object_typedef
from pypy.objspace.std.booltype import bool_typedef
@@ -50,7 +50,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
+ bytearray_typedef = W_BytearrayObject.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
@@ -76,7 +76,6 @@
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
@@ -109,7 +108,7 @@
dictmultiobject.W_DictMultiObject: [],
dictmultiobject.W_DictMultiIterObject: [],
stringobject.W_StringObject: [],
- bytearrayobject.W_BytearrayObject: [],
+ W_BytearrayObject: [],
typeobject.W_TypeObject: [],
sliceobject.W_SliceObject: [],
longobject.W_LongObject: [],
@@ -127,9 +126,7 @@
dictmultiobject.W_DictViewKeysObject: [],
dictmultiobject.W_DictViewItemsObject: [],
dictmultiobject.W_DictViewValuesObject: [],
- pypy.interpreter.pycode.PyCode: [],
- pypy.interpreter.special.Ellipsis: [],
- }
+ }
self.imported_but_not_registered = {
dictmultiobject.W_DictMultiObject: True, # XXXXXX
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -1,17 +1,17 @@
import __builtin__
import types
-from pypy.interpreter import pyframe, function, special
+
+from pypy.interpreter import function, special
from pypy.interpreter.baseobjspace import ObjSpace, Wrappable
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter.typedef import get_unique_interplevel_subclass
from pypy.objspace.std import (builtinshortcut, stdtypedef, frame, model,
transparent, callmethod, proxyobject)
from pypy.objspace.descroperation import DescrOperation, raiseattrerror
-from pypy.rlib.objectmodel import instantiate, r_dict, specialize
+from pypy.rlib import jit
from pypy.rlib.debug import make_sure_not_resized
+from pypy.rlib.objectmodel import instantiate, r_dict, specialize, we_are_translated
from pypy.rlib.rarithmetic import base_int, widen
-from pypy.rlib.objectmodel import we_are_translated
-from pypy.rlib import jit
from pypy.rlib.rbigint import rbigint
from pypy.tool.sourcetools import func_with_new_name
diff --git a/pypy/objspace/std/stdtypedef.py b/pypy/objspace/std/stdtypedef.py
--- a/pypy/objspace/std/stdtypedef.py
+++ b/pypy/objspace/std/stdtypedef.py
@@ -1,18 +1,16 @@
-from pypy.interpreter import gateway, baseobjspace, argument
+from pypy.interpreter import baseobjspace, gateway
from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.interpreter.typedef import TypeDef, GetSetProperty, Member
-from pypy.interpreter.typedef import descr_get_dict, descr_set_dict
-from pypy.interpreter.typedef import descr_del_dict
-from pypy.interpreter.baseobjspace import SpaceCache
+from pypy.interpreter.typedef import (TypeDef, GetSetProperty, Member,
+ descr_get_dict, descr_set_dict, descr_del_dict)
from pypy.objspace.std import model
-from pypy.objspace.std.model import StdObjSpaceMultiMethod
from pypy.objspace.std.multimethod import FailedToImplement
from pypy.rlib import jit
from pypy.tool.sourcetools import compile2
+
__all__ = ['StdTypeDef', 'SMM']
-SMM = StdObjSpaceMultiMethod
+SMM = StdObjSpaceMultiMethod = model.StdObjSpaceMultiMethod
class StdTypeDef(TypeDef):
@@ -48,7 +46,7 @@
# the descriptors to put into the W_TypeObjects.
#
-class TypeCache(SpaceCache):
+class TypeCache(baseobjspace.SpaceCache):
def build(cache, typedef):
"NOT_RPYTHON: initialization-time only."
# build a W_TypeObject from this StdTypeDef
@@ -102,7 +100,7 @@
result = []
seen = {}
for value in ns.itervalues():
- if isinstance(value, StdObjSpaceMultiMethod):
+ if isinstance(value, model.StdObjSpaceMultiMethod):
if value.name in seen:
raise Exception("duplicate multimethod name %r" %
(value.name,))
@@ -162,7 +160,7 @@
def make_perform_trampoline(prefix, exprargs, expr, miniglobals, multimethod, selfindex=0,
allow_NotImplemented_results=False):
- """NOT_RPYTHON"""
+ """NOT_RPYTHON"""
# mess to figure out how to put a gateway around executing expr
argnames = ['_%d'%(i+1) for i in range(multimethod.arity)]
explicit_argnames = multimethod.extras.get('argnames', [])
@@ -179,7 +177,7 @@
miniglobals.update({ 'OperationError': OperationError,
'gettypeerror': gettypeerror})
-
+
app_defaults = multimethod.extras.get('defaults', ())
i = len(argnames) - len(app_defaults)
wrapper_signature = wrapper_arglist[:]
@@ -235,7 +233,7 @@
return w_res
""" % (prefix, wrapper_sig, renaming, expr,
multimethod.operatorsymbol, ', '.join(solid_arglist))
- exec compile2(code, '', 'exec') in miniglobals
+ exec compile2(code, '', 'exec') in miniglobals
return miniglobals["%s_perform_call" % prefix]
def wrap_trampoline_in_gateway(func, methname, multimethod):
@@ -245,7 +243,7 @@
return gateway.interp2app(func, app_name=methname)
def slicemultimethod(space, multimethod, typedef, result, local=False):
- """NOT_RPYTHON"""
+ """NOT_RPYTHON"""
for i in range(len(multimethod.specialnames)):
methname = multimethod.specialnames[i]
if methname in result:
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
@@ -257,6 +257,14 @@
b.insert(-12, 'h')
assert b == bytearray('hdgabecf')
+ # A long value
+ b.insert(0L, 'q')
+ assert b == bytearray('qhdgabecf')
+
+ # A bool
+ b.insert(False, 't')
+ assert b == bytearray('tqhdgabecf')
+
raises(ValueError, b.insert, 1, 'go')
raises(TypeError, b.insert, 'g', 'o')
More information about the pypy-commit
mailing list