linuxBean14.04(45)LibreOfficeのバンドルPythonでコールグラフ

前の関連記事:linuxBean14.04(44)Pythonモジュールのインポートエラーに悩まされる


LibreOffice5.0.0.0beta1のバンドルPython3.3.5でpycallgraphを使ってコールグラフを出力します。

LibreOfficeバンドルPython用のpycallgraphコマンドpycallgraphLO5を作成する


まずはpycallgraphを使えるようにします。

linuxBean14.04(40)pycallgraphでPythonのコールグラフ:その1でgraphvizとpycallgraphをpython3.3でインストールしてlinuxBean14.04(38)LibreOfficeバンドルPythonにパッケージを追加でLibreOfficeバンドルPythonでpycallgraphを使えるようにします。

psutilを3以上にアップグレードしているときはlinuxBean14.04(41)pycallgraphでPythonのコールグラフ:その2にあるように/usr/local/lib/python3.3/dist-packages/pycallgraph/memory_profiler.pyを修正しておきます。

pycallgraphのコマンドは/usr/local/bin/pycallgraphですが、これはpython3.3で起動するものになっているので、LibreOfficeバンドルPythonで起動するpycallgraphコマンドを作成します。

豆ボタン→アクセサリ→ファイルマネージャPCManFM(root)。

/usr/local/binにあるpycallgraphをコピペしてpycallgraphLO5という別名で保存します。

pycallgraphLO5を右クリック→Geany。
#!/usr/bin/python3.3
1行目のこのshebangをバンドルPythonのものに書き換えて保存します。
#!/opt/libreofficedev5.0/program/python
これでLibreOffice5.0.0.0beta1のバンドルPython3.3.5で起動するpycallgraphができました。

GeanyのビルドコマンドにpycallgraphLO5を設定する


linuxBean14.04(7)GeanyでLibreOfficeのPythonマクロ編集linuxBean14.04(26)Geanyのビルドコマンドの設定でやったようにGeanyのビルドコマンドで、PythonのオートメーションでLibreOfficeで接続した状態でコールグラフを出力できるように設定します。

LibreOffice5.0.0.0beta1のPythonのマイマクロフォルダは~/.config/libreofficedev/4/user/Scripts/pythonで、そこにunopy.pyを置き、サブフォルダにマイマクロのpyファイルを置いています。
#!/bin/bash
export PYTHONPATH=$1
OUTPUT_DIR=~/ピクチャ/pycallgraph  #出力先フォルダ名
if [ -e ${OUTPUT_DIR} ]; then
 mkdir -p ${OUTPUT_DIR}  #出力先フォルダを作成。
fi
LOG_FILE=${OUTPUT_DIR}/$(basename $2 .py)_$(date +%Y%m%d_%H%M%S).png #出力ファイル名の作成。
pycallgraphLO5 graphviz --output-file ${LOG_FILE} $2
これをfor_geany_pycallgraph.shというファイル名で~/.config/libreofficedev/4/user/Scripts/pythonに保存します。

LibreOffice(4)PyCharmからLibreOfficeを動かす(オートメーション)で作ったtest.pyを~/.config/libreofficedev/4/user/Scripts/python/testに置いてGeanyで開きます。

ビルド→ビルドコマンドの設定。


Pythonコマンドの2にpycallgraphと項目を作成しコマンドに%p/for_geany_pycallgraph.sh "%p" "%d/%f"を入力しました。

これでGeanyの設定は完了です。

linuxBean14.04(6)LibreOffice4.3.7とPyCharmの設定と同様にしてLibreOffice5はソケット通信できる状態で起動し、Writerを起動します。

Geanyでtest.pyのタブを選択した状態で、ビルド→pycallgraph。

~/ピクチャ/pycallgraphにtest_から始まるファイル名のpngファイルが出力されているはずです。


すでに起動しているWriterに「Hello World!」と表示させるだけのプログラムなのにたくさんの関数が働いていることがわかります。

__main__はど真ん中あたりにあります。

関心のないノード名を除外する


linuxBean14.04(41)pycallgraphでPythonのコールグラフ:その2の--excludeフィルターを使って関係なさそうなノードの出力を抑制します。
#!/bin/bash
#pycallgraphのオプションの処理
OPTION=
#OPTION=-m  # --memoryオプションを設定
#pycallgraphのフィルターの処理
#除外するノード名の設定
while read LINE
do
  EXCLUDE+=" -e "${LINE}
done << EOS # 除外するノード名一覧開始
SourceFileLoader*
ExtensionFileLoader*
new_module
_w_long
set_package_wrapper
_r_long
cb
_get_module_lock
_find_module
_ModuleLock*
find_module
_ImportLockContext*
_get_loader
_path_*
path_hook_for_FileFinder
FileFinder*
cache_from_source
_verbose_message
_relax_case
*genexpr*
EOS
# 除外するノード名一覧終了
export PYTHONPATH=$1
OUTPUT_DIR=~/ピクチャ/pycallgraph  #出力先フォルダ名
if [ -e ${OUTPUT_DIR} ]; then
 mkdir -p ${OUTPUT_DIR}  #出力先フォルダを作成。
fi
LOG_FILE=${OUTPUT_DIR}/$(basename $2 .py)_$(date +%Y%m%d_%H%M%S).png #出力ファイル名の作成。
pycallgraphLO5 ${OPTION} ${EXCLUDE} graphviz --output-file ${LOG_FILE} $2
これでだいぶすっきりしたコールグラフが得られました。

_find_and_load、_find_and_load_unlocked、_call_with_frames_removedの3つのノードはunohelperとunoモジュールにあるノードへのエッジが途切れてしまうところが出てくるので残しておきました。

今回手間取ったのは「-e」をechoで表示させることです。

変数の出力確認でechoを使っていたのですが「-e」が出力されなくてどうしてかわからなくて悩みました。

結局-eはechoのオプションの一つであるのが原因でわかりました。
pq@pq-VirtualBox:~$ echo "-e"

pq@pq-VirtualBox:~$ echo '-e'

pq@pq-VirtualBox:~$ echo -e -e

pq@pq-VirtualBox:~$ echo -e "-e"

原因はわかりましたがどうがんばっても「-e」を単独でechoで出力することができませんでした。

結局linuxBean14.04(27)Geanyとシェルスクリプトのデバッグのbashdbで変数確認しました。

linuxBean14.04(45)LibreOfficeのバンドルPythonでコールグラフ - p--qfor_geany_pycallgraph.shを置いておきました。

pycallgraphのAPIでコールグラフを出力する


Python Call Graph — Python Call Graph 1.0.1 documentationにはAPIを使ってPythonスクリプトのなかから直接pycallgraphを呼び出す方法も紹介されています。
def HelloWorld_Writer():
 from pycallgraph import PyCallGraph
 from pycallgraph.output import GraphvizOutput
 with PyCallGraph(output=GraphvizOutput()):
  doc = XSCRIPTCONTEXT.getDocument()
  doc.getText().setString("Hello World!")
if __name__ == "__main__":
    import unopy
    XSCRIPTCONTEXT = unopy.connect()
    if not XSCRIPTCONTEXT:
        print("Failed to connect.")
        import sys
        sys.exit(0)
    HelloWorld_Writer()
test.pyをこうやって書き換えて実行してみます。
4行目のwith文の中の部分のみコールグラフに出力されています。

APIを使えばLibreOfficeのマクロとして呼び出したとき(Scripting Frameworkで動くモード)にもコールグラフを出力できると思ったのですが、それは無理でした。


pycallgraph自体は読み込まれているようですけど、それ以上の解決方法はわかりませんでした。

参考にしたサイト


Python Call Graph — Python Call Graph 1.0.1 documentation
Pythonのコールグラフを出力できます。

次の関連記事:linuxBean14.04(46)Eclipse Modeling Toolsのインストール

PR

0 件のコメント:

コメントを投稿