LeRobot documentation
Escrevendo docstrings
Escrevendo docstrings
A referência da API do LeRobot é gerada diretamente a partir das docstrings em src/lerobot/. Uma docstring não é um
comentário — ela é a documentação publicada para aquele objeto, e o formato abaixo é o que o renderer e
as verificações de CI analisam.
Esta página é o contrato. Se você estiver adicionando ou editando algo público em src/lerobot/, siga-o.
Um método público sem documentação é invisível.
[[autodoc]]ignora silenciosamente membros que não possuem docstring — sem aviso, sem erro, eles simplesmente não aparecem na página renderizada. Cobertura e completude da referência da API são o mesmo problema.
O formato em um exemplo
Cabeçalhos de seção do Google, formatação de tipo do Hugging Face. Ambos, não um ou o outro.
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
```
"""As referências cruzadas são omitidas nos exemplos desta página — consulte Referências cruzadas para sua sintaxe e o motivo pelo qual elas não podem ser exibidas dentro de um bloco de código.
Regras
Seções
Args: · Returns: · Raises: · Yields: · Example: · Note:
Nessa ordem. Nenhum outro cabeçalho de seção. Um resumo de uma linha vem primeiro, seguido por uma descrição opcional em formato livre, e então as seções.
A linha Args: é analisada por máquina
name (`type`, *optional*, defaults to `X`):
Description, indented on its own line.A cláusula *optional*, defaults to é verificada em relação ao padrão real da assinatura pelo make check-docstrings. Não é decorativa — se você escrever um padrão que divergiu do código, o CI
falha. Omita a cláusula por completo para parâmetros obrigatórios:
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.Tipos ficam entre crases. Use *optional* sem defaults to quando o padrão for None ou não valer a pena repetir.
Retorna: é do tipo primeiro
Uma linha indentada, digite primeiro, depois dois-pontos, e então a descrição:
Returns:
`dict[str, float]`: The action actually written to the motors after safety clipping.Yields: assume a mesma forma.
**Atributos**: , nunca Atributos:
O doc-builder interpreta um Attributes: isolado como um sinônimo de Parameters:, de modo que seus atributos são renderizados como argumentos do construtor. Isso é silencioso e incorreto. Sempre que os atributos diferem dos parâmetros do construtor, use a forma em negrito com um separador --:
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.
"""Observe --, não :.
Referências cruzadas
Use a sintaxe de colchetes do doc-builder: um caminho entre crases e colchetes. Os papéis do Sphinx (:pymeth:, :pyattr:) não são suportados e são renderizados como texto literal na página.
| Deseja | Escrever |
|---|---|
| Classe no pacote principal | [Robot] |
| Método, mostrar o caminho completo | [Robot.connect] |
| Método, mostrar o nome simples | [~Robot.connect] |
| Caminho aninhado | [~robots.Robot.connect] |
| Objeto em outra biblioteca do HF | [~accelerate.Accelerator] |
O ~ remove o caminho apenas do texto do link; o link ainda é resolvido para o caminho completo.
O doc-builder resolve essa sintaxe em toda a página — inclusive dentro de blocos de código delimitados. É por isso que os exemplos de docstring nesta página usam prosa simples em vez de referências cruzadas: um bloco de código contendo uma delas renderizaria o link resolvido em vez da sintaxe que você precisa digitar. Nas suas próprias docstrings, use referências cruzadas à vontade; essa restrição afeta apenas a documentação sobre a sintaxe.
Avisos
Use citações de bloco no estilo 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.O componente <Tip> é legado de acordo com o doc-builder; não adicione novos.
Os exemplos devem ser delimitados
Um exemplo fica dentro de um bloco ```python contendo >>>. É a cerca que faz o conteúdo ser renderizado como um bloco de código, e é o que a expressão regular do pré-processador do doctest procura:
Example:
```python
>>> from lerobot.robots.so_follower import SO101FollowerConfig
>>> cfg = SO101FollowerConfig(port="/dev/ttyACM0")
>>> cfg.use_degrees
True
```Um
>>>sem cerca ainda é coletado — o doctest encontra prompts em qualquer lugar de uma docstring. O que você perde é a renderização, de modo que ele aparece como uma parede de prosa na página. Cada exemplo precisa da cerca.
Cada exemplo é executado no CI ou contém # doctest: +SKIP. Qualquer coisa que envolva hardware, uma GPU ou
downloads do Hub recebe +SKIP:
Example:
```python
>>> robot.connect() # doctest: +SKIP
>>> policy = ACTPolicy.from_pretrained("lerobot/act_aloha_sim_transfer_cube_human") # doctest: +SKIP
```Adicione arquivos contendo exemplos executáveis a utils/documentation_tests.txt.
Coloque exemplos nos três a cinco pontos de entrada genuínos de um módulo. Exemplos em acessores triviais são ruído.
Três padrões que você encontrará constantemente
Dataclasses de configuração
Os campos de configuração são documentados historicamente com comentários # acima de cada campo. doc-builder não
pode ver comentários inline — uma classe assim é renderizada com todos os campos listados e sem nenhuma descrição. Mova-os
para um bloco Args: na docstring da 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ão herda docstrings de classes base. As classes de configuração registradas do LeRobot são frequentemente shims finos de herança múltipla:
@RobotConfig.register_subclass("so101_follower") @dataclass class SOFollowerRobotConfig(RobotConfig, SOFollowerConfig): passEssa classe renderiza todos os campos — incluindo os herdados — sem nenhuma descrição, independentemente de quão bem documentadas estejam as classes base. O bloco
Args:deve estar na classe concreta que o[[autodoc]]nomeia e deve cobrir também os campos herdados.
Classe base, depois subclasse concreta
A classe base abstrata carrega o contrato canônico. As subclasses documentam apenas o que se desvia — semântica de portas, peculiaridades de calibração, layout dos motores, chaves de recursos suportadas. Não copie o contrato da base para cada subclasse.
Robot, Teleoperator, Camera, MotorsBusBase, ProcessorStep e PreTrainedPolicy seguem todos esse formato.
Aliases em nível de módulo
Vários nomes públicos são aliases em vez de classes distintas:
SO100FollowerConfig = SOFollowerRobotConfig SO101FollowerConfig = SOFollowerRobotConfig
[[autodoc]] resolve o alias e renderiza o nome canônico da classe, de modo que um título ## SO101FollowerConfig exibirá class lerobot.robots.so_follower.SOFollowerRobotConfig no corpo do texto. Documente a classe canônica uma única vez e mencione os aliases na prosa da página, em vez de dar a cada alias seu próprio bloco autodoc.
O que não documentar
- Membros privados. Tudo que começa com
_não faz parte da API pública. - A anotação de tipo reafirmada em prosa.
port (str): A string.não acrescenta nada. Diga para que serve. - Código upstream incorporado.
src/lerobot/policies/molmoact2/molmoact2_hf_model/é incorporado dotransformerse já possui docstrings no estilo upstream. Não o altere — reestilizar apenas cria conflitos na próxima sincronização. Ele está excluído da referência da API e das verificações de docstring.
Como isso é aplicado
| Verificar | O que ele detecta |
|---|---|
make check-docstrings | Uma entrada Args: que não corresponde à assinatura; um valor padrão documentado que divergiu do real |
make doctest | Exemplos que não são mais executados |
make check-doctest-list | Entradas desatualizadas ou não ordenadas em utils/documentation_tests.txt |
ruff (regras D) | Violações do estilo de convenção do Google |
interrogate | Cobertura de docstrings abaixo do limite atual |
| doc-builder | Um caminho [[autodoc]] que aponta para algo que não existe — isso quebra a compilação da documentação |
Execute-os juntos antes de abrir um PR:
make check-docstrings && make doctest && pre-commit run --all-files
Em seguida, renderize a página e realmente observe-a:
doc-builder build lerobot docs/source/ --build_dir /tmp/doc-build
Checklist
- Todo membro público que você modificou possui uma docstring.
- Cada entrada de
Args:corresponde à assinatura, incluindo a cláusula*optional*, defaults to. -
Returns:é do tipo primeiro em uma linha indentada. - No
Attributes:simples — use**Attributes**:com separadores--. - Nos papéis do Sphinx — as referências cruzadas usam [
~module.Class.method]. - Os exemplos estão dentro de um bloco
```pythone são executados no CI ou possuem# doctest: +SKIP. - Os campos do dataclass de Config estão em um bloco
Args:na classe concreta, não em comentários#. - A página renderizada foi verificada visualmente.