LeRobot documentation
Rédaction de docstrings
Rédaction de docstrings
La référence de l’API de LeRobot est générée directement à partir des docstrings dans src/lerobot/. Une docstring n’est pas un commentaire — c’est la documentation publiée pour cet objet, et le format ci-dessous est celui que le renderer et les vérifications CI analysent.
Cette page est le contrat. Si vous ajoutez ou modifiez quoi que ce soit de public dans src/lerobot/, suivez-le.
Une méthode publique non documentée est une méthode invisible.
[[autodoc]]ignore silencieusement les membres qui n’ont pas de docstring — sans avertissement, sans erreur, ils tout simplement n’apparaissent pas sur la page rendue. La couverture et la complétude de la référence API sont le même problème.
Le format dans un exemple
En-têtes de section Google, formatage de type Hugging Face. Les deux, pas l'un ou l'autre.
def send_action(self, action: RobotAction, rate_hz: float = 30.0) -> RobotAction:
"""Command the robot to move to a target joint configuration.
Values are clipped by the configured maximum relative target before reaching the motors, so the
returned action may differ from the requested one.
Args:
action (`dict[str, float]`):
Target values keyed by motor name, e.g. `{"shoulder_pan.pos": 0.0}`. Keys must match the
robot's action features.
rate_hz (`float`, *optional*, defaults to `30.0`):
Control loop frequency.
Returns:
`dict[str, float]`: The action actually written to the motors after safety clipping.
Raises:
DeviceNotConnectedError: If the robot has not been connected.
Example:
```python
>>> from lerobot.robots.so_follower import SO101Follower, SO101FollowerConfig
>>> robot = SO101Follower(SO101FollowerConfig(port="/dev/ttyACM0")) # doctest: +SKIP
>>> robot.connect() # doctest: +SKIP
>>> robot.send_action({"shoulder_pan.pos": 0.0}) # doctest: +SKIP
```
"""Les références croisées sont omises dans les exemples de cette page — voir Références croisées pour leur syntaxe et la raison pour laquelle elles ne peuvent pas être affichées dans un bloc de code.
Règles
Sections
Args: · Returns: · Raises: · Yields: · Example: · Note:
Dans cet ordre. Aucune autre en-tête de section. Un résumé en une ligne vient en premier, puis une description libre facultative, puis les sections.
La ligne Args: est analysée par la machine
name (`type`, *optional*, defaults to `X`):
Description, indented on its own line.La clause *optional*, defaults to est vérifiée par rapport à la valeur par défaut réelle de la signature par make check-docstrings. Elle n’est pas décorative — si vous indiquez une valeur par défaut qui a divergé du code, la CI
échoue. Omettez entièrement la clause pour les paramètres obligatoires :
Args:
port (`str`):
Serial port the arm is connected to, e.g. `/dev/ttyACM0`.
max_relative_target (`float | dict[str, float]`, *optional*):
Caps the magnitude of the relative positional target vector. `None` disables clipping.
use_degrees (`bool`, *optional*, defaults to `True`):
Keep `True` for backward compatibility with existing policies and datasets.Types go in backticks. Use *optional* with no defaults to when the default is None or is otherwise not
worth restating.
Retourne : est de type premier
Une ligne indentée, le type d'abord, puis un deux-points, puis la description :
Returns:
`dict[str, float]`: The action actually written to the motors after safety clipping.Yields: prend la même forme.
**Attributs** : , jamais Attributs :
doc-builder interprète un simple Attributes: comme un synonyme de Parameters:, de sorte que vos attributs sont rendus comme des arguments du constructeur. Ce comportement est silencieux et incorrect. Chaque fois que les attributs diffèrent des paramètres du constructeur, utilisez la forme en gras avec un séparateur -- :
class Robot(abc.ABC):
"""The base abstract class for all LeRobot-compatible robots.
**Attributes**:
- **config_class** (`type[RobotConfig]`) -- The expected configuration class for this robot.
- **name** (`str`) -- The unique robot name used to identify this robot type.
"""Note --, et non :.
Références croisées
Utilisez la syntaxe des crochets de doc-builder : un chemin entre crochets et guillemets bas. Les rôles Sphinx (:pymeth:, :pyattr:) ne sont pas pris en charge et s’affichent en texte littéral sur la page.
| Souhaitez | Écrire |
|---|---|
| Classe du package principal | [Robot] |
| Méthode, afficher le chemin complet | [Robot.connect] |
| Méthode, afficher le nom brut | [~Robot.connect] |
| Chemin imbriqué | [~robots.Robot.connect] |
| Objet dans une autre bibliothèque HF | [~accelerate.Accelerator] |
Le ~ supprime le chemin uniquement du texte du lien ; le lien pointe toujours vers le chemin complet.
doc-builder résout cette syntaxe partout dans une page — y compris à l’intérieur des blocs de code délimités. C’est pourquoi les exemples de docstring sur cette page utilisent du texte simple plutôt que des références croisées : un bloc de code en contenant une afficherait le lien résolu au lieu de la syntaxe à saisir. Dans vos propres docstrings, utilisez les références croisées librement ; cette restriction ne concerne que la documentation sur la syntaxe.
Encadrés
Utilisez des citations de bloc de style GitHub :
> [!TIP]
> Call this once at startup — it takes about two seconds.
> [!WARNING]
> Torque is disabled on disconnect. The arm will drop if it is holding a load.Le composant <Tip> est obsolète selon doc-builder ; n’en ajoutez pas de nouveaux.
Les exemples doivent être encadrés
Un exemple se trouve dans un bloc ```python contenant >>>. C’est la clôture qui le fait afficher comme un bloc de code, et c’est ce que la regex du préprocesseur doctest recherche :
Example:
```python
>>> from lerobot.robots.so_follower import SO101FollowerConfig
>>> cfg = SO101FollowerConfig(port="/dev/ttyACM0")
>>> cfg.use_degrees
True
```Un
>>>non encadré est toujours collecté — doctest trouve les invites n’importe où dans une docstring. Ce que vous perdez, c’est le rendu, ce qui se présente donc comme un bloc de texte sur la page. Chaque exemple a besoin de l’encadrement.
Chaque exemple est soit exécuté en CI, soit porte la balise # doctest: +SKIP. Tout ce qui concerne le matériel, un GPU ou des téléchargements depuis le Hub reçoit la balise +SKIP :
Example:
```python
>>> robot.connect() # doctest: +SKIP
>>> policy = ACTPolicy.from_pretrained("lerobot/act_aloha_sim_transfer_cube_human") # doctest: +SKIP
```Ajoutez les fichiers contenant des exemples exécutables à utils/documentation_tests.txt.
Placez des exemples sur les trois à cinq points d’entrée réels d’un module. Les exemples sur des accesseurs triviaux sont du bruit.
Trois motifs que vous rencontrerez constamment
Config dataclasses
Les champs de configuration sont historiquement documentés par des commentaires # au-dessus de chaque champ. doc-builder ne peut pas
voir les commentaires en ligne — une telle classe s’affiche avec tous les champs listés et sans aucune description. Déplacez-les
dans un bloc Args: de la docstring de la classe :
@dataclass
class SOFollowerConfig:
"""Configuration for SO-family follower arms.
Args:
port (`str`):
Serial port the arm is connected to, e.g. `/dev/ttyACM0`.
max_relative_target (`float | dict[str, float]`, *optional*):
Caps the magnitude of the relative positional target vector. A scalar applies to all motors;
a dict maps motor name to a per-motor cap. `None` disables clipping.
use_degrees (`bool`, *optional*, defaults to `True`):
Keep `True` for backward compatibility with existing policies and datasets.
"""
port: str
max_relative_target: float | dict[str, float] | None = None
use_degrees: bool = Truedoc-builder n’hérite pas des docstrings des classes de base. Les classes de configuration enregistrées de LeRobot sont souvent de simples shims d’héritage multiple :
@RobotConfig.register_subclass("so101_follower") @dataclass class SOFollowerRobotConfig(RobotConfig, SOFollowerConfig): passCette classe affiche chaque champ — y compris ceux hérités — sans aucune description, quelle que soit la qualité de la documentation des classes de base. Le bloc
Args:doit se trouver sur la classe concrète nommée par[[autodoc]], et il doit couvrir également les champs hérités.
Classe de base, puis sous-classe concrète
La classe de base abstraite porte le contrat canonique. Les sous-classes documentent uniquement les écarts — sémantique du port, particularités de calibration, disposition des moteurs, clés de fonctionnalités prises en charge. Ne copiez pas le contrat de base dans chaque sous-classe.
Robot, Teleoperator, Camera, MotorsBusBase, ProcessorStep et PreTrainedPolicy suivent tous cette forme.
Alias au niveau du module
Plusieurs noms publics sont des alias plutôt que des classes distinctes :
SO100FollowerConfig = SOFollowerRobotConfig SO101FollowerConfig = SOFollowerRobotConfig
[[autodoc]] résout l’alias et affiche le nom de classe canonique, de sorte qu’un en-tête ## SO101FollowerConfig affichera class lerobot.robots.so_follower.SOFollowerRobotConfig dans le corps du texte. Documentez la classe canonique une seule fois et mentionnez les alias dans le texte de la page plutôt que de donner à chaque alias son propre bloc autodoc.
Ce qu'il ne faut pas documenter
- Membres privés. Tout ce qui commence par
_ne fait pas partie de l'API publique. - La réécriture de l’annotation de type sous forme de prose.
port (str): A string.n’apporte rien. Indiquez à quoi elle sert. - Code en amont intégré.
src/lerobot/policies/molmoact2/molmoact2_hf_model/est intégré depuistransformerset contient déjà des docstrings au style amont. Laissez-le tel quel — le reformater ne ferait que créer des conflits lors de la prochaine synchronisation. Il est exclu de la référence API et des vérifications de docstrings.
Comment cela est appliqué
| Vérifier | Ce qu'il détecte |
|---|---|
make check-docstrings | Une entrée Args: qui ne correspond pas à la signature ; une valeur par défaut documentée qui a divergé de la valeur réelle |
make doctest | Exemples qui ne fonctionnent plus |
make check-doctest-list | Entrées obsolètes ou non triées dans utils/documentation_tests.txt |
ruff (règles D) | Violations du style de convention Google |
interrogate | Couverture des docstrings inférieure au seuil actuel |
| doc-builder | Un chemin [[autodoc]] qui pointe vers quelque chose qui n’existe pas — cela casse la construction de la documentation |
Exécutez-les ensemble avant d’ouvrir une PR :
make check-docstrings && make doctest && pre-commit run --all-files
Puis, affichez la page et examinez-la réellement :
doc-builder build lerobot docs/source/ --build_dir /tmp/doc-build
Liste de contrôle
- Chaque membre public que vous avez modifié possède une docstring.
- Chaque entrée
Args:correspond à la signature, y compris la clause*optional*, defaults to. -
Returns:est de type premier sur une ligne indentée. - Pas d'
Attributes:nu — utilisez**Attributes**:avec des séparateurs--. - Pas de rôles Sphinx — les références croisées utilisent [
~module.Class.method]. - Les exemples sont dans un bloc
```pythonet sont soit exécutés en CI, soit marqués# doctest: +SKIP. - Les champs de la dataclass de configuration sont dans un bloc
Args:sur la classe concrète, pas des commentaires#. - La page rendue a été vérifiée visuellement.