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

esp32: socket.bind() fails with a strange error. #9410

Closed
robert-hh opened this issue Sep 25, 2022 · 5 comments
Closed

esp32: socket.bind() fails with a strange error. #9410

robert-hh opened this issue Sep 25, 2022 · 5 comments

Comments

@robert-hh
Copy link
Contributor

robert-hh commented Sep 25, 2022

Firmware version:
MicroPython v1.19.1-443-g30e50ab19 on 2022-09-25; ESP32 module with ESP32 or
MicroPython v1.19.1-443-g30e50ab19 on 2022-09-25; ESP32 module (spiram) with ESP32
esp-idf version 4.4

This little script:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0', 12345))

Causes the error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "bindfail.py", line 4, in <module>
TypeError: can't convert 'int' object to str implicitly

But only if it is executed as frozen bytecode. Importing it as .py or .mpy file from the file system succeeds. Changing the last line to:

s.bind(('0.0.0.0', int(12345)))

or using a symbol (but not a const) for the port number works as well.

Thanks to @uraich for pointing at that error.

@dpgeorge
Copy link
Member

Thanks for the report.

When frozen, that tuple used as the argument to bind turns in to:

static const mp_obj_int_t const_obj__boot_0_1 = {{&mp_type_int}, {.neg=0, .fixed_dig=1, .alloc=1, .len=1, .dig=(uint16_t*)(const uint16_t[]){0x3039}}};
static const mp_rom_obj_tuple_t const_obj__boot_0 = {{&mp_type_tuple}, 2, {
    MP_ROM_QSTR(MP_QSTR_0_dot_0_dot_0_dot_0),
    MP_ROM_PTR(&const_obj__boot_0_1),
}};

You can see that the port number is encoded as a big int.

The code for bind that extracts the port number assumes it's a small int:

static int _socket_getaddrinfo2(const mp_obj_t host, const mp_obj_t portx, struct addrinfo **resp) {
    const struct addrinfo hints = {
        .ai_family = AF_INET,
        .ai_socktype = SOCK_STREAM,
    };

    mp_obj_t port = portx;
    if (mp_obj_is_small_int(port)) {
        ...

So the fix is to change that mp_obj_is_small_int() to mp_obj_is_integer().

Also, it should probable be frozen as a small int, so that would be a good thing to improve as well.

@robert-hh
Copy link
Contributor Author

Thank you for the swift reply. It's always impressive to see how you know every little detail and dependency of MicroPython.
The change from mp_obj_is_small_int() to mp_obj_is_integer() works. I can make a PR for that, if you like.
Changing the frozen bytecode content however is definitely beyond my experience.

@dpgeorge
Copy link
Member

Thanks for confirming. I will fix it.

@uraich
Copy link

uraich commented Sep 25, 2022

All I can say: I am impressed!
Many thanks to both of you.

dpgeorge added a commit that referenced this issue Sep 25, 2022
Because the value may be a big integer, which is still a valid type to use.

Fixes issue #9410.

Signed-off-by: Damien George <damien@micropython.org>
@dpgeorge
Copy link
Member

Fixed by 3abcfb9

karfas pushed a commit to karfas/micropython that referenced this issue Apr 23, 2023
Because the value may be a big integer, which is still a valid type to use.

Fixes issue micropython#9410.

Signed-off-by: Damien George <damien@micropython.org>
alphonse82 pushed a commit to alphonse82/micropython-wch-ch32v307 that referenced this issue May 8, 2023
Because the value may be a big integer, which is still a valid type to use.

Fixes issue micropython#9410.

Signed-off-by: Damien George <damien@micropython.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants