"trace" --- 跟踪或记录 Python 语句的执行
****************************************

**源代码** ： Lib/trace.py

======================================================================

"trace" 模块允许你跟踪程序执行，生成带注解的语句覆盖率列表，打印调用者
/被调用者关系以及列出程序运行过程中执行的函数。 它可以在其他程序中使用
或从命令行使用。

参见:

  Coverage.py
     流行的第三方代码覆盖工具，可输出 HTML ，并提供分支覆盖等高级功能
     。


命令行用法
==========

"trace" 模块可以从命令行调用。 只需简单地

   python -m trace --count -C . somefile.py ...

上述命令将执行 "somefile.py" ，并在当前目录生成执行期间所有已导入
Python 模块的带注解列表。

--help

   显示用法并退出。

--version

   显示模块版本并退出。

Added in version 3.8: 增加了 "--module" 选项，它允许运行可执行的模块。


主要的可选参数
--------------

调用 "trace" 时必须至少指定以下选项之一。 "--listfuncs" 选项与 "--
trace" 和 "--count" 选项互斥。 当提供了 "--listfuncs" 时，"--count" 和
"--trace" 都不可接受，反之亦然。

-c, --count

   在程序完成时生成一组带有注解的报表文件，显示每个语句被执行的次数。
   参见下面的 "--coverdir"、"--file" 和 "--no-report"。

-t, --trace

   执行时显示每一行。

-l, --listfuncs

   显示程序运行时执行到的函数。

-r, --report

   由之前用了 "--count" 和 "--file" 运行的程序产生一个带有注解的报表。
   不会执行代码。

-T, --trackcalls

   显示程序运行时暴露出来的调用关系。


修饰器
------

-f, --file=<file>

   用于累计多次跟踪运行计数的文件名。应与 "--count" 一起使用。

-C, --coverdir=<dir>

   报表文件的所在目录。"package.module" 的覆盖率报表将被写入文件
   "*dir*/*package*/*module*.cover"。

-m, --missing

   生成带注解的报表时，用 ">>>>>>" 标记未执行的行。

-s, --summary

   在用到 "--count" 或 "--report" 时，将每个文件的简短摘要输出到
   stdout。

-R, --no-report

   不生成带注解的报表。如果打算用 "--count" 执行多次运行，然后在最后产
   生一组带注解的报表，该选项就很有用。

-g, --timing

   在每一行前面加上时间，自程序运行算起。只在跟踪时有用。


过滤器
------

以下参数可重复多次。

--ignore-module=<mod>

   忽略给出的模块名及其子模块（若为包）。参数可为逗号分隔的名称列表。

--ignore-dir=<dir>

   忽略指定目录及其子目录下的所有模块和包。参数可为 "os.pathsep" 分隔
   的目录列表。


编程接口
========

class trace.Trace(count=1, trace=1, countfuncs=0, countcallers=0, ignoremods=(), ignoredirs=(), infile=None, outfile=None, timing=False)

   创建一个对象来跟踪单个语句或表达式的执行。所有参数均为选填。
   *count* 可对行号计数。 *trace* 启用单行执行跟踪。 *countfuncs* 可列
   出运行过程中调用的函数。 *countcallers* 可跟踪调用关系。
   *ignoremods* 是要忽略的模块或包的列表。*ignoredirs* 是要忽略的模块
   或包的目录列表。 *infile* 是个文件名，从该文件中读取存储的计数信息
   。 *outfile* 是用来写入最新计数信息的文件名。 *timing* 可以显示相对
   于跟踪开始时间的时间戳。

   run(cmd)

      执行命令，并根据当前跟踪参数从执行过程中收集统计数据。 *cmd* 必
      须为字符串或 code 对象，可供传入 "exec()"。

   runctx(cmd, globals=None, locals=None)

      在定义的全局和局部环境中，执行命令并收集当前跟踪参数下的执行统计
      数据。若没有定义 *globals* 和 *locals* ，则默认为空字典。

   runfunc(func, /, *args, **kwds)

      在 "Trace" 对象的控制下，用给定的参数调用 *func*，并采用当前的跟
      踪参数。

   results()

      返回一个 "CoverageResults" 对象，包含之前对指定 "Trace" 实例调用
      "run"、"runctx" 和 "runfunc" 的累积结果。 累积的跟踪结果不会重置
      。

class trace.CoverageResults

   存放代码覆盖结果的容器，由 "Trace.results()" 创建。用户不应直接去创
   建。

   update(other)

      从另一个 "CoverageResults" 对象中合并代码覆盖数据。

   write_results(show_missing=True, summary=False, coverdir=None, *, ignore_missing_files=False)

      写入代码覆盖结果。设置 *show_missing* 可显示未命中的行。设置
      *summary* 可在输出中包含每个模块的覆盖率摘要信息。 *coverdir* 可
      指定覆盖率结果文件的输出目录，为 "None" 则结果将置于源文件所在目
      录中。

      如果 *ignore_missing_files* 为 "True"，则对于已不存在文件的覆盖
      计数将被静默地忽略。 在其他情况下，文件不存在将引发
      "FileNotFoundError"。

      在 3.13 版本发生变更: 增加了 *ignore_missing_files* 形参。

以下例子简单演示了编程接口的用法：

   import sys
   import trace

   # 创建一个 Trace 对象，告诉它要忽略什么，
   # 及是否执行跟踪或行计数或者两者均执行。
   tracer = trace.Trace(
       ignoredirs=[sys.prefix, sys.exec_prefix],
       trace=0,
       count=1)

   # 使用给定的 tracer 运行新命令
   tracer.run('main()')

   # 生成报告，将输出放入当前目录
   r = tracer.results()
   r.write_results(show_missing=True, coverdir=".")
