PyCyphal + Datatypes with intellisense/Pylance

Hi,

Given a transpiled python-package of e.g. public_regulated_datatypes and some intellisense/Pylance in a given IDE (in my case VSCode) there is a mismatch between what Intellisense believes is true and run-time behavior.

I install all my python-packages into:
install/my_project/local/lib/python3.10/dist-packages/

including /install/my_project/local/lib/python3.10/dist-packages/uavcan. Now intellisense gets that information:

// .vscode/settings.json
"python.autoComplete.extraPaths": [
        "${workspaceFolder}/install/my_project/local/lib/python3.10/dist-packages"
],

Now, I start coding e.g.:

import uavcan.node.Heartbeat_1_0
self.heartbeat_sub = self.pycyphal_node.make_subscriber(
            uavcan.node.Heartbeat_1_0,
            uavcan.node.Heartbeat_1_0._FIXED_PORT_ID_
        )

which works. But intellisense believes that’s not correct, since there is no such thing as uavcan.node.Heartbeat_1_0._FIXED_PORT_ID_ but rather it believes it should be uavcan.node.Heartbeat_1_0.Heartbeat_1_0._FIXED_PORT_ID_. At run-time the “intellisense-way” will fail. Am I an idiot, or is there something wrong? Is there a proper way to solve this?

This behavior is exemplary for all message-types and attributes. e.g.:

  • uavcan.node.Mode_1_0.OPERATIONAL and uavcan.node.Mode_1_0.Mode_1_0.OPERATIONAL
  • uavcan.register.Access_1_0.Response and uavcan.register.Access_1_0.Access_1_0.Response
    …

Interesting, IIRC it just works in PyCharm. I think the problem might be that there is a Python module named Heartbeat_1_0.py, which contains class Heartbeat_1_0, which is imported as from Heartbeat_1_0 import Heartbeat_1_0 in the __init__.py. The parser is apparently confusing the module with the class.

There are aliases without the minor version number, can you try these? In your case that would be Heartbeat_1. You could also try different import styles to see which one is accepted by the parser; e.g., from uavcan.node import Heartbeat_1.

The recommended practice is to actually omit the minor version number unless you care about it for some reason.

Also, make_subscriber can accept just the type without the fixed port-ID (it will fetch the ID automatically). You also shouldn’t explicitly access attributes prefixed with a _, they are private; the nunavut_support module provides public getters for them.

1 Like

Hi,

Yes uavcan.node.Heartbeat_1._FIXED_PORT_ID_ works without the minor version number. Since it’s an alias, this will be stable even if the minor changes, and Heartbeat_1 which currently is an alias to Heartbeat_1_0 will then point to Heartbeat_1_1? I’ve only seen this once, but what if the major changes?

:slight_smile: Thanks, then this is resolved.

Correct.

Then you will need to update your code from _1 to _2.

1 Like

Fair enough. Breaking changes may break me, too.

1 Like