Heroku部署报cannot import name 'Mapping' from 'collections'错误
报错根因
这个是典型的Python版本与第三方依赖版本不兼容问题:
- 从Python 3.3版本开始,
collections模块下的Mapping、MutableMapping等抽象基类就被标记为废弃,官方要求从collections.abc模块导入这类对象;到Python 3.10版本,这些类被彻底从collections模块路径下移除,直接导入就会触发你看到的ImportError。 - 你项目中安装的Jinja2版本过旧,老版本Jinja2的
tests.py文件中仍然保留了from collections import Mapping的旧写法,在Python3.10环境下执行到这行代码就会直接抛出导入错误。 - Heroku如果没有在项目中显式指定Python运行版本,构建时会默认拉取当前最新的Python稳定版(也就是你日志里的3.10),刚好触发了这个兼容问题,最终导致Gunicorn worker启动失败、web进程崩溃。
修复方法
两个方案二选一即可,优先选择第一个方案,长期兼容性更好:
- 方案1:升级Jinja2到兼容Python3.10的版本
Jinja2从3.0.3版本开始就已经修复了这个导入兼容问题,直接修改项目根目录的requirements.txt文件,将Jinja2的版本约束调整为jinja2>=3.0.3;如果你是用Flask这类自动依赖Jinja2的框架,也可以直接升级框架到最新稳定版,会自动安装适配版本的Jinja2。修改完成后重新提交代码推送到Heroku触发重新构建即可。 - 方案2:锁定Heroku运行环境的Python版本为3.9
如果暂时不方便升级项目依赖,可以在项目根目录新建runtime.txt文件,在文件中写入指定的Python版本号:
提交该文件到代码仓库后重新部署,Heroku就会使用Python3.9环境构建运行你的项目,旧版本Jinja2的导入逻辑在Python3.9下可以正常执行,不会触发该报错。python-3.9.13
注意:如果升级Jinja2后仍出现同类
cannot import name xxx from collections报错,说明项目中其他依赖也存在版本过旧不兼容Python3.10的问题,常见的有旧版本MarkupSafe、Werkzeug等,将对应依赖升级到最新稳定版即可解决。
内容的提问来源于stack exchange,提问作者Digant Dixit
相关产品推荐
相关产品推荐

