Python で実行される行を trace で表示する2023年01月30日 12時05分13秒

Python はスクリプト言語。シェルの sh -x の様に実行行を表示する trace モジュールがある。

trace モジュールがあり、いくつかの種類がある。

% python3 -m trace tracer.py 
usage: trace.py [-h] [--version] [-c] [-t] [-l] [-T] [-r | -R] [-f FILE]
                [-C COVERDIR] [-m] [-s] [-g] [--ignore-module IGNORE_MODULE]
                [--ignore-dir IGNORE_DIR] [--module]
                [progname] ...
trace.py: error: must specify one of --trace, --count, --report, --listfuncs, or --trackcalls

小さいプログラムで実験。

% cat tracer1.py 
a = "A"
b = 1
print(a, b)
% python3 -m trace --trace tracer1.py
 --- modulename: tracer1, funcname: 
tracer1.py(1): a = "A"
tracer1.py(2): b = 1
tracer1.py(3): print(a, b)
A 1

import 文はそのまま import だけの表示のようだ。

% cat tracer2.py
from typing import List
% python3 -m trace --trace tracer2.py
 --- modulename: tracer2, funcname: 
tracer2.py(1): from typing import List

関数の呼び出しは表示される物とされない物があるようだ。

% cat tracer3.py
b = str(1)
print(b)
(venv39-amd64) % python3 -m trace --trace tracer3.py
 --- modulename: tracer3, funcname: 
tracer3.py(1): b = str(1)
tracer3.py(2): print(b)
1

os.getenv は関数の実行内容も表示される。

% cat tracer5.py
import os

os.getenv("PYTHONPATH")
% python3 -m trace --trace tracer5.py
 --- modulename: tracer5, funcname: 
tracer5.py(1): import os
tracer5.py(3): os.getenv("PYTHONPATH")
 --- modulename: os, funcname: getenv
os.py(775):     return environ.get(key, default)
 --- modulename: _collections_abc, funcname: get
_collections_abc.py(762):         try:
_collections_abc.py(763):             return self[key]
 --- modulename: os, funcname: __getitem__
os.py(675):         try:
os.py(676):             value = self._data[self.encodekey(key)]
 --- modulename: os, funcname: encode
os.py(755):             if not isinstance(value, str):
os.py(757):             return value.encode(encoding, 'surrogateescape')
os.py(677):         except KeyError:
os.py(679):             raise KeyError(key) from None
_collections_abc.py(764):         except KeyError:
_collections_abc.py(765):             return default

最後に例外を trace。

% cat tracer4.py
raise Exception("Test")
% python3 -m trace --trace tracer4.py
 --- modulename: tracer4, funcname: <module>
tracer4.py(1): raise Exception("Test")
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/local/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/usr/local/lib/python3.9/trace.py", line 740, in 
    main()
  File "/usr/local/lib/python3.9/trace.py", line 728, in main
    t.runctx(code, globs, globs)
  File "/usr/local/lib/python3.9/trace.py", line 450, in runctx
    exec(cmd, globals, locals)
  File "tracer4.py", line 1, in <module>
    raise Exception("Test")
Exception: Test