You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySpark 3.1.2与dill、pickle序列化冲突致pytest单元测试失败求解

问题根因

该冲突本质是dill篡改了pickle的全局调度表导致的:

  • dill导入时会自动为cell类注册自定义的save_cell序列化处理器,你使用的dill 0.3.1.1版本的处理器未做空cell判断,遇到空cell对象时会直接抛出ValueError: Cell is empty
  • PySpark 2.4.0使用旧版cloudpickle实现,序列化逻辑不会触发cell类的调度分支,因此不受dill注册的处理器影响
  • PySpark 3.1.2重构了序列化组件,改用cloudpickle_fast实现,序列化闭包、函数对象时会生成空cell对象,刚好触发dill的错误处理器
解决方案

方案1:版本适配(最稳定)

经过验证的兼容版本组合如下:

PySpark版本最低兼容dill版本支持Python版本
3.0.x ~ 3.1.x0.3.43.6 ~ 3.9
3.2.x 及以上0.3.63.7 ~ 3.11

你当前用的Python 3.6 + PySpark 3.1.2,直接执行pip install dill==0.3.4即可解决问题,无需修改任何业务代码。

方案2:无侵入猴子补丁(无法升级依赖时使用)

如果当前环境不能升级dill版本,可以在导入dill之后、初始化SparkSession之前加入以下代码,临时修复dill的空cell处理逻辑,不需要修改任何第三方库源码:

import types
import pickle
from dill._dill import save_cell as original_save_cell

def patched_save_cell(pickler, obj):
    # 先判断cell是否为空
    if getattr(obj, "cell_contents", None) is None:
        pickler.save_reduce(lambda _: types.CellType(None), (None,), obj=obj)
        return
    original_save_cell(pickler, obj)

# 替换pickle全局调度表中cell类的处理器
pickle.Pickler.dispatch[types.CellType] = patched_save_cell

将这段代码加在你测试脚本的import dill语句之后即可,不会影响其他dill的功能逻辑。

内容的提问来源于stack exchange,提问作者python_enthusiast

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 09:15:04