document-public-apis

Par pytorch · pytorch

Documentez les API publiques non documentées dans PyTorch en supprimant des fonctions de `coverage_ignore_functions` et `coverage_ignore_classes` dans `docs/source/conf.py`, en exécutant la couverture Sphinx, puis en ajoutant les directives autodoc appropriées aux fichiers de documentation `.md` ou `.rst` correspondants. À utiliser lorsqu'un utilisateur demande à supprimer des fonctions des listes d'exclusion de `conf.py`.

npx skills add https://github.com/pytorch/pytorch --skill document-public-apis

Documenter les API publiques

Cette compétence documente les API publiques non documentées dans PyTorch en supprimant des entrées des listes d'exclusion de couverture dans docs/source/conf.py et en ajoutant des directives Sphinx autodoc (par ex. autosummary, currentmodule, autoclass, automodule) aux fichiers source .md ou .rst correspondants dans docs/source/.

« Documenter » signifie ajouter des directives autodoc aux fichiers source de documentation — JAMAIS modifier le code source Python. Ne pas ajouter ou modifier les docstrings dans les fichiers .py. Votre seul travail est d'ajouter la bonne directive au bon fichier de documentation.

IMPORTANT : Avant d'ajouter une fonction à l'arborescence sphinx, vérifiez qu'elle dispose d'une vraie docstring. Utilisez une vérification Python rapide (par ex. python -c "from torch.module import func; print(bool(func.__doc__))") pour confirmer que la fonction a un contenu de documentation réel — pas simplement une docstring vide ou un stub .. warning:: This API is experimental. Les fonctions sans docstrings significatives doivent rester dans les listes coverage_ignore_functions/coverage_ignore_classes. Ajouter des fonctions non documentées à l'arborescence sphinx crée des pages vides ou quasi vides qui dégradent la qualité de la documentation.

Vue d'ensemble

docs/source/conf.py contient deux listes qui suppriment les avertissements de couverture Sphinx pour les API non documentées :

  • coverage_ignore_functions : fonctions non documentées
  • coverage_ignore_classes : classes non documentées

Les entrées sont organisées par groupes de commentaires de module. Chaque groupe a un commentaire d'étiquette de module suivi des noms de fonction/classe qui appartiennent à ce module :

coverage_ignore_functions = [
    # torch.ao.quantization.fx.convert              <-- commentaire d'étiquette de module
    "convert",                                       # <-- entrées appartenant à ce module
    "convert_custom_module",
    "convert_standalone_module",
    "convert_weighted_module",
    # torch.ao.quantization.fx.fuse                 <-- groupe de module suivant
    "fuse",
    # torch.nn.functional
    "assert_int_or_pair",  # looks unintentionally public   <-- entrée avec commentaire inline
    "constant",  # deprecated                                <-- entrée avec commentaire inline
]

Il y a deux sortes de commentaires :

  • Commentaires d'étiquette de module (# torch.ao.quantization.fx.convert) : ils étiquettent quel module les entrées ci-dessous appartiennent. Ils apparaissent sur leur propre ligne avant un groupe d'entrées.
  • Commentaires inline (# deprecated, # documented as adaptive_max_pool1d) : ils apparaissent après une entrée de chaîne sur la même ligne et expliquent pourquoi l'entrée est dans la liste d'exclusion.

Le commentaire d'étiquette de module vous dit directement :

  1. À quel module les fonctions appartiennent
  2. Où les ajouter dans les docs (par ex. # torch.ao.quantization.fx.convert → les fonctions vont sous torch.ao.quantization.fx.convert dans le fichier doc)

Instructions

Chaque invocation de cette compétence traite un lot de groupes de modules. Sélectionnez un ou plusieurs groupes de modules complets à partir des listes d'exclusion, documentez leurs fonctions et vérifiez.

Étape 1 : Sélectionner les groupes de modules à documenter

Lisez docs/source/conf.py et sélectionnez un ou plusieurs groupes de modules complets à documenter. Un groupe de modules est un commentaire d'étiquette de module et toutes les entrées en dessous jusqu'au commentaire d'étiquette de module suivant. Traitez les groupes entiers — ne jamais diviser un groupe entre des lots.

Par exemple, sélectionner le groupe torch.ao.quantization.fx.convert signifie prendre tout ceci :

# torch.ao.quantization.fx.convert
"convert",
"convert_custom_module",
"convert_standalone_module",
"convert_weighted_module",

Travaillez à travers les listes de haut en bas. Choisissez assez de groupes pour faire des progrès significatifs (viser 5 à 15 fonctions au total, mais toujours inclure les groupes complets même si cela signifie dépasser légèrement).

Vérifiez les commentaires inline avant d'inclure une entrée. Certaines entrées ont des commentaires inline qui indiquent qu'elles ne doivent pas être documentées :

  • # deprecated — La fonction est obsolète. Laissez-la dans la liste d'exclusion.
  • # documented as <other_name> — Déjà documentée sous un nom différent. Laissez-la.
  • # looks unintentionally public — Probablement pas destinée à être une API publique. Laissez-la.
  • # legacy helper for ... — Même chose que obsolète. Laissez-la.
  • # utility function — Laissez-la.

Si un groupe de modules a un mélange d'entrées régulières et d'entrées avec des commentaires inline, traitez quand même le groupe — mais commentez uniquement les entrées régulières. Laissez les entrées avec des commentaires inline intouchées dans la liste d'exclusion.

Étape 1b : Vérifier que les fonctions ont des docstrings réelles

Pour chaque fonction sélectionnée à l'étape 1, vérifiez qu'elle a une docstring significative en exécutant :

python -c "from torch.module.path import func_name; doc = func_name.__doc__; print('HAS DOC' if doc and len(doc.strip()) > 80 else 'NO DOC'); print(repr(doc[:120]) if doc else 'None')"

Une fonction a une docstring significative si elle a du contenu descriptif réel — pas seulement :

  • None ou chaîne vide
  • Uniquement un stub .. warning:: This API is experimental sans description
  • Uniquement une signature auto-générée sur une ligne

Les fonctions sans docstrings significatives doivent rester dans la liste d'exclusion. Supprimez-les de votre lot. Si un groupe de modules entier n'a aucune fonction avec des docstrings, ignorez le groupe entier.

Étape 2 : Présenter le lot à l'utilisateur

Avant de faire des modifications, présentez les groupes de modules sélectionnés et leurs fonctions à l'utilisateur. Indiquez quelles fonctions ont réussi la vérification docstring et lesquelles ont été exclues. Montrez-les organisées par module :

Module : torch.ao.quantization.fx.convert
  - convert
  - convert_custom_module
  - convert_standalone_module
  - convert_weighted_module

Module : torch.ao.quantization.fx.fuse
  - fuse

Puis utilisez l'outil AskUserQuestion pour laisser l'utilisateur confirmer, avec des options telles que :

  • « Procéder avec ce lot »
  • « Ignorer certaines entrées » (l'utilisateur peut spécifier lesquelles supprimer)
  • « Choisir un lot différent »

Étape 3 : Commenter les entrées dans conf.py

Après la confirmation de l'utilisateur, éditez docs/source/conf.py et commentez (ne supprimez pas) les entrées sélectionnées. Utilisez un préfixe # sur chaque ligne d'entrée de chaîne :

# torch.ao.quantization.fx.convert
# "convert",
# "convert_custom_module",
# "convert_standalone_module",
# "convert_weighted_module",

Cela préserve les entrées originales afin qu'elles puissent être restaurées en cas d'échec de vérification.

Étape 4 : Exécuter la couverture Sphinx

cd docs && make coverage

Ignorez la sortie du terminal de make coverage. Elle contient souvent des tracebacks non liés et des erreurs provenant d'extensions Sphinx (par ex. onnx_ir, katex, sphinxcontrib) qui n'ont rien à voir avec la couverture. La seule chose qui importe est de savoir si docs/build/coverage/python.txt a été généré. Lisez ce fichier pour voir les API spécifiques non documentées.

Le format de python.txt liste chaque API non documentée comme :

torch.ao.quantization.fx.convert
   * convert
   * convert_custom_module
   * convert_standalone_module
   * convert_weighted_module

Pas toutes les fonctions commentées n'apparaîtront dans python.txt. Certaines peuvent déjà être documentées ailleurs. C'est normal — ajoutez uniquement les directives pour les fonctions qui apparaissent réellement dans python.txt.

Si make coverage échoue en raison de dépendances manquantes, exécutez d'abord :

cd docs && pip install -r requirements.txt

Étape 5 : Ajouter les directives de documentation

Pour chaque fonction listée dans python.txt, utilisez le commentaire d'étiquette de module de conf.py pour déterminer où elle doit être ajoutée. Le commentaire de module vous donne le chemin du module complet, qui correspond à un fichier source de documentation et une section dans ce fichier.

Trouver le bon fichier doc

Le commentaire du module correspond à un fichier source de documentation dans docs/source/. En cas de doute, recherchez d'autres fonctions du même module :

grep -rn "torch.module_name" docs/source/*.md docs/source/*.rst

Ou listez les fichiers candidats :

ls docs/source/*module_name*

Si aucun fichier doc n'existe pour un sous-module, vérifiez si un fichier doc du module parent a une section pour lui (par ex. backends.md a des sections pour torch.backends.cuda, torch.backends.cudnn, etc.). Si ce n'est pas le cas, ajoutez une nouvelle section au fichier parent en suivant les motifs existants.

Ajouter les directives

Lisez d'abord le fichier doc cible et faites correspondre les motifs exacts déjà utilisés. Ne pas inventer de nouveaux motifs ou utiliser autofunction simple avec des noms pleinement qualifiés — toujours utiliser la structure hiérarchique appropriée avec automodule, currentmodule et noms courts. Ne pas utiliser . py:module:: car cela supprime simplement les erreurs et ne documente pas réellement la fonction. Regardez d'autres fichiers qui correspondent au format du fichier cible (par ex. .md vs .rst) sous docs/source/ pour voir des exemples.

Il y a deux formats de fichier. Faites correspondre celui utilisé dans le fichier cible.

Motif A — Fichiers MyST Markdown (.md): Utilisé dans des fichiers comme accelerator.md, backends.md, cuda.md.

La structure hiérarchique utilise automodule pour enregistrer le module, currentmodule pour définir le contexte, puis des noms courts :

## torch.ao.quantization.fx.convert

```{eval-rst}
.. automodule:: torch.ao.quantization.fx.convert
.. currentmodule:: torch.ao.quantization.fx.convert
.. autofunction:: convert
.. autofunction:: convert_custom_module

Pour les blocs `autosummary` (utilisés dans certains fichiers à la place des directives individuelles) :

```markdown
```{eval-rst}
.. autosummary::
    :toctree: generated
    :nosignatures:

    existing_function
    your_new_function
`` `

Pour les classes :

```{eval-rst}
.. autoclass:: YourClass
    :members:
`` `

Motif B — Fichiers reStructuredText (.rst): Utilisé dans des fichiers comme torch.rst, nn.rst.

Même structure hiérarchique sans les clôtures markdown :

torch.ao.quantization.fx.convert
---------------------------------

.. automodule:: torch.ao.quantization.fx.convert

.. currentmodule:: torch.ao.quantization.fx.convert

.. autosummary::
    :toctree: generated
    :nosignatures:

    convert
    convert_custom_module
    convert_standalone_module
    convert_weighted_module

Pour les directives individuelles :

.. automodule:: torch.submodule

.. currentmodule:: torch.submodule

.. autofunction:: function_name

.. autoclass:: ClassName
    :members:

Règles clés:

  • Le commentaire d'étiquette de module de conf.py (par ex. # torch.ao.quantization.fx.convert) vous indique exactement quel automodule et currentmodule utiliser.
  • Toujours définir .. automodule:: et .. currentmodule:: avant de documenter les fonctions d'un module.
  • Utilisez des noms courts (par ex. convert, pas torch.ao.quantization.fx.convert.convert) après que currentmodule soit défini.
  • Si le module a déjà un automodule/currentmodule dans le fichier, n'en ajoutez pas un autre — ajoutez simplement votre fonction en dessous de celui existant.
  • Faites correspondre le style que le fichier utilise déjà (blocs autosummary vs. directives individuelles autofunction).

Placer dans la bonne section

Lisez le fichier doc cible et trouvez la section appropriée. Si le module a déjà une section (par ex. ## torch.backends.cuda dans backends.md), ajoutez les fonctions là. Si aucune section n'existe, créez-en une en suivant les motifs de section existants du fichier. Groupez toutes les fonctions du même groupe de modules ensemble.

Étape 6 : Vérifier avec la couverture

Exécutez la couverture à nouveau :

cd docs && make coverage

Ignorez la sortie du terminal — lisez uniquement docs/build/coverage/python.txt. La vérification réussit quand python.txt contient zéro fonction non documentée dans TOUS les modules. Il devrait seulement avoir le tableau de statistiques avec 100 % de couverture et 0 non documenté pour chaque module. Par exemple :

Undocumented Python objects
===========================

Statistics
----------

+---------------------------+----------+--------------+
| Module                    | Coverage | Undocumented |
+===========================+========================+
| torch                     | 100.00%  | 0            |
+---------------------------+----------+--------------+
| torch.accelerator         | 100.00%  | 0            |
+---------------------------+----------+--------------+

Si un module affiche des fonctions non documentées (couverture inférieure à 100 % ou nombre non documenté > 0), la vérification a échoué.

Si la vérification réussit (zéro non documenté dans tous les modules) : Allez à l'étape 7.

Si la vérification échoue (des fonctions non documentées restent) : Lisez docs/build/coverage/python.txt pour voir quelles fonctions sont toujours listées comme non documentées. Les problèmes courants incluent :

  • Mauvais fichier doc : la fonction a été ajoutée au mauvais fichier .md/.rst. Déplacez la directive vers le bon fichier.
  • Mauvais type de directive : par ex. utilisé autofunction pour une classe, ou autoclass pour une fonction. Corrigez la directive.
  • Mauvais chemin de module dans la directive : par ex. torch.foo.bar devrait être torch.foo.baz.bar. Corrigez le nom qualifié.
  • Fonction ajoutée à un bloc autosummary avec le mauvais currentmodule : assurez-vous que la directive .. currentmodule:: au-dessus du bloc correspond.
  • automodule manquant pour un sous-module qui n'a pas encore été enregistré. Ajoutez une directive .. automodule:: torch.submodule avant de documenter les fonctions de ce sous-module.

Corrigez la directive doc en fonction de l'erreur, puis réexécutez make coverage. Répétez jusqu'à ce que la vérification réussisse.

Si une fonction échoue toujours après plusieurs tentatives, arrêtez et montrez l'erreur à l'utilisateur. Présentez le nom de la fonction et l'erreur, puis utilisez l'outil AskUserQuestion avec des options telles que :

  • « Le décommenter pour restaurer à la liste d'exclusion (ignorer pour l'instant) »
  • « Essayer une approche différente »
  • « Enquêter davantage »

Étape 7 : Signaler les progrès

Présentez un résumé des progrès à l'utilisateur montrant :

  • Quels groupes de modules ont été traités et combien de fonctions ont été documentées
  • Quelles fonctions ont été ignorées ou restaurées à la liste d'exclusion (et pourquoi)
  • Combien d'entrées restent dans coverage_ignore_functions et coverage_ignore_classes

Étape 8 : Nettoyer les entrées commentées dans conf.py

Maintenant que la vérification a réussi, supprimez les entrées de chaîne commentées de l'étape 3. Ce sont des lignes qui commencent par # " dans coverage_ignore_functions et coverage_ignore_classes. Les entrées de chaîne commentées contiennent toujours des guillemets — c'est comme ça que vous les distinguez des commentaires d'étiquette de module :

# "disable_global_flags",       <-- entrée de chaîne commentée (a des guillemets) → SUPPRIMER
# torch.backends                <-- commentaire d'étiquette de module (pas de guillemets) → GARDER s'il a des entrées actives

Supprimez également tous les commentaires d'étiquette de module qui n'ont plus d'entrées actives en dessous (c.-à-d. toutes leurs entrées ont été soit commentées et maintenant supprimées, soit avaient des commentaires inline et ont été laissées en place mais l'étiquette de module est autrement vide).

Notes importantes

  • Suivez les étapes exactement comme écrites. L'étape make coverage est la vérification primaire des directives Sphinx correctes, et la vérification docstring de l'étape 1b garantit que vous ne documentez que les fonctions qui ont du contenu réel.
  • Ne jamais modifier les fichiers source Python (.py). Cette compétence édite uniquement docs/source/conf.py et les fichiers source doc (.md/.rst) dans docs/source/. Ne pas ajouter ou modifier les docstrings. La seule raison d'inspecter les modules Python est à l'étape 1b pour vérifier si une docstring existe — jamais pour modifier le code source.
  • Les entrées sont commentées à l'étape 3, vérifiées à l'étape 6 et nettoyées à l'étape 8 après que la vérification réussisse. Ne jamais supprimer directement les entrées non commentées.
  • Lisez les commentaires inline sur les entrées avant de décider de les documenter. Les entrées marquées # deprecated, # documented as ..., # looks unintentionally public ou # legacy helper doivent rester dans la liste d'exclusion.
  • La liste coverage_ignore_functions utilise des noms de fonction simples (pas pleinement qualifiés), donc le même nom peut apparaître plusieurs fois pour différents modules. Utilisez le commentaire d'étiquette de module au-dessus de chaque entrée pour identifier quel module elle appartient. Soyez prudent lors du nettoyage de l'étape 8 pour supprimer uniquement les bonnes lignes commentées — les entrées de chaîne commentées ont des guillemets (# "func_name",), les commentaires d'étiquette de module n'en ont pas.
  • Toujours faire correspondre le style existant du fichier doc cible — ne pas mélanger les directives de style .md dans les fichiers .rst ou vice versa.
  • Utilisez le commentaire d'étiquette de module (par ex. # torch.ao.quantization.fx.convert) comme guide principal à la fois pour les directives automodule/currentmodule et pour trouver la bonne section dans le fichier doc.
  • Toujours traiter les groupes de modules complets — ne jamais diviser un groupe dans les invocations.

Skills similaires