implement bit_length() for mp_type_int
int.to_bytes(size, byteorder) requires one to know how many bytes - size - the output is but int.bit_length() is not implemented.
>>> (1024).to_bytes(2, byteorder='big')
b'\x04\x00'
>>> (1024).to_bytes(10, byteorder='big')
b'\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00'
>>> (-1024).to_bytes(10, byteorder='big', signed=True)
b'\xff\xff\xff\xff\xff\xff\xff\xff\xfc\x00'
>>> x = 1000
>>> x.to_bytes((x.bit_length() + 7) // 8, byteorder='little')
b'\xe8\x03'
py/objint: Fix int.to_bytes() buffer size checks.
This "little fix" ended up growing and growing, so this might be too much code size impact. In which case this should be closed. There's a much smaller patch which only fixes the first point from the list below.
- No longer overflows if byte size is 0 (closes #13041)
- Raises OverflowError in any case where number won't fit into byte length. (Now matches CPython, previously MicroPython would return a truncated bytes object.)
- Document that micropython
int.to_bytes()doesn't implement the optionalsignedkwarg, but will behave as ifsigned=Truewhen the integer is negative (this is the current behaviour). Add tests for this also.
Changes are implemented for small ints, MPZ large ints, and "long long" large ints.
Adds a new set of unit tests for ints between 32 and 64 bits to increase coverage of "long long" large ints, which are otherwise untested.
Tested on unix port (64 bit small ints, MPZ long ints) and Zephyr STM32WB board (32 bit small ints, long long large ints).
Untested on a port whose native format is big endian (don't have one at hand).
This work was funded through GitHub Sponsors.