Skip to content
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

msgpack not choosing type correctly #6851

Open
polygnomial opened this issue Aug 31, 2022 · 6 comments · May be fixed by #7811
Open

msgpack not choosing type correctly #6851

polygnomial opened this issue Aug 31, 2022 · 6 comments · May be fixed by #7811
Assignees
Labels
Milestone

Comments

@polygnomial
Copy link

CircuitPython version

Adafruit CircuitPython 7.3.0-dirty on 2022-05-27; PyCubedv05-MRAM with samd51j19

Code/REPL

import msgpack, io
c = io.BytesIO()
msgpack.pack(145, c)
c.seek(0)
c.getvalue()

Behavior

Output in CircuitPython is b'\xd1\x00\x91', which is an int16, but this is encoded on unix as b'\xcc\x91', which is a uint8. The value is < 255 and positive, so I think it should be a uint8. Additionally, CircuitPython decodes b'\xcc\x91' as -111, which I'm pretty sure is incorrect per the msgpack spec.

Description

This causes problems for passing msgpack'd data back and forth between the two platforms. I recompiled the firmware with different pin definitions, but I don't think that is the issue.

Additional information

No response

@dhalbert dhalbert added this to the 8.0.0 milestone Aug 31, 2022
@dhalbert
Copy link
Collaborator

@bboser @iot49 of interest to you

@polygnomial
Copy link
Author

I'm poking around in the msgpack implementation, and best I can tell it never packs anything as a uint. That doesn't seem to be a huge problem in my use case, but unpacking is a bit of an issue. I am thinking for now I will get around this by on both sides encoding as a negative number (which will cause the packer to encode as a signed int) and then I will flip the sign after unpacking.

@Neradoc
Copy link

Neradoc commented Aug 31, 2022

I looked at it briefly when somebody brought it up on discord a few weeks ago, it's an issue that msgpack can't really decode what is encoded by C python. I think adding uints is straightforward, but there's 64 bit types to support too, including doubles which is the default that C-python uses for encoding floats it seems.

case 0xc1: // never used
case 0xcb: // float 64
case 0xcf: // uint 64
case 0xd3: // int 64
default:
mp_raise_NotImplementedError(translate("64 bit types"));

@iot49
Copy link

iot49 commented Aug 31, 2022

Python does not have native uint's - hence the encoder never generates them in the output. The decoder converts received uint's to int's.

You may consider adding special encoders (e.g. pack_uint) to serve your purpose.

@iot49
Copy link

iot49 commented Aug 31, 2022

Additionally, CircuitPython decodes b'\xcc\x91' as -111, which I'm pretty sure is incorrect per the msgpack spec.

Yes, that would be a bug. I have no time to fix right now.

@Neradoc
Copy link

Neradoc commented Aug 31, 2022

I think adding uints is straightforward

To be more accurate when I say that, a simple (uint*_t) cast works for ints that fit in a CP int (below 0x3FFFFFFF) but higher numbers require to use long ints,. I'll see if I can look into that.

Python does not have native uint's - hence the encoder never generates them in the output.

Note that C-Python does use uint for positive ints in msgpack. A matter of implementation choices I guess. I don't think we need it in CP because it's more code that does not add functionality, it only makes the packing potentially smaller.

python
Python 3.9.6 (default, Aug 11 2021, 01:29:00) 
>>> import msgpack
>>> msgpack.packb(151)
b'\xcc\x97'

Versus b'\xd1\x00\x97' in CP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants