
Call Mapの現在の開発はhttps://github.com/ajylee/call_mapで行われています。Call MapはPythonコールグラフをナビゲートするためのツールです。
.. default-role:: code
Call Map は、Python のコールグラフを操作するためのツールであり、他の言語のサポートも計画されています。以下は、call_map -m toolz を実行し、いくつかの関数をクリックした後のスクリーンショットです。
.. figure:: docs/UI-clicked-on-function.png
Call Map はコードベースの全体的な理解に役立つことを目的としていますが、コードパスを追跡するのにも自然に適しており、これは重要なセキュリティ上の関心事です。多くのセキュリティ問題は、ユーザー入力を危険なコーディングパターンに結び付けるコードパスを見つけることで明らかになります。
詳細については、ブログ記事__ を参照してください。
Call Map は Python 3.5 向けの Python パッケージとして配布されています。pip3 でインストールするには、次のように実行します::
pip3 install -e .
一部の Python 3 ディストリビューションではパッケージマネージャーを pip と呼び、また pip3 と呼ぶものもあるため、pip3 を pip に置き換える必要があるかもしれません。
上記のコマンドを実行すると、実行可能ファイル call_map が Python インタープリターと同じパスにインストールされるはずです。
詳細と代替方法については、INSTALL.rst を参照してください。
探索を始めるにはファイルを開きます::
call_map -f example.py
call_map -f *.py
モジュール検索パス (sys.path) に追加することもできます::
call_map -f *.py -p .
Call Map は、モジュール検索パス内でファイルが見つかると、それらをモジュールとして解決しようとします。コマンドライン引数の詳細については、call_map -h を参照してください。
Call Map を設定するには、環境変数 CALL_MAP_RC_DIRECTORY を設定します。 Call Map 設定ファイルへのパスは次のようになります::
$CALL_MAP_RC_DIRECTORY/call_map_rc.py
現時点での設定オプションは次のとおりです:
open_in_editor(path: pathlib.Path, line: int): この関数を定義すると、ファイルを開くたびに呼び出されます。たとえば、実行中の Emacs セッションで server-mode を呼び出している場合、次のコードを使用して Emacs サーバーでファイルを開くことができます::
def open_in_editor(path, line): import subprocess as sbp sbp.call(['emacsclient', '+{}'.format(line), str(path)])
また、gvim --servername my_vim_server で GVim サーバーを起動している場合、次のコードを使用して GVim サーバーでファイルを開くことができます::
def open_in_editor(path, line): import subprocess as sbp sbp.call(['gvim', '--servername', 'my_vim_server', '--remote', '+{}'.format(line), str(path)])
MULTITHREADING: GUI とコールグラフの検索に別々のスレッドを使用するかどうか。デフォルトは True です。オフにするのはデバッグ目的です。
UI デザインにはいくつかの癖があります。これは、より良い解決策にまだ到達していないか、追加の複雑さのトレードオフが好ましくないためです。
使用箇所が複数回表示されるように見えることがありますが、実際には同じスコープ内の異なる使用箇所です。
help、id、filter などの一部の組み込み関数が無視されることに気付くかもしれません。無視される関数の完全なリストについては、ソースコード内の call_map/config.py を参照してください。
ハイライトする位置がファイルの先頭にある場合、ハイライトされません。これは、通常、モジュールとスクリプトだけがそれぞれのファイルの先頭に配置されるためです。
いくつかの癖は、jedi の Python 解析バックエンドから引き継がれています。
使用箇所の検索スコープは、jedi バックエンドによってロードされたモジュールのセットです。つまり、新しいモジュールを探索するにつれて、スコープが変化します。検索スコープにモジュールを明示的に含めたい場合は、最初に検査するモジュールのリストに追加してください。
jedi は、明示的に含まれていない場合でも、常にインタープリターの sys.path を検索します。ただし、ユーザー定義の sys_path を優先します。
静的解析バックエンドに存在する注意事項は、Call Map にも当てはまります。(現時点では、jedi バックエンドのみが Call Map に統合されています。)
Python 解析のための jedi バックエンドは、すべての使用箇所を常に見つけられるわけではありません。Python の動的な性質により、静的解析で関数の定義を常に決定することは不可能です。jedi が呼び出しを複数の可能な関数に解決することがあります。たとえば、os.path.abspath はプラットフォームに依存します。この場合、call_map は両方の可能性を abspath と abspath (2) としてリストします。jedi はまた、すべての呼び出しと使用箇所を解決するわけでもありません。Jedi 自身のドキュメントにも 注意事項のリスト__ があります。
Jedi がある項目の解析中にエラーを投げると、そのエラーが他の項目に影響することがあります。たとえば、使用箇所を検索するときに、Jedi がある使用箇所でエラーを発生させると、見つかった他の使用箇所が回復できない場合があります (Jedi v0.10.0 の時点)。
__ https://jedi.readthedocs.io/en/latest/docs/features.html#caveats