3 min read

Sphinx autodoc et modules OpenERP

Sphinx autodoc et modules OpenERP

De quoi il est question.

sphinx-autodoc est une extension de Sphinx, fournie d’office mais pas activée par défaut,  qui extrait les docstrings des sources en Python pour produire une jolie documentation technique qui peut ressembler à ça :

Un exemple réel disponible en ligne et générée de cette façon, est ici : doc de la recette buildout pour OpenERP.

Mais cette dernière n'est pas un module OpenERP. Pour arriver à ce résultat, avec un module OpenERP, Sphinx a besoin d’importer tout le code, et c’est là que ça se complique.

Prérequis

Tous les imports faits depuis vos modules doivent être complètement qualifiés ou relatifs, comme ceci:

from openerp.osv import osv
from openerp.addons.anytracker.assignment import assignment
from .utils import ma_fonction
import mon_modele

et NON COMME CELA:

from osv import osv
from anytracker.assignment import assignment

Remarque: quel que soit son chemin sur le système de fichiers, le chemin canonique pour importer un module est openerp.addons.nom_du_module.

Configuration buildout

Si vous avez déjà une « part » buildout pour sphinx avec la recette collective.recipe.sphinxbuilder, supprimez-la, car autodoc n’a aucune chance de fonctionner ! Conservez le répertoire contenant la doc existante.

Ajoutez sphinx à l’option eggs de votre part dédiée à OpenERP. Ainsi, les exécutables de Sphinx vivront dans le même sys.path que votre code. Les imports faits depuis votre code fonctionneront, donc votre code est importable.

Ajoutez ces trois lignes à l’option openerp-scripts de votre part dédiée à OpenERP, pour que les scripts de Sphinx soient générés:

   openerp_scripts = sphinx-build=sphinx-build command-line-options=-d
                     sphinx-apidoc=sphinx-apidoc command-line-options=-d
                     sphinx-quickstart=sphinx-quickstart

Si votre code fait des imports depuis d'autres addons OpenERP, il est nécessaire de faire tourner Sphinx après avoir chargé une base pour pouvoir l'importer.

Si vous cherchez un exemple complet de buildout avec un sphinx qui fonctionne, en voici-un : https://bitbucket.org/anybox/anytracker_buildout/src

exécutez le buildout, vous devriez obtenir les scripts Sphinx dans bin/

Génération de la doc

lancez bin/sphinx-quickstart  et répondez oui à la question sur autodoc

Lancez ensuite la découverte auto des sources python dans le répertoire d’addons concerné:

$ bin/sphinx-apidoc -d votre_base -- -o doc/apidoc votre_module/

On remarque au passage que le script Sphinx généré par la recette Buildout est modifié dynamiquement pour accepter une option supplémentaire (-d) et que les les options habituelles de Sphinx sont situées après le « -- ». Ce comportement n'est pas spécifique à Sphinx, mais est déterminé par l'argument « command-line-options » de l'option « openerp-scripts » de la recette, applicable à n'importe quel script, par exemple Nose (pour les tests unitaires).

Correction de la doc

Il faut ensuite corriger le RST produit par sphinx-apidoc. Avant correction, il contient des lignes avec automodule :

.. automodule:: anytracker.assignment.assignment

Ça ne va pas, car anytracker.assignment ne sera pas importable depuis Sphinx. Il faut corriger en préfixant en openerp.addons, pour obtenir :

.. automodule:: openerp.addons.anytracker.assignment.assignment

Voici une commande rapide pour corriger, à adapter à votre module (ici le module s’appelle « anytracker »):

$ grep -rl automodule .  | xargs sed -i 's/automodule:: anytracker/automodule:: openerp.addons.anytracker/g'

Par la suite, vous devrez entretenir ces fichiers RST en cas de changement de la structure de vos fichiers source (ou recommencer l’étape précédente).

Compiler la doc

C’est l’action au jour le jour. Avec les chemins de mon exemple, cela se fait avec:

$ bin/sphinx-build -d votre_base -- doc doc/_build/html

Comme précédemment, je dois préciser la base (ou alors il faut que mon openerp.cfg indique laquelle il faut utiliser).

Pour contrôler le résultat:

$ firefox doc/_build/html/apidoc

Il ne manque plus qu' un lien vers le répertoire apidoc dans le index.rst général, et le tour est joué, il vous reste juste avoir des docstrings en syntaxe Sphinx !