Author: Amaury Forgeot d'Arc <[email protected]>
Branch: py3k
Changeset: r48034:6d32eeb3fc38
Date: 2011-10-13 22:38 +0200
http://bitbucket.org/pypy/pypy/changeset/6d32eeb3fc38/
Log: Implement a basic version of long.from_bytes, it's enough for the
random module. Also attach it to 'int', until these types are
unified...
diff --git a/pypy/objspace/std/inttype.py b/pypy/objspace/std/inttype.py
--- a/pypy/objspace/std/inttype.py
+++ b/pypy/objspace/std/inttype.py
@@ -33,6 +33,10 @@
val >>= 1
return space.wrap(bits)
[email protected]_spec(s='bufferstr', byteorder=str)
+def descr_from_bytes(space, w_cls, s, byteorder):
+ from pypy.objspace.std.longtype import descr_from_bytes
+ return descr_from_bytes(space, space.w_long, s)
def wrapint(space, x):
if space.config.objspace.std.withsmallint:
@@ -205,5 +209,6 @@
denominator = typedef.GetSetProperty(descr_get_denominator),
real = typedef.GetSetProperty(descr_get_real),
imag = typedef.GetSetProperty(descr_get_imag),
+ from_bytes = gateway.interp2app(descr_from_bytes, as_classmethod=True),
)
int_typedef.registermethods(globals())
diff --git a/pypy/objspace/std/longtype.py b/pypy/objspace/std/longtype.py
--- a/pypy/objspace/std/longtype.py
+++ b/pypy/objspace/std/longtype.py
@@ -113,6 +113,15 @@
raise OperationError(space.w_OverflowError,
space.wrap("too many digits in integer"))
[email protected]_spec(s='bufferstr', byteorder=str)
+def descr_from_bytes(space, w_cls, s, byteorder):
+ from pypy.rlib.rbigint import rbigint
+ bigint = rbigint.frombytes(s)
+ from pypy.objspace.std.longobject import W_LongObject
+ w_obj = space.allocate_instance(W_LongObject, w_cls)
+ W_LongObject.__init__(w_obj, bigint)
+ return w_obj
+
# ____________________________________________________________
long_typedef = StdTypeDef("long",
@@ -130,5 +139,6 @@
real = typedef.GetSetProperty(descr_get_real),
imag = typedef.GetSetProperty(descr_get_imag),
bit_length = gateway.interp2app(bit_length),
+ from_bytes = gateway.interp2app(descr_from_bytes, as_classmethod=True),
)
long_typedef.registermethods(globals())
diff --git a/pypy/objspace/std/test/test_longobject.py
b/pypy/objspace/std/test/test_longobject.py
--- a/pypy/objspace/std/test/test_longobject.py
+++ b/pypy/objspace/std/test/test_longobject.py
@@ -310,6 +310,9 @@
assert (-1<<40).bit_length() == 41
assert ((2**31)-1).bit_length() == 31
+ def test_from_bytes(self):
+ assert long.from_bytes(b'c', 'little') == 99
+ assert long.from_bytes(b'\x01\x01', 'little') == 257
def test_negative_zero(self):
x = eval("-0L")
diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py
--- a/pypy/rlib/rbigint.py
+++ b/pypy/rlib/rbigint.py
@@ -215,6 +215,24 @@
# then modify the result.
return _decimalstr_to_bigint(s)
+ @staticmethod
+ def frombytes(s):
+ accum = 0
+ accumbits = 0
+ digits = []
+ for ch in s:
+ c = ord(ch)
+ accum <<= 8
+ accum |= c
+ accumbits += 8
+ if accumbits >= SHIFT:
+ digits.append(_store_digit(accum & MASK))
+ accum >>= SHIFT
+ accumbits -= SHIFT
+ if accumbits:
+ digits.append(_store_digit(accum))
+ return rbigint(digits, 1)
+
@jit.elidable
def toint(self):
"""
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit