2015年12月10日

pydocにprivate属性も表示させる

pydoc に private属性も表示させる方法を紹介します。

pydoc は言わずと知れたドキュメント生成のための標準ライブラリです。
この pydoc で生成されるドキュメントには、protected や private 属性の変数/関数は含まれません。モジュールの使用者にとってはこの仕様でもいいのですが、モジュールを読んで解析 or 変更しようとしている人にとっては、この仕様は望ましくありません。

この部分の処理を行っているのは、pydoc の以下の関数です(pydoc のバージョンは 3.4)。

def visiblename(name, all=None, obj=None):
    """Decide whether to show documentation on a variable."""
    # Certain special names are redundant or internal.
    # XXX Remove __initializing__?
    if name in {'__author__', '__builtins__', '__cached__', '__credits__',
                '__date__', '__doc__', '__file__', '__spec__',
                '__loader__', '__module__', '__name__', '__package__',
                '__path__', '__qualname__', '__slots__', '__version__'}:
        return 0
    # Private names are hidden, but special names are displayed.
    if name.startswith('__') and name.endswith('__'): return 1
    # Namedtuples have public fields and methods with a single leading underscore
    if name.startswith('_') and hasattr(obj, '_fields'):
        return True
    if all is not None:
        # only document that which the programmer exported in __all__
        return name in all
    else:
        return not name.startswith('_')

visiblename() の最後の行で、_ で始まる変数/関数が弾かれています。この最後の行を変更した関数を作り、visiblename() と置き換えることで、protected や private 属性でもドキュメントに表示させることができます。
以下は visiblename() を置き換える具体的なファイルの例です。
### mypydoc.py
# -*- coding:utf-8 -*-

import pydoc

def my_visiblename(name, all=None, obj=None):
    """Decide whether to show documentation on a variable."""
    # Certain special names are redundant or internal.
    # XXX Remove __initializing__?
    if name in ['__author__', '__builtins__', '__cached__', '__credits__',
                '__date__', '__doc__', '__file__', '__spec__',
                '__loader__', '__module__', '__name__', '__package__',
                '__path__', '__qualname__', '__slots__', '__version__']:
        return 0
    # Private names are hidden, but special names are displayed.
    if name.startswith('__') and name.endswith('__'): return 1
    # Namedtuples have public fields and methods with a single leading underscore
    if name.startswith('_') and hasattr(obj, '_fields'):
        return True
    if all is not None:
        # only document that which the programmer exported in __all__
        return name in all
    else:
        # change to make protected/private variable visible
        return True
#        return not name.startswith('_')

def main():
    pydoc.visiblename = my_visiblename
    pydoc.cli()

if __name__ == '__main__':
    main()

ここで示した mypydoc.py は、pydoc.py と同等の使い方(e.g. python mypydoc.py -w modulename)が可能です。

0 件のコメント:

コメントを投稿