mirror of
https://github.com/python/cpython.git
synced 2025-11-25 12:44:13 +00:00
bpo-16580: [doc] Add examples to int.to_bytes and int.from_bytes (GH-27760)
* added code equivs. for to_bytes and from_bytes Based on woparry's patch[1] from the relevant issue thread[2]. [1]: https://bugs.python.org/file30372/issue16580.patch [2]: https://bugs.python.org/issue16580 Co-authored-by: Mark Dickinson <dickinsm@gmail.com>
This commit is contained in:
parent
ed524b4569
commit
ad0a8a9c62
4 changed files with 73 additions and 0 deletions
|
|
@ -529,6 +529,18 @@ class`. In addition, it provides a few more methods:
|
|||
given, an :exc:`OverflowError` is raised. The default value for *signed*
|
||||
is ``False``.
|
||||
|
||||
Equivalent to::
|
||||
|
||||
def to_bytes(n, length, byteorder, signed=False):
|
||||
if byteorder == 'little':
|
||||
order = range(length)
|
||||
elif byteorder == 'big':
|
||||
order = reversed(range(length))
|
||||
else:
|
||||
raise ValueError("byteorder must be either 'little' or 'big'")
|
||||
|
||||
return bytes((n >> i*8) & 0xff for i in order)
|
||||
|
||||
.. versionadded:: 3.2
|
||||
|
||||
.. classmethod:: int.from_bytes(bytes, byteorder, *, signed=False)
|
||||
|
|
@ -559,6 +571,22 @@ class`. In addition, it provides a few more methods:
|
|||
The *signed* argument indicates whether two's complement is used to
|
||||
represent the integer.
|
||||
|
||||
Equivalent to::
|
||||
|
||||
def from_bytes(bytes, byteorder, signed=False):
|
||||
if byteorder == 'little':
|
||||
little_ordered = list(bytes)
|
||||
elif byteorder == 'big':
|
||||
little_ordered = list(reversed(bytes))
|
||||
else:
|
||||
raise ValueError("byteorder must be either 'little' or 'big'")
|
||||
|
||||
n = sum(b << i*8 for i, b in enumerate(little_ordered))
|
||||
if signed and little_ordered and (little_ordered[-1] & 0x80):
|
||||
n -= 1 << 8*len(little_ordered)
|
||||
|
||||
return n
|
||||
|
||||
.. versionadded:: 3.2
|
||||
|
||||
.. method:: int.as_integer_ratio()
|
||||
|
|
|
|||
|
|
@ -1103,6 +1103,13 @@ class LongTest(unittest.TestCase):
|
|||
|
||||
def test_to_bytes(self):
|
||||
def check(tests, byteorder, signed=False):
|
||||
def equivalent_python(n, length, byteorder, signed=False):
|
||||
if byteorder == 'little':
|
||||
order = range(length)
|
||||
elif byteorder == 'big':
|
||||
order = reversed(range(length))
|
||||
return bytes((n >> i*8) & 0xff for i in order)
|
||||
|
||||
for test, expected in tests.items():
|
||||
try:
|
||||
self.assertEqual(
|
||||
|
|
@ -1113,6 +1120,18 @@ class LongTest(unittest.TestCase):
|
|||
"failed to convert {0} with byteorder={1} and signed={2}"
|
||||
.format(test, byteorder, signed)) from err
|
||||
|
||||
try:
|
||||
self.assertEqual(
|
||||
equivalent_python(
|
||||
test, len(expected), byteorder, signed=signed),
|
||||
expected
|
||||
)
|
||||
except Exception as err:
|
||||
raise AssertionError(
|
||||
"Code equivalent from docs is not equivalent for "
|
||||
"conversion of {0} with byteorder byteorder={1} and "
|
||||
"signed={2}".format(test, byteorder, signed)) from err
|
||||
|
||||
# Convert integers to signed big-endian byte arrays.
|
||||
tests1 = {
|
||||
0: b'\x00',
|
||||
|
|
@ -1202,6 +1221,18 @@ class LongTest(unittest.TestCase):
|
|||
|
||||
def test_from_bytes(self):
|
||||
def check(tests, byteorder, signed=False):
|
||||
def equivalent_python(byte_array, byteorder, signed=False):
|
||||
if byteorder == 'little':
|
||||
little_ordered = list(byte_array)
|
||||
elif byteorder == 'big':
|
||||
little_ordered = list(reversed(byte_array))
|
||||
|
||||
n = sum(b << i*8 for i, b in enumerate(little_ordered))
|
||||
if signed and little_ordered and (little_ordered[-1] & 0x80):
|
||||
n -= 1 << 8*len(little_ordered)
|
||||
|
||||
return n
|
||||
|
||||
for test, expected in tests.items():
|
||||
try:
|
||||
self.assertEqual(
|
||||
|
|
@ -1212,6 +1243,17 @@ class LongTest(unittest.TestCase):
|
|||
"failed to convert {0} with byteorder={1!r} and signed={2}"
|
||||
.format(test, byteorder, signed)) from err
|
||||
|
||||
try:
|
||||
self.assertEqual(
|
||||
equivalent_python(test, byteorder, signed=signed),
|
||||
expected
|
||||
)
|
||||
except Exception as err:
|
||||
raise AssertionError(
|
||||
"Code equivalent from docs is not equivalent for "
|
||||
"conversion of {0} with byteorder={1!r} and signed={2}"
|
||||
.format(test, byteorder, signed)) from err
|
||||
|
||||
# Convert signed big-endian byte arrays to integers.
|
||||
tests1 = {
|
||||
b'': 0,
|
||||
|
|
|
|||
|
|
@ -306,6 +306,7 @@ Mitch Chapman
|
|||
Matt Chaput
|
||||
William Chargin
|
||||
Yogesh Chaudhari
|
||||
Gautam Chaudhuri
|
||||
David Chaum
|
||||
Nicolas Chauvat
|
||||
Jerry Chen
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
Added code equivalents for the :meth:`int.to_bytes` and :meth:`int.from_bytes`
|
||||
methods, as well as tests ensuring that these code equivalents are valid.
|
||||
Loading…
Add table
Add a link
Reference in a new issue