Hybride pour récupérer les docstrings d'un fichier Python
Bonjour,
pour le plaisir, mais aussi par nécessité, je me suis lancé dans la création d'un outil pour récupérer les docstrings d'un fichier Python. Voici un 1er brouillon qui montre les grandes lignes :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| #! /usr/bin/env python3
# Source :
# http://docs.python.org/py3k/library/ast.html
# http://pypi.python.org/pypi/pyRegurgitator/0.1.1
import ast
IaNDENT_INCREASE = 4
def astStupidPrint(oneNode):
"""To quickly see what is done by the module "ast"."""
for oneNode in ast.iter_child_nodes(astTree):
print('--', oneNode._fields, ast.dump(oneNode), sep="\n")
def docstringPrint(oneNode, indentLevel = -INDENT_INCREASE, className = '', infoToPrint = ''):
#print(type(oneNode))
if isinstance(oneNode, ast.Expr) and isinstance(oneNode.value, ast.Str):
print(' '*indentLevel + '=== DOCSTRING {} ==='.format(infoToPrint),
' '*(indentLevel + INDENT_INCREASE) + oneNode.value.s.replace('\n',
'\n' + ' '*(indentLevel + INDENT_INCREASE)),
sep="\n")
elif 'body' in oneNode._fields:
if isinstance(oneNode, ast.FunctionDef):
if className:
infoToPrint = 'METHOD OF "{0}" :: {1}'.format(className,
oneNode.name)
else:
infoToPrint = 'FUNCTION :: ' + oneNode.name
elif isinstance(oneNode, ast.ClassDef):
infoToPrint = 'CLASS :: ' + oneNode.name
className = oneNode.name
else:
infoToPrint = 'CURRENT MODULE OR FILE'
content = getattr(oneNode, 'body')
if content:
for onePiece in content:
docstringPrint(oneNode = onePiece,
indentLevel = indentLevel + INDENT_INCREASE,
className = className,
infoToPrint = infoToPrint)
if __name__ == '__main__':
file = open('test.py')
astTree = ast.parse(file.read())
# astStupidPrint(astTree)
# print()
docstringPrint(astTree) |
Le fichier test.py est le suivant :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #! /usr/bin/env python3
"""1ère doc du fichier
sur deux lignes"""
def myFunction(x=0, y="1"):
"""Doc de la fonction nommée myFunction"""
x=3
# Un commentaire.
z = x+y
return z
"""2nde docstring mal placée..."""
print(myFunction(5,6))
class bidon():
"""Doc de la classe bidon"""
def __init__(self):
"""1ère doc de la méthode __init__ de la classe bidon"""
...
"""2ème doc mal placée de la méthode __init__""" |
Ceci me renvoie :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
| === DOCSTRING CURRENT MODULE OR FILE ===
1ère doc du fichier
sur deux lignes
=== DOCSTRING FUNCTION :: myFunction ===
Doc de la fonction nommée myFunction
=== DOCSTRING CURRENT MODULE OR FILE ===
2nde docstring mal placée...
=== DOCSTRING CLASS :: bidon ===
Doc de la classe bidon
=== DOCSTRING METHOD OF "bidon" :: __init__ ===
1ère doc de la méthode __init__ de la classe bidon
=== DOCSTRING METHOD OF "bidon" :: __init__ ===
2ème doc mal placée de la méthode __init__ |
J'essaierais d'améliorer ceci pour obtenir un mini outil de documentation à la sauce epydoc mais en plus facile à personnaliser.
De plus en ayant toutes les docstrings, on peut envisager un moyen de faire des tutos qui affichent le code morcelé avec entre chaque morceau des commentaires en ayant juste à taper quelque chose comme :
Code:
1 2 3 4 5 6 7
| for i in range(5):
print(i)
""" Nous avons ici une première façon de taper une boucle..."""
i = 0
while(i < 5):
print(i)
"""Voici une autre méthode pour obtenir le même résultat que précédemment...""" |
Ensuite un petit prog. Python donnerait la mise en forme suivante :
Citation:
Code:
1 2
| for i in range(5):
print(i) |
Nous avons ici une première façon de taper une boucle...
Code:
1 2 3
| i = 0
while(i < 5):
print(i) |
Voici une autre méthode pour obtenir le même résultat que précédemment...
PS : merci à nardo47 de m'avoir dirigé vers ast.