使用pytest运行Jupyter Notebook测试时遇OSError错误求助
解决OSError: [Errno 8] Exec format error运行Jupyter Notebook测试的问题
嘿,这个错误的根源一眼就能看出来——你调用subprocess.check_call(args)时,把命令参数的顺序完全搞混啦!系统尝试直接执行.ipynb文件(因为你把path放在了args列表的第一个位置),但.ipynb根本不是可执行的二进制文件或脚本,自然会抛出执行格式错误。
错误的参数结构
你的原args列表是:
args = [path, fout.name, "nbconvert", "--to", "notebook", "--execute", "--ExecutePreprocessor.timeout=60", "--output"]
这相当于让系统执行./file.ipynb temp.ipynb nbconvert --to ...,完全不符合jupyter nbconvert的命令语法。
修复后的代码
下面是修正后的完整测试代码,我还顺便优化了一些细节(比如避免修改全局工作目录):
import os import subprocess import tempfile import nbformat def _notebook_run(path): """Execute a notebook via nbconvert and collect output. :returns (parsed nb object, execution errors) """ dirname, filename = os.path.split(path) with tempfile.NamedTemporaryFile(suffix=".ipynb", delete=False) as fout: # 正确的jupyter nbconvert命令参数顺序 args = [ "jupyter", "nbconvert", "--to", "notebook", "--execute", "--ExecutePreprocessor.timeout=60", "--output", fout.name, filename ] # 使用cwd参数指定工作目录,避免修改全局os.chdir subprocess.check_call(args, cwd=dirname) nb = nbformat.read(fout.name, nbformat.current_nbformat) errors = [ output for cell in nb.cells if "outputs" in cell for output in cell["outputs"] if output.output_type == "error" ] # 清理临时文件 os.unlink(fout.name) return nb, errors def test_ipynb(): nb, errors = _notebook_run('./file.ipynb') assert errors == []
关键调整点
- 修正命令参数顺序:正确的
jupyter nbconvert命令格式是jupyter nbconvert [选项] <输入文件>,所以args列表必须以jupyter开头,最后才是要处理的notebook文件名。 - 改用cwd参数:不再用
os.chdir(dirname)修改全局工作目录,而是通过subprocess的cwd参数指定命令执行的工作目录,这样更安全,不会影响后续代码的执行环境。 - 临时文件处理优化:设置
delete=False确保我们能在关闭文件后读取它,最后手动删除临时文件避免残留。
备用方案(如果jupyter命令不可用)
如果你的环境中没有直接的jupyter命令,可以用python -m nbconvert的方式替代,只需要把args的前三个元素改成:
args = [ "python", "-m", "nbconvert", # 后面的参数保持不变 ]
这样调整后,你的测试代码应该就能正常执行Jupyter Notebook并检查错误了。
内容的提问来源于stack exchange,提问作者president
相关产品推荐
相关产品推荐

