DocumentationCodeBonnesPratiques » Historique » Version 23
Philippe Caseiro, 25/04/2014 11:01
| 1 | 20 | Daniel Dehennin | {{toc}} |
|---|---|---|---|
| 2 | 20 | Daniel Dehennin | |
| 3 | 1 | Emmanuel GARETTE | h1. DocumentationCodeBonnesPratiques |
| 4 | 1 | Emmanuel GARETTE | |
| 5 | 18 | Gwenael Remond | **cette page concerne la documentation développeur** |
| 6 | 18 | Gwenael Remond | (voir aussi [[TestsCodeBonnesPratiques]] pour les autres bonnes pratiques développeur) |
| 7 | 18 | Gwenael Remond | |
| 8 | 1 | Emmanuel GARETTE | h2. Généralité |
| 9 | 1 | Emmanuel GARETTE | |
| 10 | 1 | Emmanuel GARETTE | * La documentation technique doit être en anglais. |
| 11 | 5 | Gérald Schwartzmann | * Elle est placée dans les docstrings du code. |
| 12 | 1 | Emmanuel GARETTE | |
| 13 | 1 | Emmanuel GARETTE | h2. Description du module |
| 14 | 1 | Emmanuel GARETTE | |
| 15 | 12 | Daniel Dehennin | La docstring du module est placée en haut du fichier juste après le "shebang":https://fr.wikipedia.org/wiki/Shebang, la déclaration d’"encodage des caractères":https://fr.wikipedia.org/wiki/Codage_de_caract%C3%A8res et la licence du code. |
| 16 | 2 | Gwenael Remond | |
| 17 | 1 | Emmanuel GARETTE | <pre> |
| 18 | 12 | Daniel Dehennin | #!/usr/bin/python |
| 19 | 12 | Daniel Dehennin | # -*- coding: utf-8 -*- |
| 20 | 12 | Daniel Dehennin | # |
| 21 | 16 | Emmanuel GARETTE | ########################################################################## |
| 22 | 16 | Emmanuel GARETTE | # <nom du projet> |
| 23 | 19 | Daniel Dehennin | # Copyright © 2013 Pôle de compétences EOLE <eole@ac-dijon.fr> |
| 24 | 14 | Daniel Dehennin | # |
| 25 | 16 | Emmanuel GARETTE | # License CeCILL: |
| 26 | 16 | Emmanuel GARETTE | # * in french: http://www.cecill.info/licences/Licence_CeCILL_V2-fr.html |
| 27 | 16 | Emmanuel GARETTE | # * in english http://www.cecill.info/licences/Licence_CeCILL_V2-en.html |
| 28 | 16 | Emmanuel GARETTE | ########################################################################## |
| 29 | 2 | Gwenael Remond | </pre> |
| 30 | 2 | Gwenael Remond | |
| 31 | 11 | Daniel Dehennin | La docstring doit contenir : |
| 32 | 1 | Emmanuel GARETTE | * description rapide en une phrase du module ; |
| 33 | 1 | Emmanuel GARETTE | * description avancée qui explique le rôle du module ; |
| 34 | 1 | Emmanuel GARETTE | * des exemples simples d'utilisation. |
| 35 | 1 | Emmanuel GARETTE | |
| 36 | 1 | Emmanuel GARETTE | Les exemples peuvent être un prompt : |
| 37 | 1 | Emmanuel GARETTE | |
| 38 | 1 | Emmanuel GARETTE | <pre> |
| 39 | 1 | Emmanuel GARETTE | >>> is_locked() |
| 40 | 1 | Emmanuel GARETTE | True |
| 41 | 1 | Emmanuel GARETTE | </pre> |
| 42 | 1 | Emmanuel GARETTE | |
| 43 | 1 | Emmanuel GARETTE | ou une portion de code : |
| 44 | 1 | Emmanuel GARETTE | |
| 45 | 1 | Emmanuel GARETTE | <pre> |
| 46 | 1 | Emmanuel GARETTE | :: |
| 47 | 1 | Emmanuel GARETTE | |
| 48 | 1 | Emmanuel GARETTE | from toto.titi import is_locked |
| 49 | 1 | Emmanuel GARETTE | |
| 50 | 1 | Emmanuel GARETTE | toto() |
| 51 | 1 | Emmanuel GARETTE | is_locked() |
| 52 | 1 | Emmanuel GARETTE | </pre> |
| 53 | 1 | Emmanuel GARETTE | |
| 54 | 1 | Emmanuel GARETTE | h2. Docstring des méthodes |
| 55 | 1 | Emmanuel GARETTE | |
| 56 | 3 | Gwenael Remond | Seules les méthodes publiques (qui ne commencent pas par "_") seront mises dans la documentation (mais les méthodes privées sont aussi à documenter). |
| 57 | 1 | Emmanuel GARETTE | |
| 58 | 1 | Emmanuel GARETTE | La docstring doit contenir : |
| 59 | 1 | Emmanuel GARETTE | |
| 60 | 1 | Emmanuel GARETTE | * description rapide en une phrase de la méthode ; |
| 61 | 1 | Emmanuel GARETTE | * si nécessaire une description avancée qui explique le rôle du module ; |
| 62 | 1 | Emmanuel GARETTE | * si nécessaire des exemples simples d'utilisation. |
| 63 | 1 | Emmanuel GARETTE | * les paramètres de la façon suivante (xxx étant le nom du paramètre et yyyyyy la description) : |
| 64 | 1 | Emmanuel GARETTE | |
| 65 | 1 | Emmanuel GARETTE | <pre> |
| 66 | 1 | Emmanuel GARETTE | :param xxx: yyyyyy |
| 67 | 1 | Emmanuel GARETTE | </pre> |
| 68 | 1 | Emmanuel GARETTE | |
| 69 | 1 | Emmanuel GARETTE | Si nécessaire les valeurs de retour (yyyyyy étant la description) : |
| 70 | 1 | Emmanuel GARETTE | |
| 71 | 1 | Emmanuel GARETTE | <pre> |
| 72 | 1 | Emmanuel GARETTE | :return: yyyyyy |
| 73 | 1 | Emmanuel GARETTE | </pre> |
| 74 | 1 | Emmanuel GARETTE | |
| 75 | 4 | Gwenael Remond | plus d'info sur la syntaxe des docstrings: http://sphinx-doc.org/domains.html#info-field-lists |
| 76 | 4 | Gwenael Remond | |
| 77 | 1 | Emmanuel GARETTE | h2. Docstring des classes |
| 78 | 1 | Emmanuel GARETTE | |
| 79 | 10 | Gwenael Remond | comme pour la docstring des modules (mais sans la licence) |
| 80 | 8 | Gwenael Remond | |
| 81 | 8 | Gwenael Remond | h2. Tips |
| 82 | 8 | Gwenael Remond | |
| 83 | 8 | Gwenael Remond | il est possible de faire un lien portant directement sur le redmine de deux manières : |
| 84 | 8 | Gwenael Remond | |
| 85 | 8 | Gwenael Remond | <pre> |
| 86 | 8 | Gwenael Remond | |
| 87 | 8 | Gwenael Remond | :issue:`410` |
| 88 | 8 | Gwenael Remond | |
| 89 | 8 | Gwenael Remond | </pre> |
| 90 | 8 | Gwenael Remond | |
| 91 | 8 | Gwenael Remond | est un lien qui porte directement sur la demande 410 |
| 92 | 8 | Gwenael Remond | |
| 93 | 8 | Gwenael Remond | et |
| 94 | 8 | Gwenael Remond | |
| 95 | 8 | Gwenael Remond | <pre> |
| 96 | 8 | Gwenael Remond | |
| 97 | 8 | Gwenael Remond | :eole:`/projects/creole/wiki/Lock24` |
| 98 | 8 | Gwenael Remond | |
| 99 | 8 | Gwenael Remond | </pre> |
| 100 | 8 | Gwenael Remond | |
| 101 | 8 | Gwenael Remond | qui est simplement un raccourci vers http://dev-eole.ac-dijon.fr/projects/creole/wiki/Lock24 |
| 102 | 17 | Daniel Dehennin | |
| 103 | 17 | Daniel Dehennin | h2. Exemples |
| 104 | 17 | Daniel Dehennin | |
| 105 | 17 | Daniel Dehennin | Plusieurs fichiers sources ont reçu une attention assez particulière sur la documentation : |
| 106 | 17 | Daniel Dehennin | |
| 107 | 17 | Daniel Dehennin | - python-pyeole:source:pyeole/decorator.py |
| 108 | 17 | Daniel Dehennin | - python-pyeole:source:pyeole/log.py |
| 109 | 17 | Daniel Dehennin | - python-pyeole:source:pyeole/lock.py |
| 110 | 21 | Philippe Caseiro | |
| 111 | 21 | Philippe Caseiro | h2. Traduction et python |
| 112 | 22 | Philippe Caseiro | |
| 113 | 22 | Philippe Caseiro | Voici un petit aide mémoire pour traduire une application python de la manière la plus simple possible. |
| 114 | 22 | Philippe Caseiro | |
| 115 | 22 | Philippe Caseiro | Pour traduire une application il faut en premier lieux une bibliothèque qui gère les traductions, la première |
| 116 | 22 | Philippe Caseiro | qui viens à l'esprit est gettext, donc logiquement nous allons nous tourner vers python-gettext. |
| 117 | 22 | Philippe Caseiro | |
| 118 | 22 | Philippe Caseiro | Il faut noter qu'il est important de faire les choses dans l'ordre, les messages par défaut des applications doivent être dans une seule et unique langue, l'usage |
| 119 | 22 | Philippe Caseiro | est de tout écrire en anglais et ensuite de mettre une traduction pour les autres langues. |
| 120 | 22 | Philippe Caseiro | |
| 121 | 22 | Philippe Caseiro | Le principe de gettext est de remplacer tous les messages par l'appel à une "fonction/méthode/whatever" qui vais |
| 122 | 22 | Philippe Caseiro | faire les opérations de traduction. |
| 123 | 22 | Philippe Caseiro | |
| 124 | 22 | Philippe Caseiro | Dans le monde gettext cette "fonction" a pour nom '_'. |
| 125 | 22 | Philippe Caseiro | |
| 126 | 22 | Philippe Caseiro | La première chose a faire est de mettre a disposition une "fonction" '_' dans votre appli python. (Les exemples suivants proviennent de pyeole) |
| 127 | 22 | Philippe Caseiro | |
| 128 | 22 | Philippe Caseiro | h3. i18n.py |
| 129 | 22 | Philippe Caseiro | |
| 130 | 22 | Philippe Caseiro | On crée un "module" i18n.py (mais il pourrais très bien avoir un autre nom) et on y fait les déclarations et les initialisation nécessaires pour la traduction. |
| 131 | 22 | Philippe Caseiro | |
| 132 | 22 | Philippe Caseiro | * Dans ce module on importe gettext et les modules nécessaires a la gestion de la traduction (python-gettext) |
| 133 | 22 | Philippe Caseiro | <pre> |
| 134 | 22 | Philippe Caseiro | import gettext # Gettext lui même |
| 135 | 22 | Philippe Caseiro | import os # Pour les variables d'environement LANG/LC_ALL |
| 136 | 22 | Philippe Caseiro | import sys # Pour la gestion des fichiers de traduction |
| 137 | 22 | Philippe Caseiro | import locale # Pour la gestion des "locale" |
| 138 | 22 | Philippe Caseiro | </pre> |
| 139 | 22 | Philippe Caseiro | * On définis le nom du domaine de traduction (le plus souvent le nom de l'application) |
| 140 | 22 | Philippe Caseiro | <pre> |
| 141 | 22 | Philippe Caseiro | APP_NAME = 'pyeole' |
| 142 | 22 | Philippe Caseiro | </pre> |
| 143 | 22 | Philippe Caseiro | * On récupère les répertoires qui vont contentir les traductions |
| 144 | 22 | Philippe Caseiro | <pre> |
| 145 | 22 | Philippe Caseiro | # Traduction dir |
| 146 | 22 | Philippe Caseiro | APP_DIR = os.path.join(sys.prefix, 'share') |
| 147 | 22 | Philippe Caseiro | LOCALE_DIR = os.path.join(APP_DIR, 'locale') |
| 148 | 22 | Philippe Caseiro | </pre> |
| 149 | 22 | Philippe Caseiro | * On récupère la langue par défaut et on y ajoute l'anglais pour les messages non traduits |
| 150 | 23 | Philippe Caseiro | <pre> |
| 151 | 22 | Philippe Caseiro | # Default Lanugage |
| 152 | 22 | Philippe Caseiro | DEFAULT_LANG = os.environ.get('LANG', '').split(':') |
| 153 | 1 | Emmanuel GARETTE | DEFAULT_LANG += ['en_US'] |
| 154 | 23 | Philippe Caseiro | </pre> |
| 155 | 23 | Philippe Caseiro | * On définis la langue par défaut (je ne suis pas certain que cette partie ne soit pas inutile :) |
| 156 | 23 | Philippe Caseiro | <pre> |
| 157 | 22 | Philippe Caseiro | languages = [] |
| 158 | 22 | Philippe Caseiro | lc, encoding = locale.getdefaultlocale() |
| 159 | 22 | Philippe Caseiro | if lc: |
| 160 | 22 | Philippe Caseiro | languages = [lc] |
| 161 | 1 | Emmanuel GARETTE | |
| 162 | 1 | Emmanuel GARETTE | languages += DEFAULT_LANG |
| 163 | 23 | Philippe Caseiro | </pre> |
| 164 | 23 | Philippe Caseiro | * On fait les initialisations gettext |
| 165 | 23 | Philippe Caseiro | <pre> |
| 166 | 1 | Emmanuel GARETTE | mo_location = LOCALE_DIR |
| 167 | 1 | Emmanuel GARETTE | |
| 168 | 23 | Philippe Caseiro | gettext.find(APP_NAME, mo_location) # On cherche les traductions |
| 169 | 23 | Philippe Caseiro | gettext.textdomain(APP_NAME) # On crée le domaine de traduction (ou il vas chercher les messages) |
| 170 | 23 | Philippe Caseiro | gettext.bind_textdomain_codeset(APP_NAME, "UTF-8") # On définis le jeux de caracètres des traductions (utf8) |
| 171 | 23 | Philippe Caseiro | </pre> |
| 172 | 23 | Philippe Caseiro | * On initialise l'objet qui vas réaliser les traductions pour notre application |
| 173 | 23 | Philippe Caseiro | <pre> |
| 174 | 22 | Philippe Caseiro | t = gettext.translation(APP_NAME, fallback=True) |
| 175 | 23 | Philippe Caseiro | </pre> |
| 176 | 23 | Philippe Caseiro | * Enfin on créer la "fonction/methode/whatever" '_' : |
| 177 | 23 | Philippe Caseiro | <pre> |
| 178 | 1 | Emmanuel GARETTE | def _(msg): |
| 179 | 23 | Philippe Caseiro | return t.ugettext(msg) # on retourne le résultat de la traduction ! ugettext peut poser problème il ne prend que des chaines utf8 |
| 180 | 1 | Emmanuel GARETTE | </pre> |