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`.
This commit is contained in:
Rasmus Wriedt Larsen
2020-07-21 19:39:51 +02:00
parent 89e8202d11
commit 296d7d1725
2 changed files with 30 additions and 11 deletions

View File

@@ -6,6 +6,10 @@ def parse(args):
parser.add_argument("--xml") parser.add_argument("--xml")
parser.add_argument(
"--module", action="store_true", default=False, help="Trace a module"
)
parser.add_argument("progname", help="file to run as main program") parser.add_argument("progname", help="file to run as main program")
parser.add_argument( parser.add_argument(
"arguments", nargs=argparse.REMAINDER, help="arguments to the program" "arguments", nargs=argparse.REMAINDER, help="arguments to the program"

View File

@@ -41,19 +41,34 @@ def main(args=None) -> int:
# These details of setting up the program to be run is very much inspired by `trace` # These details of setting up the program to be run is very much inspired by `trace`
# from the standard library # from the standard library
sys.argv = [opts.progname, *opts.arguments] if opts.module:
sys.path[0] = os.path.dirname(opts.progname) import runpy
with open(opts.progname) as fp: module_name = opts.progname
code = compile(fp.read(), opts.progname, "exec") _mod_name, mod_spec, code = runpy._get_module_details(module_name)
sys.argv = [code.co_filename, *opts.arguments]
globs = {
"__name__": "__main__",
"__file__": code.co_filename,
"__package__": mod_spec.parent,
"__loader__": mod_spec.loader,
"__spec__": mod_spec,
"__cached__": None,
}
else:
sys.argv = [opts.progname, *opts.arguments]
sys.path[0] = os.path.dirname(opts.progname)
# try to emulate __main__ namespace as much as possible with open(opts.progname) as fp:
globs = { code = compile(fp.read(), opts.progname, "exec")
"__file__": opts.progname,
"__name__": "__main__", # try to emulate __main__ namespace as much as possible
"__package__": None, globs = {
"__cached__": None, "__file__": opts.progname,
} "__name__": "__main__",
"__package__": None,
"__cached__": None,
}
start = time.time() start = time.time()
recorded_calls, captured_stdout, captured_stderr, exit_status = record_calls( recorded_calls, captured_stdout, captured_stderr, exit_status = record_calls(