Sphinx autodoc报MockFinder的list.remove(x)不在列表错误的原因是什么
错误触发原因
这个报错是Sphinx 4.x版本的已知缺陷,根源出在autodoc扩展的mock上下文管理器逻辑缺陷:
你贴出的源码中finally块会无条件尝试从sys.meta_path中移除之前插入的finder对象,但如果在try块执行到yield的过程中,其他逻辑已经提前把该finder从sys.meta_path中移除,或者多次调用上下文管理器导致对象引用不匹配,就会触发list.remove(x): x not in list的异常。
你碰到的问题和执行命令的顺序错误直接相关:
正确的构建顺序应该是先生成apidoc的rst文件,再执行html构建,但你先执行了一次make html,再生成rst文件,再二次执行构建,第一次构建过程中autodoc已经修改过sys.meta_path的状态,残留状态和第二次构建的mock操作产生冲突,最终触发报错。
和sys.path配置的关系
你在conf.py里写的sys.path.insert配置和这个报错没有直接关联,除非你配置的路径下存在和待mock模块同名的模块,导致autodoc加载逻辑和mock逻辑冲突,但这种情况出现的概率极低。
解决方案
- 首先修正构建命令的执行顺序,按如下步骤操作:
避免在生成apidoc之前提前执行构建产生残留状态。cd docs make clean sphinx-apidoc -o ./source ../mypackage make html - 如果调整顺序后仍有报错,可以选择两种修复方式:
- 升级Sphinx到5.0及以上版本,该缺陷已经在后续版本中被官方修复
- 临时修改本地
sphinx/ext/autodoc/mock.py的代码,将finally块的移除逻辑改为防御式写法:finally: if finder in sys.meta_path: sys.meta_path.remove(finder) finder.invalidate_caches()
- 额外检查
conf.py中的autodoc_mock_imports配置项,删除不必要的、重复的mock导入条目,也可以避免该类冲突。
内容的提问来源于stack exchange,提问作者ryanhill1
相关产品推荐
相关产品推荐

