Visual Studio 2022附加调试器至Python进程引发子进程debugpy错误
Visual Studio 2022附加Python进程后subprocess调用报错ModuleNotFoundError: No module named 'debugpy'
问题背景
项目目录结构:
test-debugpy-issue | test-debugpy-issue.sln | \---test-debugpy-issue cli.py test-debugpy-issue.pyproj test_debugpy_issue_simplified.py
cli.py代码:
print("hello world")
test_debugpy_issue_simplified.py代码:
import subprocess import os import json print(os.getpid()) input() configArgs = ["python", "cli.py"] ret_code=0 while ret_code==0: ret_code = subprocess.call(configArgs, shell=False, universal_newlines=True) print(ret_code)
复现步骤:
- 在Powershell或CMD终端运行
python .\test_debugpy_issue_simplified.py - 复制输出的进程PID
- 在Visual Studio 2022中通过「Debug > Attach to Process」粘贴PID并选择进程,点击Attach(可能需多次尝试)
- 返回终端按Enter,触发报错:
0.47s - Error importing debugpy._vendored.force_pydevd (with sys.path entry: 'c:\program files\microsoft visual studio\2022\professional\common7\ide\extensions\microsoft\python\core') Traceback (most recent call last): File "c:\program files\microsoft visual studio\2022\professional\common7\ide\extensions\microsoft\python\core\debugpy_vendored\pydevd_pydevd_bundle\pydevd_defaults.py", line 60, in on_pydb_init import(module_name) ModuleNotFoundError: No module named 'debugpy'
原因分析
Visual Studio 2022的Python调试器基于pydevd实现,当通过「Attach to Process」附加到目标Python进程时,会自动修改该进程的环境变量和sys.path,注入VS自带的调试相关组件路径(如debugpy_vendored)。
当父进程通过subprocess创建子进程时,子进程默认会继承父进程的所有环境变量。此时子进程的Python环境中并没有安装debugpy模块,但继承的调试环境变量会触发pydevd的初始化逻辑(调用on_pydb_init),尝试导入debugpy,最终导致模块找不到的错误。
解决方法
方法1:清除子进程的调试相关环境变量
在调用subprocess时,创建一个干净的环境副本,移除所有与pydevd/debugpy相关的环境变量,避免子进程触发调试初始化逻辑:
修改test_debugpy_issue_simplified.py中的subprocess调用代码:
import subprocess import os import json print(os.getpid()) input() configArgs = ["python", "cli.py"] ret_code=0 while ret_code==0: # 创建环境副本并移除调试相关变量 clean_env = os.environ.copy() for key in list(clean_env.keys()): if key.startswith("PYDEVD_") or key.startswith("DEBUGPY_"): del clean_env[key] # 使用干净环境运行子进程 ret_code = subprocess.call(configArgs, shell=False, universal_newlines=True, env=clean_env) print(ret_code)
方法2:指定子进程使用独立的Python解释器
如果父进程的Python解释器已被VS调试环境修改,可以直接指定子进程使用系统/虚拟环境中未被调试器注入的Python解释器绝对路径,例如:
# 替换为你的Python解释器绝对路径 configArgs = ["C:\\Python39\\python.exe", "cli.py"]
方法3:禁用子进程的调试器自动初始化
通过设置环境变量PYDEVD_DISABLE_FILE_VALIDATION=1,强制关闭pydevd的自动初始化逻辑,避免触发debugpy导入:
clean_env = os.environ.copy() clean_env["PYDEVD_DISABLE_FILE_VALIDATION"] = "1" ret_code = subprocess.call(configArgs, shell=False, universal_newlines=True, env=clean_env)
内容的提问来源于stack exchange,提问作者user32882
相关产品推荐
相关产品推荐

