8000 Merge pull request #128 from beckjake/newint_bytes · thecodingchicken/python-future@8f22812 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8f22812

Browse files
committed
Merge pull request PythonCharmers#128 from beckjake/newint_bytes
Add handling for signed integers to newint.to_bytes and newint.from_bytes
2 parents 5924c81 + 8ff9ff5 commit 8f22812

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

src/future/types/newint.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -299,20 +299,29 @@ def to_bytes(self, length, byteorder='big', signed=False):
299299
used to represent the integer. If signed is False and a negative integer
300300
is given, an OverflowError is raised.
301301
"""
302-
if signed:
303-
raise NotImplementedError("Not yet implemented. Please contribute a patch at http://python-future.org")
302+
if length < 0:
303+
raise ValueError("length argument must be non-negative")
304+
if length == 0 and self == 0:
305+
return newbytes()
306+
if signed and self < 0:
307+
bits = length * 8
308+
num = (2**bits) + self
309+
if num <= 0:
310+
raise OverflowError("int too smal to convert")
304311
else:
305312
if self < 0:
306313
raise OverflowError("can't convert negative int to unsigned")
307314
num = self
308315
if byteorder not in ('little', 'big'):
309316
raise ValueError("byteorder must be either 'little' or 'big'")
310-
if length < 0:
311-
raise ValueError("length argument must be non-negative")
312-
if length == 0 and num == 0:
313-
return newbytes()
314317
h = b'%x' % num
315318
s = newbytes((b'0'*(len(h) % 2) + h).zfill(length*2).decode('hex'))
319+
if signed:
320+
high_set = s[0] & 0x80
321+
if self > 0 and high_set:
322+
raise OverflowError("int too big to convert")
323+
if self < 0 and not high_set:
324+
raise OverflowError("int too small to convert")
316325
if len(s) > length:
317326
raise OverflowError("int too big to convert")
318327
return s if byteorder == 'big' else s[::-1]
@@ -335,8 +344,6 @@ def from_bytes(cls, mybytes, byteorder='big', signed=False):
335344
The signed keyword-only argument indicates whether two's complement is
336345
used to represent the integer.
337346
"""
338-
if signed:
339-
raise NotImplementedError("Not yet implemented. Please contribute a patch at http://python-future.org")
340347
if byteorder not in ('little', 'big'):
341348
raise ValueError("byteorder must be either 'little' or 'big'")
342349
if isinstance(mybytes, unicode):
@@ -351,6 +358,8 @@ def from_bytes(cls, mybytes, byteorder='big', signed=False):
351358
# The encode() method has been disabled by newbytes, but Py2's
352359
# str has it:
353360
num = int(native(b).encode('hex'), 16)
361+
if signed and (b[0] & 0x80):
362+
num = num - (2 ** (len(b)*8))
354363
return cls(num)
355364

356365

0 commit comments

Comments
 (0)
0