如何确定Python库中触发TypeError的变量实际值
问题描述
我希望能够直接查看触发TypeError的变量具体值,无需阅读或修改第三方库的源码。
遇到问题的Traceback如下:
Traceback (most recent call last): File "/censored/trunk/censored-cli/censored.py", line 945, in <module> detection(filelist, []) #empty options for now because we dont need any File "/censored/trunk/censored-cli/censored.py", line 770, in detection subprocess.run(analysis_cmd,env=env,check=True) File "/home/name/.julia/conda/3/lib/python3.9/subprocess.py", line 505, in run with Popen(*popenargs, **kwargs) as process: File "/home/name/.julia/conda/3/lib/python3.9/subprocess.py", line 951, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "/home/name/.julia/conda/3/lib/python3.9/subprocess.py", line 1741, in _execute_child env_list.append(k + b'=' + os.fsencode(v)) File "/home/name/.julia/conda/3/lib/python3.9/os.py", line 810, in fsencode filename = fspath(filename) # Does type-checking of `filename`. TypeError: expected str, bytes or os.PathLike object, not int
当前报错仅提示fsencode函数第810行的filename参数被识别为int类型,需要直接看到该参数的实际值。已知可以修改本地安装的fsencode源码添加打印语句输出变量值,但希望使用Python内置的方式实现,无需修改源码。
解决方法
不需要修改标准库源码,用Python内置能力有两种直接的实现方式:
- 使用pdb事后调试
运行脚本时追加-m pdb参数启动内置调试器:
程序抛出TypeError后会自动停在异常触发位置,进入pdb交互界面。输入python -m pdb 你的脚本路径.pyup命令可以逐层向上切换调用栈帧,切换到os.fsencode对应的栈帧后,输入p filename即可直接打印触发错误的变量实际值。如果需要快速定位栈帧,可以先输入where打印完整调用栈,再用up 栈帧序号直接跳转到目标帧。 - 自定义异常钩子自动打印变量
在自己业务代码的最开头添加如下excepthook逻辑,异常触发时会自动打印目标变量值,不需要进入交互调试:
脚本运行报错时,会在默认Traceback之后直接输出那个int类型的实际值。结合Traceback判断,这个非法值就是传给import sys import traceback def print_err_var(exc_type, exc_val, exc_tb): traceback.print_exception(exc_type, exc_val, exc_tb) while exc_tb: frame = exc_tb.tb_frame # 匹配os.fsencode的栈帧 if frame.f_code.co_name == "fsencode" and frame.f_code.co_filename.endswith("os.py"): print("\n[调试信息] os.fsencode接收的非法参数值:") print(repr(frame.f_locals["filename"])) exc_tb = exc_tb.tb_next sys.excepthook = print_err_varsubprocess.run的env字典中某个键对应的value,拿到值后直接修正env构造逻辑,把所有值转为字符串即可解决报错。
注:Python 3.10及以上版本原生优化了异常提示,会自动携带更多出错位置的变量上下文,3.9版本用上述两种方法即可达到相同效果,不需要改动任何本地安装的标准库文件。
内容的提问来源于stack exchange,提问作者trisimix
相关产品推荐
相关产品推荐

