如何调试内置 Python 命令、包或模块?

How do I debug a built-in Python command, package or module?

我想调试一些Python安装自带的基础包and/or是内置包,包括pipvenv

希望来自文件权限的错误消息(无法访问具有 "unprintable file name" 的文件)我的一些团队正在获得 运行 这些命令 - 请参阅 this question详情。

问题

当试图在主要 python 可执行文件中捕获问题时,或者当直接 运行 基本 python 模块时,您如何调试 Python 源代码(参见以下示例 pipvenv)?

$ python -m pip install --upgrade
$ python -m venv .venv

如果重要的话,我的环境是 VSCode,我很高兴能够在我编写的任何自定义脚本上使用调试器,使用与主程序交互(我假设)的内置调试器Microsoft Python 扩展。

首先查看这些模块的源代码; -m 开关首先查找要导入的包或模块。如果它是一个包,则 Python 导入该包中的 __main__ 模块,然后 运行 将其作为主脚本。如果是模块,模块本身被导入并且运行 as __main__.

通常代码的结构使得调用函数也可以直接导入。然后,您只需编写一些代码来导入相同的函数并以与 __main__ 模块相同的方式调用它。从那时起,在调试器下 运行 就变得微不足道了。

例如pip 是一个包,因此 python -m pip 将导入 pip.__main__ 和 运行 作为脚本。然后触发:

from pip._internal.cli.main import main as _main  # isort:skip # noqa

if __name__ == '__main__':
    sys.exit(_main())

成为运行。你可以在 VSCode 中做同样的事情;导入 pip._internal.cli.main.main 并调用它。

您可以找到这些模块的源代码,只需导入它们并打印出生成的对象即可:

python -c "import pip; print(pip)"

模块的表示,如果从磁盘加载,将包括它的文件名。如果文件名以 /__init__.py 结尾,则它是一个包,因此您还可以仔细检查 __main__.py 文件是否存在:

python -c "import pip.__main_; print(pip.__main__)"

您可以对 venv 模块执行相同的操作。这是 Python 标准库的一部分,因此 documentation actually links directly to the source code, and the venv.__main__ module 只需导入 venv.main() 并调用它。

您需要在 launch.json 中设置 "justMyCode": false 以便调试器跟踪第三方代码。