Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 07e737d

Browse files
warsawbrandtbucher
andauthored
bpo-45155 : Default arguments for int.to_bytes(length=1, byteorder=sys.byteorder) (#28265)
Add default arguments for int.to_bytes() and int.from_bytes() Co-authored-by: Brandt Bucher <[email protected]>
1 parent a9757bf commit 07e737d

6 files changed

Lines changed: 127 additions & 65 deletions

File tree

Doc/library/stdtypes.rst

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ class`. In addition, it provides a few more methods:
499499

500500
.. versionadded:: 3.10
501501

502-
.. method:: int.to_bytes(length, byteorder, *, signed=False)
502+
.. method:: int.to_bytes(length=1, byteorder='big', *, signed=False)
503503

504504
Return an array of bytes representing an integer.
505505

@@ -513,25 +513,31 @@ class`. In addition, it provides a few more methods:
513513
>>> x.to_bytes((x.bit_length() + 7) // 8, byteorder='little')
514514
b'\xe8\x03'
515515

516-
The integer is represented using *length* bytes. An :exc:`OverflowError`
517-
is raised if the integer is not representable with the given number of
518-
bytes.
516+
The integer is represented using *length* bytes, and defaults to 1. An
517+
:exc:`OverflowError` is raised if the integer is not representable with
518+
the given number of bytes.
519519

520520
The *byteorder* argument determines the byte order used to represent the
521-
integer. If *byteorder* is ``"big"``, the most significant byte is at the
522-
beginning of the byte array. If *byteorder* is ``"little"``, the most
523-
significant byte is at the end of the byte array. To request the native
524-
byte order of the host system, use :data:`sys.byteorder` as the byte order
525-
value.
521+
integer, and defaults to ``"big"``. If *byteorder* is
522+
``"big"``, the most significant byte is at the beginning of the byte
523+
array. If *byteorder* is ``"little"``, the most significant byte is at
524+
the end of the byte array.
526525

527526
The *signed* argument determines whether two's complement is used to
528527
represent the integer. If *signed* is ``False`` and a negative integer is
529528
given, an :exc:`OverflowError` is raised. The default value for *signed*
530529
is ``False``.
531530

531+
The default values can be used to conveniently turn an integer into a
532+
single byte object. However, when using the default arguments, don't try
533+
to convert a value greater than 255 or you'll get an :exc:`OverflowError`::
534+
535+
>>> (65).to_bytes()
536+
b'A'
537+
532538
Equivalent to::
533539

534-
def to_bytes(n, length, byteorder, signed=False):
540+
def to_bytes(n, length=1, byteorder='big', signed=False):
535541
if byteorder == 'little':
536542
order = range(length)
537543
elif byteorder == 'big':
@@ -542,8 +548,10 @@ class`. In addition, it provides a few more methods:
542548
return bytes((n >> i*8) & 0xff for i in order)
543549

544550
.. versionadded:: 3.2
551+
.. versionchanged:: 3.11
552+
Added default argument values for ``length`` and ``byteorder``.
545553

546-
.. classmethod:: int.from_bytes(bytes, byteorder, *, signed=False)
554+
.. classmethod:: int.from_bytes(bytes, byteorder='big', *, signed=False)
547555

548556
Return the integer represented by the given array of bytes.
549557

@@ -562,18 +570,18 @@ class`. In addition, it provides a few more methods:
562570
iterable producing bytes.
563571

564572
The *byteorder* argument determines the byte order used to represent the
565-
integer. If *byteorder* is ``"big"``, the most significant byte is at the
566-
beginning of the byte array. If *byteorder* is ``"little"``, the most
567-
significant byte is at the end of the byte array. To request the native
568-
byte order of the host system, use :data:`sys.byteorder` as the byte order
569-
value.
573+
integer, and defaults to ``"big"``. If *byteorder* is
574+
``"big"``, the most significant byte is at the beginning of the byte
575+
array. If *byteorder* is ``"little"``, the most significant byte is at
576+
the end of the byte array. To request the native byte order of the host
577+
system, use :data:`sys.byteorder` as the byte order value.
570578

571579
The *signed* argument indicates whether two's complement is used to
572580
represent the integer.
573581

574582
Equivalent to::
575583

576-
def from_bytes(bytes, byteorder, signed=False):
584+
def from_bytes(bytes, byteorder='big', signed=False):
577585
if byteorder == 'little':
578586
little_ordered = list(bytes)
579587
elif byteorder == 'big':
@@ -588,6 +596,8 @@ class`. In addition, it provides a few more methods:
588596
return n
589597

590598
.. versionadded:: 3.2
599+
.. versionchanged:: 3.11
600+
Added default argument value for ``byteorder``.
591601

592602
.. method:: int.as_integer_ratio()
593603

Lib/test/test_call.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def test_varargs2(self):
3939
self.assertRaisesRegex(TypeError, msg, {}.__contains__, 0, 1)
4040

4141
def test_varargs3(self):
42-
msg = r"^from_bytes\(\) takes exactly 2 positional arguments \(3 given\)"
42+
msg = r"^from_bytes\(\) takes at most 2 positional arguments \(3 given\)"
4343
self.assertRaisesRegex(TypeError, msg, int.from_bytes, b'a', 'little', False)
4444

4545
def test_varargs1min(self):

Lib/test/test_long.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,9 +1117,18 @@ def equivalent_python(n, length, byteorder, signed=False):
11171117
expected)
11181118
except Exception as err:
11191119
raise AssertionError(
1120-
"failed to convert {0} with byteorder={1} and signed={2}"
1120+
"failed to convert {} with byteorder={} and signed={}"
11211121
.format(test, byteorder, signed)) from err
11221122

1123+
# Test for all default arguments.
1124+
if len(expected) == 1 and byteorder == 'big' and not signed:
1125+
try:
1126+
self.assertEqual(test.to_bytes(), expected)
1127+
except Exception as err:
1128+
raise AssertionError(
1129+
"failed to convert {} with default arguments"
1130+
.format(test)) from err
1131+
11231132
try:
11241133
self.assertEqual(
11251134
equivalent_python(
@@ -1240,9 +1249,20 @@ def equivalent_python(byte_array, byteorder, signed=False):
12401249
expected)
12411250
except Exception as err:
12421251
raise AssertionError(
1243-
"failed to convert {0} with byteorder={1!r} and signed={2}"
1252+
"failed to convert {} with byteorder={!r} and signed={}"
12441253
.format(test, byteorder, signed)) from err
12451254

1255+
# Test for all default arguments.
1256+
if byteorder == 'big' and not signed:
1257+
try:
1258+
self.assertEqual(
1259+
int.from_bytes(test),
1260+
expected)
1261+
except Exception as err:
1262+
raise AssertionError(
1263+
"failed to convert {} with default arugments"
1264+
.format(test)) from err
1265+
12461266
try:
12471267
self.assertEqual(
12481268
equivalent_python(test, byteorder, signed=signed),
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:meth:`int.to_bytes` and :meth:`int.from_bytes` now take a default value of
2+
``"big"`` for the ``byteorder`` argument. :meth:`int.to_bytes` also takes a
3+
default value of ``1`` for the ``length`` argument.

Objects/clinic/longobject.c.h

Lines changed: 59 additions & 35 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Objects/longobject.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5521,15 +5521,16 @@ int_as_integer_ratio_impl(PyObject *self)
55215521
/*[clinic input]
55225522
int.to_bytes
55235523
5524-
length: Py_ssize_t
5524+
length: Py_ssize_t = 1
55255525
Length of bytes object to use. An OverflowError is raised if the
5526-
integer is not representable with the given number of bytes.
5527-
byteorder: unicode
5526+
integer is not representable with the given number of bytes. Default
5527+
is length 1.
5528+
byteorder: unicode(c_default="NULL") = "big"
55285529
The byte order used to represent the integer. If byteorder is 'big',
55295530
the most significant byte is at the beginning of the byte array. If
55305531
byteorder is 'little', the most significant byte is at the end of the
55315532
byte array. To request the native byte order of the host system, use
5532-
`sys.byteorder' as the byte order value.
5533+
`sys.byteorder' as the byte order value. Default is to use 'big'.
55335534
*
55345535
signed as is_signed: bool = False
55355536
Determines whether two's complement is used to represent the integer.
@@ -5542,12 +5543,14 @@ Return an array of bytes representing an integer.
55425543
static PyObject *
55435544
int_to_bytes_impl(PyObject *self, Py_ssize_t length, PyObject *byteorder,
55445545
int is_signed)
5545-
/*[clinic end generated code: output=89c801df114050a3 input=ddac63f4c7bf414c]*/
5546+
/*[clinic end generated code: output=89c801df114050a3 input=d42ecfb545039d71]*/
55465547
{
55475548
int little_endian;
55485549
PyObject *bytes;
55495550

5550-
if (_PyUnicode_EqualToASCIIId(byteorder, &PyId_little))
5551+
if (byteorder == NULL)
5552+
little_endian = 0;
5553+
else if (_PyUnicode_EqualToASCIIId(byteorder, &PyId_little))
55515554
little_endian = 1;
55525555
else if (_PyUnicode_EqualToASCIIId(byteorder, &PyId_big))
55535556
little_endian = 0;
@@ -5586,12 +5589,12 @@ int.from_bytes
55865589
support the buffer protocol or be an iterable object producing bytes.
55875590
Bytes and bytearray are examples of built-in objects that support the
55885591
buffer protocol.
5589-
byteorder: unicode
5592+
byteorder: unicode(c_default="NULL") = "big"
55905593
The byte order used to represent the integer. If byteorder is 'big',
55915594
the most significant byte is at the beginning of the byte array. If
55925595
byteorder is 'little', the most significant byte is at the end of the
55935596
byte array. To request the native byte order of the host system, use
5594-
`sys.byteorder' as the byte order value.
5597+
`sys.byteorder' as the byte order value. Default is to use 'big'.
55955598
*
55965599
signed as is_signed: bool = False
55975600
Indicates whether two's complement is used to represent the integer.
@@ -5602,12 +5605,14 @@ Return the integer represented by the given array of bytes.
56025605
static PyObject *
56035606
int_from_bytes_impl(PyTypeObject *type, PyObject *bytes_obj,
56045607
PyObject *byteorder, int is_signed)
5605-
/*[clinic end generated code: output=efc5d68e31f9314f input=cdf98332b6a821b0]*/
5608+
/*[clinic end generated code: output=efc5d68e31f9314f input=33326dccdd655553]*/
56065609
{
56075610
int little_endian;
56085611
PyObject *long_obj, *bytes;
56095612

5610-
if (_PyUnicode_EqualToASCIIId(byteorder, &PyId_little))
5613+
if (byteorder == NULL)
5614+
little_endian = 0;
5615+
else if (_PyUnicode_EqualToASCIIId(byteorder, &PyId_little))
56115616
little_endian = 1;
56125617
else if (_PyUnicode_EqualToASCIIId(byteorder, &PyId_big))
56135618
little_endian = 0;

0 commit comments

Comments
 (0)