我们之前提过如何在 vscode 中优雅的使用 debugpy 来调试代码,但在那里我们主要考虑的是开发阶段的代码,也就是说代码是在本地仓库中而非安装在环境中。那么如何调试一个已安装在环境中的代码库呢?
先讲讲背景:我在虚拟环境中安装了 bonito 库,同时本地也拉下来了 bonito 库,那么我就面临两种选择:
- 调试在
~/workspace/bonito
的本地库 - 调试在
~/micromamba/envs/bonito
中的安装库
由于 bonito 提供了 cli 工具,因此在命令行中可以直接用 bonito
来启用它。于是我首先想的是我并不能在 xxx.py
文件头部分添加 debugpy 的代码,然后运行 python xxx.py
来调试,所以选择第一种方法。
我尝试了python bonito/__init__.py
,不行。因为 __init__.py
不允许直接运行,它理应以模块的方式被运行即 python -m bonito/__init__.py
,但后者我没有尝试。然后我尝试使用 python bonito/__main__.py
,是可以连接上 debugpy,但是又会陷入 import error,因为本地库与已安装在环境中的库同名,所以会导致路径解析错误等问题。如果想要继续使用第一种方法,那么就需要卸载环境中的 pip uninstall bonito
,然后安装开发依赖 pip install -r requirements.txt
,这样就可以规避路径问题。
于是我考虑第二种方法。一般来说我们可以在环境中的 bonito 库下的对应文件中添加 debugpy 的代码,但是我发现因为 bonito cli 直接注册在了 ~/.local/bin/bonito
路径下,因此直接修改代码如下:(注意这个文件不是.py
而是一个由 shell 执行的脚本文件,只不过 shell 会调用 python3 来执行它)
!/usr/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from bonito import main
# debug_bonito.py
import debugpy
import sys
# Start debugger server and wait for attachment
debugpy.listen(("localhost", 5678))
print("Waiting for debugger to attach at localhost:5678...")
debugpy.wait_for_client()
debugpy.breakpoint() # Initial breakpoint
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
这样当我们在命令行中直接运行 bonito
时,就会等待调试器连接。往后就和前文介绍的一样调试即可。不过要记得在调试完成后把调试代码删除。当然你也可以另外创建一个调试脚本调用 bonito
以免干扰。
预览: