前の関連記事: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.31行目のこの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--qにfor_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のコールグラフを出力できます。
0 件のコメント:
コメントを投稿