Skip to content

chore(robots): enable mypy type checking for robots module#3067

Open
jameslcowan wants to merge 2 commits intohuggingface:mainfrom
jameslcowan:chore/mypy-robots-1721
Open

chore(robots): enable mypy type checking for robots module#3067
jameslcowan wants to merge 2 commits intohuggingface:mainfrom
jameslcowan:chore/mypy-robots-1721

Conversation

@jameslcowan
Copy link

Fixes #1721.

Part of the broader effort to make LeRobot mypy compliant (#1719).

What changed

Enable lerobot.robots.* in the mypy overrides (pyproject.toml) and fix all 21 errors across 5 files:

  • lekiwi/lekiwi_client.py: annotate zmq_context, zmq_cmd_socket, zmq_observation_socket as Any, annotate last_frames/last_remote_state/logs dicts, add return True to is_calibrated (client requires no calibration)
  • lekiwi/lekiwi_host.py: change duration = 00.0 to match subsequent float reassignment
  • earthrover_mini_plus/robot_earthrover_mini_plus.py: add # type: ignore[import-untyped] for requests, annotate cameras dict
  • unitree_g1/unitree_g1.py: annotate sim_env/_env_wrapper as Any, subscribe_thread as Thread | None, declare kp/kd in __init__
  • so_follower/robot_kinematic_processor.py: guard .copy() call behind None check to resolve union-attr error

How was this tested

mypy src/lerobot/robots/
# Success: no issues found in 45 source files

Copilot AI review requested due to automatic review settings March 2, 2026 17:35
@github-actions github-actions bot added the robots Issues concerning robots HW interfaces label Mar 2, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Enables mypy type-checking for lerobot.robots.* and resolves type errors in the robots module as part of the repo-wide mypy compliance effort (Fixes #1721, contributes to #1719).

Changes:

  • Enable lerobot.robots.* mypy override in pyproject.toml.
  • Add/adjust type annotations in multiple robot implementations (e.g., ZMQ sockets, camera dicts, threads, gains).
  • Fix a mypy union-attribute issue in the SO follower kinematic processor by guarding a .copy() call.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/lerobot/robots/unitree_g1/unitree_g1.py Adds explicit attribute annotations for simulation env, subscriber thread, and controller gains.
src/lerobot/robots/so_follower/robot_kinematic_processor.py Makes observation copying safe under None by splitting retrieval vs copy.
src/lerobot/robots/lekiwi/lekiwi_host.py Adjusts duration initialization to a float for type consistency.
src/lerobot/robots/lekiwi/lekiwi_client.py Adds Any annotations for ZMQ handles and internal dicts; makes is_calibrated return a boolean.
src/lerobot/robots/earthrover_mini_plus/robot_earthrover_mini_plus.py Adds typing for cameras and suppresses untyped import checking for requests.
pyproject.toml Turns on mypy checking for the lerobot.robots.* module override.
Comments suppressed due to low confidence (1)

src/lerobot/robots/so_follower/robot_kinematic_processor.py:568

  • q_raw is created with np.array(...) and will never be None, so the if q_raw is None: branch is unreachable. If you want to validate missing joint positions, check for an empty result (e.g., zero-sized array) or validate expected keys before building q_raw.
        q_raw = np.array(
            [float(v) for k, v in observation.items() if isinstance(k, str) and k.endswith(".pos")],
            dtype=float,
        )
        if q_raw is None:
            raise ValueError("Joints observation is require for computing robot kinematics")


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +558 to +560
if raw_observation is None:
raise ValueError("Joints observation is require for computing robot kinematics")
observation = raw_observation.copy()
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

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

The ValueError message has a grammar typo: "is require" should be "is required".

Copilot uses AI. Check for mistakes.
import cv2
import numpy as np
import requests
import requests # type: ignore[import-untyped]
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

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

This # type: ignore[import-untyped] should include a short justification (and ideally a TODO/issue link), consistent with other type: ignore usages in the repo (they typically explain why the ignore is necessary). Consider adding a note that requests lacks bundled typing here and/or adding types-requests as a dependency if feasible.

Suggested change
import requests # type: ignore[import-untyped]
import requests # type: ignore[import-untyped] # requests lacks bundled type hints; TODO: consider adding `types-requests`

Copilot uses AI. Check for mistakes.
Fixes huggingface#1721.

Enable the lerobot.robots.* override in pyproject.toml and resolve all
21 mypy errors across 5 files:

- lekiwi_client.py: annotate zmq sockets/dicts as Any, add return to
  is_calibrated (returns True — client requires no calibration)
- lekiwi_host.py: change duration = 0 to 0.0 to match float reassignment
- earthrover_mini_plus.py: type:ignore untyped requests import, annotate
  cameras dict
- unitree_g1.py: annotate sim_env/_env_wrapper as Any, subscribe_thread
  as Thread | None, declare kp/kd in __init__
- robot_kinematic_processor.py: guard .copy() call behind None check to
  fix union-attr error
@jameslcowan jameslcowan force-pushed the chore/mypy-robots-1721 branch from 2fe44a6 to c138b83 Compare March 11, 2026 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

robots Issues concerning robots HW interfaces

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ensure the robots module passes MyPy type checks

2 participants