Author: Amaury Forgeot d'Arc <amaur...@gmail.com> Branch: py3k Changeset: r48838:c30f57c0a8d2 Date: 2011-10-26 12:29 +0200 http://bitbucket.org/pypy/pypy/changeset/c30f57c0a8d2/
Log: Share code between bytes and bytearray constructors. Add support for bytes(unicode_string, encoding) 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 @@ -39,49 +39,6 @@ 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 = makebytesdata_w(space, w_source) - w_bytearray.data = data - def len__Bytearray(space, w_bytearray): result = len(w_bytearray.data) return wrapint(space, result) 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 @@ -14,6 +14,7 @@ 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.stringtype import makebytesdata_w from pypy.objspace.std.listtype import ( list_append, list_extend) @@ -61,6 +62,12 @@ def descr__new__(space, w_bytearraytype, __args__): return new_bytearray(space,w_bytearraytype, []) +@gateway.unwrap_spec(encoding='str_or_None', errors='str_or_None') +def descr__init__(space, w_bytearray, w_source=gateway.NoneNotWrapped, + encoding=None, errors=None): + data = makebytesdata_w(space, w_source, encoding, errors) + w_bytearray.data = data + def descr_bytearray__reduce__(space, w_self): from pypy.objspace.std.bytearrayobject import W_BytearrayObject @@ -125,6 +132,7 @@ If the argument is a bytearray, the return value is the same object.''', __new__ = gateway.interp2app(descr__new__), + __init__ = gateway.interp2app(descr__init__), __hash__ = None, __reduce__ = gateway.interp2app(descr_bytearray__reduce__), fromhex = gateway.interp2app(descr_fromhex, as_classmethod=True) diff --git a/pypy/objspace/std/stringtype.py b/pypy/objspace/std/stringtype.py --- a/pypy/objspace/std/stringtype.py +++ b/pypy/objspace/std/stringtype.py @@ -271,7 +271,36 @@ "byte must be in range(0, 256)")) return chr(value) -def makebytesdata_w(space, w_source): +def makebytesdata_w(space, w_source, encoding=None, errors=None): + # None value + if w_source is None: + if encoding is not None or errors is not None: + raise OperationError(space.w_TypeError, space.wrap( + "encoding or errors without string argument")) + return [] + # 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("negative count")) + if encoding is not None or errors is not None: + raise OperationError(space.w_TypeError, space.wrap( + "encoding or errors without string argument")) + return ['\0'] * count + # Unicode with encoding + if space.isinstance_w(w_source, space.w_unicode): + if encoding is None: + raise OperationError(space.w_TypeError, space.wrap( + "string argument without an encoding")) + from pypy.objspace.std.unicodetype import encode_object + w_source = encode_object(space, w_source, encoding, errors) + # and continue with the encoded string + # String-like argument try: string = space.bufferstr_new_w(w_source) @@ -295,11 +324,13 @@ data.append(value) return data -def descr__new__(space, w_stringtype, w_source=gateway.NoneNotWrapped): +@gateway.unwrap_spec(encoding='str_or_None', errors='str_or_None') +def descr__new__(space, w_stringtype, w_source=gateway.NoneNotWrapped, + encoding=None, errors=None): if (w_source and space.is_w(space.type(w_source), space.w_bytes) and space.is_w(w_stringtype, space.w_bytes)): return w_source - value = ''.join(makebytesdata_w(space, w_source)) + value = ''.join(makebytesdata_w(space, w_source, encoding, errors)) if space.config.objspace.std.withrope: from pypy.objspace.std.ropeobject import rope, W_RopeObject w_obj = space.allocate_instance(W_RopeObject, w_stringtype) diff --git a/pypy/objspace/std/test/test_stringobject.py b/pypy/objspace/std/test/test_stringobject.py --- a/pypy/objspace/std/test/test_stringobject.py +++ b/pypy/objspace/std/test/test_stringobject.py @@ -89,6 +89,12 @@ class AppTestStringObject: + def test_constructor(self): + assert bytes() == b'' + assert bytes(3) == b'\0\0\0' + assert bytes(b'abc') == b'abc' + assert bytes('abc', 'ascii') == b'abc' + def test_format(self): import operator raises(TypeError, operator.mod, b"%s", (1,)) @@ -627,7 +633,8 @@ assert b'a' in b'abc' assert b'ab' in b'abc' assert not b'd' in b'abc' - raises(TypeError, b'a'.__contains__, 1) + assert 97 in b'a' + raises(TypeError, b'a'.__contains__, 1.0) def test_decode(self): assert b'hello'.decode('ascii') == 'hello' _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit