Type hinting for ROS 2 python messages for

Has anyone figured out a way to get a language server like pyright to work with ros2 python messages? Normally if you have a class like this

class MyRosMessage:
    def __init__(x: float, y: float, z: float):
        ...
my_ros_message = MyRosMessage(x=1.0, y=2.0, z=3)

My LSP will warn me that z is an int when it should be a float.

However I noticed that the ROS2 implementation of Python ROS messages is as such:

class MyRosMessage:
    def __init__(kwargs**):
        ...
        self.x = kwargs.get('x', float())
        self.y = kwargs.get('y', float())
        self.z = kwargs.get('z', float())

    @x.setter
    def x(self, value):
        if __debug__:
            assert \
                isinstance(value, float), \
                "The 'x' field must be of type 'float'"
            assert not (value < -1.7976931348623157e+308 or value > 1.7976931348623157e+308) or math.isinf(value), \
                "The 'x' field must be a double in [-1.7976931348623157e+308, 1.7976931348623157e+308]"
        self._x = value

# This line will throw an assertion error. pyright will not warn you about this mistake.
my_ros_message = MyRosMessage(x=1.0, y=2.0, z=3)

Is there any way to make a language server understand the the code above will throw an exception before hand? Is there an easy way to modify the ROS2 message generation to include type hinting in the setter or something like such?

class MyRosMessage:
...

    @x.setter
    def x(self, value: float):
...

Check out GitHub - rospypi/rosidl_generator_mypy

This works at build time only so you’ll need to build any messages from source to get it to work.

3 Likes