[pypy-commit] pypy py3k: (chronitis) Implement bytes.fromhex().
amauryfa
noreply at buildbot.pypy.org
Mon Nov 7 21:22:41 CET 2011
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3k
Changeset: r48880:02d89bbd9a31
Date: 2011-11-07 21:17 +0100
http://bitbucket.org/pypy/pypy/changeset/02d89bbd9a31/
Log: (chronitis) Implement bytes.fromhex(). Thanks!
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
@@ -93,18 +93,13 @@
return val - 87
return -1
-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.unicode_w(w_hexstring)
+def _hexstring_to_array(space, s):
data = []
- length = len(hexstring)
+ length = len(s)
i = -2
while True:
i += 2
- while i < length and hexstring[i] == ' ':
+ while i < length and s[i] == ' ':
i += 1
if i >= length:
break
@@ -112,16 +107,28 @@
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])
+ top = _hex_digit_to_int(s[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])
+ bot = _hex_digit_to_int(s[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))
+ return data
+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')."
+ if not space.is_w(space.type(w_hexstring), space.w_unicode):
+ raise OperationError(space.w_TypeError, space.wrap(
+ "must be str, not %s" % space.type(w_hexstring).name))
+ hexstring = space.unicode_w(w_hexstring)
+
+ data = _hexstring_to_array(space, hexstring)
# 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)
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
@@ -342,6 +342,29 @@
W_StringObject.__init__(w_obj, value)
return w_obj
+def descr_fromhex(space, w_type, w_hexstring):
+ "bytes.fromhex(string) -> bytes\n"
+ "\n"
+ "Create a bytes object from a string of hexadecimal numbers.\n"
+ "Spaces between two numbers are accepted.\n"
+ "Example: bytes.fromhex('B9 01EF') -> bytes(b'\\xb9\\x01\\xef')."
+ from pypy.objspace.std.bytearraytype import _hexstring_to_array
+ if not space.is_w(space.type(w_hexstring), space.w_unicode):
+ raise OperationError(space.w_TypeError, space.wrap(
+ "must be str, not %s" % space.type(w_hexstring).name))
+ hexstring = space.unicode_w(w_hexstring)
+ chars = ''.join(_hexstring_to_array(space, hexstring))
+ if space.config.objspace.std.withrope:
+ from pypy.objspace.std.ropeobject import rope, W_RopeObject
+ w_obj = space.allocate_instance(W_RopeObject, w_type)
+ W_RopeObject.__init__(w_obj, rope.LiteralStringNode(chars))
+ return w_obj
+ else:
+ from pypy.objspace.std.stringobject import W_StringObject
+ w_obj = space.allocate_instance(W_StringObject, w_type)
+ W_StringObject.__init__(w_obj, chars)
+ return w_obj
+
# ____________________________________________________________
str_typedef = StdTypeDef("bytes",
@@ -349,7 +372,8 @@
__doc__ = '''str(object) -> string
Return a nice string representation of the object.
-If the argument is a string, the return value is the same object.'''
+If the argument is a string, the return value is the same object.''',
+ fromhex = gateway.interp2app(descr_fromhex, as_classmethod=True)
)
str_typedef.registermethods(globals())
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
@@ -99,6 +99,14 @@
import operator
raises(TypeError, operator.mod, b"%s", (1,))
+ def test_fromhex(self):
+ assert bytes.fromhex("abcd") == b'\xab\xcd'
+ assert b''.fromhex("abcd") == b'\xab\xcd'
+ assert bytes.fromhex("ab cd ef") == b'\xab\xcd\xef'
+ raises(TypeError, bytes.fromhex, b"abcd")
+ raises(TypeError, bytes.fromhex, True)
+ raises(ValueError, bytes.fromhex, "hello world")
+
def test_split(self):
assert b"".split() == []
assert b"".split(b'x') == [b'']
More information about the pypy-commit
mailing list