【问题标题】:How do I debug a built-in Python command, package or module?如何调试内置的 Python 命令、包或模块?
【发布时间】:2020-05-06 19:55:34
【问题描述】:

我想调试一些 Python 安装附带的基本包和/或内置包,包括 pipvenv

希望来自文件权限的错误消息(无法访问具有“不可打印文件名”的文件),我的一些团队正在运行这些命令 - 有关详细信息,请参阅 this question

问题

在尝试捕获主要 python 可执行文件中的问题或直接运行基本 python 模块时如何调试 Python 源代码(请参阅以下示例以了解 pipvenv)?

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

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

【问题讨论】:

  • pip 是一个预构建的二进制文件,所以如果你想调试它很可能需要直接修改它的source code 并重建可执行文件。对于venv,源似乎位于<python_install>\lib\venv 下的__init__.py 文件中。在那里,你可以添加 import pdb; pdb.set_trace() 来启动 Python 调试器(或者只是 breakpoint(),它应该在 VSCode 中工作)。
  • @b_c:pip 'executable' 只是一个 Python 脚本,它使用pkg_resources library (间接)导入pip._internal.cli.main 模块并在其中运行main() 函数。打开which pip 指向的路径,您会看到它只是可以添加调试语句的文本。
  • @MartijnPieters 很高兴知道!我看的时候没有看到 pip 模块(没想到它会在 site-packages 中)而且我不认为 python -m pip 会暗示它确实作为模块存在于某处.

标签: python debugging visual-studio-code vscode-debugger


【解决方案1】:

首先查看这些模块的源代码; -m 开关首先查找要导入的包或模块。如果它是一个包,那么 Python 会在该包中导入 __main__ 模块并将其作为主脚本运行。如果是模块,则模块本身被导入并以__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 实际上直接链接到source code,而venv.__main__ module 只是导入venv.main() 并调用它。

【讨论】:

  • 谢谢!所以找到并下载源代码——我是否还需要主要 Python 安装中的“调试二进制文件”?我记得原始 Python 安装期间的复选框(至少在 Windows 上)。
  • @LightCC: python -c "import pip; print(pip)" 将为您提供硬盘上源代码的路径。
  • @LightCC:您不需要 Python 调试版本,不。这里没有什么是二进制扩展,都是 Python 代码。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多