[pypy-svn] pypy default: (mfoord, antocuni) implement bytearray.fromhex
mfoord
commits-noreply at bitbucket.org
Tue Jan 18 14:02:00 CET 2011
Author: Michael Foord <michael at voidspace.org.uk>
Branch:
Changeset: r40847:2031592f79e7
Date: 2011-01-18 14:01 +0100
http://bitbucket.org/pypy/pypy/changeset/2031592f79e7/
Log: (mfoord, antocuni) implement bytearray.fromhex
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
@@ -190,6 +190,26 @@
assert b == 'abcdef'
assert isinstance(b, bytearray)
+ def test_fromhex(self):
+ raises(TypeError, bytearray.fromhex, 9)
+
+ assert bytearray.fromhex('') == bytearray()
+ assert bytearray.fromhex(u'') == bytearray()
+
+ b = bytearray([0x1a, 0x2b, 0x30])
+ assert bytearray.fromhex('1a2B30') == b
+ assert bytearray.fromhex(u'1a2B30') == b
+ assert bytearray.fromhex(u' 1A 2B 30 ') == b
+ assert bytearray.fromhex(u'0000') == '\0\0'
+
+ raises(ValueError, bytearray.fromhex, u'a')
+ raises(ValueError, bytearray.fromhex, u'A')
+ raises(ValueError, bytearray.fromhex, u'rt')
+ raises(ValueError, bytearray.fromhex, u'1a b cd')
+ raises(ValueError, bytearray.fromhex, u'\x00')
+ raises(ValueError, bytearray.fromhex, u'12 \x00 34')
+ raises(UnicodeEncodeError, bytearray.fromhex, u'\u1234')
+
def test_extend(self):
b = bytearray('abc')
b.extend(bytearray('def'))
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
@@ -18,6 +18,7 @@
from pypy.objspace.std.listtype import (
list_append, list_extend)
+
def getbytevalue(space, w_value):
if space.isinstance_w(w_value, space.w_str):
string = space.str_w(w_value)
@@ -104,6 +105,49 @@
space.wrap('latin-1')]),
w_dict])
+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
+
+ at gateway.unwrap_spec(ObjSpace, W_Root, W_Root)
+def descr_fromhex(space, w_type, w_hexstring):
+ "bytearray.fromhex(string) -> bytearray\n\nCreate a bytearray object "
+ "from a string of hexadecimal numbers.\nSpaces between two numbers are "
+ "accepted.\nExample: 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)
+
# ____________________________________________________________
bytearray_typedef = StdTypeDef("bytearray",
@@ -114,5 +158,6 @@
__new__ = gateway.interp2app(descr__new__),
__hash__ = None,
__reduce__ = gateway.interp2app(descr_bytearray__reduce__),
+ fromhex = gateway.interp2app(descr_fromhex, as_classmethod=True)
)
bytearray_typedef.registermethods(globals())
More information about the Pypy-commit
mailing list