Author: Amaury Forgeot d'Arc <[email protected]>
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, [])
[email protected]_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):
[email protected]_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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit