私はepytextからreSTマークアップへのコンバーターを作成しました。今、ライブラリ全体のすべての docstring を epytext から reST 形式に変換したいと考えています。
モジュール内のすべての docstring を読み取り、置換を書き戻すスマートな方法はありますか?
ps:おそらくastモジュール?
この単純な使い方ではやり過ぎかもしれませんが、編集を行うために2to3の機構を使用することを検討します。カスタム フィクサーを作成するだけです。十分に文書化されているわけではありませんが、Python 3.0 の開発者ガイド: Python 2.6 と 2 から 3 への移行: 2to3の詳細とカスタム フィクサーの実装には、開始するのに十分な詳細が記載されています...
Epydoc にはto_rst()
、docstring を実際に翻訳するのに役立つメソッドが含まれているようです。良いかどうかはわかりません...
イントロスペクションとソース処理の組み合わせについて疑問に思います。テストされていない疑似コードを次に示します。
import foo #where foo is your module
with open('foo.py',r) as f:
src = f.readlines()
for pything in dir(foo): #probably better ways to do this...
try:
docstring = pything.__doc__
except AttributeError:
#no docstring here
pass
#modify the docstring
new_docstring = my_format_changer(docstring)
#now replace it in the source
src = src.replace(docstring, new_docstring)
#When done, write it out
with open('new_foo.py','w') as fout:
fout.write(src)
明らかに、再帰するようにdocstringを持つオブジェクトを探してモジュールをトラバースするコードにいくらかの巧妙さを加える必要がありますが、これで一般的なアイデアが得られます。
おそらく、昔ながらの方法で行うのが最も簡単です。これが最初のコードです。それはおそらくもっときれいかもしれませんが、基本的なアイデアを与える必要があります:
def is_docstr_bound(line):
return "'''" in line or '"""' in line
# XXX: output using the same name to some other folder
output = open('output.py', 'w')
docstr_found = False
docstr = list()
with open('input.py') as f:
for line in f.readlines():
if docstr_found:
if is_docstr_bound(line):
# XXX: do conversion now
# ...
# and write to output
output.write(''.join(docstr))
output.write(line)
docstr = list()
docstr_found = False
else:
docstr.append(line)
else:
if is_docstr_bound(line):
docstr_found = True
output.write(line)
output.close()
本当に機能させるには、ファイルファインダーに接続して、ファイルを他のディレクトリに出力する必要があります。参照用にos.pathモジュールを確認してください。
docstring バウンド チェックが非常に弱い可能性があることはわかっています。少し強化するのはおそらく良い考えです (行を削除し、docstring バインドで開始または終了するかどうかを確認します)。
うまくいけば、それがおそらくどのように進めるかについてのアイデアを与えるでしょう。おそらく、問題を処理するためのよりエレガントな方法があります。:)