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

module msgpack #3659

Merged
merged 36 commits into from Jan 11, 2021
Merged

module msgpack #3659

merged 36 commits into from Jan 11, 2021

Conversation

ghost
Copy link

@ghost ghost commented Nov 9, 2020

Support for msgpack (https://msgpack.org/) encoding/decoding. Like json, but binary encoding.

Example:

import msgpack
from io import StringIO

objs = [
    ( True, False, None, 0, 1, -1, 'abc' ),
    { 'a': 1, 'b': (2, 3) },
    123,
    'abc',
    1.2345,
    ( 1, 'abc', 5.3 ),
    {
        "a tuple": (1, 42, 3.141, 1337, "help"),
        "a string": "bla",
        "another dict": {"foo": "bar", "key": "value", "the answer": 42}
    },
    tuple(range(50)),
]

for obj in objs:
    s = StringIO()
    msgpack.pack(obj, s)
    s.seek(0)
    out = msgpack.unpack(s)
    if obj == out:
        print("ok:", obj)
    else:
        print("!!! MISMACH:\n    {}\n    {}".format(obj, out))

Output:

ok: (True, False, None, 0, 1, -1, 'abc')
ok: {'a': 1, 'b': (2, 3)}
ok: 123
ok: abc
ok: 1.2345
ok: (1, 'abc', 5.3)
ok: {'another dict': {'the answer': 42, 'foo': 'bar', 'key': 'value'}, 'a tuple': (1, 42, 3.141, 1337, 'help'), 'a string': 'bla'}
ok: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49)

@tannewt tannewt self-requested a review November 9, 2020 23:46
@tannewt tannewt added cpython api modules from cpython enhancement labels Nov 9, 2020
@tannewt tannewt added this to the 6.x.0 - Features milestone Nov 9, 2020
Copy link
Member

@tannewt tannewt left a comment

Choose a reason for hiding this comment

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

Thank you for the PR! I've left a few suggestions. Let me know if you have any questions.

py/circuitpy_mpconfig.h Outdated Show resolved Hide resolved
py/circuitpy_mpconfig.mk Outdated Show resolved Hide resolved
ports/nrf/mpconfigport.mk Outdated Show resolved Hide resolved
shared-bindings/msgpack/__init__.c Outdated Show resolved Hide resolved
@tannewt
Copy link
Member

tannewt commented Nov 9, 2020

(The CI error is due to missing documentation in shared-bindings' __init__.c. Take a look at time or struct for module-only examples.)

Copy link
Member

@tannewt tannewt left a comment

Choose a reason for hiding this comment

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

Looks great! To fix the translation issue run make translate at the top level and commit the result. It'll add entries to locale/circuitpython.pot. Then, the CI should build every board.

@ghost
Copy link
Author

ghost commented Nov 12, 2020

Still fails for some architectures.

More significantly, the current version does not convert output to big endian. I have a fix in a few days.

@ghost
Copy link
Author

ghost commented Nov 12, 2020

Updated to correctly output binary in big endian format.
Verified with round-trips c-python -> circuitpython -> c-python: https://github.com/iot49/iot-notebooks/blob/main/tests/msgpack.ipynb.

Tests are fairly comprehensive, except big data structures (due to memory limitations).

Copy link
Member

@tannewt tannewt left a comment

Choose a reason for hiding this comment

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

Looks like it needs another make translate.

@tannewt
Copy link
Member

tannewt commented Nov 16, 2020

Looks like a number of SAMD21 boards are out of flash now. In the short term, we can disable them on an individual basis but in the longer term we'll want to follow up with a way to freeze the modules on SAMD21. The spresence build is also failing due to a type issue.

@ghost
Copy link
Author

ghost commented Nov 17, 2020

I've disabled msgpack for the builds that are tight on memory.

Regarding the spresence :

First error is:

In file included from ../../shared-module/msgpack/__init__.c:29:
spresense-exported-sdk/nuttx/include/inttypes.h:185:31: error: unknown type name 'wchar_t'
  185 | intmax_t  wcstoimax(FAR const wchar_t *nptr, FAR wchar_t **endptr, int base);
      |                               ^~~~~~~

I added #include <stddef.h> as the first import, now I get the error below. Looks to be a problem with whatever stddef.h the port imports. Anyway - no clue how to fix it; I simply disabled msgpack for this port as well.

spresense-exported-sdk/nuttx/include/inttypes.h:186:50: note: 'wchar_t' is defined in header '<stddef.h>'; did you forget to '#include <stddef.h>'?
../../shared-module/msgpack/__init__.c:60:13: error: conflicting types for 'read'
   60 | STATIC void read(msgpack_stream_t *s, void *buf, mp_uint_t size) {
      |             ^~~~
In file included from spresense-exported-sdk/nuttx/include/pthread.h:52,
                 from spresense-exported-sdk/nuttx/include/nuttx/sched.h:50,
                 from spresense-exported-sdk/nuttx/include/sched.h:49,
                 from spresense-exported-sdk/nuttx/include/stdio.h:48,
                 from ../../shared-module/msgpack/__init__.c:28:

@ghost ghost requested a review from tannewt November 17, 2020 20:27
@ghost
Copy link
Author

ghost commented Nov 17, 2020

For some reason, the checks are not re-run. I'd expect them to pass, but how can I know?

@tannewt
Copy link
Member

tannewt commented Nov 17, 2020

@iot49 disabling is totally fine. @kamtom480 may know what the issue is.

I'm not sure why the CI didn't run. I'll look into it.

tannewt
tannewt previously approved these changes Nov 17, 2020
@tannewt
Copy link
Member

tannewt commented Nov 17, 2020

Ah, I think you need to fix the merge conflict before the CI can run because it runs on the merge.

@kamtom480
Copy link

@iot49 Regarding the spresence, could you rename the read and write function? I think the problem is in the header of the read and write functions in Spresense which are not compatible with your read and write functions.

@kamtom480
Copy link

@iot49 Thank you for renaming the read and write functions. The second problem is in the Spresense SDK configuration. I will fix this. You can disable msgpack for the Spresense for now.

@ghost
Copy link
Author

ghost commented Nov 18, 2020

@tannewt Sorry to bother again - do you have an idea how to fix the remaining (new) 3 errors, all of the same format:

Run actions/upload-artifact@v2
  with:
    name: espressif_saola_1_wrover
    path: bin/espressif_saola_1_wrover
    if-no-files-found: warn
  env:
    pythonLocation: /opt/hostedtoolcache/Python/3.8.6/x64
With the provided path, there will be 36 file(s) uploaded
Error: read ECONNRESET

@tannewt
Copy link
Member

tannewt commented Nov 19, 2020

@iot49 Those are network failures. You don't need to worry about them.

@tannewt
Copy link
Member

tannewt commented Dec 1, 2020

Would you mind rebasing this? I'm a bit worried that the diff includes a lot of extra changes.

If you are uncomfortable with git, then I can do it for you.

@ghost
Copy link
Author

ghost commented Dec 2, 2020

| If you are uncomfortable with git, then I can do it for you.

I'd appreciate this. I've tried to fix this mess, but seem to only add to it. Hate to admit it.

@ghost
Copy link
Author

ghost commented Dec 10, 2020

Essentially complete, except for a newline somewhere in the documentation but I can't figure out where. I'd appreciate a hint if you have time to take a look. Thanks for fixing the branch.

Should tests be added to the tests directory?

The class is a strict sub-set of the c-version. I use it for communication between Python interpreters.

@tannewt
Copy link
Member

tannewt commented Dec 10, 2020

Essentially complete, except for a newline somewhere in the documentation but I can't figure out where. I'd appreciate a hint if you have time to take a look. Thanks for fixing the branch.

I think you need more

//|

these lines lead to empty lines in the resulting rst. I think you need one after every section. See here for an example: https://github.com/adafruit/circuitpython/blob/main/shared-bindings/struct/__init__.c#L51

Should tests be added to the tests directory?

If you like. Not required.

The class is a strict sub-set of the c-version. I use it for communication between Python interpreters.

Nice!

@ghost
Copy link
Author

ghost commented Dec 10, 2020

I think you need more

//|

Thanks, did that!

Now CI is not running: "Workflow runs completed with no jobs"

@tannewt
Copy link
Member

tannewt commented Dec 11, 2020

The build wasn't running due to the merge conflict. I've fixed it so make sure and update your local copy.

I think you'll need ... anywhere implementation would have been, such as in a function call.

@tannewt
Copy link
Member

tannewt commented Jan 6, 2021

Looks like there is a doc build error:

/home/runner/work/circuitpython/circuitpython/shared-bindings/msgpack/index.rst:34:Definition list ends without a blank line; unexpected unindent.

@ghost
Copy link
Author

ghost commented Jan 6, 2021 via email

@tannewt
Copy link
Member

tannewt commented Jan 6, 2021

Thanks for looking into this again. It's time to quit. You have better things to do and I have no clue which blank line is missing. I've used the library extensively and it works correctly as best I can tell. So if perhaps in the future someone has a need this might be a starting point. Sorry to have wasted your time.

You are so close! I'll look now and see if I can find it. The line number is for the intermediate generated file.

@ghost
Copy link
Author

ghost commented Jan 6, 2021 via email

@tannewt
Copy link
Member

tannewt commented Jan 6, 2021

I just pushed the fixes to: cdad59f

You can build the docs locally with make html at the top level. There are some install instructions for sphinx here: https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library/sharing-our-docs-on-readthedocs I think you may also need to pip install sphinxcontrib-svg2pdfconverter and recommonmark too.

@FoamyGuy
Copy link
Collaborator

FoamyGuy commented Jan 6, 2021

Looks like it ran out of space on a few more of the smaller devices.

I can try to disable this new module on those devices this week to see if that will get it passing CI.

Thanks for all of your work on this @iot49! This looks very cool, I am interested using this for a few different things. Am willing to help out any way that I can to get this to the finish line.

@FoamyGuy
Copy link
Collaborator

FoamyGuy commented Jan 9, 2021

latest commit disables msgpack on the 3 boards that failed. 🤞

❯ make BOARD=qtpy_m0_haxpress

249216 bytes used, 4480 bytes free in flash firmware space out of 253696 bytes (247.75kB).
10908 bytes used, 21860 bytes free in ram for stack and heap out of 32768 bytes (32.0kB).
❯ make BOARD=stackrduino_m0_pro

251304 bytes used, 2392 bytes free in flash firmware space out of 253696 bytes (247.75kB).
10892 bytes used, 21876 bytes free in ram for stack and heap out of 32768 bytes (32.0kB).
❯ make BOARD=pca10100

233648 bytes used, 3920 bytes free in flash firmware space out of 237568 bytes (232.0kB).
41500 bytes used, 89572 bytes free in ram for stack and heap out of 131072 bytes (128.0kB).

@FoamyGuy
Copy link
Collaborator

FoamyGuy commented Jan 9, 2021

🎉 its passing now. I also tested this successfully (albeit very basically) with this code:

import msgpack
from io import StringIO

s = StringIO()
msgpack.pack({"test":"hello","num":4}, s)
print(s)
s.seek(0)
out = msgpack.unpack(s)
print(out)

Copy link
Member

@tannewt tannewt left a comment

Choose a reason for hiding this comment

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

Thanks @iot49 and @FoamyGuy. Merging now

@tannewt tannewt merged commit 9124529 into adafruit:main Jan 11, 2021
@ghost
Copy link
Author

ghost commented Jan 13, 2021

Many thanks to @tannewt and @FoamyGuy to make it happen!

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

Successfully merging this pull request may close these issues.

4 participants