Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 296d7d1

Browse files
committed
Python: CG trace: Allow tracing modules
As would normally be invoked by `python -m <module-name>` now works with `cg-trace --module <module-name>`. This is useful for tracing invocations of `pytest`.
1 parent 89e8202 commit 296d7d1

2 files changed

Lines changed: 32 additions & 13 deletions

File tree

python/tools/recorded-call-graph-metrics/src/cg_trace/cmdline.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ def parse(args):
66

77
parser.add_argument("--xml")
88

9+
parser.add_argument(
10+
"--module", action="store_true", default=False, help="Trace a module"
11+
)
12+
913
parser.add_argument("progname", help="file to run as main program")
1014
parser.add_argument(
1115
"arguments", nargs=argparse.REMAINDER, help="arguments to the program"

python/tools/recorded-call-graph-metrics/src/cg_trace/main.py

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,34 @@ def main(args=None) -> int:
4141

4242
# These details of setting up the program to be run is very much inspired by `trace`
4343
# from the standard library
44-
sys.argv = [opts.progname, *opts.arguments]
45-
sys.path[0] = os.path.dirname(opts.progname)
46-
47-
with open(opts.progname) as fp:
48-
code = compile(fp.read(), opts.progname, "exec")
49-
50-
# try to emulate __main__ namespace as much as possible
51-
globs = {
52-
"__file__": opts.progname,
53-
"__name__": "__main__",
54-
"__package__": None,
55-
"__cached__": None,
56-
}
44+
if opts.module:
45+
import runpy
46+
47+
module_name = opts.progname
48+
_mod_name, mod_spec, code = runpy._get_module_details(module_name)
49+
sys.argv = [code.co_filename, *opts.arguments]
50+
globs = {
51+
"__name__": "__main__",
52+
"__file__": code.co_filename,
53+
"__package__": mod_spec.parent,
54+
"__loader__": mod_spec.loader,
55+
"__spec__": mod_spec,
56+
"__cached__": None,
57+
}
58+
else:
59+
sys.argv = [opts.progname, *opts.arguments]
60+
sys.path[0] = os.path.dirname(opts.progname)
61+
62+
with open(opts.progname) as fp:
63+
code = compile(fp.read(), opts.progname, "exec")
64+
65+
# try to emulate __main__ namespace as much as possible
66+
globs = {
67+
"__file__": opts.progname,
68+
"__name__": "__main__",
69+
"__package__": None,
70+
"__cached__": None,
71+
}
5772

5873
start = time.time()
5974
recorded_calls, captured_stdout, captured_stderr, exit_status = record_calls(

0 commit comments

Comments
 (0)