因为pep 657使cpython 3.11在 traceback 中注入 ast 节点的 col_offset 和 end_col_offset,pytest(≥6.2.5)直接调用标准 traceback.format_exception() 保留并渲染这些位置信息,从而实现 ~^^^^ 行内高亮;旧版仅提供 lineno,故只能标整行。

pytest 在 Python 3.11 下 traceback 更详细,不是因为 pytest 本身改了,而是它默认复用了 CPython 3.11 新的 traceback 渲染机制——只要没被中间层拦截或降级,就能原样展示 PEP 657 提供的细粒度列偏移信息。
为什么 pytest 能显示 ~^^^^ 行内高亮?
Python 3.11 的 traceback 模块在生成异常报告时,会把每个 AST 节点的 col_offset 和 end_col_offset 注入 traceback 对象。而 pytest(≥6.2.5)调用的是标准 traceback.format_exception(),没做额外截断或重格式化,所以这些位置信息被完整保留并渲染为波浪线和插入符。
- 旧版本(如 3.10)只提供
lineno,pytest只能标整行 - 3.11 下,
x['a']['b']['c']报KeyError,高亮精准落在x['a']上,不是整行 - 若用
pytest --tb=short或--tb=line,会主动丢弃列信息,退化为旧样式
哪些情况会让 pytest 丢失 3.11 的精细标注?
即使装了 3.11,pytest 也可能显示不出 ~^^^^,常见原因:
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
-
pytest版本太老( - 自定义了
pytest_exception_interacthook 并手动调用traceback.print_exception(),且没传compact=False - 终端不支持 ANSI 转义序列(比如某些 Windows CMD 环境),导致高亮符号无法渲染,但位置数据其实还在
- 使用了
pytest-xdist并开启--boxed,子进程的 traceback 渲染可能被简化
如何验证 pytest 是否真启用了 3.11 的 traceback?
写个最小测试:
def test_keyerror():
d = {"a": {"b": None}}
d["a"]["b"]["c"]
运行 pytest test_demo.py -v,观察输出中是否出现类似:
d["a"]["b"]["c"]
~~~~~~~~~~~~~~~~^
KeyError: 'c'
- 如果只看到
File "test_demo.py", line X, in test_keyerror后直接跟错误类型,说明标注被绕过了 - 检查是否误加了
sys.excepthook = ...或第三方异常处理器(如rich的 traceback hook),它们常主动降级渲染 - Jupyter 中默认用 IPython 的异常处理器,需执行
%xmode Verbose才见原生效果
pytest 配置本身,而是底层 traceback 是否被透传、终端是否支持渲染、以及有没有其他代码提前接管了异常格式化流程。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










