py/objint: Make byteorder argument optional in byte-conversion methods. by AmirHmZz · Pull Request #14387 · micropython/micropython · GitHub
Skip to content

py/objint: Make byteorder argument optional in byte-conversion methods.#14387

Merged
dpgeorge merged 4 commits into
micropython:masterfrom
AmirHmZz:to_bytes_arg_fix
Sep 2, 2024
Merged

py/objint: Make byteorder argument optional in byte-conversion methods.#14387
dpgeorge merged 4 commits into
micropython:masterfrom
AmirHmZz:to_bytes_arg_fix

Conversation

@AmirHmZz

Copy link
Copy Markdown
Contributor

This PR intends to make byteorder argument optional in int.to_bytes() and int.from_bytes() methods. According to CPython documentation, byteorder argument is optional and set to "big" by default. This PR makes Micropython compatible with CPython in this case.

@codecov

codecov Bot commented Apr 28, 2024

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Apr 28, 2024

Copy link
Copy Markdown

Code size report:

   bare-arm:   +16 +0.028% 
minimal x86:   +32 +0.017% 
   unix x64:   +32 +0.004% standard
      stm32:    +8 +0.002% PYBV10
     mimxrt:    +0 +0.000% TEENSY40
        rp2:   +16 +0.002% RPI_PICO_W
       samd:    +8 +0.003% ADAFRUIT_ITSYBITSY_M4_EXPRESS

@projectgus

projectgus commented Apr 28, 2024

Copy link
Copy Markdown
Contributor

Hi @AmirHmZz,

Thanks for noticing this and submitting this PR.

According to CPython documentation, byteorder argument is optional and set to "big" by default. This PR makes Micropython compatible with CPython in this case.

To expand a bit on this, these byteorder arguments only became optional in CPython 3.11 (3.10 version is here). MicroPython only advertises full compatibility with CPython 3.4 at this point.

That said, there are a number of improvements from later CPython versions that are supported in MicroPython and this one might be useful to have. 😁

I was going to suggest adding unit test cases for these as well, although it will be a little fiddly because the unit tests compare behaviour with CPython by default, and only some CPython versions will accept the optional argument.

@projectgus projectgus added the py-core Relates to py/ directory in source label Apr 28, 2024
@AmirHmZz

AmirHmZz commented Apr 29, 2024

Copy link
Copy Markdown
Contributor Author

@projectgus One of the most important points about making that arg optional is reducing redundant allocations and deallocations on "big" string which is used in most cases. I use int>bytes and bytes>int conversions many many times in my projects and most of them are in the loops.

I was going to suggest adding unit test cases for these as well, although it will be a little fiddly because the unit tests compare behaviour with CPython by default, and only some CPython versions will accept the optional argument.

Where should I add unit tests? I will be glad to contribute!

@projectgus

Copy link
Copy Markdown
Contributor

I asked @dpgeorge about this change and it seems like it really will depend on the code size hit as to whether it's desirable to merge. It's currently small, which is encouraging.

However, Damien noted that in Python 3.11 the int.to_bytes() function also gained a default value for the length argument. What's the size impact if this is added as well? It's desirable to keep the CPython compatibility changes consistent as possible, although if that additional change somehow has much higher code size impact then it can be dropped.

Where should I add unit tests? I will be glad to contribute!

Thanks, that'd be great!

tests/basic/int_bytes.py has the current test cases for int.to_bytes and int.from_bytes. However, this test file works by comparing output to CPython which won't be consistent for this change. You'll need to do something like tests/basics/string_format_cp310.py and tests/basics/string_format_cp310.exp which has the test case and expected output in separate files.

Suggest something like int_bytes_optional_args_cp311.py.

making that arg optional is reducing redundant allocations and deallocations on "big" string which is used in most cases. I use int>bytes and bytes>int conversions many many times in my projects and most of them are in the loops.

I would have expected if you're either freezing your .py files into the firmware, or compiling to .mpy with mpy-cross, then the "big" string should end up interned as a QSTR with minimal performance impact. If you've got some "real world" type code where this change makes a significant performance difference, please share it as it'd be interesting to look into.

@AmirHmZz AmirHmZz force-pushed the to_bytes_arg_fix branch 2 times, most recently from 1bc8778 to ca84705 Compare April 30, 2024 16:27
@AmirHmZz

Copy link
Copy Markdown
Contributor Author

@projectgus Thanks for feedback. I've added tests and also made length optional in int.to_bytes().

@projectgus

Copy link
Copy Markdown
Contributor

Nice work @AmirHmZz, thanks! Implementation and tests look good to me. It's encouraging this implementation is free or almost free in terms of code size on most of the smaller microcontroller ports.

@projectgus projectgus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, I think whether this is merged will come down to @dpgeorge's call about the binary size cost.

@projectgus

Copy link
Copy Markdown
Contributor

One thing about the optional length argument for int.to_bytes(), currently MicroPython will truncate to the length if the int doesn't fit (CPython raises an exception.) Which may be a bit counter-intuitive. However, I have a PR open (#13087) which changes the behaviour to match CPython on this.

(Regrettably, that PR adds more than 8 bytes binary size! 😆)

@AmirHmZz AmirHmZz force-pushed the to_bytes_arg_fix branch 2 times, most recently from 45d7909 to 52a3d60 Compare July 12, 2024 11:43
@AmirHmZz

AmirHmZz commented Jul 12, 2024

Copy link
Copy Markdown
Contributor Author

I've rebased this PR against master.

@AmirHmZz AmirHmZz requested a review from projectgus July 13, 2024 20:32
@projectgus

Copy link
Copy Markdown
Contributor

This still looks good to me, and the code size impact is pretty small, but we'll need to wait for @dpgeorge to take a look now.

This was made optional in CPython 3.11.

Signed-off-by: Amirreza Hamzavi <amirrezahamzavi2000@gmail.com>
This was made optional in CPython 3.11.

Signed-off-by: Amirreza Hamzavi <amirrezahamzavi2000@gmail.com>
This was made optional in CPython 3.11.

Signed-off-by: Amirreza Hamzavi <amirrezahamzavi2000@gmail.com>
Signed-off-by: Amirreza Hamzavi <amirrezahamzavi2000@gmail.com>
@dpgeorge dpgeorge merged commit 1897fe6 into micropython:master Sep 2, 2024
@dpgeorge

dpgeorge commented Sep 2, 2024

Copy link
Copy Markdown
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

py-core Relates to py/ directory in source

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants