Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 2, 2024

Conversation

AmirHmZz
Copy link
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.

Copy link

codecov bot commented Apr 28, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.43%. Comparing base (9670666) to head (1897fe6).
Report is 4 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #14387      +/-   ##
==========================================
- Coverage   98.43%   98.43%   -0.01%     
==========================================
  Files         163      163              
  Lines       21295    21294       -1     
==========================================
- Hits        20961    20960       -1     
  Misses        334      334              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

github-actions bot commented Apr 28, 2024

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
Copy link
Contributor

projectgus commented Apr 28, 2024

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
Copy link
Contributor Author

AmirHmZz commented Apr 29, 2024

@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
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
Contributor Author

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

@projectgus
Copy link
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.

Copy link
Contributor

@projectgus projectgus left a comment

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
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
Copy link
Contributor Author

AmirHmZz commented Jul 12, 2024

I've rebased this PR against master.

@AmirHmZz AmirHmZz requested a review from projectgus July 13, 2024 20:32
@projectgus
Copy link
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
64 checks passed
@dpgeorge
Copy link
Member

dpgeorge commented Sep 2, 2024

Thanks for this, it does look good now: CPython compatibility with minimal code size increase.

Rebased and merged!

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
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy